Thanks guys. Sorry I stepped over some of the finer details, wasn't entirely sure what other info would be needed and was strapped for time at the moment. Will give as much info as possible and almost full code will be attached in this post (the important parts).
@ floresta:
1 - the lcd-arduino connections are as follows:
V0 - trimpot (for contrast); RS - dpin 7; E - dpin 6
D4 - dpin 5; D5 - dpin 4; D6 - dpin 3; D7 - dpin 2
2 - processData() at the moment is being called every single loop (it will have a time condition, ie to only be called every 10 seconds or so, but it hasn't been implemented yet), under no other condition than simply being called inside the loop, every single cycle.
3 - I cleared the display because I thought it was inocuous enough, and standard procedure before writing something. And was worried that when changing from, for example, 10.05 to 9.90 (5 chars vs 4 chars), the last digit would still show up (ie 9.905).
4 - I'm calling lcd.begin(16,4) at the setup, however I was still having an offset when trying to change lines, hence why I had to cobble up those offsets. Maybe I'm missing something here, as I'm pretty sure this shouldn't be needed.
-
As I said earlier, buttons are on dpins 8, 9, 12, 13.
-
Using Arduino Uno and Arduino 0022 IDE.
Alright, code!
#include <LiquidCrystal.h>
#include <SPI.h>
#include <Ethernet.h>
#include <stdio.h>
#include <string.h>
#include "float2string.h"
#define GAIN 10
#define VREF 2.366
#define PHSENSOR 0 //apin 0
#define TEMPSENSOR 1 //apin 1
#define GAS_CONSTANT_R 8.31451
#define FARADAY_CONSTANT_F 96485
#define NERNST 59.16
#define SAMPLES 200
//DIGITAL IN/OUT PINS FOR BUTTONS
int OK = 13;
int Calib = 12;
int Up = 9;
int Down = 8;
//VARIABLES
float setPoint = 7.00; //set point pH, 7.00 Default
float interval_SP = 0.05; //resolution interval for pH SetPoint, on button presses
int buttonState0 = 0; //Calib button state
int buttonState1 = 0; //Up button state
int buttonState2 = 0; //Down button state
int buttonState3 = 0; //OK button state
float temp_mv = 0; //mV sensed by temperature sensor
float ph_mv = 0; //mV sensed by pH sensor, x10 hardware gain
float ph_calib7 = 0; //calibration offset (zero) on buffer solution ph7
float ph_calib4 = 1; //calibration offset (gain) on buffer solution ph4
float T = 0; //temperature value
float E = 0; //electrolitic potential
float PH = 0; //real pH, considering calib7, calib4 and temperature compensation
char temp_str[6]; //temperature in string, to display in lcd
char ph_str[6]; //pH in string
char sp_str[6]; //setPoint in string
int comm_status = 0; //state of ethernet link
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x6F, 0x2C };
byte ip[] = { 10, 0, 0, 177 };
byte server[] = { 173, 203, 98, 29 }; // www.pachube.com
byte gateway[] = { 10, 0, 0, 1 };
byte mask[] = { 255, 255, 255, 0 }; //subnet
int port = 80;
Client client(server, port);
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
void setup()
{
lcd.begin(16, 4);
pinMode (OK, INPUT);
pinMode (Calib, INPUT);
pinMode (Up, INPUT);
pinMode (Down, INPUT);
Ethernet.begin(mac, ip, gateway, mask);
Serial.begin(9600);
delay(1000);
}
unsigned int readADC(unsigned char channel) {
double d = 0;
int i = 0;
for (i = 0; i < SAMPLES; i++)
{
d = d + analogRead(channel);
}
d = d / i;
return (unsigned int)(d);
}
void processData(void)
{
ph_mv = readADC(PHSENSOR);
temp_mv = readADC(TEMPSENSOR);
T = (100 * temp_mv * 5.0 / 1024);
E = (((ph_mv - ph_calib7) * 5.0 / 1024) - VREF) / (GAIN * ph_calib4);
PH= ((-1 * FARADAY_CONSTANT_F * E) / (2.303 * GAS_CONSTANT_R * (273.15 + T))) + 7.0;
floatToString(temp_str, T, 1);
floatToString(ph_str, PH, 2);
floatToString(sp_str, setPoint, 2);
lcd.clear();
lcd.setCursor (0,0);
lcd.print("T=");
lcd.print(temp_str);
lcd.print((char)223); // degree symbol
lcd.print("C");
lcd.setCursor (0,1);
lcd.print("SetPoint=");
lcd.print(sp_str);
lcd.setCursor (-4,2);
lcd.print("pH=");
lcd.print(ph_str);
lcd.setCursor (-4,3);
if (comm_status == 0) {lcd.print("Com:off");}
if (comm_status == 1) {lcd.print("Com:on");}
lcd.setCursor (5,3);
if (valve_status == 0) {lcd.print("Vlv:off");}
if (valve_status == 1) {lcd.print("Vlv:on");}
}
float calibrate_ph7() //calibration routine for pH 7 buffer solution
{
lcd.clear();
lcd.print("Calibration pH7:");
buttonState3 = digitalRead(OK);
if (buttonState3 == HIGH)
{
if (ph_mv != 0)
{
ph_calib7 = ph_mv;
}
else
{
ph_calib7 = 0;
}
lcd.clear();
lcd.setCursor(1,1);
lcd.print("Calibrated pH7!");
delay(2500);
lcd.clear();
digitalWrite (Calib, LOW);
buttonState0 = 0;
digitalWrite (OK, LOW);
buttonState3 = 0;
}
else
{
delay(200); //reduces lcd flicker
calibracao_ph7(); //recursive until OK button press
}
}
float calibrate_ph4() //calibration routine for pH 4 buffer solution
{
float difference = 0;
float new_gain = 0;
lcd.clear();
lcd.print("Calibration pH4:");
buttonState3 = digitalRead(OK);
if (buttonState3 == HIGH)
{
if (ph_mv != ((NERNST * 3) * GAIN) + (VREF - ph_calib7))
{
difference = ((NERNST * 3) * GAIN) + (VREF - ph_calib7) - ph_mv;
new_gain = (((((NERNST * 3) * GAIN) + (VREF - ph_calib7)) - difference) * GAIN) / (((NERNST * 3) * GAIN) + (VREF - ph_calib7));
ph_calib4 = new_gain / GAIN;
}
else
{
ph_calib4 = 1;
}
lcd.clear();
lcd.setCursor(1,1);
lcd.print("Calibrated pH4!");
delay(2500);
lcd.clear();
digitalWrite (Calib, LOW);
buttonState0 = 0;
digitalWrite (OK, LOW);
buttonState3 = 0;
}
else
{
delay(200); //reduces lcd flicker
calibrate_ph4(); //recursive until OK button is pressed
}
}
void loop(void)
{
if (client.connected() == 0)
{
comm_status = 0;
client.connect();
}
else
{
comm_status = 1;
}
processData();
buttonState0 = digitalRead(Calib);
buttonState1 = digitalRead(Up);
buttonState2 = digitalRead(Down);
if (buttonState0 == HIGH) //starts calibration routine
{
calibrate_ph7();
calibrate_ph4();
}
if (buttonState1 == HIGH) //increases setpoint
{
setPoint = setPoint + interval_SP;
delay(200);
}
if (buttonState2 == HIGH) //decreases setpoint
{
setPoint = setPoint - interval_SP;
delay(200);
}
}
I think that pretty much covers it all. If I did miss something important again, I'll supply the info if you let me know.
Thank you so much!