temperaturedimmer/temperaturedimmer.ino

105 lines
4.4 KiB
C++

// 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 <OneWire.h>
#include <DallasTemperature.h>
#include <Thread.h>
#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);
}
}
}