Использование обратной связи энкодера для управления 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;
}
Поэтому, когда я запускаю программу, я не получаю никакого движения на сервоприводе.
Спасибо.
@MattS, 👍-1
Обсуждение1 ответ
Ваша первоначальная проблема здесь:
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 каждую итерацию. А где определяется Счетчик
? Это, конечно, должна быть глобальная переменная счетчика?
Если вы блокируете ожидание последовательного ввода, то как вы можете управлять сервоприводом, чтобы доставить его в нужное место?
Короче говоря, в вашем коде так много ошибок и проблем, что вам нужно вернуться к основам и переосмыслить / переписать многие его части.
- Tower Pro MG996R сервопривод с высоким крутящим моментом 180 °, управляющий с помощью Arduino
- Считывание нескольких поворотных энкодеров
- Как заставить сервопривод вращаться на угол больше 180°
- Пповорот сервопривода на 90 градусов
- Использование поворотных энкодеров с прерываниями смены контактов
- Как синхронно управлять двумя сервоприводами?
- Ошибка "Servo" does not name a type
- Выводы прерываний Arduino Mega 2560 и отображение портов с помощью поворотного энкодера
сократите свой код , чтобы повернуть сервопривод только в одном направлении ... не более того ... бессмысленно даже смотреть на ваш код, пока вы не убедитесь, что сервопривод действительно работает, @jsotola