#include <Wire.h>
#include <EEPROM.h>
#define PROBE_IN A3 //57 // anlaog a3 - green wire
#define PROBE_REF A2 //56 // anlaog a2 - white wire
byte i2cAdd = 99; // eeprom 1
double pH;
byte in_char = 0;
char inData[15];
byte w = 0; //counter used for ph_data array.
byte q = 0; //counter used for ph_data array.
char computerdata[31]; //we make a 31 byte character array to hold incoming data
char phData[31]; //we make a 31 byte character array to hold incoming data
byte flashLED = 0;
unsigned long previousMillis = 0;
void setup()
{
byte z = 255;
z = EEPROM.read(50);
if (z != 1)
{
defaults(); // Defaults
}
pinMode(1, OUTPUT);
flashLED = 1;
i2cAdd = EEPROM.read(1);
readDefaults();
measuremV();
Wire.begin(i2cAdd);
Wire.onReceive(receiveEvent);
Wire.onRequest(requestEvent);
}
void loop()
{
if (flashLED == 1)
{
for(byte i=0; i < 4; i++)
{
digitalWrite(1, LOW); // LED on circuit board
delay(200);
digitalWrite(1, HIGH); // LED on circuit board
delay(200);
}
flashLED = 0;
}
if ((millis() - previousMillis) >= 3000)
{
measuremV();
previousMillis = millis();
}
}
byte buttonPressCount = 0;
void measuremV()
{
double differentialmV;
float probeIn, probeRef, inputV;
int buttonReset = readADC(PROBE_REF);
if (buttonReset > 1000)
{
buttonPressCount++;
if (buttonPressCount == 1) {defaults();}
}
else {buttonPressCount = 0;}
analogReference(INTERNAL); // set to INTERNAL for ATtiny
// take a reading
probeIn = ((readADC(PROBE_IN) * 1.1) / 1024.0);
probeRef = ((readADC(PROBE_REF) * 1.1) / 1024.0);
// calculate mV
differentialmV = (probeIn - probeRef) * 1000;
float temp_mvPerPH = 59.16; // calibrated mV per pH with temperature compensation
float mVPerPH = 59.16;; // calibrated mV per pH without temperature compensation
// temp_mvPerPH = mVPerPH * (tempC+273.15) / ((tempCalibrated)+273.15);
// convert to pH
pH = fabs(7.0 - (differentialmV / temp_mvPerPH));
dtostrf(pH, 0, 3, phData); // convert float to char array so it can be sent over I2C
}
void receiveEvent()
{
while (Wire.available()) { // are there bytes to receive.
in_char = Wire.read(); // receive a byte.
inData[w] = in_char; // load this byte into our array.
if (q > 0)
{
computerdata[q-1] = inData[w];
q += 1;
}
if (inData[w] == ',') {q = 1;}
w += 1; // incur the counter for the array element.
if (in_char == 0) { // if we see that we have been sent a null command.
w = 0; // reset the counter w to 0.
q = 0; // reset the counter q to 0.
digitalWrite(1, LOW); // LED on circuit board
break; // exit the while loop.
}
}
}
void requestEvent()
{
if ((inData[0] == 'R')) // send pH
{
memset(inData,0,sizeof(inData));
Wire.write(1); // send byte 1
Wire.write(phData,30);
digitalWrite(1, HIGH);
}
else if ((inData[0] == 'A')) // change I2C address
{
byte a = 0;
a = atoi(computerdata);
if ((a > 0) && (a < 128)) // verify address is valid
{
flashLED = 1;
i2cAdd = a; // change address
EEPROM.write(1, i2cAdd); // I2C address - 40, 41, 42, 43, 44, 45, 46, 47
}
memset(inData,0,sizeof(inData));
digitalWrite(1, HIGH); // LED on circuit board
}
else if (inData[0] == 'D') // set defaults
{
defaults();
memset(inData,0,sizeof(inData));
Wire.write(1);
// Wire.write("ok",30);
digitalWrite(1, HIGH);
}
else
{
memset(inData,0,sizeof(inData));
digitalWrite(1, HIGH); // LED on circuit board
}
}
void defaults()
{
flashLED = 1;
// Defaults
EEPROM.write(1, 99); // I2C address - 40, 41, 42, 43, 44, 45, 46, 47
delay(200);
// read defaults
readDefaults();
}
void readDefaults()
{
// read defaults
i2cAdd = EEPROM.read(1);
}
double readADC(int channel)
{
uint32_t total = 0UL;
uint16_t sampleCount = 4096; // 2048
for (uint16_t i = 0; i < sampleCount; i++) {total += analogRead(channel);}
total = total >> 6;
double proportional = (total * 1.0) / (0b00000001 << 6);
return proportional;
}