Go Down

Topic: Python read file and write to arduino (Read 1 time) previous topic - next topic

Northof49

Nov 23, 2018, 04:43 pm Last Edit: Nov 23, 2018, 05:12 pm by Northof49
I am trying to come up with a variation on Robin's python Arduino example, where instead of it reading data from within the file, it reads data from an outside file.


I have it working, but it doesn't seem to read any data back from the Arduino.  Can anyone help me out?  I am sure I have messed up something in the While... If

It reads each of the five lines of the text file that contains the same data as in Robin's example, and sends them to the Arduino, but it doesn't seem to read anything coming back from the Arduino.

My goal is to be able to have the python program wait for an <ok> to come back from the Arduino, before it sends another line from the text file back to the Arduino, and to display what communication comes back from the Arduino.

Code: [Select]

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

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 'Ok' - 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 ()
        
#======================================


import serial
import time

print ()
print ()

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

startMarker = 60
endMarker = 62

file = open('test.txt')
waitForArduino()

waitingForReply = False

while 1:
    waitingForReply = False
    line = file.readline()
    if not line:
       break
    if waitingForReply == False:
        ser.write(str.encode(line))
        print ("reading and writing line  " +  line)
        waitingForReply == True

    if waitingForReply == True:
        print ("waiting for reply")
        while ser.inWaiting() == 0:
            pass
        
        dataRecvd = recvFromArduino()
        print ("Reply Received  " + dataRecvd)
        waitingForReply = False

        print ("===========")
        time.sleep(5)

      
      
file.close
print ('file closed')

ser.close
print ('serial closed')

Robin2

I am trying to come up with a variation on Robin's python Arduino example, where instead of it reading data from within the file, it reads data from an outside file.
Can you please identify the exact changes that you have made to my program code.

My brain is not switched to Python at the moment and if this is complex I'm not going to be able to help.

...R

Two or three hours spent thinking and reading documentation solves most programming problems.

Northof49

#2
Nov 23, 2018, 06:48 pm Last Edit: Nov 23, 2018, 07:28 pm by Northof49
I eliminated runTest(td)

Code: [Select]
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)



and instead substituted in the code in the main part of the program:


Code: [Select]
while 1:
   
    line = file.readline()
    if not line:
       break
   
    if waitingForReply == False:
        ser.write(str.encode(line))
        print ("reading and writing line  " +  line)
        waitingForReply == True

    if waitingForReply == True:
        print ("waiting for reply")
        while ser.inWaiting() == 0:
            pass
       
        dataRecvd = recvFromArduino()
        print ("Reply Received  " + dataRecvd)
        waitingForReply = False

        print ("===========")
        time.sleep(5)


In the text file I placed:

Code: [Select]
<LED1,200,0.2>
<LED1,800,0.7>
<LED2,800,0.5>
<LED2,200,0.2>
<LED1,200,0.7>


being the same data that you called td

It works, serves up the text file one line at a time, but it doesn't receive and print any data returned from the Arduino.

It's likely something I've done wrong with the receive data from Arduino.  I call up the same unchanged functions, other than eliminating runTest(td).

For some reason the

if waiting for reply == true


Code: [Select]
if waitingForReply == True:
        print ("waiting for reply")
        while ser.inWaiting() == 0:
            pass


Never becomes True.  

It never prints "Waiting for reply", so its obviously never accessing that part of the if.

Robin2

Please post the complete program. It is too difficult to make sense of snippets - and the problem is often in the place you are not looking.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Northof49

Complete code:

Code: [Select]
#======================================

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 'Ok' - 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 ()
       
#======================================


import serial
import time

print ()
print ()

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

startMarker = 60
endMarker = 62

file = open('test.txt')
waitForArduino()
waitingForReply = False

while 1:
   
    line = file.readline()
    if not line:
       break
   
    if waitingForReply == False:
       ser.write(str.encode(line))
       print ("reading file and writing line to arduino  " +  line)
       waitingForReply == True
       
    if waitingForReply == True:
       print ("waiting for reply")
       while ser.inWaiting() == 0:
           pass
       
       dataRecvd = recvFromArduino()
       print ("Reply Received  " + dataRecvd)
       waitingForReply = False

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

    time.sleep(5)

     
     
file.close
print ('file closed')
print
ser.close
print ('serial closed')

Northof49

Here is the output that I get:



Serial port COM6 opened  Baudrate 9600
Arduino is ready

reading file and writing line to arduino  <LED1,200,0.2>

reading file and writing line to arduino  <LED1,800,0.7>

reading file and writing line to arduino  <LED2,800,0.5>

reading file and writing line to arduino  <LED2,200,0.2>

reading file and writing line to arduino  <LED1,200,0.7>
file closed
serial closed
>>>

Northof49

#6
Nov 23, 2018, 09:20 pm Last Edit: Nov 23, 2018, 09:40 pm by Northof49
 :o
Crap, embarrassing error.  I wrote

 waitingForReply == true

when I should have written

 waitingForReply = true

Funny that python lets something like that go unnoticed.


changed it and it now works!

Complete code corrected:

Code: [Select]

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

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 'Ok' - 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 ()
        
#======================================


import serial
import time

print ()
print ()

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

startMarker = 60
endMarker = 62

file = open('test.txt')
waitForArduino()
waitingForReply = False  

while 1:
    
    line = file.readline()
    if not line:
       break
    
    if waitingForReply == False:
       waitingForReply = True
       ser.write(str.encode(line))
       print ("reading file and writing line to arduino  " +  line)
      
      
    if waitingForReply == True:
       print ("waiting for reply")
       while ser.inWaiting() == 0:
           pass
        
       dataRecvd = recvFromArduino()
       print ("Reply Received  " + dataRecvd)
       waitingForReply = False

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

    time.sleep(5)

      
      
file.close
print ('file closed')
print
ser.close
print ('serial closed')

Go Up