From bf315ee5c6270101c75635a44a5f522ecc19c3e1 Mon Sep 17 00:00:00 2001 From: Hiroyuki Mino Date: Tue, 12 Mar 2019 00:02:06 +0000 Subject: [PATCH] 2jciebu01: initial implementation of Omron's USB type Environment Sensor Signed-off-by: Hiroyuki Mino Signed-off-by: Mihai Tudor Panu --- .../upm/examples/c++/omron2jciebu01_usb.cxx | 415 ++++++++++++++++++ .../upm/src/2jciebu01-usb/2jciebu01.cxx | 98 +++++ .../upm/src/2jciebu01-usb/2jciebu01.hpp | 240 ++++++++++ .../upm/src/2jciebu01-usb/2jciebu01_usb.cxx | 351 +++++++++++++++ .../upm/src/2jciebu01-usb/2jciebu01_usb.hpp | 247 +++++++++++ .../upm/src/2jciebu01-usb/2jciebu01_usb.i | 8 + .../upm/src/2jciebu01-usb/2jciebu01_usb.json | 35 ++ .../upm/src/2jciebu01-usb/CMakeLists.txt | 5 + Omron_2jcie-bu01_usb/upm/src/CMakeLists.txt | 2 + 9 files changed, 1401 insertions(+) create mode 100644 Omron_2jcie-bu01_usb/upm/examples/c++/omron2jciebu01_usb.cxx create mode 100644 Omron_2jcie-bu01_usb/upm/src/2jciebu01-usb/2jciebu01.cxx create mode 100644 Omron_2jcie-bu01_usb/upm/src/2jciebu01-usb/2jciebu01.hpp create mode 100644 Omron_2jcie-bu01_usb/upm/src/2jciebu01-usb/2jciebu01_usb.cxx create mode 100644 Omron_2jcie-bu01_usb/upm/src/2jciebu01-usb/2jciebu01_usb.hpp create mode 100644 Omron_2jcie-bu01_usb/upm/src/2jciebu01-usb/2jciebu01_usb.i create mode 100644 Omron_2jcie-bu01_usb/upm/src/2jciebu01-usb/2jciebu01_usb.json create mode 100644 Omron_2jcie-bu01_usb/upm/src/2jciebu01-usb/CMakeLists.txt create mode 100644 Omron_2jcie-bu01_usb/upm/src/CMakeLists.txt diff --git a/Omron_2jcie-bu01_usb/upm/examples/c++/omron2jciebu01_usb.cxx b/Omron_2jcie-bu01_usb/upm/examples/c++/omron2jciebu01_usb.cxx new file mode 100644 index 00000000..7a97c2bc --- /dev/null +++ b/Omron_2jcie-bu01_usb/upm/examples/c++/omron2jciebu01_usb.cxx @@ -0,0 +1,415 @@ +/* +* Author: Hiroyuki Mino +* Copyright (c) 2019 Omron Electronic Components - Americas +* +* 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. +*/ + +/* standard headers */ +#include +#include +#include +#include + + +/* omron sensor headers */ +#include "2jciebu01_usb.hpp" + +using namespace std; +using namespace upm; + +volatile sig_atomic_t flag = 1; +#define PREVIOUS_MENU_CHOICE 10 + +upm::OM2JCIEBU_UART::om2jciebuData_t om2jciebuSensorData; + +void +sig_handler(int signum) +{ + if(signum == SIGABRT) { //check for Abort signal + std::cout << "Exiting..." << std::endl; + } + if(signum == SIGINT) { //check for Interrupt signal + std::cout << "Exiting..." << std::endl; + flag = 0; + } +} + + +void getSensorData(OM2JCIEBU_UART *p_om2jcieuart) +{ + if(p_om2jcieuart == NULL) { + std::cout << "Null pointer received..." << std::endl; + return; + } + uint16_t parameterChoice = 0; + int displayDelay = 0; + bool seconds_validate = false; + uint16_t sensorParamData = 0; + uint32_t pressureData = 0; + + while(true) { + printf("************************************************************\r\n"); + printf("Please select sensor attribute for display\r\n"); + printf("0) All parameter\r\n"); + printf("1) Temperature data\r\n"); + printf("2) Relative humidity data\r\n"); + printf("3) Ambient light data\r\n"); + printf("4) Barometric pressure data\r\n"); + printf("5) Sound noise data\r\n"); + printf("6) eTVOC data\r\n"); + printf("7) eCO2 data\r\n"); + printf("8) Discomfort index data\r\n"); + printf("9) Heat stroke data\r\n"); + printf("10) Return to main menu\r\n"); + printf("Note :: Press Ctrl+C for sensor attribute display menu\r\n"); + printf("************************************************************\r\n"); + while(!(std::cin >> parameterChoice)) { + std::cin.clear(); //clear bad input flag + std::cin.ignore(std::numeric_limits::max(), '\n'); //discard input + std::cout << "Invalid input; please re-enter.\n"; + } + if(parameterChoice >= OM2JCIEBU_UART::ALL_PARAM && parameterChoice <= OM2JCIEBU_UART::HEAT_STROKE) { + flag = 1; + printf("Please enter time interval (in Seconds), for display sensor data\r\n"); + while(!seconds_validate) { //validate user input values + cin >> displayDelay; + if(!cin.fail() && (cin.peek() == EOF || cin.peek() == '\n') && (displayDelay >= 1 && displayDelay <= 10)) { + seconds_validate = true; + } else { + cin.clear(); + cin.ignore(); + cout << "Error, enter an second between 1 to 10!" << endl; + } + } + while(flag) { + switch(parameterChoice) { + case OM2JCIEBU_UART::ALL_PARAM: + if(p_om2jcieuart->getSensorData(OM2JCIEBU_UART::ALL_PARAM, &om2jciebuSensorData) == OM2JCIEBU_UART::SUCCESS) { + printf("************** Sensor Attribute Values ***************\r\n"); + printf("Sequence Number :: %d \r\n", om2jciebuSensorData.sequence_number); + printf("Temperature :: %d degC\r\n", om2jciebuSensorData.temperature); + printf("Relative humidity :: %d RH\r\n", om2jciebuSensorData.relative_humidity); + printf("Ambient light :: %d lx\r\n", om2jciebuSensorData.ambient_light); + printf("Barometric pressure :: %d hPa\r\n", om2jciebuSensorData.pressure); + printf("Sound noise :: %d dB\r\n", om2jciebuSensorData.noise); + printf("eTVOC :: %d ppb\r\n", om2jciebuSensorData.eTVOC); + printf("eCO2 :: %d ppm\r\n", om2jciebuSensorData.eCO2); + printf("Discomfort index :: %d \r\n", om2jciebuSensorData.discomfort_index); + printf("Heat stroke :: %d degC\r\n", om2jciebuSensorData.heat_stroke); + printf("**********************************************************\r\n"); + memset(&om2jciebuSensorData, 0, sizeof(om2jciebuSensorData)); + } else { + flag = 0; + } + break; + case OM2JCIEBU_UART::TEMP: + if(p_om2jcieuart->getSensorData(OM2JCIEBU_UART::TEMP, &sensorParamData) == OM2JCIEBU_UART::SUCCESS) { + printf("************** Temperature Attribute Values ***************\r\n"); + printf("Temperature :: %d degC\r\n", sensorParamData); + printf("************************************************************\r\n"); + } else { + flag = 0; + } + break; + case OM2JCIEBU_UART::HUMIDITY: + if(p_om2jcieuart->getSensorData(OM2JCIEBU_UART::HUMIDITY, &sensorParamData) == OM2JCIEBU_UART::SUCCESS) { + printf("************** Relative humidity Attribute Values ***************\r\n"); + printf("Relative humidity :: %d RH\r\n", sensorParamData); + printf("******************************************************************\r\n"); + } else { + flag = 0; + } + break; + case OM2JCIEBU_UART::AMBIENT_LIGHT: + if(p_om2jcieuart->getSensorData(OM2JCIEBU_UART::AMBIENT_LIGHT, &sensorParamData) == OM2JCIEBU_UART::SUCCESS) { + printf("************** Ambient light Attribute Values ***************\r\n"); + printf("Ambient light :: %d lx\r\n", sensorParamData); + printf("**************************************************************\r\n"); + } else { + flag = 0; + } + break; + case OM2JCIEBU_UART::PRESSURE: + if(p_om2jcieuart->getSensorData(OM2JCIEBU_UART::PRESSURE, &pressureData) == OM2JCIEBU_UART::SUCCESS) { + printf("************** Barometric pressure Attribute Values ***************\r\n"); + printf("Barometric pressure :: %d hPa\r\n", pressureData); + printf("********************************************************************\r\n"); + } else { + flag = 0; + } + break; + + case OM2JCIEBU_UART::NOISE: + if(p_om2jcieuart->getSensorData(OM2JCIEBU_UART::NOISE, &sensorParamData) == OM2JCIEBU_UART::SUCCESS) { + printf("************** Sound noise Attribute Values ***************\r\n"); + printf("Sound noise :: %d dB\r\n", sensorParamData); + printf("************************************************************\r\n"); + } else { + flag = 0; + } + break; + + case OM2JCIEBU_UART::ETVOC: + if(p_om2jcieuart->getSensorData(OM2JCIEBU_UART::ETVOC, &sensorParamData) == OM2JCIEBU_UART::SUCCESS) { + printf("************** eTVOC Attribute Values ***************\r\n"); + printf("eTVOC :: %d ppb\r\n", sensorParamData); + printf("******************************************************\r\n"); + } else { + flag = 0; + } + break; + case OM2JCIEBU_UART::ECO2: + if(p_om2jcieuart->getSensorData(OM2JCIEBU_UART::ECO2, &sensorParamData) == OM2JCIEBU_UART::SUCCESS) { + printf("************** eCO2 Attribute Values ***************\r\n"); + printf("eCO2 :: %d ppm\r\n\r\n", sensorParamData); + printf("******************************************************\r\n"); + } else { + flag = 0; + } + break; + case OM2JCIEBU_UART::DISCOMFORT_INDEX: + if(p_om2jcieuart->getSensorData(OM2JCIEBU_UART::DISCOMFORT_INDEX, &sensorParamData) == OM2JCIEBU_UART::SUCCESS) { + printf("************** eCO2 Attribute Values ***************\r\n"); + printf("Discomfort index :: %d \r\n\r\n", sensorParamData); + printf("******************************************************\r\n"); + } else { + flag = 0; + } + break; + case OM2JCIEBU_UART::HEAT_STROKE: + if(p_om2jcieuart->getSensorData(OM2JCIEBU_UART::HEAT_STROKE, &sensorParamData) == OM2JCIEBU_UART::SUCCESS) { + printf("************** eCO2 Attribute Values ***************\r\n"); + printf("Heat stroke :: %d degC\r\n\r\n", sensorParamData); + printf("******************************************************\r\n"); + } else { + flag = 0; + } + break; + } + printf("\r\n"); + p_om2jcieuart->delay(displayDelay); + } + } else if(parameterChoice == PREVIOUS_MENU_CHOICE) { + break; + } else { + printf("Invalid choice\r\n"); + } + seconds_validate = false; + } +} + +void configureLEDSetting(OM2JCIEBU_UART *p_om2jcieuart) +{ + if(p_om2jcieuart == NULL) { + std::cout << "Null pointer received..." << std::endl; + return; + } + int led_choice = 0; + bool red_scale_validate = false, green_scale_validate = false, blue_scale_validate = false; + unsigned short int red_scale = 0, green_scale = 0, blue_scale = 0; + printf("************** Sensor LED Configuration ***************\r\n"); + printf("Please select a operation for LED\r\n"); + printf("0) Normally OFF\r\n"); + printf("1) Normally ON\r\n"); + printf("2) Temperature value scales\r\n"); + printf("3) Relative humidity value scales\r\n"); + printf("4) Ambient light value scales\r\n"); + printf("5) Barometric pressure value scales\r\n"); + printf("6) Sound noise value scales\r\n"); + printf("7) eTVOC value scales\r\n"); + printf("8) SI vale scales\r\n"); + printf("9) PGA value scales\r\n"); + printf("**********************************************************\r\n"); + while(!(std::cin >> led_choice)) { + std::cin.clear(); //clear bad input flag + std::cin.ignore(std::numeric_limits::max(), '\n'); //discard input + std::cout << "Invalid input; please re-enter.\n"; + } + + if(led_choice == OM2JCIEBU_UART::NORMALLY_ON) { + printf("Please Select a LED color scale\r\n"); + printf("Please enter Red Color scale (scale range 0 to 255)\r\n"); + while(!red_scale_validate) { + cin >> red_scale; + if(!cin.fail() && (cin.peek() == EOF || cin.peek() == '\n') && (red_scale >= 0 && red_scale <= 255)) { + red_scale_validate = true; + } else { + cin.clear(); + cin.ignore(); + cout << "Error, enter an red color scale between 0 and 255!" << endl; + } + } + printf("Please enter Green Color scale(scale range 0 to 255)\r\n"); + while(!green_scale_validate) { + cin >> green_scale; + if(!cin.fail() && (cin.peek() == EOF || cin.peek() == '\n') && (green_scale >= 0 && green_scale <= 255)) { + green_scale_validate = true; + } else { + cin.clear(); + cin.ignore(); + cout << "Error, enter an green color scale between 0 and 255!" << endl; + } + } + printf("Please enter Blue Color scale(scale range 0 to 255)\r\n"); + while(!blue_scale_validate) { + cin >> blue_scale; + if(!cin.fail() && (cin.peek() == EOF || cin.peek() == '\n') && (blue_scale >= 0 && blue_scale <= 255)) { + blue_scale_validate = true; + } else { + cin.clear(); + cin.ignore(); + cout << "Error, enter an blue color scale between 0 and 255!" << endl; + } + } + p_om2jcieuart->configureSensorLedState(OM2JCIEBU_UART::NORMALLY_ON, red_scale, green_scale, blue_scale); + } else { + switch(led_choice) { + case OM2JCIEBU_UART::NORMALLY_OFF: + p_om2jcieuart->configureSensorLedState(OM2JCIEBU_UART::NORMALLY_OFF, 0, 0, 0); + break; + case OM2JCIEBU_UART::TEMP_SACLE: + p_om2jcieuart->configureSensorLedState(OM2JCIEBU_UART::TEMP_SACLE, 0, 0, 0); + break; + case OM2JCIEBU_UART::HUMIDITY_SCALE: + p_om2jcieuart->configureSensorLedState(OM2JCIEBU_UART::HUMIDITY_SCALE, 0, 0, 0); + break; + case OM2JCIEBU_UART::AMBIENT_LIGHT_SCALE: + p_om2jcieuart->configureSensorLedState(OM2JCIEBU_UART::AMBIENT_LIGHT_SCALE, 0, 0, 0); + break; + case OM2JCIEBU_UART::PRESSURE_SCALE: + p_om2jcieuart->configureSensorLedState(OM2JCIEBU_UART::PRESSURE_SCALE, 0, 0, 0); + break; + case OM2JCIEBU_UART::NOISE_SCALE: + p_om2jcieuart->configureSensorLedState(OM2JCIEBU_UART::NOISE_SCALE, 0, 0, 0); + break; + case OM2JCIEBU_UART::ETVOC_SCALE: + p_om2jcieuart->configureSensorLedState(OM2JCIEBU_UART::ETVOC_SCALE, 0, 0, 0); + break; + case OM2JCIEBU_UART::SI_SCALE: + p_om2jcieuart->configureSensorLedState(OM2JCIEBU_UART::SI_SCALE, 0, 0, 0); + break; + case OM2JCIEBU_UART::PGA_SCALE: + p_om2jcieuart->configureSensorLedState(OM2JCIEBU_UART::PGA_SCALE, 0, 0, 0); + break; + default: + std::cout << "Wrong LED scale choice please try again" << std::endl; + } + } +} + +void configureAdvInterval(OM2JCIEBU_UART *p_om2jcieuart) +{ + if(p_om2jcieuart == NULL) { + std::cout << "Null pointer received..." << std::endl; + return; + } + bool millisecond_validate = false; + uint16_t millisecond = 0; + int advertising_mode = 0; + printf("************** Sensor Advertise Configuration ***************\r\n"); + printf("Please enter time interval (in Milliseconds), for changing Advertise interval, between 100 to 10240 milliseconds\r\n"); + while(!millisecond_validate) {//validate millisecond + cin >> millisecond; + if(!cin.fail() && (cin.peek() == EOF || cin.peek() == '\n') && (millisecond >= 100 && millisecond <= 10240)) { + millisecond_validate = true; + } else { + cin.clear(); + cin.ignore(); + cout << "Error, enter an milisecond between 100 and 10240!" << endl; + } + } + printf("Please select an Advertise mode with the selected Advertise interval \r\n"); + printf("1) Sensor data\r\n"); + printf("2) Calculation data\r\n"); + printf("3) Sensor data and Calculation data\r\n"); + printf("4) Sensor flag and Calculation flag\r\n"); + printf("5) Serial number\r\n"); + while(!(std::cin >> advertising_mode)) { + std::cin.clear(); //clear bad input flag + std::cin.ignore(std::numeric_limits::max(), '\n'); //discard input + std::cout << "Invalid input; please re-enter.\n"; + } + switch(advertising_mode) { + case OM2JCIEBU_UART::SENSOR_DATA: + p_om2jcieuart->configureSensorAdvSetting(millisecond, OM2JCIEBU_UART::SENSOR_DATA); + break; + case OM2JCIEBU_UART::ACCELERATION_DATA: + p_om2jcieuart->configureSensorAdvSetting(millisecond, OM2JCIEBU_UART::ACCELERATION_DATA); + break; + case OM2JCIEBU_UART::ACCELERATION_SENSOR_DATA: + p_om2jcieuart->configureSensorAdvSetting(millisecond, OM2JCIEBU_UART::ACCELERATION_SENSOR_DATA); + break; + case OM2JCIEBU_UART::ACCELERATION_SENSOR_FLAG: + p_om2jcieuart->configureSensorAdvSetting(millisecond, OM2JCIEBU_UART::ACCELERATION_SENSOR_FLAG); + break; + case OM2JCIEBU_UART::SERIAL_NUMBER: + p_om2jcieuart->configureSensorAdvSetting(millisecond, OM2JCIEBU_UART::SERIAL_NUMBER); + break; + default: + std::cout << "Invalid choice\n"; + } + printf("**************************************************************\r\n"); +} + +int +main(int argc, char *argv[]) +{ + char *dev_path; + int operation_choice = 0; + if(argc <= 1) { + std::cout << "usage ./a.out /dev/ttyUSB*" << std::endl; + return 0; + } + signal(SIGABRT, sig_handler); + signal(SIGINT, sig_handler); + upm::OM2JCIEBU_UART om2jciebu_uart(argv[1], 115200); + om2jciebu_uart.setMode(8, mraa::UART_PARITY_NONE, 1); + om2jciebu_uart.setFlowControl(false, false); + while(true) { + std::cout << "*************************************************************" << std::endl; + std::cout << "Please choose one option for Omron sensor operation" << std::endl; + std::cout << "1) Display Sensor attriutes" << std::endl; + std::cout << "2) Configure LED setting " << std::endl; + std::cout << "3) Configure advertise setting" << std::endl; + std::cout << "4) Exit" << std::endl; + std::cout << "*************************************************************" << std::endl; + while(!(std::cin >> operation_choice)) { //validate operation choice from user input + std::cin.clear(); //clear bad input flag + std::cin.ignore(std::numeric_limits::max(), '\n'); //discard input + std::cout << "Invalid input; please re-enter.\n"; + } + switch(operation_choice) { + case 1: + getSensorData(&om2jciebu_uart); + break; + case 2: + configureLEDSetting(&om2jciebu_uart); + break; + case 3: + configureAdvInterval(&om2jciebu_uart); + break; + case 4: + std::cout << "Application Exited" << std::endl; + exit(0); + break; + default: + std::cout << "Invalid choice" << std::endl; + } + } +} diff --git a/Omron_2jcie-bu01_usb/upm/src/2jciebu01-usb/2jciebu01.cxx b/Omron_2jcie-bu01_usb/upm/src/2jciebu01-usb/2jciebu01.cxx new file mode 100644 index 00000000..67c68f70 --- /dev/null +++ b/Omron_2jcie-bu01_usb/upm/src/2jciebu01-usb/2jciebu01.cxx @@ -0,0 +1,98 @@ +/* +* Author: Hiroyuki Mino +* Copyright (c) 2019 Omron Electronic Components - Americas +* +* 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 +#include +#include + +#include "2jciebu01.hpp" + +using namespace upm; +using namespace std; + + +void OM2JCIEBU::getAddress(OM2JCIEBU_ATTRIBUTE_T attribute_name, OM2JCIEBU_INTERFACE_T interface, void *attribute_value) +{ + if(attribute_value == NULL) { + std::cout << "Null pointer received..." << std::endl; + return; + } + switch(attribute_name) { + case ALL_PARAM: + case TEMP: + case HUMIDITY: + case AMBIENT_LIGHT: + case PRESSURE: + case NOISE: + case ETVOC: + case ECO2: + case DISCOMFORT_INDEX: + case HEAT_STROKE: + if(interface == USB_TO_UART) //Check for interface + *(uint16_t *)attribute_value = OM2JCIEBU_LIVE_LONG_DATA_READ_ADD_UART; + else + memcpy(attribute_value, OM2JCIEBU_LIVE_LONG_DATA_READ_UUID_BLE, strlen(OM2JCIEBU_LIVE_LONG_DATA_READ_UUID_BLE)); + break; + case LED_CONFIGURE: + if(interface == USB_TO_UART) + *(uint16_t *)attribute_value = OM2JCIEBU_LED_CONFIGUARTION_ADD_UART; + else + memcpy(attribute_value, OM2JCIEBU_LED_CONFIGUARTION_UUID_BLE, strlen(OM2JCIEBU_LED_CONFIGUARTION_UUID_BLE)); + break; + case ADV_CONFIGURE: + if(interface == USB_TO_UART) + *(uint16_t *)attribute_value = OM2JCIEBU_ADV_CONFIGUARTION_ADD_UART; + else + memcpy(attribute_value, OM2JCIEBU_ADV_CONFIGUARTION_UUID_BLE, strlen(OM2JCIEBU_ADV_CONFIGUARTION_UUID_BLE)); + break; + } +} + + +void OM2JCIEBU::delay(int second) +{ + sleep(second); +} + +uint16_t OM2JCIEBU::crc_16(uint8_t *data, int length) +{ + /* calculate crc_16 for payload */ + if(data == NULL) { + std::cout << "Null pointer received..." << std::endl; + return 0; + } + uint16_t crc = OM2JCIEBU_CRC16, l_outeriterator = 0, l_Inneriterator = 0, carrayFlag = 0; + for(l_outeriterator = 0; l_outeriterator < length; l_outeriterator++) { + crc = crc ^ data[l_outeriterator]; + for(l_Inneriterator = 0; l_Inneriterator < 8; l_Inneriterator++) { + carrayFlag = crc & 1; + crc = crc >> 1; + if(carrayFlag == 1) { + crc = crc ^ 0xA001; + } + } + } + return crc; +} + + + diff --git a/Omron_2jcie-bu01_usb/upm/src/2jciebu01-usb/2jciebu01.hpp b/Omron_2jcie-bu01_usb/upm/src/2jciebu01-usb/2jciebu01.hpp new file mode 100644 index 00000000..8797525c --- /dev/null +++ b/Omron_2jcie-bu01_usb/upm/src/2jciebu01-usb/2jciebu01.hpp @@ -0,0 +1,240 @@ +/* +* Author: Hiroyuki Mino +* Copyright (c) 2019 Omron Electronic Components - Americas +* +* 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 +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include + + +/*MACROS and enum */ + + +#define OM2JCIEBU_FLASH_LONG_DATA_READ_ADD_UART 0x500E +#define OM2JCIEBU_LIVE_LONG_DATA_READ_ADD_UART 0x5021 + +#define OM2JCIEBU_LED_CONFIGUARTION_ADD_UART 0x5111 +#define OM2JCIEBU_ADV_CONFIGUARTION_ADD_UART 0x5115 + +#define OM2JCIEBU_LED_CONFIGUARTION_UUID_BLE "ab705111-0a3a-11e8-ba89-0ed5f89f718b" +#define OM2JCIEBU_ADV_CONFIGUARTION_UUID_BLE "ab705115-0a3a-11e8-ba89-0ed5f89f718b" +#define OM2JCIEBU_LIVE_LONG_DATA_READ_UUID_BLE "ab705012-0a3a-11e8-ba89-0ed5f89f718b" + + + +#define OM2JCIEBU_CRC_LENGTH 2 +#define OM2JCIEBU_CRC16 0xFFFF +#define OM2JCIEBU_INTERVAL_UNIT 0.625 + + +/*=========================================================================*/ + +namespace upm +{ +/** + * @brief omron 2JCIEBU01 Environment sensor + * @defgroup 2jciebu01 libupm-2jciebu01 + * @ingroup Omron USB type + */ + +/** + * @library 2jciebu01 + * @sensor 2jciebu01 + * @comname Environment Sensor Module + * @altname Omron Environment sensor USB type + * @type USB + * @man Omron + * @web https://www.components.omron.com/solutions/mems-sensors/environment-sensor + * @con usb + * + * @brief API for the Omron USB type environment Sensor Module using USB to UART interface + * + * It is connected via a UART at 115200 baud. + * + * @snippet 2jciebu01.cxx Interesting + */ +class OM2JCIEBU +{ +public : + typedef enum { + ALL_PARAM, + TEMP, + HUMIDITY, + AMBIENT_LIGHT, + PRESSURE, + NOISE, + ETVOC, + ECO2, + DISCOMFORT_INDEX, + HEAT_STROKE, + LED_CONFIGURE, + ADV_CONFIGURE, + } OM2JCIEBU_ATTRIBUTE_T; + + typedef enum { + BLE, + USB_TO_UART + } OM2JCIEBU_INTERFACE_T; + + typedef enum { + SENSOR_DATA = 1, + ACCELERATION_DATA, + ACCELERATION_SENSOR_DATA, + ACCELERATION_SENSOR_FLAG, + SERIAL_NUMBER + } OM2JCIEBU_ADV_PARAM_T; + + typedef enum { + ERROR_CRC_WRONG = -1, + ERROR_WRONG_COMMAND, + ERROR_WRONG_ADDRESS, + ERROR_WRONG_LENGTH, + ERROR_DATA_RANGE, + ERROR_BUSY, + ERROR_UNKNOWN, + ERROR_CRC_MISMATCH, + FAILURE = 0, + SUCCESS = 1 + } OM2JCIEBU_ERROR_T; + + typedef enum { + NORMALLY_OFF = 0, + NORMALLY_ON, + TEMP_SACLE, + HUMIDITY_SCALE, + AMBIENT_LIGHT_SCALE, + PRESSURE_SCALE, + NOISE_SCALE, + ETVOC_SCALE, + SI_SCALE, + PGA_SCALE + } OM2JCIEBU_LED_SCALE_T; + + typedef struct { + uint8_t sequence_number; + int16_t temperature; + int16_t relative_humidity; + int16_t ambient_light; + int32_t pressure; + int16_t noise; + int16_t eTVOC; + int16_t eCO2; + int16_t discomfort_index; + int16_t heat_stroke; + } __attribute__((packed))om2jciebuData_t; + + /** + * OM2JCIEBU destructor + */ + virtual ~OM2JCIEBU() {} + + /** + * get address or UUID based on attribute name + * + * @param attribute_name attribute name of sensor + * @param interface Interface name of sensor + * @param attribute_value address value and UUID based on attribute name + */ + void getAddress(OM2JCIEBU_ATTRIBUTE_T attribute_name, OM2JCIEBU_INTERFACE_T interface, void *attribute_value); + + /** + * Delay for read sensor data; + * + * @param second second for delay + */ + void delay(int second); + + /** + * Calculate crc-16 from the header + * to the end of the payload. + * + * @param data Packet + * @param length length of packet + * @return 16 bit crc of payload + */ + uint16_t crc_16(uint8_t *data, int length); + + + /** + * Set LED configartion of sensor + * + * @param state state for led configuartion + * @param red value of red + * @param green value of green + * @param blue value of blue + */ + virtual void configureSensorLedState(OM2JCIEBU_LED_SCALE_T state, uint8_t red, uint8_t green, uint8_t blue) = 0; + + /** + * Set Advertise configuration of sensor + * + * @param miliseconds interval for Advertise data + * @param adv_mode Advertise mode + */ + virtual void configureSensorAdvSetting(uint16_t milliseconds, OM2JCIEBU_ADV_PARAM_T adv_mode) = 0; + + + /** + * Calculate and parse sensor data and store into + * Sensor data structure + * + * @param data Packet + * + */ + virtual void parseSensorData(uint8_t *data) = 0; + + /** + * Get omron sensor live data as per attribute name + * + * @param attribute_name Name of attribute + * @param attribute_data Data of attirbute + * @return One of the OM2JCIEBU_ERROR_T values + */ + virtual OM2JCIEBU_ERROR_T getSensorData(OM2JCIEBU_ATTRIBUTE_T attribute_name, void *attribute_data) = 0; + + /** + * Verifies the packet header and indicates it is valid or not + * + * @param pkt Packet to check + * @param len length of packet + * @return One of the OM2JCIEBU_ERROR_T values + */ + + virtual OM2JCIEBU_ERROR_T verifyPacket(uint8_t *pkt, int len) = 0; +}; +} diff --git a/Omron_2jcie-bu01_usb/upm/src/2jciebu01-usb/2jciebu01_usb.cxx b/Omron_2jcie-bu01_usb/upm/src/2jciebu01-usb/2jciebu01_usb.cxx new file mode 100644 index 00000000..2a867a2f --- /dev/null +++ b/Omron_2jcie-bu01_usb/upm/src/2jciebu01-usb/2jciebu01_usb.cxx @@ -0,0 +1,351 @@ +/* +* Author: Hiroyuki Mino +* Copyright (c) 2019 Omron Electronic Components - Americas +* +* 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 +#include +#include + +#include "2jciebu01_usb.hpp" + +using namespace upm; +using namespace std; + +static const int defaultDelay = 1000; // max wait time for read + + +OM2JCIEBU_UART::OM2JCIEBU_UART(std::string uart_raw, int baud) : m_uart(uart_raw) +{ + if(!setupTty(baud)) + throw std::runtime_error(std::string(__FUNCTION__) + + ": failed to set baud rate to " + std::to_string(baud)); +} + +bool OM2JCIEBU_UART::setupTty(uint32_t baud) +{ + return m_uart.setBaudRate(baud) == mraa::SUCCESS; +} + +uint8_t OM2JCIEBU_UART::setMode(int bytesize, mraa::UartParity parity, int stopbits) +{ + return m_uart.setMode(bytesize, parity, stopbits); +} + +uint8_t OM2JCIEBU_UART::setFlowControl(bool xonxoff, bool rtscts) +{ + return m_uart.setFlowcontrol(xonxoff, rtscts); +} + +int OM2JCIEBU_UART::readData(char *buffer, int len) +{ + if(buffer == NULL) { + std::cout << "Null pointer received..." << std::endl; + return FAILURE; + } + if(!m_uart.dataAvailable(defaultDelay)) //time out for read UART data + return 0; + + int rv = m_uart.read(buffer, len); + + //check for UART read fail + if(rv < 0) + throw std::runtime_error(std::string(__FUNCTION__) + + ": Uart::read() failed: " + string(strerror(errno))); + + return rv; +} + +int OM2JCIEBU_UART::writeData(char *buffer, int len) +{ + if(buffer == NULL) { + std::cout << "Null pointer received..." << std::endl; + return FAILURE; + } + int rv = m_uart.write(buffer, len); + + //check for UART write fail + if(rv < 0) + throw std::runtime_error(std::string(__FUNCTION__) + + ": Uart::write() failed: " + + string(strerror(errno))); + //check for UART write fail + if(rv == 0) + throw std::runtime_error(std::string(__FUNCTION__) + + ": Uart::write() failed, no bytes written"); + + return rv; +} + +int OM2JCIEBU_UART::readCmdPacket(OM2JCIEBU_UART::OM2JCIEBU_ATTRIBUTE_T attribute_name) +{ + /* Create a payload as per OMRON uart frame format*/ + uint8_t omPkt[OM2JCIEBU_UART_MAX_PKT_LEN] = {0}; + uint16_t pktLength = 0, crc = 0, pktIndex = 0, address = 0; + + + omPkt[pktIndex++] = OM2JCIEBU_UART_HEADER_START; + omPkt[pktIndex++] = OM2JCIEBU_UART_HEADER_END; + + pktLength = OM2JCIEBU_CRC_LENGTH + OM2JCIEBU_UART_ADDRESS_LENGTH + OM2JCIEBU_UART_COMMAND_LENGHT; + + omPkt[pktIndex++] = pktLength & 0x00FF; + omPkt[pktIndex++] = pktLength >> 8; + + omPkt[pktIndex++] = UART_CMD_READ; + + getAddress(attribute_name, USB_TO_UART, &address); + + omPkt[pktIndex++] = address & 0x00FF; + omPkt[pktIndex++] = address >> 8; + + crc = crc_16(omPkt, pktIndex); + + omPkt[pktIndex++] = crc & 0x00FF; + omPkt[pktIndex++] = crc >> 8; + + return (writeData((char *)omPkt, pktIndex)); +} + +void OM2JCIEBU_UART::configureSensorAdvSetting(uint16_t milliseconds, OM2JCIEBU::OM2JCIEBU_ADV_PARAM_T adv_mode) +{ + + uint8_t adv_config[3] = {0}; + uint16_t interval; + interval = milliseconds / OM2JCIEBU_INTERVAL_UNIT; /*calculate interval which is given by user using interval unit */ + + adv_config[0] = interval & 0x00FF; + adv_config[1] = interval >> 8; + adv_config[2] = adv_mode; + + writeCmdPacket(ADV_CONFIGURE, adv_config, sizeof(adv_config)); +} + +void OM2JCIEBU_UART::configureSensorLedState(OM2JCIEBU::OM2JCIEBU_LED_SCALE_T state, uint8_t red, uint8_t green, uint8_t blue) +{ + uint8_t led_config[5] = {0}; + + led_config[0] = state; + led_config[1] = 0x00; + led_config[2] = red; + led_config[3] = green; + led_config[4] = blue; + + writeCmdPacket(LED_CONFIGURE, led_config, sizeof(led_config)); +} + +int OM2JCIEBU_UART::writeCmdPacket(OM2JCIEBU_UART::OM2JCIEBU_ATTRIBUTE_T attribute_name, uint8_t *data, uint16_t length) +{ + /* Create a frame formate for write a data on UART as per common frame formate*/ + if(data == NULL) { + std::cout << "Null pointer received..." << std::endl; + return FAILURE; + } + uint8_t omPkt[OM2JCIEBU_UART_MAX_PKT_LEN] = {0}; + uint16_t pktLength = 0, crc = 0, pktIndex = 0, l_iterator = 0, address = 0; + + omPkt[pktIndex++] = OM2JCIEBU_UART_HEADER_START; + omPkt[pktIndex++] = OM2JCIEBU_UART_HEADER_END; + + pktLength = OM2JCIEBU_CRC_LENGTH + OM2JCIEBU_UART_ADDRESS_LENGTH + OM2JCIEBU_UART_COMMAND_LENGHT + length; + + omPkt[pktIndex++] = pktLength & 0x00FF; + omPkt[pktIndex++] = pktLength >> 8; + + omPkt[pktIndex++] = UART_CMD_WRITE; + + getAddress(attribute_name, USB_TO_UART, &address); + + omPkt[pktIndex++] = address & 0x00FF; + omPkt[pktIndex++] = address >> 8; + + for(l_iterator = 0; l_iterator < length; l_iterator++) { + omPkt[pktIndex++] = data[l_iterator]; + } + + crc = crc_16(omPkt, pktIndex); + + omPkt[pktIndex++] = crc & 0x00FF; + omPkt[pktIndex++] = crc >> 8; + + return (writeData((char *)omPkt, pktIndex)); +} + +void OM2JCIEBU_UART::getSensorAttribute(OM2JCIEBU_ATTRIBUTE_T attribute_name, void *attributeValue) +{ + /* Assign sensor value attributes to void pointer*/ + if(attributeValue == NULL) { + std::cout << "Null pointer received..." << std::endl; + return; + } + switch(attribute_name) { + case ALL_PARAM: + memcpy(attributeValue, &om2jciebuData_uart, sizeof(om2jciebuData_uart)); + break; + case TEMP: + *(int16_t *) attributeValue = om2jciebuData_uart.temperature; + break; + case HUMIDITY: + *(int16_t *) attributeValue = om2jciebuData_uart.relative_humidity; + break; + case AMBIENT_LIGHT: + *(int16_t *) attributeValue = om2jciebuData_uart.ambient_light; + break; + case PRESSURE: + *(int32_t *) attributeValue = om2jciebuData_uart.pressure; + break; + case NOISE: + *(int16_t *) attributeValue = om2jciebuData_uart.noise; + break; + case ETVOC: + *(int16_t *) attributeValue = om2jciebuData_uart.eTVOC; + break; + case ECO2: + *(int16_t *) attributeValue = om2jciebuData_uart.eCO2; + break; + case DISCOMFORT_INDEX: + *(int16_t *) attributeValue = om2jciebuData_uart.discomfort_index; + break; + case HEAT_STROKE: + *(int16_t *) attributeValue = om2jciebuData_uart.heat_stroke; + break; + case LED_CONFIGURE: + break; + case ADV_CONFIGURE: + break; + } +} + +OM2JCIEBU_UART::OM2JCIEBU_ERROR_T OM2JCIEBU_UART::getSensorData(OM2JCIEBU_ATTRIBUTE_T attribute_name, void *attribute_data) +{ + if(attribute_data == NULL) { + std::cout << "Null pointer received..." << std::endl; + return FAILURE; + } + //create a payload frame for read sensor data + readCmdPacket(attribute_name); + + char buf[OM2JCIEBU_UART_MAX_READ_PKT_LEN]; + uint8_t pkt[OM2JCIEBU_UART_MAX_PKT_LEN]; + int rv; + int8_t pkt_index = 0, idx = 0; + OM2JCIEBU_UART::OM2JCIEBU_ERROR_T verifyResult = FAILURE; + + //read from UART + while(true) { + rv = readData(buf, OM2JCIEBU_UART_MAX_READ_PKT_LEN); + if(rv > 0) { + for(idx = 0; idx < rv; idx++) + pkt[pkt_index++] = buf[idx]; + } else { + verifyResult = verifyPacket(pkt, pkt_index); + if(verifyResult == SUCCESS) { + break; + } else { + return verifyResult; + } + } + } + //calculate a data and store in struct + parseSensorData(pkt); + + //copy data to user provided pointer + getSensorAttribute(attribute_name, attribute_data); + + return verifyResult; +} + +OM2JCIEBU_UART::OM2JCIEBU_ERROR_T OM2JCIEBU_UART::verifyPacket(uint8_t *pkt, int len) +{ + if(pkt == NULL) { + std::cout << "Null pointer received..." << std::endl; + return FAILURE; + } + uint16_t crc = 0; + OM2JCIEBU_UART::OM2JCIEBU_ERROR_T verifyResult = FAILURE; + //Verify a data which is read from UART buffer + if((pkt[OM2JCIEBU_UART_COMMAND_INDEX] & 0xF0) == 0x80) { //Check for error in payload + if(pkt[OM2JCIEBU_UART_COMMAND_ERROR_CODE_INDEX] == ERROR_UART_CRC_WRONG) { + std::cout << "Error CRC wrong" << std::endl; + verifyResult = ERROR_CRC_WRONG; + } else if(pkt[OM2JCIEBU_UART_COMMAND_ERROR_CODE_INDEX] == ERROR_UART_WRONG_COMMAND) { + std::cout << "Error Invalid Command" << std::endl; + verifyResult = ERROR_WRONG_COMMAND; + } else if(pkt[OM2JCIEBU_UART_COMMAND_ERROR_CODE_INDEX] == ERROR_UART_WRONG_ADDRESS) { + std::cout << "Error Invalid Address" << std::endl; + verifyResult = ERROR_WRONG_ADDRESS; + } else if(pkt[OM2JCIEBU_UART_COMMAND_ERROR_CODE_INDEX] == ERROR_UART_WRONG_LENGTH) { + std::cout << "Error Invalid Length" << std::endl; + verifyResult = ERROR_WRONG_LENGTH; + } else if(pkt[OM2JCIEBU_UART_COMMAND_ERROR_CODE_INDEX] == ERROR_UART_DATA_RANGE) { + std::cout << "Error Invalid Data Range" << std::endl; + verifyResult = ERROR_DATA_RANGE; + } else if(pkt[OM2JCIEBU_UART_COMMAND_ERROR_CODE_INDEX] == ERROR_UART_BUSY) { + std::cout << "Uart is BUSY" << std::endl; + verifyResult = ERROR_BUSY; + } + } else if((pkt[OM2JCIEBU_UART_COMMAND_INDEX] & 0xFF) == 0xFF) { //Check for unknow error in UART frame + std::cout << "Invalid reponse" << std::endl; + verifyResult = ERROR_UNKNOWN; + } else { + crc = crc_16(pkt, (len - OM2JCIEBU_CRC_LENGTH)); //Check for CRC which is read from UART frame + if(pkt[len - OM2JCIEBU_CRC_LENGTH] == (crc & 0x00FF) && pkt[len - 1] == crc >> 8) { + verifyResult = SUCCESS; + } else { + std::cout << "Does not match CRC" << std::endl; + verifyResult = ERROR_CRC_MISMATCH; + } + } + return verifyResult; +} + +void OM2JCIEBU_UART::parseSensorData(uint8_t *data) +{ + if(data == NULL) { + std::cout << "Null pointer received..." << std::endl; + return; + } + //Parse data after payload verfication + om2jciebuData_uart.sequence_number = data[7]; + + om2jciebuData_uart.temperature = data[8] | data[9] << 8; + om2jciebuData_uart.temperature = om2jciebuData_uart.temperature / 100; + + om2jciebuData_uart.relative_humidity = data[10] | data[11] << 8; + om2jciebuData_uart.relative_humidity = om2jciebuData_uart.relative_humidity / 100; + + om2jciebuData_uart.ambient_light = data[12] | data[13] << 8; + + om2jciebuData_uart.pressure = data[14] | data[15] << 8 | data[16] << 16 | data[17] << 24; + om2jciebuData_uart.pressure = om2jciebuData_uart.pressure / 1000; + + om2jciebuData_uart.noise = data[18] | data[19] << 8; + om2jciebuData_uart.noise = om2jciebuData_uart.noise / 100; + + om2jciebuData_uart.eTVOC = data[20] | data[21] << 8; + + om2jciebuData_uart.eCO2 = data[22] | data[23] << 8; + + om2jciebuData_uart.discomfort_index = data[24] | data[25] << 8; + om2jciebuData_uart.discomfort_index = om2jciebuData_uart.discomfort_index / 100; + + om2jciebuData_uart.heat_stroke = data[26] | data[27] << 8; + om2jciebuData_uart.heat_stroke = om2jciebuData_uart.heat_stroke / 100; +} diff --git a/Omron_2jcie-bu01_usb/upm/src/2jciebu01-usb/2jciebu01_usb.hpp b/Omron_2jcie-bu01_usb/upm/src/2jciebu01-usb/2jciebu01_usb.hpp new file mode 100644 index 00000000..8a81e7f0 --- /dev/null +++ b/Omron_2jcie-bu01_usb/upm/src/2jciebu01-usb/2jciebu01_usb.hpp @@ -0,0 +1,247 @@ +/* +* +* Author: Hiroyuki Mino +* Copyright (c) 2019 Omron Electronic Components - Americas +* +* 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 "mraa.hpp" +#include "2jciebu01.hpp" + +/*MACROS and enum */ + +// protocol start codes +#define OM2JCIEBU_UART_HEADER_START 0x52 +#define OM2JCIEBU_UART_HEADER_END 0x42 + +#define OM2JCIEBU_UART_MAX_PKT_LEN 256 +#define OM2JCIEBU_UART_MAX_READ_PKT_LEN 10 +#define OM2JCIEBU_UART_COMMAND_LENGHT 1 +#define OM2JCIEBU_UART_ADDRESS_LENGTH 2 +#define OM2JCIEBU_UART_HEADER_LENGTH 2 + +#define OM2JCIEBU_UART_COMMAND_INDEX 0x04 +#define OM2JCIEBU_UART_COMMAND_ERROR_CODE_INDEX 0x07 + + + + + +/*=========================================================================*/ + +namespace upm +{ +/** + * @brief 2JCIEBU01 Environment sensor + * @defgroup 2jciebu01 libupm-2jciebu01_usb + * @ingroup Omron USB type + */ + +/** + * @library libupm-2jciebu01_usb + * @sensor 2jciebu01 + * @comname Environment Sensor Module + * @altname Omron Environment sensor USB type + * @type USB + * @man Omron + * @web https://www.components.omron.com/solutions/mems-sensors/environment-sensor + * @con usb + * + * @brief API for the Omron USB type environment Sensor Module using USB to UART interface + * + * It is connected via a UART at 115200 baud. + * + * @snippet 2jciebu01_usb.cxx Interesting + */ +class OM2JCIEBU_UART : public OM2JCIEBU +{ +public : + + typedef enum { + UART_CMD_READ = 0x01, + UART_CMD_WRITE = 0x02 + } OM2JCIEBU_UART_COMMAND_T; + + + typedef enum { + ERROR_UART_CRC_WRONG = 0x01, + ERROR_UART_WRONG_COMMAND = 0x02, + ERROR_UART_WRONG_ADDRESS = 0x03, + ERROR_UART_WRONG_LENGTH = 0x04, + ERROR_UART_DATA_RANGE = 0x05, + ERROR_UART_BUSY = 0x06, + ERROR_UART_UNKNOWN = 0XFF + } OM2JCIEBU_UART_ERROR_T; + + typedef enum { + PARITY_UART_NONE = 0, + PARITY_UART_EVEN = 1, + PARITY_UART_ODD = 2, + PARITY_UART_MARK = 3, + PARITY_UART_SPACE = 4 + } OM2JCIEBU_UART_PARITY_T; + + /** + * OM2JCIEBU_UART Constructor, takes a string to the path of the serial + * interface that is needed. + * + * @param uart File path (/dev/ttyXXX to uart + * @param baud Desired baud rate + */ + OM2JCIEBU_UART(std::string path, int baud = 115200); + + /** + * Sets up proper tty I/O modes and the baud rate. For this device, + * the default baud rate is 115200. + * + * @param baud Desired baud rate. + * @return True if successful + */ + bool setupTty(uint32_t baud = 115200); + + /** + * Set the transfer mode + * For example setting the mode to 8N1 would be + * "dev.setMode(8,PARITY_NONE , 1)" + * + * @param bytesize data bits + * @param parity Parity bit setting + * @param stopbits stop bits + * + * @return Return success or Failure + */ + uint8_t setMode(int bytesize, mraa::UartParity parity, int stopbits); + + /** + * Set the flowcontrol + * + * @param xonxoff XON/XOFF Software flow control. + * @param rtscts RTS/CTS out of band hardware flow control + * @return Return success or Failure + */ + uint8_t setFlowControl(bool xonxoff, bool rtscts); + + + /** + * Get omron sensor live data as per request + * + * @param attribute_name Name of attribute + * @param attribute_data Data of attirbute + * @return One of the OM2JCIEBU_ERROR_T values + */ + OM2JCIEBU_ERROR_T getSensorData(OM2JCIEBU::OM2JCIEBU_ATTRIBUTE_T attribute_name, void *attribute_data); + + /** + * Set LED configartion of sensor + * + * @param state state for led configuartion + * @param red value of red + * @param green value of green + * @param blue value of blue + */ + void configureSensorLedState(OM2JCIEBU::OM2JCIEBU_LED_SCALE_T state, uint8_t red, uint8_t green, uint8_t blue); + + /** + * Set Advertise interval setting of sensor + * + * @param miliseconds interval for Advertise data + * @param adv_mode Advertise mode + */ + void configureSensorAdvSetting(uint16_t milliseconds, OM2JCIEBU::OM2JCIEBU_ADV_PARAM_T adv_mode); + +private: + + mraa::Uart m_uart; + om2jciebuData_t om2jciebuData_uart; + + /** + * Composes write command packet and Writes the data + * in the buffer to the device + * + * @param attribute_name Attribute name of sensor + * @param data data for write on particular address + * @param length length of data + * @return Number of bytes written + */ + int writeCmdPacket(OM2JCIEBU::OM2JCIEBU_ATTRIBUTE_T attribute_name, uint8_t *data, uint16_t length); + + /** + * Composes read command packet and Writes the data + * in the buffer to the device + * + * @param attribute_name Attribute name of sensor + * @return Number of bytes written + */ + int readCmdPacket(OM2JCIEBU::OM2JCIEBU_ATTRIBUTE_T attribute_name); + + /** + * Get sensor data from global struct. + * + * @param attributeValue Data of attirbute + * + */ + + void getSensorAttribute(OM2JCIEBU::OM2JCIEBU_ATTRIBUTE_T attribute_name, void *attributeValue); + + /** + * Writes the data in the buffer to the device + * + * @param buffer Buffer to hold the data read + * @param len Length of the buffer + * @return Number of bytes written + */ + int writeData(char *buffer, int len); + + /** + * Reads any available data in a user-supplied buffer. Note: the + * call blocks until data is available to be read. Use + * dataAvailable() to determine whether there is data available + * beforehand, to avoid blocking. + * + * @param buffer Buffer to hold the data read + * @param len Length of the buffer + * @return Number of bytes read + */ + int readData(char *buffer, int len); + + /** + * Verifies the packet header and indicates it is valid or not + * + * @param pkt Packet to check + * @param len length of packet + * @return One of the OM2JCIEBU_ERROR_T values + */ + + OM2JCIEBU_ERROR_T verifyPacket(uint8_t *pkt, int len); + + + /** + * Calculate and parse sensor data and store into + * Sensor data structure + * + * @param data Packet + * + */ + void parseSensorData(uint8_t *data); +}; +} diff --git a/Omron_2jcie-bu01_usb/upm/src/2jciebu01-usb/2jciebu01_usb.i b/Omron_2jcie-bu01_usb/upm/src/2jciebu01-usb/2jciebu01_usb.i new file mode 100644 index 00000000..f174f758 --- /dev/null +++ b/Omron_2jcie-bu01_usb/upm/src/2jciebu01-usb/2jciebu01_usb.i @@ -0,0 +1,8 @@ +%include "../common_top.i" + +/* BEGIN Common SWIG syntax ------------------------------------------------- */ +%{ +#include "2jciebu01_usb.hpp" +%} +%include "2jciebu01_usb.hpp" +/* END Common SWIG syntax */ diff --git a/Omron_2jcie-bu01_usb/upm/src/2jciebu01-usb/2jciebu01_usb.json b/Omron_2jcie-bu01_usb/upm/src/2jciebu01-usb/2jciebu01_usb.json new file mode 100644 index 00000000..59bdd5fc --- /dev/null +++ b/Omron_2jcie-bu01_usb/upm/src/2jciebu01-usb/2jciebu01_usb.json @@ -0,0 +1,35 @@ +{ + "Library": "2jciebu01_usb", + "Description": "Omron USB type enviroment sensor", + "Sensor Class": { + "OM2JCIEBU_UART": { + "Name": "API for 2JCIEBU01 Sensor Module using USB to UART interface", + "Description": "This is the UPM Module for the Omron Enviroment Sensor Module using USB to UART interface.", + "Aliases": [""], + "Categories": ["USB"], + "Connections": ["uart"], + "Project Type": ["sensor"], + "Manufacturers": ["Omron"], + "Image": "", + "Examples": { + "C++": ["omron2jciebu01_usb.cxx"] + }, + "Specifications": { + "Baud Rate": { + "unit" : "bps", + "default": 115200 + } + }, + "Platforms": { + "Intel Edison": { + "Notes": ["Might need USB type omron enviroment sensor"] + } + }, + "Urls": { + "Product Pages": ["https://www.components.omron.com/solutions/mems-sensors/environment-sensor"], + "Datasheets": ["https://omronfs.omron.com/en_US/ecb/products/pdf/A279-E1-01.pdf"] + } + } + } +} + diff --git a/Omron_2jcie-bu01_usb/upm/src/2jciebu01-usb/CMakeLists.txt b/Omron_2jcie-bu01_usb/upm/src/2jciebu01-usb/CMakeLists.txt new file mode 100644 index 00000000..0d79831d --- /dev/null +++ b/Omron_2jcie-bu01_usb/upm/src/2jciebu01-usb/CMakeLists.txt @@ -0,0 +1,5 @@ +set (libname "2jciebu01_usb") +set (libdescription "Omron Environment Sensor") +set (module_src ${libname}.cxx "2jciebu01.cxx") +set (module_hpp ${libname}.hpp "2jciebu01.hpp") +upm_module_init(mraa utilities-c) diff --git a/Omron_2jcie-bu01_usb/upm/src/CMakeLists.txt b/Omron_2jcie-bu01_usb/upm/src/CMakeLists.txt new file mode 100644 index 00000000..8ddff1a9 --- /dev/null +++ b/Omron_2jcie-bu01_usb/upm/src/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(2jciebu01-usb) +file(COPY 2jciebu01.hpp DESTINATION /usr/local/include/)