Guest User

Untitled

a guest
Mar 21st, 2018
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.32 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <EEPROM.h>
  3. #include <SoftwareSerial.h>
  4.  
  5. #include <avr/sleep.h> // Sleep Modes
  6. #include <avr/power.h> // Power management
  7. #include <avr/wdt.h> // Watchdog timer
  8. #include <avr/interrupt.h> // Interrupts handling
  9.  
  10. // Definitions
  11. #define rxPin 3
  12. #define txPin 4
  13.  
  14. // 0 1 0 Internal 1.1V Voltage Reference, calling INTERNAL should set the reference voltage to 1.1
  15.  
  16. SoftwareSerial mySerial(rxPin, txPin);
  17.  
  18. int currentTime = 0;
  19. int timeLastSaveFullTemp = 0;
  20.  
  21. int nbr_remaining;
  22. int sensorPin = 7; // This is the 7th pin on the ATtiny85,
  23.  
  24. // it is an analog input when reading as digital call it 7? analogpintochannel function
  25. // (On the HLT tutorial it is labelled as Pin2: Analog input 1, SCK )
  26.  
  27. float temperature = -500.00f; // Create a new float called temperature and give it the value -500 to start with
  28. float prevTemp = -500.00f;
  29. float tempDiff = -500.00f;
  30.  
  31. int tempAsInt = 0;
  32. int tempDiffAsInt = 0; // create int to store temperature difference between samples
  33.  
  34. 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)
  35. signed char warningNextDataIsTwoBytes = 111;
  36.  
  37. int eepromAddress = 0; // initialize variable for position in eeprom to store data collected
  38.  
  39. 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.
  40.  
  41.  
  42. // interrupt raised by the watchdog firing
  43. // when the watchdog fires during sleep, this function will be executed
  44. // remember that interrupts are disabled in ISR functions
  45. ISR(WDT_vect)
  46. {
  47. // not hanging, just waiting
  48. // reset the watchdog
  49. wdt_reset();
  50. }
  51.  
  52.  
  53. // function to configure the watchdog: let it sleep 8 seconds before firing
  54. // when firing, configure it for resuming program execution
  55. void configure_wdt(void)
  56. {
  57.  
  58. cli(); // disable interrupts for changing the registers
  59.  
  60. MCUSR = 0; // reset status register flags
  61.  
  62. // Put timer in interrupt-only mode:
  63. WDTCR |= 0b00011000; // Set WDCE (5th from left) and WDE (4th from left) to enter config mode,
  64. // using bitwise OR assignment (leaves other bits unchanged).
  65. WDTCR = 0b01000000 | 0b100001; // set WDIE: interrupt enabled, 8 seconds
  66. // clr WDE: reset disabled
  67. // and set delay interval (right side of bar) to 8 seconds
  68.  
  69. sei(); // re-enable interrupts
  70.  
  71.  
  72.  
  73. }
  74.  
  75. // Put arduino to sleep.
  76. void sleep(int ncycles)
  77. {
  78. nbr_remaining = ncycles; // defines how many cycles should sleep
  79.  
  80. // Set sleep to full power down. Only external interrupts or
  81. // the watchdog timer can wake the CPU!
  82. set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  83.  
  84. // Turn off the ADC while asleep.
  85. power_adc_disable();
  86.  
  87. while (nbr_remaining > 0){ // while some cycles left, sleep!
  88.  
  89. // Enable sleep and enter sleep mode.
  90. sleep_mode();
  91.  
  92. // CPU is now asleep and program execution completely halts!
  93. // Once awake, execution will resume at this point if the
  94. // watchdog is configured for resume rather than restart
  95.  
  96. // When awake, disable sleep mode
  97. sleep_disable();
  98.  
  99. // we have slept one time more
  100. nbr_remaining = nbr_remaining - 1;
  101.  
  102. }
  103.  
  104. // put everything on again
  105. power_all_enable();
  106.  
  107. }
  108.  
  109.  
  110. // the setup routine runs once when you press reset:
  111. void setup() {
  112. 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
  113. pinMode(sensorPin, INPUT); // make pin 7 on the ATTiny an input pin
  114.  
  115. delay(1000);
  116.  
  117. configure_wdt(); // configure the watchdog
  118.  
  119. mySerial.begin(9600); // begin software serial at rate of 9600
  120.  
  121. }
  122.  
  123. // the loop routine runs over and over forever:
  124. void loop() {
  125.  
  126. sleep(450); // sleep for a given number of cycles (here, 450 * 8 seconds = 60mins) in lowest power mode
  127.  
  128. currentTime = currentTime + 60; // add 60 min to current time
  129.  
  130.  
  131. if((eepromAddress<=510)) // the eeprom still has space
  132. {
  133.  
  134. /***********Get temperature from sensor, then calculate difference since previous reading****************/
  135.  
  136. //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)
  137. //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.
  138.  
  139. 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.
  140. temperature = (temperature - 500)/ 10; //Celcius temperature = [(analog voltage in mV) - 500] / 10
  141. tempDiff = temperature - prevTemp;
  142.  
  143. /******* Change temperature diffence to integer and a signed char if it's between -2 and 2 deg ***********/
  144. 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.
  145. tempDiffAsInt = int (round(tempDiff*10));
  146.  
  147. // work out whether want to save complete temperature or just temp difference
  148. 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
  149. {
  150. decideWhatToSaveFlag = 1; // Set flag to 1, since want to save entire temperature
  151. }
  152. else
  153. decideWhatToSaveFlag = 0; // If the entire temperature has already been saved recently then set flag to zero since only want to save the difference.
  154.  
  155. 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.
  156. tempDiffAsChar = (char)(tempDiffAsInt);
  157.  
  158. 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
  159.  
  160.  
  161. if (decideWhatToSaveFlag == 0)
  162. {
  163. //mySerial.print(" Temp diff");
  164. EEPROM.put(eepromAddress, tempDiffAsChar);
  165. eepromAddress = eepromAddress + sizeof(tempDiffAsChar);
  166. }
  167.  
  168. else
  169. {
  170. EEPROM.put(eepromAddress, warningNextDataIsTwoBytes);
  171. eepromAddress = eepromAddress + sizeof(warningNextDataIsTwoBytes);
  172. EEPROM.put(eepromAddress, tempAsInt);
  173. eepromAddress = eepromAddress + sizeof(tempAsInt);
  174. timeLastSaveFullTemp = currentTime; // Update time entire temperature was last saved to the current time.
  175. }
  176.  
  177. prevTemp = temperature; // copy temp to prev temp for next time.
  178.  
  179. }
  180.  
  181. }
Add Comment
Please, Sign In to add comment