evenjc

Raspberry Pi - Master Node

Apr 5th, 2019
792
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.04 KB | None | 0 0
  1. #!/usr/bin/env python
  2. #-*- coding: utf-8 -*-
  3.  
  4.  
  5. # Importing modules
  6. import serial
  7. import time
  8. import datetime
  9.  
  10. # Definition of UNIX shell colors
  11. class bcolors:
  12.     HEADER = '\033[95m'
  13.     OKBLUE = '\033[94m'
  14.     OKGREEN = '\033[93m'
  15.     TEST = '\033[92m'
  16.     ENDC = '\033[0m'
  17.     RED = '\033[91m'
  18.  
  19.  
  20. # Holder for active serial ports
  21. serialPorts = []
  22.  
  23. # Populated by the Ardunios by either "TIL" or "PUST"
  24. # This decides the name of the logfile for this arduino.
  25. typeOfSensorNode = []
  26.  
  27. # Header info for all the files
  28. # Should look like headerInfo = ["CO2;HUMIDITY", "TEMPERATURE"]
  29. headerInfo = []
  30.  
  31. # Holder for generated files
  32. filenames = []
  33. files = []
  34.  
  35. # messages[0] = '1' is used to ask the Arduino's for sensor data
  36. # messages[1] = '2' is used for probing each active serial port and checking for an answer 'PUST' or 'TIL'
  37. messages = ['1', '2', '3']
  38.  
  39. # Time between each sensor log.
  40. # Change this if you want to alter the frequency of data transfers.
  41. timeBetweenDataTransfers = 2
  42.  
  43. # Number of connected devices.
  44. # Change if you want to add more or less sensor nodes.
  45. numberOfArduinoDevices = 2
  46.  
  47. # Serial Connection settings.
  48. # Do not change.
  49. baudrate = 9600
  50. parity = serial.PARITY_NONE
  51. stopbits = serial.STOPBITS_ONE
  52. bytesize = serial.EIGHTBITS
  53. timeout = 1
  54.  
  55. # Routine that probes the first 100 possible Arduino-COMs.
  56. # This routine populates serialPorts.
  57. def establishSerialConnections():
  58.     counter = 0
  59.     print(bcolors.OKGREEN + "\n--- Establishing serial connections ---" + bcolors.ENDC)
  60.     while (counter < 100):
  61.         try:
  62.             ser = serial.Serial(
  63.                 port= "/dev/ttyACM" + counter.__str__(),
  64.                 baudrate = baudrate,
  65.                 parity = parity,
  66.                 stopbits = stopbits,
  67.                 bytesize = bytesize,
  68.                 timeout = 1
  69.             )
  70.             serialPorts.append(ser)
  71.             ser.close()
  72.             ser.open()
  73.             print ("Found open device at /dev/ttyACM" + counter.__str__())
  74.            
  75.         except IOError:
  76.             None
  77.        
  78.         counter += 1
  79.     if len(serialPorts) < numberOfArduinoDevices:
  80.         raw_input(bcolors.RED + "To few devices found, are you sure they are connected? \nPress enter to quit." + bcolors.ENDC)
  81.         exit()
  82.     elif len(serialPorts) > numberOfArduinoDevices:
  83.         rawinput(bcolors.RED + "To many devices found, did you forget to adjust the numberOfArduinoDevices variable?" + bcolors.ENDC)
  84.         exit()
  85.     print(bcolors.OKGREEN + "--- Serial connections established --- \n\n" + bcolors.ENDC)
  86.    
  87. # Routine checking what type of sensorNode we found.
  88. # This routine populates typeOfSensoNodes.
  89. # It is also detrimental to ensure established connection.
  90. # If the number of established connections is not the number of expected Arduinos, the program will shut down.
  91. def checkDeviceConnectivity():
  92.     print(bcolors.OKGREEN + "--- Checking if devices are sensor nodes ---" + bcolors.ENDC)
  93.     establishedConnections = 0
  94.     for portNumber in range(0, numberOfArduinoDevices):
  95.         print ('Writing to Arduino at ' + serialPorts[portNumber].write(messages[1]).__str__())
  96.         recievedData = serialPorts[portNumber].readline()
  97.                
  98.         print("First package from Arduino is: " + recievedData)
  99.         if (recievedData == "HELLO"):
  100.             print ('We found a sensor node')
  101.             # typeOfSensorNode.append(recievedData)
  102.             establishedConnections += 1
  103.        
  104.     print(bcolors.OKGREEN + "--- Done checking if devices are sensor nodes --- \n\n" + bcolors.ENDC)
  105.     if (establishedConnections == numberOfArduinoDevices):
  106.         return True
  107.     else:
  108.         return False
  109.  
  110. # Routine generating filenames, using typeOfSensorNode.
  111. # File names are hard coded to /home/pi/Desktop/log/filename.csv.
  112. # Each file is named with millisecond precision, meaning files will never generate the same names.
  113. def generateFileNames():
  114.     for device in range(0, numberOfArduinoDevices):
  115.         filenames.append("/home/pi/Desktop/log/"+typeOfSensorNode[device].__str__()+'_Arduino_nr_'+device.__str__()+'_'+datetime.datetime.now().__str__()+'.csv')
  116.         print ("Created file: " + filenames[device].__str__())
  117.  
  118.  
  119. # Routine for gathering information on what sensors this node is logging
  120. def defineSensorNodes():
  121.     x = 0
  122.     for portNumber in range(0, numberOfArduinoDevices):
  123.         print('Asking Arduino at ' + serialPorts[portNumber].port.__str__() + ' for sensor types')
  124.         serialPorts[portNumber].write(messages[2])
  125.        
  126.         recievedData = serialPorts[portNumber].readline()
  127.         elements = recievedData.split('\t')
  128.         counter = 0
  129.         headerInfo.append('')
  130.         for item in elements:
  131.             if counter is 0:
  132.                 typeOfSensorNode.append(item)
  133.             else:
  134.                 headerInfo[x] = headerInfo[x] + item.__str__() + ';'
  135.             counter = counter + 1
  136.         x = x + 1
  137.         # read line from serial port. Should be a string of "sensor types"
  138.         # e.g. "temp    humidity    co2"
  139.         # this info is then used to generate measurement files with a corresponding header
  140.        
  141. # Routine creating actual measurement files and fills in first two rows.
  142. def createMeasurementFiles():
  143.     print(bcolors.OKGREEN + "--- Generating measurement files ---" + bcolors.ENDC)
  144.     generateFileNames()
  145.     counter = 0
  146.     for device in range(0, numberOfArduinoDevices):
  147.         files.append(open(filenames[device], "w+"))
  148.         #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')
  149.         files[device].write('Date;Time;' + headerInfo[counter])
  150.         files[device].write("\r\n")
  151.         #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')
  152.         #files[device].write("\r\n")
  153.         files[device].close()
  154.         counter = counter + 1
  155.     print(bcolors.OKGREEN + "--- Done generating measurement files --- \n\n" + bcolors.ENDC)
  156.  
  157.  
  158. # Function for reading from the nodes.
  159. # All write functionality here should at a later point be written in a writeToFile-routine.
  160. def readFromArduino_writeToFile():
  161.     for device in range(0, numberOfArduinoDevices):
  162.         print ('Reading from Arduino at ' + serialPorts[device].port.__str__())
  163.         recievedData = serialPorts[device].readline()
  164.         #print ("Recieved: " + recievedData.__str__())
  165.         if (recievedData != None):
  166.             print ('Read successfully from ' + serialPorts[device].port.__str__())
  167.         else:
  168.             print ('Failed')
  169.         files[device] = open(filenames[device], "a")
  170.         files[device].write(datetime.datetime.now().date().__str__() + ";" + datetime.datetime.now().time().__str__() + ";")
  171.         #files[device].write(";")
  172.         #files[device].write(datetime.datetime.now().time().__str__())
  173.         #files[device].write(";")
  174.         files[device].write(recievedData)
  175.         files[device].write("\r\n")
  176.         files[device].close()
  177.  
  178. # Routine for writing a message to all the sensor nodes.    
  179. def writeToArduino(message):
  180.     for device in range(0, numberOfArduinoDevices):
  181.         serialPorts[device].write(message)
  182.  
  183. # Brute force connection establisher for odd cases where Arduino wont respond
  184. def bruteForceWrite(message):
  185.     foundDevices = 0
  186.     counter = 0
  187.     for ports in serialPorts:
  188.         print(bcolors.OKGREEN + "\n--- Probing " + ports.name + " ---" + bcolors.ENDC)
  189.         ports.write(message)
  190.         recievedData = ports.readline()
  191.         if recievedData == "HELLO":
  192.             foundDevices += 1
  193.             print ("I see an arduino")
  194.            
  195.         counter += 1
  196.         print(bcolors.OKGREEN + "--- Finished probing device ---\n\n" + bcolors.ENDC)
  197.     return foundDevices
  198.  
  199.  
  200. establishSerialConnections()
  201.  
  202. startup = True
  203.  
  204. # Force while loop to continue until numberOfArduinoDevices Arduinos responds.
  205. while startup:        
  206.     if (bruteForceWrite(messages[1]) == numberOfArduinoDevices):
  207.         startup = False
  208.  
  209. # Safety check that connection is still in place. Legacy code that may be altered.
  210. connection_established = checkDeviceConnectivity()
  211. defineSensorNodes()
  212.  
  213. print(headerInfo)
  214. createMeasurementFiles()
  215. # If connection is good, this is where the program loops.    
  216. if connection_established:
  217.     print(bcolors.HEADER + "Connection is established, going into measurement mode \n \n" + bcolors.ENDC)
  218.     while True:
  219.         print(bcolors.OKGREEN + "--- Performing measurement ---" + bcolors.ENDC)
  220.         writeToArduino(messages[0])
  221.         readFromArduino_writeToFile()
  222.         print(bcolors.OKGREEN + "--- Measurement done --- \n\n" + bcolors.ENDC)
  223.         print((bcolors.TEST + "Waiting between measurements. Press CTRL+C to exit \n\n" + bcolors.ENDC))
  224.         time.sleep(timeBetweenDataTransfers)
  225. else:
  226.     print ('Failed finding enough Arduino Devices, shutting down')
Advertisement
Add Comment
Please, Sign In to add comment