Skip to content

Instantly share code, notes, and snippets.

@technobly
Created January 9, 2014 21:05
Show Gist options
  • Save technobly/8342009 to your computer and use it in GitHub Desktop.
Save technobly/8342009 to your computer and use it in GitHub Desktop.
Temperature filtering with a 1/16th Dilution Filter for Spark Core
//----------------------------------------------------
// Temperature filtering with a 1/16th Dilution Filter
// BDub 12-21-2013
//
// 1/16th of the new reading gets added to the ongoing
// running total of 16 virtual readings, with a little
// correction for the truncation process. Very fast
// filter for slow 8-bit uC's that don't have multiply
// or divide instructions.
//
// avg = (new + (avg * 16) - avg +/- offset) / 16;
// avg = (new + (avg * 15) +/- offset) / 16;
//----------------------------------------------------
uint8_t TEMP_PIN = A0;
uint8_t LEDPIN = D7;
uint8_t DEBUG = true;
uint16_t rawTemp = 0;
uint16_t avgTemp = 0;
int16_t offset = 0;
uint32_t lastTime = 0;
uint16_t msCounter = 0;
uint16_t threshTEMP = 2048; // approx. 3.3V/2
// The larger the update interval, the heavier the filter will be.
uint32_t UPDATE_INTERVAL = 10; // in milliseconds
void setup()
{
// for debug
if(DEBUG) Serial1.begin(115200);
//pinMode(TEMP_PIN, INPUT);
pinMode(LEDPIN, OUTPUT);
// seed the average reading
avgTemp = analogRead(TEMP_PIN);
}
void loop() {
// Update the filter every 10ms (default)
if(millis() - lastTime > UPDATE_INTERVAL) {
// Set a new last time
lastTime = millis();
// Read the temperature input
rawTemp = analogRead(TEMP_PIN);
// Add or subtract the offset based on new reading
if(rawTemp >= avgTemp)
offset = 15;
else
offset = -15;
// Filter the ADC every 10 ms (will resolve in approx. 740ms worst case 0-5V)
avgTemp = (uint16_t)((rawTemp + (avgTemp << 4) - avgTemp + offset ) >> 4);
// You can see this is a fast way to multiply by 15.
// Debug
if(DEBUG) {
Serial1.print("RAW: ");
Serial1.print(rawTemp);
if((rawTemp > 99) && (rawTemp < 1000))
Serial1.print(" ");
else if((rawTemp > 9) && (rawTemp < 100))
Serial1.print(" ");
else if(rawTemp < 10)
Serial1.print(" ");
Serial1.print(" AVG: ");
Serial1.println(avgTemp);
}
// Process Temperature Reading every 100ms
// Every time through is 10ms, 10 x 10ms = 100ms.
if(++msCounter > 10) {
msCounter = 0;
// If temperature is above thresh, light the LED
if(avgTemp > threshTEMP) {
digitalWrite(LEDPIN,HIGH);
}
// else keep the LED off
else {
digitalWrite(LEDPIN,LOW);
}
} // End inner timing loop (100 ms)
} // End outer timing loop (10 ms)
} // End main loop (currently runs every 5-6 ms
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment