class AsyncReader(object): def __init__(self, address): self.requester = GATTRequester(address, False) self.response = GATTResponse() self.connect() self.request_data() self.wait_response() def connect(self): print("Connecting...", end=' ') sys.stdout.flush() self.requester.connect(True) print("OK!") def request_data(self): self.requester.read_by_handle_async(0x1, self.response) def wait_response(self): while not self.response.received(): time.sleep(0.1) data = self.response.received()[0] print("bytes received:", end=' ') for b in data: print(hex(ord(b)), end=' ') print("")
class AsyncReader(object): def __init__(self, address): self.requester = GATTRequester(address, False) self.response = GATTResponse() self.connect() self.request_data() self.wait_response() def connect(self): print("Connecting...", end=' ') sys.stdout.flush() self.requester.connect(True) print("OK!") def request_data(self): self.requester.read_by_handle_async(0x1, self.response) def wait_response(self): while not self.response.received(): time.sleep(0.1) data = self.response.received()[0] print("bytes received:", end=' ') for b in data: print(hex(ord(b)), end=' ') print("")
class AsyncReader(object): def __init__(self, address): self.requester = GATTRequester(address, False) self.response = NotifyMeYourValue() self.connect() self.request_data() self.loop() def connect(self): print("Connecting...", end=' ') sys.stdout.flush() self.requester.connect(True) print("OK!") def request_data(self): self.requester.read_by_handle_async(0x1, self.response) def loop(self): while not self.response.done: time.sleep(0.1)
class Koshian: """ Koshian.pyの基本クラス """ def __init__(self, mac=""): if mac == "": self.mac = find() else: self.mac = mac self.startup() def startup(self): self.connect() delay(500) self.pin = 0 self.pin_mode = 0 self.pwm_mode = 0 #self.hardwareReset() # このシーケンスを経ると一発目の入力が正しく機能する(?) self.writePinMode(0xFF) self.writePIO(0xFF) self.writePinMode(0x00) self.I2C_read_length = 1 # ------------------------------------------- # Digital I/O Functions # ------------------------------------------- def pinMode(self, pin, mode): """ PIOを入出力指定します。 pin: ピン番号。PIO0などのように指定します。 mode: INPUT/OUTPUT で指定します。 """ self.setPWMmode(pin, DISABLE) r = self.readPinMode() if mode == OUTPUT: r |= (1 << pin) & 0xFF else: r &= (~((1 << pin)) & 0xFF) self.writePinMode(r) def digitalWrite(self, pin, value): """ PIOにデジタル出力します。 pin: ピン番号。PIO0などのように指定します。 value: HIGH/LOW で指定します。 """ self.setPWMmode(pin, DISABLE) if value == HIGH: self.pin |= (1 << pin) & 0xFF else: self.pin &= (~((1 << pin)) & 0xFF) self.writePIO(self.pin) def digitalRead(self, pin): """ PIOからデジタル入力します。 pin: ピン番号。PIO0などのように指定します。 戻り値は HIGH/LOW です。 """ if (self.pwm_mode & (1 << pin)) != 0: self.setPWMmode(pin, DISABLE) dat = self.readPIO() mask = (1 << pin) & 0xFF if (dat & mask) == 0: return LOW else: return HIGH # ------------------------------------------- # Analog I/O Functions # ------------------------------------------- def analogRead(self, pin): """ AIOからデジタル入力します。 pin: ピン番号。AIO0などのように指定します。 戻り値は mV単位です """ return self.ANALOG_read(pin) def analogWrite(self, pin, value): """ DACは未対応のようなので、PWMのみです。 pin: PIO0,1,2のみ。 value: 0-255 value/255*VCC が出力されます。 """ self.setPWMmode(pin, ENABLE) self.writePWMperiod(pin, 255 * 20) self.writePWMduty(pin, value * 20) # ------------------------------------------- # Others # ------------------------------------------- # ------------------------------------------- # PWM Functions # ------------------------------------------- def setPWMmode(self, pin, mode): """ pin: PIO0,1,2を指定。 mode: ENABLE/DISABLE """ new_mode = self.pwm_mode if mode == ENABLE: new_mode |= (1 << pin) & 0xFF else: new_mode &= (~((1 << pin)) & 0xFF) if new_mode != self.pwm_mode: self.writePWMmode(new_mode) # ------------------------------------------- # konashi PIO functions # ------------------------------------------- def writePinMode(self, value): """ value bit0-5: PIO0-5 0: INPUT 1: OUTPUT """ return self.write_command("PIO_setting", [value]) def readPinMode(self): return self.read_command("PIO_setting") def writePIOpullup(self, value): """ value bit0-5: PIO0-5 0: DISABLE 1: ENABLE """ return self.write_command("PIO_pullup", [value]) def readPIOpullup(self): return self.read_command("PIO_pullup") def writePIO(self, value): """ value bit0-5: PIO0-5 0: LOW 1: HIGH """ return self.write_command("PIO_output", [value]) def readPIO(self): return self.read_command("PIO_notification") # ------------------------------------------- # konashi Analog IO functions # ------------------------------------------- #def ANALOG_drive(self,pin): def ANALOG_read(self, pin): handle_string = "" if pin == AIO0: handle_string = "ANALOG_read_0" elif pin == AIO1: handle_string = "ANALOG_read_1" elif pin == AIO2: handle_string = "ANALOG_read_2" dat = self.read_async_command(handle_string, length=2) adat = (dat[0] << 8) + dat[1] return adat # ------------------------------------------- # konashi UART functions # ------------------------------------------- def UART_config(self, mode): """ mode 0: UART DISABLE 1: UART ENABLE """ self.write_command("UART_config", [mode]) def UART_baud_rate(self, bit_rate): """ bit_rate: bps(2400/9600 is supported) """ dat = [0, 0] bit_rate /= 240 dat[0] = (bit_rate & 0xFF00) >> 8 dat[1] = (bit_rate & 0x00FF) self.write_command("UART_baud_rate", dat) def UART_tx(self, data): """ data: max 18bytes strings """ dat = (map(lambda n: ord(n), data)) self.write_command("UART_tx", dat) def UART_rx(self): """ read 1 byte strings """ return chr(self.read_command("UART_rx", dat)[0]) # ------------------------------------------- # konashi I2C functions # ------------------------------------------- def I2C_config(self, mode): """ mode 0: I2C DISABLE 1: I2C ENABLE(100kHz) 2: I2C ENABLE(400kHz) """ self.write_command("I2C_config", [mode]) def I2C_start_stop(self, mode): """ mode 0: STOP CONDITION 1: START CONDITION 2: REPEATED START CONDITION """ self.write_command("I2C_start_stop", [mode]) def I2C_write(self, slave_address, data): """ slave_address: I2C slave address(8bit) data: data array (max 16 bytes) """ dat = [0] * 2 dat[0] = len(data) + 2 dat[1] = (slave_address << 1) & 0xfe if isinstance(data, list): dat += data if isinstance(data, str): dat += map(lambda n: ord(n), data) self.write_command("I2C_write", dat) def I2C_read_parameter(self, slave_address, length): """ Send Read Request slave_address: I2C slave address(7bit) """ self.I2C_read_length = length dat = [0] * 2 dat[0] = self.I2C_read_length dat[1] = (slave_address << 1) | 0x01 self.write_command("I2C_read_parameter", dat) def I2C_read(self): return self.read_async_command("I2C_read", length=self.I2C_read_length) # ------------------------------------------- # konashi PWM functions # ------------------------------------------- def readPWMmode(self): return self.read_command("PWM_config") def writePWMmode(self, mode): self.mode = mode self.write_command("PWM_config", [self.mode]) def writePWMperiod(self, pin, period): """ period: 1000-20480[usec] """ param = [pin, 0, 0, 0, 0] param[1] = (period & 0xFF000000) >> 24 param[2] = (period & 0x00FF0000) >> 16 param[3] = (period & 0x0000FF00) >> 8 param[4] = (period & 0x000000FF) self.write_command("PWM_parameter", param) def writePWMduty(self, pin, duty): param = [pin, 0, 0, 0, 0] param[1] = (duty & 0xFF000000) >> 24 param[2] = (duty & 0x00FF0000) >> 16 param[3] = (duty & 0x0000FF00) >> 8 param[4] = (duty & 0x000000FF) self.write_command("PWM_duty", param) # ------------------------------------------- # konashi other functions # ------------------------------------------- def hardwareReset(self): self.write_command("hardware_reset", [0xff]) # ------------------------------------------- # Bluetooth functions (depend on pygattlib) # ------------------------------------------- def connect(self): self.req = GATTRequester(self.mac) def write_command(self, handle_id, parameter): """ parameter: 配列 """ handle = HANDLE[handle_id] self.req.write_by_handle(handle, str(bytearray(parameter))) def read_async_command(self, handle_id, length=1): """ 1バイトリードのときはintで、 2バイト以上リードするときは配列で返します。 """ response = GATTResponse() handle = HANDLE[handle_id] self.req.read_by_handle_async(handle, response) while not response.received(): time.sleep(0.1) ans = response.received()[0] ans = map(lambda n: ord(n), ans) if length == 1: return ans[0] else: return ans def read_command(self, handle_id, length=1): """ 同期リード。 1バイトリードのときはintで、 2バイト以上リードするときは配列で返します。 """ handle = HANDLE[handle_id] ans = self.req.read_by_handle(handle)[0] ans = map(lambda n: ord(n), ans) if length == 1: return ans[0] else: return ans # ------------------------------------------- # Main Routine # ------------------------------------------- def setup(self): pass def loop(self): pass def run(self): self.setup() while 1: self.loop()
from gattlib import GATTRequester, GATTResponse import time import os service = DiscoveryService("hci1") devices = service.discover(2) tag_address = "B0:B4:48:BF:C3:83" for address, name in devices.items(): print("name: {}, address: {}".format(name, address)) if address == tag_address: print "cilia found" req = GATTRequester(tag_address, False, "hci1") response = GATTResponse() req.connect() req.read_by_handle_async(0x3A, response) while not response.received(): time.sleep(0.1) steps = response.received()[0] #print "steps..." #print type(steps) #print steps #for b in steps: # print hex(ord(b)),' ' req.write_by_handle(0x3C, str(bytearray([0xff, 0xff]))) req.write_by_handle(0x3E, str(bytearray([0x64]))) data = req.read_by_handle(0x3C)[0] #for d in data: # print hex(ord(d)),' '
from gattlib import GATTRequester, GATTResponse class NotifyYourName(GATTResponse): def on_response(self, name): print("your name is: {}".format(name)) response = NotifyYourName() req = GATTRequester("00:11:22:33:44:55") # use your address here req.read_by_handle_async(0x12, response) while True: # here, do other interesting things sleep(1)
class RoboRoach: ####################### # API Constants ####################### ROBOROACH_FREQUENCY_HANDLE = 0x002A ROBOROACH_PULSE_WIDTH_HANDLE = 0x002D ROBOROACH_NUM_PULSES_HANDLE = 0x0030 ROBOROACH_RANDOM_MODE = 0x0033 ROBOROACH_RIGHT_HANDLE = 0x0036 ROBOROACH_LEFT_HANDLE = 0x0039 ROBOROACH_GAIN_HANDLE = 0x003C ROBOROACH_MIN_FREQ_HANDLE = 0x003F ROBOROACH_MAX_FREQ_HANDLE = 0x0042 ROBOROACH_MIN_PW_HANDLE = 0x0045 ROBOROACH_MAX_PW_HANDLE = 0x0048 ROBOROACH_MIN_GAIN_HANDLE = 0x004B ROBOROACH_MAX_GAIN_HANDLE = 0x004E ####################### # CONSTRUCTOR ####################### def __init__(self, mac_address): self.mac_address = mac_address self.req = GATTRequester(mac_address) self._set_min_freq(0x0A) self._set_max_freq(0X46) self._set_min_pw(0x01) self._set_max_pw(0x14) self._set_min_gain(0x0A) self._set_max_gain(0x46) ####################### # AUXILIAR FUNCTIONS ####################### def read_async(self, handle): response = GATTResponse() self.req.read_by_handle_async(handle, response) while not response.received(): time.sleep(0.1) return response.received()[0] ####################### # COMMON FUNCTIONS ####################### def _turn(self, direction): if direction == 'right': self.req.write_by_handle(self.ROBOROACH_LEFT_HANDLE, str(bytearray([1]))) elif direction == 'left': self.req.write_by_handle(self.ROBOROACH_RIGHT_HANDLE, str(bytearray([1]))) else: print "Unknown direction" def _rand(self, random): if random == True: self.req.write_by_handle(self.ROBOROACH_RANDOM_MODE, str(bytearray([1]))) else: self.req.write_by_handle(self.ROBOROACH_RANDOM_MODE, str(bytearray([0]))) def _set_freq(self, frequency): self.req.write_by_handle(self.ROBOROACH_FREQUENCY_HANDLE, str(bytearray([frequency]))) def _get_freq(self): freq = self.read_async(self.ROBOROACH_FREQUENCY_HANDLE) return freq.encode('hex') def _set_pw(self, pulse_width): self.req.write_by_handle(self.ROBOROACH_PULSE_WIDTH_HANDLE, str(bytearray([pulse_width]))) def _get_pw(self): pulse_width = self.read_async(self.ROBOROACH_PULSE_WIDTH_HANDLE) return pulse_width.encode('hex') def _set_gain(self, gain): self.req.write_by_handle(self.ROBOROACH_GAIN_HANDLE, str(bytearray([gain]))) def _get_gain(self): gain = self.read_async(self.ROBOROACH_GAIN_HANDLE) return gain.encode('hex') def _set_min_freq(self, freq): self.req.write_by_handle(self.ROBOROACH_MIN_FREQ_HANDLE, str(bytearray([freq]))) def _set_max_freq(self, freq): self.req.write_by_handle(self.ROBOROACH_MAX_FREQ_HANDLE, str(bytearray([freq]))) def _get_min_freq(self): min_freq = self.read_async(self.ROBOROACH_MIN_FREQ_HANDLE) return min_freq.encode('hex') def _get_max_freq(self): max_freq = self.read_async(self.ROBOROACH_MAX_FREQ_HANDLE) return max_freq.encode('hex') def _set_min_pw(self, pulse_width): self.req.write_by_handle(self.ROBOROACH_MIN_PW_HANDLE, str(bytearray([pulse_width]))) def _set_max_pw(self, pulse_width): self.req.write_by_handle(self.ROBOROACH_MAX_PW_HANDLE, str(bytearray([pulse_width]))) def _get_min_pw(self): min_freq = self.read_async(self.ROBOROACH_MIN_PW_HANDLE) return min_freq.encode('hex') def _get_max_pw(self): max_freq = self.read_async(self.ROBOROACH_MAX_PW_HANDLE) return max_freq.encode('hex') def _set_min_gain(self, gain): self.req.write_by_handle(self.ROBOROACH_MIN_GAIN_HANDLE, str(bytearray([gain]))) def _set_max_gain(self, gain): self.req.write_by_handle(self.ROBOROACH_MAX_GAIN_HANDLE, str(bytearray([gain]))) def _get_min_gain(self): min_gain = self.read_async(self.ROBOROACH_MIN_GAIN_HANDLE) return min_gain.encode('hex') def _get_max_gain(self): max_gain = self.read_async(self.ROBOROACH_MAX_GAIN_HANDLE) return max_gain.encode('hex') # Need more testing: def _set_np(self, num_pulses): self.req.write_by_handle(self.ROBOROACH_NUM_PULSES_HANDLE, str(bytearray([num_pulses]))) def _get_np(self): response = GATTResponse() self.req.read_by_handle_async(self.ROBOROACH_NUM_PULSES_HANDLE, response) while not response.received(): time.sleep(0.1) num_pulses = response.received()[0] return num_pulses.encode('hex')