diff --git a/scripts/examples/Arduino/Nano-RP2040/00-Basics/blinky.py b/scripts/examples/Arduino/Nano-RP2040/00-Basics/blinky.py new file mode 100644 index 000000000..6a4c54232 --- /dev/null +++ b/scripts/examples/Arduino/Nano-RP2040/00-Basics/blinky.py @@ -0,0 +1,14 @@ +# Blinky example + +import time +from machine import Pin + +# This is the only LED pin available on the Nano RP2040, +# other than the RGB LED connected to Nina WiFi module. +led = Pin(6, Pin.OUT) + +while (True): + led.on() + time.sleep_ms(250) + led.off() + time.sleep_ms(250) diff --git a/scripts/examples/Arduino/Nano-RP2040/00-Basics/i2c_scanner.py b/scripts/examples/Arduino/Nano-RP2040/00-Basics/i2c_scanner.py new file mode 100644 index 000000000..7a07fd3f6 --- /dev/null +++ b/scripts/examples/Arduino/Nano-RP2040/00-Basics/i2c_scanner.py @@ -0,0 +1,18 @@ +# I2C scanner examples +# +# 7-bit addresses for NANO RP2040 on I2C0 bus: +# +# ATECC608A 0x60 +# LSM6DSOX 0x6A + +import time +from machine import Pin, I2C + +i2c_list = [None, None] +i2c_list[0] = I2C(0, scl=Pin(13), sda=Pin(12), freq=100_000) +i2c_list[1] = I2C(1, scl=Pin(7), sda=Pin(6), freq=100_000) + +for bus in range(0, 2): + print("\nScanning bus %d..."%(bus)) + for addr in i2c_list[bus].scan(): + print("Found device at addres %d:0x%x" %(bus, addr)) diff --git a/scripts/examples/Arduino/Nano-RP2040/01-Sensors/lsm6dsox.py b/scripts/examples/Arduino/Nano-RP2040/01-Sensors/lsm6dsox.py new file mode 100644 index 000000000..29146b0f8 --- /dev/null +++ b/scripts/examples/Arduino/Nano-RP2040/01-Sensors/lsm6dsox.py @@ -0,0 +1,12 @@ +# LSM9DS1 Gyro example. +import time +from lsm6dsox import LSM6DSOX + +from machine import Pin, I2C +lsm = LSM6DSOX(I2C(0, scl=Pin(13), sda=Pin(12))) + +while (True): + print('Accelerometer: x:{:>8.3f} y:{:>8.3f} z:{:>8.3f}'.format(*lsm.read_accel())) + print('Gyroscope: x:{:>8.3f} y:{:>8.3f} z:{:>8.3f}'.format(*lsm.read_gyro())) + print("") + time.sleep_ms(100) diff --git a/scripts/examples/Arduino/Nano-RP2040/02-Bluetooth/ble_blinky.py b/scripts/examples/Arduino/Nano-RP2040/02-Bluetooth/ble_blinky.py new file mode 100644 index 000000000..d03306d92 --- /dev/null +++ b/scripts/examples/Arduino/Nano-RP2040/02-Bluetooth/ble_blinky.py @@ -0,0 +1,59 @@ +# Bluetooth Blinky Example +# +# Use nRFConnect app from the App store, connect to the Nano and write 1/0 to control the LED. + +import bluetooth +import random +import struct +import time +from ble_advertising import advertising_payload +from machine import Pin +from micropython import const + +LED_PIN = 6 + +_IRQ_CENTRAL_CONNECT = const(1) +_IRQ_CENTRAL_DISCONNECT = const(2) +_IRQ_GATTS_WRITE = const(3) + +_FLAG_READ = const(0x0002) +_FLAG_WRITE = const(0x0008) +_FLAG_NOTIFY = const(0x0010) +_FLAG_INDICATE = const(0x0020) + +_SERVICE_UUID = bluetooth.UUID(0x1523) +_LED_CHAR_UUID = (bluetooth.UUID(0x1525), _FLAG_WRITE) +_LED_SERVICE = (_SERVICE_UUID, (_LED_CHAR_UUID,),) + +class BLETemperature: + def __init__(self, ble, name="NANO RP2040"): + self._ble = ble + self._ble.active(True) + self._ble.irq(self._irq) + ((self._handle,),) = self._ble.gatts_register_services((_LED_SERVICE,)) + self._connections = set() + self._payload = advertising_payload(name=name, services=[_SERVICE_UUID]) + self._advertise() + + def _irq(self, event, data): + # Track connections so we can send notifications. + if event == _IRQ_CENTRAL_CONNECT: + conn_handle, _, _ = data + self._connections.add(conn_handle) + elif event == _IRQ_CENTRAL_DISCONNECT: + conn_handle, _, _ = data + self._connections.remove(conn_handle) + # Start advertising again to allow a new connection. + self._advertise() + elif event == _IRQ_GATTS_WRITE: + Pin(LED_PIN, Pin.OUT).value(int(self._ble.gatts_read(data[-1])[0])) + + def _advertise(self, interval_us=500000): + self._ble.gap_advertise(interval_us, adv_data=self._payload) + +if __name__ == "__main__": + ble = bluetooth.BLE() + temp = BLETemperature(ble) + + while True: + time.sleep_ms(1000) diff --git a/scripts/examples/Arduino/Nano-RP2040/02-Bluetooth/ble_temperature.py b/scripts/examples/Arduino/Nano-RP2040/02-Bluetooth/ble_temperature.py new file mode 100644 index 000000000..b55fe4680 --- /dev/null +++ b/scripts/examples/Arduino/Nano-RP2040/02-Bluetooth/ble_temperature.py @@ -0,0 +1,97 @@ +# This example demonstrates a simple temperature sensor peripheral. +# +# The sensor's local value updates every second, and it will notify +# any connected central every 10 seconds. + +import bluetooth +import random +import struct +import time +from ble_advertising import advertising_payload +from machine import Pin +from micropython import const + +LED_PIN = 6 + +_IRQ_CENTRAL_CONNECT = const(1) +_IRQ_CENTRAL_DISCONNECT = const(2) +_IRQ_GATTS_INDICATE_DONE = const(20) + +_FLAG_READ = const(0x0002) +_FLAG_NOTIFY = const(0x0010) +_FLAG_INDICATE = const(0x0020) + +# org.bluetooth.service.environmental_sensing +_ENV_SENSE_UUID = bluetooth.UUID(0x181A) +# org.bluetooth.characteristic.temperature +_TEMP_CHAR = ( + bluetooth.UUID(0x2A6E), + _FLAG_READ | _FLAG_NOTIFY | _FLAG_INDICATE, +) +_ENV_SENSE_SERVICE = ( + _ENV_SENSE_UUID, + (_TEMP_CHAR,), +) + +# org.bluetooth.characteristic.gap.appearance.xml +_ADV_APPEARANCE_GENERIC_THERMOMETER = const(768) + + +class BLETemperature: + def __init__(self, ble, name="NANO RP2040"): + self._ble = ble + self._ble.active(True) + self._ble.irq(self._irq) + ((self._handle,),) = self._ble.gatts_register_services((_ENV_SENSE_SERVICE,)) + self._connections = set() + self._payload = advertising_payload( + name=name, services=[_ENV_SENSE_UUID], appearance=_ADV_APPEARANCE_GENERIC_THERMOMETER + ) + self._advertise() + + def _irq(self, event, data): + # Track connections so we can send notifications. + if event == _IRQ_CENTRAL_CONNECT: + conn_handle, _, _ = data + self._connections.add(conn_handle) + Pin(LED_PIN, Pin.OUT).high() + elif event == _IRQ_CENTRAL_DISCONNECT: + conn_handle, _, _ = data + self._connections.remove(conn_handle) + # Start advertising again to allow a new connection. + self._advertise() + Pin(LED_PIN, Pin.OUT).low() + elif event == _IRQ_GATTS_INDICATE_DONE: + conn_handle, value_handle, status = data + + def set_temperature(self, temp_deg_c, notify=False, indicate=False): + # Data is sint16 in degrees Celsius with a resolution of 0.01 degrees Celsius. + # Write the local value, ready for a central to read. + self._ble.gatts_write(self._handle, struct.pack("IIIIIIIIIIII", data)[10] - TIMESTAMP +print ("Year:%d Month:%d Day:%d Time: %d:%d:%d" % (utime.localtime(t)[0:6])) diff --git a/scripts/examples/Arduino/Nano-RP2040/03-WiFi/scan.py b/scripts/examples/Arduino/Nano-RP2040/03-WiFi/scan.py new file mode 100644 index 000000000..54ad8d45f --- /dev/null +++ b/scripts/examples/Arduino/Nano-RP2040/03-WiFi/scan.py @@ -0,0 +1,16 @@ +# Scan Example +# +# This example shows how to scan for WiFi networks. + +import time, network + +wlan = network.WLAN(network.STA_IF) +wlan.active(True) + +print("Scanning...") +while (True): + scan_result = wlan.scan() + for ap in scan_result: + print("Channel:%d RSSI:%d Auth:%d BSSID:%s SSID:%s"%(ap)) + print() + time.sleep_ms(1000) diff --git a/scripts/examples/Arduino/Nano-RP2040/04-Audio/audio_fft.py b/scripts/examples/Arduino/Nano-RP2040/04-Audio/audio_fft.py new file mode 100644 index 000000000..14f538bbb --- /dev/null +++ b/scripts/examples/Arduino/Nano-RP2040/04-Audio/audio_fft.py @@ -0,0 +1,60 @@ +import image, audio, time +from ulab import numpy as np +from ulab import scipy as sp + +CHANNELS = 1 +FREQUENCY = 32000 +N_SAMPLES = 32 if FREQUENCY == 16000 else 64 +SCALE = 2 +SIZE = (N_SAMPLES * SCALE) // CHANNELS + +raw_buf = None +fb = image.Image(SIZE+(50*SCALE), SIZE, image.RGB565, copy_to_fb=True) +audio.init(channels=CHANNELS, frequency=FREQUENCY, gain_db=16) + +def audio_callback(buf): + # NOTE: do Not call any function that allocates memory. + global raw_buf + if (raw_buf == None): + raw_buf = buf + +# Start audio streaming +audio.start_streaming(audio_callback) + +def draw_fft(img, fft_buf): + fft_buf = (fft_buf / max(fft_buf)) * SIZE + fft_buf = np.log10(fft_buf + 1) * 20 + color = (0xFF, 0x0F, 0x00) + for i in range(0, len(fft_buf)): + img.draw_line(i*SCALE, SIZE, i*SCALE, SIZE-int(fft_buf[i]) * SCALE, color, SCALE) + +def draw_audio_bar(img, level, offset): + blk_size = (SIZE//10) + color = (0xFF, 0x00, 0xF0) + blk_space = (blk_size//4) + for i in range(0, int(round(level/10))): + fb.draw_rectangle(SIZE+offset, SIZE - ((i+1)*blk_size) + blk_space, 20 * SCALE, blk_size - blk_space, color, 1, True) + +while (True): + if (raw_buf != None): + pcm_buf = np.frombuffer(raw_buf, dtype=np.int16) + raw_buf = None + + if CHANNELS == 1: + fft_buf = sp.signal.spectrogram(pcm_buf) + l_lvl = int((np.mean(abs(pcm_buf[1::2])) / 32768)*100) + else: + fft_buf = sp.signal.spectrogram(pcm_buf[0::2]) + l_lvl = int((np.mean(abs(pcm_buf[1::2])) / 32768)*100) + r_lvl = int((np.mean(abs(pcm_buf[0::2])) / 32768)*100) + + fb.clear() + draw_fft(fb, fft_buf) + draw_audio_bar(fb, l_lvl, 0) + draw_audio_bar(fb, l_lvl, 25*SCALE) + if CHANNELS == 2: + draw_audio_bar(fb, r_lvl, 25 * SCALE) + fb.flush() + +# Stop streaming +audio.stop_streaming() diff --git a/scripts/examples/Arduino/Nano-RP2040/05-Thermal/thermal_camera.py b/scripts/examples/Arduino/Nano-RP2040/05-Thermal/thermal_camera.py new file mode 100644 index 000000000..ecd9a0703 --- /dev/null +++ b/scripts/examples/Arduino/Nano-RP2040/05-Thermal/thermal_camera.py @@ -0,0 +1,30 @@ +# Thermal Camera Demo +# +# This example shows how to use common low-res FIR sensors (like MLX or AMG). +# NOTE: Only the AMG8833 is currently enabled for NANO RP2040. + +import image, time, fir + +IMAGE_SCALE = 5 # Higher scaling uses more memory. +drawing_hint = image.BICUBIC # or image.BILINEAR or 0 (nearest neighbor) + +# Initialize the thermal sensor +fir.init() #Auto-detects the connected sensor. +w = fir.width() * IMAGE_SCALE +h = fir.height() * IMAGE_SCALE + +# FPS clock +clock = time.clock() + +while (True): + clock.tick() + + try: + img = fir.snapshot(x_size=w, y_size=h, + color_palette=fir.PALETTE_IRONBOW, hint=drawing_hint, + copy_to_fb=True) + except OSError: + continue + + # Print FPS. + print(clock.fps())