Im Januar 2021 wurde von Arduino das Board Nano RP2040 Connect angekündigt, welches denselben Mikrocontroller enthalten soll wie der Raspberry Pi Pico. Am 17.05.2021 wurde nun die Veröffentlichung des Nano RP2040 Connect bekannt gegeben und davon habe ich mir auch eine bestellt, um dessen Möglichkeiten auszuprobieren.
Laut der offiziellen Dokumentation verfügt der Nano RP2040 Connect über die folgende Ausstattung:
Mikrocontroller | Raspberry Pi RP2040 |
---|---|
Taktfrequenz | 133 MHz |
Flash-Speicher | 16MB |
SRAM | 264kB |
Digital I/O Pins | 20 |
Analoge Eingänge | 8 |
PWM pins | 20 (außer A6 und A7) |
Externe Interrupts | 20 (außer A6 und A7) |
Betriebsspannung |
VIN: 5-21V VUSB: 5V VLOGIK: 3,3V VOUT: 3,3V |
Max. Stromaufnahme | pro Pin: 4mA |
Zusätzliche Features |
|
WiFi/Bluetooth | U-blox® Nina W102-Modul |
A4
und A5
sollten nur für I²C verwendet werden.A6
und A7
unterstützen kein PWM und können nur als Eingänge verwendet werdenINPUT_PULLUP
konfigurieren.A4
, A5
, A6
und A7
Diese Unterlage für den Arduino Nano RP2040 Connect kann verwendet werden, wenn dieser nicht auf ein Steckbrett montiert wird.
nano_rp2040_mount.scadDer Arduino Nano RP2040 lässt sich direkt in der Arduino IDE (v1.8.x und v2.0.x) programmieren. Dazu muss im Boards Manager der Arduino Mbed OS Nano Boards core für das Board ausgewählt und installiert werden:
Zur Einrichtung in der Arduino IDE 2.0.X (beta) siehe auch:
Board manager with the Arduino IDE 2.0.
Nach der Installation des Cores wird nun der Arduino Nano RP2040 Connect im Menüpunkt Tools » Board
ausgewählt.
Die Arduino IoT Cloud unterstützt bereits ebenfalls den Nano RP2040 Connect.
Einrichtung und Verwendung mit dieser Plattform kann in der
Arduino IoT Cloud-Dokumentation
nachgelesen werden.
Eine Programmierung in Micropython ist ebenso möglich analog zur Beitrag mit der
Programmierung des Raspberry Pi Pico in MicroPython.
Um dafür den Nano RP2040 Connect in den richtigen Modus zu setzen muss er als Massenspeicher-Laufwerk
vom PC erkannt werden. Dazu wird das Board zunächst vom PC getrennt, dann ein 2,54mm-Jumper zwischen
GND
und REC
gesteckt und das Board wieder mit dem PC verbunden.
(siehe auch: Bootloader)
Nun kann der Jumper wieder entfernt werden und z.B. mit der Entwicklungsumgebung "Thonny" das Board mit Micropython programmiert werden.
Der einfachste Sketch ist zunächst die interne LED (orange) zum blinken zu bekommen.
void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
}
void loop()
{
digitalWrite(LED_BUILTIN, HIGH);
delay(500);
digitalWrite(LED_BUILTIN, LOW);
delay(500);
}
Um die digitale Ein- und Ausgabe zu testen, werden -wie im folgenden Schaltplan gezeigt- zwei verschiedenfarbige LEDs mit Vorwiderständen und zwei Mikrotaster an das Board angeschlossen und mit dem nachfolgenden Sketch programmiert.
#define PIN_LED_GREEN 10
#define PIN_LED_RED 9
#define PIN_BUTTON_GREEN 8
#define PIN_BUTTON_RED 7
void setup()
{
pinMode(PIN_LED_GREEN, OUTPUT);
pinMode(PIN_LED_RED, OUTPUT);
pinMode(PIN_BUTTON_GREEN, INPUT_PULLUP);
pinMode(PIN_BUTTON_RED, INPUT_PULLUP);
}
void loop()
{
if (digitalRead(PIN_BUTTON_GREEN) == LOW) {
digitalWrite(PIN_LED_GREEN, HIGH);
} else {
digitalWrite(PIN_LED_GREEN, LOW);
}
if (digitalRead(PIN_BUTTON_RED) == LOW) {
digitalWrite(PIN_LED_RED, HIGH);
} else {
digitalWrite(PIN_LED_RED, LOW);
}
}
Zum Test der analogen Eingabe und der PWM-Funktionalität wird ein Potentiometer und eine LED mit Vorwiderstand so mit dem Board verbunden wie der folgende Schaltplan zeigt:
Der Sketch lässt die LED dann entsprechend der Stellung des Potentiometers heller bzw. dunkler leuchten.
#define PIN_POTI A0
#define PIN_LED 12
void setup()
{
Serial.begin(9600);
pinMode(PIN_LED, OUTPUT);
}
void loop()
{
static int value = 0;
value = analogRead(PIN_POTI);
analogWrite(PIN_LED, map(value, 0, 1024, 0, 255));
}
Um die eingebaute RGB-LED mit gemeinsamer Anode ansprechen zu können wird die Library WiFiNINA benötigt, denn die Pins können nur indirekt über das Nina W102-Modul angesprochen werden.
#include <WiFiNINA.h>
void setup()
{
pinMode(LEDR, OUTPUT);
pinMode(LEDG, OUTPUT);
pinMode(LEDB, OUTPUT);
}
void loop()
{
for (byte i = 0; i < 255; i++) {
analogWrite(LEDR, random(0, 256));
analogWrite(LEDG, random(0, 256));
analogWrite(LEDB, random(0, 256));
delay(500);
}
}
Das auf dem Nano RP2040 Connect verbaute MEMS-Mikrofon zeichnet
sich durch geringes Rauschen, einen breiten Dynamikbereich, geringe Verzerrung und hohe Widerstandsfähigkeit gegenüber
akustischer Überlastung aus. Es soll sich daher gut für Anwendungen im Bereich der Spracherkennung eignen.
In diesem Beispiel sollen lediglich akustische Signale vom Mikrofon ausgelesen und mit dem seriellen Plotter grafisch
darstellt werden. Die Library PDM erleichter den
Umgang mit sog. PDM-Mikrofonen (Pulse-density modulation), wie dem auf dem Board verbauten MP34DT06JTR.
Der folgende Sketch entspricht mehr oder weniger dem Beispiel PDMSerialPlotter der PDM-Library:
#include <PDM.h>
static const char channels = 1;
static const int frequency = 16000;
short sampleBuffer[512];
volatile int samplesRead = 0;
void setup()
{
Serial.begin(9600);
while (!Serial);
// Configure the data receive callback
PDM.onReceive(onPDMdata);
// PDM.setGain(30);
if (!PDM.begin(channels, frequency)) {
Serial.println("Failed to start PDM!");
while (1);
}
}
void loop()
{
if (samplesRead) {
for (int i = 0; i < samplesRead; i++) {
Serial.println(sampleBuffer[i]);
}
// Clear the read count
samplesRead = 0;
}
}
void onPDMdata()
{
int bytesAvailable = PDM.available();
PDM.read(sampleBuffer, bytesAvailable);
samplesRead = bytesAvailable / 2;
}
Leider wurden bei mir immer nur -128
als Wert ausgegeben, es scheint als würde hier entweder
ein Defekt auf dem Board vorliegen oder in der Software besteht noch ein Fehler...
Um das eingebaute Nina W102-Modul für WLAN (WiFi) auszuprobieren, wird im folgenden Sketch zunächst die aktuelle
Temperatur des eingebauten Sensors ausgelesen und anschließend an ThingSpeak
weitergereicht.
Zum Verbinden es WLAN-Netzwerks und des WWW-Servers wird wiederum die
Library WiFiNINA benötigt.
Der interne Temperatursensor misst nicht wirklich die Umgebungstemperatur, sondern vielmehr die Temperatur des IC.
#include <WiFiNINA.h>
// WiFi settings:
const char* SSID = "mySSID";
const char* PASSWORD = "myPassword";
// ThingSpeak settings:
const char* TS_HOST = "api.thingspeak.com";
const char* TS_API_KEY = "myWriteApiKey";
WiFiClient client;
void setup()
{
Serial.begin(9600);
// Init onboard temperature sensor
adc_init();
adc_set_temp_sensor_enabled(true);
adc_select_input(4);
}
void loop()
{
connectWiFi();
String measureData = "&field1=" + String(getTemp());
httpRequest(measureData);
delay(15000);
}
void connectWiFi()
{
if (WiFi.status() == WL_CONNECTED) {
return;
}
Serial.print("Connecting to WiFi...");
WiFi.begin(SSID, PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("[connected]");
}
void httpRequest(String data)
{
String postData = "api_key=" + String(TS_API_KEY) + data;
if (client.connect(TS_HOST, 80)) {
client.println("POST /update HTTP/1.1");
client.println("Host: " + String(TS_HOST));
client.println("Connection: close");
client.println("Content-Type: application/x-www-form-urlencoded");
client.println("Content-Length: " + String(postData.length()));
client.println();
client.println(postData);
Serial.println("Sent data to server: " + String(postData));
String line = client.readStringUntil('\n');
Serial.println(line);
} else {
Serial.println("Connection to server failed!");
}
client.stop();
}
int getTemp()
{
uint16_t raw = adc_read();
const float conversion_factor = 3.3f / (1 << 12);
float result = raw * conversion_factor;
float temp = 27 - (result - 0.706) / 0.001721;
return (int)temp;
}
Da nur alle 15 Sekunden die gemessene Temperatur an ThingSpeak geschickt wird, kann erst nach ein paar Minuten ein brauchbarer Graph angezeigt werden:
zurück