|
| 1 | +--- |
| 2 | +author: 'Karl Söderby' |
| 3 | +title: 'Nano 33 BLE Python® Guide' |
| 4 | +description: 'Discover how to access the features on the Nano 33 BLE using Python® scripts.' |
| 5 | +compatible-products: [nano-33-ble] |
| 6 | +tags: |
| 7 | + - MicroPython |
| 8 | + - OpenMV |
| 9 | +featuredImage: 'board' |
| 10 | +--- |
| 11 | + |
| 12 | + |
| 13 | + |
| 14 | +The [Nano 33 BLE](https://store.arduino.cc/arduino-nano-33-ble-sense) board can be programmed using the popular **Python®** programming language. More specifically, it supports [OpenMV's fork of MicroPython](https://github.com/openmv/micropython), where MicroPython is an implementation of the Python® language, designed to run on microcontrollers. In this article, you will find a lot of sample scripts that will work directly with your Nano 33 BLE, such as general GPIO control, reading data from the IMU module and testing Bluetooth® Low Energy connection. |
| 15 | + |
| 16 | +- If you want to read more about Arduino & Python®, you can visit the [Python® with Arduino](/learn/programming/arduino-and-python) article. Here you will find a lot of useful examples, such as how to use delays, interrupts, reading pins and more general functions. |
| 17 | + |
| 18 | +***If you are looking for information related to the similar Nano 33 BLE Sense board, you can refer to the [Nano 33 BLE Sense Python® Guide](/tutorials/nano-33-ble-sense/ble-sense-python-api).*** |
| 19 | + |
| 20 | +## Hardware & Software Needed |
| 21 | + |
| 22 | +- [Arduino Nano 33 BLE](https://store.arduino.cc/nano-33-ble). |
| 23 | +- [OpenMV IDE](https://openmv.io/pages/download) |
| 24 | + |
| 25 | +***This guide does not cover the installation of OpenMV and MicroPython on your board. Please refer to [Getting started with OpenMV and Nano 33 BLE](/tutorials/nano-33-ble/getting-started-omv) for a detailed guide.*** |
| 26 | + |
| 27 | +## API |
| 28 | + |
| 29 | +Below you will find a lot of useful examples that can be loaded to your Nano 33 BLE board. Many of these examples were extracted from the [OpenMV repository](https://github.com/openmv/openmv), where you can find many useful examples for other boards as well. |
| 30 | + |
| 31 | +***In this article, you will only find examples for the Nano 33 BLE board. For more information on how to use delays, read and write to pins, please refer to the [Python® with Arduino](/learn/programming/arduino-and-python) main article.*** |
| 32 | + |
| 33 | +## Pin Control |
| 34 | + |
| 35 | +The pinout for the **Nano 33 BLE** and the **NRF52840 microcontroller** varies greatly. For example, if we are to use `D2` according to the Arduino pinout, we would actually need to use **pin 43**. |
| 36 | + |
| 37 | +```python |
| 38 | +# Defining "D2" on the Nano 33 BLE |
| 39 | +p0 = Pin(43, Pin.OUT) |
| 40 | +``` |
| 41 | + |
| 42 | +***In the MicroPython port of the Nano 33 BLE board, the pinout is the same as the Nordic NRF52840 (the microcontroller). You will find a GPIO Map below this section that explains how to address the different pins.*** |
| 43 | + |
| 44 | +### Pin Map |
| 45 | + |
| 46 | +Before you start using the board's pins, it might be a good idea to check out the table below to understand the relationship between Arduino's pinout and the NRF52840's pinout. |
| 47 | + |
| 48 | +| Arduino | nRF52840 | |
| 49 | +| ------- | -------- | |
| 50 | +| TX | 35 | |
| 51 | +| RX | 42 | |
| 52 | +| D2 | 43 | |
| 53 | +| D3 | 44 | |
| 54 | +| D4 | 47 | |
| 55 | +| D5 | 45 | |
| 56 | +| D6 | 46 | |
| 57 | +| D7 | 23 | |
| 58 | +| D8 | 21 | |
| 59 | +| D9 | 27 | |
| 60 | +| D10 | 34 | |
| 61 | +| D11 | 33 | |
| 62 | +| D12 | 40 | |
| 63 | +| D13 | 13 | |
| 64 | +| D14/A0 | 4 | |
| 65 | +| D15/A1 | 5 | |
| 66 | +| D16/A2 | 30 | |
| 67 | +| D17/A3 | 29 | |
| 68 | +| D18/A4 | 31 | |
| 69 | +| D19/A5 | 2 | |
| 70 | +| D20/A6 | 28 | |
| 71 | +| D21/A7 | 3 | |
| 72 | + |
| 73 | +### Analog Pins |
| 74 | + |
| 75 | +To read the analog pins on the Nano BLE , we can choose from the following pins: |
| 76 | + |
| 77 | +- A0 - `4` |
| 78 | +- A1 - `5` |
| 79 | +- A2 - `30` |
| 80 | +- A3 - `29` |
| 81 | +- A4 - `31` |
| 82 | +- A5 - `2` |
| 83 | +- A6 - `28` |
| 84 | +- A7 - `3` |
| 85 | + |
| 86 | +To define them, we need to import the `machine` module, and define the pin as follows: |
| 87 | + |
| 88 | +```python |
| 89 | +import machine |
| 90 | + |
| 91 | +adc_pin = machine.Pin(29) |
| 92 | +adc = machine.ADC(adc_pin) |
| 93 | +``` |
| 94 | + |
| 95 | +To read the analog pin, simply use: |
| 96 | + |
| 97 | +```python |
| 98 | +reading = adc.read_u16() #16-bit resolution (0-65535) |
| 99 | +``` |
| 100 | + |
| 101 | +The below script will read the `A3` pin on the board and print the value in the terminal. |
| 102 | + |
| 103 | +```python |
| 104 | +import machine |
| 105 | +import time |
| 106 | + |
| 107 | +adc_pin = machine.Pin(29) # A3 |
| 108 | +adc = machine.ADC(adc_pin) |
| 109 | + |
| 110 | +while True: |
| 111 | + reading = adc.read_u16() |
| 112 | + print("ADC: ",reading) |
| 113 | + time.sleep_ms(500) |
| 114 | +``` |
| 115 | + |
| 116 | +## LED Control |
| 117 | + |
| 118 | +There are 3 different LEDs that can be accessed on the Nano BLE: **RGB, the built-in LED** and the **power LED**. |
| 119 | + |
| 120 | +They can be accessed by importing the `LED` module, where the RGB and built-in LED can be accessed. |
| 121 | + |
| 122 | +```python |
| 123 | +from board import LED |
| 124 | + |
| 125 | +led_red = LED(1) # red LED |
| 126 | +led_green = LED(2) # green LED |
| 127 | +led_blue = LED(3) # blue LED |
| 128 | +led_builtin = LED(4) # classic built-in LED (also accessible through pin 13) |
| 129 | +``` |
| 130 | + |
| 131 | +To access the **power LED** we need to import the `Pin` module. |
| 132 | + |
| 133 | +```python |
| 134 | +from machine import Pin |
| 135 | + |
| 136 | +led_pwr = Pin(41, Pin.OUT) |
| 137 | +``` |
| 138 | + |
| 139 | +### RGB |
| 140 | + |
| 141 | +Blink all RGB lights every 0.25 seconds. |
| 142 | + |
| 143 | +```python |
| 144 | +from board import LED |
| 145 | +import time |
| 146 | + |
| 147 | +led_red = LED(1) |
| 148 | +led_green = LED(2) |
| 149 | +led_blue = LED(3) |
| 150 | + |
| 151 | +while (True): |
| 152 | + |
| 153 | + # Turn on LEDs |
| 154 | + led_red.on() |
| 155 | + led_green.on() |
| 156 | + led_blue.on() |
| 157 | + |
| 158 | + # Wait 0.25 seconds |
| 159 | + time.sleep_ms(250) |
| 160 | + |
| 161 | + # Turn off LEDs |
| 162 | + led_red.off() |
| 163 | + led_green.off() |
| 164 | + led_blue.off() |
| 165 | + |
| 166 | + # Wait 0.25 seconds |
| 167 | + time.sleep_ms(250) |
| 168 | +``` |
| 169 | + |
| 170 | +### Built-in LED |
| 171 | + |
| 172 | +The classic blink example! Blink the built-in LED every 0.25 seconds. |
| 173 | + |
| 174 | +```python |
| 175 | +from board import LED |
| 176 | +import time |
| 177 | + |
| 178 | +led_builtin = LED(4) |
| 179 | + |
| 180 | +while (True): |
| 181 | + |
| 182 | + # Turn on LED |
| 183 | + led_builtin.on() |
| 184 | + |
| 185 | + # Wait 0.25 seconds |
| 186 | + time.sleep_ms(250) |
| 187 | + |
| 188 | + # Turn off LED |
| 189 | + led_builtin.off() |
| 190 | + |
| 191 | + # Wait 0.25 seconds |
| 192 | + time.sleep_ms(250) |
| 193 | + |
| 194 | +``` |
| 195 | + |
| 196 | +## IMU (LSM9DS1) |
| 197 | + |
| 198 | +Access the `accelerometer`, `magnetometer`, and `gyroscope` data from the LSM9DS1 IMU module. |
| 199 | + |
| 200 | +```python |
| 201 | +import time |
| 202 | +import lsm9ds1 |
| 203 | +from machine import Pin, I2C |
| 204 | + |
| 205 | +bus = I2C(1, scl=Pin(15), sda=Pin(14)) |
| 206 | +lsm = lsm9ds1.LSM9DS1(bus) |
| 207 | + |
| 208 | +while (True): |
| 209 | + #for g,a in lsm.iter_accel_gyro(): print(g,a) # using fifo |
| 210 | + print('Accelerometer: x:{:>8.3f} y:{:>8.3f} z:{:>8.3f}'.format(*lsm.read_accel())) |
| 211 | + print('Magnetometer: x:{:>8.3f} y:{:>8.3f} z:{:>8.3f}'.format(*lsm.read_magnet())) |
| 212 | + print('Gyroscope: x:{:>8.3f} y:{:>8.3f} z:{:>8.3f}'.format(*lsm.read_gyro())) |
| 213 | + print("") |
| 214 | + time.sleep_ms(500) |
| 215 | +``` |
| 216 | + |
| 217 | + |
| 218 | + |
| 219 | +## Bluetooth® Low Energy |
| 220 | + |
| 221 | +This example allows us to connect to our board via our phone, and control the built-in LED. We recommend using the **nRF Connect** applications. |
| 222 | + |
| 223 | +- [nRF desktop](https://www.nordicsemi.com/Products/Development-tools/nrf-connect-for-desktop) |
| 224 | +- [nRF mobile](https://www.nordicsemi.com/Products/Development-tools/nrf-connect-for-mobile) |
| 225 | + |
| 226 | +***After loading the script below, your board should be listed as "Nano 33 BLE" in the list of available devices. You need to pair in order to control the built-in LED.*** |
| 227 | + |
| 228 | +```python |
| 229 | +# Use nRF Connect from App store, connect to the Nano and write 1/0 to control the LED. |
| 230 | + |
| 231 | +import time |
| 232 | +from board import LED |
| 233 | +from ubluepy import Service, Characteristic, UUID, Peripheral, constants |
| 234 | + |
| 235 | +def event_handler(id, handle, data): |
| 236 | + global periph |
| 237 | + global service |
| 238 | + if id == constants.EVT_GAP_CONNECTED: |
| 239 | + pass |
| 240 | + elif id == constants.EVT_GAP_DISCONNECTED: |
| 241 | + # restart advertisement |
| 242 | + periph.advertise(device_name="Nano 33 BLE", services=[service]) |
| 243 | + elif id == constants.EVT_GATTS_WRITE: |
| 244 | + LED(1).on() if int(data[0]) else LED(1).off() |
| 245 | + |
| 246 | +# start off with LED(1) off |
| 247 | +LED(1).off() |
| 248 | + |
| 249 | +notif_enabled = False |
| 250 | +uuid_service = UUID("0x1523") |
| 251 | +uuid_led = UUID("0x1525") |
| 252 | + |
| 253 | +service = Service(uuid_service) |
| 254 | +char_led = Characteristic(uuid_led, props=Characteristic.PROP_WRITE) |
| 255 | +service.addCharacteristic(char_led) |
| 256 | + |
| 257 | +periph = Peripheral() |
| 258 | +periph.addService(service) |
| 259 | +periph.setConnectionHandler(event_handler) |
| 260 | +periph.advertise(device_name="Nano 33 BLE", services=[service]) |
| 261 | + |
| 262 | +while (True): |
| 263 | + time.sleep_ms(500) |
| 264 | +``` |
| 265 | + |
| 266 | +## Summary |
| 267 | + |
| 268 | +In this article we have gone through a selection of scripts that will help you control your Nano BLE board, via the OpenMV IDE. Feel free to check out our [Python® with Arduino boards article](/learn/programming/arduino-and-python), where you can find guides to other boards, useful links to learn Python® and more. |
0 commit comments