// temperaturedimmer : AC Light Dimmer Module with DS18B20 temperature sensor changes gradually changing // of AC power (useful for infrared ceramic heating bulbs). Note maxtemp and mintemp variables, in this // range, the dimmer is working at partially power gradient-like. Reads temperature every minute, changes // of dimming - 3 times per minute. #include #include #include #define ONE_WIRE_BUS 6 // Temperature senson DS18B20 signal pin OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); bool serialshow = true; // Enable/disable serial output int currenttemp = -127; // -127 - means sensor can't gain temperature data int dimmerpin = 10; // Dimmer Digital PWM pin int dimming = 128; // Dimming level (0-128) 0 = FULL ON, 128 = OFF // 4-128 is recommended range (4 is maximum) int maxtemp = 24; // Maximum temperature - dimmer works at minimum power // if above maxtemp, dimmer not working int mintemp = 21; // Minumum temperature (or less) - dimmer works at maximum power // Threads: Thread checkTempThread = Thread(); // Thread for temperature state checking Thread changeDimmerThread = Thread(); // Thread for dimmer level changing void setup() { if (serialshow) { Serial.begin(9600); // Initializes the Serial connection @ 9600 baud for debug Serial.println("start"); } pinMode(LED_BUILTIN, OUTPUT); // Initializes builtin LED digitalWrite(LED_BUILTIN, HIGH); pinMode(dimmerpin, OUTPUT); // Set the AC Load as output attachInterrupt(0, zero_cross_int, RISING); // Choose the zero cross interrupt # from the table above sensors.begin(); // Warning! zero_cross_int with sensors changes internal time, // so digital 1000ms ~ physical 7100ms on Arduino Uno checkTempThread.onRun(checkTemp); checkTempThread.setInterval(8450); // Interval for checking temperature ~60sec changeDimmerThread.onRun(changeDimmer); changeDimmerThread.setInterval(2800); // Interval for change dimmer state ~20sec checkTemp(); } // zero_cross_int function from http://electronics.stackexchange.com/q/59615 // the interrupt function must take no parameters and return nothing void zero_cross_int() { // function to be fired at the zero crossing to dim the light // Firing angle calculation : 1 full 50Hz wave =1/50=20ms // Every zerocrossing thus: (50Hz)-> 10ms (1/2 Cycle) // For 60Hz => 8.33ms (10.000/120) // 10ms=10000us // (10000us - 10us) / 128 = 75 (Approx) For 60Hz =>65 int dimtime = (75*dimming); // For 60Hz =>65 delayMicroseconds(dimtime); // Wait till firing the TRIAC digitalWrite(dimmerpin, HIGH); // Fire the TRIAC delayMicroseconds(10); // triac On propogation delay (for 60Hz use 8.33) digitalWrite(dimmerpin, LOW); // No longer trigger the TRIAC (the next zero crossing will swith it off) TRIAC } void loop() { digitalWrite(LED_BUILTIN, LOW); // Threads init: if (checkTempThread.shouldRun()) checkTempThread.run(); if (changeDimmerThread.shouldRun()) changeDimmerThread.run(); } void checkTemp() { sensors.requestTemperatures(); currenttemp = int(sensors.getTempCByIndex(0)); if (serialshow) { long currentTime = millis(); String tempString = currentTime + String(" temp: ")+ currenttemp; Serial.println(tempString); } } void changeDimmer() { if (currenttemp != -127) { if (currenttemp <= mintemp) if (dimming > 4) dimming = dimming - 1; if (currenttemp > maxtemp) if (dimming < 128) dimming = dimming + 1; if ((mintemp < currenttemp) and (currenttemp <= maxtemp)) { int dimlevel = (124 / (maxtemp - mintemp)) * (currenttemp - mintemp); if (dimming < dimlevel) dimming = dimming + 1; if (dimming > dimlevel) dimming = dimming - 1; } } else { if (dimming < 128) dimming = dimming + 1; if (serialshow) { long currentTime = millis(); String tempString = currentTime + String(" can't get temp data"); Serial.println(tempString); } // LED blinking is indication of temperature sensor failure for (int i=1; i <= 10; i++) { digitalWrite(LED_BUILTIN, HIGH); delay(10); digitalWrite(LED_BUILTIN, LOW); delay(20); } } }