Плата Arduino Nano 33 BLE Sense представляет собой прекрасное аппаратное обеспечение, напичканное датчиками и достаточно мощное, чтобы запускать модели машинного обучения с использованием TinyML. Она также оснащена Bluetooth LE (BLE) и может служить центральным или периферийным устройством.

В данном проекте будет показано, как вы можете управлять своим Arduino Nano BLE, считывать значения датчиков и активировать элементы управления, связываясь с ним через Bluetooth с помощью Python, например, с компьютера Windows, Mac или Linux, такого как Raspberry Pi. Это откроет массу возможностей.
В данном проекте будет продемонстровано использование встроенного RGB-светодиода Arduino Nano 33 BLE Sense, но он переполнен также различными датчиками, поэтому вы можете использовать ту же структуру и добавить в программу код для других датчиков и исполнительных механизмов. Чтобы разместить Arduino Nano 33 BLE Sense и обеспечить возможность использования большего количества компонентов и схем в будущем, мы использовали корпус ProtoStax.

Общий профиль атрибутов (или GATT) определяет, как устройства Bluetooth LE могут передавать данные туда и обратно, используя протокол атрибутов (или ATT), который иерархически организует данные в службы и характеристики. Для нашей цели мы определяем сервис верхнего уровня, а также 3 характеристики, соответствующие каждому из 3 цветов нашего светодиода RGB.
BLEService nanoService("13012F00-F8C3-4F4A-A8F4-15CD926DA146");
BLEByteCharacteristic redLEDCharacteristic("13012F01-F8C3-4F4A-A8F4-15CD926DA146", BLERead | BLEWrite);
BLEByteCharacteristic greenLEDCharacteristic("13012F02-F8C3-4F4A-A8F4-15CD926DA146", BLERead | BLEWrite);
BLEByteCharacteristic blueLEDCharacteristic("13012F03-F8C3-4F4A-A8F4-15CD926DA146", BLERead | BLEWrite);
Используемые выше UUID были сгенерированы случайным образом. Они должны совпадать между периферийным устройством (Nano) и центральным устройством (программой Python). В нашей функции настройки, помимо настройки pinMode для светодиодов RGB, мы также настраиваем нашу службу BLE. Здесь мы устанавливаем локальное имя для нашего периферийного устройства BLE – центральные устройства будут видеть это при попытке подключиться к сервисам вещания. Добавляем сервис и характеристики, которые мы определили выше, устанавливаем их начальные значения и запускаем вещание. Здесь, на этом этапе, центральные устройства, которые прослушивают, увидят наши вещательные пакеты и узнают, что мы готовы принимать соединения.
BLE.setLocalName("Arduino Nano 33 BLE Sense");
BLE.setAdvertisedService(nanoService);
nanoService.addCharacteristic(redLEDCharacteristic);
nanoService.addCharacteristic(greenLEDCharacteristic);
nanoService.addCharacteristic(blueLEDCharacteristic);
BLE.addService(nanoService);
redLEDCharacteristic.writeValue(0);
greenLEDCharacteristic.writeValue(0);
blueLEDCharacteristic.writeValue(0);
BLE.advertise();
В нашем основном цикле loop() мы ждем подключения центрального устройства. Затем мы ждем, чтобы увидеть, записаны ли какие-либо характеристики, и значение этой характеристики. В нашем примере ненулевое значение, записанное, например, в redLEDCharacteristic, заставит нас включить КРАСНЫЙ светодиод. При обнаружении нулевого значения выключаем светодиод.
void loop() {
BLEDevice central = BLE.central();
if (central) {
...
while (central.connected()) {
if (redLEDCharacteristic.written()) {
if (redLEDCharacteristic.value()) {
Serial.println("RED LED on");
digitalWrite(RED_PIN, LOW);
} else {
Serial.println(F("RED LED off"));
digitalWrite(RED_PIN, HIGH);
}
}
....
}
Serial.print(F("Disconnected from central: "));
Serial.println(central.address());
}
}
Здесь мы должны отметить, что светодиоды RGB на Arduino Nano 33 BLE Sense следуют обратной логике, поэтому установка вывода LOW включает светодиод, а установка HIGH выключает его. Встроенный светодиод RGB также не поддерживает ШИМ, поэтому состояния светодиодов могут быть включены или выключены, что дает нам 7 разных цветов.
R | G | B
OFF | OFF | OFF - OFF
ON | OFF | OFF - RED
OFF | ON | OFF - GREEN
OFF | OFF | ON - BLUE
ON | ON | OFF - ORANGE
ON | OFF | ON - PURPLE
OFF | ON | ON - CYAN
ON | ON | ON - WHITE
Центральное устройство также может считывать значение характеристики. Это автоматически обрабатывается библиотекой BLE, и нам больше ничего делать не нужно. Мы инициализируем значение соответствующим образом при запуске и поддерживаем значение, чтобы его можно было прочитать в любое время.
На стороне Python мы используем библиотеку для поддержки BLE Python bleak library for BLE support – конечно, машина, на которой мы ее запускаем, также должна иметь поддержку Bluetooth. Мы также используем асинхронную структуру asyncio для нашей программы. Наш главный цикл – это функция run(). Он переходит в режим обнаружения и проверяет локальные имена устройств Bluetooth, которые вещают, и подключается к устройству с локальным именем «Arduino Nano 33 BLE Sense» (выбранное нами локальное имя). Затем он параметрв RED, GREEN и BLUE, чтобы узнать начальные состояния светодиодов, а затем переходит в цикл setColor().
async def run():
global RED, GREEN, BLUE
print('ProtoStax Arduino Nano BLE LED Peripheral Central Service')
print('Looking for Arduino Nano 33 BLE Sense Peripheral Device...')
found = False
devices = await discover()
for d in devices:
if 'Arduino Nano 33 BLE Sense'in d.name:
print('Found Arduino Nano 33 BLE Sense Peripheral')
found = True
async with BleakClient(d.address) as client:
print(f'Connected to {d.address}')
val = await client.read_gatt_char(RED_LED_UUID)
if (val == on_value):
print ('RED ON')
RED = True
else:
print ('RED OFF')
RED = False
... do similar stuff for GREEN and BLUE
while True:
await setColor(client)
if not found:
print('Could not find Arduino Nano 33 BLE Sense Peripheral')
В setColor() он запрашивает ввод данных пользователем и проверяет вводимые пользователем данные, чтобы увидеть, есть ли в строке какие-либо значения «r», «g» или «b». Затем он переключает цвет и записывает соответствующее значение в характеристику и снова ждет дальнейшего ввода пользователем. Это продолжается до тех пор, пока пользователь не нажмет Control-C, чтобы остановить программу.
async def setColor(client):
global RED, GREEN, BLUE
val = input('Enter rgb to toggle red, green and blue LEDs :')
print(val)
if ('r' in val):
RED = not RED
await client.write_gatt_char(RED_LED_UUID, getValue(RED))
... то же самое для GREEN и BLUE
Arduino Nano имеет на борту целый набор датчиков. Вы можете расширить проект, добавив характеристики для других датчиков – например, считывая значения температуры, влажности и давления.
© digitrode.ru