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).
This commit is contained in:
Admar Schoonen 2012-01-07 10:20:42 +01:00
parent f74e4aedca
commit c5561f8aaf
1 changed files with 104 additions and 65 deletions

View File

@ -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);
}