//---------------------------------------------------- // 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 bool state = 0; // 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 > 500) { // punch this every 5 secs msCounter = 0; state = !state; digitalWrite(D7,state); Spark.sleep(5); // 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