Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- #-*- coding: utf-8 -*-
- # Importing modules
- import serial
- import time
- import datetime
- # Definition of UNIX shell colors
- class bcolors:
- HEADER = '\033[95m'
- OKBLUE = '\033[94m'
- OKGREEN = '\033[93m'
- TEST = '\033[92m'
- ENDC = '\033[0m'
- RED = '\033[91m'
- # Holder for active serial ports
- serialPorts = []
- # Populated by the Ardunios by either "TIL" or "PUST"
- # This decides the name of the logfile for this arduino.
- typeOfSensorNode = []
- # Header info for all the files
- # Should look like headerInfo = ["CO2;HUMIDITY", "TEMPERATURE"]
- headerInfo = []
- # Holder for generated files
- filenames = []
- files = []
- # messages[0] = '1' is used to ask the Arduino's for sensor data
- # messages[1] = '2' is used for probing each active serial port and checking for an answer 'PUST' or 'TIL'
- messages = ['1', '2', '3']
- # Time between each sensor log.
- # Change this if you want to alter the frequency of data transfers.
- timeBetweenDataTransfers = 2
- # Number of connected devices.
- # Change if you want to add more or less sensor nodes.
- numberOfArduinoDevices = 2
- # Serial Connection settings.
- # Do not change.
- baudrate = 9600
- parity = serial.PARITY_NONE
- stopbits = serial.STOPBITS_ONE
- bytesize = serial.EIGHTBITS
- timeout = 1
- # Routine that probes the first 100 possible Arduino-COMs.
- # This routine populates serialPorts.
- def establishSerialConnections():
- counter = 0
- print(bcolors.OKGREEN + "\n--- Establishing serial connections ---" + bcolors.ENDC)
- while (counter < 100):
- try:
- ser = serial.Serial(
- port= "/dev/ttyACM" + counter.__str__(),
- baudrate = baudrate,
- parity = parity,
- stopbits = stopbits,
- bytesize = bytesize,
- timeout = 1
- )
- serialPorts.append(ser)
- ser.close()
- ser.open()
- print ("Found open device at /dev/ttyACM" + counter.__str__())
- except IOError:
- None
- counter += 1
- if len(serialPorts) < numberOfArduinoDevices:
- raw_input(bcolors.RED + "To few devices found, are you sure they are connected? \nPress enter to quit." + bcolors.ENDC)
- exit()
- elif len(serialPorts) > numberOfArduinoDevices:
- rawinput(bcolors.RED + "To many devices found, did you forget to adjust the numberOfArduinoDevices variable?" + bcolors.ENDC)
- exit()
- print(bcolors.OKGREEN + "--- Serial connections established --- \n\n" + bcolors.ENDC)
- # Routine checking what type of sensorNode we found.
- # This routine populates typeOfSensoNodes.
- # It is also detrimental to ensure established connection.
- # If the number of established connections is not the number of expected Arduinos, the program will shut down.
- def checkDeviceConnectivity():
- print(bcolors.OKGREEN + "--- Checking if devices are sensor nodes ---" + bcolors.ENDC)
- establishedConnections = 0
- for portNumber in range(0, numberOfArduinoDevices):
- print ('Writing to Arduino at ' + serialPorts[portNumber].write(messages[1]).__str__())
- recievedData = serialPorts[portNumber].readline()
- print("First package from Arduino is: " + recievedData)
- if (recievedData == "HELLO"):
- print ('We found a sensor node')
- # typeOfSensorNode.append(recievedData)
- establishedConnections += 1
- print(bcolors.OKGREEN + "--- Done checking if devices are sensor nodes --- \n\n" + bcolors.ENDC)
- if (establishedConnections == numberOfArduinoDevices):
- return True
- else:
- return False
- # Routine generating filenames, using typeOfSensorNode.
- # File names are hard coded to /home/pi/Desktop/log/filename.csv.
- # Each file is named with millisecond precision, meaning files will never generate the same names.
- def generateFileNames():
- for device in range(0, numberOfArduinoDevices):
- filenames.append("/home/pi/Desktop/log/"+typeOfSensorNode[device].__str__()+'_Arduino_nr_'+device.__str__()+'_'+datetime.datetime.now().__str__()+'.csv')
- print ("Created file: " + filenames[device].__str__())
- # Routine for gathering information on what sensors this node is logging
- def defineSensorNodes():
- x = 0
- for portNumber in range(0, numberOfArduinoDevices):
- print('Asking Arduino at ' + serialPorts[portNumber].port.__str__() + ' for sensor types')
- serialPorts[portNumber].write(messages[2])
- recievedData = serialPorts[portNumber].readline()
- elements = recievedData.split('\t')
- counter = 0
- headerInfo.append('')
- for item in elements:
- if counter is 0:
- typeOfSensorNode.append(item)
- else:
- headerInfo[x] = headerInfo[x] + item.__str__() + ';'
- counter = counter + 1
- x = x + 1
- # read line from serial port. Should be a string of "sensor types"
- # e.g. "temp humidity co2"
- # this info is then used to generate measurement files with a corresponding header
- # Routine creating actual measurement files and fills in first two rows.
- def createMeasurementFiles():
- print(bcolors.OKGREEN + "--- Generating measurement files ---" + bcolors.ENDC)
- generateFileNames()
- counter = 0
- for device in range(0, numberOfArduinoDevices):
- files.append(open(filenames[device], "w+"))
- #files[device].write('Date;Time;Temperature;Relative Humidity;CO2;Formaldehyde Start;Control;High bit;Low bit;Reserved;Reserved;High bit;Low bit;Checksum;PM1.0;PM2.5;PM4.0;PM10;NCPM0.5;NCPM1.0;NCPM2.5;NCPM4.0;NCPM10.0;Typical Particle Size')
- files[device].write('Date;Time;' + headerInfo[counter])
- files[device].write("\r\n")
- #files[device].write('YYYY-MM-DD;HH:MM:SS.ssssss;oC;%;ppm;255;134;µg/m3;µg/m3;0;0;ppb;ppb;Checksum[int];µg/m3;µg/m3;µg/m3;µg/m3;#/cm3;#/cm3;#/cm3;#/cm3;#/cm3;µm')
- #files[device].write("\r\n")
- files[device].close()
- counter = counter + 1
- print(bcolors.OKGREEN + "--- Done generating measurement files --- \n\n" + bcolors.ENDC)
- # Function for reading from the nodes.
- # All write functionality here should at a later point be written in a writeToFile-routine.
- def readFromArduino_writeToFile():
- for device in range(0, numberOfArduinoDevices):
- print ('Reading from Arduino at ' + serialPorts[device].port.__str__())
- recievedData = serialPorts[device].readline()
- #print ("Recieved: " + recievedData.__str__())
- if (recievedData != None):
- print ('Read successfully from ' + serialPorts[device].port.__str__())
- else:
- print ('Failed')
- files[device] = open(filenames[device], "a")
- files[device].write(datetime.datetime.now().date().__str__() + ";" + datetime.datetime.now().time().__str__() + ";")
- #files[device].write(";")
- #files[device].write(datetime.datetime.now().time().__str__())
- #files[device].write(";")
- files[device].write(recievedData)
- files[device].write("\r\n")
- files[device].close()
- # Routine for writing a message to all the sensor nodes.
- def writeToArduino(message):
- for device in range(0, numberOfArduinoDevices):
- serialPorts[device].write(message)
- # Brute force connection establisher for odd cases where Arduino wont respond
- def bruteForceWrite(message):
- foundDevices = 0
- counter = 0
- for ports in serialPorts:
- print(bcolors.OKGREEN + "\n--- Probing " + ports.name + " ---" + bcolors.ENDC)
- ports.write(message)
- recievedData = ports.readline()
- if recievedData == "HELLO":
- foundDevices += 1
- print ("I see an arduino")
- counter += 1
- print(bcolors.OKGREEN + "--- Finished probing device ---\n\n" + bcolors.ENDC)
- return foundDevices
- establishSerialConnections()
- startup = True
- # Force while loop to continue until numberOfArduinoDevices Arduinos responds.
- while startup:
- if (bruteForceWrite(messages[1]) == numberOfArduinoDevices):
- startup = False
- # Safety check that connection is still in place. Legacy code that may be altered.
- connection_established = checkDeviceConnectivity()
- defineSensorNodes()
- print(headerInfo)
- createMeasurementFiles()
- # If connection is good, this is where the program loops.
- if connection_established:
- print(bcolors.HEADER + "Connection is established, going into measurement mode \n \n" + bcolors.ENDC)
- while True:
- print(bcolors.OKGREEN + "--- Performing measurement ---" + bcolors.ENDC)
- writeToArduino(messages[0])
- readFromArduino_writeToFile()
- print(bcolors.OKGREEN + "--- Measurement done --- \n\n" + bcolors.ENDC)
- print((bcolors.TEST + "Waiting between measurements. Press CTRL+C to exit \n\n" + bcolors.ENDC))
- time.sleep(timeBetweenDataTransfers)
- else:
- print ('Failed finding enough Arduino Devices, shutting down')
Advertisement
Add Comment
Please, Sign In to add comment