Search code examples
pythonparsingserial-portreal-timesensors

Reading Serial Port data and saving to .csv Python


I'm having success reading in and printing some Serial Port data in a python script. I'm having difficulty with what tools/functions to use to change the Serial port data into a table or continuously append to a .csv. So after spending many hours researching everything about Serial Ports and python on stack overflow and other sites I'm reaching out for a hand as I don't know what steps to take next and I can't find information that helps answer my question.

Here is my script so far:

ser = serial.Serial('com4',
                    baudrate=38400,
                    timeout=1,
                    parity=serial.PARITY_NONE,
                    stopbits=serial.STOPBITS_ONE,
                    bytesize=serial.EIGHTBITS)

while True:
    rawdata = (ser.readline().decode('ascii'))
    print(rawdata)

Ok....great we have the Sensor data printing in the console looking like this:

$PDLMA,+11.91,+20.7,-0.1,-0.4*6C

$PDLMH,134829.844,+2644.8,+81.46,+3094.7,+21.99*6F

$PDLM1,134829.844,+1824.1,+127.69,+3276.7,+36.82*26

Now here's how the data from the sensor is structured:

$PDLMH  134829.844  2644.8  81.46   3094.7  21.99   *6F
       Hhmmss.sss   HCP05   HCPI    PRP05   PRP05I  Checksum
$PDLM1  134829.844  1824.1  127.69  3727.7  36.82   *26
       Hhmmss.sss   HCP10   HCP10I  PRP10   PRP10I  Checksum
$PDLMA  11.91    20.7      -0.1     -0.4        
      Voltage  Temperature  Pitch   Roll

Now my goal is to get the final output to look like this:

Time HCP05 HCP05I PRP05 PRP05I HCP10 HCP10I PRP10 PRP10I Voltage Temp Pitch
(now) data   data  data   data  data   data  data   data    Data Data  Data

So what should I do to take the serial data and transform it to what I need above as well as continuously reading in the data? I have tried dataframes, lists, etc but clearly I'm missing something here. In the .csv output file I would expect there to be about 120000 lines of data on average in our use case.

The Newbie of the day.


Solution

  • I achieved my desired output with the following code:

     while dser.inWaiting() == 0:
                pass
            NMEA1 = dser.readline().decode("ascii")
            while dser.inWaiting() == 0:
                pass
            NMEA2 = dser.readline().decode("ascii")
            while dser.inWaiting() == 0:
                pass
            NMEA3 = dser.readline().decode("ascii")
            while dser.inWaiting() == 0:
                pass
            NMEA4 = dser.readline().decode("ascii")
            while dser.inWaiting() == 0:
                pass
            NMEA1_array = NMEA1.split(',')
            NMEA2_array = NMEA2.split(',')
            NMEA3_array = NMEA3.split(',')
            NMEA4_array = NMEA4.split(',')
            if NMEA1_array[0] == '$PDLMH':
                HCP05 = NMEA1_array[2]
                PRP05 = NMEA1_array[4]
            if NMEA1_array[0] == '$PDLM1':
                HCP10 = NMEA1_array[2]
                PRP10 = NMEA1_array[4]
            if NMEA1_array[0] == '$PDLM2':
                HCP20 = NMEA1_array[2]
                PRP20 = NMEA1_array[4]
            if NMEA1_array[0] == '$PDLMA':
                Voltage = NMEA1_array[1]
                Temperature = NMEA1_array[2]
                Pitch = NMEA1_array[3]
                Roll = NMEA1_array[4].partition("*")[0]
            if NMEA2_array[0] == '$PDLMH':
                HCP05 = NMEA2_array[2]
                PRP05 = NMEA2_array[4]
            if NMEA2_array[0] == '$PDLM1':
                HCP10 = NMEA2_array[2]
                PRP10 = NMEA2_array[4]
            if NMEA2_array[0] == '$PDLM2':
                HCP20 = NMEA2_array[2]
                PRP20 = NMEA2_array[4]
            if NMEA2_array[0] == '$PDLMA':
                Voltage = NMEA2_array[1]
                Temperature = NMEA2_array[2]
                Pitch = NMEA2_array[3]
                Roll = NMEA2_array[4].partition("*")[0]
            if NMEA3_array[0] == '$PDLMH':
                HCP05 = NMEA3_array[2]
                PRP05 = NMEA3_array[4]
            if NMEA3_array[0] == '$PDLM1':
                HCP10 = NMEA3_array[2]
                PRP10 = NMEA3_array[4]
            if NMEA3_array[0] == '$PDLM2':
                HCP20 = NMEA3_array[2]
                PRP20 = NMEA3_array[4]
            if NMEA3_array[0] == '$PDLMA':
                Voltage = NMEA3_array[1]
                Temperature = NMEA3_array[2]
                Pitch = NMEA3_array[3]
                Roll = NMEA3_array[4].partition("*")[0]
            if NMEA4_array[0] == '$PDLMH':
                HCP05 = NMEA4_array[2]
                PRP05 = NMEA4_array[4]
            if NMEA4_array[0] == '$PDLM1':
                HCP10 = NMEA4_array[2]
                PRP10 = NMEA4_array[4]
            if NMEA4_array[0] == '$PDLM2':
                HCP20 = NMEA4_array[2]
                PRP20 = NMEA4_array[4]
            if NMEA4_array[0] == '$PDLMA':
                Voltage = NMEA4_array[1]
                Temperature = NMEA4_array[2]
                Pitch = NMEA4_array[3]
                Roll = NMEA4_array[4].partition("*")[0]
            if () is not None:
                return (float(HCP05), float(PRP05), float(HCP10),
                        float(PRP10), float(HCP20), float(PRP20),
                        float(Voltage), float(Temperature), float(Pitch),
                        float(Roll))
    

    Not to sure if this is the best result but it is now working.