Arduino and Raspberry Pi Serial Communication

Hello, everyone

I was serializing Arduino and Raspberry Pi and I ended up writing this because of a strange error.

Below is the code applied to Arduino Uno.

//blinking led by usb serial communication
const int ledPin = 13;  // pin number with built-in LED

void setup() {
// Serial communication initialization
  Serial.begin(9600);
  
// Set internal LED as output pin
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // If there is data in the serial buffer
  if (Serial.available()) {
    //Read and process text
    String receivedString = Serial.readStringUntil('\n'); // 개행 문자까지 읽기
    
    //Internal LED control when 'pm1' string is received
    if (receivedString.startsWith("pm1")) {
      int num = receivedString.substring(4).toInt(); // Extract numeric parts from string
      Serial.println(receivedString);
      blinkLED(num);
    }
  }
}

// Function that blinks the internal LED a given number of times
void blinkLED(int times) {
  for (int i = 0; i < times; i++) {
    Serial.println(i+1);
    digitalWrite(ledPin, HIGH);  // LED 켜기
    delay(1000);  // 1000ms 대기 (1초)
    digitalWrite(ledPin, LOW);   // LED 끄기
    delay(1000);  // 1000ms 대기 (1초)
  }
}

And below this is Python code executed by Raspberry Pi.

import serial
import sys

# Serial Port and Speed Settings
serial_port = '/dev/ttyUSB0'  # 아두이노와 연결된 포트
baud_rate = 9600

# Serial Port Initialization
ser = serial.Serial(serial_port, baud_rate)

# Translate numbers passed by command-line arguments into strings and send
def send_data(data):
    ser.write(data.encode())  #Convert string to bytes and send

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Usage: python send_data.py <number>")
        sys.exit(1)

    number = sys.argv[1]
    send_data(number)

I checked on Raspberry Pi that if you run the above codes, the value goes well when you enter the value.

1

I typed pm1_2 and actually made sure it was typed correctly.
But led doesn't blink twice.

I tried the following method in a different way, and this method succeeded.
But this code doesn't end because the script is a while statement.

import serial

# Serial Port and Speed Settings
serial_port = '/dev/tyUSB0' #Port associated with Arduino
baud_rate = 9600

# Serial Port Initialization
ser = serial.Serial(serial_port, baud_rate)

while True:
# Receive data input from users
data = input("Enter data to send: ")

# data transfer
ser.write(data.code()) #Convert string to bytes and send

The way I want it to be done is once the python code is entered together as an argument from another code, and the executed code forwards the argument to Arduino, blinking the led as much as the entered argument.

In other words, I want to succeed the first code.
I don't know what's wrong with this.

Tell me about your experiences.
I couldn't find this problem on the Internet.

The IDE1.x is for Problems with the Arduino IDE itself NOT your project. It says so in the description of the section. Therefore I have moved your post here.

You might want to look at this How to get the best out of this forum before you proceed any further.

My experience shows me that you can't simply connect the serial ports of the Arduino and Pi together. This is because most of the Arduinos used are 5V systems and the Raspberry Pi is a 3V3 system. Therefore the 5V signal from the Arduino Uno to the Pi can damage the Pi if you do not cut it down to 3V3 with a potential divider.

Likewise the voltages from the Pi might not be enough to trigger the Arduino, this is less likely to be a problem but it can happen.

Python sends things to the serial port in 'byte code' format not in strings. So you are sending the wrong thing.

I don't think that it applies here; I think that OP is using USB.

Thanks, I hadn't considered that. In which case the Python is wrong.

That is for connecting the Nano or Mega. For using the Uno you need to use:-
serial_port = serial.Serial("/dev/ttyACM0", 9600, timeout = 5) # For Uno' You also need an import serial` at the start of the code as well.

This is a python example of sending all the ASCII characters to the Arduino.

for c in range(0x20,0x7F):
   if c % 16 ==0:
      print() 
      print(hex(c),"  ",end='')
   print(chr(c)," ",end='') 
'''

Thank you for your detailed explanation and comments.
I have one more thing to show you.

This is a picture that shows that it is connected to the USB0 port.

And going in bytes already works within the Arduino code above.

Actually, if I run the code below on Raspberry Pi, it will run as I intended.

import serial

# # Serial Port and Speed Settings
serial_port = '/dev/tyUSB0' #Port associated with Arduino
baud_rate = 9600

# # Serial Port Initialization
ser = serial.Serial(serial_port, baud_rate)

while True:
# # Receive data input from users
data = input("Enter data to send: ")

# # data transfer
ser.write(data.code())

But what I want is

import serial
import sys

# # Serial Port and Speed Settings
serial_port = '/dev/tyUSB0' #Port associated with Arduino
baud_rate = 9600

# # Serial Port Initialization
ser = serial.Serial(serial_port, baud_rate)

# # Translate numbers passed by command-line arguments into strings and send
def send_data(data):
    ser.write(data.encode())  #Convert string to bytes and send

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Usage: python send_data.py <number>")
        sys.exit(1)

    number = sys.argv[1]
    send_data(number)

This is when you run it with this code.
Also, I don't know why this code doesn't work.

This code receives a factor upon execution and sends a value to Arduino.

I don't know why this isn't working.

How are you connecting the Pi to the Arduino?

Connecting with USB.

As you have found this will not work.
That code is incomplete.

There is no main function in this code. Why is this line in here?

As far as I know, if I put the code I want to run under this code, I only run that code.
Does this matter?

First this is wrong, second if it is true then you never run the code above it so the port never gets set up.

import serial
import sys

def main():
	serial_port = '/dev/ttyUSB0'
	baud_rate = 9600

	ser = serial.Serial(serial_port, baud_rate)

	if(len(sys.argv) != 2):
		print("Usage: python t.py <number>")
		exit(1)
	else:
		number = sys.argv[1]
		ser.write(number.encode())

if __name__ == '__main__':
	main()

I temporarily revised the following code.
But it still doesn't work.

I haven't looked at this (because I don't use python) but maybe it can be useful: Demo of PC-Arduino comms using Python

Thank you for your effort.

I'd suggest you change this

to this

String receivedString = Serial.readString(); // read till time out
Serial.println(receivedString );  // see what came in

and on python add a print so you can see your input argument ?

You would not expect this to work. As I said before it is all wrong.
That code runs only once and then quits. So the ' if ... else' will only take one of those options. Where are these numbers coming from? The whole sketch makes no sense to me so it is hard to say what is going on.

I see where you read until you get a newline but I don't see where the newline comes from.
Perhaps I'm missing something if not you could try adding the newline to see if there is a difference.

# # Translate numbers passed by command-line arguments into strings and send
def send_data(data):
    ser.write(data.encode())  #Convert string to bytes and send
    ser.write('\n'.encode())  # add a newline char

I was currently working on Python, but I was told that I had to work on node.js.
I'm not saying Python doesn't work, but the model I'm using told me that it's easier to use js, so I'm rewriting the code with node.js.

Thank you for your help and I'm sorry.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.