Serial data between Uno and Raspberry Pi

I have an uno connected directly to a raspberry pi with a usb cable, I wish to send from the pi this line....

/ /c#004400GREEN /c#7E0000RED/c#000D7DBLUE /f9/c#004400/.GREEN /c#7E0000 /c#7E0000

which is written on a file on the pi located here...

/home/pi/Desktop/SerPython/read_it.txt

I am having some partial success with this python script I obtained elewhere on this forum, this script deilvers via serial to the uno my line..
/ /c#004400GREEN /c#7E0000RED/c#000D7DBLUE /f9/c#004400/.GREEN /c#7E0000 /c#7E0000
but isnt reading it from my file location.

The second block of code below can read from the file location but doesnt send it out to serial so what I,m asking is can these two scripts be merged to achieve my read from file and output to uno ambition.

I am using python version 3.7

Any help would be greatly appreciated.

#=====================================

#  Function Definitions

#=====================================

def sendToArduino(sendStr):
    ser.write(sendStr.encode('utf-8')) # change for Python3


#======================================

def recvFromArduino():
    global startMarker, endMarker
    
    ck = ""
    x = "z" # any value that is not an end- or startMarker
    byteCount = -1 # to allow for the fact that the last increment will be one too many
    
    # wait for the start character
    while  ord(x) != startMarker: 
        x = ser.read()
    
    # save data until the end marker is found
    while ord(x) != endMarker:
        if ord(x) != startMarker:
            ck = ck + x.decode("utf-8") # change for Python3
            byteCount += 1
        x = ser.read()
    
    return(ck)


#============================

def waitForArduino():

    # wait until the Arduino sends 'Arduino Ready' - allows time for Arduino reset
    # it also ensures that any bytes left over from a previous message are discarded
    
    global startMarker, endMarker
    
    msg = ""
    while msg.find("Arduino is ready") == -1:

        while ser.inWaiting() == 0:
            pass
        
        msg = recvFromArduino()

        print (msg) # python3 requires parenthesis
        print ()
        
#======================================

def runTest(td):
    numLoops = len(td)
    waitingForReply = False

    n = 0
    while n < numLoops:
        teststr = td[n]

        if waitingForReply == False:
            sendToArduino(teststr)
            print ("Sent from PC -- LOOP NUM " + str(n) + " TEST STR " + teststr)
            waitingForReply = True

        if waitingForReply == True:

            while ser.inWaiting() == 0:
                pass
            
            dataRecvd = recvFromArduino()
            print ("Reply Received  " + dataRecvd)
            n += 1
            waitingForReply = False

            print ("===========")

        time.sleep(5)


#======================================

# THE DEMO PROGRAM STARTS HERE

#======================================

import serial
import time

print ()
print ()

# NOTE the user must ensure that the serial port and baudrate are correct
# serPort = "/dev/ttyS80"
serPort = "/dev/ttyUSB0"
baudRate = 9600
ser = serial.Serial(serPort, baudRate)
print ("Serial port " + serPort + " opened  Baudrate " + str(baudRate))


startMarker = 60
endMarker = 62


waitForArduino()


testData = []
#testData.append("<LED1,200,0.2>")
#testData.append("<LED1,800,0.7>")
testData.append("          /c#004400GREEN /c#7E0000RED/c#000D7DBLUE /f9/c#004400/GREEN /c#7E0000/bRED/c#000D7DBLUE /c#7E0000/bRED/c#000D7DBLUE/c#000000..")
#testData.append("<LED2,200,0.2>")
#testData.append("<LED1,200,0.7>")

runTest(testData)


ser.close
import serial
import time

print ()
print ()

# NOTE the user must ensure that the serial port and baudrate are correct
# serPort = "/dev/ttyS80"
serPort = "/dev/ttyUSB0"
baudRate = 9600
ser = serial.Serial(serPort, baudRate)
#print ("Serial port " + serPort + " opened  Baudrate " + str(baudRate))
print("/           /c#004400GREEN /c#7E0000RED/c#000D7DBLUE /f9/c#004400/.GREEN /c#7E0000/bRED/c#000D7DBLUE /c#7E0000/bRED/c#000D7DBLUE/c#000000..")
text_file = open("/home/pi/Desktop/SerPython/read_it.txt", "r")
text_file.seek(0)
print(text_file.read())
#print ("Output of Read function is ")
print (text_file.read()) 
print

text_file.seek(0)  
  
#print ("Output of Readline function is ")
print (text_file.readline()) 
print

text_file.seek(0) 
  
print ("Output of Readline(9) function is ")
print (text_file.readline(9))

text_file.seek(0) 
# readlines function 
print ("Output of Readlines function is ")
print (text_file.readlines()) 
print
ser.write("This is my second arduino message\n")

text_file.close()

You can interface Python with Arduinos more easily and reliably using the compatible libraries: pySerialTransfer and SerialTransfer.h.

pySerialTransfer is pip-installable and cross-platform compatible. SerialTransfer.h runs on the Arduino platform and can be installed through the Arduino IDE's Libraries Manager.

Both of these libraries have highly efficient and robust packetizing/parsing algorithms with easy to use APIs.

Example Python Script:

from time import sleep
from pySerialTransfer import pySerialTransfer as txfer

if __name__ == '__main__':
    try:
        link = txfer.SerialTransfer('COM13')
        
        link.open()
        sleep(2) # allow some time for the Arduino to completely reset
    
        link.txBuff[0] = 'h'
        link.txBuff[1] = 'i'
        link.txBuff[2] = '\n'
        
        link.send(3)
        
        while not link.available():
            if link.status < 0:
                print('ERROR: {}'.format(link.status))
            
        print('Response received:')
        
        response = ''
        for index in range(link.bytesRead):
            response += chr(link.rxBuff[index])
        
        print(response)
        link.close()
        
    except KeyboardInterrupt:
        link.close()

Example Arduino Sketch:

#include "SerialTransfer.h"

SerialTransfer myTransfer;

void setup()
{
  Serial.begin(115200);
  Serial1.begin(115200);
  myTransfer.begin(Serial1);
}

void loop()
{
  myTransfer.txBuff[0] = 'h';
  myTransfer.txBuff[1] = 'i';
  myTransfer.txBuff[2] = '\n';
  
  myTransfer.sendData(3);
  delay(100);

  if(myTransfer.available())
  {
    Serial.println("New Data");
    for(byte i = 0; i < myTransfer.bytesRead; i++)
      Serial.write(myTransfer.rxBuff[i]);
    Serial.println();
  }
  else if(myTransfer.status < 0)
  {
    Serial.print("ERROR: ");
    Serial.println(myTransfer.status);
  }
}

Use the example code above to add the transfer functionality to the Python snippet that successfully reads from the text file. Then update the Arduino code. After that, you should be good to go!

Also, when reading files in Python, use "with open()" blocks to make things easier for you.

Thankyou, giving this a go I,m on the examples getting...

'Serial1' was not declared in this scope

???

Because you're not using an Arduino with multiple hardware serial ports. Check out the examples for software serial ports.

I want to send data from the pi to the uno only so is it the tx_simple or rx_simple example I should be using ??
and is the python script going to be the same for either as you sent above ??
Thanks

Not to sound mean, but you have to use your head at least a little - examples are meant to show what you can do in general, but not what exactly to do for your specific project. The library does a lot for you, but you still need to configure and use it properly based on how your system is designed. For instance:

  • The Python's serial port needs to be changed to whatever port you will be communicating on. 'COM13' may not work for your specific project but can be easily changed
  • The Arduino code assumes you're using a board with multiple hardware serial ports with a USB to TTL converter connected to Serial1. Again, this may not work for your specific project. If you simply want to use the Arduino's builtin USB, use 'Serial' instead and it will work just fine
  • Use the RX examples as a reference for the portion of the code that is expected to receive data and the TX examples as a reference for the portion of the code that is expected to transmit data

Again, it's really up to you and how your project is designed. For your case, you can use the Arduino code I originally posted, just using 'Serial' whenever 'Serial1' was mentioned. I hope that makes sense.

this is the code now on my uno which compiles..

#include "SerialTransfer.h"

SerialTransfer myTransfer;

void setup()
{
  Serial.begin(115200);
//  Serial1.begin(115200);
  myTransfer.begin(Serial);
}

void loop()
{
  if(myTransfer.available())
  {
    Serial.println("New Data");
    for(byte i = 0; i < myTransfer.bytesRead; i++)
      Serial.write(myTransfer.rxBuff[i]);
    Serial.println();
  }
  else if(myTransfer.status < 0)
  {
    Serial.print("ERROR: ");
    Serial.println(myTransfer.status);
  }
}

I cant get this to work, heres the python code

from time import sleep
from pySerialTransfer import pySerialTransfer as txfer

if __name__ == '__main__':
    try:
        link = txfer.SerialTransfer('/dev/ttyUSB0')
#        serPort = "/dev/ttyUSB0"
#baudRate = 9600
        
        link.open()
        sleep(2) # allow some time for the Arduino to completely reset
    
        link.txBuff[0] = 'h'
        link.txBuff[1] = 'i'
        link.txBuff[2] = '\n'
        
        link.send(3)
        
        while not link.available():
            if link.status < 0:
                print('ERROR: {}'.format(link.status))
            
        print('Response received:')
        
        response = ''
        for index in range(link.bytesRead):
            response += chr(link.rxBuff[index])
        
        print(response)
        link.close()
        
    except KeyboardInterrupt:
        link.close()

and here is the output from it let me know your thoughts thanks..

%Run pySerialTransfer.py
Traceback (most recent call last):
File "/home/pi/Downloads/pySerialTransfer.py", line 2, in
from pySerialTransfer import pySerialTransfer as txfer
File "/home/pi/Downloads/pySerialTransfer.py", line 2, in
from pySerialTransfer import pySerialTransfer as txfer
ImportError: cannot import name 'pySerialTransfer' from 'pySerialTransfer' (/home/pi/Downloads/pySerialTransfer.py)