Per chi fosse interessato a vedere il programma caricato su ORTOLINO, è qui sotto. Noterete alcuni commenti in inglese che derivano dal programma originale del Jeelabs, da cui sono partito.
/* Trasmette le variabili misurate da Ortolino
struttura del pacchetto di 10 byte trasmesso
1 - 2 RH resistenza del soil moisture in centinaia di ohm
3 - 4 T temperatura del suolo in decimi di grado
5 - 6 L luminosità in unità digit
7 - 8 libero
9 - 10 Vcc in mV
*/
#include <JeeLib.h>
#include <avr/sleep.h>
ISR(WDT_vect) { Sleepy::watchdogEvent(); }
Port an1 (1);
Port an2 (2);
Port an3 (3);
Port an4 (4);
MilliTimer readoutTimer, aliveTimer;
//word runningAvg1;
word runningAvg2;
word runningAvg3;
word runningAvg4;
byte radioIsOn;
word pluto[5];
int nodeID;
int ECHO = 0; // Print debug
float R1 = 55.3; // Kohm
float VCC = 3.3;
float Vconv = VCC/1023;
float V1=0;
float V2=0;
float RH1=0;
float RH2=0;
float RH=0;
float diff = 0;
float temper= 0;
//////////function for reading power supply/////////////////
long readVcc() { // SecretVoltmeter from TinkerIt
long result;
// Read 1.1V reference against AVcc
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
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 AVcc in mV
return result;
}
///////////////////////////////////////////////////////
void setup () {
// initialize the serial port and the RF12 driver
Serial.begin(57600);
Serial.print("\n[pof66]");
nodeID = rf12_config();
if(ECHO == 1){
delay(1000);
Serial.println(nodeID);
}
// set up easy transmissions at 30 sec rate
rf12_easyInit(30);
// setta come INPUT le 4 porte analogiche
an1.mode2(INPUT);
an2.mode2(INPUT);
an3.mode2(INPUT);
an4.mode2(INPUT);
// setta come output la porta digitale 1 e 2
an1.mode(OUTPUT);
an2.mode(OUTPUT);
// pull up resistors on analog ports
an1.digiWrite2(0); //no pullup soil moisture
an2.digiWrite2(0); // no pullup termometer TMP36GZ
an3.digiWrite2(1); // pullup photoresistor
an4.digiWrite2(1);
// prime the running average
// runningAvg1 = an1.anaRead();
runningAvg2 = 0;
runningAvg3 = 0;
runningAvg4 = 0;
// start with the radio on
radioIsOn = 1;
}
////////////////////////////////////////////////
static void lowPower (byte mode) {
// disable the ADC
byte prrSave = PRR, adcsraSave = ADCSRA;
ADCSRA &= ~ bit(ADEN);
PRR &= ~ bit(PRADC);
// go into power down mode
set_sleep_mode(mode);
sleep_mode();
// re-enable the ADC
PRR = prrSave;
ADCSRA = adcsraSave;
}
////////////////////////////////////////////////////
static void loseSomeTime (word ms) {
// only slow down for longer periods of time, as this is a bit inaccurate
if (ms > 100) {
word ticks = ms / 32 - 1;
if (ticks > 127) // careful about not overflowing as a signed byte
ticks = 127;
rf12_sleep(ticks); // use the radio watchdog to bring us back to life
lowPower(SLEEP_MODE_PWR_DOWN); // now we'll completely power down
rf12_sleep(0); // stop the radio watchdog again
// adjust the milli ticks, since we've just missed lots of them
extern volatile unsigned long timer0_millis;
timer0_millis += 32U * ticks;
}
}
//////////////////////////////////////////////////////////
void loop () {
// switch to idle mode while waiting for the next event
lowPower(SLEEP_MODE_IDLE);
// keep the easy tranmission mechanism going
if (radioIsOn && rf12_easyPoll() == 0) {
rf12_sleep(0); // turn the radio off
radioIsOn = 0;
}
// if we will wait for quite some time, go into total power down mode
if (!radioIsOn)
loseSomeTime(readoutTimer.remaining());
// only take sensors reading once a second
// fa una lettura dei sensori ogni 30 secondi
if (readoutTimer.poll(30000)) {
// sensor power supply for measuring V1, i.e. P1-D on and P2-D off
an1.digiWrite(1);
an2.digiWrite(0);
Sleepy::loseSomeTime(1000);
// delay(1000);
V1 = Vconv*an1.anaRead();
// sensor power supply for measuring V2, i.e. P1-D off and P2-D on
an1.digiWrite(0);
an2.digiWrite(1);
Sleepy::loseSomeTime(1000);
// delay(1000);
V2 = Vconv*an1.anaRead();
// compute RH
diff = abs(3.3 - V2);
if(diff < 0.001){
RH2 = 5000.0;
}
else{
RH2 = R1*V2/(3.3 - V2);
}
if(V1 < 0.001){
RH1 = 5000.0;
}
else{
RH1 = R1*(3.3 - V1)/V1;
}
RH = 5*(RH1+RH2); // 0.1 kohm
//
runningAvg2 = an2.anaRead();
runningAvg3 = an3.anaRead();
runningAvg4 = an4.anaRead();
//
pluto[0] = word(RH);
temper = 10*(25 + (100*Vconv*runningAvg2-75));
pluto[1] = word(temper); // gradi in decimi interi
pluto[2] = 1023 - runningAvg3; // unità digit per la luminosità
pluto[3] = runningAvg4;
pluto[4] = word(readVcc()); // read power supply in mV
// send measurement data, but only when it changes
char sending = rf12_easySend(&pluto, sizeof pluto);
// Backup //////////////////////////////////
if(ECHO == 1){
Serial.print(" Node ID: ");
Serial.print(nodeID);
Serial.print(" n.byte payload: ");
Serial.println(sizeof pluto);
Serial.print(" P1: ");
Serial.print(pluto[0]);
Serial.print(" P2: ");
Serial.print(pluto[1]);
Serial.print(" P3: ");
Serial.print(pluto[2]);
Serial.print(" P4: ");
Serial.print(pluto[3]);
Serial.print(" Vcc: ");
Serial.println(pluto[4]);
}
///////////////////////////////////////////////
// force a "sign of life" packet out every 60 seconds
if (aliveTimer.poll(60000))
sending = rf12_easySend(0, 0); // always returns 1
if (sending) {
// make sure the radio is on again
if (!radioIsOn)
rf12_sleep(-1); // turn the radio back on
radioIsOn = 1;
}
}
}
Nessun commento:
Posta un commento