Аналоговый вывод () колеблется, даже если контакт заземлен - PullRequest
1 голос
/ 24 июня 2019

Я использую Arduino Micro для считывания с 5 датчиков гибкости и отображения соответствующих углов на последовательном мониторе.В настоящее время у меня довольно много проблем с осциллирующими значениями, которые я получаю от analogRead ().Кажется, не имеет значения, подключен ли контакт к гибкому датчику или он просто заземлен - выход сильно колеблется.

Первоначально все считывалось и выводилось просто нормально, но я хотел иметь точную частоту 100 Гцчастота дискретизации и попытался немного поиграть с прерываниями по таймеру.И вот тогда это колебательное поведение началось. Я вернулся к своему исходному коду, который просто использует некоторую задержку (), и упростил чтение только с двух контактов, но, похоже, не может стряхнуть колебания.

Я думаю, что, возможно, что-то напутал об АЦП при попытке реализовать прерывания, но я не знаю, как это проверить или исправить.Пожалуйста, помогите мне разобраться, как это исправить!

Это необработанный вывод аналогового чтения.Падение значений происходит, когда я изгиба гибкого датчика

И это результирующий рассчитанный угол.Также колеблющийся.

Вот мой код минимальный рабочий пример:


int fin;
const int input[5] = {A0,A1,A2,A3,A4}; // the analog pins

int flex[5]; // analog signal read
float flexV; 
float flexR[5]; // resistance on the 47k resistor
int angle[5]; // joint angles

const float VCC = 4.98; // Measured voltage of Arduino 5V line
// Measured resistance of the 47k resistors R1-R5
const float R[5] = {45900.0,45900.0,45900.0,45900.0,45900.0}; 

// Calibration values of resistance measured during straight phase and 90 deg bend phase
const float R_STRAIGHT[5] = {37651.0,37651.0,37651.0,37651.0,37651.0};
const float R_BEND[5] = {71783.0,71783.0,71783.0,71783.0,71783.0};

void setup() {

}

void loop() {

  for(fin = 0; fin <= 4; fin++) {
   flex[fin] = analogRead(input[fin]);
   flexV = flex[fin]*VCC/1023.0;
   flexR[fin] = R[fin] * (VCC/flexV - 1.0);
   angle[fin] = map(flexR[fin],R_STRAIGHT[fin],R_BEND[fin],0,90.0);
   delay(1);   
    }
    Serial.print(angle[0]);
    Serial.print(" ");
    Serial.print(angle[1]);
    Serial.print(" ");
    Serial.print(angle[2]);
    Serial.print(" ");
    Serial.print(angle[3]);
    Serial.print(" ");
    Serial.print(angle[4]);
    Serial.print(" ");
    Serial.println(millis());
    delay(6);   
}

1 Ответ

2 голосов
/ 25 июня 2019

хорошо, аналоговые чтения обычно имеют небольшое колебание, это нормально! они измеряют значения напряжения и, в зависимости от используемого вами датчика, будут колебаться, такая же идея измерения напряжения с помощью мультиметра. если вы хотите узнать больше об этом, лучше всего начать с АЦП.

Что вам нужно сделать, чтобы предотвратить эти колебания, так это разработать фильтр. это может быть сделано на оборудовании или программном обеспечении. Очевидно, что программное обеспечение - это самый простой способ.

Мой совет для вас - средний фильтр! это простая концепция, вы получите показания Х одновременно с этими датчиками (значения будут изменяться), и вы получите из этого среднее значение.

Вот простой пример использования вашего кода:

int fin;
const int input[5] = {A0,A1,A2,A3,A4}; // the analog pins

int flex[5]; // analog signal read
float flexV; 
float flexR[5]; // resistance on the 47k resistor
float average; //Variable to store the sum of measurements
int nSamples = 4;  //Number of reading you are going to use
int angle[5]; // joint angles

const float VCC = 4.98; // Measured voltage of Arduino 5V line
// Measured resistance of the 47k resistors R1-R5
const float R[5] = {45900.0,45900.0,45900.0,45900.0,45900.0}; 

// Calibration values of resistance measured during straight phase and 90 deg bend phase
const float R_STRAIGHT[5] = {37651.0,37651.0,37651.0,37651.0,37651.0};
const float R_BEND[5] = {71783.0,71783.0,71783.0,71783.0,71783.0};

void setup() {

}

void loop() {

  for(fin = 0; fin <= 4; fin++) {
   /* A new for here to make readings and store them on the average variable */
   for(int x = 0; x <= nSamples; x++){
    flex[fin] = analogRead(input[fin]);
    average = average + flex[fin];
   }
   /*Do de avarage and clear the value on this variable*/
   flex[fin] = average/nSamples;
   avarage = 0;
   flexV = flex[fin]*VCC/1023.0;
   flexR[fin] = R[fin] * (VCC/flexV - 1.0);
   angle[fin] = map(flexR[fin],R_STRAIGHT[fin],R_BEND[fin],0,90.0);
   delay(1);   
    }
    Serial.print(angle[0]);
    Serial.print(" ");
    Serial.print(angle[1]);
    Serial.print(" ");
    Serial.print(angle[2]);
    Serial.print(" ");
    Serial.print(angle[3]);
    Serial.print(" ");
    Serial.print(angle[4]);
    Serial.print(" ");
    Serial.println(millis());
    delay(6);   
}

Идея здесь проста: сгладить значения, выполнив это среднее, что приведет к более согласованным значениям. Очевидно, что большее количество образцов улучшает результаты.

Это простая математика, если вы получаете 4 значения, такие как: 45, 50, 55, 50, ваше среднее значение будет 50 (45 + 50 + 55 + 50 = 200 / nSamples = 50)

...