Last active
December 29, 2020 17:14
-
-
Save tayeke/4c738b7cce680a427c77275184575f3a to your computer and use it in GitHub Desktop.
Fish Tank Monitoring Arduino App
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Arduino.h" | |
#include "ph_probe.h" | |
#include "EEPROM.h" | |
Ph_Probe::Ph_Probe(int pin, int calibrationAddress){ | |
this->pin = pin; | |
this->calibrationAddress = calibrationAddress; | |
} | |
bool Ph_Probe::begin(){ | |
if(EEPROM.read(calibrationAddress) == this->magic_char){ | |
EEPROM.get(this->calibrationAddress,this->pH); | |
return true; | |
} | |
return false; | |
} | |
float Ph_Probe::read_voltage() { | |
float voltage_mV = 0; | |
for (int i = 0; i < this->volt_arr_len; ++i) { | |
voltage_mV += analogRead(this->pin) / 1024.0 * 5000.0; | |
} | |
voltage_mV /= volt_arr_len; | |
return voltage_mV; | |
} | |
float Ph_Probe::read_ph(float voltage_mV) { | |
if (voltage_mV > pH.mid_cal) { //high voltage = low ph | |
return 7.0 - 3.0 / (this->pH.low_cal - this->pH.mid_cal) * (voltage_mV - this->pH.mid_cal); | |
} else { | |
return 7.0 - 3.0 / (this->pH.mid_cal - this->pH.high_cal) * (voltage_mV - this->pH.mid_cal); | |
} | |
} | |
float Ph_Probe::read_ph() { | |
return(read_ph(read_voltage())); | |
} | |
void Ph_Probe::set_mid_calibration(float voltage_mV) { | |
this->pH.mid_cal = voltage_mV; | |
EEPROM.put(this->calibrationAddress,pH); | |
} | |
void Ph_Probe::set_mid_calibration() { | |
set_mid_calibration(read_voltage()); | |
} | |
void Ph_Probe::set_low_calibration(float voltage_mV) { | |
this->pH.low_cal = voltage_mV; | |
EEPROM.put(this->calibrationAddress,pH); | |
} | |
void Ph_Probe::set_low_calibration() { | |
set_low_calibration(read_voltage()); | |
} | |
void Ph_Probe::set_high_calibration(float voltage_mV) { | |
this->pH.high_cal = voltage_mV; | |
EEPROM.put(this->calibrationAddress,pH); | |
} | |
void Ph_Probe::set_high_calibration() { | |
set_high_calibration(read_voltage()); | |
} | |
void Ph_Probe::clear_calibration() { | |
this->pH.mid_cal = 1500; | |
this->pH.low_cal = 2030; | |
this->pH.high_cal = 975; | |
EEPROM.put(this->calibrationAddress,pH); | |
} | |
Ph_Probe::PH Ph_Probe::get_calibration() { | |
return this->pH; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef PH_PROBE_H | |
#define PH_PROBE_H | |
class Ph_Probe { | |
public: | |
Ph_Probe(int pin, int calibrationAddress); | |
bool begin(); | |
float read_voltage(); | |
float read_ph(float voltage_mV); | |
float read_ph(); | |
void set_mid_calibration(float voltage_mV); | |
void set_mid_calibration(); | |
void set_low_calibration(float voltage_mV); | |
void set_low_calibration(); | |
void set_high_calibration(float voltage_mV); | |
void set_high_calibration(); | |
void clear_calibration(); | |
struct PH { | |
const int magic = magic_char; | |
float mid_cal = 1500; | |
float low_cal = 2030; | |
float high_cal = 975; | |
}; | |
PH get_calibration(); | |
private: | |
int pin = 0; | |
int calibrationAddress = 0; | |
static const int volt_arr_len = 10; | |
static const int magic_char = 0xAA; | |
struct PH pH; | |
}; | |
#endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SPI.h> | |
#include <WiFiNINA.h> | |
#include <OneWire.h> | |
#include <DallasTemperature.h> | |
#include "secrets.h" | |
#include <EEPROM.h> | |
#include "ph_probe.h" | |
// wire locations | |
#define ONE_WIRE_BUS 4 | |
#define PH_PROBE_BUS_ANALOG 0 | |
// memory locations | |
#define WIFI_STATUS_ADDRESS 0 | |
#define PH_PROBE_CALIBRATION_ADDRESS 1 | |
OneWire oneWire(ONE_WIRE_BUS); | |
DallasTemperature sensors(&oneWire); | |
Ph_Probe pH(PH_PROBE_BUS_ANALOG, PH_PROBE_CALIBRATION_ADDRESS); | |
const char ssid[] = SECRET_SSID; | |
const char pass[] = SECRET_PASS; | |
const char basicAuthToken[] = BASIC_AUTH_TOKEN; | |
int status = WL_IDLE_STATUS; | |
const char appHost[] = "fish-tank-monitor.herokuapp.com"; | |
WiFiSSLClient client; | |
void setup() { | |
Serial.begin(9600); | |
connectToWifi(); | |
if (pH.begin()) { | |
// just manually setting my calibrations for record keeping | |
pH.set_low_calibration(1987.30); | |
pH.set_mid_calibration(1474.61); | |
pH.set_high_calibration(976.56); | |
Ph_Probe::PH ph_calibration = pH.get_calibration(); | |
Serial.println("PH Calibrations"); | |
Serial.print("LOW: "); | |
Serial.println(ph_calibration.low_cal); | |
Serial.print("MID: "); | |
Serial.println(ph_calibration.mid_cal); | |
Serial.print("HIGH: "); | |
Serial.println(ph_calibration.high_cal); | |
} else { | |
Serial.println("PH Probe needs calibration!"); | |
while(true); | |
} | |
Serial.end(); | |
} | |
void loop() { | |
Serial.begin(9600); | |
int randtest = random(10, 500); | |
updateTest(randtest); | |
sensors.requestTemperatures(); | |
float temp = sensors.getTempFByIndex(0); | |
updateTemp(temp); | |
float ph = pH.read_ph(); | |
updatePH(ph); | |
double minute = 60.0*1000.0; | |
double delayTime = 15.0*minute; | |
Serial.end(); | |
delay(delayTime); | |
} | |
void updateTest(int testValue) { | |
Serial.print("sending test value: "); | |
Serial.println(testValue); | |
String json = "{\"measure\": "; | |
json += testValue; | |
json += "}"; | |
postJson("/tests.json", json); | |
} | |
void updateTemp(float tempValue) { | |
Serial.print("sending temperature F: "); | |
Serial.println(tempValue); | |
String json = "{\"measure\": "; | |
json += tempValue; | |
json += "}"; | |
postJson("/temperatures.json", json); | |
} | |
void updatePH(float ph) { | |
Serial.print("sending PH: "); | |
Serial.println(ph); | |
String json = "{\"measure\": "; | |
json += ph; | |
json += "}"; | |
postJson("/ph.json", json); | |
} | |
void postJson(String path, String json) { | |
if (client.connect(appHost, 443)) { | |
// request | |
client.print("POST "); | |
client.print(path); | |
client.println(" HTTP/1.1"); | |
// headers | |
client.print("Host: "); | |
client.println(appHost); | |
client.print("Authorization: Basic "); | |
client.println(basicAuthToken); | |
client.println("Content-Type: application/json"); | |
client.println("Cache-Control: no-cache"); | |
client.print("Content-Length: "); | |
client.println(json.length()); | |
client.println("Accept: */*"); | |
client.println("Connection: close"); | |
// send body | |
client.println(); | |
client.println(json); | |
} else { | |
client.stop(); | |
delay(2000); | |
connectToWifi(); | |
} | |
} | |
void connectToWifi() { | |
// attempt to connect to WiFi network: | |
int previousStatus = EEPROM.read(WIFI_STATUS_ADDRESS); | |
Serial.print("Previous wifi connection status: "); | |
Serial.println(previousStatus); | |
status = WiFi.status(); | |
Serial.print("Current wifi connection status: "); | |
Serial.println(status); | |
while (status != WL_CONNECTED) { | |
Serial.print("Attempting to connect to SSID: "); | |
Serial.println(ssid); | |
status = WiFi.begin(ssid, pass); | |
EEPROM.update(WIFI_STATUS_ADDRESS, status); | |
delay(10000); | |
} | |
Serial.println("Connected to wifi"); | |
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"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment