/*
We need your help to stop forest fires and bake tasty cookies!
See `requirements.md` for how to help.
Then check `notes.md`.
NOTES:
-Switch that controls the oven door is a bit fincky. My guess is a pull up resistor or debouncing method may help.
-With more time I would implement a safeguard for when the reference voltage is not within 4.5-5V.
-Didn't have time to implement unit tests, but I had a couple ideas I would implement:
1. Testing to make sure when the door is closed/opened, the gas and ignition are properly handled.
2. Testing the temperature conversion function, and ensuring edge cases are dealt with properly if passed specific signals.
*/
#include "api.h"
bool door_opened; //True if oven door is open
bool above_ideal_temp; //True if above ideal temperature
uint32_t ignition_time; //Keeps track of how long igniter is on for
int ideal_temp = 180; //Ideal temperature oven should be at
int ignition_shutoff_delay = 5000; //Milliseconds used for turning off igniter (5 seconds)
void setup()
{
Serial.begin(115200);
setup_api();
Serial.println("Elf oven 2000 starting up.");
serial_printf("Days without fire incident: %i\n", 0);
ignition_time = get_millis(); //Starting time
}
void door_sensor_interrupt_handler(bool voltage_high)
{
//If pin 3 read as high, set door bool to indicate open
if (voltage_high)
{
door_opened = true;
}
//If pin 3 read as low, set door bool to indicate closed
else
{
door_opened = false;
}
}
//Printing the outputs
void print_outputs(uint16_t sensor_voltage, uint16_t sensor_voltage_ref, int temp)
{
serial_printf("Sensor Voltage: %i\n", sensor_voltage);
serial_printf("Voltage Ref: %i\n", sensor_voltage_ref);
serial_printf("Temperature: %iC\n", temp);
}
//Getting the temperature based on the voltages
int temperature_conversion(uint16_t sensor_voltage, uint16_t sensor_voltage_ref)
{
//Had to use some magic here to make this work without floats since arduino does not support them
uint32_t percentage = ((uint32_t)sensor_voltage*1000)/sensor_voltage_ref; //Scaling by 1000 since ints cant use decimals (0-1)
uint32_t temperature = (0.3875*percentage-48.75); //Using slope equation I calculated on paper (mx + b)
//In industry would not have the magic numbers
return temperature;
}
//Turns off the gas and ignition
void door_is_open()
{
serial_printf("Oven Door Open - Shutting off Gas/Ignition\n");
set_output(GAS_VALVE, false);
set_output(IGNITER, false);
ignition_time = get_millis();
}
void door_is_closed(int temp)
{
serial_printf("Oven Closed\n");
set_output(GAS_VALVE, temp < ideal_temp);
//If we have hit the ideal temperature
if (temp > ideal_temp)
{
above_ideal_temp = true;
serial_printf("Higher than Target Temperature - Shutting off Gas/Ignition\n");
}
else
{
above_ideal_temp = false;
}
//If igniter hasn't been on for 5 seconds
if (get_millis() < ignition_time + ignition_shutoff_delay)
{
set_output(IGNITER, !above_ideal_temp);
}
//If igniter has been on for more than 5 seconds, shut off
else
{
set_output(IGNITER, false);
if (above_ideal_temp)
{
ignition_time = get_millis(); //Added this to turn the ignition back on after returning to below ideal temp
}
}
}
void loop()
{
//Getting the outputs
uint16_t sensor_voltage = read_voltage(TEMPERATURE_SENSOR);
uint16_t sensor_voltage_ref = read_voltage(TEMPERATURE_SENSOR_REFERENCE);
if (sensor_voltage_ref < 4500)
{
}
int temp = temperature_conversion(sensor_voltage, sensor_voltage_ref);
print_outputs(sensor_voltage, sensor_voltage_ref, temp);
//If oven door is open
if (door_opened)
{
door_is_open();
}
//If oven door is closed
else
{
door_is_closed(temp);
}
delay(1000); // feel free to change. What would you use for an actual iteration period?
//In a real life scenario, I would make it around the average human reaction time. (Must check if door is open constantly)
}