FFT analyzátor – tříosý

Tvoříte zajímavý projekt? Pochlubte se s ním.
Pravidla fóra
Vkládejte prosím jen HOTOVÉ projekty, které chcete představit ostatním.
Odpovědět
ohruska
Příspěvky: 235
Registrován: 08 pro 2017, 20:56
Reputation: 0

FFT analyzátor – tříosý

Příspěvek od ohruska » 23 led 2018, 14:25

FFT analyzátor – tříosý

Protože jsem chtěl graficky zobrazovat chvění stroje při obrábění, snažil jsem se vytvořit grafické rozhraní, pro tuto úlohu. Zařízení slouží k ověření skeletu stroje a zjištění vlastních frekvencí stroje, která ovlivňují stabilitu při obrábění.
Jako snímač vibrací jsem použil akcelerometr ADXL345, opatřený neodinovým magnetem, s rozhraním I2C, který jsem připojil do ARDUINA - MEGA 2560.
Mega 2560 zvládne nasnímat 1024 vzorků ve třech osách do pole za 110560µs.

TESTOVACÍ OBRAZOVKA - pouze napěťový šum na vstupech 0 až 2 - 50 Hz.
FFT.jpg
Ovládání a vyhodnocení, skoro online FFT analýzy je provedeno v programovacím prostředí "PROCESSING 2".
Vyhovovala mě hlavně odladěná rychlá komunikace přes COM port.

První skutečná naměřená data ze stroje, při obrábění:
FFT_Data3.png
FFT_Data3.png (53.5 KiB) Zobrazeno 3303 x
Je jasně vidět, jak se stroj rozvibruje na frekvenci přibližně 37Hz. Tato frekvence není závislá na budící frekvenci od řezného nástroje.

Další obrazovka ukazuje doplnění o výpočet hodnot chvění, pro každý kanál. Také již funguje přepínání rozsahů akcelerometru.
Dále se podařilo urychlit komunikaci I2C na 1024 vzorků za 805588µs, při přečtení a poslání dat. Pokud budeme data ukládat do pole (max 1024x3) je rychlost ještě asi dvojnásobná.
Je to, ale maximum, pro zaplnění paměti arduina.
FFT_Data1.png
FFT_Data1.png (42.15 KiB) Zobrazeno 3303 x

petan
Příspěvky: 358
Registrován: 23 črc 2017, 10:19
Reputation: 0
Kontaktovat uživatele:

Re: FFT analyzátor – tříosý

Příspěvek od petan » 23 led 2018, 19:12

Opět bezvadná práce :o

Nebyly by třeba ještě nějaký fotky hotové elektroniky? Jen tak na doplnění?
Nebo třeba kus kódu? Pro zajímavost - nějaký špeky, nebo jak to celý vzniklo...

jankop
Příspěvky: 1029
Registrován: 06 zář 2017, 20:04
Reputation: 0
Bydliště: Brno
Kontaktovat uživatele:

Re: FFT analyzátor – tříosý

Příspěvek od jankop » 23 led 2018, 19:21

To je docela zajímavé využití akcelerometru. Kdysi se na firmě říkalo, že Rus opře šroubovák o mašinu a o něj bradu a hned ví kolik to klepe :D
Tohle je trochu sofistikovanější.

ohruska
Příspěvky: 235
Registrován: 08 pro 2017, 20:56
Reputation: 0

Re: FFT analyzátor – tříosý

Příspěvek od ohruska » 23 led 2018, 19:52

To s tím šroubovákem, fungovalo na strojích se zubovými převodovkami. Tam to bylo i rychlejší jak nějaká vibrodiagnostika. Dnes je to ale o skeletu, protože se moc šetří na materiálu a stroje se pohybují velkými rychlostmi s velkým zrychlením a z toho plynoucími rázy.

ohruska
Příspěvky: 235
Registrován: 08 pro 2017, 20:56
Reputation: 0

Re: FFT analyzátor – tříosý

Příspěvek od ohruska » 24 led 2018, 14:23

Krabička pro ARDUINO - MEGA 2560 a koncovka konektoru, byly vytištěny na 3D tiskárně.
Fotografie094.jpg
Přílohy
Fotografie093.jpg

petan
Příspěvky: 358
Registrován: 23 črc 2017, 10:19
Reputation: 0
Kontaktovat uživatele:

Re: FFT analyzátor – tříosý

Příspěvek od petan » 24 led 2018, 14:28

jankop píše:
23 led 2018, 19:21
To je docela zajímavé využití akcelerometru. Kdysi se na firmě říkalo, že Rus opře šroubovák o mašinu a o něj bradu a hned ví kolik to klepe :D
Tohle je trochu sofistikovanější.
Místo šroubováku používám stetoskop/fonendoskop. Super věc při diagnostice ložisek :)

ohruska
Příspěvky: 235
Registrován: 08 pro 2017, 20:56
Reputation: 0

Re: FFT analyzátor – tříosý

Příspěvek od ohruska » 24 led 2018, 14:33

Ještě přidám trochu kódu.

Kód: Vybrat vše

#include "Wire.h"
#include "ADXL345.h"

/************************************************************************
 * Arduino driver test for ADXL345 3-axes accelerometer                 *
 * Version 2.1                                                          *
 *                                                                      *
 * This program is free software; you can redistribute it and/or modify *
 * it under the terms of the GNU License V2.                            *
 * This program is distributed in the hope that it will be useful,      *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        *
 * GNU General Public License, version 2 for more details               *
 *                                                                      *
 * Original development: Kevin Stevenard                                *
 * Modified by Justin Shaw May 2010                                     *
 * Modified by Jens Chr Brynildsen April 2012                           *
 ***********************************************************************/
 
// Cabling for i2c using Sparkfun's breakout with an Arduino Uno / Duemilanove:
// Arduino <-> Breakout board
// Gnd      -  GND
// 3.3v     -  VCC
// 3.3v     -  CS
// Analog 4 -  SDA
// Analog 5 -  SLC

// Cabling for i2c using Sparkfun's breakout with an Arduino Mega / Mega ADK:
// Arduino <-> Breakout board
// Gnd      -  GND
// 3.3v     -  VCC
// 3.3v     -  CS
// 20       -  SDA
// 21       -  SLC

ADXL345 accel;

String carac_lus="";
int nb_carac=0;
int pos_sep;
String freq;
String dc;
int freg1;
int dc1=0;
int os=0;

unsigned long time10;
unsigned long time1;
int vzorku=1024*4;
int ax;// Displayed graph pixel dat
int ay; // Displayed graph pixel dat
int az; // Displayed graph pixel dat
int ofx, ofy, ofz;
int x, y, z;
int g=4;
int    incomingByte; 

void setup(void){
  int i;
  double xyz[3], gains[3], gains_orig[3];

  Serial.begin(115200*10);
 // Serial.println("");
  accel.powerOn();
  
  accel.getAxisGains(gains_orig);
////  Serial.println("gains_orig[]:");
  for(i = 0; i < 3; i++){
//  //  Serial.print(gains_orig[i], 6);
//  //  Serial.print(" ");
  }
//  Serial.println("");
  
  gains[0] = .1;
  gains[1] = 1.1;
  gains[2] = 2.1;
  accel.setAxisGains(gains);
  accel.getAxisGains(gains);
//  Serial.println("set gains[]:");
  for(i = 0; i < 3; i++){
  //  Serial.print(gains[i]);
  //  Serial.print(" ");
  }
//  Serial.println("");

  accel.setAxisGains(gains_orig);
  accel.getAxisGains(gains);
//  Serial.println("original gains?");
  for(i = 0; i < 3; i++){
  //  Serial.print(gains[i], 6);
  //  Serial.print(" ");
  }
//  Serial.println("");
    
  accel.readAccel(&x, &y, &z);
//  Serial.print("XYZ COUNTS: ");
//  Serial.print(x, DEC);
//  Serial.print(" ");
//  Serial.print(y, DEC);
//  Serial.print(" ");
//  Serial.print(z, DEC);
//  Serial.println("");

  accel.get_Gxyz(xyz);
//  Serial.print("XYZ Gs: ");
  for(i = 0; i<3; i++){
  //  Serial.print(xyz[i], DEC);
  //  Serial.print(" ");
  }
//  Serial.println("");

  accel.setTapThreshold(1);
//  Serial.print("getTapThreshold(): ");
//  Serial.println(accel.getTapThreshold(), DEC);
  
  accel.setAxisOffset(2, 3, 4);
//  Serial.print("getAxisOffset(&x, &y, &z): ");
  accel.getAxisOffset(&ofx, &ofy, &ofz);
//  Serial.print(x);
//  Serial.print(" ");
//  Serial.print(y);
//  Serial.print(" ");
//  Serial.print(z);
//  Serial.println("");

  accel.setTapDuration(5);
//  Serial.print("getTapDuration(): ");
//  Serial.println(accel.getTapDuration(), DEC);

  accel.setDoubleTapLatency(6);
//  Serial.print("getDoubleTapLatency(): ");
//  Serial.println(accel.getDoubleTapLatency(), DEC);

  accel.setDoubleTapWindow(7);
//  Serial.print("getDoubleTapWindow() ");
//  Serial.println(accel.getDoubleTapWindow());

  accel.setActivityThreshold(8);
//  Serial.print("getActivityThreshold() ");
//  Serial.println(accel.getActivityThreshold(), DEC);

  accel.setInactivityThreshold(9);
//  Serial.print("getInactivityThreshold() ");
//  Serial.println(accel.getInactivityThreshold(), DEC);

  accel.setTimeInactivity(10);
//  Serial.print("getTimeInactivity(): ");
//  Serial.println(accel.getTimeInactivity());

  accel.setFreeFallThreshold(11);
//  Serial.print("getFreeFallThreshold(): ");
//  Serial.println(accel.getFreeFallThreshold());

  accel.setFreeFallDuration(12);
//  Serial.print("getFreeFallDuration(): ");
//  Serial.println(accel.getFreeFallDuration(), DEC);

//  Serial.print("isActivityXEnabled(): ");
//  Serial.println(accel.isActivityXEnabled(), DEC);

//  Serial.print("isActivityYEnabled(): ");
//  Serial.println(accel.isActivityYEnabled(), DEC);

//  Serial.print("isActivityZEnabled(): ");
//  Serial.println(accel.isActivityZEnabled(), DEC);

//  Serial.print("isInactivityXEnabled(): ");
//  Serial.println(accel.isInactivityXEnabled(), DEC);

//  Serial.print("isInactivityYEnabled(): ");
//  Serial.println(accel.isInactivityYEnabled(), DEC);

//  Serial.print("isInactivityZEnabled(): ");
//  Serial.println(accel.isInactivityZEnabled(), DEC);

//  Serial.print("isActivityAc(): ");
//  Serial.println(accel.isInactivityAc(), DEC);

  accel.setActivityAc(true);
  accel.setInactivityAc(true);

  accel.setSuppressBit(true);
//  Serial.print("getSuppressBit(); true? ");
//  Serial.println(accel.getSuppressBit());

  accel.setSuppressBit(false);
//  Serial.print("getSuppressBit(); false? ");
//  Serial.println(accel.getSuppressBit());
  
  accel.setTapDetectionOnX(true);
//  Serial.print("isTapDetectionOnX(); true? ");
//  Serial.println(accel.isTapDetectionOnX(), DEC);
  accel.setTapDetectionOnX(false);
//  Serial.print("isTapDetectionOnX(); false? ");
//  Serial.println(accel.isTapDetectionOnX(), DEC);

  accel.setTapDetectionOnY(true);
//  Serial.print("isTapDetectionOnY(); true? ");
//  Serial.println(accel.isTapDetectionOnY(), DEC);
  accel.setTapDetectionOnY(false);
//  Serial.print("isTapDetectionOnY(); false? ");
//  Serial.println(accel.isTapDetectionOnY(), DEC);

  accel.setTapDetectionOnZ(true);
//  Serial.print("isTapDetectionOnZ(); true? ");
//  Serial.println(accel.isTapDetectionOnZ(), DEC);
  accel.setTapDetectionOnZ(false);
//  Serial.print("isTapDetectionOnZ(); false? ");
//  Serial.println(accel.isTapDetectionOnZ(), DEC);

  accel.setActivityX(true);
  accel.setActivityY(true);
  accel.setActivityZ(true);

  accel.setInactivityX(false);
  accel.setInactivityY(false);
  accel.setInactivityZ(false);

//  Serial.print("isActivitySourceOnX(): ");
//  Serial.println(accel.isActivitySourceOnX(), DEC);

//  Serial.print("accel.isActivitySourceOnY(): ");
//  Serial.println(accel.isActivitySourceOnY(), DEC);

//  Serial.print("accel.isActivitySourceOnZ(): ");
//  Serial.println(accel.isActivitySourceOnZ(), DEC);

//  Serial.print("accel.isTapSourceOnX(): ");
//  Serial.println(accel.isTapSourceOnX(), DEC);

//  Serial.print("accel.isTapSourceOnY(): ");
//  Serial.println(accel.isTapSourceOnY(), DEC);

//  Serial.print("accel.isTapSourceOnZ(): ");
//  Serial.println(accel.isTapSourceOnZ(), DEC);

//  Serial.print("accel.isAsleep(): ");
//  Serial.println(accel.isAsleep(), DEC);

//  Serial.print("accel.isLowPower(): ");
//  Serial.println(accel.isLowPower(), DEC);
  accel.setLowPower(false);
  
  accel.setRate(3.14159);
//  Serial.print("getRate(): 3.14159?");
//  Serial.println(accel.getRate());

//  Serial.print("getInterruptSource(): ");
//  Serial.println(accel.getInterruptSource(), DEC);

//  Serial.print("getInterruptSource(1): ");
//  Serial.println(accel.getInterruptSource(1), DEC);
  
//  Serial.print("getInterruptMapping(1): ");
//  Serial.println(accel.getInterruptMapping(1), DEC);
  
  accel.setInterruptMapping(1, true);
//  Serial.print("isInterruptEnabled(1): ");
//  Serial.println(accel.isInterruptEnabled(1));
  
  accel.setInterrupt(1, true);

  accel.setSelfTestBit(false);
//  Serial.print("getSelfTestBit(): ");
//  Serial.println(accel.getSelfTestBit(), DEC);

 accel.setRangeSetting(2);
 accel.setRate(800);

// Serial.print("getRate(): ");
//  Serial.println(accel.getRate(), DEC);

//  accel.printAllRegister();
accel.readAccel(&x, &y, &z);
  
}
void loop(void){
    int  i;

  if (Serial.available() > 0) {
    incomingByte = Serial.read();
    if (incomingByte == 'A')g=64;
    if (incomingByte == 'B')g=32;
    if (incomingByte == 'C')g=16;
    if (incomingByte == 'D')g=8;
    if (incomingByte == 'E')g=4;
    if (incomingByte == 'F')g=2;
    if (incomingByte == 'G')g=1;
    if (incomingByte == 'a')accel.setRangeSetting(2);
    if (incomingByte == 'b')accel.setRangeSetting(4);
    if (incomingByte == 'c')accel.setRangeSetting(8);
    if (incomingByte == 'd')accel.setRangeSetting(16);
    if (incomingByte == 'e')accel.setRate(3200);
    if (incomingByte == 'f')accel.setRate(1600);
    if (incomingByte == 'g')accel.setRate(800);
    if (incomingByte == 'h')accel.setRate(400);
    if (incomingByte == 'i')accel.setRate(200);
    if (incomingByte == 'j')accel.setRate(100);
    if (incomingByte == 'x')os=1;
    if (incomingByte == 'y')os=2;
    if (incomingByte == 'z')os=4;
    if (incomingByte == 'Z')os=0;
 

}
 //Serial.print(";point;");
 //Serial.print(vzorku);
 //Serial.println(":");
  Wire.setClock(800000L); 

accel.readAccel(&x, &y, &z);

time10 = micros();
  //delay(10);        // delay in between reads for stability
 Serial.print("Size:");
 Serial.print(vzorku/g);
 Serial.println(":");  // read the input on analog pin 0:

 for (int i=1; i <= vzorku/g; i++)
 {
accel.readAccel(&ax, &ay, &az);
if ((os==0) || (os==1)) { Serial.print(ax-x, DEC);
  Serial.print(";");}
if ((os==0) || (os==2)) { Serial.print(ay-y, DEC);
  Serial.print(";");}
if ((os==0) || (os==4)) {  Serial.print(az-z, DEC);
  Serial.println(";");}  
 
 } 
time1 = micros();
Serial.print("Time_");
Serial.print(time1-time10);
Serial.println("_");
}

int strToInt(String str){
int result = 0;
for(int i=0; i < str.length(); i++)
   {
    if (isdigit (str[i])) {
       result = result * 10 + str[i] - '0';
    }
    else {
       break;
    }
  }
  return result;
} 

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 12 hostů