OK you should remove the 5V wire as I can't see it doing any good to have them connected
Why do you have a power supply on the slave ? it does get power from the USB from the RPi
have you tried a simple code to see if the Serial coms work:
Python code for example:
RPI is listening for keyboard entries and sending it to Slave
RPI is listening for Serial input from the Slave and printing it on screen
I've this code from my "tutorial" in French
#!/usr/bin/python3
# ============================================
# code is placed under the MIT license
# Copyright (c) 2023 J-M-L
# For the Arduino Forum : https://forum.arduino.cc/u/j-m-l
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
# ===============================================
import sys, threading, queue, serial
import serial.tools.list_ports
baudRate = 115200
arduinoQueue = queue.Queue()
localQueue = queue.Queue()
def selectArduino():
ports = serial.tools.list_ports.comports()
choices = []
print('PORT\tDEVICE\t\t\tMANUFACTURER')
for index,value in enumerate(sorted(ports)):
if (value.hwid != 'n/a'):
choices.append(index)
print(index, '\t', value.name, '\t', value.manufacturer) # https://pyserial.readthedocs.io/en/latest/tools.html#serial.tools.list_ports.ListPortInfo
choice = -1
while choice not in choices:
answer = input("➜ Select your port: ")
if answer.isnumeric() and int(answer) <= int(max(choices)):
choice = int(answer)
print('selecting: ', ports[choice].device)
return ports[choice].device
def listenToArduino():
message = b''
while True:
incoming = arduino.read()
if (incoming == b'\n'):
arduinoQueue.put(message.decode('utf-8').strip().upper())
message = b''
else:
if ((incoming != b'') and (incoming != b'\r')):
message += incoming
def listenToLocal():
while True:
command = sys.stdin.readline().strip().upper()
localQueue.put(command)
def configureUserInput():
localThread = threading.Thread(target=listenToLocal, args=())
localThread.daemon = True
localThread.start()
def configureArduino():
global arduinoPort
arduinoPort = selectArduino()
global arduino
arduino = serial.Serial(arduinoPort, baudrate=baudRate, timeout=.1)
arduinoThread = threading.Thread(target=listenToArduino, args=())
arduinoThread.daemon = True
arduinoThread.start()
# ---- CALLBACKS UPON MESSAGES -----
def handleLocalMessage(aMessage):
print("=> [" + aMessage + "]")
arduino.write(aMessage.encode('utf-8'))
arduino.write(bytes('\n', encoding='utf-8'))
def handleArduinoMessage(aMessage):
print("<= [" + aMessage + "]")
# ---- MAIN CODE -----
configureArduino() # will reboot AVR based Arduinos
configureUserInput() # handle stdin
print("Waiting for Arduino")
# --- A good practice would be to wait for a know message from the Arduino
# for example at the end of the setup() the Arduino could send "OK"
while True:
if not arduinoQueue.empty():
if arduinoQueue.get() == "OK":
break
print("Arduino Ready")
# --- Now you handle the commands received either from Arduino or stdin
while True:
if not arduinoQueue.empty():
handleArduinoMessage(arduinoQueue.get())
if not localQueue.empty():
handleLocalMessage(localQueue.get())
The master just echoes what it gets from the console (Serial) to Serial1 (Slave)
void setup() {
Serial.begin(115200);
Serial1.begin(115200);
}
void loop() {
if (Serial.available()) Serial1.write(Serial.read());
}
The slave is listening on both Serial and Serial1 and buffering until it gets a full line and then echo that back to the RPI on Serial, something like this (typed here, fully untested)
#define RPI Serial
#define MASTER Serial1
const byte maxMessageSize = 50;
char messageFromRPI[maxMessageSize + 1];
char messageFromMaster[maxMessageSize + 1];
bool gotMessageFromRPI() {
static byte index = 0;
bool messageReady = false;
int r = RPI.read();
if (r != -1) { // got something
if (r == '\n') { // end of line terminates the message
messageFromRPI[index] = '\0';
index = 0; // get ready for next time
messageReady = true;
} else {
if (index < maxMessageSize) messageFromRPI[index++] = r; // don't overflow
}
}
return messageReady;
}
bool gotMessageFromMaster() {
static byte index = 0;
bool messageReady = false;
int r = RPI.read();
if (r != -1) { // got something
if (r == '\n') { // end of line terminates the message
messageFromMaster[index] = '\0';
index = 0; // get ready for next time
messageReady = true;
} else {
if (index < maxMessageSize) messageFromMaster[index++] = r; // don't overflow
}
}
return messageReady;
}
void setup() {
RPI.begin(115200);
MASTER.begin(115200);
Serial.println("OK"); // let the python code on RPi know we are ready
}
void loop() {
if (gotMessageFromRPI()) {
RPI.print(F("Message from RPI: "));
RPI.println(messageFromRPI);
}
if (gotMessageFromMaster()) {
RPI.print(F("Message from MASTER: "));
RPI.println(messageFromMaster);
}
}