giovedì 12 febbraio 2015

BAsic Remote Sensor su mysql



BAsic Remote Sensor su mysql

BARS trasmette i dati dal sensore remoto ad un Raspberry; il semplice ricevitore proposto scrive su standard output, redirezionabile su file. L'evoluzione naturale consiste nell'inserire i dati su database e mostrarli tramite web e web application.

Per essere inseriti nel db e gestiti da un'applicazione più complessa, e' opportuno normalizzare i dati alla sorgente.

Su Raspberry e' necessario installare il software per MySQL e creare il database:



# sudo apt-get install mysql-server
# sudo apt-get install mysql-client
# sudo apt-get install libmysqlclient-dev
# mysql -u root -p

mysql> create database sensors;
mysql> create user 'dbusername'@'%' IDENTIFIED BY 'password';
mysql> grant all privileges on sensors.* to 'dbusername'@'%';
mysql> use sensors;

mysql> create table rec_data (timestamp TIMESTAMP, data_type VARCHAR(4), serial VARCHAR(4), counter INT, data FLOAT, battery FLOAT);

mysql> describe rec_data;
+-----------+------------+------+-----+-------------------+-----------------------------+
| Field     | Type       | Null | Key | Default           | Extra                       |
+-----------+------------+------+-----+-------------------+-----------------------------+
| timestamp | timestamp  | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| data_type | int(11)    | YES  |     | NULL              |                             |
| serial    | varchar(5) | YES  |     | NULL              |                             |
| counter   | int(11)    | YES  |     | NULL              |                             |
| data      | float      | YES  |     | NULL              |                             |
| battery   | float      | YES  |     | NULL              |                             |
+-----------+------------+------+-----+-------------------+-----------------------------+
6 rows in set (0.01 sec)


Il software in ascolto su Raspberry deve essere modificato per gestire i nuovi dati e la connessione al db.

creare il file nRF24l01_receive.cpp:

// nRF24l01_receive.cpp
// nRF24L01+ su RaspberryPi
// code for data RX and store on mysql DB
// compile with: g++ -Ofast -mfpu=vfp -mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s -Wall -I../ -lrf24-bcm nRF24l01_receive.cpp -o nRF24l01_receive `mysql_config --cflags` `mysql_config --libs`
// see http://slartitorto.blogspot.it/2015/02/basic-remote-sensor-su-mysql-bars.html for details and DB preparation
// connect:
// nrf24L01:     1   2   3   4   5   6   7 
// RaspberryPi:  6   1   22  24  23  19  21


#include <cstdlib>
#include <iostream>
#include <RF24/RF24.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <mysql/mysql.h>

#define DATABASE_SERVER "localhost"
#define DATABASE_NAME "sensors"
#define DATABASE_USERNAME "dbusername"
#define DATABASE_PASSWORD "password"
MYSQL *mysql1;

using namespace std;

RF24 radio(RPI_V2_GPIO_P1_22, RPI_V2_GPIO_P1_24, BCM2835_SPI_SPEED_8MHZ);


void setup(void)
{
// init radio for reading
    radio.begin();
    radio.enableDynamicPayloads();
    radio.setAutoAck(1);
    radio.setRetries(15,15);
    radio.setDataRate(RF24_250KBPS);
    radio.setPALevel(RF24_PA_MAX);
    radio.setChannel(76);
    radio.setCRCLength(RF24_CRC_16);
    radio.openReadingPipe(1,0xF0F0F0F0E1LL);
    radio.startListening();

//initialize MYSQL object for connections
    mysql1 = mysql_init(NULL);
     if(mysql1 == NULL)
     {
         fprintf(stderr, "ABB : %s\n", mysql_error(mysql1));
         return;
     }
     //Connect to the database
     if(mysql_real_connect(mysql1, DATABASE_SERVER, DATABASE_USERNAME, DATABASE_PASSWORD, DATABASE_NAME, 0, NULL, 0) == NULL)
     {
      fprintf(stderr, "%s\n", mysql_error(mysql1));
     }
     else
     {
         printf("Database connection successful.\r\n");
     }
}

void loop(void)
{
    // 32 byte character array is max payload
    char receivePayload[32]="";
// sleep 20 ms
usleep(20000);

    while (radio.available())
    {
        // read from radio until payload size is reached
        uint8_t len = radio.getDynamicPayloadSize();
        radio.read(receivePayload, len);
   cout << receivePayload << endl;

// conto i separatori ":"
const char * z = receivePayload;
int separator_count;
int m;
separator_count = 0;
for (m=0; z[m]; m++) {
if(z[m] == ':') {
separator_count ++;
}
}

// se sono 5, ok
if (separator_count == 5) {

        int data_type = 0;
        char * serial;
        int counter = 0;
        float data = 0;
        float battery = 0;

        char query[256];

        data_type = atoi(strtok (receivePayload, ":"));
        serial = strtok (NULL, ":");
        counter = atoi(strtok (NULL, ":"));
        data = atof(strtok (NULL, ":")) / 100;
        battery = atof(strtok (NULL, ":")) / 1000;

        printf("%04d %s %04d %.2f %.3f \n",data_type,serial,counter,data,battery);


        sprintf(query, "INSERT INTO rec_data (data_type,serial,counter,data,battery) VALUES (%04d,'%s',%04d,%.2f,%.3f)", data_type, serial, counter, data, battery);

//   printf("%s \n",query);


        mysql_query(mysql1,query); 
}
    }
}

int main(int argc, char** argv)
{
    setup();
    while(1)
        loop();

    return 0;


}

E' possibile inviare i dati ad un database server remoto (opportunamente predisposto con db, utente, previlegi e tabella) sostituendo "localhost" con l'indirizzo ip del server.

Compilare con 

g++ -Ofast -mfpu=vfp -mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s -Wall -I../ -lrf24-bcm nRF24l01_receive.cpp -o nRF24l01_receive `mysql_config --cflags` `mysql_config --libs`

Accendere i sensori
Controllare la tabella che viene popolata:

mysql> select * from rec_data;
+---------------------+-----------+--------+---------+-------+---------+
| timestamp           | data_type | serial | counter | data  | battery |
+---------------------+-----------+--------+---------+-------+---------+
| 2015-02-12 21:51:28 |         1 | 0001   |       0 | 19.88 |   3.587 |
| 2015-02-12 21:52:36 |         1 | 0001   |       1 | 21.39 |   3.587 |
| 2015-02-12 21:53:39 |         1 | 00A2   |       0 | 20.07 |   4.037 |
| 2015-02-12 21:53:44 |         1 | 0001   |       2 | 21.34 |   3.587 |
| 2015-02-12 21:53:57 |         1 | 00A2   |       1 | 22.05 |   4.037 |
| 2015-02-12 21:54:14 |         1 | 00A2   |       2 |    22 |   4.037 |
| 2015-02-12 21:54:31 |         1 | 00A2   |       3 | 21.76 |   4.037 |
| 2015-02-12 21:54:49 |         1 | 00A2   |       4 | 21.58 |   4.037 |
| 2015-02-12 21:54:52 |         1 | 0001   |       3 | 21.06 |   3.587 |
+---------------------+-----------+--------+---------+-------+---------+

9 rows in set (0.00 sec)


Mettiamo tutto su web


<?php

print  "<head><title>Test Sensors</title>
<meta name=\"apple-mobile-web-app-capable\" content=\"yes\">
<link rel=\"apple-touch-icon\" href=\"/app_icon128.png\">
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />
<BR><BR><CENTER>

<style type=\"text/css\">
table.gridtable {
font-family: verdana,arial,sans-serif;
font-size:11px;
color:#333333;
border-width: 1px;
border-color: #666666;
border-collapse: collapse;
}
table.gridtable th {
border-width: 1px;
padding: 8px;
border-style: solid;
border-color: #666666;
background-color: #dedede;
}
table.gridtable td {
border-width: 1px;
padding: 8px;
text-align: center;
border-style: solid;
border-color: #666666;
background-color: #ffffff;
}
</style>";

$servername = "localhost";
$username = "dbusername";
$password = "password";
$dbname = "sensors";

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);

$sql = "SELECT timestamp, data, battery FROM rec_data where serial = '0001' order by timestamp desc limit 10";
$result = $conn->query($sql);
if ($result->num_rows > 0) {

print "
<table class=\"gridtable\">
<tr><th colspan=3>Frigorifero</th></tr>
<tr><th>Timestamp</th><th>Temperatura</th><th>Batteria</th></tr>
";

    while($row = $result->fetch_assoc()) {
        echo "<TR><TD>".$row["timestamp"]. "</TD><TD>" . $row["data"]. "</TD><TD>" . $row["battery"]. "</TD></TR>";
    }
echo "</table>";
} else {
    echo "0 results";
}
echo "<BR><BR>";

$sql = "SELECT timestamp, data, battery FROM rec_data where serial = '00B3' order by timestamp desc limit 10";
$result = $conn->query($sql);

if ($result->num_rows > 0) {
print "
        <table class=\"gridtable\">
        <tr><th colspan=3>Congelatore</th></tr>
<tr><th>Timestamp</th><th>Temperatura</th><th>Batteria</th></tr>";
    while($row = $result->fetch_assoc()) {
        echo "<TR><TD>".$row["timestamp"]. "</TD><TD>" . $row["data"]. "</TD><TD>" . $row["battery"]. "</TD></TR>";
    }
echo "</table>";

} else {
    echo "0 results";
}

$conn->close();


?>

venerdì 16 gennaio 2015

nRF24L01+ and TMP36 as remote temp sensor: TX ATtiny84 - RX RaspberryPi




Il progetto: BAsic Remote Sensor (BARS)

Il progetto e' di realizzare un sensore di temperatura in ambiente domestico che trasmette via radio i dati ad una stazione centrale; il sensore trasmettitore deve costare meno di 10 euro, compresa batteria. La stazione ricevente deve ricevere dati da più sensori e renderli fruibili facilmente. Il consumo deve essere ridotto al minimo per consentire alle batterie di durare il più a lungo possibile.

Ho deciso di utilizzare:
  • una coppia di moduli radio nRF24L01+ per trasmettere e per ricevere
  • il chip ATtiny84 come microcontroller del sensore remoto
  • il chip TMP36 come sensore di temperatura (va bene anche il TMP37)
  • RaspberryPi come stazione ricevente
La portata non e' un granché tra le mura domestiche, ma il segnale si riceve tranquillamente almeno da una stanza all'altra; in linea d'aria, copro almeno una ventina di metri.

NB il TMP36 ha un range di temperatura tra -40 e +125 °C mentre il TMP37 va da +5 a +85; e' più preciso, ma non provate a metterlo in congelatore perche' non andrà sotto il suo minimo.


ATtiny84


Il microcontroller ATtiny84 della ATmel è un chip semplice da programmare grazie anche alla compatibilità con l'IDE di Arduino (vedi la guida di programmazione).


Il modulo radio nRF24L01+




E' un modulo radio molto economico (con un po' di fortuna si trova sotto i 3 dollari a coppia), opera a 2,4 GHz ed esistono le librerie per utilizzarlo con Arduino, ATtiny84 e  RaspberryPi.

Attenzione: il modulo va alimentato al massimo a 3.6V; in caso di alimentazione superiore c'e' il rischio di bruciarlo; conviene usare un regolatore di tensione.



Il circuito del trasmettitore

Il cuore del trasmettitore e' ovviamente costituito dal microcontroller ATtiny84.

Un pin in output alimenta il sensore di temperatura TMP36, mentre un pin in input analogico legge il valore di temperatura in uscita dal sensore.

Ho inserito un regolatore di tensione per evitare di bruciare il modulo radio che non sopporta tensioni di alimentazione oltre i 3,6V; infatti anche una batteria ricaricabile da 3,6V completamente carica può facilmente arrivare a 4,2V
Grazie alla presenza del regolatore di tensione, e' possibile alimentare tutto il circuito anche con un alimentatore esterno a 5 V.
Per diminuire il consumo di corrente, ho utilizzato un regolatore di tensione MIC5205-3.3YM5 smd dotato di un pin EN ("chip ENable"); con il pin a livello basso, il regolatore si comporta come un interruttore ed il circuito non consuma praticamente niente; quando attivato tramite un pin del microcontroller, il regolatore eroga i 3,3 v necessari ad alimentare il dispositivo nRF24L01+. Il condensatore C3 (470pF) e' necessario per l'abbattimento del rumore nel regolatore.

I condensatori C5 e C6 sono elettrolitici da 10 uF.

Ho aggiunto un led con resistenza (R3 da 220 ohm) per verificare il fluire del processo di lettura dei valori e trasmissione dei dati.






Il ponticello J1 e' usato come interruttore di alimentazione.

Riporto il collegamento tra microcontroller ed il modulo nRF24l01:


nRF24L
ATtiny84
1
GND
14
GND
2
VCC
1
VCC
3
CE
6
PA7
4
CSN
10
PA3
5
SCK
9
USCK
6
MOSI
8
MISO
7
MISO
7
MOSI

ATTENZIONE!  Il piedino 8 (IRQ) del nRF24l01 non e' usato; tuttavia, nello schema (e nel pcb), ho collegato anche quel piedino del connettore al PB3 (reset) del ATtiny84 in modo da poter programmare il microcontroller senza toglierlo dallo zoccolo, collegando semplicemente un cavetto tra arduino e lo zoccolo del modulo nRF24l01. L'unica accortezza, e' quella di piegare il pin del modulo radio prima di inserirlo in modo che non venga collegato.




Come dicevo, la programmazione del microcontroller può essere effettuata senza toglierlo dallo zoccolo; è sufficiente togliere il nRF dallo zoccolo ed inserire al suo posto il connettore del cavetto verso arduino:




Le specifiche del cavetto sono:







BARS (zoccolo nRF)
Arduino UNO
5
SCK
13
6
MOSI
12
7
MISO
11
8
IRQ
10
BARS Alimentazione
Arduino UNO
1
+
+5V
2
-
GND




Un connettore a tre pin consente di collegare eventuali altri sensori direttamente ai pin PA0 e PA1 del microcontroller.
Il sistema è alimentato da una batteria da 3,6 v

Qui il progetto in formato Fritzing; di seguito l'immagine del circuito:




Per ottenere le schede già stampate e forate, ho usato il servizio di SeeedStudio, uplodando il file gerber zippato realizzato con Fritzing; 10 schede al prezzo di 9,99 $ più 3,30 di spedizione (3-4 settimane).




Elenco componenti:


Qtà
Componente
Prezzo
Vendor
Cod. Vendor
1
Microcontroller ATTINY84A-PU
1,80
RS Components 738-0684
1
Zoccolo 14 pin
0,08
RS Components 674-2438
1
Modulo radio nRF24L01+
1,25
Bobowaytoway ND
1
Zoccolo 8 pin (*)
0,07
RS Components 674-2435
1
Led
0,13
RS Components
1
resistenza 220 ohm
0,02
RS Components
1
regolatore LDO MIC5205-3.3YM5
0,55
RS Components 453-467
1
Condensatore 470 pF
0,16
RS Components 699-4936
2
Condensatore elettrolitico 10 uF
0,24
RS Components 715-2511
1
PCB
1,20
SeeedStudio
1
Batteria ricaricabile 3,6V
1,57
SunSky

Totale
7,07



(*) lo zoccolo 8 pin e' usato per il modulo radio; va tagliato a metà e saldato con le due metà affiancate al contrario







Ecco il sensore assemblato:





ll software per ATtiny84

Ho utilizzato l'ambiente MacOS per la realizzazione del progetto.

Per compilare il software su Tiny e’ necessario innanzitutto correggere un bug di ArduinoIDE; seguire il link:

https://github.com/TCWORLD/ATTinyCore/tree/master/PCREL%20Patch%20for%20GCC cliccare su MAC ld.zip, poi view raw; questo fa il download del file.

unzippare il file e, avendo cura di salvare il vecchio, mettere il file ld al posto del precedente nella directory:
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/avr/bin

Installare le librerie RF24 da:


scompattare il file RF24-master.zip, rinominare la directory da RF24-master in RF24; copiare la directory nella Documents/Arduino/libraries 

E' possibile anche utilizzare la funzione propria di import dal menù Sketch -> Importa libreria -> Add library.

Come sopra, installare le librerie Narcoleptic; servirà per mandare il microcontroller in standby consumando circa 3 uA tra una trasmissione e la successiva.

Installare questo codice sul ATtiny84:




// nRF24L01+ su ATTiny84
// code for data TX vers. 6a
// hardware connections: 
// nrf24L01:  1 2 3  4 5 6 7
// attiny84: 14 1 6 10 9 8 7

#include <RF24.h>
#include <Narcoleptic.h>
// #include "printf.h" //DEBUG

RF24 radio(PA3,PA7);   // attiny84: pins for nrf24l01 CSN,CE

#define tempPin A2     // TMP36 Vout connected to A2 (ATtiny pin 11)
#define radioPower 0   // EN Voltage Regulator pin is connected on pin PB0 - D0 (ATtiny pin 2)
#define ledPin 1       // Led pin is connected on pin D1 (ATtiny pin 3)
#define tempPower 2    // TMP36 Power pin is connected on pin PB2 - D2 (ATtiny pin 5)

// define user variables
int data_type = 1;          // 4 digit (0-9) data type = 1 for temp sensor
char * serial = "0002";     // 4 hex digit (0-F) sensor serial number
int period = 300;           // # seconds period between trasmissions < 32767 (9,13 hours)

// define software variables
int count = 0;
int tempReading = 0;

void setup(void)
{
// Serial.begin(9600); //DEBUG
// printf_begin(); //DEBUG
 analogReference(INTERNAL);    // set the aref to the internal 1.1V reference
 pinMode(tempPower, OUTPUT);   // set power pin for TMP36 to output
 pinMode(ledPin, OUTPUT);      // set power pin for LED to output
 pinMode(radioPower, OUTPUT);  // set power pin for EN Voltage regulator
 period = period * 0.9;        // 10% Narcoleptic library correction
}

void loop(void)
{
 bitClear(PRR, PRADC); // power up the ADC
 ADCSRA |= bit(ADEN);  // enable the ADC

 digitalWrite(tempPower, HIGH);   // turn TMP36 sensor on
 digitalWrite(ledPin, HIGH);      // turn LED on
 delay(20);                       // Allow 20ms for the sensor to be ready
 analogRead(tempPin);             // first junk read
 for(int i = 0; i < 10 ; i++)     // take 10 more readings
  {
   tempReading += analogRead(tempPin); // accumulate readings
  }
 tempReading = tempReading / 10 ;      // calculate the average
 digitalWrite(ledPin, LOW);            // turn LED off
 digitalWrite(tempPower, LOW);         // turn TMP36 sensor off

 long vcc=readVcc();

 ADCSRA &= ~ bit(ADEN); // disable the ADC
 bitSet(PRR, PRADC);    // power down the ADC

 // Calibration
 double voltage = tempReading * 0.942382812;

 // Temp calculation for TMP36
 // double temperatureC = (voltage - 500) / 10;

 // Temp calculation for TMP37
 double temperatureC = voltage / 20;

 // Final temp calculation
 int temptx = temperatureC * 100;

 // Preparing Payload (32 bytes is maximum)
 char outBuffer[32]= "";
 sprintf(outBuffer,"%04d:%s:%04d:%04d:%04d:",data_type,serial,count,temptx,vcc);
 // Serial.println(outBuffer); //DEBUG

 // turn Voltage Regulator ON
 digitalWrite(radioPower, HIGH);
 delay(5);

 // init radio for writing on channel 76
 radio.begin();
 radio.setPALevel(RF24_PA_MAX);
 radio.setChannel(0x4c);
 radio.setDataRate(RF24_250KBPS);
 radio.openWritingPipe(0xF0F0F0F0E1LL);
 radio.enableDynamicPayloads();
 radio.powerUp();
 // radio.printDetails(); //DEBUG

 // Transmit and go down.
 delay(5);
 radio.write(outBuffer, strlen(outBuffer));
 radio.powerDown();
 digitalWrite(radioPower, LOW); // turn Voltage Regulator OFF

 // pause between trasmissions
 int timerSeconds = period % 30;
 int timerHalfminutes = ((period - timerSeconds)/30);

 if (timerHalfminutes > 0)
  {
    for(int i = 0; i < timerHalfminutes ; i++)
     {
      Narcoleptic.delay(30000);   // 30 sec. sleeping is max for Narcoleptic
     }
  }
  if (timerSeconds > 0)
  {
  Narcoleptic.delay(timerSeconds*1000);  // delay the rest
  }

 // increase counter
 count ++;
 if (count == 10000) {
   count = 0;
   }
}

 long readVcc() {
   long result;
   // Read 1.1V reference against Vcc
   ADMUX = _BV(MUX5) | _BV(MUX0);
   delay(2); // Wait for Vref to settle
   ADCSRA |= _BV(ADSC); // Convert
   while (bit_is_set(ADCSRA,ADSC));
   result = ADCL;
   result |= ADCH<<8;
   result = 1126400L / result; // Back-calculate Vcc in mV
   return result;
}


Ho considerato i 32 byte come massima lunghezza del messaggio e ci ho messo:
- un data_type per identificare eventuali diversi tipi di sensore

- un serial number da 4 caratteri che può essere diverso da sensore a sensore, in modo che il ricevitore possa distinguere le varie sorgenti

- un contatore che incrementa di 1 ogni invio e si azzera a 10.000

- la temperatura con il segno (+ o -) davanti, senza virgola (le librerie del ATtiny non consentono di gestire i float, quindi il numero e’ in centesimi di grado (2040 = 20,40 gradi cent.)

- il valore delle batterie di alimentazione del sensore, anche qui in millivolt (3362 = 3,362 V)


I campi sono separati da ":"


Il ricevitore

Il ricevitore è un semplice RaspberryPi a cui e' collegato il modulo nRF24l01 sul connettore del GPIO. La libreria per la gestione del modulo e poche righe di codice C++ sono sufficienti a realizzare il ricevitore.

Il modulo radio sul ricevitore e' quello in versione con antenna esterna per massimizzare la portata della ricezione (non potendo più di tanto agire sul trasmettitore).





Ho saldato il modulo direttamente sul Raspberry (la carcassa del connettore ethernet direttamente sul bnc dorato del nRF) per poi inserire tutto facilmente in un box:






Collegamenti elettrici su Raspberry:


nRF24L
RaspberryPi
1
GND
6
GND
2
VCC
1
VCC +3V
3
CE
22
GPIO25
4
CSN
24
GPIO08/CE0
5
SCK
23
GPIO11/SCLK
6
MOSI
19
GPIO10/MOSI
7
MISO
21
GPIO09/MISO


Il software per Raspberry:


questo programma "nRF24l01_receive_no_DB.cpp" legge i dati che arrivano dai sensori e li mostra su standard output; la versione per inserire i dati su DB e mostrarli via webapp e' qui.


Abilitare SPI sul kernel:

# raspi-config

nel menu’ “Advanced” abilitare SPI kernel module



Creare una directory per contenere la libreria RF24:

    mkdir ~/rf24libs
  cd ~/rf24libs

Clonare il repository RF24

  git clone https://github.com/tmrh20/RF24.git RF24

Entrare nella nuova directory RF24

  cd RF24

Compilare la libreria

  sudo make install
  cd examples_RPi
   
Preparare il file ”nRF24l01_receive_no_DB.cpp” e modificare il Makefile inserendo nei PROGRAMS solo il file “nRF24l01_receive_no_DB”

  vi nRF24l01_receive_no_DB.cpp [copia e incolla il sorgente]
  vi Makefile [inserisci nei PROGRAMS solo "nRF24l01_receive_no_DB"]

Compilare ed eseguire il binario

  make
  sudo ./nRF24l01_receive_no_DB
  
Accendere il sensore remoto, si dovrebbe vedere lo scorrere dei dati, alla cadenza programmata sui trasmettitori:


0001:00A2:0000:1809:3128:
0001:00A2:0001:1993:3137:
0001:00A2:0002:2011:3137:
0001:00A2:0003:2011:3137:
0001:00A2:0004:2011:3137:
0001:00A2:0005:2035:3137:
0001:00A2:0006:2068:3137:

I campi sono rispettivamente: data_type (= 0001), serial number del dispositivo (00A2), contatore, temperatura in centesimi di grado (2068 = 20,68 °C), tensione della batteria in millivolt (3137 = 3,137 V)


Sorgente nRF24l01_receive_no_DB.cpp


// nRF24l01_receive_no_DB.cpp
// nRF24L01+ su RaspberryPi
// example code for data RX on standard output
// connect:
// nrf24L01:     1   2   3   4   5   6   7 
// RaspberryPi:  6   1   22  24  23  19  21

// compile with:
// g++ -Ofast -mfpu=vfp -mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s -Wall -I../ -lrf24-bcm nRF24l01_receive.cpp -o nRF24l01_receive



#include <cstdlib>
#include <iostream>
#include <RF24/RF24.h>

using namespace std;

RF24 radio(RPI_V2_GPIO_P1_22, RPI_V2_GPIO_P1_24, BCM2835_SPI_SPEED_8MHZ);


void setup(void)
{
    // init radio for reading
    radio.begin();
    radio.enableDynamicPayloads();
    radio.setAutoAck(1);
    radio.setRetries(15,15);
    radio.setDataRate(RF24_250KBPS);
    radio.setPALevel(RF24_PA_MAX);
    radio.setChannel(76);
    radio.setCRCLength(RF24_CRC_16);
    radio.openReadingPipe(1,0xF0F0F0F0E1LL);
    radio.startListening();
}

void loop(void)
{
    // 32 byte character array is max payload
    char receivePayload[32]="";

    while (radio.available())
    {
        // read from radio until payload size is reached
        uint8_t len = radio.getDynamicPayloadSize();
        radio.read(receivePayload, len);

        // display payload
        cout << receivePayload << endl;
    }
}

int main(int argc, char** argv)
{
    setup();
    while(1)
        loop();

    return 0;

}


TODO:

Gestire il pin 8 IRQ del modulo radio per evitare di doverlo piegare (dovrebbe bastare predisporre il pin 4 (PB3) del ATtiny come entrata non gestita)

Caricabatterie direttamente dalla scheda, con connettore microUSB

Creare un modulo ripetitore (HW e SW) con maggiore potenza in uscita alimentato dalla rete elettrica.