From c5561f8aafcba9f6c0f787d1416900cfab3cd76e Mon Sep 17 00:00:00 2001 From: Admar Schoonen Date: Sat, 7 Jan 2012 10:20:42 +0100 Subject: [PATCH] Split up wordclock thread into multiple threads wordclock thread is now reduced to only taking care of displaying the time; blink thread and lightsensor thread take care of blinking led and reading lightsensor (and calculating new brightness value). --- wordclock/wordclock.ino | 169 ++++++++++++++++++++++++---------------- 1 file changed, 104 insertions(+), 65 deletions(-) diff --git a/wordclock/wordclock.ino b/wordclock/wordclock.ino index e06b546..3f5b92a 100644 --- a/wordclock/wordclock.ino +++ b/wordclock/wordclock.ino @@ -102,7 +102,6 @@ unsigned int brightness_per_unit_light = ((1 << LIGHTSENSOR_SCALE) * (MAXBRIGHTN MINBRIGHTNESS)) / (LIGHTSENSOR_TOP - LIGHTSENSOR_BOTTOM); int hour=12, minute=0, second=0; -static unsigned long msTick =0; // the number of Millisecond Ticks since we last // incremented the second counter int count; int selftestmode; // 1 = in self test - flash display @@ -159,7 +158,7 @@ char buf[50]; // time output string for debugging DS1302 rtc(DS1302CEPin, DS1302IOPin, DS1302CLKPin); // ProtoThread structures (one for each thread) -static struct pt blink_thread_pt, buttons_thread_pt, wordclock_thread_pt; +static struct pt blink_thread_pt, lightsensor_thread_pt, buttons_thread_pt, wordclock_thread_pt; void print_DS1302time() { @@ -310,7 +309,6 @@ void setup() Serial.println("Finished setting up Timer2 Interrupt"); - msTick=millis(); // Initialise the msTick counter #if (SKIPSELFTEST != 1) selftest(); // validate the hardware for the user @@ -414,10 +412,6 @@ void process_buttons(unsigned char button_status) static unsigned long button_delay = BUTTON_DELAY_LONG; unsigned long millisNow = 0, new_button_delay; - // test to see if both buttons are being held down - // if so - start a self test till both buttons are held - // down again. - //if ( digitalRead(FWD_BUTTON_PIN)==BTNActive && digitalRead(REV_BUTTON_PIN)==BTNActive) if (BTNActive) { if ((button_status & FWD_BUTTON_MASK) > 0) @@ -438,6 +432,10 @@ void process_buttons(unsigned char button_status) selftestmode != selftestmode; } + // test to see if both buttons are being held down + // if so - start a self test till both buttons are held + // down again. + //if ( digitalRead(FWD_BUTTON_PIN)==BTNActive && digitalRead(REV_BUTTON_PIN)==BTNActive) if (selftestmode) { Serial.println("Selftest Mode TRUE"); for(int i=0; i<100; i++) @@ -468,7 +466,6 @@ void process_buttons(unsigned char button_status) displaytime(); } - //if (digitalRead(REV_BUTTON_PIN)==BTNActive ) if (revButtonPressed) { Serial.println("Backwards Button Down"); @@ -530,17 +527,101 @@ static int buttons_thread(struct pt *pt) PT_END(pt); } +static int lightsensor_thread(struct pt *pt) +{ + static unsigned long msTick =0; // the number of Millisecond Ticks since we last + static unsigned long int lightlevel_avg; + unsigned long int lightlevel_sample; + static char millisWillOverflow = 0; + static char n_lightlevel_samples = 0; + + PT_BEGIN(pt); + + while(1) + { + PT_WAIT_UNTIL(pt, millisWillOverflow ? (millis() - msTick > 99) : + ((millis() < 4294967295 - 98) && (millis() - msTick > 99))); + msTick=millis(); + + lightlevel_sample = analogRead(LIGHTSENSOR_INPUTPIN); + + // update average + if (n_lightlevel_samples < (1 << LIGHTSENSOR_WEIGHT)) + { + // add (1 << (LIGHTSENSOR_WEIGHT - 1)) to average before division so that + // the average is round()-ed instead of floor()-ed + lightlevel_avg = (n_lightlevel_samples * lightlevel_avg + + lightlevel_sample + (1 << (LIGHTSENSOR_WEIGHT - 1))) / + (n_lightlevel_samples + 1); + n_lightlevel_samples++; + } + else + { + // do not update n_lightlevel_samples to prevent overflow + + // add (1 << (LIGHTSENSOR_WEIGHT - 1)) to average before division so that + // the average is round()-ed instead of floor()-ed + lightlevel_avg = ( ((1 << LIGHTSENSOR_WEIGHT) - 1) * lightlevel_avg + + lightlevel_sample + (1 << (LIGHTSENSOR_WEIGHT - 1))) >> LIGHTSENSOR_WEIGHT; + } + + // compute new brightness level + /* + // linear method + if (lightlevel_avg <= LIGHTSENSOR_BOTTOM) + current_brightnes = MINBRIGHTNESS; + else if (lightlevel_avg >= LIGHTSENSOR_TOP) + current_brightnes = MAXBRIGHTNESS; + else + { + current_brightnes = (brightness_per_unit_light * (lightlevel_avg - + LIGHTSENSOR_BOTTOM)) / (1 << LIGHTSENSOR_SCALE) + MINBRIGHTNESS; + } */ + + current_brightnes = ambient_light_to_brightness[lightlevel_avg]; + + Serial.print("lightsensor: "); + Serial.print(lightlevel_sample); + Serial.print(" / "); + Serial.print(lightlevel_avg); + Serial.print(", brightness: "); + Serial.println(current_brightnes); + } + + PT_END(pt); +} + static int blink_thread(struct pt *pt) { + static unsigned long msTick =0; // the number of Millisecond Ticks since we last + static char millisWillOverflow = 0; + PT_BEGIN(pt); + + while(1) + { + PT_WAIT_UNTIL(pt, millisWillOverflow ? (millis() - msTick > 999) : + ((millis() < 4294967295 - 998) && (millis() - msTick > 999))); + msTick=millis(); + Serial.println(":)"); + + // Flash the onboard Pin13 Led so we know something is hapening! + digitalWrite(13,HIGH); + delay(50); + digitalWrite(13,LOW); + delay(50); + digitalWrite(13,HIGH); + delay(50); + digitalWrite(13,LOW); + } + + PT_END(pt); } static int wordclock_thread(struct pt *pt) { - static unsigned long int lightlevel_avg; - unsigned long int lightlevel_sample; - static char n_lightlevel_samples = 0; static unsigned int counter = 0; + static unsigned long msTick =0; // the number of Millisecond Ticks since we last static char millisWillOverflow = 0; #ifdef TESTMODE @@ -550,6 +631,7 @@ static int wordclock_thread(struct pt *pt) //Serial.println("Loop Started"); PT_BEGIN(pt); + msTick=millis(); // Initialise the msTick counter // heart of the timer - keep looking at the millisecond timer on the Arduino // and increment the seconds counter every 1000 ms @@ -569,20 +651,18 @@ static int wordclock_thread(struct pt *pt) millisWillOverflow = 0; second++; - // Flash the onboard Pin13 Led so we know something is hapening! - digitalWrite(13,HIGH); - delay(50); - digitalWrite(13,LOW); - delay(50); - digitalWrite(13,HIGH); - delay(50); - digitalWrite(13,LOW); //test to see if we need to increment the time counters if (second==60) { incrementtime(); displaytime(); + Serial.print("time: "); + Serial.print(hour, DEC); + Serial.print(":"); + Serial.print(minute, DEC); + Serial.print(":"); + Serial.println(second, DEC); } if (DS1302Present==1) { @@ -593,53 +673,8 @@ static int wordclock_thread(struct pt *pt) hour=t.hr; } + #if (USELIGHTSENSOR == 0) // set the brightnes level based on the current hour - night=7pm - 6.59am - // - #if (USELIGHTSENSOR == 1) - lightlevel_sample = analogRead(LIGHTSENSOR_INPUTPIN); - - // update average - if (n_lightlevel_samples < (1 << LIGHTSENSOR_WEIGHT)) - { - // add (1 << (LIGHTSENSOR_WEIGHT - 1)) to average before division so that - // the average is round()-ed instead of floor()-ed - lightlevel_avg = (n_lightlevel_samples * lightlevel_avg + - lightlevel_sample + (1 << (LIGHTSENSOR_WEIGHT - 1))) / - (n_lightlevel_samples + 1); - n_lightlevel_samples++; - } - else - { - // do not update n_lightlevel_samples to prevent overflow - - // add (1 << (LIGHTSENSOR_WEIGHT - 1)) to average before division so that - // the average is round()-ed instead of floor()-ed - lightlevel_avg = ( ((1 << LIGHTSENSOR_WEIGHT) - 1) * lightlevel_avg + - lightlevel_sample + (1 << (LIGHTSENSOR_WEIGHT - 1))) >> LIGHTSENSOR_WEIGHT; - } - - // compute new brightness level - /* - // linear method - if (lightlevel_avg <= LIGHTSENSOR_BOTTOM) - current_brightnes = MINBRIGHTNESS; - else if (lightlevel_avg >= LIGHTSENSOR_TOP) - current_brightnes = MAXBRIGHTNESS; - else - { - current_brightnes = (brightness_per_unit_light * (lightlevel_avg - - LIGHTSENSOR_BOTTOM)) / (1 << LIGHTSENSOR_SCALE) + MINBRIGHTNESS; - } */ - - current_brightnes = ambient_light_to_brightness[lightlevel_avg]; - - Serial.print("lightsensor: "); - Serial.print(lightlevel_sample); - Serial.print(" / "); - Serial.print(lightlevel_avg); - Serial.print(", brightness: "); - Serial.println(current_brightnes); - #else if ((hour < DAYLIGHTHOUR) | (hour >= NIGHTLIGHTHOUR)) current_brightnes=MINBRIGHTNESS; else @@ -655,5 +690,9 @@ void loop() // call each thread continuously wordclock_thread(&wordclock_thread_pt); buttons_thread(&buttons_thread_pt); + #if (USELIGHTSENSOR == 1) + lightsensor_thread(&lightsensor_thread_pt); + #endif + blink_thread(&blink_thread_pt); }