def main(): board = Arduino('COM3') board.add_cmd_handler(pyfirmata.pyfirmata.STRING_DATA, on_string_received) iter = util.Iterator(board) iter.start() write_loop(board)
def main(): board = Arduino("/dev/ttyACM0") board.add_cmd_handler(pyfirmata.pyfirmata.STRING_DATA, on_string_received) iter = util.Iterator(board) iter.start() write_loop(board)
class ArduinoInterface: def __init__(self, config): self.config = config self.button_status_handler = None @staticmethod def _autodiscover_device(): device_list = ['/dev/ttyACM{}'.format(i) for i in range(10)] devices = [dev for dev in device_list if os.path.exists(dev)] return devices[0] def connect(self): device = None try: device = self.config['device'] except KeyError: device = self.__class__._autodiscover_device() self.board = Arduino(device, baudrate=57600, timeout=100) Iterator(self.board).start() self.board.add_cmd_handler(STRING_DATA, self._button_status_handler) def send_alert_update(self, alert=True): self.board.send_sysex(0x01, bytes([alert])) def request_button_status(self): self.board.send_sysex(0x02, bytes([])) def _button_status_handler(self, *string): status = None try: status = int(chr(string[0])) except ValueError: print('Empty button status received: {}'.format(string)) else: self.button_status_handler(status) def attach_button_status_handler(self, func): self.button_status_handler = func
from pyfirmata import Arduino, util import time board = Arduino('/dev/ttyUSB0') it = util.Iterator(board) it.start() print('✔ board ready!') def handle_read_write(*data): print(data[0]) board.send_sysex(0x01, [12, data[0]]) board.add_cmd_handler(0x03, handle_read_write) while True: board.send_sysex(0x03, [18]) time.sleep(0.01)
class Arduino_Interface(object): ## ## ## CONSTANTS ## ## ## ## ## PING = 0x01 TEST_DATA = 0x02 ## ## ## Initalization ## ## ## ## ## def __init__(self, port, log_handler): ## Initalize logging logging.basicConfig(level=logging.DEBUG) self.logger = logging.getLogger('Arduino_Interface') self.logger.addHandler(log_handler) # Add Tk log handler self.logger.debug('__init__') ## Board Initalization self.board = Arduino(port) self.board.add_cmd_handler(pyfirmata.START_SYSEX, self.handleIncomingSysEx) self.board.add_cmd_handler(pyfirmata.STRING_DATA, self.handleIncomingString) ## Data Buffer Initalization self.incoming_data = [] ## Callback holder self.callback_holder = dict() ## ## ## Runtime Functions ## ## ## ## ## def begin_scanning(self): self.board.iterate() ## ## ## Senders ## ## ## ## ## def ping(self, pingCallback): self.logger.debug('----Sending Ping----') ## Attach callback self.callback_holder[Arduino_Interface.PING] = pingCallback byte_array = bytearray() byte_array.append(Arduino_Interface.PING) self.sendSysEx(byte_array) def requestTestData(self, testDataCallback): self.logger.debug('----Requesting Test Data----') ## Attach callback self.callback_holder[Arduino_Interface.TEST_DATA] = testDataCallback byte_array = bytearray() byte_array.append(Arduino_Interface.TEST_DATA) self.sendSysEx(byte_array) def sendSysEx(self, byteArray): self.logger.debug('----sendSysEx----') self.logger.debug('SEND Data: {}'.format(binascii.hexlify(byteArray))) self.board.send_sysex(pyfirmata.START_SYSEX, byteArray) self.begin_scanning() def sendString(self, stringToSend): pass #self.board.send_sysex # for byte in dataArray: # self.incoming_data.append(chr(byte)) # print self.incoming_data ## ## ## Handlers ## ## ## ## ## def handleIncomingString(self, *string): self.logger.debug('handling Incoming String') ## Flush incoming_data self.incoming_data = [] for byte in string: self.incoming_data.append(chr(byte)) recieved_string = ''.join(self.incoming_data) print recieved_string def handleIncomingSysEx(self, *byteArray): self.logger.debug('----Incoming SysEx----') ## Flush incoming_data array self.incoming_data = [] self.incoming_data = self.filterSysEx(byteArray) ## Get header header = byteArray[0] self.logger.debug('header: {}'.format(header)) if (header == Arduino_Interface.PING): self.logger.debug('PING Response recieved') ## Ping response recieved. Return True self.callback_holder[Arduino_Interface.PING](True) elif (header == Arduino_Interface.TEST_DATA): self.logger.debug('Test Data recieved') self.callback_holder[Arduino_Interface.TEST_DATA](self.incoming_data) ## ## ## Utilities ## ## ## ## ## def filterSysEx(self, byteArray): self.logger.debug('filterSysEx') incoming_data = [] for idx, byte in enumerate(byteArray): if idx == 0: continue incoming_data.append(byte) self.logger.debug('SysEx Data:') self.logger.debug(incoming_data) return incoming_data
from pyfirmata import Arduino, util import time board = Arduino('/dev/ttyUSB0') it = util.Iterator(board) it.start() print('✔ board ready!') def handle_read(*data): # print(data[0]) #Get read value of array print(data) board.add_cmd_handler(0x03, handle_read) while True: board.send_sysex(0x03, [18]) time.sleep(0.01)
from pyfirmata import Arduino, util import time board = Arduino('/dev/ttyUSB0') it = util.Iterator(board) it.start() print('✔ board ready!') def handle_write(*data): print(data) board.add_cmd_handler(0x02, handle_write) def writePwmValue(pin, value): datasToWrite = [] datasToWrite.append(pin) datasToWrite.append(0) datasToWrite.append(15) datasToWrite.append(10) v = divmod(value, 127) for i in range(1, v[0]): datasToWrite.append(127) if (v[0] >= 1):
class Collector(): """ Handles the communication to arduino SensorReader The arduino firmware publishes messages using firmata once per second with sensor readings. This class is responsible for collection and persistance of readings. AttachTo: "" """ NAME = "Collector" def __init__(self, port): ''' Constructor. Adds the callback handler to accept firmata messages from the arduino board connected to the sensors. ''' self.last_rain_reading_saved = None self.last_sky_temperature_reading_saved = 0 self.last_ambient_temperature_reading_saved = 0 self.last_reading_saved_time = time.time() self.board = Arduino(port) # start an iterator thread so that serial buffer doesn't overflow it = util.Iterator(self.board) it.start() self.board.add_cmd_handler(pyfirmata.pyfirmata.STRING_DATA, self._messageHandler) def _messageHandler(self, *args, **kwargs): ''' Calback method envoked by the firmata library. Handles the string message sent from the arduino. Grabs the sensor data from the message and persists in the DB table. :param args: :param kwargs: :return: ''' readings = json.loads(util.two_byte_iter_to_str(args)) sky_temperature = readings['sky'] ambient_temperature = readings['ambient'] rain = readings['rain'] if self.should_persist_sensor_reading(sky_temperature, ambient_temperature, rain): conn = sqlite3.connect('weather_sensor.db') c = conn.cursor() print('inserting observation') c.execute( "INSERT INTO weather_sensor (rain,sky_temperature,ambient_temperature) VALUES (?,?,?)", (rain, sky_temperature, ambient_temperature)) c.execute( "DELETE FROM weather_sensor WHERE date_sensor_read <= date('now','-365 day')" ) print('inserted') # new_id = c.lastrowid conn.commit() self.last_rain_reading_saved = rain self.last_sky_temperature_reading_saved = sky_temperature self.last_ambient_temperature_reading_saved = ambient_temperature self.last_reading_saved_time = time.time() c.close() def update(self): super(Collector, self).update() def writeData(self, data): self.board.send_sysex(pyfirmata.pyfirmata.STRING_DATA, data) def dispose(self): super(Collector, self).dispose() try: self.board.exit() except AttributeError: print('exit() raised an AttributeError unexpectedly!') def should_persist_sensor_reading(self, sky_temperature, ambient_temperature, rain): ''' Returns true if the sensor data should be persisted in the DB. The rules are if any temp change is more than 1 degree, or the rain state changes or 60sec have elapsed since the last save :param sky_temperature: :param ambient_temperature: :param rain: :return: ''' if abs(sky_temperature - self.last_sky_temperature_reading_saved) > 1 or abs( ambient_temperature - self.last_ambient_temperature_reading_saved ) > 1 or rain != self.last_rain_reading_saved or time.time( ) - self.last_reading_saved_time > 60: return True else: return False
class Arduino_Interface(object): ## ## ## CONSTANTS ## ## ## ## ## PING = 0x01 TEST_DATA = 0x02 ## ## ## Initalization ## ## ## ## ## def __init__(self, port, log_handler): ## Initalize logging logging.basicConfig(level=logging.DEBUG) self.logger = logging.getLogger('Arduino_Interface') self.logger.addHandler(log_handler) # Add Tk log handler self.logger.debug('__init__') ## Board Initalization self.board = Arduino(port) self.board.add_cmd_handler(pyfirmata.START_SYSEX, self.handleIncomingSysEx) self.board.add_cmd_handler(pyfirmata.STRING_DATA, self.handleIncomingString) ## Data Buffer Initalization self.incoming_data = [] ## Callback holder self.callback_holder = dict() ## ## ## Runtime Functions ## ## ## ## ## def begin_scanning(self): self.board.iterate() ## ## ## Senders ## ## ## ## ## def ping(self, pingCallback): self.logger.debug('----Sending Ping----') ## Attach callback self.callback_holder[Arduino_Interface.PING] = pingCallback byte_array = bytearray() byte_array.append(Arduino_Interface.PING) self.sendSysEx(byte_array) def requestTestData(self, testDataCallback): self.logger.debug('----Requesting Test Data----') ## Attach callback self.callback_holder[Arduino_Interface.TEST_DATA] = testDataCallback byte_array = bytearray() byte_array.append(Arduino_Interface.TEST_DATA) self.sendSysEx(byte_array) def sendSysEx(self, byteArray): self.logger.debug('----sendSysEx----') self.logger.debug('SEND Data: {}'.format(binascii.hexlify(byteArray))) self.board.send_sysex(pyfirmata.START_SYSEX, byteArray) self.begin_scanning() def sendString(self, stringToSend): pass #self.board.send_sysex # for byte in dataArray: # self.incoming_data.append(chr(byte)) # print self.incoming_data ## ## ## Handlers ## ## ## ## ## def handleIncomingString(self, *string): self.logger.debug('handling Incoming String') ## Flush incoming_data self.incoming_data = [] for byte in string: self.incoming_data.append(chr(byte)) recieved_string = ''.join(self.incoming_data) print recieved_string def handleIncomingSysEx(self, *byteArray): self.logger.debug('----Incoming SysEx----') ## Flush incoming_data array self.incoming_data = [] self.incoming_data = self.filterSysEx(byteArray) ## Get header header = byteArray[0] self.logger.debug('header: {}'.format(header)) if (header == Arduino_Interface.PING): self.logger.debug('PING Response recieved') ## Ping response recieved. Return True self.callback_holder[Arduino_Interface.PING](True) elif (header == Arduino_Interface.TEST_DATA): self.logger.debug('Test Data recieved') self.callback_holder[Arduino_Interface.TEST_DATA]( self.incoming_data) ## ## ## Utilities ## ## ## ## ## def filterSysEx(self, byteArray): self.logger.debug('filterSysEx') incoming_data = [] for idx, byte in enumerate(byteArray): if idx == 0: continue incoming_data.append(byte) self.logger.debug('SysEx Data:') self.logger.debug(incoming_data) return incoming_data
'C': 'GC', 'S': 'GS' } mqtt_gate_command_topic = 'gate/target/set' def handle_string(*received): global lastReceived print('received:') lastReceived="".join(map(chr, map(util.from_two_bytes,zip(received[0::2],received[1::2])))) print(lastReceived) # '/dev/ttyUSB0' on rpi # /dev/tty.usbserial-14430 on Mac through dell dongle # /dev/tty.usbserial-2230 on Mac through belkin station board = Arduino('/dev/ttyUSB0') board.add_cmd_handler(STRING_DATA, handle_string) def send_string(msg): print('sending') board.send_sysex(0x71, util.str_to_two_byte_iter(msg+'\0')) def on_incoming_mqtt_gate_cmd(topic, payload): send_string(mqtt_gate_ops[payload]) it = util.Iterator(board) it.start() moskito_sub.start_client('127.0.0.1', mqtt_gate_command_topic, on_incoming_mqtt_gate_cmd) @get('/last') def index():