Created
March 23, 2015 10:27
-
-
Save OrganicIrradiation/9e51a0a6c3bcc8ff3871 to your computer and use it in GitHub Desktop.
Arduino FIO Internal Voltmeter and Thermometer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
long readTemp() { | |
long result; | |
// Read temperature sensor against 1.1V reference | |
ADMUX = _BV(REFS1) | _BV(REFS0) | _BV(MUX3); | |
delay(2); // Wait for Vref to settle | |
ADCSRA |= _BV(ADSC); // Convert | |
while (bit_is_set(ADCSRA,ADSC)); | |
result = ADCL; | |
result |= ADCH<<8; | |
result = (result - 125) * 1075; | |
return result; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// See: http://code.google.com/p/tinkerit/wiki/SecretThermometer | |
float readTemp() { | |
signed long resultTemp; | |
float resultTempFloat; | |
// Read temperature sensor against 1.1V reference | |
ADMUX = _BV(REFS1) | _BV(REFS0) | _BV(MUX3); | |
delay(10); // Wait for Vref to settle | |
ADCSRA |= _BV(ADSC); // Convert | |
while (bit_is_set(ADCSRA,ADSC)); | |
resultTemp = ADCL; | |
resultTemp |= ADCH<<8; | |
resultTempFloat = (float) resultTemp * 0.9338 - 282.7; // Apply calibration correction | |
resultTempFloat = resultTempFloat * 1.8 + 32.0; // Convert to F | |
return resultTempFloat; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
long readVcc() { | |
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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// See: http://code.google.com/p/tinkerit/wiki/SecretVoltmeter | |
float readVcc() { | |
signed long resultVcc; | |
float resultVccFloat; | |
// Read 1.1V reference against AVcc | |
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); | |
delay(10); // Wait for Vref to settle | |
ADCSRA |= _BV(ADSC); // Convert | |
while (bit_is_set(ADCSRA,ADSC)); | |
resultVcc = ADCL; | |
resultVcc |= ADCH<<8; | |
resultVcc = 1126400L / resultVcc; // Back-calculate AVcc in mV | |
resultVccFloat = (float) resultVcc / 1000.0; // Convert to Float | |
return resultVccFloat; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* SuperSleepyTempAndVolts SuperSleepyTempAndVolts.ino | |
* Steven A Cholewiak - www.semifluid.com | |
* | |
* This sketch takes advantage of the XBee's hibernation mode as | |
* well as the Ardunio Fio's Power Save Mode to grossly reduce power | |
* consumption. Also uses some *supersecret* code to access the Arduino | |
* Fio's own voltage rail (http://code.google.com/p/tinkerit/wiki/SecretVoltmeter) | |
* and internal thermometer (http://code.google.com/p/tinkerit/wiki/SecretThermometer). | |
* | |
*/ | |
#include <avr/wdt.h> | |
#include <avr/sleep.h> | |
#include <avr/interrupt.h> | |
const int ledPin = 13; | |
const int XBeeSleep = 2; // Connect to XBee DTR for hibernation mode | |
const int waitPeriod = 8; // Number of 8 second cycles before waking | |
// up XBee and sending data (8*8 = 64 seconds) | |
// See: http://code.google.com/p/tinkerit/wiki/SecretVoltmeter | |
float readVcc() { | |
signed long resultVcc; | |
float resultVccFloat; | |
// Read 1.1V reference against AVcc | |
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); | |
delay(10); // Wait for Vref to settle | |
ADCSRA |= _BV(ADSC); // Convert | |
while (bit_is_set(ADCSRA,ADSC)); | |
resultVcc = ADCL; | |
resultVcc |= ADCH<<8; | |
resultVcc = 1126400L / resultVcc; // Back-calculate AVcc in mV | |
resultVccFloat = (float) resultVcc / 1000.0; // Convert to Float | |
return resultVccFloat; | |
} | |
// See: http://code.google.com/p/tinkerit/wiki/SecretThermometer | |
float readTemp() { | |
signed long resultTemp; | |
float resultTempFloat; | |
// Read temperature sensor against 1.1V reference | |
ADMUX = _BV(REFS1) | _BV(REFS0) | _BV(MUX3); | |
delay(10); // Wait for Vref to settle | |
ADCSRA |= _BV(ADSC); // Convert | |
while (bit_is_set(ADCSRA,ADSC)); | |
resultTemp = ADCL; | |
resultTemp |= ADCH<<8; | |
resultTempFloat = (float) resultTemp * 0.9338 - 282.7; // Apply calibration correction | |
resultTempFloat = resultTempFloat * 1.8 + 32.0; // Convert to F | |
return resultTempFloat; | |
} | |
void sleepNow() | |
{ | |
/* Now is the time to set the sleep mode. In the Atmega8 datasheet | |
* http://www.atmel.com/dyn/resources/prod_documents/doc2486.pdf on page 35 | |
* there is a list of sleep modes which explains which clocks and | |
* wake up sources are available in which sleep modus. | |
* | |
* In the avr/sleep.h file, the call names of these sleep modus are to be found: | |
* | |
* The 5 different modes are: | |
* SLEEP_MODE_IDLE -the least power savings | |
* SLEEP_MODE_ADC | |
* SLEEP_MODE_PWR_SAVE | |
* SLEEP_MODE_STANDBY | |
* SLEEP_MODE_PWR_DOWN -the most power savings | |
* | |
* the power reduction management <avr/power.h> is described in | |
* http://www.nongnu.org/avr-libc/user-manual/group__avr__power.html | |
*/ | |
set_sleep_mode(SLEEP_MODE_PWR_SAVE); // Sleep mode is set here | |
sleep_enable(); // Enables the sleep bit in the mcucr register | |
// so sleep is possible. just a safety pin | |
sleep_mode(); // Here the device is actually put to sleep!! | |
// THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP | |
sleep_disable(); // Dirst thing after waking from sleep: | |
// disable sleep... | |
} | |
ISR (WDT_vect) { // WDT Wakeup | |
cli(); | |
wdt_disable(); | |
sei(); | |
} | |
// Variable Definition | |
volatile int MeasurementID = 1; | |
volatile int timeKeeper = 0; | |
volatile float averageVcc = 0.0; | |
volatile float averageTemp = 0.0; | |
void setup() { | |
Serial.begin(57600); | |
pinMode(XBeeSleep, OUTPUT); | |
digitalWrite(XBeeSleep, 0); // Enable XBee | |
digitalWrite(ledPin, 1); // Turn on Notification LED | |
delay(4000); // 4 second LED blink, good for wireless programming | |
digitalWrite(ledPin, 0); // Turn off Notification LED | |
Serial.write( 170 ); // Sync Byte | |
Serial.print( '\t' ); // Tab | |
Serial.print( '0' ); // Reading # (0) | |
Serial.print( '\t' ); // Tab | |
Serial.print( '0' ); // Voltage (unmeasured, so 0) | |
Serial.print( '\t' ); // Tab | |
Serial.println( '0' ); // Temperature (unmeasured, so 0) | |
digitalWrite(XBeeSleep, 1); // Disable XBee | |
} | |
void loop() { | |
// | |
averageVcc = averageVcc + (float) readVcc(); | |
averageTemp = averageTemp + (float) readTemp(); | |
if (timeKeeper == (waitPeriod-1)) { // Transmit every 8*8 (64) seconds | |
digitalWrite(XBeeSleep, 0); // Enable XBee | |
delay(50); // Wait for XBee Wakeup | |
Serial.write( 170 ); // Sync Byte | |
Serial.print( '\t' ); | |
Serial.print( MeasurementID, DEC ); | |
Serial.print( '\t' ); | |
Serial.print( (float) (averageVcc/waitPeriod) , 3); | |
Serial.print( '\t' ); | |
Serial.println( (float) (averageTemp/waitPeriod) , 2); | |
MeasurementID++; | |
digitalWrite(ledPin, 1); // Turn on Notification LED | |
delay(50); // Blink LED | |
digitalWrite(ledPin, 0); // Turn off Notification LED | |
digitalWrite(XBeeSleep, 1); // Disable XBee | |
averageVcc = 0; // Reset voltage for new measurements | |
averageTemp = 0; // Reset temperature for new measurements | |
timeKeeper = 0; | |
} else { // Add a reading to the average | |
digitalWrite(ledPin, 1); // Turn on Notification LED | |
delay(1); // Blink LED very quickly | |
digitalWrite(ledPin, 0); // Turn off Notification LED | |
timeKeeper++; | |
} | |
wdt_reset(); // Get ready to go to sleep... | |
watchdogEnable(); // Turn on the watchdog timer | |
sleepNow(); // Go to sleep, watchdog timer will wake later | |
} | |
void watchdogEnable() { // Turn on watchdog timer; interrupt mode every 8.0s | |
cli(); | |
MCUSR = 0; | |
WDTCSR |= B00011000; | |
//WDTCSR = B01000111; // 2 Second Timeout | |
//WDTCSR = B01100000; // 4 Second Timeout | |
WDTCSR = B01100001; // 8 Second Timeout | |
sei(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment