Questo e' uno dei progetti piu' completo a cui lavoro da un po' di tempo a questa parte
Si tratta di un sistema GPS con microcontrollore Arduino e trasmissione dati via Xbee con alimentazione da batteria Lipo e ricarica solare
|
Penna per riferimento di scala sulla sinistra |
I componenti utilizzati sono
- Arduino Uno
- Solar Charger Shield v2.2. (gia' visto in
questo post con le modifiche apportate)
- Pannello solare da 1W (8x10 cm)
- Batteria Lipo da 3000 mAh
- Scatola per esterni 10x6.8x5.0 mm
- Accelerometro ADXL335 (attualmente non in uso)
Il sistema in completo funzionamento (trasmissione dati + acquisizione GPS) consuma circa da 50 a 70 mA. Con ibernazione del sistema GPS ed dello XBee scende intorno a 20 mA
La batteria completamente carica misura 4.1-4.12 V; il limite inferiore a cui il sistema continua ad essere operativo e stabile e' circa 3.65 V
In uso continuativo con la tramissione dati ed il Gps accesi si ha un consumo di 0.03V/ora di esercizio
E' piu' difficile sitmare la ricarica derivante dal pannello solare. A sistema spento, quindi solo in ricarica, in un paio di giornate soleggiate di novembre la ricarica e' stata compresa tra 0.1 e 0.2 V per giorno
Nello sketch seguente l'Arduino acquisisce e trasmette per circa 10 minuti i dati GPS (la trasmissione si attiva solo dopo il fix GPS) ed iberna sia il GPS che la trasmissione per circa un minuto. In queste condizioni, senza ricarica solare, si ha un consumo sulla batteria di circa 0.3 V/h.
--------------------------------------------------------------------
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
#define XBEE_SLEEP 9
const int analogInPin = A0;
int BatteryValue = 0;
float outputValue = 0;
unsigned long delaytime=250;
//GESTIONE DEL RISPAMIO ENERGETICO
// in max_misure c'e' il valore di quante misure consecutive vengono effettuate
// in sleep_time il numero di millisecondi in cui il GPS deve risultare spento
const int max_misure = 600;
int conta_misure = 0;
unsigned long sleep_time = 60000; //in millesimi di secondo
SoftwareSerial mySerial(3, 2);
Adafruit_GPS GPS(&mySerial);
#define GPSECHO true
boolean usingInterrupt = false;
void useInterrupt(boolean);
void setup() {
Serial.begin(9600);
GPS.begin(9600);
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // 1 Hz update rate
GPS.sendCommand(PGCMD_ANTENNA);
//enable DPGS
GPS.sendCommand(PMTK_ENABLE_SBAS);
GPS.sendCommand(PMTK_ENABLE_WAAS);
useInterrupt(true);
delay(1000);
mySerial.println(PMTK_Q_RELEASE);
//setta il pin 9 come controllo dello sleep di XBEE
pinMode(XBEE_SLEEP,OUTPUT);
//mette a ground il pin ovvero sveglia la trasmissione
analogWrite(XBEE_SLEEP,0);
//digitalWrite(XBEE_SLEEP,LOW);
}
SIGNAL(TIMER0_COMPA_vect) {
char c = GPS.read();
#ifdef UDR0
//if (GPSECHO)
//if (c) UDR0 = c;
#endif
}
void useInterrupt(boolean v) {
if (v) {
OCR0A = 0xAF;
TIMSK0 |= _BV(OCIE0A);
usingInterrupt = true;
} else {
TIMSK0 &= ~_BV(OCIE0A);
usingInterrupt = false;
}
}
uint32_t timer = millis();
void loop() {
if (! usingInterrupt) {
char c = GPS.read();
//if (GPSECHO)
//if (c) Serial.print(c);
}
if (GPS.newNMEAreceived()) {
if (!GPS.parse(GPS.lastNMEA()))
return;
}
if (timer > millis()) timer = millis();
if (millis() - timer > 1000) {
timer = millis(); // reset the timer
if (GPS.fix)
{
//NOME DELLA STAZIONE
Serial.print("ST01-");
//carica della batteria
BatteryValue = analogRead(analogInPin);
// Calculate the battery voltage value
outputValue = (float(BatteryValue)*5)/1023*2;
Serial.print(outputValue);
Serial.print("-");
//GPS
if (GPS.hour < 10) Serial.print("0");
Serial.print(GPS.hour,DEC);
Serial.print(":");
if (GPS.minute < 10) Serial.print("0");
Serial.print(GPS.minute,DEC);
Serial.print(":");
if (GPS.seconds < 10) Serial.print("0");
Serial.print(GPS.seconds,DEC);
//Serial.print(".");
//Serial.print(GPS.milliseconds,DEC);
Serial.print(" ");
if (GPS.day < 10) Serial.print("0");
Serial.print(GPS.day, DEC); Serial.print('/');
if (GPS.month < 10) Serial.print("0");
Serial.print(GPS.month, DEC); Serial.print("/20");
Serial.print(GPS.year, DEC);
Serial.print("-");
/*Serial.print(GPS.latitude,4);
Serial.print("-");
Serial.print(GPS.lat);
Serial.print("-");
Serial.print(GPS.longitude,4);
Serial.print("-");
Serial.print(GPS.lon);
Serial.print("-");*/
Serial.print(GPS.latitude_fixed);
Serial.print("-");
Serial.print(GPS.longitude_fixed);
Serial.print("-");
Serial.print(GPS.altitude,1);
Serial.print("-");
Serial.print(GPS.HDOP,1);
Serial.print("-");
Serial.print((int)GPS.fixquality);
Serial.print("-");
if (GPS.satellites < 10) Serial.print("0");
Serial.print((int)GPS.satellites);
Serial.println("-LU");
//conta_misure++;
}
conta_misure++;
//GESTIONE RISPARMIO ENERGETICO
//controlla se e' stato raggiunto il numero limite di misure
if (conta_misure >= max_misure)
{
//se e' stato raggiunto spenge il GPS, attende lo sleep_time e lo riaccende
conta_misure = 0;
GPS.standby(); //spenge il GPS
analogWrite(XBEE_SLEEP,168); //spenge XBEE, 3.3V PWM
//digitalWrite(XBEE_SLEEP,HIGH);
delay(sleep_time); //tempo di standby
GPS.wakeup(); //risveglia il GPS
analogWrite(XBEE_SLEEP,0); //risveglia XBEE
//digitalWrite(XBEE_SLEEP,LOW);
}
}
}
--------------------------------------------------------------------
La ricevente e' un sistema Xbee in modalita' coordinator montato su Xbee Explorer e collegato ad un PC
Lo script per ricevere i dati in Python e' il seguente
--------------------------------------------------------------------
import serial
import sys
s = serial.Serial('/dev/ttyUSB1',9600)
while 1:
try:
if s.inWaiting():
val = s.readline(s.inWaiting())
sys.stdout.write(val)
except serial.serialutil.SerialException:
pass
--------------------------------------------------------------------