Python Forum

Full Version: Creating csv header from user-input list
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I'm writing a script to read signals from a 32-channel pressure scanner via an Arduino. The basic operation is that the user will input a list defining the scanner's ports he/she is going to use, then specify the duration the test should run (how long will it collect data). After that, the program will send an address to the scanner via digital pins 2 through 7 on the Arduino that represent the port address in binary (eg 000000 for port 1, addressed as port 0, and 111110 for port 32, addressed as port 31).

Currently the output reads in the format [elapsed time, port #, signal], then it goes to the next port in a new line. I'd like to configure this to write to a csv in which the first row is the port numbers as identified by the user, and all subsequent rows are the signals for each port at a given elapsed time. For example:
time, 1, 2, 3, 4, 5
0.1, 0, 128, 256, 512, 1024
0.2, 128, 256, 512, 1024, 0
etc

Would anyone be able to help me configure this?

Here's the code. It doesn't have anything to do with csv stuff right now.
from pyfirmata import Arduino, util
import time

comport = 'COM13'
sleep = 0.025

board = Arduino(comport)
a0 = board.get_pin('a:0:i')
a0.enable_reporting()

it = util.Iterator(board)
it.start()
time.sleep(0.025)

print('Enter the port numbers you are using, separated only by spaces:')
ports = [int(x) for x in input().split()]
print('For how long do you want to take data? Enter the time in seconds:')
duration = input()
duration = int(duration)

print ('The ports used in this test are ' + str(ports))
print ('The test will run for ' + str(duration) + ' seconds')
print ('Continue? y/n')

condition = input()

length = len(ports)

for j in range(length):
    ports[j] = int(ports[j])-1
    

if condition=='y':
    start = time.time()
    current = 0

    while current < duration:
        for i in range(length):
            value = str(bin(ports[i])[2:].zfill(6))
            newval = list(value)
            newval.reverse()
            board.digital[2].write(int(newval[0]))
            board.digital[3].write(int(newval[1]))
            board.digital[4].write(int(newval[2]))
            board.digital[5].write(int(newval[3]))
            board.digital[6].write(int(newval[4]))
            board.digital[7].write(int(newval[5]))
            analogval = a0.read()
            analogval = analogval*1024
            current = time.time()-start
            print("%.4f" % current, ports[i], analogval)
            time.sleep(sleep)

else:
    print('Please run the script again, and check all setup parameters carefully before entering')
    quit
Here's what the output currently looks like:
Output:
Enter the port numbers you are using, separated only by spaces: 1 2 3 4 5 6 7 For how long do you want to take data? Enter the time in seconds: 1 The ports used in this test are [1, 2, 3, 4, 5, 6, 7] The test will run for 1 seconds Continue? y/n y 0.0020 0 532.48 0.0271 1 532.48 0.0521 2 541.4912 0.0820 3 541.4912 0.1109 4 541.4912 0.1400 5 523.4688 0.1693 6 533.504 0.1993 0 531.5584
I'm also seeing I'll have to adjust the ports so it prints out starting at 1 instead of 0. That should be an easy fix that I didn't catch until typing that out just now.
the header record is just a text record with the same number of fields as the data.
The delimiter must be the same (normally ',', but other character can be used (so long as accounted for when reading later))
each line must be terminated with a newline ('\n')
you can write simply as text, example (untested):

def write_header(fp):
    fp.write(f"'time','port','signal'\n")

def write_data(time, port, signal):
    fp.write(f"{time},{port},{signal}\n"

def main():
   with open('myfile.csv', 'w') as fp:
       write_header(fp)
       ... gather data ...
       for time, port, signal in data:
           write_data(time, port, signal)


[/python]
Thanks for the help. With that I have the data going in a .csv file with a name of my choosing. I was thinking it was still an incorrect format, but after thinking about it, since the ports are being addressed sequentially (each signal has a different time stamp), it won't make any sense to have the format I was discussing earlier (one line of data from each port on the same time stamp). I'll be able to parse this file and analyze the data as it is.

I may be back here with more later, but for now I can proceed!

Many thanks.