Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdlib.h>
- #include <EEPROM.h>
- #include <SoftwareSerial.h>
- #include <avr/sleep.h> // Sleep Modes
- #include <avr/power.h> // Power management
- #include <avr/wdt.h> // Watchdog timer
- #include <avr/interrupt.h> // Interrupts handling
- // Definitions
- #define rxPin 3
- #define txPin 4
- // 0 1 0 Internal 1.1V Voltage Reference, calling INTERNAL should set the reference voltage to 1.1
- SoftwareSerial mySerial(rxPin, txPin);
- int currentTime = 0;
- int timeLastSaveFullTemp = 0;
- int nbr_remaining;
- int sensorPin = 7; // This is the 7th pin on the ATtiny85,
- // it is an analog input when reading as digital call it 7? analogpintochannel function
- // (On the HLT tutorial it is labelled as Pin2: Analog input 1, SCK )
- float temperature = -500.00f; // Create a new float called temperature and give it the value -500 to start with
- float prevTemp = -500.00f;
- float tempDiff = -500.00f;
- int tempAsInt = 0;
- int tempDiffAsInt = 0; // create int to store temperature difference between samples
- signed char tempDiffAsChar; // create char to store temp difference between samples, hopefully this saves as a 1 byte no. between -128 and 127 (will store like this on EEPROM where difference is small enough since only 1 byte) (range around -128 to 128 so can't use for temp diff greater than 10 deg)
- signed char warningNextDataIsTwoBytes = 111;
- int eepromAddress = 0; // initialize variable for position in eeprom to store data collected
- int decideWhatToSaveFlag = 1; // Decide what to save, if this = 0 then save the temp difference as a char (1 byte), otherwise save the entire temperature as an integer.
- // interrupt raised by the watchdog firing
- // when the watchdog fires during sleep, this function will be executed
- // remember that interrupts are disabled in ISR functions
- ISR(WDT_vect)
- {
- // not hanging, just waiting
- // reset the watchdog
- wdt_reset();
- }
- // function to configure the watchdog: let it sleep 8 seconds before firing
- // when firing, configure it for resuming program execution
- void configure_wdt(void)
- {
- cli(); // disable interrupts for changing the registers
- MCUSR = 0; // reset status register flags
- // Put timer in interrupt-only mode:
- WDTCR |= 0b00011000; // Set WDCE (5th from left) and WDE (4th from left) to enter config mode,
- // using bitwise OR assignment (leaves other bits unchanged).
- WDTCR = 0b01000000 | 0b100001; // set WDIE: interrupt enabled, 8 seconds
- // clr WDE: reset disabled
- // and set delay interval (right side of bar) to 8 seconds
- sei(); // re-enable interrupts
- }
- // Put arduino to sleep.
- void sleep(int ncycles)
- {
- nbr_remaining = ncycles; // defines how many cycles should sleep
- // Set sleep to full power down. Only external interrupts or
- // the watchdog timer can wake the CPU!
- set_sleep_mode(SLEEP_MODE_PWR_DOWN);
- // Turn off the ADC while asleep.
- power_adc_disable();
- while (nbr_remaining > 0){ // while some cycles left, sleep!
- // Enable sleep and enter sleep mode.
- sleep_mode();
- // CPU is now asleep and program execution completely halts!
- // Once awake, execution will resume at this point if the
- // watchdog is configured for resume rather than restart
- // When awake, disable sleep mode
- sleep_disable();
- // we have slept one time more
- nbr_remaining = nbr_remaining - 1;
- }
- // put everything on again
- power_all_enable();
- }
- // the setup routine runs once when you press reset:
- void setup() {
- analogReference(INTERNAL); // This sets the internal ref to be 1.1V (or close to this), note that this makes 1.1V the highest voltage. The TMP36 gives 1.1V at around 55 or 60 deg so need to not put the chip in temperatures hotter than 55deg
- pinMode(sensorPin, INPUT); // make pin 7 on the ATTiny an input pin
- delay(1000);
- configure_wdt(); // configure the watchdog
- mySerial.begin(9600); // begin software serial at rate of 9600
- }
- // the loop routine runs over and over forever:
- void loop() {
- sleep(450); // sleep for a given number of cycles (here, 450 * 8 seconds = 60mins) in lowest power mode
- currentTime = currentTime + 60; // add 60 min to current time
- if((eepromAddress<=510)) // the eeprom still has space
- {
- /***********Get temperature from sensor, then calculate difference since previous reading****************/
- //Earlier set the reference voltage for the analog to digital converter to 1.1V. This means a value of 1.1V will be read as the maximum (not sure if 1023 or 1024, but anyway)
- //Note that this means an input greater than 1.1V from the temperature sensor (temperature about 55deg) is bad, not sure if it will damage the circuit or give bad readings but avoid.
- temperature = analogRead(sensorPin)*1100.0/1024.0; // read value on pin 7, between 0 and 1023 where 1023 is max, convert result back to a voltage in millivolts.
- temperature = (temperature - 500)/ 10; //Celcius temperature = [(analog voltage in mV) - 500] / 10
- tempDiff = temperature - prevTemp;
- /******* Change temperature diffence to integer and a signed char if it's between -2 and 2 deg ***********/
- tempAsInt = int(round(temperature*10)); // multiply temp. by 10 then round and change to an integer type, this should give temp. as a three digit integer scaled by x10, e.g. 335 = 33.5deg, 120 = 12.0deg etc.
- tempDiffAsInt = int (round(tempDiff*10));
- // work out whether want to save complete temperature or just temp difference
- if ((currentTime - timeLastSaveFullTemp) >=10) // If the entire temperature hasn't been saved for more than 10 min, then want to save the entire temperature rather than just difference
- {
- decideWhatToSaveFlag = 1; // Set flag to 1, since want to save entire temperature
- }
- else
- decideWhatToSaveFlag = 0; // If the entire temperature has already been saved recently then set flag to zero since only want to save the difference.
- if ((tempDiffAsInt>-20 and tempDiffAsInt<20)and (decideWhatToSaveFlag == 0)) // if temp change is less than 2 degrees and if the decideWhatToSaveFlag hasn't been previously set to 1 for another reason.
- tempDiffAsChar = (char)(tempDiffAsInt);
- else decideWhatToSaveFlag = 1; // if the temp diff since prev sample is > 2 degrees or less than -2 degrees then set flag to 1 since want to save the entire temp. not just the difference
- if (decideWhatToSaveFlag == 0)
- {
- //mySerial.print(" Temp diff");
- EEPROM.put(eepromAddress, tempDiffAsChar);
- eepromAddress = eepromAddress + sizeof(tempDiffAsChar);
- }
- else
- {
- EEPROM.put(eepromAddress, warningNextDataIsTwoBytes);
- eepromAddress = eepromAddress + sizeof(warningNextDataIsTwoBytes);
- EEPROM.put(eepromAddress, tempAsInt);
- eepromAddress = eepromAddress + sizeof(tempAsInt);
- timeLastSaveFullTemp = currentTime; // Update time entire temperature was last saved to the current time.
- }
- prevTemp = temperature; // copy temp to prev temp for next time.
- }
- }
Add Comment
Please, Sign In to add comment