Indietro

Demo Multi-Protocollo Pico: Serial, I2C, SPI e ADC su RP2040

Introduzione

Benvenuti alla Demo Multi-Protocollo Pico! In questo tutorial, esploreremo come utilizzare il Raspberry Pi Pico (RP2040) per comunicare simultaneamente su più protocolli: Serial, I2C, SPI e ADC. Questo è un esempio avanzato che unisce diverse competenze chiave per lo sviluppo embedded. Costruiremo il circuito nel simulatore Velxio, scriveremo il codice e analizzeremo ogni parte passo dopo passo.

Diagramma del circuito pico-multi-protocollo sul canvas del simulatore Velxio

Analisi del Circuito

Diamo un’occhiata ai componenti e ai collegamenti. Il circuito utilizza un Raspberry Pi Pico (Nano RP2040 Connect) e diverse periferiche:

Tutti i LED condividono una massa comune. Il potenziometro è alimentato dalla linea a 3.3V. I collegamenti sono semplici, ma notate che stiamo utilizzando le periferiche I2C e SPI integrate del Pico (anche se non mostrate esplicitamente nello schema, il codice presuppone che siano disponibili sui pin predefiniti).

Analisi del Codice

Il codice è scritto in Arduino C++ e utilizza le librerie Wire e SPI. Analizziamolo sezione per sezione.

Setup

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(115200);
  delay(500);

  Serial.println("==============================");
  Serial.println(" Pico Multi-Protocol Demo");
  Serial.println("==============================");
  Serial.println();

Inizializziamo il LED integrato e la Serial a 115200 baud. Il ritardo dà il tempo al monitor seriale di connettersi.

1. Scanner I2C

  Wire.begin();
  Serial.println("[I2C] Scanning bus...");
  int found = 0;
  for (byte addr = 1; addr < 127; addr++) {
    Wire.beginTransmission(addr);
    if (Wire.endTransmission() == 0) {
      found++;
      Serial.print("  Found device at 0x");
      if (addr < 16) Serial.print('0');
      Serial.println(addr, HEX);
    }
  }
  Serial.print("  Total devices: "); Serial.println(found);
  Serial.println();

Questo codice scansiona tutti gli indirizzi I2C possibili (1-126) e segnala quelli che rispondono. Nel simulatore, potresti vedere dispositivi virtuali agli indirizzi come 0x50 (EEPROM) e 0x68 (RTC).

2. Lettura/Scrittura EEPROM I2C

  Serial.println("[I2C] EEPROM test at 0x50...");
  Wire.beginTransmission(0x50);
  Wire.write(0x00); // register 0
  Wire.write(0x42); // data
  Wire.endTransmission();
  delay(5);

  Wire.beginTransmission(0x50);
  Wire.write(0x00);
  Wire.endTransmission();
  Wire.requestFrom(0x50, 1);
  if (Wire.available()) {
    byte val = Wire.read();
    Serial.print("  Wrote 0x42, Read 0x");
    Serial.print(val, HEX);
    Serial.println(val == 0x42 ? " — OK" : " — FAIL");
  }
  Serial.println();

Scriviamo il valore 0x42 nel registro 0 dell’EEPROM all’indirizzo 0x50, poi lo rileggiamo per verificare. Questo testa la lettura/scrittura I2C di base.

3. RTC I2C

  Serial.println("[I2C] Reading DS1307 RTC at 0x68...");
  Wire.beginTransmission(0x68);
  Wire.write(0x00);
  Wire.endTransmission();
  Wire.requestFrom(0x68, 3);
  if (Wire.available() >= 3) {
    byte sec = ((Wire.read() & 0x7F) >> 4) * 10 + (Wire.read() & 0x0F);
    byte min2 = Wire.read();
    (void)sec; (void)min2;
    Serial.println("  RTC responded OK");
  }
  Serial.println();

Qui proviamo a leggere i registri dell’ora da un RTC DS1307 all’indirizzo 0x68. Il codice legge tre byte (secondi, minuti, ore) ma controlla solo se il dispositivo ha risposto.

4. Loopback SPI

  Serial.println("[SPI] Loopback test...");
  SPI.begin();
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
  byte tx = 0xAB;
  byte rx = SPI.transfer(tx);
  Serial.print("  TX: 0x"); Serial.print(tx, HEX);
  Serial.print("  RX: 0x"); Serial.println(rx, HEX);
  SPI.endTransaction();
  Serial.println();

Questo esegue un semplice loopback SPI: invia 0xAB e legge ciò che viene ricevuto. Nel simulatore, MISO e MOSI non sono collegati esternamente, quindi il valore ricevuto potrebbe essere 0xFF o altro. Questo testa l’hardware SPI.

5. ADC

  Serial.println("[ADC] Reading analog channels...");
  analogReadResolution(12);
  int a0 = analogRead(A0);
  Serial.print("  A0 (GP26): "); Serial.println(a0);
  Serial.println();

Impostiamo la risoluzione dell’ADC a 12 bit e leggiamo il valore da A0 (GP26). Viene letta la tensione del cursore del potenziometro, ottenendo un valore tra 0 e 4095.

6. Lampeggio GPIO

  Serial.println("[GPIO] Blinking LED...");
  for (int i = 0; i < 3; i++) {
    digitalWrite(LED_BUILTIN, HIGH);
    delay(200);
    digitalWrite(LED_BUILTIN, LOW);
    delay(200);
  }
  Serial.println("  3 blinks done");
  Serial.println();

  Serial.println("=== All protocol tests complete ===");
}

Infine, facciamo lampeggiare il LED integrato tre volte per indicare che il setup è completo.

Loop

void loop() {
  // Heartbeat
  static unsigned long last = 0;
  if (millis() - last >= 3000) {
    last = millis();
    Serial.print("[Heartbeat] ");
    Serial.print(millis() / 1000);
    Serial.println("s");
  }
}

Il loop stampa un messaggio di heartbeat ogni 3 secondi per mostrare che il programma è ancora in esecuzione.

Concetti Chiave

Insidie Comuni e Suggerimenti per il Debug

Estensioni Suggerite

Provalo Tu Stesso!

Pronto a sperimentare? Apri l’esempio live in Velxio ed esegui la simulazione. Puoi modificare il codice, aggiungere componenti e vedere i risultati istantaneamente.

Avvia la Demo Multi-Protocollo Pico su Velxio

Barra degli strumenti dell'editor Velxio con controlli di compilazione ed esecuzione

Barra degli strumenti del canvas Velxio sopra il viewport di simulazione

Finestra modale del selettore componenti Velxio che sfoglia parti per categoria

Buon hacking!


Condividi su:
David Montero

Scritto da

David Montero

Creator of Velxio, the open-source circuit and Arduino simulator.

GitHub velxio.dev

Articoli correlati


Articolo precedente
Velxio vs Wokwi, Tinkercad, Proteus e Fritzing: un confronto onesto
Articolo successivo
Leggere Sensori Analogici su Raspberry Pi Pico con Velxio