
Library for the EZO ph probe communicating with the I2C protocol.
Revision 0:1e392c8ebfcd, committed 2017-03-06
- Comitter:
- gaul2411
- Date:
- Mon Mar 06 19:03:29 2017 +0000
- Commit message:
- Library for the EZO ph probe communication with the I2C protocol
Changed in this revision
diff -r 000000000000 -r 1e392c8ebfcd EZOPH/EZOPH.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EZOPH/EZOPH.cpp Mon Mar 06 19:03:29 2017 +0000 @@ -0,0 +1,631 @@ +/** + * Ezo ph sensor library + * + * @author Louis-Philippe Gauthier + * @version 1.0 + * @date 03-March-2017 + * + * Library for "EZO PH sensor module" from Atlas Scientific + * http://www.atlas-scientific.com/product_pages/circuits/ezo_ph.html + * + * For more information about the EZO: + * http://www.atlas-scientific.com/_files/_datasheets/_circuit/pH_EZO_datasheet.pdf? + */ + +#include "mbed.h" +#include "EZOPH.h" + +EZOPH::EZOPH(PinName sda, PinName scl, char slave_adr) + : + i2c_p(new I2C(sda, scl)), + i2c(*i2c_p), + address(slave_adr) +{ + clear(); + i2c.frequency(100000); + error255 = "No Data"; + error254 = "Pending"; + failedStr = "Failed"; + succesStr = "Success"; + failed = 2; + success = 1; +} + +EZOPH::~EZOPH() +{ + if (NULL != i2c_p) + delete i2c_p; +} + +void EZOPH::clear(void) +{ + for (int i=0; i<sizeof(ezodata); i++) { + ezodata[i] = '0'; + } + for (int i=0; i<sizeof(cmdData); i++) { + cmdData[i] = '0'; + } + for (int i=0; i<sizeof(receivedValue); i++) { + receivedValue[i] = '0'; + } + ezovalue = "0"; +} + +int EZOPH::Tcompensation (float tmp) +{ + clear(); + int value = static_cast<int>(tmp); + char dig[3] = { NULL, NULL, NULL}; + int x = 0; + while (value > 0 && x < 3) { + dig[x] = value % 10; + value /= 10; + x++; + } + + cmdData[0] = 'T'; + cmdData[1] = ','; + cmdData[2] = dig[0]; + cmdData[3] = '.'; + cmdData[4] = dig[1]; + cmdData[5] = dig[2]; + + i2c.write(address, cmdData, 6, false); + wait(0.3); + + i2c.read(address, ezodata, 1, false); + + if( ezodata[0] == 1) { + return success; + } else { + return failed; + } +} + +float EZOPH::QTcompensation (void) +{ + clear(); + cmdData[0] = 'T'; + cmdData[1] = ','; + cmdData[3] = '?'; + + i2c.write(address, cmdData, 3, false); + wait(0.3); + + i2c.read(address, ezodata, 10, false); + + if(ezodata[0] == 1) { + receivedValue[0] = ezodata[4]; + receivedValue[1] = ezodata[5]; + receivedValue[2] = ezodata[6]; + receivedValue[3] = ezodata[7]; + float tmp = atof(receivedValue); + return tmp; + } else { + return 0.0; + } +} + +string EZOPH::getSensorInfo(void) +{ + clear(); + cmdData[0] = 'I'; + + i2c.write(address, cmdData, 1, false); + wait(0.3); + + i2c.read(address, ezodata, 21, false); + + if(ezodata[0] == 1) { + receivedValue[0] = ezodata[1]; + receivedValue[1] = ezodata[2]; + receivedValue[2] = ezodata[3]; + receivedValue[3] = ezodata[4]; + receivedValue[4] = ezodata[5]; + receivedValue[5] = ezodata[6]; + receivedValue[6] = ezodata[7]; + receivedValue[7] = ezodata[8]; + receivedValue[8] = ezodata[9]; + receivedValue[9] = ezodata[10]; + receivedValue[10] = ezodata[11]; + receivedValue[11] = ezodata[12]; + receivedValue[12] = ezodata[13]; + receivedValue[13] = ezodata[14]; + receivedValue[14] = ezodata[15]; + receivedValue[15] = ezodata[16]; + receivedValue[16] = ezodata[17]; + receivedValue[17] = ezodata[18]; + receivedValue[18] = ezodata[19]; + receivedValue[19] = ezodata[20]; + return receivedValue; + } else if(ezodata[0] == 254) { + return error254; + } else if(ezodata[0] == 255) { + return error255; + } else { + return failedStr; + } +} + +string EZOPH::getSensorStatus(void) +{ + clear(); + cmdData[0] = 'S'; + cmdData[1] = 'T'; + cmdData[2] = 'A'; + cmdData[3] = 'T'; + cmdData[4] = 'U'; + cmdData[5] = 'S'; + + i2c.write(address, cmdData, 6, false); + wait(0.3); + + i2c.read(address, ezodata, 21, false); + + if(ezodata[0] == 1) { + receivedValue[0] = ezodata[1]; + receivedValue[1] = ezodata[2]; + receivedValue[2] = ezodata[3]; + receivedValue[3] = ezodata[4]; + receivedValue[4] = ezodata[5]; + receivedValue[5] = ezodata[6]; + receivedValue[6] = ezodata[7]; + receivedValue[7] = ezodata[8]; + receivedValue[8] = ezodata[9]; + receivedValue[9] = ezodata[10]; + receivedValue[10] = ezodata[11]; + receivedValue[11] = ezodata[12]; + receivedValue[12] = ezodata[13]; + receivedValue[13] = ezodata[14]; + receivedValue[14] = ezodata[15]; + receivedValue[15] = ezodata[16]; + receivedValue[16] = ezodata[17]; + receivedValue[17] = ezodata[18]; + receivedValue[18] = ezodata[19]; + receivedValue[19] = ezodata[20]; + return receivedValue; + } else if(ezodata[0] == 254) { + return error254; + } else if(ezodata[0] == 255) { + return error255; + } else { + return failedStr; + } +} + +float EZOPH::read(void) +{ + clear(); + cmdData[0] = 'R'; + + i2c.write(address, cmdData, 1, false); + wait(1); + + i2c.read(address, ezodata, 21, false); + + if(ezodata[0] == 1) { + receivedValue[0] = ezodata[1]; + receivedValue[1] = ezodata[2]; + receivedValue[2] = ezodata[3]; + receivedValue[3] = ezodata[4]; + receivedValue[4] = ezodata[5]; + receivedValue[5] = ezodata[6]; + receivedValue[6] = ezodata[7]; + receivedValue[7] = ezodata[8]; + receivedValue[8] = ezodata[9]; + receivedValue[9] = ezodata[10]; + receivedValue[10] = ezodata[11]; + receivedValue[11] = ezodata[12]; + receivedValue[12] = ezodata[13]; + receivedValue[13] = ezodata[14]; + receivedValue[14] = ezodata[15]; + receivedValue[15] = ezodata[16]; + receivedValue[16] = ezodata[17]; + receivedValue[17] = ezodata[18]; + receivedValue[18] = ezodata[19]; + receivedValue[19] = ezodata[20]; + float PhValue = atof(receivedValue); + return PhValue; + } else { + return 16.999; + } +} + +int EZOPH::sensorLED(bool on) +{ + clear(); + cmdData[0] = 'L'; + cmdData[1] = ','; + if(on) { + cmdData[2] = '1'; + } else { + cmdData[2] = '0'; + } + i2c.write(address, cmdData, 3, false); + wait(0.3); + + i2c.read(address, ezodata, 1, false); + if( ezodata[0] == 1) { + return success; + } else { + return failed; + } +} +int EZOPH::QsensorLED(void) +{ + clear(); + cmdData[0] = 'L'; + cmdData[1] = ','; + cmdData[2] = '?'; + + i2c.write(address, cmdData, 3, false); + wait(0.3); + + i2c.read(address, ezodata, 6, false); + + if(ezodata[0] == 1) { + if(ezodata[4] == '1') { + return 1; + } else if(ezodata[4] == '0') { + return 0; + } + } else { + return failed; + } +} + +int EZOPH::calibrationClear(void) +{ + clear(); + cmdData[0] = 'C'; + cmdData[1] = 'a'; + cmdData[2] = 'l'; + cmdData[3] = ','; + cmdData[4] = 'c'; + cmdData[5] = 'l'; + cmdData[6] = 'e'; + cmdData[7] = 'a'; + cmdData[8] = 'r'; + + i2c.write(address, cmdData, 9, false); + wait(0.3); + + i2c.read(address, ezodata, 1, false); + + if(ezodata[0] == 1) { + return success; + } else { + return failed; + } +} + +string EZOPH::calibrationQuery(void) +{ + clear(); + cmdData[0] = 'C'; + cmdData[1] = 'a'; + cmdData[2] = 'l'; + cmdData[3] = ','; + cmdData[4] = '?'; + + i2c.write(address, cmdData, 5, false); + wait(0.3); + + i2c.read(address, ezodata, 21, false); + + if(ezodata[0] == 1) { + receivedValue[0] = ezodata[1]; + receivedValue[1] = ezodata[2]; + receivedValue[2] = ezodata[3]; + receivedValue[3] = ezodata[4]; + receivedValue[4] = ezodata[5]; + receivedValue[5] = ezodata[6]; + receivedValue[6] = ezodata[7]; + receivedValue[7] = ezodata[8]; + receivedValue[8] = ezodata[9]; + receivedValue[9] = ezodata[10]; + receivedValue[10] = ezodata[11]; + receivedValue[11] = ezodata[12]; + receivedValue[12] = ezodata[13]; + receivedValue[13] = ezodata[14]; + receivedValue[14] = ezodata[15]; + receivedValue[15] = ezodata[16]; + receivedValue[16] = ezodata[17]; + receivedValue[17] = ezodata[18]; + receivedValue[18] = ezodata[19]; + receivedValue[19] = ezodata[20]; + return receivedValue; + } else if(ezodata[0] == 254) { + return error254; + } else if(ezodata[0] == 255) { + return error255; + } else { + return failedStr; + } +} + +int EZOPH::calibratingMid(void) +{ + clear(); + cmdData[0] = 'C'; + cmdData[1] = 'a'; + cmdData[2] = 'l'; + cmdData[3] = ','; + cmdData[4] = 'm'; + cmdData[5] = 'i'; + cmdData[6] = 'd'; + cmdData[7] = ','; + cmdData[8] = '7'; + cmdData[9] = '.'; + cmdData[10] = '0'; + cmdData[11] = '0'; + + i2c.write(address, cmdData, 12, false); + wait(1.6); + + i2c.read(address, ezodata, 21, false); + + if(ezodata[0] == 1) { + return success; + } else { + return failed; + } +} + +int EZOPH::calibratingLow(void) +{ + clear(); + cmdData[0] = 'C'; + cmdData[1] = 'a'; + cmdData[2] = 'l'; + cmdData[3] = ','; + cmdData[4] = 'l'; + cmdData[5] = 'o'; + cmdData[6] = 'w'; + cmdData[7] = ','; + cmdData[8] = '4'; + cmdData[9] = '.'; + cmdData[10] = '0'; + cmdData[11] = '0'; + + i2c.write(address, cmdData, 12, false); + wait(1.6); + + i2c.read(address, ezodata, 1, false); + + if(ezodata[0] == 1) { + return success; + } else { + return failed; + } +} + +int EZOPH::calibratingHigh(void) +{ + clear(); + cmdData[0] = 'C'; + cmdData[1] = 'a'; + cmdData[2] = 'l'; + cmdData[3] = ','; + cmdData[4] = 'h'; + cmdData[5] = 'i'; + cmdData[6] = 'g'; + cmdData[7] = 'h'; + cmdData[8] = ','; + cmdData[9] = '1'; + cmdData[10] = '0'; + cmdData[11] = '.'; + cmdData[12] = '0'; + cmdData[13] = '0'; + + i2c.write(address, cmdData, 14, false); + wait(1.6); + + i2c.read(address, ezodata, 21, false); + + if(ezodata[0] == 1) { + return success; + } else { + return failed; + } +} + +string EZOPH::slope(void) +{ + clear(); + cmdData[0] = 'S'; + cmdData[1] = 'l'; + cmdData[2] = 'o'; + cmdData[3] = 'p'; + cmdData[4] = 'e'; + cmdData[5] = ','; + cmdData[6] = '?'; + + i2c.write(address, cmdData, 7, false); + wait(0.3); + + i2c.read(address, ezodata, 21, false); + + if(ezodata[0] == 1) { + receivedValue[0] = ezodata[1]; + receivedValue[1] = ezodata[2]; + receivedValue[2] = ezodata[3]; + receivedValue[3] = ezodata[4]; + receivedValue[4] = ezodata[5]; + receivedValue[5] = ezodata[6]; + receivedValue[6] = ezodata[7]; + receivedValue[7] = ezodata[8]; + receivedValue[8] = ezodata[9]; + receivedValue[9] = ezodata[10]; + receivedValue[10] = ezodata[11]; + receivedValue[11] = ezodata[12]; + receivedValue[12] = ezodata[13]; + receivedValue[13] = ezodata[14]; + receivedValue[14] = ezodata[15]; + receivedValue[15] = ezodata[16]; + receivedValue[16] = ezodata[17]; + receivedValue[17] = ezodata[18]; + receivedValue[18] = ezodata[19]; + receivedValue[19] = ezodata[20]; + return receivedValue; + } else if(ezodata[0] == 254) { + return error254; + } else if(ezodata[0] == 255) { + return error255; + } else { + return failedStr; + } +} + +string EZOPH::factoryReset(void) +{ + clear(); + cmdData[0] = 'F'; + cmdData[1] = 'a'; + cmdData[2] = 'c'; + cmdData[3] = 't'; + cmdData[4] = 'o'; + cmdData[5] = 'r'; + cmdData[6] = 'y'; + + i2c.write(address, cmdData, 7, false); + wait(0.3); + + i2c.read(address, ezodata, 21, false); + + if(ezodata[0] == 1) { + receivedValue[0] = ezodata[1]; + receivedValue[1] = ezodata[2]; + receivedValue[2] = ezodata[3]; + receivedValue[3] = ezodata[4]; + receivedValue[4] = ezodata[5]; + receivedValue[5] = ezodata[6]; + receivedValue[6] = ezodata[7]; + receivedValue[7] = ezodata[8]; + receivedValue[8] = ezodata[9]; + receivedValue[9] = ezodata[10]; + receivedValue[10] = ezodata[11]; + receivedValue[11] = ezodata[12]; + receivedValue[12] = ezodata[13]; + receivedValue[13] = ezodata[14]; + receivedValue[14] = ezodata[15]; + receivedValue[15] = ezodata[16]; + receivedValue[16] = ezodata[17]; + receivedValue[17] = ezodata[18]; + receivedValue[18] = ezodata[19]; + receivedValue[19] = ezodata[20]; + return receivedValue; + } else if(ezodata[0] == 254) { + return error254; + } else if(ezodata[0] == 255) { + return error255; + } else { + return failedStr; + } +} + +void EZOPH::sleep(void) +{ + clear(); + + cmdData[0] = 'S'; + cmdData[1] = 'l'; + cmdData[2] = 'e'; + cmdData[3] = 'e'; + cmdData[4] = 'p'; + + i2c.write(address, cmdData, 5, false); + wait(0.3); + + // no response code +} + +int EZOPH::EDProtocolLock(bool on) +{ + clear(); + cmdData[0] = 'P'; + cmdData[1] = 'L'; + cmdData[2] = 'O'; + cmdData[3] = 'C'; + cmdData[4] = 'K'; + cmdData[5] = ','; + if(on) { + cmdData[6] = '1'; + } else { + cmdData[6] = '0'; + } + + i2c.write(address, cmdData, 7, false); + wait(0.3); + + i2c.read(address, ezodata, 1, false); + + if(ezodata[0] == 1) { + return success; + } else { + return failed; + } +} + +int EZOPH::QProtocolLock() +{ + clear(); + cmdData[0] = 'P'; + cmdData[1] = 'L'; + cmdData[2] = 'O'; + cmdData[3] = 'C'; + cmdData[4] = 'K'; + cmdData[5] = ','; + cmdData[6] = '?'; + + i2c.write(address, cmdData, 7, false); + wait(0.3); + + i2c.read(address, ezodata, 1, false); + + if(ezodata[0] == 1) { + return ezodata[8]; + } else { + return failed; + } +} + +void EZOPH::changeUART(int baudRate) +{ + clear(); + + char dig[6] = { NULL, NULL, NULL, NULL, NULL, NULL}; + int x = 0; + int value = baudRate; + int number = 10; + + while (value > 0 && x < 3) { + dig[x] = value % 10; + value /= 10; + x++; + } + cmdData[0] = 'S'; + cmdData[1] = 'E'; + cmdData[2] = 'R'; + cmdData[3] = 'I'; + cmdData[4] = 'A'; + cmdData[5] = 'L'; + cmdData[6] = ','; + cmdData[7] = dig[0]; + cmdData[8] = dig[1]; + cmdData[9] = dig[2]; + if (dig[3] != NULL) { + cmdData[10] = dig[3]; + number = 11; + } else if (dig[4] != NULL) { + cmdData[11] = dig[3]; + number = 12; + } else if (dig[5] != NULL) { + cmdData[12] = dig[3]; + number = 13; + } + + i2c.write(address, cmdData, number, false); + wait(0.3); + // No response code +}
diff -r 000000000000 -r 1e392c8ebfcd EZOPH/EZOPH.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EZOPH/EZOPH.h Mon Mar 06 19:03:29 2017 +0000 @@ -0,0 +1,207 @@ +/** + * Ezo ph sensor library + * + * @author Louis-Philippe Gauthier + * @version 1.0 + * @date 03-March-2017 + * + * Library for "EZO PH sensor module" from Atlas Scientific + * http://www.atlas-scientific.com/product_pages/circuits/ezo_ph.html + * + * For more information about the EZO: + * http://www.atlas-scientific.com/_files/_datasheets/_circuit/pH_EZO_datasheet.pdf? + */ + +#ifndef MBED_EZOPH_H +#define MBED_EZOPH_H + +#include "mbed.h" +#include <string> + +#define DEFAULT_SLAVE_ADDRESS (0x63 << 1) + + +/** EZO class + * + * EZO: A library to communicate with the Ezo PH sensor + * + * @endcode + */ + +class EZOPH +{ +public: + + /** Create a EZOPH instance + * which is connected to specified I2C pins with specified address + * + * @param sda I2C-bus SDA pin + * @param scl I2C-bus SCL pin + * @param slave_adr (option) I2C-bus address (default: 0x63) + */ + EZOPH(PinName sda, PinName sck, char slave_adr = DEFAULT_SLAVE_ADDRESS); + + /** Destructor of EZOPH + */ + virtual ~EZOPH(); + + /** clear cmd buffer and response buffer + * + */ + void clear(void); + + /** Set the temperature compensation value in DegC + * + */ + int Tcompensation (float tmp); + + /** Ask the compensation temperature of the EZOPH sensor + * + * return the compensation temperature in float with one decimal : + * 19.5 is the temperature in degC + * + */ + float QTcompensation (void); + + /** Ask EZOPH sensor information + * + * return a string containing the sensor information in the following template : + * ?I,ph,1.0 + * ph = device type + * 1.0 = firmware version number + * + */ + string getSensorInfo(void); + + /** Ask EZOPH sensor status (reason for last reset and value of VCC) + * + * return a string containing the sensor information in the following template : + * ?STATUS,P,5.038 + * P = reason for the last reset event + * P = power on reset + * S = software reset + * B = nrown out reset + * W = watchdog reset + * U = unknown + * 5.038 = voltage at VCC + */ + string getSensorStatus(void); + + + /** EZOPH sensor do a single reading + * + */ + float read(void); + + /** Enable or Disable the LED of the EZOPH sensor + * + * [in] 1 : Enable LED (default) + * [in] 0 : Disable LED + * + */ + int sensorLED(bool on); + + /** Query the LED state of the EZOPH sensor + * + */ + int QsensorLED(void); + + /** Clear the EZOPH sensor calibration + * + */ + int calibrationClear(void); + + + /** Ask the status of the EZOPH sensor calibration + * + * return a string in the following template : + * ?CAL,0 : not calibrated + * ?CAL,1 : single point calibration + * ?CAL,2 : two point calibration + * ?CAL,3 : three point calibration + */ + string calibrationQuery(void); + + + /** Calibrate the EZOPH sensor for a PH of 7.00 + * + */ + int calibratingMid(void); + + + /** Calibrate the EZOPH sensor for a PH of 4.00 + * + */ + int calibratingLow(void); + + + /** Calibrate the EZOPH sensor for a PH of 10.00 + * + */ + int calibratingHigh(void); + + + /** Ask the precision of the actual calibration + * + * return a string containing the slope information in the following template : + * ?SLOPE,99.7,100.3 + * 99.7 : how closely the slope of the acid calibration matched the "ideal" ph probe + * 100.3 : how closely the slope of the base calibration matched the "ideal" ph probe + * + */ + string slope(void); + + + /** Do a factory reset on the EZOPH sensor + * + */ + string factoryReset(void); + + + /** Put the EZOPH sensor to sleep + * + */ + void sleep(void); + + /** Enable or Disable the protocol lock of the EZOPH sensor + * + * [in] 1 : Enable protocol lock + * [in] 0 : Disable protocol lock + * + */ + int EDProtocolLock(bool on); + + + /** Ask the status of the protocol lock of the EZOPH sensor + * + * return a string containing the protocl lock information in the following template : + * ?PLOCK,1 : Protocl lock is ON + * ?PLOCK,0 : Protocol lock is OFF + */ + int QProtocolLock(); + + + /** Change protocol of communication from UART to I2C + * + */ + void changeUART(int baudRate); + + +private: + + I2C *i2c_p; + I2C &i2c; + char address; + char cmdData[16]; + char ezodata[21]; + char receivedValue[20]; + string ezovalue; + string error255; + string error254; + string failedStr; + string succesStr; + int failed; + int success; +}; + +#endif // MBED_EZOPH_H
diff -r 000000000000 -r 1e392c8ebfcd main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Mon Mar 06 19:03:29 2017 +0000 @@ -0,0 +1,60 @@ + +#include "mbed.h" +#include "EZOPH/EZOPH.h" + +/* ------------------------------------------------ SERIAL OUTPUT DEBUGGING SETUP ------------------------------------------------ */ + +Serial device(USBTX, USBRX); // tx, rx +int number = 0; + +// Ph sensor +EZOPH sensor(p30, p7); // sda, scl + +string value0 = NULL; +string value1 = NULL; +string value2 = NULL; +string value3 = NULL; + +int value10 = 100; +int value11 = 100; +int value12 = 100; + +float temp = 12.325; +float ph = 0.0; + +int main(void) +{ + + value0 = sensor.getSensorInfo(); + wait(2); + value1 = sensor.getSensorStatus(); + wait(2); + value10 = sensor.sensorLED(1); + wait(2); + value11 = sensor.QsensorLED(); + wait(2); + value2 = sensor.calibrationQuery(); + wait(2); + value3 = sensor.slope(); + wait(2); + value12 = sensor.Tcompensation(20.0); + wait(2); + temp = sensor.QTcompensation(); + wait(2); + ph = sensor.read(); + wait(2); + sensor.sleep(); + /* ------------ SERIAL DEBUGGING OUTPUT ------------ */ + + device.baud(9600); + device.printf("\n\nNew set of mesure\r\n"); + device.printf("\nSensor info : %s\r\n", value0); + device.printf("\nSensor status : %s\r\n", value1); + device.printf("\nEnable sensor led: %d\r\n", value10); + device.printf("\nQ sensor LED : %d\r\n", value11); + device.printf("\nQuery calibration : %s\r\n", value2); + device.printf("\nSlope : %s\r\n", value3); + device.printf("\nSet temp compensation : %d\r\n", value12); + device.printf("\nQT compensation : %.3f\r\n", temp); + device.printf("\nPH reading : %.3f\r\n", ph); +}
diff -r 000000000000 -r 1e392c8ebfcd mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Mon Mar 06 19:03:29 2017 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/e1686b8d5b90 \ No newline at end of file