mirror of
				https://github.com/eclipse/upm.git
				synced 2025-10-31 07:04:14 +03:00 
			
		
		
		
	2jciebu01: put new sources in right location
Signed-off-by: Mihai Tudor Panu <mihai.tudor.panu@intel.com>
This commit is contained in:
		
							
								
								
									
										500
									
								
								src/2jciebu01-ble/2jciebu01_ble.cxx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										500
									
								
								src/2jciebu01-ble/2jciebu01_ble.cxx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,500 @@ | ||||
| /* | ||||
| * Author: Hiroyuki Mino <omronsupportupm@omron.com> | ||||
| * 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 "2jciebu01_ble.hpp" | ||||
|  | ||||
| using namespace upm; | ||||
| using namespace std; | ||||
|  | ||||
|  | ||||
|  | ||||
| OM2JCIEBU_BLE::OM2JCIEBU_BLE(std::string ble_address) | ||||
| { | ||||
|     //initializing tinyB  | ||||
|     try { | ||||
|         bleManager = BluetoothManager::get_bluetooth_manager(); | ||||
|     } catch(const std::runtime_error& e) { | ||||
|         std::cerr << "Error while initializing libtinyb: " << e.what() << std::endl; | ||||
|         exit(1); | ||||
|     } | ||||
|     OM2JCIEBU_BLE::bleMACaddress = ble_address; | ||||
|  | ||||
| } | ||||
|  | ||||
| bool OM2JCIEBU_BLE::connectBleDevice(std::string ble_address) | ||||
| { | ||||
|      | ||||
|     bool ret; | ||||
|     //Start BLE discovery | ||||
|     if(startBleDiscovery()) { | ||||
|         std::cout << "Searching for Sensor...\r\n"; | ||||
|         for(int i = 0; i < OM2JCIEBU_BLE_DISCOVERY_RETRY ; ++i) { | ||||
|             auto list = bleManager->get_devices(); | ||||
|  | ||||
|             for(auto it = list.begin(); it != list.end(); ++it) { | ||||
| #if DEBUG_LOG | ||||
|                 std::cout << "Class = " << (*it)->get_class_name() << " "; | ||||
|                 std::cout << "Path = " << (*it)->get_object_path() << " "; | ||||
|                 std::cout << "Name = " << (*it)->get_name() << " "; | ||||
|                 std::cout << "Connected = " << (*it)->get_connected() << " "; | ||||
|                 std::cout << std::endl; | ||||
| #endif | ||||
|  | ||||
|                 /* Search for the device with the address given as a parameter to the program */ | ||||
|                 if((*it)->get_address() == ble_address) { | ||||
|                     bleSensorTag = (*it).release(); | ||||
|                 } | ||||
|             } | ||||
|             /* Free the list of devices and stop if the device was found */ | ||||
|             if(bleSensorTag != nullptr) { | ||||
|                 std::cout << "Omron Sensor found  : " << ble_address << std::endl; | ||||
|                 break; | ||||
|             } | ||||
|             std::this_thread::sleep_for(std::chrono::seconds(4)); | ||||
|         } | ||||
|     } | ||||
|     ret = stopBleDiscovery(); | ||||
|     std::cout << "Stopped Ble Discovery = " << (ret ? "true" : "false") << std::endl; | ||||
|     if(bleSensorTag == nullptr) { | ||||
|         throw std::runtime_error(std::string(__FUNCTION__) + | ||||
|                                  ": Could not find device " + ble_address); | ||||
|     } | ||||
|     if(bleSensorTag->connect()) { | ||||
|         is_BleConnected = true; | ||||
|     } | ||||
|     return is_BleConnected; | ||||
| } | ||||
|  | ||||
| bool OM2JCIEBU_BLE::removeBleDevice() | ||||
| { | ||||
|     if(is_BleConnected) { //disconnect with device if connected | ||||
|         if(bleSensorTag->disconnect()) { | ||||
|             is_BleConnected = false; | ||||
|         } | ||||
|     } | ||||
|     return is_BleConnected; | ||||
| } | ||||
|  | ||||
| bool OM2JCIEBU_BLE::startBleDiscovery() | ||||
| { | ||||
|     return bleManager->start_discovery(); | ||||
| } | ||||
|  | ||||
| bool OM2JCIEBU_BLE::stopBleDiscovery() | ||||
| { | ||||
|     return bleManager->stop_discovery(); | ||||
| } | ||||
|  | ||||
| bool OM2JCIEBU_BLE::writePacket(OM2JCIEBU::OM2JCIEBU_ATTRIBUTE_T attribute_name, const std::vector<unsigned char> &arg_value) | ||||
| { | ||||
|     if(!(is_BleConnected)) { //Connect with device if not connected | ||||
|         if(!(connectBleDevice(OM2JCIEBU_BLE::bleMACaddress))) { | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
|     const char *cptr = (const char *)malloc(MAX_UUID_SIZE); | ||||
|     if(cptr == NULL) { | ||||
|         printf("Error. Allocation was unsuccessful. \r\n"); | ||||
|         return false; | ||||
|     } | ||||
|     memset((void *)cptr, 0, 64); | ||||
|     getAddress(attribute_name, BLE, (void *)cptr); | ||||
|     std::string uuid = ((const char *)cptr); | ||||
|     free((void *)cptr); | ||||
|     uint16_t getServiceRetryCount = 0; | ||||
|     while(true) { | ||||
|         auto list = bleSensorTag->get_services(); | ||||
|         //check for service list is empty or not | ||||
|         if(list.empty()) { | ||||
|             std::cout << "get services list empty " << std::endl; | ||||
|             getServiceRetryCount++; | ||||
|             if(getServiceRetryCount == OM2JCIEBU_BLE_DISCOVERY_RETRY) { | ||||
|                 getServiceRetryCount = 0; | ||||
|                 removeBleDevice(); | ||||
|                 throw std::runtime_error(std::string(__FUNCTION__) + | ||||
|                                          ": Could not find services "); | ||||
|             } | ||||
|             sleep(1); | ||||
|             continue; | ||||
|         } | ||||
|         for(auto it = list.begin(); it != list.end(); ++it) { | ||||
| #if DEBUG_LOG | ||||
|             std::cout << "Class = " << (*it)->get_class_name() << " "; | ||||
|             std::cout << "Path = " << (*it)->get_object_path() << " "; | ||||
|             std::cout << "UUID = " << (*it)->get_uuid() << " "; | ||||
|             std::cout << "Device = " << (*it)->get_device().get_object_path() << " "; | ||||
|             std::cout << std::endl; | ||||
| #endif | ||||
|  | ||||
|             /* Search for the LIVE sensor data service, by UUID */ | ||||
|             if((*it)->get_uuid() == OM2JCIEBU_BLE_LED_AND_ADV_CONFIGUARTION_SERVICE) { | ||||
|                 bleService = (*it).release(); | ||||
|             } | ||||
|         } | ||||
|         break; | ||||
|     } | ||||
|     if(bleService != nullptr) { | ||||
|         auto charList = bleService->get_characteristics(); | ||||
|         std::cout << "Discovered characteristics: " <<  uuid  << std::endl; | ||||
|         for(auto it = charList.begin(); it != charList.end(); ++it) { | ||||
| #if DEBUG_LOG | ||||
|             std::cout << "Class = " << (*it)->get_class_name() << " "; | ||||
|             std::cout << "Path = " << (*it)->get_object_path() << " "; | ||||
|             std::cout << "UUID = " << (*it)->get_uuid() << " "; | ||||
|             std::cout << "Service = " << (*it)->get_service().get_object_path() << " "; | ||||
|             std::cout << std::endl; | ||||
| #endif | ||||
|  | ||||
|             if((*it)->get_uuid() == uuid) { | ||||
|                 bleSensorChar = (*it).release(); | ||||
|             } | ||||
|         } | ||||
|     } else { | ||||
|         //If not find any sevice then disconnect BLE device | ||||
|         removeBleDevice(); | ||||
|         throw std::runtime_error(std::string(__FUNCTION__) + | ||||
|                                  ": Could not find Service "); | ||||
|     } | ||||
|     if(bleSensorChar == nullptr) { | ||||
|         //If not find any characteristics then disconnect BLE device | ||||
|         removeBleDevice(); | ||||
|         throw std::runtime_error(std::string(__FUNCTION__) + | ||||
|                                  ": Could not find characteristics "); | ||||
|     } | ||||
|     bool ret = bleSensorChar->write_value(arg_value, 0);  | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| OM2JCIEBU_BLE::OM2JCIEBU_ERROR_T OM2JCIEBU_BLE::getDiscoveredServices(OM2JCIEBU::OM2JCIEBU_ATTRIBUTE_T attribute_name) | ||||
| { | ||||
|     if(!(is_BleConnected)) { //Connect with device if not connected | ||||
|         if(!(connectBleDevice(OM2JCIEBU_BLE::bleMACaddress))) { | ||||
|             return FAILURE; | ||||
|         } | ||||
|     } | ||||
|     short int getServiceRetryCount = 0; | ||||
|     const char *cptr = (const char *)malloc(MAX_UUID_SIZE); | ||||
|     if(cptr == NULL) { | ||||
|         printf("Error. Allocation was unsuccessful. \r\n"); | ||||
|         return FAILURE; | ||||
|     } | ||||
|     memset((void *)cptr, 0, MAX_UUID_SIZE); | ||||
|     getAddress(attribute_name, BLE, (void *)cptr); | ||||
|     std::string uuid = ((const char *)cptr); | ||||
|     free((void *)cptr); | ||||
|     //read services from connected BLE device | ||||
|     while(true) { | ||||
|         auto list = bleSensorTag->get_services(); | ||||
|         if(list.empty()) { | ||||
|             std::cout << "get services list empty " << std::endl; | ||||
|             getServiceRetryCount++; | ||||
|             if(getServiceRetryCount == OM2JCIEBU_BLE_DISCOVERY_RETRY) { | ||||
|                 getServiceRetryCount = 0; | ||||
|                 removeBleDevice(); | ||||
|                 throw std::runtime_error(std::string(__FUNCTION__) + | ||||
|                                          ": Not Found any service "); | ||||
|             } | ||||
|             sleep(1); | ||||
|             continue; | ||||
|         } | ||||
|         for(auto it = list.begin(); it != list.end(); ++it) { | ||||
| #if DEBUG_LOG | ||||
|             std::cout << "Class = " << (*it)->get_class_name() << " "; | ||||
|             std::cout << "Path = " << (*it)->get_object_path() << " "; | ||||
|             std::cout << "UUID = " << (*it)->get_uuid() << " "; | ||||
|             std::cout << "Device = " << (*it)->get_device().get_object_path() << " "; | ||||
|             std::cout << std::endl; | ||||
| #endif | ||||
|             //check for service  | ||||
|             if((*it)->get_uuid() == OM2JCIEBU_BLE_LIVE_SENSOR_DATA_SERVICE) { | ||||
|                 bleService = (*it).release(); | ||||
|             } | ||||
|         } | ||||
|         break; | ||||
|     } | ||||
|     if(bleService != nullptr) { | ||||
|         auto charList = bleService->get_characteristics(); | ||||
|         std::cout << "Discovered characteristics: " << uuid << std::endl; | ||||
|         for(auto it = charList.begin(); it != charList.end(); ++it) { | ||||
| #if DEBUG_LOG | ||||
|             std::cout << "Class = " << (*it)->get_class_name() << " "; | ||||
|             std::cout << "Path = " << (*it)->get_object_path() << " "; | ||||
|             std::cout << "UUID = " << (*it)->get_uuid() << " "; | ||||
|             std::cout << "Service = " << (*it)->get_service().get_object_path() << " "; | ||||
|             std::cout << std::endl; | ||||
| #endif | ||||
|             //compare UUID  | ||||
|             if((*it)->get_uuid() == uuid) { | ||||
|                 bleSensorChar = (*it).release(); | ||||
|                 return SUCCESS; | ||||
|             } | ||||
|         } | ||||
|     } else { | ||||
|         //If not find any sevice then disconnect BLE device | ||||
|         removeBleDevice(); | ||||
|         throw std::runtime_error(std::string(__FUNCTION__) + | ||||
|                                  ": Could not find characteristics "); | ||||
|     } | ||||
|     if(bleSensorChar == nullptr) { | ||||
|         //If not find any characteristics then disconnect BLE device | ||||
|         removeBleDevice(); | ||||
|         throw std::runtime_error(std::string(__FUNCTION__) + | ||||
|                                  ": Could not find characteristics "); | ||||
|     } | ||||
|     return FAILURE; | ||||
| } | ||||
|  | ||||
|  | ||||
| OM2JCIEBU_BLE::OM2JCIEBU_ERROR_T OM2JCIEBU_BLE::getSensorData(OM2JCIEBU::OM2JCIEBU_ATTRIBUTE_T attribute_name, void *attribute_data) | ||||
| { | ||||
|     if(attribute_data == NULL) { | ||||
|         std::cout << "Null pointer received..." << std::endl; | ||||
|         return FAILURE; | ||||
|     } | ||||
|     unsigned char *data; | ||||
|     OM2JCIEBU_BLE::OM2JCIEBU_ERROR_T verifyResult = FAILURE; | ||||
|     //Read raw data from connected BLE device based on characteristics | ||||
|     std::vector<unsigned char> response = bleSensorChar->read_value(); | ||||
|     unsigned int size = response.size(); | ||||
|     if(size > 0) { | ||||
|         data = response.data(); | ||||
| #if DEBUG_LOG | ||||
|         std::cout << "Raw data=["; | ||||
|         for(unsigned i = 0; i < response.size(); i++) | ||||
|             std::cout << std::hex << static_cast<int>(data[i]) << ", "; | ||||
|         std::cout << "] "; | ||||
|         std::cout << "" << std::endl; | ||||
| #endif | ||||
|         //parse a data which is read from connected device | ||||
|         parseSensorData(data); | ||||
|         //Get data from structer | ||||
|         getSensorAttribute(attribute_name, attribute_data); | ||||
|         verifyResult = SUCCESS; | ||||
|     } | ||||
|     return verifyResult; | ||||
| } | ||||
|  | ||||
| OM2JCIEBU_BLE::OM2JCIEBU_ERROR_T OM2JCIEBU_BLE::getAdvSensorData(OM2JCIEBU::OM2JCIEBU_ATTRIBUTE_T attribute_name, void *attribute_data) | ||||
| { | ||||
|     if(attribute_data == NULL) { | ||||
|         std::cout << "Null pointer received..." << std::endl; | ||||
|         return FAILURE; | ||||
|     } | ||||
|     uint8_t advSensordata[MAX_SENSOR_DATA_SIZE] = {0}; | ||||
|     int advDataindex = 0; | ||||
|     OM2JCIEBU_BLE::OM2JCIEBU_ERROR_T verifyResult = FAILURE; | ||||
|     if(is_BleConnected) { //disconnect with device if connected | ||||
|         removeBleDevice(); | ||||
|         is_BleConnected = false; | ||||
|     } | ||||
|  | ||||
|     if(startBleDiscovery()) { | ||||
|         auto list = bleManager->get_devices(); | ||||
|  | ||||
|         for(auto it = list.begin(); it != list.end(); ++it) { | ||||
| 			//read manufacturer data | ||||
|             auto mfg = (*it)->get_manufacturer_data(); | ||||
|             if(!mfg.empty()) { | ||||
|                 //read manufacturer data for particular MAC address which is given by user | ||||
|                 if((*it)->get_address() == bleMACaddress) { | ||||
| #if DEBUG_LOG | ||||
|                     std::cout << "MFG" << std::endl; | ||||
|                     for(auto it : mfg) { | ||||
|                         std::cout << it.second.size() << std::endl; | ||||
|                         std::cout << "\t" << it.first << " = [ "; | ||||
|                         for(auto arr_it : it.second) { | ||||
|                             std::cout << std::hex << (int) arr_it << ", "; | ||||
|                         } | ||||
|                         std::cout << "]" << std::endl; | ||||
|                     } | ||||
| #endif | ||||
|                     //store in buffer for verify data and parsing  | ||||
|                     for(auto it : mfg) { | ||||
|                         advSensordata[advDataindex++] = it.first; | ||||
|                         advSensordata[advDataindex++] = it.first >> 8; | ||||
|                         for(auto arr_it : it.second) { | ||||
|                             advSensordata[advDataindex++] = arr_it; | ||||
|                         } | ||||
|                     } | ||||
|                     //verfiy a packet | ||||
|                     verifyResult = verifyPacket(advSensordata, advDataindex); | ||||
|                     if(verifyResult == SUCCESS) { | ||||
|                         parseAdvSensorData(advSensordata); | ||||
|                         getSensorAttribute(attribute_name, attribute_data); | ||||
|                         advDataindex = 0; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     return verifyResult; | ||||
| } | ||||
|  | ||||
| void OM2JCIEBU_BLE::getSensorAttribute(OM2JCIEBU::OM2JCIEBU_ATTRIBUTE_T attribute_name, void *attributeValue) | ||||
| { | ||||
|     if(attributeValue == NULL) { | ||||
|         std::cout << "Null pointer received..." << std::endl; | ||||
|         return; | ||||
|     } | ||||
|     switch(attribute_name) { | ||||
|         case ALL_PARAM: | ||||
|             memcpy(attributeValue, &om2jciebuData_ble, sizeof(om2jciebuData_ble)); | ||||
|             break; | ||||
|         case TEMP: | ||||
|             *(int16_t *) attributeValue = om2jciebuData_ble.temperature; | ||||
|             break; | ||||
|         case HUMIDITY: | ||||
|             *(int16_t *) attributeValue = om2jciebuData_ble.relative_humidity; | ||||
|             break; | ||||
|         case AMBIENT_LIGHT: | ||||
|             *(int16_t *) attributeValue = om2jciebuData_ble.ambient_light; | ||||
|             break; | ||||
|         case PRESSURE: | ||||
|             *(int32_t *) attributeValue = om2jciebuData_ble.pressure; | ||||
|             break; | ||||
|         case NOISE: | ||||
|             *(int16_t *) attributeValue = om2jciebuData_ble.noise; | ||||
|             break; | ||||
|         case ETVOC: | ||||
|             *(int16_t *) attributeValue = om2jciebuData_ble.eTVOC; | ||||
|             break; | ||||
|         case ECO2: | ||||
|             *(int16_t *) attributeValue = om2jciebuData_ble.eCO2; | ||||
|             break; | ||||
|         case DISCOMFORT_INDEX: | ||||
|             break; | ||||
|         case HEAT_STROKE: | ||||
|             break; | ||||
|         case LED_CONFIGURE: | ||||
|             break; | ||||
|         case ADV_CONFIGURE: | ||||
|             break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| OM2JCIEBU_BLE::OM2JCIEBU_ERROR_T OM2JCIEBU_BLE::verifyPacket(uint8_t *pkt, int len) | ||||
| { | ||||
|     if(pkt == NULL) { | ||||
|         std::cout << "Null pointer received..." << std::endl; | ||||
|         return FAILURE; | ||||
|     } | ||||
|     OM2JCIEBU_BLE::OM2JCIEBU_ERROR_T verifyResult = FAILURE; | ||||
|     if(pkt[OM2JCIEBU_BLE_COM_ID_INDEX] == 0xD5) { //Check for Omron company ID | ||||
|         if(pkt[OM2JCIEBU_BLE_COM_ID_INDEX + 1] == 0x02) { | ||||
|             if(pkt[OM2JCIEBU_BLE_DATA_TYPE_INDEX] == 0x01) { // Check for sensor data type | ||||
|                 verifyResult = SUCCESS; | ||||
|             } else { | ||||
|                 printf("Unable to get sensor data in advertisement packet,Please check advertisement setting\r\n"); | ||||
|                 verifyResult = ERROR_UNKNOWN ; | ||||
|             } | ||||
|         } | ||||
|     } else { | ||||
|         printf("Unable to get sensor data in advertisement packet,Please check advertisement setting\r\n"); | ||||
|         verifyResult = ERROR_UNKNOWN ; | ||||
|     } | ||||
|     return verifyResult; | ||||
| } | ||||
|  | ||||
| void OM2JCIEBU_BLE::configureSensorLedState(OM2JCIEBU::OM2JCIEBU_LED_SCALE_T state, uint8_t red, uint8_t green, uint8_t blue) | ||||
| { | ||||
|     std::vector<unsigned char> led_scale; | ||||
|  | ||||
|     led_scale.push_back(state); | ||||
|     led_scale.push_back(0x00); | ||||
|     led_scale.push_back(red); | ||||
|     led_scale.push_back(green); | ||||
|     led_scale.push_back(blue); | ||||
|  | ||||
|     writePacket(LED_CONFIGURE, led_scale); | ||||
| } | ||||
|  | ||||
| void OM2JCIEBU_BLE::configureSensorAdvSetting(uint16_t milliseconds, OM2JCIEBU::OM2JCIEBU_ADV_PARAM_T adv_mode) | ||||
| { | ||||
|     std::vector<unsigned char> advSetting; | ||||
|     uint16_t interval = 0; | ||||
|     interval = milliseconds / OM2JCIEBU_INTERVAL_UNIT;/*calculate interval which is given by user using interval unit */ | ||||
|  | ||||
|     advSetting.push_back(interval & 0x00FF); | ||||
|     advSetting.push_back(interval >> 8); | ||||
|     advSetting.push_back(adv_mode); | ||||
|  | ||||
|     writePacket(ADV_CONFIGURE, advSetting); | ||||
| } | ||||
|  | ||||
| void OM2JCIEBU_BLE::parseSensorData(uint8_t *data) | ||||
| { | ||||
| 	/* pasre and calculate sensor data and store in sensor data struct*/ | ||||
|     if(data == NULL) { | ||||
|         std::cout << "Null pointer received..." << std::endl; | ||||
|         return; | ||||
|     } | ||||
|     om2jciebuData_ble.sequence_number = data[0]; | ||||
|  | ||||
|     om2jciebuData_ble.temperature = data[1] | data[2] << 8; | ||||
|     om2jciebuData_ble.temperature = om2jciebuData_ble.temperature / 100; | ||||
|  | ||||
|     om2jciebuData_ble.relative_humidity = data[3] | data[4] << 8; | ||||
|     om2jciebuData_ble.relative_humidity = om2jciebuData_ble.relative_humidity / 100; | ||||
|  | ||||
|     om2jciebuData_ble.ambient_light = data[5] | data[6] << 8; | ||||
|  | ||||
|     om2jciebuData_ble.pressure = data[7] | data[8] << 8 | data[9] << 16 | data[10] << 24; | ||||
|     om2jciebuData_ble.pressure = om2jciebuData_ble.pressure / 1000; | ||||
|  | ||||
|     om2jciebuData_ble.noise = data[11] | data[12] << 8; | ||||
|     om2jciebuData_ble.noise = om2jciebuData_ble.noise / 100; | ||||
|  | ||||
|     om2jciebuData_ble.eTVOC = data[13] | data[14] << 8; | ||||
|  | ||||
|     om2jciebuData_ble.eCO2 = data[15] | data[16] << 8; | ||||
| } | ||||
|  | ||||
| void OM2JCIEBU_BLE::parseAdvSensorData(uint8_t *data) | ||||
| { | ||||
| 	/* pasre and calculate Advertisement data and store in sensor data struct*/ | ||||
|     if(data == NULL) { | ||||
|         std::cout << "Null pointer received..." << std::endl; | ||||
|         return; | ||||
|     } | ||||
|     om2jciebuData_ble.sequence_number = data[3]; | ||||
|  | ||||
|     om2jciebuData_ble.temperature = data[4] | data[5] << 8; | ||||
|     om2jciebuData_ble.temperature = om2jciebuData_ble.temperature / 100; | ||||
|  | ||||
|     om2jciebuData_ble.relative_humidity = data[6] | data[7] << 8; | ||||
|     om2jciebuData_ble.relative_humidity = om2jciebuData_ble.relative_humidity / 100; | ||||
|  | ||||
|     om2jciebuData_ble.ambient_light = data[8] | data[9] << 8; | ||||
|  | ||||
|     om2jciebuData_ble.pressure = data[10] | data[11] << 8 | data[12] << 16 | data[13] << 24; | ||||
|     om2jciebuData_ble.pressure = om2jciebuData_ble.pressure / 1000; | ||||
|  | ||||
|     om2jciebuData_ble.noise = data[14] | data[15] << 8; | ||||
|     om2jciebuData_ble.noise = om2jciebuData_ble.noise / 100; | ||||
|  | ||||
|     om2jciebuData_ble.eTVOC = data[16] | data[17] << 8; | ||||
|  | ||||
|     om2jciebuData_ble.eCO2 = data[18] | data[19] << 8; | ||||
| } | ||||
|  | ||||
|  | ||||
							
								
								
									
										230
									
								
								src/2jciebu01-ble/2jciebu01_ble.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										230
									
								
								src/2jciebu01-ble/2jciebu01_ble.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,230 @@ | ||||
| /* | ||||
| * | ||||
| * Author: Hiroyuki Mino <omronsupportupm@omron.com> | ||||
| * 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 <tinyb.hpp> | ||||
| #include <iostream> | ||||
| #include <string> | ||||
| #include <stdexcept> | ||||
| #include <vector> | ||||
| #include <thread> | ||||
| #include <atomic> | ||||
| #include <csignal> | ||||
| #include "../2jciebu01.hpp" | ||||
|  | ||||
| /*MACROS and enum */ | ||||
|  | ||||
|  | ||||
| #define OM2JCIEBU_BLE_DISCOVERY_RETRY                      15 | ||||
| #define OM2JCIEBU_BLE_LED_AND_ADV_CONFIGUARTION_SERVICE    "ab705110-0a3a-11e8-ba89-0ed5f89f718b" | ||||
| #define OM2JCIEBU_BLE_LIVE_SENSOR_DATA_SERVICE             "ab705010-0a3a-11e8-ba89-0ed5f89f718b" | ||||
|  | ||||
| #define OM2JCIEBU_BLE_COM_ID_INDEX                         0x00 | ||||
| #define OM2JCIEBU_BLE_DATA_TYPE_INDEX                      0x02 | ||||
|  | ||||
| #define VERIFY_PACKET                                      0 | ||||
| #define DEBUG_LOG                                          0 | ||||
| #define MAX_UUID_SIZE                                      64 | ||||
| #define MAX_SENSOR_DATA_SIZE                               64 | ||||
|  | ||||
|  | ||||
| /*=========================================================================*/ | ||||
|  | ||||
| namespace upm | ||||
| { | ||||
| /** | ||||
|   * @brief 2JCIEBU01 Environment sensor | ||||
|   * @defgroup 2jciebu01 libupm-2jciebu01_ble | ||||
|   * @ingroup Omron USB type | ||||
|   */ | ||||
|  | ||||
| /** | ||||
|  * @library libupm-2jciebu01_ble | ||||
|  * @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 ble | ||||
|  * | ||||
|  * @brief API for the Omron USB type environment Sensor Module using BLE interface | ||||
|  * | ||||
|  * It is connected via a BLE Interface | ||||
|  * | ||||
|  * @snippet 2jciebu01_ble.cxx Interesting | ||||
|  */ | ||||
| class OM2JCIEBU_BLE : public OM2JCIEBU | ||||
| { | ||||
| public : | ||||
|  | ||||
|     /** | ||||
|     * OM2JCIEBU_BLE Constructor, takes the device address as | ||||
|     * an argument | ||||
|     * | ||||
|     * @param device MAC address of Omron Environment Sensor | ||||
|     */ | ||||
|     OM2JCIEBU_BLE(std::string ble_address); | ||||
|  | ||||
|  | ||||
|     /** | ||||
|     * Get discovery service from Connetced BLE device | ||||
|     * | ||||
|     * @param attribute_name  attribute name of sensor | ||||
|     * @return OM2JCIEBU_ERROR_T | ||||
|     */ | ||||
|     OM2JCIEBU_ERROR_T getDiscoveredServices(OM2JCIEBU::OM2JCIEBU_ATTRIBUTE_T attribute_name); | ||||
|  | ||||
|     /** | ||||
|      * Get omron sensor live data as per request uisng 0x5012 UUID | ||||
|      * | ||||
|      * @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); | ||||
|  | ||||
|     /** | ||||
|      * Get omron sensor live data based on advertise payload | ||||
|      * | ||||
|      * @param attribute_name   Name of attribute | ||||
|      * @param attribute_data   Data of attirbute | ||||
|      * @return One of the OM2JCIEBU_ERROR_T values | ||||
|      */ | ||||
|     OM2JCIEBU_ERROR_T getAdvSensorData(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); | ||||
|  | ||||
|     /** | ||||
|      * Disconnect BLE Device | ||||
|      * | ||||
|      * @return Return success or Failure | ||||
|      * | ||||
|      */ | ||||
|     bool removeBleDevice(); | ||||
|  | ||||
| private: | ||||
|     BluetoothManager *bleManager = nullptr; | ||||
|     BluetoothDevice  *bleSensorTag = nullptr; | ||||
|     BluetoothGattCharacteristic *bleSensorChar = nullptr; | ||||
|     BluetoothGattService *bleService = nullptr; | ||||
|     om2jciebuData_t om2jciebuData_ble; | ||||
|     std::string bleMACaddress; | ||||
|     bool is_BleConnected = false; | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      *connect BLE Device | ||||
|      * | ||||
|      * @param device_address  BLE deivce adddress | ||||
|      * | ||||
|      * @return Return success or Failure | ||||
|      */ | ||||
|     bool connectBleDevice(std::string ble_address); | ||||
|  | ||||
|     /** | ||||
|      * Start BLE Discovery | ||||
|      * | ||||
|      * @return Return success or Failure | ||||
|      */ | ||||
|     bool startBleDiscovery(); | ||||
|  | ||||
|     /** | ||||
|      * Stop BLE Discovery | ||||
|      * | ||||
|      * @return Return success or Failure | ||||
|      */ | ||||
|     bool stopBleDiscovery(); | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Get sensor data from global struct. | ||||
|      * | ||||
|      * @param attribute_name   attribute_name of sensor data | ||||
|      * @param attributeValue   Data of attirbute | ||||
|      */ | ||||
|  | ||||
|     void getSensorAttribute(OM2JCIEBU::OM2JCIEBU_ATTRIBUTE_T attribute_name, void *attributeValue); | ||||
|  | ||||
|     /** | ||||
|      * Verifies the packet header and indicates its 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 advertise sensor data and store into | ||||
|     * structure | ||||
|     * | ||||
|     * @param data   Packet | ||||
|     * | ||||
|     */ | ||||
|     void parseAdvSensorData(uint8_t *data); | ||||
|  | ||||
|     /** | ||||
|     * Calculate and parse sensor data and store into | ||||
|     * structure | ||||
|     * | ||||
|     * @param data   Packet | ||||
|     * | ||||
|     */ | ||||
|     void parseSensorData(uint8_t *data); | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Write packet over BLE | ||||
|      * | ||||
|      * @param attribute_name   attribute_name of sensor | ||||
|      * @param arg_value        arg value for write a data over BLE | ||||
|      * | ||||
|      * @return Return success or Failure | ||||
|      */ | ||||
|     bool writePacket(OM2JCIEBU::OM2JCIEBU_ATTRIBUTE_T attribute_name, const std::vector<unsigned char> &arg_value); | ||||
| }; | ||||
| } | ||||
|  | ||||
							
								
								
									
										8
									
								
								src/2jciebu01-ble/2jciebu01_ble.i
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/2jciebu01-ble/2jciebu01_ble.i
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| %include "../common_top.i" | ||||
|  | ||||
| /* BEGIN Common SWIG syntax ------------------------------------------------- */ | ||||
| %{ | ||||
| #include "2jciebu01_ble.hpp" | ||||
| %} | ||||
| %include "2jciebu01_ble.hpp" | ||||
| /* END Common SWIG syntax */ | ||||
							
								
								
									
										29
									
								
								src/2jciebu01-ble/2jciebu01_ble.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/2jciebu01-ble/2jciebu01_ble.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| { | ||||
|     "Library": "2jciebu01_ble", | ||||
|     "Description": "Omron Environment Sensor", | ||||
|     "Sensor Class": { | ||||
|         "OM2JCIEBU_BLE": { | ||||
|             "Name": "API for 2JCIEBU01 Sensor Module using BLE interface", | ||||
|             "Description": "This is the UPM Module for the Omron Environment Sensor Module using BLE interface.", | ||||
|             "Aliases": [""], | ||||
|             "Categories": ["USB"], | ||||
|             "Connections": ["ble"], | ||||
|             "Project Type": ["sensor"], | ||||
|             "Manufacturers": ["Omron"], | ||||
|             "Image": "", | ||||
|             "Examples": { | ||||
|                 "C++": ["omron2jciebu01_ble.cxx"] | ||||
|             }, | ||||
|             "Platforms": { | ||||
|                 "Intel Edison": { | ||||
|                     "Notes": ["Might need USB type omron environment 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"] | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
							
								
								
									
										5
									
								
								src/2jciebu01-ble/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/2jciebu01-ble/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| set (libname "2jciebu01_ble") | ||||
| set (libdescription "Omron Environment Sensor") | ||||
| set (module_src ${libname}.cxx "2jciebu01.cxx") | ||||
| set (module_hpp ${libname}.hpp "2jciebu01.hpp") | ||||
| upm_module_init(2jciebu01-usb) | ||||
							
								
								
									
										98
									
								
								src/2jciebu01-usb/2jciebu01.cxx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								src/2jciebu01-usb/2jciebu01.cxx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,98 @@ | ||||
| /* | ||||
| * Author: Hiroyuki Mino <omronsupportupm@omron.com> | ||||
| * 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 <iostream> | ||||
| #include <string> | ||||
| #include <stdexcept> | ||||
|  | ||||
| #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; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										240
									
								
								src/2jciebu01-usb/2jciebu01.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										240
									
								
								src/2jciebu01-usb/2jciebu01.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,240 @@ | ||||
| /* | ||||
| * Author: Hiroyuki Mino <omronsupportupm@omron.com> | ||||
| * 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 <string> | ||||
| #include <iostream> | ||||
| #include <limits> | ||||
|  | ||||
| #include <stdint.h> | ||||
| #include <stdlib.h> | ||||
| #include <unistd.h> | ||||
| #include <string.h> | ||||
| #include <fcntl.h> | ||||
| #include <errno.h> | ||||
| #include <sys/select.h> | ||||
| #include <sys/types.h> | ||||
| #include <sys/stat.h> | ||||
|  | ||||
|  | ||||
| #include <upm/upm_utilities.h> | ||||
|  | ||||
|  | ||||
| /*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; | ||||
| }; | ||||
| } | ||||
							
								
								
									
										351
									
								
								src/2jciebu01-usb/2jciebu01_usb.cxx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										351
									
								
								src/2jciebu01-usb/2jciebu01_usb.cxx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,351 @@ | ||||
| /* | ||||
| * Author: Hiroyuki Mino <omronsupportupm@omron.com> | ||||
| * 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 <iostream> | ||||
| #include <string> | ||||
| #include <stdexcept> | ||||
|  | ||||
| #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; | ||||
| } | ||||
							
								
								
									
										247
									
								
								src/2jciebu01-usb/2jciebu01_usb.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										247
									
								
								src/2jciebu01-usb/2jciebu01_usb.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,247 @@ | ||||
| /* | ||||
| * | ||||
| * Author: Hiroyuki Mino <omronsupportupm@omron.com> | ||||
| * 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); | ||||
| }; | ||||
| } | ||||
							
								
								
									
										8
									
								
								src/2jciebu01-usb/2jciebu01_usb.i
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/2jciebu01-usb/2jciebu01_usb.i
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| %include "../common_top.i" | ||||
|  | ||||
| /* BEGIN Common SWIG syntax ------------------------------------------------- */ | ||||
| %{ | ||||
| #include "2jciebu01_usb.hpp" | ||||
| %} | ||||
| %include "2jciebu01_usb.hpp" | ||||
| /* END Common SWIG syntax */ | ||||
							
								
								
									
										35
									
								
								src/2jciebu01-usb/2jciebu01_usb.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/2jciebu01-usb/2jciebu01_usb.json
									
									
									
									
									
										Normal file
									
								
							| @@ -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"] | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
							
								
								
									
										5
									
								
								src/2jciebu01-usb/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/2jciebu01-usb/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -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) | ||||
		Reference in New Issue
	
	Block a user
	 Mihai Tudor Panu
					Mihai Tudor Panu