Skip to content

Commit

Permalink
Add play_beep capability to microbit (ukBaz#101)
Browse files Browse the repository at this point in the history
  • Loading branch information
ukBaz authored Nov 24, 2016
1 parent a9a6644 commit b5ffe05
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 15 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ before_script:
# If dbusmock installed from github
- export PYTHONPATH=$PYTHONPATH:/tmp/python-dbusmock-bluez_gatt
script:
- python -m unittest -v tests.test_url_to_hex
- python -m unittest -v tests.test_tools
- python -m unittest -v tests.test_adapter
- python -m unittest -v tests.test_device
- python -m unittest -v tests.test_gatt
Expand Down
55 changes: 43 additions & 12 deletions bluezero/microbit.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ def _get_dbus_paths(self):
self.io_pin_config_path = tools.uuid_dbus_path(
constants.GATT_CHRC_IFACE,
IO_PIN_CONFIG)[0]
self.io_pin_pwm_path = tools.uuid_dbus_path(
constants.GATT_CHRC_IFACE,
IO_PIN_PWM)[0]
self.io_ad_config_path = tools.uuid_dbus_path(
constants.GATT_CHRC_IFACE,
IO_AD_CONFIG)[0]
Expand Down Expand Up @@ -371,7 +374,7 @@ def read_bearing(self):
return int.from_bytes(mag_bear_val,
byteorder='little', signed=False)

def _pin_config(self):
def _pin_config(self, states=None):
"""
A bit mask (32 bit) which defines which inputs will be read.
A value of 0 means configured for output and 1 means configured
Expand All @@ -383,34 +386,43 @@ def _pin_config(self):
pin_conf_iface = tools.get_dbus_iface(constants.GATT_CHRC_IFACE,
pin_conf_obj)

return pin_conf_iface.ReadValue(())
if states is None:
return pin_conf_iface.ReadValue(())
else:
pin_conf_iface.WriteValue([states], ())

def _pin_ad_config(self):
def _pin_ad_config(self, states=None):
"""
A bit mask (32 bit) which allows each pin to be configured for
analogue or digital use.
A value of 0 means digital and 1 means analogue.
If no states are specified then the current state is returned
"""
pin_ad_conf_obj = tools.get_dbus_obj(constants.BLUEZ_SERVICE_NAME,
self.io_ad_config_path)

pin_ad_conf_iface = tools.get_dbus_iface(constants.GATT_CHRC_IFACE,
pin_ad_conf_obj)
if states is None:
return pin_ad_conf_iface.ReadValue(())
else:
pin_ad_conf_iface.WriteValue([states], ())

return pin_ad_conf_iface.ReadValue(())

def _pin_states(self):
def _pin_states(self, pin_value_pairs):
"""
:return:
Contains data relating to zero or more pins.
Structured as a variable length list of up to 19 Pin
Number / Value pairs.
"""
pin_states_obj = tools.get_dbus_obj(constants.BLUEZ_SERVICE_NAME,
self.io_pin_data_path)

pin_states_iface = tools.get_dbus_iface(constants.GATT_CHRC_IFACE,
pin_states_obj)

return pin_states_iface.ReadValue(())
if states is None:
return pin_states_iface.ReadValue(())
else:
pin_states_iface.WriteValue([pin_value_pairs], ())

def _pin_pwn_control(self, pin, value, period):
"""
Expand All @@ -426,5 +438,24 @@ def _pin_pwn_control(self, pin, value, period):

pin_pwm_iface = tools.get_dbus_iface(constants.GATT_CHRC_IFACE,
pin_pwm_obj)

return pin_pwm_iface.WriteValue([pin, value, period], ())
byte_value = tools.int_to_uint16(value)
byte_period = tools.int_to_uint32(period)
pin_pwm_iface.WriteValue([pin,
byte_value[0],
byte_value[1],
byte_period[0],
byte_period[1],
byte_period[2],
byte_period[3]
], ())

def play_beep(self, duration):
"""
If a buzzer is attached to pin 0 then a beep will be played
:param duration: time in seconds
"""
self._pin_config(0)
self._pin_ad_config(1)
self._pin_pwn_control(0, 512, 2094)
sleep(duration)
self._pin_pwn_control(0, 0, 0)
10 changes: 10 additions & 0 deletions bluezero/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -347,3 +347,13 @@ def bytes_to_xyz(bytes):
z = sint16_to_int(bytes[4:6]) / 1000

return [x, y, z]


def int_to_uint32(value_in):
bin_string = '{0:032b}'.format(value_in)
octet0 = int(bin_string[25:32], 2)
octet1 = int(bin_string[17:24], 2)
octet2 = int(bin_string[9:16], 2)
octet3 = int(bin_string[0:8], 2)

return [octet0, octet1, octet2, octet3]
1 change: 1 addition & 0 deletions examples/microbit_poll.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
'0b10000',
'0b1110']

ubit.play_beep(0.25)
ubit.display_scroll_delay(20)
delay = ubit.display_scroll_delay()
ubit.display_text('Scroll speed {}'.format(delay))
Expand Down
4 changes: 2 additions & 2 deletions run_local_tests.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
python -m unittest -v tests.test_url_to_hex
python -m unittest -v tests.test_tools
test11=$?
python3 -m unittest -v tests.test_url_to_hex
python3 -m unittest -v tests.test_tools
test12=$?
python -m unittest -v tests.test_adapter
test21=$?
Expand Down
10 changes: 10 additions & 0 deletions tests/test_url_to_hex.py → tests/test_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,15 @@ def test(self):
0x00, 0x61, 0x62, 0x6f, 0x75, 0x74])


class IntToUint32(unittest.TestCase):
def test_with_zeros(self):
little_endian = tools.int_to_uint32(2094)
self.assertListEqual(little_endian, [0x2E, 0x08, 0x00, 0x00])

def test_all_full(self):
little_endian = tools.int_to_uint32(305419896)
self.assertListEqual(little_endian, [0x78, 0x56, 0x34, 0x12])


if __name__ == '__main__':
unittest.main()

0 comments on commit b5ffe05

Please sign in to comment.