class interface: def __init__(self, bus_number: int): self.bus = SMBus(bus_number) return # Get a sensor readings from an arduino with a given id. # This will ultimately call the `get_sensor_[number]()` # function on the specified arduino. The arduino will # send the value over I2C and it will be returned from # this function. def get_sensor_reading(self, arduino_ID: int, sensor_number: int): # Request reading from sensor, Data returned as float in 4 Bytes sensor_data = bytearray( self.bus.read_block_data(arduino_ID, sensor_number, 4)) # Convert 4 raw bytes into Float value # Uses BIG ENDIAN, This may be incorrect. If float values are # incorrect, try '>f' instead value = struct.unpack('>f', sensor_data[:4]) return value # Send a text command to the arduino, This will call the `handle_commnd()` # function on thw arduino. No value is returned from the arduino. def send_command(self, arduino_ID: int, command_code: int, extra_data: bytearray): # Create Data array to send data_array = bytearray(command_code) + extra_data # Send command over I2C self.bus.write_block_data(arduino_ID, I2C_COMMAND_CODE, data_array) return
class i2c_device: def __init__(self, addr, port=I2CBUS): self.addr = addr self.bus = SMBus(port) # Write a single command def write_cmd(self, cmd): self.bus.write_byte(self.addr, cmd) sleep(0.0001) # Write a command and argument def write_cmd_arg(self, cmd, data): self.bus.write_byte_data(self.addr, cmd, data) sleep(0.0001) # Write a block of data def write_block_data(self, cmd, data): self.bus.write_block_data(self.addr, cmd, data) sleep(0.0001) # Read a single byte def read(self): return self.bus.read_byte(self.addr) # Read def read_data(self, cmd): return self.bus.read_byte_data(self.addr, cmd) # Read a block of data def read_block_data(self, cmd): return self.bus.read_block_data(self.addr, cmd)
global bus, alert_act, alert_dir, alert_reg, ADDR while True: try: alert_dir_rand = random.choice(alert_dir) alert_act_rand = random.choice(alert_act) alert_st = alert_dir_rand + ':' + alert_act_rand alert_st_byte = bytearray(alert_st, 'ascii') bus.write_block_data(ADDR, alert_reg, alert_st_byte) print('Sent alert :', alert_st) except: print('Cannot write alert state @ ', time.time()) finally: time.sleep(alert_data_delay) y = threading.Thread(target=send_alert, daemon=True) y.start() while True: try: drive_st = random.choice(l_st) + ':' + random.choice(r_st) drive_st_byte = bytearray(drive_st, 'ascii') bus.write_block_data(ADDR, drive_st_reg, drive_st_byte) print('Sent drive st : ', drive_st) time.sleep(0.1) except: print('Cannot write bot state @ ', time.time()) finally: time.sleep(dir_data_delay)
bus.write_byte_data(ADDRESS, 4, 0x44) b = bus.read_byte_data(ADDRESS, 1) assert b == 0x44 print("Write byte data@4 OK") bus.write_byte_data(ADDRESS, 5, 0x55) b = bus.read_byte_data(ADDRESS, 2) assert b == 0x55 print("Write byte data@5 OK") bus.write_byte_data(ADDRESS, 6, 0x66) b = bus.read_byte_data(ADDRESS, 3) assert b == 0x66 print("Write byte data@6 OK") bus.write_word_data(ADDRESS, 9, 0xabcd) w = bus.read_word_data(ADDRESS, 7) assert w == 0xabcd print("Write word data@9, read word data@7 OK") bus.write_word_data(ADDRESS, 10, 0xef12) w = bus.read_word_data(ADDRESS, 8) assert w == 0xef12 print("Write word data@10, read word data@8 OK") bus.write_block_data( 0x19, 13, [1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2]) block = bus.read_i2c_block_data(0x19, 11, 9) assert block == [8, 1, 2, 3, 4, 5, 6, 7, 8] print("Write/Read block OK")
class client: def __init__(self, config: json): self._config = config self._bus = SMBus(config["i2c"]["device"]) # Load msg configs on init self._conf_bytes(config["mqtt"]["byte_config_paths"]) self._header_size = _calc_msg_size(self._header_conf) self._general_size = _calc_msg_size(self._general_conf["general"]) # Colors mode_size = int(self._color_conf["mode"]["size"]) self._color_static_size = _calc_msg_size(self._color_conf["static_color"]) + mode_size self._color_grad_size = _calc_msg_size(self._color_conf["grad_color"]) + mode_size self._color_rnd_size = _calc_msg_size(self._color_conf["rnd_color"]) + mode_size # States mode_size = int(self._state_conf["mode"]["size"]) self._state_static_size = _calc_msg_size(self._state_conf["static_state"]) + mode_size self._state_snake_size = _calc_msg_size(self._state_conf["snake_state"]) + mode_size # Mqtt self._client = mqtt.Client(transport=config['mqtt']['transport']) # Set callbacks self._client.on_connect = self._on_connect self._client.on_message = self._on_message self._client.on_subscribe = self._on_subscribe self._client.on_publish = self._on_publish def _conf_bytes(self, byte_config_paths: json): self._color_conf = json.load(open(byte_config_paths["color_modes"])) self._general_conf = json.load(open(byte_config_paths["general"])) self._header_conf = json.load(open(byte_config_paths["header"])) self._state_conf = json.load(open(byte_config_paths["state_modes"])) pass def _on_connect(self, client, userdata, flags, rc): print("Connected with result code " + str(rc)) client.subscribe(self._config["mqtt"]['in_topic']) def _on_message(self, client, userdata, msg): input_json = json.loads(msg.payload) if "general_data" in input_json: self._send_i2c(self._general_conf, input_json["general_data"], self._general_size + self._header_size, "general", input_json["zone"], {}) color_topic = "color_mode" if color_topic in input_json: if input_json[color_topic] == "static": self._send_i2c(self._color_conf, input_json["color_data"], self._color_static_size + self._header_size, "static_color", input_json["zone"], {}) elif input_json[color_topic] == "random": self._send_i2c(self._color_conf, input_json["color_data"], self._color_rnd_size + self._header_size, "rnd_color", input_json["zone"], {}) elif input_json[color_topic] == "gradient": self._send_i2c(self._color_conf, input_json["color_data"], self._color_grad_size + self._header_size, "grad_color", input_json["zone"], {"colors": "color_number"}) display_topic = "display_mode" if display_topic in input_json: if input_json[display_topic] == "static": self._send_i2c(self._state_conf, {}, self._state_static_size + self._header_size, "static_state", input_json["zone"], {}) elif input_json[display_topic] == "snake": self._send_i2c(self._state_conf, input_json["display_data"], self._state_snake_size + self._header_size, "snake_state", input_json["zone"], {}) def _on_subscribe(self, mosq, obj, mid, granted_qos): if granted_qos == 128: sys.exit("Unable to subscribe to topic") # bad print("Subscribed: " + str(mid)) print("Granted qos: " + str(granted_qos)) def _on_publish(self, client, userdata, result): print("data published") # msg_size = body + header # byte_conf - top-level conf (for example toUColorModes.json), cause we need to take mode conf somewhere # array_dict - dictionary like (array_field:array_length_field) def _send_i2c(self, byte_conf, input_json, msg_size, msg_name, zone_num, array_dict: dict): for key, value in array_dict.items(): msg_size += (len(input_json[key]) - 1) * byte_conf[msg_name][key]["size"] out_data: list = [None] * msg_size # Fill header _set_bytes(self._header_conf["zone"], zone_num, out_data, 0) _set_bytes(self._header_conf["msg_type"], byte_conf["msg_num"], out_data, 0) # Fill body # There is no mode_num - it's general msg (hello there) if "mode_num" in byte_conf[msg_name]: _set_bytes(byte_conf["mode"], byte_conf[msg_name]["mode_num"], out_data, self._header_size) for key in input_json: if key not in array_dict: # second condition is for the keys like array size _set_bytes(byte_conf[msg_name][key], input_json[key], out_data, self._header_size) # Well it basically works only for colors for array_field in array_dict: _set_bytes(byte_conf[msg_name][array_dict[array_field]], len(input_json[array_field]), out_data, self._header_size) for num, el in enumerate(input_json[array_field]): color = [el[0], el[1], el[2]] _set_bytes(byte_conf[msg_name][array_field], int.from_bytes(color, byteorder='big'), out_data, self._header_size + num * byte_conf[msg_name][array_field]["size"]) # this should be illegal print(msg_name + str(out_data)) self._bus.write_block_data(self._config["i2c"]["address"], 0, out_data) def start(self): self._client.connect(self._config['mqtt']['ip'], self._config['mqtt']['port']) self._client.loop_start()
lpwr = '0.556' rpwr = '0.987' pwrr = lpwr + ',' + rpwr pwrr = bytearray(pwrr, 'ascii') def get_data(): global bus while True: try: data = bus.read_i2c_block_data(ADDR, 5, 2) print('Bat-1 : ', data[0], ' ', 'Bat-2 : ', data[1]) time.sleep(5) except: print('Cannot request @ ', time.time()) time.sleep(1) x = threading.Thread(target=get_data, daemon=True) x.start() while True: try: bus.write_block_data(ADDR, 3, pwrr) print('Sent @ ', time.time()) time.sleep(0.1) except: print('Cannot write @ ', time.time()) time.sleep(1)