Created
January 9, 2014 21:05
-
-
Save technobly/8342009 to your computer and use it in GitHub Desktop.
Temperature filtering with a 1/16th Dilution Filter for Spark Core
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//---------------------------------------------------- | |
// 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