Считывание значений потенциометра с Arduino не работает хорошо - PullRequest
0 голосов
/ 25 февраля 2020

Я программирую Robotarm с двигателями D C и пытаюсь прочитать значения для двигателей с помощью потенциометров. Для хранения нескольких позиций я сохраняю значения в массивах. Каким-то образом чтение значений потенциометров работает не так хорошо. Код работает нормально, сообщение об ошибке отсутствует, но последовательная связь возвращает значения, которые не соответствуют потису. Есть один потенциометр, который всегда показывает одно и то же значение.

Вот мой код:

//Variablen definieren
byte read1 = 0;
byte read2 = 0;
byte read3 = 0;
byte read4 = 0;
byte read5 = 0;

int array1[9];
int array2[9];
int array3[9];
int array4[9];
int array5[9];

int cur[] = {0,0,0,0,0};
int tmp[] = {0,0,0,0,0};

int i = 0;
int j = 0;
int dif = 0;
byte k = 0;
byte l = 0;

// Poti Pins definieren
const int Poti1 = A1;
const int Poti2 = A2;
const int Poti3 = A3;
const int Poti4 = A4;
const int Poti5 = A5;

// Motoren Pins definieren
const int Motor []= {2,3,4,5,6,7,8,9,10,11};

// Knöpfe Pins defininieren
byte Knopftmp = 12;
byte Knopfarr = 13;

void setup(){
Serial.begin(19200); // Serial begin
// Pin Modes festlegen
pinMode(Poti1, INPUT);
pinMode(Poti2, INPUT);
pinMode(Poti3, INPUT);
pinMode(Poti4, INPUT);
pinMode(Poti5, INPUT);

pinMode(Motor[0], OUTPUT);
pinMode(Motor[1], OUTPUT);
pinMode(Motor[2], OUTPUT);
pinMode(Motor[3], OUTPUT);
pinMode(Motor[4], OUTPUT);
pinMode(Motor[5], OUTPUT);
pinMode(Motor[6], OUTPUT);
pinMode(Motor[7], OUTPUT);
pinMode(Motor[8], OUTPUT);
pinMode(Motor[9], OUTPUT);

pinMode(Knopftmp, INPUT_PULLUP);
pinMode(Knopfarr, INPUT_PULLUP);
}

void loop(){
// Werte auslesen
read1 = analogRead(Poti1);
delay(5);
read2 = analogRead(Poti2);
delay(5);
read3 = analogRead(Poti3);
delay(5);
read4 = analogRead(Poti4);
delay(5);
read5 = analogRead(Poti5);


// Sekunden berechnen
//        Potivariable, 0, 100, 0, Millisekunden für eine volle/maximale Umdrehung
cur[0] = map(read1, 0, 1024, 0, 100)*10;
delay(5);
cur[1] = map(read2, 0, 1024, 0, 100)*10;
delay(5);
cur[2] = map(read3, 0, 1024, 0, 100)*10;
delay(5);
cur[3] = map(read4, 0, 1024, 0, 100)*10;
delay(5);
cur[4] = map(read5, 0, 1024, 0, 100)*10;
delay(5);

// Bei Knopfdruck die aktuell in tmp gespeicherte Position mit der cur Position abgleichen und bei Bedarf die Ärme in die neue Position fahren
if (digitalRead(Knopftmp) == LOW){ //Knopfabfrage
  while (i <= 4){                  // i als Variable mit der Motoren bestimmt werden
      switch (i)                   // Cases passen die Pins an den Motor an
      {
      case 0:                     
        k = 0;
        l = 1;
        break;
      case 1:
        k = 2;
        l = 3;
        break;
      case 2:
        k = 4;
        l = 5;
        break;
      case 3:
        k = 6;
        l = 7;
        break;
      case 4:
        k = 8;
        l = 9;
        break;
      default:
        break;
      }

    if (tmp[i] == cur[i]){}             // bei keiner Änderung passiert nichts
    else if (0 > cur[i] - tmp[i]){      // sollte der cur Wert geringer als der tmp Wert sein wird der Motor um die differenz zurück gedreht
      digitalWrite(Motor[k], LOW);
      digitalWrite(Motor[l], HIGH);
      delay ((cur[i]-tmp[i])*(-1));
      digitalWrite(Motor[k], LOW);
      digitalWrite(Motor[l], LOW);
      }
    else{                               // sollte der cur Wert größer als der tmp Wert sein wird der Motor um die differenz weiter gedreht
      digitalWrite(Motor[k], HIGH);
      digitalWrite(Motor[l], LOW);
      delay ((cur[i]-tmp[i]));
      digitalWrite(Motor[k], LOW);
      digitalWrite(Motor[l], LOW);
      }
      tmp[i]=cur[i];
      i++;
    }
  }
else{                                   // Zurücksetzen des Motorencounter
      if (i == 5)
    {
      i = 0;
    }
    }

// Position in Arrayspeichern    
if (digitalRead(Knopfarr) == LOW){
  array1[j] = {tmp[1]};
  array2[j] = {tmp[2]};
  array3[j] = {tmp[3]};
  array4[j] = {tmp[4]};
  array5[j] = {tmp[5]};

  Serial.print(j);Serial.println(":");
  Serial.print(array1[0]); Serial.print(" "); Serial.print(array1[1]); Serial.print(" "); Serial.print(array1[2]); Serial.print(" "); Serial.print(array1[3]); Serial.print(" ");Serial.print(array1[4]);Serial.print(" ");Serial.print(array1[5]); Serial.print(" "); Serial.print(array1[6]); Serial.print(" "); Serial.print(array1[7]); Serial.print(" "); Serial.println(array1[8]);
  Serial.print(array2[0]); Serial.print(" "); Serial.print(array2[1]); Serial.print(" "); Serial.print(array2[2]); Serial.print(" "); Serial.print(array2[3]); Serial.print(" ");Serial.print(array2[4]);Serial.print(" ");Serial.print(array2[5]); Serial.print(" "); Serial.print(array2[6]); Serial.print(" "); Serial.print(array2[7]); Serial.print(" "); Serial.println(array2[8]);
  Serial.print(array3[0]); Serial.print(" "); Serial.print(array3[1]); Serial.print(" "); Serial.print(array3[2]); Serial.print(" "); Serial.print(array3[3]); Serial.print(" ");Serial.print(array3[4]);Serial.print(" ");Serial.print(array3[5]); Serial.print(" "); Serial.print(array3[6]); Serial.print(" "); Serial.print(array3[7]); Serial.print(" "); Serial.println(array3[8]);
  Serial.print(array4[0]); Serial.print(" "); Serial.print(array4[1]); Serial.print(" "); Serial.print(array4[2]); Serial.print(" "); Serial.print(array4[3]); Serial.print(" ");Serial.print(array4[4]);Serial.print(" ");Serial.print(array4[5]); Serial.print(" "); Serial.print(array4[6]); Serial.print(" "); Serial.print(array4[7]); Serial.print(" "); Serial.println(array4[8]);
  Serial.print(array5[0]); Serial.print(" "); Serial.print(array5[1]); Serial.print(" "); Serial.print(array5[2]); Serial.print(" "); Serial.print(array5[3]); Serial.print(" ");Serial.print(array5[4]);Serial.print(" ");Serial.print(array5[5]); Serial.print(" "); Serial.print(array5[6]); Serial.print(" "); Serial.print(array5[7]); Serial.print(" "); Serial.println(array5[8]);
  Serial.println();

  j++;
  }
}

1 Ответ

1 голос
/ 27 февраля 2020

Сравнение точных значений потенциометра приведет к плохим результатам. Ознакомьтесь с таблицей данных Atmel для получения спецификаций (линейность, точность) контактов AD C. А АЦП колеблются даже при ОЧЕНЬ постоянном входном напряжении ... Осциллограф это покажет. Вы должны разработать свой код так, чтобы он реагировал на значения AD C в диапазонах, возможно, с небольшой «мертвой зоной» в середине, что означает «ничего не делать». Помните, что при 5 В, 1024-го от этого - всего несколько милливольт, поэтому, добавив в неточности AD C, вы должны увидеть, что это очень похоже на сравнение значений с плавающей запятой до 0 без использования epsilon . Если это не ТОЧНО ноль, сравнение не удастся.

Лучшие детали также часто не помогут. Даже в конструкциях, в которых я использовал дорогие прецизионные потенциометры с 25 витками, есть небольшие колебания значений AD C, которые необходимо учитывать в вашем коде.

Ознакомьтесь с разделом таблицы данных по AD C Методы шумоподавления. Лист данных и по AD C Точность.

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

...