Skip to content

Instantly share code, notes, and snippets.

@tayeke
Last active December 29, 2020 17:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tayeke/4c738b7cce680a427c77275184575f3a to your computer and use it in GitHub Desktop.
Save tayeke/4c738b7cce680a427c77275184575f3a to your computer and use it in GitHub Desktop.
Fish Tank Monitoring Arduino App
#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;
}
#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
#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