Home > Enterprise >  How to write Arduino sensor data in a csv file vertically from top to bottom?
How to write Arduino sensor data in a csv file vertically from top to bottom?

Time:03-03

I am trying to save Arduino sensor data that I receive via serial communication. I tried CSV writer and I had partial success. It did what I wanted but it saved data in a single row rather than storing them in columns. I tried writerow and writerows as well both did not work as I wanted. How can I solve this problem?

I also had one more issue, is there a way of displaying this data in Tkinter in real time? I tried treeview but it did not work.

Here is my code

def arduino_read_serialdata():
    global ser
    ser = serial.Serial('COM4', 9800, timeout=1)
    time.sleep(0.9)
    ser.flushInput() 
    while True:
            global analog_voltage, Voltage, Temperature, Current, yp
            incoming_data = ser.inWaiting()
            incoming_data = ser.readline()
            incoming_data = incoming_data.decode()
            cleaned_data = incoming_data.strip("/n")
            data_to_sort.append(cleaned_data)
            time.sleep(1)
     
            for everyrow in data_to_sort:
               if everyrow.startswith("Measuring voltage and current with INA219 ..."):
                   pass
               
               elif everyrow.startswith("MAX31855 test"):
                   pass
               
               elif everyrow.startswith("Initializing sensor...DONE checking reading the values now."):
                   pass
               
               elif everyrow.startswith("The Analog Voltage is:"):
                   anvol = everyrow[-8:]
                   analog_voltage.append(float(anvol))
               
               
               elif everyrow.startswith("Bus Voltage............:"):
                   vol = everyrow[-8:]
                   Voltage.append(float(vol))
               
               elif everyrow.startswith("Current..............:"):
                   cur = everyrow[-8:]
                   Current.append(float(cur))
               
               elif everyrow.startswith("Temperature in celcius:"):
                   temp = everyrow[-7:]
                   Temperature.append(float(temp))
               else:
                   pass
            with open("Sensor_data.csv", 'w ', newline='') as output_file:   
                output_file.flush()
                output_file = csv.writer(output_file)    
                fields = ['Analog Voltage V', 'Voltage V', 'Current mA', 'Temperature °C']        
                output_file.writerow(fields)
                output_file.writerow([analog_voltage,Voltage, Current,Temperature])    
            
        
            if keyboard.is_pressed("q"):
                    print("Manually interrupted by user")
                    ser.close()
                    print("Serial port closed")
                    break

My data looks like this But I want it in columns vertically from top to bottom

CodePudding user response:

I'm assuming that all arrays have the same amount of items. Then iterate over one of them, e.g. range(0, len(analog_voltage)) and access each item in the lists individually by their index.

for idx in range(0, len(analog_voltage)):
    output_file.writerow([analog_voltage[idx],Voltage[idx], Current[idx],Temperature[idx]])

Just some thoughts:

It would certainly be faster if the Arduino would just send the data without all the human readable information. I also think that the Arduino would always process the data in the same order and could send the data in CSV format already. This would probably simplify both the Arduino program and the Python program.

CodePudding user response:

I would recommend you open your output file before the while loop and keep it open. That way you can write a row at a time. It also avoids you writing multiple headers to the file.

Try the following kind of approach:

def arduino_read_serialdata():
    global ser
    ser = serial.Serial('COM4', 9800, timeout=1)
    time.sleep(0.9)
    ser.flushInput() 

    with open("Sensor_data.csv", 'w', newline='') as f_output:
        csv_output = csv.writer(f_output)    
        csv_output.writerow(['Analog Voltage V', 'Voltage V', 'Current mA', 'Temperature °C'])

        while True:
            incoming_data = ser.inWaiting()
            incoming_data = ser.readline()
            incoming_data = incoming_data.decode()
            cleaned_data = incoming_data.strip("/n")
            data_to_sort.append(cleaned_data)
            time.sleep(1)
     
            # Defaults if value missing
            anvol = ''
            vol = ''
            cur = ''
            temp = ''
            
            for everyrow in data_to_sort:
               if everyrow.startswith("The Analog Voltage is:"):
                   anvol = everyrow[-8:].strip()
               elif everyrow.startswith("Bus Voltage............:"):
                   vol = everyrow[-8:].strip()
               elif everyrow.startswith("Current..............:"):
                   cur = everyrow[-8:].strip()
               elif everyrow.startswith("Temperature in celcius:"):
                   temp = everyrow[-7:].strip()
        
            csv_output.writerow([anvol, vol, cur, temp])
    
            if keyboard.is_pressed("q"):
                print("Manually interrupted by user")
                ser.close()
                print("Serial port closed")
                break

You could also add a timestamp to the output filename if needed so you don't overwrite previous sessions.

Note: not tested as I don't have a suitable environment

  • Related