ecezo: initial implementation; C, C++; FTI + examples

Signed-off-by: Jon Trulson <jtrulson@ics.com>
This commit is contained in:
Jon Trulson 2016-11-18 17:32:34 -07:00
parent d4559878df
commit ad275e1d41
18 changed files with 1857 additions and 0 deletions

View File

@ -323,6 +323,7 @@ add_example (dfrec)
add_example (sht1x)
add_example (ms5803)
add_example (ims)
add_example (ecezo)
# These are special cases where you specify example binary, source file and module(s)
include_directories (${PROJECT_SOURCE_DIR}/src)

81
examples/c++/ecezo.cxx Normal file
View File

@ -0,0 +1,81 @@
/*
* Author: Jon Trulson <jtrulson@ics.com>
* Copyright (c) 2016 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <unistd.h>
#include <signal.h>
#include <upm_utilities.h>
#include <ecezo.hpp>
using namespace std;
using namespace upm;
bool shouldRun = true;
void sig_handler(int signo)
{
if (signo == SIGINT)
shouldRun = false;
}
int main()
{
signal(SIGINT, sig_handler);
//! [Interesting]
// Instantiate a ECEZO sensor on uart 0 at 9600 baud.
upm::ECEZO *sensor = new upm::ECEZO(0, 9600, false);
// For I2C, assuming the device is configured for address 0x64 on
// I2C bus 0, you could use something like:
//
// upm::ECEZO *sensor = new upm::ECEZO(0, 0x64, true);
while (shouldRun)
{
// this will take about 1 second to complete
sensor->update();
cout << "EC "
<< sensor->getEC()
<< " uS/cm, TDS "
<< sensor->getTDS()
<< " mg/L, Salinity "
<< sensor->getSalinity()
<< " PSS-78, SG "
<< sensor->getSG()
<< endl;
upm_delay(5);
}
//! [Interesting]
cout << "Exiting..." << endl;
delete sensor;
return 0;
}

View File

@ -140,6 +140,7 @@ add_example (button_intr)
add_example (my9221)
add_example (ms5803)
add_example (ims)
add_example (ecezo)
# Custom examples
add_custom_example (nmea_gps_i2c-example-c nmea_gps_i2c.c nmea_gps)

85
examples/c/ecezo.c Normal file
View File

@ -0,0 +1,85 @@
/*
* Author: Jon Trulson <jtrulson@ics.com>
* Copyright (c) 2016 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <unistd.h>
#include <signal.h>
#include <upm_utilities.h>
#include <ecezo.h>
bool shouldRun = true;
void sig_handler(int signo)
{
if (signo == SIGINT)
shouldRun = false;
}
int main()
{
signal(SIGINT, sig_handler);
//! [Interesting]
// Instantiate a ECEZO sensor on uart 0 at 9600 baud.
ecezo_context sensor = ecezo_uart_init(0, 9600);
// For I2C, assuming the device is configured for address 0x64 on
// I2C bus 0, you could use something like:
//
// ecezo_context sensor = ecezo_i2c_init(0, 0x64);
if (!sensor)
{
printf("ecezo_init() failed.\n");
return 1;
}
while (shouldRun)
{
// this will take about 1 second to complete
if (ecezo_update(sensor))
{
printf("ecezo_update() failed\n");
}
else
{
printf("EC %f uS/cm, TDS %f mg/L, Salinity %f PSS-78, SG %f\n",
ecezo_get_ec(sensor),
ecezo_get_tds(sensor),
ecezo_get_salinity(sensor),
ecezo_get_sg(sensor));
}
upm_delay(5);
}
//! [Interesting]
printf("Exiting\n");
ecezo_close(sensor);
return 0;
}

View File

@ -157,6 +157,7 @@ add_example(DFRORP_Example dfrorp)
add_example(DFREC_Example dfrec)
add_example(SHT1X_Example sht1x)
add_example(MS5803_Example ms5803)
add_example(ECEZO_Example ecezo)
add_example_with_path(Jhd1313m1_lcdSample lcd i2clcd)
add_example_with_path(Jhd1313m1Sample lcd i2clcd)

View File

@ -0,0 +1,60 @@
/*
* Author: Jon Trulson <jtrulson@ics.com>
* Copyright (c) 2016 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
import upm_ecezo.ECEZO;
public class ECEZO_Example
{
public static void main(String[] args) throws InterruptedException
{
// ! [Interesting]
// Instantiate a ECEZO sensor on uart 0 at 9600 baud.
ECEZO sensor = new ECEZO(0, 9600, false);
// For I2C, assuming the device is configured for address 0x64 on
// I2C bus 0, you could use something like:
//
// ECEZO sensor = new ECEZO(0, 0x64, true);
while (true)
{
// update our values from the sensor
sensor.update();
System.out.println("EC "
+ sensor.getEC()
+ " uS/cm, TDS "
+ sensor.getTDS()
+ " mg/L, Salinity "
+ sensor.getSalinity()
+ " PSS-78, SG "
+ sensor.getSG());
Thread.sleep(5000);
}
// ! [Interesting]
}
}

View File

@ -0,0 +1,59 @@
/*
* Author: Jon Trulson <jtrulson@ics.com>
* Copyright (c) 2016 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
var sensorObj = require('jsupm_ecezo');
// Instantiate a ECEZO sensor on uart 0 at 9600 baud.
var sensor = new sensorObj.ECEZO(0, 9600, false);
// For I2C, assuming the device is configured for address 0x64 on
// I2C bus 0, you could use something like:
//
// var sensor = new sensorObj.ECEZO(0, 0x64, true);
setInterval(function()
{
// update our values from the sensor
sensor.update();
console.log("EC "
+ sensor.getEC()
+ " uS/cm, TDS "
+ sensor.getTDS()
+ " mg/L, Salinity "
+ sensor.getSalinity()
+ " PSS-78, SG "
+ sensor.getSG());
}, 5000);
// exit on ^C
process.on('SIGINT', function()
{
sensor = null;
sensorObj.cleanUp();
sensorObj = null;
console.log("Exiting.");
process.exit(0);
});

66
examples/python/ecezo.py Executable file
View File

@ -0,0 +1,66 @@
#!/usr/bin/python
# Author: Jon Trulson <jtrulson@ics.com>
# Copyright (c) 2016 Intel Corporation.
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
from __future__ import print_function
import time, sys, signal, atexit
from upm import pyupm_ecezo as sensorObj
def main():
# Instantiate a ECEZO sensor on uart 0 at 9600 baud.
sensor = sensorObj.ECEZO(0, 9600, False);
# For I2C, assuming the device is configured for address 0x64 on
# I2C bus 0, you could use something like:
#
# sensor = sensorObj.ECEZO(0, 0x64, True);
## Exit handlers ##
# This function stops python from printing a stacktrace when you
# hit control-C
def SIGINTHandler(signum, frame):
raise SystemExit
# This function lets you run code on exit
def exitHandler():
print("Exiting")
sys.exit(0)
# Register exit handlers
atexit.register(exitHandler)
signal.signal(signal.SIGINT, SIGINTHandler)
while (1):
sensor.update()
print("EC "
+ str(sensor.getEC())
+ " uS/cm, TDS "
+ str(sensor.getTDS())
+ " mg/L, Salinity "
+ str(sensor.getSalinity())
+ " PSS-78, SG "
+ str(sensor.getSG()));
time.sleep(5)
if __name__ == '__main__':
main()

9
src/ecezo/CMakeLists.txt Normal file
View File

@ -0,0 +1,9 @@
upm_mixed_module_init (NAME ecezo
DESCRIPTION "EC EZO Atlas Scientific EC circuit"
C_HDR ecezo.h ecezo_defs.h
C_SRC ecezo.c
CPP_HDR ecezo.hpp
CPP_SRC ecezo.cxx
FTI_SRC ecezo_fti.c
CPP_WRAPS_C
REQUIRES mraa)

666
src/ecezo/ecezo.c Normal file
View File

@ -0,0 +1,666 @@
/*
* Author: Jon Trulson <jtrulson@ics.com>
* Copyright (c) 2016 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>
#include <upm_utilities.h>
#include "ecezo.h"
// "Typical" command completion delay in ms
#define CMD_DELAY (350)
// uncomment for dubugging
//#define ECEZO_DEBUG (1)
// I2C read helper
static int readBytes(const ecezo_context dev, uint8_t *buffer, int len)
{
assert(dev != NULL);
assert(dev->i2c != NULL);
bool done = false;
int rv;
int retries = 10;
while (!done && (retries-- > 0))
{
if ((rv = mraa_i2c_read(dev->i2c, buffer, len)) < 0)
{
printf("%s: mraa_i2c_read(code) failed.\n", __FUNCTION__);
return rv;
}
#if defined(ECEZO_DEBUG)
printf("CODE: %02x\n", buffer[0]);
#endif
if (buffer[0] == 0xff || buffer[0] == 0x02)
{
// no data available, or error
return -1;
}
else if (buffer[0] == 0x01)
{
// data is ready
done = true;
// now we need to move the data one byte down so the rest
// of this driver can work as-is.
memmove(buffer, (buffer + 1), len - 1);
}
else
{
// buffer[0] 0xfe - data is pending. wait and loop again.
upm_delay_ms(CMD_DELAY);
}
}
if (retries <= 0)
{
printf("%s: timed out waiting for correct response.\n", __FUNCTION__);
return -1;
}
#if defined(ECEZO_DEBUG)
printf("%s: Got %d bytes\n", __FUNCTION__, rv);
for (int i=0; i<rv; i++)
{
printf("%02x (%c) ", buffer[i],
isprint(buffer[i]) ? buffer[i] : '@');
}
printf("\n");
#endif // ECEZO_DEBUG
return rv;
}
static upm_result_t generic_init(const ecezo_context dev)
{
assert(dev != NULL);
// do some generic initialization
bool error = false;
// turn off response (*OK) codes (UART only)
if (dev->uart)
{
if (ecezo_send_command(dev, "Response,0", NULL, 0) < 0)
error = true;
}
// turn off continuous sampling
if (ecezo_set_continuous(dev, false))
error = true;
// make sure all parameters are enabled
if (ecezo_send_command(dev, "O,EC,1", NULL, 0) < 0)
error = true;
if (ecezo_send_command(dev, "O,TDS,1", NULL, 0) < 0)
error = true;
if (ecezo_send_command(dev, "O,S,1", NULL, 0) < 0)
error = true;
if (ecezo_send_command(dev, "O,SG,1", NULL, 0) < 0)
error = true;
if (error)
return UPM_ERROR_OPERATION_FAILED;
else
return UPM_SUCCESS;
}
static upm_result_t decode_report(const ecezo_context dev, char *data)
{
assert(dev != NULL);
char *startptr = data;
char *endptr = NULL;
float val;
// the format of the data string should be: ec,tds,s,sg
// ec
val = strtof(startptr, &endptr);
if (startptr == endptr)
{
// error
return UPM_ERROR_OPERATION_FAILED;
}
dev->ec = val;
startptr = endptr + 1;
// tds
val = strtof(startptr, &endptr);
// error
if (startptr == endptr)
return UPM_ERROR_OPERATION_FAILED;
dev->tds = val;
startptr = endptr + 1;
// salinity
val = strtof(startptr, &endptr);
// error
if (startptr == endptr)
return UPM_ERROR_OPERATION_FAILED;
dev->salinity = val;
startptr = endptr + 1;
// sg
val = strtof(startptr, &endptr);
if (startptr == endptr)
return UPM_ERROR_OPERATION_FAILED;
dev->sg = val;
return UPM_SUCCESS;
}
static bool ecezo_data_available(const ecezo_context dev, unsigned int millis)
{
assert(dev != NULL);
// i2c, we don't support this
if (dev->i2c)
{
return false;
}
// uart
if (mraa_uart_data_available(dev->uart, millis))
return true;
else
return false;
}
// uart init
ecezo_context ecezo_uart_init(unsigned int uart, unsigned int baudrate)
{
ecezo_context dev =
(ecezo_context)malloc(sizeof(struct _ecezo_context));
if (!dev)
return NULL;
// zero out context
memset((void *)dev, 0, sizeof(struct _ecezo_context));
// initialize the MRAA contexts
// uart, default should be 8N1
if (!(dev->uart = mraa_uart_init(uart)))
{
printf("%s: mraa_uart_init() failed.\n", __FUNCTION__);
ecezo_close(dev);
return NULL;
}
if (mraa_uart_set_baudrate(dev->uart, baudrate))
{
printf("%s: mraa_uart_set_baudrate() failed.\n", __FUNCTION__);
ecezo_close(dev);
return NULL;
}
mraa_uart_set_flowcontrol(dev->uart, false, false);
if (generic_init(dev))
{
printf("%s: generic_init() failed.\n", __FUNCTION__);
ecezo_close(dev);
return NULL;
}
return dev;
}
// i2c ublox init
ecezo_context ecezo_i2c_init(unsigned int bus, uint8_t addr)
{
// make sure MRAA is initialized
int mraa_rv;
if ((mraa_rv = mraa_init()) != MRAA_SUCCESS)
{
printf("%s: mraa_init() failed (%d).\n", __FUNCTION__, mraa_rv);
return NULL;
}
ecezo_context dev =
(ecezo_context)malloc(sizeof(struct _ecezo_context));
if (!dev)
return NULL;
// zero out context
memset((void *)dev, 0, sizeof(struct _ecezo_context));
// initialize the MRAA contexts
if (!(dev->i2c = mraa_i2c_init(bus)))
{
printf("%s: mraa_i2c_init() failed.\n", __FUNCTION__);
ecezo_close(dev);
return NULL;
}
if (mraa_i2c_address(dev->i2c, addr))
{
printf("%s: mraa_i2c_address() failed.\n", __FUNCTION__);
ecezo_close(dev);
return NULL;
}
if (generic_init(dev))
{
printf("%s: generic_init() failed.\n", __FUNCTION__);
ecezo_close(dev);
return NULL;
}
return dev;
}
void ecezo_close(ecezo_context dev)
{
assert(dev != NULL);
if (dev->uart)
mraa_uart_stop(dev->uart);
if (dev->i2c)
mraa_i2c_stop(dev->i2c);
free(dev);
}
upm_result_t ecezo_set_continuous(const ecezo_context dev, bool enable)
{
int rv;
if (enable)
rv = ecezo_send_command(dev, "C,1", NULL, 0);
else
rv = ecezo_send_command(dev, "C,0", NULL, 0);
return ((rv < 0) ? UPM_ERROR_OPERATION_FAILED : UPM_SUCCESS);
}
upm_result_t ecezo_set_temperature(const ecezo_context dev, float temp)
{
char buffer[ECEZO_MAX_BUFFER_LEN];
snprintf(buffer, ECEZO_MAX_BUFFER_LEN, "T,%f", temp);
int rv = ecezo_send_command(dev, buffer, NULL, 0);
return ((rv < 0) ? UPM_ERROR_OPERATION_FAILED : UPM_SUCCESS);
}
upm_result_t ecezo_set_led(const ecezo_context dev, bool enable)
{
int rv;
if (enable)
rv = ecezo_send_command(dev, "L,1", NULL, 0);
else
rv = ecezo_send_command(dev, "L,0", NULL, 0);
return ((rv < 0) ? UPM_ERROR_OPERATION_FAILED : UPM_SUCCESS);
}
upm_result_t ecezo_set_k_value(const ecezo_context dev, float k)
{
char buffer[ECEZO_MAX_BUFFER_LEN];
// the K value must be between 0.1 and 10.0
if (k < 0.1 || k > 10.0)
{
printf("%s: K value must be between 0.1 and 10.0\n", __FUNCTION__);
return UPM_ERROR_OUT_OF_RANGE;
}
snprintf(buffer, ECEZO_MAX_BUFFER_LEN, "K,%f", k);
int rv = ecezo_send_command(dev, buffer, NULL, 0);
return ((rv < 0) ? UPM_ERROR_OPERATION_FAILED : UPM_SUCCESS);
}
upm_result_t ecezo_set_sleep(const ecezo_context dev, bool enable)
{
int rv = 0;
if (enable)
rv = ecezo_send_command(dev, "SLEEP", NULL, 0);
else
{
// "WAKE" isn't a real command, but should wake the device up.
// We ignore the return value, as it will likely be an error
// anyway.
ecezo_send_command(dev, "WAKE", NULL, 0);
}
return ((rv < 0) ? UPM_ERROR_OPERATION_FAILED : UPM_SUCCESS);
}
int ecezo_read(const ecezo_context dev, char *buffer, size_t len)
{
assert(dev != NULL);
upm_delay_ms(CMD_DELAY); // delay CMD_DELAY ms to make sure cmd completed
// i2c
if (dev->i2c)
{
return readBytes(dev, (uint8_t *)buffer, len);
}
else
{
// UART
int bytesRead = 0;
while(bytesRead < len)
{
// we read one byte at a time, exiting when either len is
// reached, or a '\r' is found indicating the end of a
// sentence. Most commands (except 'R') require a minimum
// of 300ms to execute, so we wait up to CMD_DELAY ms after all
// data (if any) is read.
if (ecezo_data_available(dev, CMD_DELAY))
{
int br = mraa_uart_read(dev->uart, &buffer[bytesRead], 1);
if (br <= 0)
return br;
if (buffer[bytesRead] == '\r')
{
// if we found a CR, replace it with a 0 byte
buffer[bytesRead++] = 0;
return bytesRead;
}
bytesRead++;
}
else
{
// timed out - ok with responses disabled
return 0;
}
}
}
// anything else is an error
return -1;
}
upm_result_t ecezo_write(const ecezo_context dev, char *buffer, size_t len)
{
assert(dev != NULL);
if (dev->uart)
{
if (mraa_uart_write(dev->uart, buffer, len) != len)
{
printf("%s: mraa_uart_write() failed.\n", __FUNCTION__);
return UPM_ERROR_OPERATION_FAILED;
}
}
else
{
// I2C
if (mraa_i2c_write(dev->i2c, (uint8_t *)buffer, len))
{
printf("%s: mraa_i2c_write() failed.\n", __FUNCTION__);
return UPM_ERROR_OPERATION_FAILED;
}
}
return UPM_SUCCESS;
}
int ecezo_send_command(const ecezo_context dev, char *cmd, char *buffer,
int len)
{
assert(dev != NULL);
if (!cmd)
return -1;
// Our local buffer in case one isn't supplied
char localBuffer[ECEZO_MAX_BUFFER_LEN];
// our read buffer ptr
char *readBuffer = NULL;
if (!buffer || !len)
{
readBuffer = localBuffer;
len = ECEZO_MAX_BUFFER_LEN;
}
else
{
readBuffer = buffer;
}
#if defined(ECEZO_DEBUG)
printf("Command: %s\n", cmd);
#endif // ECEZO_DEBUG
// our write buffer
char writeBuffer[ECEZO_MAX_BUFFER_LEN];
strncpy(writeBuffer, cmd, ECEZO_MAX_BUFFER_LEN);
writeBuffer[ECEZO_MAX_BUFFER_LEN - 1] = 0;
int writelen = strlen(writeBuffer);
if (dev->uart)
{
if (strlen(writeBuffer) >= ECEZO_MAX_BUFFER_LEN - 2)
{
// too big. Should never happen in real life.
printf("%s: cmd writeBuffer too big.\n", __FUNCTION__);
return -1;
}
strcat(writeBuffer, "\r");
}
// for the uart this will now include the added CR, for I2C, this
// will now include the already existing \0 terminator.
writelen++;
// Let the games begin...
int retries = 10;
while (retries-- > 0)
{
if (ecezo_write(dev, writeBuffer, writelen))
{
printf("%s: ecezo_write() failed\n", __FUNCTION__);
return -1;
}
// we wait up to CMD_DELAY ms for an error response, which should be
// more than enough time. No response is also ok, since we
// disable the "*OK" response in the init.
memset((void *)readBuffer, 0, len);
int bytesRead = 0;
if ((bytesRead = ecezo_read(dev, readBuffer, len)) < 0)
{
return -1;
}
// for I2C, we are done at this point
if (dev->i2c)
break;
// for UART, we need some more checks
if (bytesRead && strstr(readBuffer, "*ER"))
{
// need to retry the command
#if defined(ECEZO_DEBUG)
printf("%s: *ER DETECTED, retry\n", __FUNCTION__);
#endif // ECEZO_DEBUG
continue;
}
else if (bytesRead && strchr(readBuffer, '*'))
{
// Some other diagnostic code, output it.
#if defined(ECEZO_DEBUG)
printf("%s: * diagnostic code detected (%s), retry\n",
__FUNCTION__, buffer);
#endif // ECEZO_DEBUG
continue;
}
else
{
// we are done here
#if defined(ECEZO_DEBUG)
printf("%s: bytesRead = %d\n", __FUNCTION__, bytesRead);
#endif // ECEZO_DEBUG
break;
}
}
if (retries <= 0)
{
printf("%s: read timed out and/or and retries exhausted\n",
__FUNCTION__);
return 0;
}
return len;
}
upm_result_t ecezo_update(const ecezo_context dev)
{
assert(dev != NULL);
// first we send a 'R' command to get a reading (takes a minimum
// of 1 second), then we parse out the string values into the
// context variables.
char buffer[ECEZO_MAX_BUFFER_LEN];
// first issue the report command
int rv = ecezo_send_command(dev, "R", buffer, ECEZO_MAX_BUFFER_LEN);
if (rv == 0)
{
printf("%s: timed out waiting for data\n", __FUNCTION__);
return UPM_ERROR_OPERATION_FAILED;
}
else if (rv < 0)
{
printf("%s: error retrieving data\n", __FUNCTION__);
return UPM_ERROR_OPERATION_FAILED;
}
// decode
if (decode_report(dev, buffer))
{
printf("%s: decode_report() failed\n", __FUNCTION__);
return UPM_ERROR_OPERATION_FAILED;
}
return UPM_SUCCESS;
}
float ecezo_get_ec(const ecezo_context dev)
{
assert(dev != NULL);
return dev->ec;
}
float ecezo_get_tds(const ecezo_context dev)
{
assert(dev != NULL);
return dev->tds;
}
float ecezo_get_salinity(const ecezo_context dev)
{
assert(dev != NULL);
return dev->salinity;
}
float ecezo_get_sg(const ecezo_context dev)
{
assert(dev != NULL);
return dev->sg;
}
upm_result_t ecezo_calibrate(const ecezo_context dev, ECEZO_CALIBRATION_T cal,
float ec)
{
assert(dev != NULL);
char cmdBuffer[ECEZO_MAX_BUFFER_LEN];
switch(cal)
{
case ECEZO_CALIBRATE_CLEAR:
snprintf(cmdBuffer, ECEZO_MAX_BUFFER_LEN, "cal,clear");
break;
case ECEZO_CALIBRATE_DRY:
snprintf(cmdBuffer, ECEZO_MAX_BUFFER_LEN, "cal,dry");
break;
case ECEZO_CALIBRATE_ONE:
snprintf(cmdBuffer, ECEZO_MAX_BUFFER_LEN, "cal,one,%f", ec);
break;
case ECEZO_CALIBRATE_LOW:
snprintf(cmdBuffer, ECEZO_MAX_BUFFER_LEN, "cal,low,%f", ec);
break;
case ECEZO_CALIBRATE_HIGH:
snprintf(cmdBuffer, ECEZO_MAX_BUFFER_LEN, "cal,high,%f", ec);
break;
default:
// should be able to happen
printf("%s: invalid cal parameter\n", __FUNCTION__);
return UPM_ERROR_INVALID_PARAMETER;
}
return ecezo_send_command(dev, cmdBuffer, NULL, 0);
}

146
src/ecezo/ecezo.cxx Normal file
View File

@ -0,0 +1,146 @@
/*
* Author: Jon Trulson <jtrulson@ics.com>
* Copyright (c) 2016 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <iostream>
#include <stdexcept>
#include "ecezo.hpp"
using namespace upm;
using namespace std;
ECEZO::ECEZO(unsigned int bus, unsigned int addrBaud, bool isI2C) :
m_ecezo(nullptr)
{
if (isI2C)
m_ecezo = ecezo_i2c_init(bus, addrBaud);
else
m_ecezo = ecezo_uart_init(bus, addrBaud);
if (!m_ecezo)
throw std::runtime_error(string(__FUNCTION__)
+ ": ecezo_*_init() failed");
}
ECEZO::~ECEZO()
{
ecezo_close(m_ecezo);
}
void ECEZO::update()
{
if (ecezo_update(m_ecezo))
throw std::runtime_error(string(__FUNCTION__)
+ ": ecezo_update() failed");
}
void ECEZO::setTemperature(float temp)
{
if (ecezo_set_temperature(m_ecezo, temp))
throw std::runtime_error(string(__FUNCTION__)
+ ": ecezo_set_temperature() failed");
}
void ECEZO::setKValue(float k)
{
if (ecezo_set_k_value(m_ecezo, k))
throw std::runtime_error(string(__FUNCTION__)
+ ": ecezo_set_k_value() failed");
}
void ECEZO::setSleep(bool enable)
{
if (ecezo_set_sleep(m_ecezo, enable))
throw std::runtime_error(string(__FUNCTION__)
+ ": ecezo_set_sleep() failed");
}
float ECEZO::getEC()
{
return ecezo_get_ec(m_ecezo);
}
float ECEZO::getTDS()
{
return ecezo_get_tds(m_ecezo);
}
float ECEZO::getSalinity()
{
return ecezo_get_salinity(m_ecezo);
}
float ECEZO::getSG()
{
return ecezo_get_sg(m_ecezo);
}
void ECEZO::calibrate(ECEZO_CALIBRATION_T cal, float ec)
{
if (ecezo_calibrate(m_ecezo, cal, ec))
throw std::runtime_error(string(__FUNCTION__)
+ ": ecezo_calibrate() failed");
}
void ECEZO::setContinuous(bool enable)
{
if (ecezo_set_continuous(m_ecezo, enable))
throw std::runtime_error(string(__FUNCTION__)
+ ": ecezo_set_continuous() failed");
}
string ECEZO::sendCommand(string cmd)
{
char buffer[ECEZO_MAX_BUFFER_LEN];
int rv;
if ((rv = ecezo_send_command(m_ecezo, (char *)cmd.c_str(),
buffer, ECEZO_MAX_BUFFER_LEN)) < 0)
throw std::runtime_error(string(__FUNCTION__)
+ ": ecezo_send_command() failed");
return string(buffer, rv);
}
string ECEZO::read()
{
char buffer[ECEZO_MAX_BUFFER_LEN];
int rv;
if ((rv = ecezo_read(m_ecezo, buffer, ECEZO_MAX_BUFFER_LEN)) < 0)
throw std::runtime_error(string(__FUNCTION__)
+ ": ecezo_read() failed");
return string(buffer, rv);
}
void ECEZO::write(std::string data)
{
if (ecezo_write(m_ecezo, (char*)data.data(),
data.size()))
throw std::runtime_error(string(__FUNCTION__)
+ ": ecezo_write() failed");
}

267
src/ecezo/ecezo.h Normal file
View File

@ -0,0 +1,267 @@
/*
* Author: Jon Trulson <jtrulson@ics.com>
* Copyright (c) 2016 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#pragma once
#include <stdint.h>
#include <upm.h>
#include <mraa/uart.h>
#include <mraa/i2c.h>
#include <mraa/gpio.h>
#include "ecezo_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @file ecezo.h
* @library ecezo
* @brief C API for the EC-EZO EC Sensor
*
* @include ecezo.c
*/
/**
* Device context
*/
typedef struct _ecezo_context {
mraa_uart_context uart;
mraa_i2c_context i2c;
// our values
float ec; // electrical conductivity
float tds; // total dissolved solids
float salinity;
float sg; // specific gravity
} *ecezo_context;
/**
* ECEZO Initializer for UART operation
*
* @param uart Specify which uart to use.
* @param baudrate Specify the baudrate to use. The device defaults
* to 9600 baud, though the datasheet implies the default is 38400.
* @return an initialized device context on success, NULL on error.
*/
ecezo_context ecezo_uart_init(unsigned int uart, unsigned int baudrate);
/**
* ECEZO Initializer for I2C operation
*
* @param bus Specify which the I2C bus to use.
* @param addr Specify the I2C address to use. This is
* configurable on the device, so there is no default.
* @return an initialized device context on success, NULL on error.
*/
ecezo_context ecezo_i2c_init(unsigned int bus, uint8_t addr);
/**
* ECEZO sensor close function
*/
void ecezo_close(ecezo_context dev);
/**
* Query the device for a reading, parse the response, and store
* the read values into the device context. This function must be
* called prior to calling any function that returns the data,
* like ecezo_get_ec().
*
* @param dev Device context
* @return UPM result
*/
upm_result_t ecezo_update(const ecezo_context dev);
/**
* For accurate readings, the temperature of the liquid being
* measured should be known. This function allows you to specify
* the liquid's temperature (in Celsius) so that proper
* compensation can take place. How you measure this temperature
* is up to you. By default, the device will assume a temperature
* of 25C.
*
* @param dev Device context
* @param temp The temperature of the liquid being measured
* @return UPM result
*/
upm_result_t ecezo_set_temperature(const ecezo_context dev, float temp);
/**
* Set the K value of the probe being used. By default, this is
* 1.0. Valid values are between 0.1 and 10.0.
*
* @param dev Device context
* @param k The K value of the probe
* @return UPM result
*/
upm_result_t ecezo_set_k_value(const ecezo_context dev, float k);
/**
* Enable or disable Sleep mode.
*
* @param dev Device context
* @param enable True to enable sleep mode, false to wake up
* @return UPM result
*/
upm_result_t ecezo_set_sleep(const ecezo_context dev, bool enable);
/**
* Retrieve the last measured Electrical Conductivity (EC) value
* in microsiemens. ecezo_update() must have been called before
* calling this function.
*
* @param dev Device context
* @return EC value in microsiemens
*/
float ecezo_get_ec(const ecezo_context dev);
/**
* Retrieve the last measured Total Dissolved solids (TDS) value.
* ecezo_update() must have been called before calling this
* function.
*
* @param dev Device context
* @return TDS value
*/
float ecezo_get_tds(const ecezo_context dev);
/**
* Retrieve the last measured Salinity value. ecezo_update() must
* have been called before calling this function.
*
* @param dev Device context
* @return Salinity value
*/
float ecezo_get_salinity(const ecezo_context dev);
/**
* Retrieve the last measured Specific Gravity (SG) value.
* ecezo_update() must have been called before calling this
* function.
*
* @param dev Device context
* @return SG value
*/
float ecezo_get_sg(const ecezo_context dev);
/**
* Specify calibration data for calibrating the device. See the
* datasheet for details on how calibration is performed. This
* function provides a mechanism for clearing out, and setting
* calibration data.
*
* A simple one point calibration might work as follows:
*
* 1. CLEAR the calibration data
* 2. with a dry probe, set the DRY point.
* 3. with the probe immersed in a standardized solution, set the
* ONE parameter to the solution's known EC value in microsiemens.
*
* A two point calibration might work as follows:
*
* 1. CLEAR the calibration data
* 2. with a dry probe, set the DRY point.
* 3. with the probe immersed in the lowest EC standardized
* solution, set the LOW parameter to the solution's known EC
* value in microsiemens.
* 4. with the probe immersed in the highest EC standardized
* solution, set the HIGH parameter to the solution's known EC
* value in microsiemens.
*
* @param dev Device context
* @param cal One of the ECEZO_CALIBRATION_T values
* @param ec The EC value of the calibration fluid. This
* parameter is ignored when cal is either ECEZO_CALIBRATE_CLEAR
* or ECEZO_CALIBRATE_DRY.
* @return UPM result
*/
upm_result_t ecezo_calibrate(const ecezo_context dev,
ECEZO_CALIBRATION_T cal,
float ec);
/**
* Enable or disable "continuous" operation. In continuous
* operation, the device will sample and emit readings every
* second. The driver disables this mode by default. If you wish
* to use continuous mode, you will be responsible for reading and
* parsing the returned data yourself.
*
* The functionality of this driver depends on continuous mode
* being disabled. When disabled, the driver will manually
* request a reading when desired via ecezo_update().
*
* @param dev Device context
* @param enable true to enable continuous mode, false to disable.
* @return UPM result
*/
upm_result_t ecezo_set_continuous(const ecezo_context dev, bool enable);
/**
* Directly send a command to the device and optionally get a
* response. This is a low level function and should not be
* called unless you know what you are doing.
*
* @param dev Device context
* @param cmd command to send to the device. See the datasheet
* for valid commands.
* @param buffer Optional buffer in which to return any data.
* NULL if you are not interested in any returned data.
* @param len Length of the buffer, or 0 if you are not interested
* in returned data
* @return Number of characters read back, 0 if a timeout or no
* data, -1 if an error
*/
int ecezo_send_command(const ecezo_context dev, char *cmd,
char *buffer, int len);
/**
* Read character data from the device. This is a low level
* function and should not be called unless you know what you are
* doing.
*
* @param dev sensor context
* @param buffer The character buffer to read data into.
* @param len The maximum size of the buffer
* @return The number of bytes successfully read, or -1 on error
*/
int ecezo_read(const ecezo_context dev, char *buffer, size_t len);
/**
* Write character data to the device. This is a low level
* function and should not be called unless you know what you are
* doing.
*
* @param dev sensor context
* @param buffer The character buffer containing data to write.
* @param len The number of bytes to write.
* @return The number of bytes successfully written, or -1 on error.
*/
upm_result_t ecezo_write(const ecezo_context dev, char *buffer, size_t len);
#ifdef __cplusplus
}
#endif

238
src/ecezo/ecezo.hpp Normal file
View File

@ -0,0 +1,238 @@
/*
* Author: Jon Trulson <jtrulson@ics.com>
* Copyright (c) 2016 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#pragma once
#include <string>
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include "ecezo.h"
namespace upm {
/**
* @brief API for the EC-EZO EC Sensor
* @defgroup ecezo libupm-ecezo
* @ingroup uart i2c liquid
*/
/**
* @library ecezo
* @sensor ecezo
* @comname EC-EZO EC Sensor
* @type liquid
* @man sparkfun
* @con uart i2c
* @web https://www.sparkfun.com/products/12908
*
* @brief API for the EC-EZO EC Sensor
*
* This driver was tested with the Atlas Scientific Electrical
* Conductivity kit.
*
* This device can operate in either UART or I2C modes.
*
* @snippet ecezo.cxx Interesting
*/
class ECEZO {
public:
/**
* ECEZO object constructor. This can use either UART
* (default) or I2C communications. For UART, specify the
* uart number as the bus parameter, the baudrate as the
* addrBaud parameter, and false for the isI2C parameter.
*
* For I2C, specify the bus parameter, the I2C address as the
* addrBaud parameter, and true for the isI2C parameter.
*
* @param bus Specify which uart or I2C bus to use
* @param addrBaud Specify the baudrate if using UART, or the
* I2C address of the device if using I2C.
* @param isI2C true if using I2C, false if using a UART
*/
ECEZO(unsigned int bus=0, unsigned int addrBaud=9600,
bool isI2C=false);
/**
* ECEZO object destructor
*/
~ECEZO();
/**
* Query the device for a reading, parse the response, and store
* the read values into the device context. This function must be
* called prior to calling any function that returns the data,
* like getEC().
*/
void update();
/**
* For accurate readings, the temperature of the liquid being
* measured should be known. This function allows you to specify
* the liquid's temperature (in Celsius) so that proper
* compensation can take place. How you measure this temperature
* is up to you. By default, the device will assume a temperature
* of 25C.
*
* @param temp The temperature of the liquid being measured
* @return UPM result
*/
void setTemperature(float temp);
/**
* Set the K value of the probe being used. By default, this is
* 1.0. Valid values are between 0.1 and 10.0.
*
* @param k The K value of the probe
*/
void setKValue(float k);
/**
* Enable or disable Sleep mode.
*
* @param enable True to enable sleep mode, false to wake up
*/
void setSleep(bool enable);
/**
* Retrieve the last measured Electrical Conductivity (EC)
* value in microsiemens. update() must have been called
* before calling this function.
*
* @return EC value in microsiemens
*/
float getEC();
/**
* Retrieve the last measured Total Dissolved solids (TDS) value.
* update() must have been called before calling this
* function.
*
* @return TDS value
*/
float getTDS();
/**
* Retrieve the last measured Salinity value. update() must
* have been called before calling this function.
*
* @return Salinity value
*/
float getSalinity();
/**
* Retrieve the last measured Specific Gravity (SG) value.
* update() must have been called before calling this
* function.
*
* @return SG value
*/
float getSG();
/**
* Specify calibration data for calibrating the device. See the
* datasheet for details on how calibration is performed. This
* function provides a mechanism for clearing out, and setting
* calibration data.
*
* A simple one point calibration might work as follows:
*
* 1. CLEAR the calibration data
* 2. with a dry probe, set the DRY point.
* 3. with the probe immersed in a standardized solution, set the
* ONE parameter to the solution's known EC value in microsiemens.
*
* A two point calibration might work as follows:
*
* 1. CLEAR the calibration data
* 2. with a dry probe, set the DRY point.
* 3. with the probe immersed in the lowest EC standardized
* solution, set the LOW parameter to the solution's known EC
* value in microsiemens.
* 4. with the probe immersed in the highest EC standardized
* solution, set the HIGH parameter to the solution's known EC
* value in microsiemens.
*
* @param cal One of the ECEZO_CALIBRATION_T values
* @param ec The EC value of the calibration fluid. This
* parameter is ignored when cal is either ECEZO_CALIBRATE_CLEAR
* or ECEZO_CALIBRATE_DRY.
*/
void calibrate(ECEZO_CALIBRATION_T cal, float ec);
protected:
// ecezo device context
ecezo_context m_ecezo;
/**
* Enable or disable "continuous" operation. In continuous
* operation, the device will sample and emit readings every
* second. The driver disables this mode by default. If you wish
* to use continuous mode, you will be responsible for reading and
* parsing the returned data yourself.
*
* The functionality of this driver depends on continuous mode
* being disabled. When disabled, the driver will manually
* request a reading when desired via ecezo_update().
*
* @param enable true to enable continuous mode, false to disable.
*/
void setContinuous(bool enable);
/**
* Directly send a command to the device and optionally get a
* response. This is a low level function and should not be
* called unless you know what you are doing.
*
* @param cmd a String containing the command to send to the
* device. See the datasheet for valid commands.
* @return The string response, if any
*/
std::string sendCommand(std::string cmd);
/**
* Read character data from the device. This is a low level
* function and should not be called unless you know what you are
* doing.
*
* @return A string containing the data read back, if any
*/
std::string read();
/**
* Write character data to the device. This is a low level
* function and should not be called unless you know what you are
* doing.
*
* @param data The string containing data to write.
*/
void write(std::string data);
private:
};
}

45
src/ecezo/ecezo_defs.h Normal file
View File

@ -0,0 +1,45 @@
/*
* Author: Jon Trulson <jtrulson@ics.com>
* Copyright (c) 2016 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
// our maximum buffer size
#define ECEZO_MAX_BUFFER_LEN (64)
// calibration commands
typedef enum {
ECEZO_CALIBRATE_CLEAR = 0, // clear calibration
ECEZO_CALIBRATE_DRY, // cal dry point
ECEZO_CALIBRATE_ONE, // single point cal EC value
ECEZO_CALIBRATE_LOW, // 2-point cal, LOW EC value
ECEZO_CALIBRATE_HIGH // 2-point cal, HIGH EC value
} ECEZO_CALIBRATION_T;
#ifdef __cplusplus
}
#endif

88
src/ecezo/ecezo_fti.c Normal file
View File

@ -0,0 +1,88 @@
/*
* Author: Jon Trulson <jtrulson@ics.com>
* Copyright (c) 2016 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "ecezo.h"
#include "upm_fti.h"
/**
* This file implements the Function Table Interface (FTI) for this sensor
*/
const char upm_ecezo_name[] = "ECEZO";
const char upm_ecezo_description[] = "EC-EZO EC sensor";
const upm_protocol_t upm_ecezo_protocol[] = {UPM_UART, UPM_I2C};
const upm_sensor_t upm_ecezo_category[] = {UPM_EC};
// forward declarations
const void* upm_ecezo_get_ft(upm_sensor_t sensor_type);
void* upm_ecezo_init_name();
void upm_ecezo_close(void *dev);
upm_result_t upm_ecezo_get_value(const void *dev, float *value);
static const upm_sensor_ft ft =
{
.upm_sensor_init_name = &upm_ecezo_init_name,
.upm_sensor_close = &upm_ecezo_close,
};
static const upm_ec_ft ecft =
{
.upm_ec_get_value = upm_ecezo_get_value
};
const void* upm_ecezo_get_ft(upm_sensor_t sensor_type)
{
switch(sensor_type)
{
case UPM_SENSOR:
return &ft;
case UPM_EC:
return &ecft;
default:
return NULL;
}
}
void* upm_ecezo_init_name()
{
return NULL;
}
void upm_ecezo_close(void *dev)
{
ecezo_close((ecezo_context)dev);
}
upm_result_t upm_ecezo_get_value(const void *dev, float *value)
{
upm_result_t rv;
if ((rv = ecezo_update((ecezo_context)dev)))
return rv;
*value = ecezo_get_ec((ecezo_context)dev);
return UPM_SUCCESS;
}

22
src/ecezo/javaupm_ecezo.i Normal file
View File

@ -0,0 +1,22 @@
%module javaupm_ecezo
%include "../upm.i"
%include "std_string.i"
%include "stdint.i"
%include "typemaps.i"
%include "ecezo_defs.h"
%include "ecezo.hpp"
%{
#include "ecezo.hpp"
%}
%pragma(java) jniclasscode=%{
static {
try {
System.loadLibrary("javaupm_ecezo");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load. \n" + e);
System.exit(1);
}
}
%}

9
src/ecezo/jsupm_ecezo.i Normal file
View File

@ -0,0 +1,9 @@
%module jsupm_ecezo
%include "../upm.i"
%include "std_string.i"
%include "ecezo_defs.h"
%include "ecezo.hpp"
%{
#include "ecezo.hpp"
%}

13
src/ecezo/pyupm_ecezo.i Normal file
View File

@ -0,0 +1,13 @@
// Include doxygen-generated documentation
%include "pyupm_doxy2swig.i"
%module pyupm_ecezo
%include "../upm.i"
%include "std_string.i"
%feature("autodoc", "3");
%include "ecezo_defs.h"
%include "ecezo.hpp"
%{
#include "ecezo.hpp"
%}