0

I have successfully made my pico W advertise bluetooth using this tutorial. However with this raw code alone, i am able to detect the bluetooth from an older android phone, but not an iphone. I am sure this maybe has something to do with services being needed or maybe the byte that i am advertising isnt correct for modern phones (0x19). On an iphone i can use an app such as nrf connect and that will see the signal and connect to it and then it will show in bluetooth on the phone as connected. So its not a wasted signal but it clearly isnt the right one for whatever ios is looking for.

On a separate note, i have wired a speaker to work with the pico and can play simple tones and waves proving it is wired correctly. What i would like to do is be able to connect to the pico with the iphones settings bluetooth (starting by even seeing it to pair to) and then playing audio and have it send over bluetooth to the speakers. I am trying to become more adept in bluetooth logic but i am hoping someone can make things a little more clear for me and others in the future.

The code i am using is as follows, by the way this is through microPython:

 import bluetooth import random import struct import time from machine import Pin from ble_advertising import advertising_payload from micropython import const _IRQ_CENTRAL_CONNECT = const(1) _IRQ_CENTRAL_DISCONNECT = const(2) _IRQ_GATTS_WRITE = const(3) _FLAG_READ = const(0x0002) _FLAG_WRITE_NO_RESPONSE = const(0x0004) _FLAG_WRITE = const(0x0008) _FLAG_NOTIFY = const(0x0010) _UART_UUID = bluetooth.UUID("6E400001-B5A3-F393-E0A9-E50E24DCCA9E") _UART_TX = ( bluetooth.UUID("6E400003-B5A3-F393-E0A9-E50E24DCCA9E"), _FLAG_READ | _FLAG_NOTIFY, ) _UART_RX = ( bluetooth.UUID("6E400002-B5A3-F393-E0A9-E50E24DCCA9E"), _FLAG_WRITE | _FLAG_WRITE_NO_RESPONSE, ) _UART_SERVICE = ( _UART_UUID, (_UART_TX, _UART_RX), ) class BLESimplePeripheral: def __init__(self, ble, name="Pi Pico"): self._ble = ble self._ble.active(True) self._ble.irq(self._irq) ((self._handle_tx, self._handle_rx),) = self._ble.gatts_register_services((_UART_SERVICE,)) self._connections = set() self._write_callback = None self._payload = advertising_payload(name=name, services=[_UART_UUID]) self._advertise() def _irq(self, event, data): if event == _IRQ_CENTRAL_CONNECT: conn_handle, _, _ = data print("New connection", conn_handle) self._connections.add(conn_handle) elif event == _IRQ_CENTRAL_DISCONNECT: conn_handle, _, _ = data print("Disconnected", conn_handle) self._connections.remove(conn_handle) self._advertise() elif event == _IRQ_GATTS_WRITE: conn_handle, value_handle = data value = self._ble.gatts_read(value_handle) if value_handle == self._handle_rx and self._write_callback: self._write_callback(value) def send(self, data): for conn_handle in self._connections: self._ble.gatts_notify(conn_handle, self._handle_tx, data) def is_connected(self): return len(self._connections) > 0 def _advertise(self, interval_us=500000): print("Starting advertising") self._ble.gap_advertise(interval_us, adv_data=self._payload) def on_write(self, callback): self._write_callback = callback def demo(): led_onboard = Pin("LED", Pin.OUT) ble = bluetooth.BLE() p = BLESimplePeripheral(ble) def on_rx(v): print("RX", v) p.on_write(on_rx) i = 0 while True: if p.is_connected(): led_onboard.on() for _ in range(3): data = str(i) + "_" print("TX", data) p.send(data) i += 1 time.sleep_ms(100) if __name__ == "__main__": demo() 

and the ble_advertising file which is also saved on the pi is as follows.

 from micropython import const import struct import bluetooth _ADV_TYPE_FLAGS = const(0x01) _ADV_TYPE_NAME = const(0x09) _ADV_TYPE_UUID16_COMPLETE = const(0x3) _ADV_TYPE_UUID32_COMPLETE = const(0x5) _ADV_TYPE_UUID128_COMPLETE = const(0x7) _ADV_TYPE_UUID16_MORE = const(0x2) _ADV_TYPE_UUID32_MORE = const(0x4) _ADV_TYPE_UUID128_MORE = const(0x6) _ADV_TYPE_APPEARANCE = const(0x19) def advertising_payload(limited_disc=False, br_edr=False, name=None, services=None, appearance=0): payload = bytearray() def _append(adv_type, value): nonlocal payload payload += struct.pack("BB", len(value) + 1, adv_type) + value _append( _ADV_TYPE_FLAGS, struct.pack("B", (0x01 if limited_disc else 0x02) + (0x18 if br_edr else 0x04)), ) if name: _append(_ADV_TYPE_NAME, name) if services: for uuid in services: b = bytes(uuid) if len(b) == 2: _append(_ADV_TYPE_UUID16_COMPLETE, b) elif len(b) == 4: _append(_ADV_TYPE_UUID32_COMPLETE, b) elif len(b) == 16: _append(_ADV_TYPE_UUID128_COMPLETE, b) if appearance: _append(_ADV_TYPE_APPEARANCE, struct.pack("<h", appearance)) return payload def decode_field(payload, adv_type): i = 0 result = [] while i + 1 < len(payload): if payload[i + 1] == adv_type: result.append(payload[i + 2 : i + payload[i] + 1]) i += 1 + payload[i] return result def decode_name(payload): n = decode_field(payload, _ADV_TYPE_NAME) return str(n[0], "utf-8") if n else "" def decode_services(payload): services = [] for u in decode_field(payload, _ADV_TYPE_UUID16_COMPLETE): services.append(bluetooth.UUID(struct.unpack("<h", u)[0])) for u in decode_field(payload, _ADV_TYPE_UUID32_COMPLETE): services.append(bluetooth.UUID(struct.unpack("<d", u)[0])) for u in decode_field(payload, _ADV_TYPE_UUID128_COMPLETE): services.append(bluetooth.UUID(u)) return services def demo(): payload = advertising_payload( name="micropython", services=[bluetooth.UUID(0x181A), bluetooth.UUID("6E400001-B5A3-F393-E0A9-E50E24DCCA9E")], ) print(payload) print(decode_name(payload)) print(decode_services(payload)) if __name__ == "__main__": demo() 

UPDATE: If need be i will be willing to use HC-05 module but im not sure that will make a difference. i just need an iphone and android to connect and play bluetooth music to be translated to my speaker setup which already plays tones.

3
  • are you sure you are calling advertising_payload correctly? Commented Dec 31, 2024 at 4:47
  • yes because i if i remove the import it will fail, and the tutorial explains Commented Dec 31, 2024 at 4:49
  • I didn't say remove the import, I said CALL the function - I'm no pythin expert, hardly, but it looks like you should be calling it with appearance=something if you want to _append(_ADV_TYPE_APPEARANCE, struct.pack("<h", appearance)) Commented Dec 31, 2024 at 4:51

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.