#do you know that the `I92` is putting
1 messages · Page 1 of 1 (latest)
this is a long shot, but you could try doing .write(b'I92\n') to send that startup string all at once
while uart_connection.connected:
is the print statement in that loop above printing anything, and if so, how often?
.write(b'I92\n') was my first version, but since reading things did not work I reverted to wording that was more identical to your example
Every 1 second a newline is printed
-and I92 is not a startup command, it is just a command to check if sending commands works
all other commands execute text reply, only 92 executes blue leds
so once you send the I92 does the device need anything else sent to it? Change the print to print(repr(uart_connection.read(20)). I just want to know exactly what it's getting
but is it supposed to send something every once in a while even if nothing is happening? What shows up on the Adafruit Blufruit Connect app if you connect?
in the app sentences appear regularily they are event-texts, so report on events in the box
b''
every second a b''
sorry - that is from the print(repr code
got it
from the app, typically 'evTimerA'
I forgot to ask, where are you running the program that is reading from the device? Is it on a PC under blinka_bleio, or is it on some other board?
Running on a Feather nRF52840
what version of CircuitPython
7.3.3
please try 9.1.0 with the latest libraries
good night!
Good morning!
Unfortunately with 9.1.0 it still does not read anything. 😦
Found this Java, it seems to do som enable notification in the GATT protocol?
void enableNotification(BluetoothGattService gattService, String characteristicUUID, boolean enable) {
ServiceAction action = serviceNotifyAction(gattService, characteristicUUID, enable);
mQueue.add(action);
}
private BleGattExecutor.ServiceAction serviceNotifyAction(final BluetoothGattService gattService, final String characteristicUuidString, final boolean enable) {
return new BleGattExecutor.ServiceAction() {
@Override
public boolean execute(BluetoothGatt bluetoothGatt) {
if (characteristicUuidString != null) {
final UUID characteristicUuid = UUID.fromString(characteristicUuidString);
final BluetoothGattCharacteristic dataCharacteristic = gattService.getCharacteristic(characteristicUuid);
if (dataCharacteristic == null) {
Log.w(TAG, "Characteristic with UUID " + characteristicUuidString + " not found");
return true;
}
final UUID clientCharacteristicConfiguration = UUID.fromString(CHARACTERISTIC_CONFIG);
final BluetoothGattDescriptor config = dataCharacteristic.getDescriptor(clientCharacteristicConfiguration);
if (config == null)
return true;
// enableNotification/disable locally
bluetoothGatt.setCharacteristicNotification(dataCharacteristic, enable);
// enableNotification/disable remotely
config.setValue(enable ? BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE : BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
bluetoothGatt.writeDescriptor(config);
return false;
} else {
Log.w(TAG, "Characteristic UUID is null");
return true;
}
}
};
}
I found this educational text:
Notifications and Indications must be subscribed to by the client before the server can send them. This subscription is performed by writing to a descriptor (Client Characteristic Configuration Descriptor) of the characteristic that the client would like to subscribe to.
at https://punchthrough.com/ble-connectivity-architecture/
Sorry to bog you down with this. It is hard to let go of a problem unsolved.
Here it is - now I only need to know how to subscribe:
LightBlue is a very nice app!
The subscribe should already be happening automatically.
I'm pasting this here for reference:
i'm going to compare that with our own impl
The subscribe does happen automatically in most apps (except LightBlue which exposes it to the user), but my Feather is not doing any Subscribe action. I believe I must write some flags to the Characteristics, but I do not know how. https://docs.circuitpython.org/projects/ble/en/latest/characteristics.html#
could you upload your code here again? It's lost in main channel
never mind found out
Sorry, I was out for a moment
I'm trying to reproduce. I see problems but not sure why
Are you using another nRF52 as peripheral/server?
Or, are you connecting to a non-Adafruit device/product like I do?
I am using another nRF52 as a server (call it P). When I connect to that in Bluefruit Connect, etc., it works fine. I think the problem is on the central side (call it C) -- the notification push is not showing up. I do get stuff from SPwhen I write from C to P. In other words each time I write from C to P (like the "I92"), one value gets through.
Not sure I understood: I do get stuff from SPwhen I write from C to P. ?
Are you getting anything from P to C at all?
I have a C test program that writes "I92" and the "\n" to P.
The P test program logs what it receives and also writes the current time every two seconds.
Central side:
from adafruit_ble import BLERadio
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.nordic import UARTService
import time
ble = BLERadio()
uart_connection = None
while True:
if not uart_connection:
print("Trying to connect...")
for adv in ble.start_scan(ProvideServicesAdvertisement):
print(".")
if UARTService in adv.services:
uart_connection = ble.connect(adv)
print("Connected")
break
ble.stop_scan()
if uart_connection and uart_connection.connected:
uart_service = uart_connection[UARTService]
try:
uart_service.write('I92'.encode('utf-8'))
uart_service.write(b'\n')
except:
print('Command failed to tx')
time.sleep(0.1)
while uart_connection.connected:
if uart_service.in_waiting:
print(uart_service.read(uart_service.in_waiting))
peripheral side:
from adafruit_ble import BLERadio
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.nordic import UARTService
import time
ble = BLERadio()
uart = UARTService()
advertisement = ProvideServicesAdvertisement(uart)
while True:
ble.start_advertising(advertisement)
while not ble.connected:
pass
print("connected")
while ble.connected:
if uart.in_waiting:
print("got", uart.read(uart.in_waiting))
uart.write(str(time.monotonic()).encode())
time.sleep(2)
print("disconnected")
If I connect to the P from Bluefruit connect, I get time numbers every two seconds.
I am going to try a C on Espressif and see what its behavior is
C on Espressif works fine, so it's something peculiar with the C on nRF. I'll debug that.
Espressif:
Trying to connect...
.
Connected
b'6961.29'
b'6963.29'
b'6965.29'
...
Now I'll try some older versions. (I know you were trying with 7.3.3 earlier).
This is weird. "something peculiar on nRF" indeed.
The side effect of this trouble is that I have read up on BLE, GATT, Central, etc. So, at least I understand BLE better.
But I have no more ideas where to look further.
This is a bug. I'll track it down. It's not your code.
still debugging. It all of a sudden started working fine, which was very mysterious. restarting either Central or Periphal in either order did not matter. Then I went away for an hour, and it stopped working again completely.
@regal creek does your device continue to advertise when it is connected? For instance, could more than one central connect to it at a time.
No, the device does not continue to advertise - it is no longer visible on any of the apps.
-sounds like timing issue; a wait which is on the borderline too tight
FYI - I'm continuing to debug this. I got some packet traces for a case that does not work (periph is espressif) and one that does (perfiph is nRF), and there are some small but interesting differences. Will get back to you later -- it may take a few days
This is very interesting!
I will take my wife for an overnight sailboat trip tomorrow, so I guess I will check in here again a few days from now.
@regal creek I may have a fix for you. See
https://github.com/adafruit/circuitpython/pull/9441
build artifacts to try here:
https://github.com/adafruit/circuitpython/actions/runs/10016015063?pr=9441
@steep spruce Looks good, but I am not fluent enough to understand the problem/fix entirely. Also I am not fluent in Github, so I do not know how to find the relevant artifact - assuming that refers to a new uf2 file?
The artifacts (scroll down the page) are zip files containing UF2 files. However, since then, I've merged the change, so you can now access the UF2 file more easily here:
https://adafruit-circuit-python.s3.amazonaws.com/index.html?prefix=bin/feather_nrf52840_express/en_US/. Look for the the latest uf2, which has "PR9441" in the filename (or anything after that). If that's not the right board, you can nativate upwards to the right board directory.
@steep spruce After some initial trouble (old code.py made the board crash on start) I successfully ran my Client code, and it works fine. Thanks a bunch for the support and help!
thanks for testing! That fix will be in CircuitPython 9.1.1 and later.