SolarTherm

From JimWIKI

Jump to: navigation, search

SolarTHERM - SmartLED

Flickr Error ( ): PhotoID 2912778809This project is about creating an ornament that will display the current temperature periodically. It is powered by solar energy. It is designed to fit into a category of devices which have become known as smartLEDs. The idea is to imbue the humble LED with some kind of intelligence or purpose other than just as a dumb light. A good write up on SmartLED, the idea and theory can be found here on todbot.com and the original project which I think started the whole idea off is here on instructables

The intelligence or purpose that I'm trying to give the LED in this case is to display the ambient temperature that it finds it's self in. It will do this by pulsing the led in a sequence that displays the temperature in Celsius by first flashing out the tens, then the units of the reading.

Flickr Error ( ): PhotoID 219271415 The brain of the system is (currently) an Atmel ATTiny25 microcontroler, which has the benifit of having a built in temprature sensor, which helps keep the componnet count as low as practicaly possible. The LED is a fairly high power 'Flux' RGB LED, common annode type.

The well documented SmartLED examples on the net, all share the same traits, low component count, components soldered together directly, some level of asthetic consideration, and they are also all battery powered.

Flickr Error ( ): PhotoID 2205497475

These deisgn characteristics bring the SmartLED concept into close alignment with another area of engineering that I'm keen to explore, the world of BEAM Robotics. Specifically, I'm thinking of the 'Pummer' family, which are often described as a sort of electronic plant life.

There are a several differences between Pummers and SmartLEDs, but the two that really stick out are true pummers are solar powered and they also tend not to use microcontrolers. Thus, this project is never really going to sit well in either camp, but somewhere in between.

The Power is supplied by a small (or perhaps two) solar panels, which are connected to a circuit known as a Solar Engine. These circuits are at the heart of BEAM robotics and there are many designs. I've chosen a Solar Engine based (unusually) on an IC, the Maxim 8212. It's a simple circuit, and highly tunable to a specific purpose, working well as an energy reservoir for a micro controller. The key will be to make sure the current draw is absolutely minimal during the time the SolarTherm is sleeping (there will be about 30sec to 1 min between pulses), and this is done by using the uC's Watchdog, and low power sleep modes.

The aim of the solar engine is to store enough energy that the SmartLED will continue to function as the sun sets, into the twilight and early night. The ATTiny25 isn't the most accurate or well calibrated temperature sensor, but it should be good enough. However, I've also been interested in the Dallas DS1820 sensor which is very well calibrated, but tricky to code for. If the mood takes me, I may add this in for improved accuracy. As a final observation the word "Pummer" is supposed to suggest the action of the light as it fades up and down rather than basic flashing. Therefore, I'll need to implement some kind of PWM to allow the LED to fade ('Pum') or perhaps add in some caps to add some fall off.


--Jim 11:36, 14 September 2009 (UTC)

New Prototype

Flickr Error ( ): PhotoID 4473900008 Flickr Error ( ): PhotoID 4473900018 Flickr Error ( ): PhotoID 4473900026 Flickr Error ( ): PhotoID 4473899984

I've built a new prototype that follows the form factor of a SmartLED and is powered by a 3v coin cell. This tests the code as well as the basic structure outside of the breadboard. It was also a whole heap of fun to solder. I've made the call with this one not to bother using resistors (Gasp!). You can't pull too much current through a coin cell anyway, so I don't think I'm going to burn anything. When we move to caps we are going to have to plumb in resistors as that is a totally different story.

This version has a function that 'Pums' the brightness of the LED so that it has the appearance of a traditional BEAM Pummer, however this is using a Software PWM mechanism rather than using a Cap as a 'real' Beam Pummer would.

The code running on this version also fires after only eight seconds, rather than the ~30 seconds I had planned. Even so, it's been running constantly from the coin cell for about three days now, so that makes me feel good about the energy consumption.

I've not updated the code below yet to the latest version, but I'll do that soon.
















Code

#include <avr/io.h>
#define F_CPU 1000000UL  //1Mhz
#include <util/delay.h>
#include <avr/sleep.h>
#include <avr/wdt.h>

volatile uint8_t counter __attribute__ ((section (".noinit"))); 

void get_temp(void);
void spell_out(void);

volatile int offset = 278; //specific to individual chips
volatile int real_temp = 0;
volatile int avg_temp;
volatile int number_of_readings = 20;
volatile int raw_temp[20];

int main (void)
{
	while (1)
	{
		MCUSR = 0; 
			wdt_disable(); 
	  	set_sleep_mode(SLEEP_MODE_PWR_DOWN);

		if (counter == 0)
		{
			get_temp(); //first time to warm up
			get_temp();
			spell_out();
			_delay_ms(1000);
		}
		counter++; 
		if (counter >= 6) counter = 0;
			 
	  	wdt_enable(WDTO_8S);                
	    sleep_enable(); 
	    sleep_mode(); 
	}

}


void get_temp()
{

	////////////////////////////
	// Set the ADMUX register //
	////////////////////////////
	ADMUX = 0b00000000;

	// Use 1.1V internal Ref
	ADMUX |= 0b10000000;

	// Select ADC04 (temp sensor)
	ADMUX |= 0b00001111;


	/////////////////////////////
	// Set the ADCSRA register //
	/////////////////////////////
	ADCSRA = 0b00000000;

	// Auto triger enable
	ADCSRA |= 0b001000000;

	// Pre-Scaler to divide by 8
	ADCSRA |= 0b00000011;

	// Enable ADC
	ADCSRA |= 0b10000000;

	// Take First Measurements and discard it.
	ADCSRA |= 0b01000000;

	_delay_ms(100);


	// Take Measurements
	for( int i = 0; i < (number_of_readings-1); i++)
	{
		ADCSRA |= 0b01000000;
		raw_temp[i] = ADC;
		avg_temp += raw_temp[i];
		_delay_ms(50);
	}

	// Disable ADC
	ADCSRA |= 0b00000000;

	// Average the [number_of_readings] temp readings
	avg_temp = avg_temp/number_of_readings;

	real_temp=avg_temp-offset;

}

void spell_out()
{
		//Speak to Me!!
		volatile int i;
		volatile int temp_hundreds = real_temp/100;
		volatile int temp_ten = (real_temp/10)-(temp_hundreds*10);
		volatile int temp_unit = real_temp - ((temp_hundreds*100)+(temp_ten*10));

		DDRB  = 0x7;

		PORTB = 0x0;
		_delay_ms(100);

		PORTB = 0x7;
		_delay_ms(100);

		PORTB = 0x0;
		_delay_ms(100);

		PORTB = 0x7;
		_delay_ms(2000);

		for( i = 0; i < temp_hundreds; i++)
		{
			PORTB = 0x6;
			_delay_ms(500);
			PORTB = 0x7;
			_delay_ms(500);
		}

		_delay_ms(1000);
		for( i = 0; i < temp_ten; i++)
		{
			PORTB = 0x5;
			_delay_ms(500);
			PORTB = 0x7;
			_delay_ms(500);
		}

		_delay_ms(1000);

		for( i = 0; i < temp_unit; i++)
		{
			PORTB = 0x3;
			_delay_ms(500);
			PORTB = 0x7;
			_delay_ms(500);
		}
		DDRB  = 0x00;
}

Personal tools
Edge Of Space Program
Other Projects