0
votes

My python code does not seem to be receiving the first line of serial data from my Arduino. With the same commands sent through the Arduino's Serial Monitor, I can have all the same data points printed on screen, in the correct order. But when I switch to python, I can get all the data except the very first line. As a temporary workaround, I'm now sending the original first line of data as the last line of data from the arduino to python. My python code is then able to read that missing data as long as it's not the leading line. It's strange. Here's a snippet of the python code that is handling the serial exchange:

def get_data(messageHeader, val):
"""sends and receives arduino data

Arguments:
    messageHeader {str} -- determines which command to upload
    val {str} -- value of input data to upload
"""
header = str(messageHeader)
value = str(val)

if header == "a":
    command = "<" + header + ", " + value + ">"
    print(command)
    ser.write(command.encode())
    if ser.readline():
        time.sleep(0.5)
        for x in range(0, numPoints):
            data = ser.readline().decode('ascii')
            dataList[x] = data.strip('\r\n')
            print("AU: " + str(x) + ": " + dataList[x])
        print(dataList)
else:
    print("Invalid Command")

I send the command "a" through my python terminal when I want to retrieve serial data from the arduino because it matches a temporary command built into the arudino code.

Here's some of the arduino code:

void loop() 
{
  recvWithStartEndMarkers();
  checkForSerialMessage();
}

void checkForSerialMessage()
{
  if (newData == true) 
  {
    strcpy(tempBytes, receivedBytes);
    // this temporary copy is necessary to protect the original data
    //   because strtok() replaces the commas with \0
    parseData();
    showParsedData();
    newData = false;
    if (messageFromPC[0] == 'a')
    {
        ledState = !ledState;
        bitWrite(PORTB, 7, ledState);

        for(int i = 0; i < 6; i++)
        {
          Serial.println(threshold_longVals[i]);
        }

        for(int i = 0; i < 9; i++)
        {
          Serial.println(threshold_intVals[i]);  
        }

        Serial.println(threshold_floatVal);
        Serial.println(threshold_longVals[0]);
    }
   }
}

When "a" is sent through the Arduino's Serial Monitor, I receive all the threshold_long/int/floatVals in the correct order. You'll notice that at the bottom of the arduino code, I added an additional line to print threshold_longVals[0] again because, for some unknown reason to me, data printed on screen from the python side starts with threshold_longVals[1]. I'm struggling to understand why it isn't beginning with threshold_longVals[0]?

Thanks.

1

1 Answers

2
votes
if ser.readline():

Here you are reading the first line but are discarding it immediately.

You need to store it in a variable and then use it appropriately:

first_line = ser.readline()
if first_line:
    # do something with first_line