4

I was trying to send and receive data between Raspberry pi and Arduino UNO. I'm able to send and receive a string from Arduino to Pi using Serial.println. I spent hours searching a better tutorial or a solution. Couldn't find any.

The code below will send an answer('Got') to Arduino when it recieves a 'Hi' from Arduino.

Simple Python code I'm using:

import serial
import time
ser = serial.Serial('/dev/ttyACM0',9600)
ser.flushInput()

while True:
s= ser.readline()
s= s.strip()
print (s.decode("utf-8"))
if (s.decode("utf-8") == "Hi"):
    print("sending")
    ans = "Got"
    ans = ans.encode("utf-8")
    ser.write(ans)
time.sleep(0.5)

Arduino code:

void setup() {
    Serial.begin(9600); As        
    Serial.println("Hi");   // send the data
}

void loop() {
    delay(1000);
    if (Serial.available()) {

        //define SerIn here
        SerIn = //code for reading string goes here 

        if (SerIn=='Got') { 
            Serial.println('I got it');
        }else{
            Serial.println('Oopz');
        } 

    } 
}

I tried this:

String SerIn;    
SerIn = Serial.readStringUntil('\n');

This throws an error while compiling.

error: invalid conversion from ‘int’ to ‘const char*’ [-fpermissive]
In file included from /usr/share/arduino/hardware/arduino/cores/arduino/Arduino.h:192:0,
                 from RPI_ARDSerial.ino:2:
/usr/share/arduino/hardware/arduino/cores/arduino/WString.h:130:16: note:   initializing argument 1 of ‘unsigned char String::operator==(const char*) const’
  unsigned char operator == (const char *cstr) const {return equals(cstr);}
12
  • 1
    Instead of String SerIn; try char SerIn[]; If that works I'll make it a proper answer. A string is really a character array, and that is what it is expecting. Commented May 31, 2019 at 15:50
  • 1
    I just tried this char SerIn[]; SerIn = Serial.readStringUntil('\n'); gives an error: storage size of ‘SerIn’ isn’t known Is this Serial.readStringUntil('\n'); part correct?
    – smc
    Commented May 31, 2019 at 15:52
  • 1
    That looks ok to me. Initialize SerIn[]; with a big enough buffer. Maybe char SerIn[16]; Commented May 31, 2019 at 15:57
  • 1
    In c and c++ double quotes must be used for string literals.
    – crasic
    Commented May 31, 2019 at 15:58
  • 1
    @crasic Good catch, the next part of his code will fail otherwise. Commented May 31, 2019 at 16:00

2 Answers 2

4

Finally I was able to find a solution. I used the example 2 from this post posted in Arduino forum https://forum.arduino.cc/index.php?topic=396450.0. I have edited python code also.

Arduino code

// Example 2 - Receive with an end-marker

const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data

boolean newData = false;

void setup() {
    Serial.begin(9600);

}

void loop() {
  //This code will continuously send '<Arduino is ready>' python.
  Serial.println("<Arduino is ready>");
  delay(10);// must be added.
  recvWithEndMarker();
  showNewData();
}

void recvWithEndMarker() {
    static byte ndx = 0;
    char endMarker = '\n';
    char rc;

    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (rc != endMarker) {
            receivedChars[ndx] = rc;
            ndx++;
            if (ndx >= numChars) {
                ndx = numChars - 1;
            }
        }
        else {
            receivedChars[ndx] = '\0'; // terminate the string
            ndx = 0;
            newData = true;
        }
    }
}

void showNewData() {
    if (newData == true) {
        Serial.println("This just in ... ");
        Serial.println(receivedChars);
        newData = false;
    }
}

Edited Python code:

import serial
import time
ser = serial.Serial('/dev/ttyACM0',9600)
ser.flushInput()

while True:
    s= ser.readline()
    s= s.strip()
    print (s.decode("utf-8"))
    if (s.decode("utf-8") == "<Arduino is ready>"):
        print("sending")
        ans = 'hello Arduino"\n"'
        ans = ans.encode("utf-8")
        ser.write(ans)
1
  • Well done, tried so much, and this finally worked!
    – Woodstock
    Commented May 4, 2020 at 19:12
2

I appreciate that you've since circumnavigated the problem by implementing your own version of readStringUntil()/readBytesUntil() but, as @crasic and @evildemonic alluded to in the comments, I think the error message you are seeing is down to this part of your code:

if (SerIn=='Got') { 
  Serial.println('I got it');
}else{
  Serial.println('Oopz');
} 

And not about the attempt to use readStringUntil() beforehand. As "Got", "I got it" and "Oopz" are strings you need to use " around them, not '. Using the ' tells the compiler to use the ASCII values for the character hence the error being about you using an integer instead of a const character array and, specifically, "unsigned char String::operator==(const char*) const" is referring to your if() line not comparing two strings.

You've used the correct notation for the string in your Serial.println("Hi"); line in setup() (although I think there's a typo on the previous line, extra As; on the end?).

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.