Использование обратной связи энкодера для управления 360 градусным сервоприводом

Я собрал скетч для управления сервоприводом, который вращает энкодер. В конце концов я планирую построить его до входа DMX, так что у меня есть диапазон входных данных от 0 до 255. По сути, он должен попросить вас ввести диапазон от 0 до 255, а затем изменить это значение на 0 -180 для сервоуправления. Затем он должен сравнить это с кодером и вращать правильное направление до тех пор, пока значение кодера и запрошенные значения не совпадут. Я только изучаю arduino, поэтому уверен, что совершил какую-то ошибку. Вот код:

// Входы поворотного энкодера
#define inputCLK 22
#define inputDT 24

#include <Servo.h>

Servo myservo;
int pos = 90;
int counter = 90; 
int currentStateCLK;
// Настройка последовательного монитора
   
// Считайте начальное состояние inputCLK
// Назначить переменной
int previousStateCLK; 
 
String encdir ="";

void setup() { 
  Serial.begin (9600);  
  previousStateCLK = digitalRead(inputCLK);
  // Установить контакты энкодера в качестве входов
  pinMode (inputCLK,INPUT);
  pinMode (inputDT,INPUT);
  myservo.attach(9);
    
void loop() { 
  Serial.println("Enter a number from 0 to 255");  
  while (Serial.available() == 0); {}  
  int val = Serial.parseInt(); // прочитайте int или parseFloat для ..float...
  long Pos = val;
  Pos = Pos * 180 / 255;
  Serial.println(val);
  Serial.println(Pos);
  if (Pos > Counter) {
    myservo.write 0;
  }
  if (Pos < Counter) {
    myservo.write 180;
  }
  if (Pos = Counter) {
    myservo.write 90;
  }

  // Считывание текущего состояния inputCLK
  currentStateCLK = digitalRead(inputCLK);
   
  // Если предыдущее и текущее состояния inputCLK различны, то произошел импульс
  if (currentStateCLK != previousStateCLK) { 
    // Если состояние inputDT отличается от состояния inputCLK, то 
    // кодер вращается против часовой
    if (digitalRead(inputDT) != currentStateCLK) { 
      counter --;
      encdir ="CCW";
    } else {
      // Энкодер вращается по часовой стрелке
      counter ++;
      encdir ="CW";       
    }
    Serial.print("Direction: ");
    Serial.print(encdir);
    Serial.print(" -- Value: ");
    Serial.println(counter);
  } 
  // Обновить previousStateCLK с текущим состоянием
  previousStateCLK = currentStateCLK; 
}

Поэтому, когда я запускаю программу, я не получаю никакого движения на сервоприводе.

Спасибо.

, 👍-1

Обсуждение

сократите свой код , чтобы повернуть сервопривод только в одном направлении ... не более того ... бессмысленно даже смотреть на ваш код, пока вы не убедитесь, что сервопривод действительно работает, @jsotola


1 ответ


0

Ваша первоначальная проблема здесь:

  if (Pos = Counter) {

Если результат (провал) назначения Счетчика Pos отличен от нуля, то остановитесь.

Это неправильно. Вы назначаете, а не сравниваете. В C == - это сравнение, а = - это присвоение. Вместо этого он должен гласить:

  if (Pos == Counter) {

Однако есть еще одна, более хитрая проблема с вашим кодом - использование Serial.parseInt().

Если вы отправляете строку 56\r\n, как обычно (с окончанием строки CR + LF, типичным для последовательной связи), то parseInt прочитает первую часть строки вплоть до первого нецифрового символа и проанализирует ее как число. То есть 56\r и возвращает значение 56. Затем на следующем проходе он увидит, что в последовательном буфере все еще есть данные, и проанализирует их, вплоть до первого нецифрового символа, который является просто \n. Таким образом, он вернет 0.

Это означает, что при первом проходе через loop() вы получаете 56, а затем сразу же после следующего прохода через loop() вы получаете 0.

А затем, глядя на ваш код в третий раз, возникает еще одна большая проблема: вы блокируете ожидание последовательного ввода, а ваша переменная Pos является локальной и будет теряться на каждой итерации. Я думаю, вы хотели использовать pos, который является глобальной переменной, а не создавать новую длинную переменную Pos каждую итерацию. А где определяется Счетчик? Это, конечно, должна быть глобальная переменная счетчика?

Если вы блокируете ожидание последовательного ввода, то как вы можете управлять сервоприводом, чтобы доставить его в нужное место?

Короче говоря, в вашем коде так много ошибок и проблем, что вам нужно вернуться к основам и переосмыслить / переписать многие его части.

,