VirtualWire

In fase di sviluppo Stesura preliminare In fase di sviluppo

La libreria VirtualWire permette ad Arduino di trasmettere un payload di lunghezza variabile usando una codifica 4B-6B; è pensata per utilizzare moduli radio a basso costo (e tecnologia di un paio di decenni fa...).

Nella fotografia di apertura è mostrato a sinistra il trasmettitore (TX); a destra, in secondo piano, il ricevitore (RX).

Il frame

Un esempio del frame generato è il seguente:

VirtualWire

Il codice che ha generato questo frame è mostrato nell'esempio presente nell'attività 2.

Il frame ha la seguente struttura (nota 1):

Gli ultimi tre campi sono codifica 4B-6B, secondo la tabella symbols[] presente all'interno del codice (file VirtualWire.cpp):

// 4 bit to 6 bit symbol converter table
// Used to convert the high and low nibbles of the transmitted data
// into 6 bit symbols for transmission. Each 6-bit symbol has 3 1s and 3 0s
// with at most 3 consecutive identical bits
static uint8_t symbols[] =
{0x0D, 0x0E, 0x13, 0x15, 0x16, 0x19, 0x1A, 0x1C, 0x23, 0x25, 0x26, 0x29, 0x2A, 0x2C, 0x32, 0x34};

Il contenuto di ciascuna cella di questo array deve essere interpretato come il blocco di sei bit che codifica i quattro bit dell'indice dell'array.

Per esempio il nibble formato da quattro uni 1111 (15, indice dell'ultima cella dell'array) è codificato come 11 1000 (0x34). Si noti che nella sequenza 111000, come in tutte le altre, sono presenti tre uni e tre zeri.

Attività 1

Completare la tabella con la codifica 4B-6B presente nell'array symbols[].

4B 6B
0 0x0 0000 0x0D 001101
1 0x1 0001 0x0E 001110
2 0x2 0010 0x13 010011
... ... ... ... ...
15 0xF 1111 0x34 111000

Attività 2: trasmissione

Dopo aver installato la libreria VirtualWire (nota 2), utilizzare il seguente codice per trasmettere un frame contente due byte, entrambi pari a 0x00.

#include <VirtualWire.h>
const int TX_DIO_Pin = 2;

void setup() {
  vw_set_tx_pin(TX_DIO_Pin);
  vw_setup(2000); // Bits per sec
}

void loop() {
  byte TxBuffer[2]; // Payload buffer
  TxBuffer[0] = 0x00;
  TxBuffer[1] = 0x00;
  vw_send(TxBuffer, sizeof(TxBuffer));
  vw_wait_tx();
  delay(100);
}

Per questa prima attività serve un solo Arduino (TX) che trasmettere il frame ed un oscilloscopio per osservarlo.

Nel caso non si disponga di un oscilloscopio, in questo file sono disponibili alcuni esempi utilizzabili con il software di Picoscope in modalità demo. Si tratta di due frame con payload di 1 + 2 + 2 byte e di un frame con payload di 1 + 5 + 2 byte. Verrà mostrata l'analisi del primo di questi frame, con trasmissione dei bue byte: 0x00 e 0x00.

Analizziamo gli elementi che costituiscono il frame:

  1. Trovare la lunghezza di un bit usando uno dei primi bit (0 ed 1 alternati)

Lunghezza di un bit

Dall'immagine si risale immediatamente alla durata di ciascun bit, pari a 0.5 ms

  1. Evidenziati i 36 bit del preambolo, con durata 18 ms

Preambolo

  1. Trovare i 4 + 4 + 4 bit del simbolo di start 0xB38 (1011 0011 1000). Tali bit devono essere letti da destra a sinistra.

Start

  1. Trovare la lunghezza del payload, un byte codificato 4B-6B, per un totale di 12 bit

Lunghezza dela payload

La lettura deve essere fatta a blocchi di sei bit ciascuno, da sinistra verso destra; i bit di ciascun blocco vanno letti da destra verso sinistra: 00 1101 (0x0D) e 01 1001 (0x19); infine per la decodifica occorre consultare la tabella ricavata con l'attività 1, convertendo il codice 0x0D 0x19 nelle cifre esadecimali 0x0 e 0x5. Tale numero indica che sono trasmessi 5 byte:

  1. Individuiamo il primo byte trasmesso, formato da 6 + 6 bit codificati 4B-6B. Consultare la tabella ricavata con l'attività 1 (001101 = 0x0) per decodificare il byte:

Primo byte

  1. Il secondo byte è identico al primo, come può essere facilmente visto guardando i successivi 6 ms del diagramma temporale
  2. L'ultimo campo è il CRC-16, due byte codificati in 24 bit, dalla durata di 12 ms. VirtualWire trasmette prima il byte meno significativo del CRC-16

CRC-16

Per la verifica del CRC è utile l'uso di appositi calcolatori on line, per esempio https://crccalc.com. La soluzione è nella figura seguente (dettagli lasciati come esercizio).

Attività 3

Analizzare un frame diverso rispetto a quello utilizzato nell'attività 2. Se non disponete di un oscilloscopio potete usare uno di quelli contenuti in questo file

Attività 4: ricezione

Collegare un secondo Arduino (RX) e ricevere il frame con il codice seguente:

#include <VirtualWire.h>
const int receive_pin = 11;

void setup() {
  delay(1000);
  Serial.begin(9600);
  vw_set_rx_pin(receive_pin);
  vw_setup(2000);
  vw_rx_start();
}

void loop() {
  uint8_t buf[VW_MAX_MESSAGE_LEN];
  uint8_t buflen = VW_MAX_MESSAGE_LEN;
  if (vw_get_message(buf, &buflen)) {
    int i;
    Serial.print("Recived ");
    Serial.print(buflen);
    Serial.print(" bytes: ");
    for (i = 0; i < buflen; i++) {
      Serial.print(buf[i], HEX);
      Serial.print(' ');
    }
    Serial.println();
  }
}

Attività 5: trasmissione wireless

Per procedere con questa attività è necessario disporre di un trasmettitore ed un ricevitore radio. La scelta è caduta sull'uso di una modulazione OOK a 433 MHz:

un trasmettitore e due ricevitori

I moduli sono stati usati senza antenna esterna, a breve distanza.

Il software sia del trasmettitore che dl ricevitore sono quelli già utilizzati nelle attività 2 e 4. I test sono stati fatti sia alla velocità di 2 000 bit/s che a 4 000 bit/s, il massimo che ha garantito una trasmissione ragionevolmente priva di errori.

I segnali trasmesso (pin TX, in blu) e ricevuto da RXB6 (pin RX, in rosso) sono mostrati nella seguente immagine:

RX e TX

Non è stato possibile osservare nel dominio del tempo il segnale modulato: servirebbe un oscilloscopio con banda di svariati GHz...

Con un analizzatore di spettro è possibile misurare il segnale trasmesso, sebbene non particolarmente significativo:

Spettro

Note

  1. VirtualWire.pdf
  2. La libreria VirtualWire deve essere scaricata manualmente (qui una copia) e copiata all'interno della cartella Arduino/libraries/


Pagina creata nel dicembre 2021
Ultima modifica: 27 dicembre 2021


Licenza "Creative Commons" - Attribuzione-Condividi allo stesso modo 3.0 Unported


Pagina principaleAccessibilitàNote legaliPosta elettronicaXHTML 1.0 StrictCSS 3

Vai in cima