Итак-с у меня кой чего получилось.
Доработанная качающаяся рама. Есть возможность быстро корректировать собственную частоту колебаний за счет замены пружин и смещения места ее опоры. Точность на такой раме реально выше других.
Аппаратная часть состоит из arduino и акселя adsl 345 подключенного по SPI (вот такой например купить можно за
не дорого ) и оптопары (с компаратором
например), которая метку на моторе распознает (если корпус темный можно корректором нарисовать белую метку ). Еще можно было бы сделать вариант использующий лазер\датчик и следить по пропеллеру, но до этого я не дошел.
Вот рабочий код:
- Код: Выделить всё • Развернуть
//Add the SPI library so we can communicate with the ADXL345 sensor
#include <SPI.h>
#define MAX_SAMPLES 550
//Assign the Chip Select signal to pin 10.
int CS=10;
//This is a list of some of the registers available on the ADXL345.
//To learn more about these and the rest of the registers on the ADXL345, read the datasheet!
char POWER_CTL = 0x2D; //Power Control Register
char DATA_FORMAT = 0x31;
char DATAX0 = 0x32; //X-Axis Data 0
char DATAX1 = 0x33; //X-Axis Data 1
char DATAY0 = 0x34; //Y-Axis Data 0
char DATAY1 = 0x35; //Y-Axis Data 1
char DATAZ0 = 0x36; //Z-Axis Data 0
char DATAZ1 = 0x37; //Z-Axis Data 1
//This buffer will hold values read from the ADXL345 registers.
unsigned char values[10];
//These variables will be used to hold the x,y and z axis accelerometer values.
int x,y,z;
byte lowbyte_x[MAX_SAMPLES], highbyte_x[MAX_SAMPLES];
//byte lowbyte_y[MAX_SAMPLES], highbyte_y[MAX_SAMPLES];
//byte lowbyte_z[MAX_SAMPLES], highbyte_z[MAX_SAMPLES];
byte zero[MAX_SAMPLES];
int inPin = 2;
int val = 0;
int sample_index,t;
const int dataReadyPin = 4;
void setup(){
//Initiate an SPI communication instance.
SPI.begin();
//Configure the SPI connection for the ADXL345.
SPI.setDataMode(SPI_MODE3);
//Create a serial connection to display the data on the terminal.
Serial.begin(115200);
pinMode(dataReadyPin, INPUT);
pinMode(inPin, INPUT);
//Set up the Chip Select pin to be an output from the Arduino.
pinMode(CS, OUTPUT);
//Before communication starts, the Chip Select pin needs to be set high.
digitalWrite(CS, HIGH);
//Put the ADXL345 into Measurement Mode by writing 0x08 to the POWER_CTL register.
writeRegister(POWER_CTL, 0x08); //Measurement mode
//Put the ADXL345 into +/- 8G range by writing the value 0x01 to the DATA_FORMAT register.
writeRegister(DATA_FORMAT, 0x02);
writeRegister(0x2C, 0x0F); // 3200 HZ
writeRegister(0x2E, 0x80); // set dataready to interrupt pin INT1 and active high
/* writeRegister(0x1E, 0x00); // X-offset to 0
writeRegister(0x1F, 0x00); // Y-offset to 0
writeRegister(0x20, 0x00); // Z-offset to 0
*/ delay(100);
}
void loop(){
for (sample_index=0; sample_index<MAX_SAMPLES; sample_index++)
{
while (digitalRead (dataReadyPin) == LOW) ;
//Reading 6 bytes of data starting at register DATAX0 will retrieve the x,y and z acceleration values from the ADXL345.
//The results of the read operation will get stored to the values[] buffer.
readRegister(DATAX0, 6, values);
zero[sample_index] = digitalRead(inPin) ;//digitalRead (dataReadyPin); //
//The ADXL345 gives 10-bit acceleration values, but they are stored as bytes (8-bits). To get the full value, two bytes must be combined for each axis.
//The X value is stored in values[0] and values[1].
lowbyte_x[sample_index]=values[0];
highbyte_x[sample_index]=values[1];
//x = ((int)values[1]<<8)|(int)values[0];
//The Y value is stored in values[2] and values[3].
// lowbyte_y[sample_index]=values[2];
// highbyte_y[sample_index]=values[3];
//y = ((int)values[3]<<8)|(int)values[2];
//The Z value is stored in values[4] and values[5].
// lowbyte_z[sample_index]=values[4];
// highbyte_z[sample_index]=values[5];
// z = ((int)values[5]<<8)|(int)values[4];
}
for (t=0; t < MAX_SAMPLES; t++)
{
x = ((int)highbyte_x[t] << 8) | (int)lowbyte_x[t];
// y = ((int)highbyte_y[t] << 8) | (int)lowbyte_y[t];
// z = ((int)highbyte_z[t] << 8) | (int)lowbyte_z[t];
val = zero[t];
//Print the results to the terminal.
Serial.print(x, DEC);
Serial.print("\t");
/* Serial.print(y, DEC);
Serial.print("\t");
Serial.print(z, DEC);
Serial.print("\t"); */
Serial.println(val);
// delay(1);
}
Serial.println ("End");
}
//This function will write a value to a register on the ADXL345.
//Parameters:
// char registerAddress - The register to write a value to
// char value - The value to be written to the specified register.
void writeRegister(char registerAddress,unsigned char value){
//Set Chip Select pin low to signal the beginning of an SPI packet.
digitalWrite(CS, LOW);
//Transfer the register address over SPI.
SPI.transfer(registerAddress);
//Transfer the desired register value over SPI.
SPI.transfer(value);
//Set the Chip Select pin high to signal the end of an SPI packet.
digitalWrite(CS, HIGH);
}
//This function will read a certain number of registers starting from a specified address and store their values in a buffer.
//Parameters:
// char registerAddress - The register addresse to start the read sequence from.
// int numBytes - The number of registers that should be read.
// char * values - A pointer to a buffer where the results of the operation should be stored.
void readRegister(char registerAddress, int numBytes,unsigned char * values){
//Since we're performing a read operation, the most significant bit of the register address should be set.
char address = 0x80 | registerAddress;
//If we're doing a multi-byte read, bit 6 needs to be set as well.
if(numBytes > 1)address = address | 0x40;
//Set the Chip select pin low to start an SPI packet.
digitalWrite(CS, LOW);
//Transfer the starting register address that needs to be read.
SPI.transfer(address);
//Continue to read registers until we've read the number specified, storing the results to the input buffer.
for(int i=0; i<numBytes; i++){
values[i] = SPI.transfer(0x00);
}
//Set the Chips Select pin high to end the SPI packet.
digitalWrite(CS, HIGH);
}
Тут у нас чтение данных с акселя ( с 1 координаты) и оптопары, запись в память (на atmega328 влазят 550 значений) и выдача их в порт. В конце передачи еще пишется "end" для того что ПО на компе разбивала на части.
А вот что я наваял для компа в LabVIEW естественно...
тут у нас прием всего,корректировок всякого, есть подсчет оборотов, есть фильтр данных с акселя, есть выдача фильтрованных данных за 1 оборот в полярных координатах (кружки такие получаются когда синусоида четкая). Ну и собственно считается всякими хитрыми преобразованиями спектр всего этого дела. Можно с обработанных и необработанных данных считать. Отдельно просматривается наш рабочий диапозон (10Гц это 600об\мин 100Гц-6000об\мин). Для нашей частоты смотрим фазу вычитаем фазу сигнала оптопары и находим искомое смещение масс. Уровень того смещения у нас по амплитуде смотрится. На графике 10 последних значений рисуются. Исходник под labview 13 (там еще надо ставить visa,robotics модули):
чего еще не хватает? там наблюдается сдвиг фазы в зависимости от оборотов. видать какое то запаздывания. тоже корректировки нужны. ну а так работает очень даже. у мну мотор без пропеллера без крепления пропеллера за счет резонанса выдает норм данные годные для нахождения фазы.
потом еще я работу не закончил. буду еще варианты пробовать ну и начну пользоваться наберу данных, отпишусь.