Сервопривод слайдера не выдает правильный выходной сигнал

#include <HCPCA9685.h>
#include <Wire.h>
#define I2CAdd 0x40

HCPCA9685 HCPCA9685(I2CAdd);
String state = "";

int servo5Pos;
int servo5PPos;

  
void setup() {
  Wire.begin();
  Serial.begin(4800);
  HCPCA9685.Init(SERVO_MODE);
  HCPCA9685.Sleep(false);
  servo5PPos = 63;

}

void loop(){
  if (Serial.available() > 0){
    state = Serial.readString(); // Прочитать данные как строку
    Serial.print(state + "\n");
    // Если ползунок «Талия» изменил значение — переместите сервопривод 5 в положение
    if (state.startsWith("s5")){ 
      String stateS = state.substring(2, state.length()); // Извлечь только число. Например, из "s1120" в "120"
      servo5Pos = stateS.toInt(); // Преобразуем строку в целое число
      // Мы используем циклы for, чтобы контролировать скорость сервопривода
      // Если предыдущая позиция больше текущей позиции
      Serial.print(servo5Pos);
      if (servo5PPos > servo5Pos){
        for (int pos = servo5PPos; pos >= servo5Pos; pos--) {
          HCPCA9685.Servo(5, pos);
          delay(20);
        }
      }
      if (servo5PPos < servo5Pos){
        for (int pos = servo5PPos; pos <= servo5Pos; pos++) {
          HCPCA9685.Servo(5, pos);  
          delay(20); 
        }
      }
      servo5PPos = servo5Pos;
    }
  }
}

Я пытаюсь передать свой код блока MIT этому коду Arduino, чтобы управлять сервоприводом через слайдер. Передавая ему текст ''s5'' для перемещения сервопривода. Однако вместо этого я получаю этот вывод, когда печатаю полученные данные. Ниже приведен вывод кода и код блока MIT.

, 👍1


1 ответ


1

Не используйте Serial.readString()

Ваша главная проблема в том, что вы, похоже, предполагаете, что последовательный порт передает сообщения с вашего компьютера на ваш Arduino. Это не так. Это передает только поток байтов (здесь символы ASCII), что и есть Arduino съедает другой конец.

Serial.readString() не имеет возможности узнать, где заканчивается одно сообщение, а начинается следующий. Вместо этого он полагается на очень простую эвристику: если прошла одна полная секунда, а байт не получен, то предполагается, все, что было получено до сих пор, является полным сообщением. Это работает достаточно хорошо для сообщений, набранных вручную на последовательном мониторе, потому что вы вряд ли наберете два сообщения в течение одной секунды.

Однако, когда вы перемещаете ползунок, ваш код блока отправляет сообщения быстрая последовательность: «s539.7», затем «s540.8», затем «s543»... Arduino затем получает строку символов: 's', '5', '3', '9', '.', '7', 's', '5', '4', '0', '.', '8', 's', '5', '4', '3', ... Это интерпретируется как единое сообщение Последовательный.readString().

Решение: Используйте индикатор «конец сообщения» вместо (или в дополнение к) индикатор «начало сообщения». Символы CR (\r) и LF (\n) являются популярными вариантами. Затем вы можете использовать Serial.readStringUntil() для получения полного сообщения.

Или, еще лучше, вообще не используйте класс String. Смотрите Чтение последовательного порта на Arduino.

,