Go Down

Topic: Hot Yet? (a tiny85 project) (Read 992 times) previous topic - next topic

mrburnette

The concept is simple, if a thermistor detects a temperature change when the tiny85 wakes which was significantly different from the previous awake period, turn PWM on a RGB led based upon the current temperature and track the change until it stabilizes.
http://youtu.be/PTEd7IiuHaE
http://www.youtube.com/watch?v=PTEd7IiuHaE&feature=youtu.be

The example here is just for fun, but was intended to provide a visual feedback for a hot water faucet; that is, as the temperature moves from cold to hot, the RGB LED goes from Blue to Green to Red with overlap in the crossover ranges.
http://youtu.be/AhAL-5vd79U
http://www.youtube.com/watch?v=AhAL-5vd79U&feature=youtu.be

The code is simple.  The sleep routines are a combination of Nick Gammon low-power settings, Watchdog settings from the InsideGadgets site, and the tiny core from Coding Badly.

This is a project that simply screams for hacking.  If the temperature has not changed during the wakeup, the circuit goes back to sleep.  Here in the lab, I have been running the project off of a CR2032 (already half-dead) for several weeks.  So, what about a wearable "mood" pendant, or "mood" wrist-band?  Using surface mount tiny, you may be able to get this into a large ring?  

Whatever you decide to do, have fun and keep us posted!


Ray

Code: [Select]

/*
  M. Ray Burnette 20140210 Open Source: for "Hot Yet?" publication
  Coding Badly Tiny core: https://code.google.com/p/arduino-tiny/
  Binary sketch size: 2,852 bytes (of a 8,192 byte maximum)
  Arduino 1.0.5 No bootloader used.  Upload via ISP.
  Project 3.3V Attiny85 @8MHz internal,  under 10mA idle at 68F

  Schematic:
  x-----------------/\/\/\/\/\/\/\/---------------x---/\/\/\/\/\/\/\----xGND
  |                NTC 10K Thermistor             |  10K 1% Resistor
  |                                               |
  |              ATTINY85 / ARDUINO               |
  |                     +-\/-+                    |
  |    Ain0 (D 5) PB5  1|    |8  Vcc              |
  x--- Ain3 (D 3) PB3  2|    |7  PB2 (D 2) Ain1 ---
(Blue)- Ain2 (D 4) PB4  3|    |6  PB1 (D 1) pwm1  (Green) ----------|<---x
  |               GND  4|    |5  PB0 (D 0) pwm0  (Red) ------------|<---x
  |                     +----+                                          |    100 Ohm
  x----------------------------------------------------------------|<---x---/\/\/\/\/---Vcc 3.3V

*/
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>

boolean flag_wdt = 1;

int pinT = PB3;           // Thermistor source voltage
int pinR = PB0;           // Digital pin #0  Red
int pinG = PB1;           // Digital pin #1  Green
int pinB = PB4;           // Digital pin #4  Blue
int r; int g; int b;
const int nToSleep = 50 ; // # of stable temp readings before sleep
const int Delay =    100; // main loop delay in mS
double ADCcount;
double ADCprevious;
int nCount;
int ThermistorPin  = 1 ;  // A1 is physical pin #7 (PB2)

void setup()
{
 // WDTO_15MS, WDTO_30MS, WDTO_60MS, WDTO_120MS, WDTO_250MS, WDTO_500MS,
 // WDTO_1S, WDTO_2S, WDTO_4S, WDTO_8S
 setup_watchdog(WDTO_4S);  // Periodic Heartbeat to awaken deep sleep()
 sleep_disable();
 pinMode(pinT, OUTPUT); digitalWrite(pinT, HIGH);  // Thermistor Source
 pinMode(pinR, OUTPUT);
 pinMode(pinG, OUTPUT);
 pinMode(pinB, OUTPUT);
}
 
void loop()
{
 wdt_reset();    // pat K9
 ADCcount = analogRead(ThermistorPin) ;
 if (ADCcount == ADCprevious) ++nCount;
 if ( nCount > nToSleep )
 { // prepare for low current power-down state
   pinMode(pinR, INPUT); digitalWrite(pinR, HIGH);  // pullup enabled
   pinMode(pinG, INPUT); digitalWrite(pinG, HIGH);
   pinMode(pinB, INPUT); digitalWrite(pinB, HIGH);
   SleepLonger:    // Come here to re-sleep
   pinMode(pinT, INPUT); digitalWrite(pinT, HIGH);
     system_sleep();
     sleep_disable();  // deep sleep until WDT kicks
     pinMode(pinT, OUTPUT); digitalWrite(pinT, HIGH);
     delay(50);
     // Yawn, exercise a few reads for stabilization
     for (uint8_t z=0; z<5; z++) {
       ADCcount = analogRead(ThermistorPin) ;
     }
     if (abs(ADCcount - ADCprevious) < 4) goto SleepLonger;  // hysteresis
   // restore LED output drivers ... temp has gone up
   pinMode(pinR, OUTPUT); digitalWrite(pinR, HIGH);
   pinMode(pinG, OUTPUT); digitalWrite(pinG, HIGH);
   pinMode(pinB, OUTPUT); digitalWrite(pinB, HIGH);
   nCount = 0;
 } else {
 // 261 = 32F, 447 = 64F, 537 = 75F, 575 = 82F
 b = map(ADCcount, 261,  447, 100, 255 );
 g = map(ADCcount, 435,  574, 250, 100);  // overlap green & blue
 r = map(ADCcount, 575, 1023, 250,  50);

 if (ADCcount > 574)              // HOT: ADCcount goes up with increase temperature
   {
     // Show only Red when Hot with Red intensity increasing with temperature
     analogWrite(pinR,   r);
     analogWrite(pinG, 255);      // 255 = 100% High == NO LED Current Common Anode --> Vcc
     analogWrite(pinB, 255);      // Blue Off
   } else {                       // Cold to Cool transition with Blue fading into Green
     analogWrite(pinR, 255);      // Red Off
     analogWrite(pinG, g);
     analogWrite(pinB, b);        // Brighter Blue with colder temp
   }
 }
 ADCprevious = ADCcount;
 delay(Delay);
}

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
// http://www.insidegadgets.com/wp-content/uploads/2011/02/ATtiny85_watchdog_example.zip
void system_sleep()
{
   cbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter OFF
   power_all_disable ();                // power off ADC, Timer 0 and 1, serial interface
   set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
   noInterrupts ();                     // timed sequence coming up
   sleep_enable();
   interrupts ();                       // interrupts are required now
   sleep_mode();                        // System sleeps here
   sleep_disable();                     // System continues execution here when watchdog timed out
   power_all_enable ();                 // power everything back on
   sbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter ON
}

// 0=16ms, 1=32ms, 2=64ms, 3=128ms, 4=250ms, 5=500ms, 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
void setup_watchdog(int ii)
{
 byte bb;
 int ww;
 if (ii > 9 ) ii=9;
 bb=ii & 7;
 if (ii > 7) bb|= (1<<5);
 bb|= (1<<WDCE);
 ww=bb;

 MCUSR &= ~(1<<WDRF);
 // start timed sequence
 WDTCR |= (1<<WDCE) | (1<<WDE);
 // set new watchdog timeout value
 WDTCR = bb;
 WDTCR |= _BV(WDIE);
}
 
// Watchdog Interrupt Service / is executed when watchdog timed out
ISR(WDT_vect) {
    // wdt_disable();  // disable watchdog
}

elac

Very cool 8) ... or hot  ]:)
My 85s should be here this week, great project to play around with.
The wrist band idea is neat, could be done with a few segments of an RGB strip.
It's all about the skills

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy