P.S. I am an electrical engineering student, coding is not my best ability but i can manage. Its a bit messy so go easy on me :) code is attached. thanks in advance.
- Code: Select all | TOGGLE FULL SIZE
#include <ArduinoJson.h>
#include <SPI.h>
#include <ArduinoHttpClient.h>
#include <Wire.h>
#include <DallasTemperature.h>
#include <OneWire.h>
#include "ThingSpeak.h"
#include "secrets.h"
//Wifinina is for SAMD boards such as nano 33 IoT
#include <WiFiNINA.h>
//uncomment this for esp32
//#include <WiFi.h>
#include <LiquidCrystal_I2C.h>
#include "RTClib.h"
#define ONE_WIRE_BUS 12
#define compressor_relay_pin 11
#define case_lights_relay_pin 10
//eventually i want to cycle the fan on 5 min off 5 min for energy saving
//#define fan_relay_pin 3
#define button_pin 2
RTC_DS3231 rtc;
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress sensor_1_address = { 0x28, 0xCD, 0x50, 0x45, 0x92, 0x6, 0x2, 0x4E };
//DeviceAddress sensor_2_address = { 0x28, 0x97, 0xCB, 0x79, 0x97, 0x0, 0x3, 0xF3 }; BAD SENSOR
LiquidCrystal_I2C lcd(0x27,20,4);
int port = 443;
char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;
int keyIndex = 0;
const char url[] = "io.adafruit.com/api/v2/mgenova79/feeds/autonomous-beer-fridge-temp";
String response;
int statusCode = 0;
char adafruit_username[] = IO_USERNAME;
char adafruit_key[] = IO_KEY;
int status = WL_IDLE_STATUS;
WiFiSSLClient wifi;
HttpClient client = HttpClient(wifi, url, port);
//***********************VARIABLES******************************************
unsigned long myChannelNumber = SECRET_CH_ID;
const char * myWriteAPIKey = SECRET_WRITE_APIKEY;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
unsigned long current_millis;
unsigned long previous_compressor_millis = 0;
unsigned long previous_email_millis = 0;
unsigned long previous_datalog_millis = 0;
unsigned long previous_alarm_millis = 0;
unsigned long rtc_interval = 30000;
unsigned long log_interval = 30000;
unsigned long compressor_interval = 30000;
unsigned long alarm_interval = 30000;
unsigned long email_interval = 1800000;
unsigned int alarm_counter = 0;
//thingspeak will take a float or integer, not a double. double will not compile
float discharge_air_temp = 0;
float return_air_temp = 0;
const int high_alarm_setpoint = 65;
const int low_alarm_setpoint = 20;
const int cut_in_temp = 45;
const int cut_out_temp = 25;
bool alarm_state = 0;
unsigned long previous_millis_rtc = 0;
int button_state;
int last_button_state = LOW;
unsigned long last_debounce_time = 0;
unsigned long debounce_delay = 50;
const unsigned int on_hour = 17;
const unsigned int on_min = 0;
const unsigned int off_hour = 23;
const unsigned int off_min = 0;
byte curr_hour;
byte curr_min;
bool manual_lights = false;
bool auto_lights = false;
//**************************************************************************
void init_wifi() {
// check for the WiFi module:
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("Communication with WiFi module failed!");
// don't continue
while (true);
}
String fv = WiFi.firmwareVersion();
if (fv < "1.0.0") {
Serial.println("Please upgrade the firmware");
}
// attempt to connect to WiFi network:
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
Serial.println("Connected to wifi");
}
void reconnect() {
if(WiFi.status() != WL_CONNECTED){
Serial.print("Attempting to connect to SSID: ");
Serial.println(SECRET_SSID);
while(WiFi.status() != WL_CONNECTED){
WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network
Serial.print(".");
delay(2000);
}
Serial.println("\nConnected.");
Serial.println(WiFi.localIP());
}
}
void print_wifi_status() {
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
lcd.setCursor(0,1);
lcd.print(WiFi.localIP());
delay(3000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("AutonomousBeerFridge"); // if you see this, net connection is ok
}
void get_rtc_time() {
if ( ( millis() - previous_millis_rtc) >= rtc_interval) {
DateTime now = rtc.now();
curr_hour = now.hour();
curr_min = now.minute();
Serial.println();
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(" (");
Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
Serial.print(") ");
Serial.print(curr_hour, DEC);
Serial.print(':');
Serial.print(curr_min, DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
previous_millis_rtc = millis();
if ( on_hour <= off_hour) {
if ( ( curr_hour >= on_hour ) && ( curr_min >= on_min )) {
auto_lights = 1;
}
if ( ( curr_hour >= off_hour ) && ( curr_min >= off_min )) {
auto_lights = 0;
}
}
if ( on_hour > off_hour) {
if ( ( curr_hour >= off_hour ) && ( curr_min >= off_min )) {
auto_lights = 0;
}
if ( ( curr_hour >= on_hour ) && ( curr_min >= on_min )) {
auto_lights = 1;
}
}
Serial.print( "manual light ststus: ");
Serial.print(manual_lights);
Serial.print( " auto light ststus: ");
Serial.print(auto_lights);
Serial.println();
if ( ( manual_lights == 1 ) || ( auto_lights == 1 ) ) {
digitalWrite(case_lights_relay_pin, HIGH);
}
else {
digitalWrite(case_lights_relay_pin, LOW );
}
}
}
void check_button_status() {
int reading = digitalRead(button_pin);
if (reading != last_button_state) {
last_debounce_time = millis();
}
if ( (millis() - last_debounce_time) > debounce_delay) {
if (reading != button_state) {
button_state = reading;
if (button_state == LOW) {
manual_lights = !manual_lights;
if (manual_lights == 1) {
Serial.print("manual lights on = ");
Serial.println(manual_lights);
}
else {
Serial.print("manual lights off = ");
Serial.println(manual_lights);
}
}
}
}
last_button_state = reading;
}
void log_temp_data_to_cloud() {
if ( current_millis - previous_datalog_millis >= log_interval) {
sensors.requestTemperatures();
discharge_air_temp = sensors.getTempF(sensor_1_address);
//return_air_temp = sensors.getTempF(sensor_2_address);
Serial.println(discharge_air_temp);
//Serial.println(return_air_temp);
// AIO http code
String values = "temp=" + String(discharge_air_temp);
client.beginRequest();
client.post("/api/v2/mgenova79/feeds/autonomous-beer-fridge-temp" + values);
client.sendHeader("X-AIO-Key", adafruit_key);
client.sendHeader("Content-Type", "application/json");
client.endRequest();
int statusCode = client.responseStatusCode();
String response = client.responseBody();
if (statusCode == 200 ) {
Serial.println("data uploaded successfully!");
}
else {
Serial.print("sorry, an error occured with status code: ");
Serial.println(statusCode);
Serial.print("response: ");
Serial.println(response);
}
// https://io.adafruit.com/api/v2/mgenova79/feeds/autonomous-beer-fridge-temp
// https://io.adafruit.com/mgenova79/feeds/autonomous-beer-fridge-temp
previous_datalog_millis = current_millis;
}
}
void cycle_compressor_relay() {
if (current_millis - previous_compressor_millis >= compressor_interval) {
if (discharge_air_temp > cut_in_temp){
digitalWrite(compressor_relay_pin, HIGH); //relay command on
lcd.setCursor(0,2);
lcd.print(" ");
lcd.setCursor(0,2);
lcd.print("Mode: Cooling");
Serial.println("Mode: Cooling");
}
if (discharge_air_temp < cut_out_temp){
digitalWrite(compressor_relay_pin, LOW); //relay command off
lcd.setCursor(0,2);
lcd.print(" ");
lcd.setCursor(0,2);
lcd.print("Mode: idle");
Serial.println("Mode: Idle");
}
previous_compressor_millis = current_millis;
}
}
void check_alarm_status() {
if (current_millis - previous_alarm_millis >= alarm_interval) {
if (discharge_air_temp >= high_alarm_setpoint || discharge_air_temp <= low_alarm_setpoint) {
alarm_state = 1;
Serial.print("in alarm state for ");
Serial.print( ( current_millis - alarm_counter )/1000);
Serial.println(" seconds");
lcd.setCursor(0,3);
lcd.print("ALARM !!");
}
else {
alarm_state = 0;
alarm_counter = current_millis;
lcd.setCursor(0,3);
lcd.print(" ");
}
previous_alarm_millis = current_millis;
}
if (current_millis - previous_email_millis >= email_interval && alarm_state == 1) {
//send email here, create a new function
Serial.println("Email Sent!");
previous_email_millis = current_millis;
}
}
void setup() {
delay(3000); // wait for console opening
Serial.begin(115200);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
lcd.init();
lcd.backlight();
lcd.clear();
sensors.begin();
init_wifi();
print_wifi_status();
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
if (rtc.lostPower()) {
Serial.println("RTC lost power, lets set the time!");
// following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
// rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}
pinMode(compressor_relay_pin, OUTPUT);
pinMode(case_lights_relay_pin, OUTPUT);
digitalWrite(compressor_relay_pin, LOW);
digitalWrite(case_lights_relay_pin, LOW);
pinMode(button_pin, INPUT_PULLUP);
digitalWrite(button_pin, HIGH);
ThingSpeak.begin(wifi);
}
void loop() {
if (WiFi.status() != WL_CONNECTED) {
reconnect();
print_wifi_status();
return;
}
current_millis = millis();
get_rtc_time();
check_button_status();
log_temp_data_to_cloud();
cycle_compressor_relay();
check_alarm_status();
}