/*
Software for FCL Mockup Controller, CAYNOVA AG, Dorfgasse 5, 4900 Langenthal
Software Name: FCL Mockup Controller R1.1 (based on R1.0)
Revision: 00
Datum: 29.11.2022
Status: development
programmed: Th. Hertig
Security Timer set to 5min
Controller: Arduino NanoR3 (ATmega328P)
Changelog:
00: initial code
*/
//Code:
//variables:
#define x 85 // high value venting (0-98)
#define u 255 // high value heating (0-255)
int sec_time = 5; // security timer (minutes)
//--------------------------------------------------------------
//constants, do not change
// input pins
const byte button_vent = 7; // button with led, function venting, pin to GND
const byte button_heat = 2; // button with led, function heating, pin to GND
const byte config1 = A4; // input for config byte check output1, analog value
const byte config2 = A5; // input for config byte check output1, analog value
const byte config3 = A6; // input for config byte check output1, analog value
const byte config4 = A7; // input for config byte check output1, analog value
// output pins
const byte pwm1 = 11; // pwm pin output 1
const byte pwm2 = 6; // pwm pin output 2
const byte pwm3 = 5; // pwm pin output 3
const byte pwm4 = 3; // pwm pin output 4
const byte pwmv = 9; // pwm pin venting
const byte vgreen = 8; // green status LED venting
const byte hgreen = 4; // green status LED heating
#define debounce_delay 20 // debounce time (ms)
//--------------------------------------------------------------
//program variables
bool button_vent_value;
bool button_vent_value_old;
bool button_heat_value;
bool button_heat_value_old;
bool timerh1; //timer state for heating
bool timerv1;
bool set1 = false; // states for output 1-4
bool set2 = false;
bool set3 = false;
bool set4 = false;
//timer state for venting
unsigned long timeh; //timer values
unsigned long timev;
uint8_t button_vent_count; // button counters for state machine
uint8_t button_heat_count;
const byte pin_PWM = 9;
int conf_val1 = 0; // analog values for configuration bits, for HMAT/AMD check on output 1-4
int conf_val2 = 0;
int conf_val3 = 0;
int conf_val4 = 0;
unsigned long secura = (sec_time * 60000); // security time calculation to minutes orig:(sec_time * 60 * 1000)
// register for 79Hz PWM
const unsigned int TOP = 99; //
unsigned int DutyCycle = 0; // 0% Pulsweite, OCR1A <= ICR1 !!!
//----END VARIABLE DEFINITION----------------------------------------
//----SETUP----------------------------------------------------------
void setup() { //sets pins as input/output
pinMode (button_vent, INPUT_PULLUP); //internal pullup resistor, switch to GND
pinMode (button_heat, INPUT_PULLUP); //internal pullup resistor, switch to GND
pinMode (config1, INPUT);
pinMode (config2, INPUT);
pinMode (config3, INPUT);
pinMode (config4, INPUT);
pinMode (pwm1, OUTPUT);
pinMode (pwm2, OUTPUT);
pinMode (pwm3, OUTPUT);
pinMode (pwm4, OUTPUT);
pinMode (hgreen, OUTPUT);
pinMode (vgreen, OUTPUT);
pinMode(pin_PWM, OUTPUT);
int randomSeed(analogRead(0));
set_Timer1();
set_pwm_DutyCycle (DutyCycle);
}
void loop()
{
conf_val1 = analogRead(config1);
conf_val2 = analogRead(config2);
conf_val3 = analogRead(config3);
conf_val4 = analogRead(config4);
if (conf_val1 < 10 ) {
analogWrite(pwm1, 255);
set1 = true;
}
else if (conf_val1 > 100 ) {
analogWrite(pwm1, 0);
set1 = false;
}
if (conf_val2 < 10 ) {
analogWrite(pwm2, 255);
set2 = true;
}
else if (conf_val2 > 100 ) {
analogWrite(pwm2, 0);
set2 = false;
}
if (conf_val3 < 10 ) {
analogWrite(pwm3, 255);
set3 = true;
}
else if (conf_val3 > 100 ) {
analogWrite(pwm3, 0);
set3 = false;
}
if (conf_val4 < 10 ) {
analogWrite(pwm4, 255);
set4 = true;
}
else if (conf_val4 > 100 ) {
analogWrite(pwm4, 0);
set4 = false;
}
//button venting check
static uint32_t debounce_time;
if (millis() - debounce_time > debounce_delay)
{ button_vent_value = digitalRead(button_vent);
if (button_vent_value != button_vent_value_old)
{ debounce_time = millis();
button_vent_value_old = button_vent_value;
if (!button_vent_value)
{ button_vent_count++;
if (button_vent_count > 1) button_vent_count = 0;
}
}
}
if (button_vent_count == 0) {
venting_off();
}
if (button_vent_count == 1) {
venting_high();
heating_off();
}
if (millis() - debounce_time > debounce_delay) //button heating check
{ button_heat_value = digitalRead(button_heat);
if (button_heat_value != button_heat_value_old)
{ debounce_time = millis();
button_heat_value_old = button_heat_value;
if (!button_heat_value)
{ button_heat_count++;
if (button_heat_count > 1) button_heat_count = 0;
}
}
}
if (button_heat_count == 0) {
heating_off();
}
if (button_heat_count == 1) {
heating_high();
venting_off();
}
Serial.println("conf_val1");
Serial.println(conf_val1);
Serial.println("conf_val2");
Serial.println(conf_val2);
Serial.println("conf_val3");
Serial.println(conf_val3);
Serial.println("conf_val4");
Serial.println(conf_val4);
Serial.println("pwm1");
Serial.println(pwm1);
Serial.println("pwm2");
Serial.println(pwm2);
Serial.println("pwm3");
Serial.println(pwm3);
Serial.println("pwm4");
Serial.println(pwm4);
Serial.println("DutyCycle");
Serial.println(DutyCycle);
delay(500);
}
void heating_off() //off, no color
{
analogWrite(pwm1, 0);
analogWrite(pwm2, 0);
analogWrite(pwm3, 0);
analogWrite(pwm4, 0);
digitalWrite(hgreen, LOW);
}
void heating_high() //
{
if (timerh1 == LOW) {
timerh1 = HIGH;
timeh = millis();
digitalWrite(hgreen, HIGH);
}
if (timerh1 == HIGH && set1 == false) {
analogWrite(pwm1, x);
}
if (timerh1 == HIGH && set2 == false) {
analogWrite(pwm2, x);
}
if (timerh1 == HIGH && set3 == false) {
analogWrite(pwm3, x);
}
if (timerh1 == HIGH && set4 == false) {
analogWrite(pwm4, x);
}
else {
if (millis() - timeh > secura) {
button_heat_count = 0;
timerh1 = LOW;
heating_off();
}
}
}
void venting_off() //off, no color
{
digitalWrite(vgreen, LOW);
set_pwm_DutyCycle (DutyCycle = 0);
timerv1 = LOW;
}
void venting_high() // color green
{
if (timerv1 == LOW) {
timerv1 = HIGH;
timev = millis();
set_pwm_DutyCycle (DutyCycle = x);
digitalWrite(vgreen, HIGH);
}
else {
if (millis() - timev > secura) {
button_vent_count = 0;
timerv1 = LOW;
venting_off();
}
}
}
void set_pwm_DutyCycle (unsigned int duty)
{
if (duty <= TOP) { // simple plausibility check
OCR1A = duty;
}
}
void set_Timer1()
{
cli(); // interrupts off
TCCR1B = 0; // Reset, stop Timer
TCCR1A = 0; // Reset
TCNT1 = 0; // Reset
TIMSK1 = 0; // Reset
ICR1 = TOP;
OCR1A = DutyCycle; // pulse width, OCR1A <= ICR1
TCCR1A = (1 << COM1A1);
TCCR1B = (1 << WGM13) | (1 << CS12) | (1 << CS10); // Prescaler 1024
sei(); // interrupts on
}