var triac;
var htu;
var temp;
var averageTemp;
var humidity;
var compHumidity;
var targetTemp;
var tempHistory = Float32Array(60);
function onInit () {
I2C2.setup( {scl: B10, sda: B3, bitrate: 19200 } );
htu = require('HTU21D').connect( I2C2 );
// Before anything else we should turn off the triac
triac=A8;
digitalWrite(triac,0); //this shoud reset the pin and set it as output
temp = (htu.readTemperature()+htu.readTemperature()+htu.readTemperature())/3;
//at power-on we assume the temperature was constant for the entire measurement history
tempHistory.fill(temp);
averageTemp = temp;
//turn HTU21D heater on for two seconds just to make sure the HTU21D sensor
//has no condensation
htu.setHeaterOn( true );
setTimeout('htu.setHeaterOn(false);', 2000);
targetTemp = 8.00;
}
function pidControlLoop() {
temp = (htu.readTemperature()+htu.readTemperature()+htu.readTemperature())/3;
humidity = htu.readHumidity();
compHumdity = htu.getCompensatedHumidity( humidity, temp );
var regulatedTemp = targetTemp;
//we want to check that moving towards regulated temp does not produce
//condensation. Furthermore, if the current temp is close or bellow
//dew point we wish to move to slightly higher temp
var dewPointTemp=htu.getDewPoint(temp,compHumdity);
if (((targetTemp-dewPointTemp) < 1) || ((temp - dewPointTemp) < 1)) {
regulatedTemp=dewPointTemp + 1;
}
//same, we want to check that the oldest temperature measured was above the dew point temperature
//this is needed to avoid condensation due to thermal inertia for glass or metal objects
//we better move slowly to higher temperature if such.
if ((tempHistory[59] - dewPointTemp) < 1) {
regulatedTemp = tempHistory[59] + 1;
}
// here we apply the proportional-integrative-derivative control
var PIDresult =0.75 * (regulatedTemp-temp + 2 * (regulatedTemp-averageTemp) + 2 * (tempHistory[0]-temp));
calculatedPWM = E.clip (PIDresult, 0, 1);
analogWrite(triac, calculatedPWM, { freq : 0.2 });
//Prepare for the next loop
averageTemp = averageTemp - (tempHistory[59] - temp)/60;
for (i=59;i>0;i--) {
tempHistory[i] = tempHistory[i-1];
}
tempHistory[0] = temp;
}
//power on initialization. Will be deleted if code saved in flash
onInit();
// hereby we set the control loop to 60 seconds
setInterval('pidControlLoop()',60000);
And few thoughts after the prototype build:
It is wiser to use a snuberless triac. It's even chipper and allows you to build the power control circuit without R4 and C1. That's good because you will want to keep the ac circuitry as simple as possible;
The triac needs a 6 cm x 4cm radiator. I trust the triac will not dissipate more than 10-15W, and due to the fact that it is triggered with the MOC3083 zero cross circuit, the heat is kept to a minimum. But since it is powered directly to the ac mains circuitry it's good to avoid any overheating, plastic melting or even worse - fire. After all the load is over 10A at 220V ac;
The regulation precision is 0,15°C with the suited PID parameters but may easily move to +/- 1°C when the PID parameters are not adequate.
No humans, animals or Espruino pico boards were hurt during this experiment, do not attempt to build this project if you are not familiar working with mains electricity and power electronics.
Espruino is a JavaScript interpreter for low-power Microcontrollers. This site is both a support community for Espruino and a place to share what you are working on.
Updated code after extensive testing:
And few thoughts after the prototype build:
The regulation precision is 0,15°C with the suited PID parameters but may easily move to +/- 1°C when the PID parameters are not adequate.
No humans, animals or Espruino pico boards were hurt during this experiment, do not attempt to build this project if you are not familiar working with mains electricity and power electronics.