简体   繁体   中英

Python Serial and CSV for Arduino

I'm trying to write a code to read value from Arduino Uno every 2ms. At the Arduino end here is the code and what it will send every 2ms.

Serial.print(AngleV);
Serial.print(",");   
Serial.print(AngleH);
Serial.print(",");
Serial.println(distance);

whereas the AngleV value is from 0-180,AngleH value is from 0-3600,distance value is from 0-4000.

At the pc end, I want to read all 3 value in, then do some calculation and write it to the csv file:

x = distance * sin(AngleV)*cos(AngleH)
y = distance * cos(AngleV)*sin(AngleH)
z = distance * cos(AngleV)

So in the .csv file it will be something like x,y,z.... So far this is what I have done.Can any one point me to what to do next? Thank you for your time.

 import serial
    import csv

    # open com port
    ser = serial.Serial('COM4', 115200)
    print (ser.name)

    # create csv file
    with open('C:/Users/sylan/Desktop/Python/datafile.csv', 'w') as new_file:
        csv_writer = csv.writer(new_file)

        while True:
            line = ser.readline()
            print(line)
            if line[0] == "B":
                line = line[1:len(line)]

            if line[len(line)-2] == "E":
                line = line[:(len(line)-2)]
                csv_writer.writerow([line])

                print('\n\nThis is the end of the file\n')
                ser.close()
                break
            else:
                line = line[:(len(line)-1)]
                csv_writer.writerow([line])

I will assume two approaches, depending on the format that is being sent by the Arduino board.

  1. The first line starts with a B, and the last line ends with an E.
  2. Each line starts with a B and ends with an E.

Approach 1

In this case, we rely on seeing the letter "E" to know when to stop reading from the file.

import csv
import serial

# Open com port
ser = serial.Serial('COM4', 115200)

with open("datafile.csv", "w") as new_file:
    csv_writer = csv.writer(new_file)

    while True:
        # Strip whitespace on the left and right side
        # of the line
        line = ser.readline().strip()

        # If line starts with B, strip the B
        if line.startswith("B"):
            line = line[1:]

        # If the line ends with E, we reached the last line
        # We strip the E, and keep in mind that the serial
        # reader should be closed
        should_close = False
        if line.endswith("E"):
            line = line[:-1]
            should_close = True

        # Split the string "180,3600,1234" into a list ["180", "3600", "1234"]
        xyz_string_triplet = line.split(",")
        if len(xyz_string_triplet) != 3:
            print("Ignored invalid line: " + line)
            continue

        # Convert the numbers from string format to integer
        x = int(xyz_string_triplet[0])
        y = int(xyz_string_triplet[1])
        z = int(xyz_string_triplet[2])

        # Write XYZ to the CSV file
        csv_writer.writerow([x, y, z])

        # If we reached the last line, we close
        # the serial port and stop the loop
        if should_close:
            ser.close()
            break

Approach 2

In this case, since all the lines end with E, we don't have any way to know when to stop processing the lines. For this reason, we choose arbitrarily to stop reading after 10 lines.

import csv
import serial

# Open com port
ser = serial.Serial('COM4', 115200)

with open("datafile.csv", "w") as new_file:
    csv_writer = csv.writer(new_file)

    line_count = 0
    while True:
        # Strip whitespace on the left and right side
        # of the line
        line = ser.readline().strip()

        # Check whether line starts with a B and ends
        # with an E, and ignore it otherwise
        is_valid = line.startswith("B") and line.endswith("E")
        if not is_valid:
            print("Ignored invalid line: " + line)
            continue

        # Strip B and E
        xyz_line = line[1:-1]

        # Split the string "180,3600,1234" into a list ["180", "3600", "1234"]
        xyz_string_triplet = xyz_line.split(",")
        if len(xyz_string_triplet) != 3:
            print("Ignored invalid XYZ line: " + xyz_line)
            continue

        # Convert the numbers from string format to integer
        x = int(xyz_string_triplet[0])
        y = int(xyz_string_triplet[1])
        z = int(xyz_string_triplet[2])

        # Write XYZ to the CSV file
        csv_writer.writerow([x, y, z])

        # Increment the line count, and stop the loop
        # once we have 10 lines
        line_count += 1
        if line_count >= 10:
            break
import csv
import serial
import math
import time
# Open com port
ser = serial.Serial('COM4', 115200)
print('Serial Port is open : ' + ser.name)
with open("datafile.csv", "w") as new_file:
    csv_writer = csv.writer(new_file)
    time.sleep(3)
    ser.write(b'B')

    while ser.is_open:
            line = ser.readline()
            print(line)

            # If line starts with B, strip the B
            if line[0] == "B":
                line = line[1:len(line)]

            # If the line ends with E, we reached the last line
            # We strip the E, and keep in mind that the serial
            # reader should be closed
            if line[len(line)-2]=="E":
                line = line[:(len(line)-2)]
                v,h,d=line.split(",")
                polar = float(v)
                azimuthal = float(h)
                distance = float(d)
                x=float(distance*math.sin(polar)*math.cos(azimuthal))
                y=float(distance*math.sin(polar)*math.sin(azimuthal))
                z=float(distance*math.cos(polar))
                # Write XYZ to the CSV file
                csv_writer.writerow([x, y, z,distance])
                print('\nThis is the end of the file\n')
                ser.close()
                break
            else:
                line = line[:(len(line)-1)]
                v,h,d=line.split(",")
                if len(v)>3 or len(h)>4 or len(d)>4:
                    print('Ignored invalid line: ')
                    continue
                # Convert the numbers from string format to integer
                polar = float(v)
                azimuthal = float(h)
                distance = float(d)
                x=float(distance*math.sin(polar)*math.cos(azimuthal))
                y=float(distance*math.sin(polar)*math.sin(azimuthal))
                z=float(distance*math.cos(polar))
                # Write XYZ to the CSV file
                csv_writer.writerow([x, y, z,distance])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM