1
#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(); // Read the data as string
    Serial.print(state + "\n");
    // If "Waist" slider has changed value - Move Servo 5 to position
    if (state.startsWith("s5")){ 
      String stateS = state.substring(2, state.length()); // Extract only the number. E.g. from "s1120" to "120"
      servo5Pos = stateS.toInt(); // Convert the string into integer
      // We use for loops so we can control the speed of the servo
      // If previous position is bigger then current position
      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;
    }
  }
}

I'm trying to communicate my MIT Block Code to this Arduino Code, to control a servo via slider. By giving it a ''s5'' text to move the servo. However, I get this output instead when I'm printing the data received. Below is the code output and MIT block code.

enter image description here

enter image description here

3
  • what were you expecting to see in the output? ... please replace the picture of text with the text
    – jsotola
    Commented Mar 18 at 3:34
  • what is your question? ... please add a focused, answerable question to your post
    – jsotola
    Commented Mar 18 at 3:35
  • Welcome to SE/Arduino! Please take the tour to learn how this site works, and read "How to Ask". Please edit your question to replace the image of text with actual text. -- This "code output" you show, which device generates that? -- Your sketch expects just an integer after the servo number, but the text you show has a floating point number. Are you aware of this? -- How do you think are the different messages separated? The text you show has no separator between them. Did you consider to add for example a \n? Commented Mar 18 at 6:45

1 Answer 1

1

Do not use Serial.readString()

Your main issue here is that you seem to assume that the serial port transmits messages from your computer to your Arduino. It doesn't. It only transmits a stream of bytes (ASCII characters here), which is what the Arduino gets ate the other end.

Serial.readString() has no way of knowing where one message ends and the next one begins. Instead, it relies on a very simple heuristic: if one full second has elapsed with no byte being received, then it assumes whatever has been received so far is a complete message. This works reasonably well for messages manually typed at the serial monitor, because you are unlikely to type two messages within one second.

When you move the slider, however, your block code sends messages in quick succession: “s539.7”, then “s540.8”, then “s543”... The Arduino then receives a string of characters: 's', '5', '3', '9', '.', '7', 's', '5', '4', '0', '.', '8', 's', '5', '4', '3', ... This is interpreted as a single message by Serial.readString().

Solution: Use an “end of message” indicator instead of (or in addition to) the “start of message” indicator. The characters CR (\r) and LF (\n) are popular choices. You can then use Serial.readStringUntil() to get a full message.

Or, better yet, do not use the String class at all. See Reading Serial on the Arduino.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.