/*
We need your help to stop forest fires and bake tasty cookies!
See `requirements.md` for how to help.
Then check `notes.md`.
*/
#include "api.h"
static boolean retrigger_igniter = true;//represents if the igniter is need to re-trigger
static int time_igniter_on = 0;//count how long have been passed since the igniter turn on
void setup() {
Serial.begin(115200);
setup_api();
Serial.println("Elf oven 2000 starting up.");
serial_printf("Days without fire incident: %i\n", 0);
//Unit test:
//test function: is_safe_temperature(float temp)
float test_min_temperature = -10.0;
float test_max_temperature = 180.0;
float random = ((float) rand()) / (float) RAND_MAX;
float test_in_range_temperature = random * 190 - 10.0;
float test_below_min_temperature = -10.00001;//Assumption: temperature < -10,
float test_above_max_temperature = 180.00001;
boolean test1_result = is_safe_temperature(test_min_temperature);
if(test1_result){Serial.println("is_safe_temperature()function works well @ -10 Celsius");}
test1_result = is_safe_temperature(test_max_temperature);
if(test1_result){Serial.println("is_safe_temperature()function works well @ 180 Celsius");}
test1_result = is_safe_temperature(test_in_range_temperature);
if(test1_result){Serial.println("is_safe_temperature()function works well @ in-range temperature");}
test1_result = is_safe_temperature(test_below_min_temperature);
if(!test1_result){Serial.println("is_safe_temperature()function works well @ -10.00001 Celsius");}
test1_result = is_safe_temperature(test_above_max_temperature);
if(!test1_result){Serial.println("is_safe_temperature()function works well @ 180.00001 Celsius");}
}
void loop() {
//Read sensor voltage and sensor vref voltage
uint16_t sensor_voltage = read_voltage(TEMPERATURE_SENSOR);
uint16_t sensor_voltage_ref = read_voltage(TEMPERATURE_SENSOR_REFERENCE);
sensor_voltage_ref = get_vref(sensor_voltage_ref);
//calculation temperature and print measurement
float temperature = get_temperature(sensor_voltage, sensor_voltage_ref);
print_measurements( sensor_voltage, sensor_voltage_ref, temperature);
//check if oven is working under safe temperature, decide to turn on or turn off
boolean at_safe_temper = is_safe_temperature(temperature);
if(!at_safe_temper){
turn_off_oven();
}else if(at_safe_temper && (!is_open_door())){
turn_on_oven();
}
//Check and automatically turn off igniter, once it turn on more than 5 seconds
auto_off_igniter();
delay(1000); // TODO: reduce time of the delay, let oven react faster
}
/*------Function to turn on oven---------------------------------------------------------*/
void turn_on_oven(){
if(retrigger_igniter == true) set_output(IGNITER, HIGH);
set_output(GAS_VALVE, HIGH);
}
/*------Function to turn off oven--------------------------------------------------------*/
void turn_off_oven(){
set_output(IGNITER, LOW);
set_output(GAS_VALVE, LOW);
}
/*------Function to check if temperature is safe(< 180 Celsius)--------------------------*/
bool is_safe_temperature(float temp){
if(int(ceil(temp)) > 180) return false;
if(int(floor(temp))< -10) return false;
return true;
}
/*------Function: Interrupt handler,handle the situation for DOOR open/off---------------*/
void door_sensor_interrupt_handler(bool voltage_high)
{
retrigger_igniter = true;
time_igniter_on = 0;
if(!is_open_door()){
turn_on_oven();
}
if(is_open_door()){
turn_off_oven();
}
}
/*------Function: to calculate actual reference voltage---------------*/
int get_vref(int sensor_vol_ref){
//Assumption: 0V vref input represents 4.5V, 5V vref represents 5.5V
int vref = 4500 + (sensor_vol_ref/5);
return vref;
}
//Caculate the temperature by voltage and reference voltage
float get_temperature(int sensor_vol, int sensor_vol_ref){
float dif = (float(sensor_vol) / float(sensor_vol_ref));
//TODO: Remove magic numbers here
float temp = -10.0 + 3.875*(dif-0.1)*100.0;
return temp;
}
/*-------------Function to print Measurements-----------------------------------------------/
1.oven temperature sensor `vref` voltage
2.oven temperature sensor signal voltage
3. oven temperature in degrees Celsius
*/
void print_measurements(int sensor_vol, int sensor_vol_ref, float temp){
serial_printf("sensor voltage = %i mV\n", sensor_vol);
serial_printf("reference voltage = %i mV\n", sensor_vol_ref);
//Print temperature
if(floor(temp) < -10 || ceil(temp) > 300){
Serial.print("temperature = ??????\n");
}else{
//Assumption: Temperature print in int format
serial_printf("temperature = %i Celsius\n", (ceil(temp) > 0)?int(ceil(temp)):int(floor(temp)));
/*Print accurate termerature
Serial.print("temperature = ");
Serial.print(temp);
serial_printf(" Celsius\n");
*/
}
}
/*------------Function: count 5 seconds, than turn off the igniter---------*/
void auto_off_igniter(){
serial_printf("time@igniter turn on = %i sec\n", time_igniter_on);
if (digitalRead(OUT_IGNITER) == HIGH){
time_igniter_on = time_igniter_on + 1;
if(time_igniter_on == 5){
time_igniter_on = 0;
set_output(IGNITER, LOW);
retrigger_igniter = false;
}
if (digitalRead(OUT_IGNITER) == LOW){
time_igniter_on = 0;
}
}
}