Hi to all,
I am trying to write a "simple" sketch to improve the following task:
I have an instrument that sometimes, during the day heats up at more than 100 °C for a few minutes and the rest of the day stays at ambient temperature. I need a simple, and battery powered , circuit to read the amount of time the instrument is hot and save that duration (ex. minutes) in EEPROM.
My idea is to use a ATMEGA 328p programmed to run at 8MHz internal clock without any other components outside (crystal etc.) in order to save power.
The firmware i am writing simply keep the CPU always SLEEP_MODE_PWR_DOWN, until an interrupt is made on pin 2 (FALLING) . The interrupt is done using a simple mechanical termostat calibrated at 100 °C (those used inside domestic devices, like flat irons, for security reasons). It can be seen as a mechanical button connected to pin2 kept high by INPUT_PULLUP.
When the CPU is awaked from sleep it keeps the value of millis() and go to sleep in SLEEP_MODE_IDLE until the termostat opens (RISING). At that time the CPU calculate the time elapsed and write inside the EEPROM, after that goes to SLEEP_MODE_PWR_DOWN again until next event.
My problems (2):
- When i put the CPU in PWR_DOWN mode the arduino sleeps, but when it awakes i have strange characters coming from the serial port (strange bytes)
- When i call IDLE sleep the CPU doesn't go to sleep.. I am usind IDLE because it seems the only way to keep millis() running, otherwise i cannot take durations.
Below i attach only the "core" part of the code, in wich i implement the sleep/awake tasks.
#include <Arduino.h>
#include <avr/sleep.h>
#include <avr/power.h>
// VARS
#define int_pin 2
#define led_pin 8
#define debounce_time 10
uint8_t int_type = 0;
long lastMillis = millis();
long elapsedTime = 0;
int counter = 0;
// ================================================================================
// ISR
// ================================================================================
void isr()
{
// do nothing
}
// ================================================================================
// Blink led
// ================================================================================
void blink_led(int time)
{
digitalWrite(led_pin, HIGH);
delay(time);
digitalWrite(led_pin, LOW);
}
// ================================================================================
// Setup
// ================================================================================
void setup()
{
// Declare pins
pinMode(int_pin, INPUT_PULLUP);
pinMode(led_pin, OUTPUT);
// Begin serial
Serial.begin(115200);
// Disable unused peripherals to reduce power consumption
power_adc_disable();
power_spi_disable();
power_twi_disable();
// Attach interrupt
attachInterrupt(digitalPinToInterrupt(int_pin), isr, CHANGE);
// Set the sleep mode to Power-down
set_sleep_mode(SLEEP_MODE_PWR_DOWN;
}
// ================================================================================
// Loop
// ================================================================================
void loop()
{
// Go to sleep
sleep_mode();
// ----------- sleeping . . . ----------------
Serial.println("AWAKE!");
// debounce
delay(debounce_time);
// Flush serial
Serial.flush();
// Detect INT type
int_type = digitalRead(int_pin);
// HOT condition
if(int_type == 0)
{
Serial.println("FALLING, HOT");
blink_led(10);
lastMillis = millis();
set_sleep_mode(SLEEP_MODE_IDLE);
}
// COLD condition
else
{
Serial.println("RISING, COLD");
blink_led(10);
elapsedTime = lastMillis;
Serial.print("Time elapsed: ");
Serial.println(elapsedTime);
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
}
}