From 5ded843b9aa6401fd132a437e1b3ac5b4ae2da94 Mon Sep 17 00:00:00 2001 From: Libelium Date: Thu, 11 May 2017 11:24:21 +0200 Subject: [PATCH] API v028 --- libraries/CAN/WaspCAN.cpp | 78 ++++---- libraries/CAN/WaspCAN.h | 30 ++-- libraries/Frame/WaspFrame.cpp | 16 +- libraries/Frame/WaspFrameConstantsv15.h | 167 +++++++++++++----- libraries/ModbusMaster/ModbusMaster.cpp | 74 +++++--- libraries/ModbusMaster/ModbusMaster.h | 5 +- libraries/ModbusSlave/ModbusSlave.cpp | 45 +++-- libraries/SensorAmbient/WaspSensorAmbient.cpp | 6 +- .../SensorCities_PRO/WaspSensorCities_PRO.cpp | 109 ++++++++++-- .../SensorCities_PRO/WaspSensorCities_PRO.h | 10 +- libraries/SensorCities_PRO/keywords.txt | 3 +- .../SensorEvent_v30/WaspSensorEvent_v30.cpp | 97 +++++++++- .../SensorEvent_v30/WaspSensorEvent_v30.h | 8 +- libraries/SensorGas_PRO/WaspSensorGas_Pro.cpp | 18 +- libraries/SensorGas_v30/WaspSensorGas_v30.cpp | 10 +- libraries/WIFI_PRO/WaspWIFI_PRO.cpp | 58 +++--- libraries/Wasp4G/Wasp4G.cpp | 6 +- waspmote-api/WaspConstants.h | 9 +- waspmote-api/WaspPWR.cpp | 51 ++++-- waspmote-api/WaspXBeeCore.cpp | 138 ++++++++------- waspmote-api/Wire.cpp | 18 +- 21 files changed, 664 insertions(+), 292 deletions(-) diff --git a/libraries/CAN/WaspCAN.cpp b/libraries/CAN/WaspCAN.cpp index 30cc1a2..bba20ec 100755 --- a/libraries/CAN/WaspCAN.cpp +++ b/libraries/CAN/WaspCAN.cpp @@ -1,7 +1,7 @@ /*! \file WaspCAN.cpp \brief Library for managing CAN Bus modules * - * Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. + * Copyright (C) 2017 Libelium Comunicaciones Distribuidas S.L. * http://www.libelium.com * * This program is free software: you can redistribute it and/or modify @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * - * Version: 3.0 + * Version: 3.1 * Design: David Gascon * Implementation: Luis Antonio Martin Nuez & Ahmad Saad */ @@ -506,11 +506,11 @@ unsigned int WaspCAN::getEngineCoolantTemp() //! Name: getFuelPressure() //! Description: Fuel pressure //! Param : void -//! Returns: unsigned int: Fuel pressure (0 - 765 Kpa) +//! Returns: uint16_t: Fuel pressure (0 - 765 Kpa) //!************************************************************* -unsigned int WaspCAN::getFuelPressure() +uint16_t WaspCAN::getFuelPressure() { - unsigned int data; + uint16_t data; CiARequest(FUEL_PRESSURE); @@ -530,11 +530,11 @@ unsigned int WaspCAN::getFuelPressure() //! Name: getIntakeMAPressure() //! Description: Intake manifold absolute pressure //! Param : void -//! Returns: unsigned int: absolute pressure (0 - 255 Kpa) +//! Returns: uint16_t: absolute pressure (0 - 255 Kpa) //!************************************************************* -unsigned int WaspCAN::getIntakeMAPressure() +uint16_t WaspCAN::getIntakeMAPressure() { - unsigned int data; + uint16_t data; CiARequest(INTAKE_M_A_PRESSURE); @@ -556,12 +556,12 @@ unsigned int WaspCAN::getIntakeMAPressure() //! Name: getEngineRPM() //! Description: Engine RPM //! Param : void -//! Returns: unsigned int: Engine RPM (0 - 16,383 RPM) +//! Returns: uint16_t: Engine RPM (0 - 16,383 RPM) //!************************************************************* -unsigned int WaspCAN::getEngineRPM() +uint16_t WaspCAN::getEngineRPM() { - unsigned int data; + uint16_t data; CiARequest(ENGINE_RPM); @@ -583,9 +583,9 @@ unsigned int WaspCAN::getEngineRPM() //! Param : void //! Returns: unsigned int: Vehicle speed (0 - 255) //!************************************************************* -unsigned int WaspCAN::getVehicleSpeed() +uint16_t WaspCAN::getVehicleSpeed() { - unsigned int data; + uint16_t data; CiARequest(VEHICLE_SPEED); @@ -608,9 +608,9 @@ unsigned int WaspCAN::getVehicleSpeed() //! Param : void //! Returns: unsigned int: Time (-64 - 63.5) //!************************************************************* -unsigned int WaspCAN::getTimingAdvance() +uint16_t WaspCAN::getTimingAdvance() { - unsigned int data; + uint16_t data; CiARequest(TIMING_ADVANCE); @@ -629,11 +629,11 @@ unsigned int WaspCAN::getTimingAdvance() //! Name: getIntankeAirTemp() //! Description: Intake air temperature //! Param : void -//! Returns: unsigned int: Intake air temperature(-40 - 215) +//! Returns: uint8_t: Intake air temperature(-40 - 215) //!************************************************************* -unsigned int WaspCAN::getIntankeAirTemp() +uint16_t WaspCAN::getIntankeAirTemp() { - unsigned int data; + uint16_t data; CiARequest(INTAKE_AIR_TEMP); @@ -653,11 +653,11 @@ unsigned int WaspCAN::getIntankeAirTemp() //! Name: getMAFairFlowRate() //! Description: MAF air flow rate //! Param : void -//! Returns: unsigned int: air flow rate (0 - 655.35 g/s) +//! Returns: uint8_t: air flow rate (0 - 655.35 g/s) //!************************************************************* -unsigned int WaspCAN::getMAFairFlowRate() +uint16_t WaspCAN::getMAFairFlowRate() { - unsigned int data; + uint16_t data; CiARequest(MAF_AIR_FLOW_RATE); @@ -669,8 +669,7 @@ unsigned int WaspCAN::getMAFairFlowRate() #endif } - return data; - + return data; } @@ -678,11 +677,11 @@ unsigned int WaspCAN::getMAFairFlowRate() //! Name: getThrottlePosition() //! Description: Throttle position //! Param : void -//! Returns: unsigned int: Throttle position (0 - 100%) +//! Returns: uint8_t: Throttle position (0 - 100%) //!************************************************************* -unsigned int WaspCAN::getThrottlePosition() +uint8_t WaspCAN::getThrottlePosition() { - unsigned int data; + uint16_t data; CiARequest(THROTTLE_POSITION); @@ -694,9 +693,7 @@ unsigned int WaspCAN::getThrottlePosition() #endif } - return data; - - + return (uint8_t)data; } @@ -704,11 +701,11 @@ unsigned int WaspCAN::getThrottlePosition() //! Name: getFuelLevel() //! Description: Fuel Level Input //! Param : void -//! Returns: unsigned int: Fuel Level Input (0 - 100%) +//! Returns: uint8_t: Fuel Level Input (0 - 100%) //!************************************************************* -unsigned int WaspCAN::getFuelLevel() +uint8_t WaspCAN::getFuelLevel() { - unsigned int data; + uint16_t data; CiARequest(FUEL_LEVEL); @@ -720,7 +717,7 @@ unsigned int WaspCAN::getFuelLevel() #endif } - return data; + return (uint8_t)data; } @@ -729,11 +726,11 @@ unsigned int WaspCAN::getFuelLevel() //! Name: getBarometricPressure() //! Description: Barometric pressure //! Param : void -//! Returns: unsigned int: Barometric pressure (0 - 255 Kpa) +//! Returns: uint8_t: Barometric pressure (0 - 255 Kpa) //!************************************************************* -unsigned int WaspCAN::getBarometricPressure() +uint8_t WaspCAN::getBarometricPressure() { - unsigned int data; + uint16_t data; CiARequest(BAROMETRIC_PRESSURE); @@ -745,7 +742,7 @@ unsigned int WaspCAN::getBarometricPressure() #endif } - return data; + return (uint8_t)data; } @@ -755,9 +752,9 @@ unsigned int WaspCAN::getBarometricPressure() //! Param : void //! Returns: unsigned int: Engine fuel rate (0 - 3212 L/h) //!************************************************************* -unsigned int WaspCAN::getEngineFuelRate() +uint16_t WaspCAN::getEngineFuelRate() { - unsigned int data; + uint16_t data; CiARequest(ENGINE_FUEL_RATE); @@ -769,8 +766,7 @@ unsigned int WaspCAN::getEngineFuelRate() #endif } - return data; - + return data; } diff --git a/libraries/CAN/WaspCAN.h b/libraries/CAN/WaspCAN.h index 0120923..d61eec9 100755 --- a/libraries/CAN/WaspCAN.h +++ b/libraries/CAN/WaspCAN.h @@ -1,7 +1,7 @@ /*! \file WaspCAN.h \brief Library for managing CAN Bus modules - Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. + Copyright (C) 2017 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com This program is free software: you can redistribute it and/or modify @@ -17,7 +17,7 @@ You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . - Version: 3.0 + Version: 3.1 Design: David Gascón Implementation: Luis Antonio Martín Nuez & Ahmad Saad */ @@ -490,19 +490,19 @@ class WaspCAN CAN in Automation (CiA) ***********************************************************************/ - unsigned int getEngineLoad(); - unsigned int getEngineCoolantTemp(); - unsigned int getFuelPressure(); - unsigned int getIntakeMAPressure(); - unsigned int getEngineRPM(); - unsigned int getVehicleSpeed(); - unsigned int getTimingAdvance(); - unsigned int getIntankeAirTemp(); - unsigned int getMAFairFlowRate(); - unsigned int getThrottlePosition(); - unsigned int getFuelLevel(); - unsigned int getBarometricPressure(); - unsigned int getEngineFuelRate(); + uint16_t getEngineLoad(); + uint16_t getEngineCoolantTemp(); + uint16_t getFuelPressure(); + uint16_t getIntakeMAPressure(); + uint16_t getEngineRPM(); + uint16_t getVehicleSpeed(); + uint16_t getTimingAdvance(); + uint16_t getIntankeAirTemp(); + uint16_t getMAFairFlowRate(); + uint8_t getThrottlePosition(); + uint8_t getFuelLevel(); + uint8_t getBarometricPressure(); + uint16_t getEngineFuelRate(); // General Function void CiARequest(uint8_t PID); diff --git a/libraries/Frame/WaspFrame.cpp b/libraries/Frame/WaspFrame.cpp index 65e5432..e028d7c 100755 --- a/libraries/Frame/WaspFrame.cpp +++ b/libraries/Frame/WaspFrame.cpp @@ -15,7 +15,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * - * Version: 3.1 + * Version: 3.2 * Design: David Gascón * Implementation: Yuri Carmona, Javier Siscart, Joaquín Ruiz */ @@ -2866,13 +2866,23 @@ int8_t WaspFrame::addTimestamp() /* * setTinyLength * + * Set the maximum payload of the tiny frames. + * Range: 10 to 100 Bytes + * */ void WaspFrame::setTinyLength(uint8_t length) { + if (length > sizeof(bufferTiny)) { + // max range _maxTinyLength = sizeof(bufferTiny); } + else if (length < 10) + { + // min range + _maxTinyLength = 10; + } else { _maxTinyLength = length; @@ -2889,8 +2899,8 @@ uint8_t WaspFrame::generateTinyFrame() memset(bufferTiny, 0x00, sizeof(bufferTiny)); lengthTiny = 0; - // insert data in Sigfox frame with the following format: - // [seq]+ [length] + [sensor_1] + ... + [sensor_N] + // insert data in tiny frame with the following format: + // S + [sensor_1] + ... + [sensor_N] // where [sensor_x] is composed of [id]+[data] bufferTiny[0] = readSequence() - 1; lengthTiny++; diff --git a/libraries/Frame/WaspFrameConstantsv15.h b/libraries/Frame/WaspFrameConstantsv15.h index 79d021f..65339c5 100644 --- a/libraries/Frame/WaspFrameConstantsv15.h +++ b/libraries/Frame/WaspFrameConstantsv15.h @@ -17,7 +17,7 @@ You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . - Version: 3.2 + Version: 3.3 Design: David Gascón Implementation: Yuri Carmona, Javier Siscart, Joaquín Ruiz, Alejandro Gallego @@ -181,10 +181,10 @@ #define SENSOR_WATER_COND 133 #define SENSOR_WATER_WT 134 #define SENSOR_WATER_TURB 135 -#define SENSOR_WATER_PH_ 136 -#define SENSOR_WATER_PH_D 137 +#define SENSOR_WATER_PH_A 136 +#define SENSOR_WATER_PH_E 137 #define SENSOR_WATER_ORP_A 138 -#define SENSOR_WATER_ORP_D 139 +#define SENSOR_WATER_ORP_E 139 // Smart Agriculture v30 @@ -231,6 +231,18 @@ #define SENSOR_4_20_CURRENT_SOCKET_C 177 #define SENSOR_4_20_CURRENT_SOCKET_D 178 +// Industrial protocols (ModBus & CAN bus) +#define SENSOR_MODBUS_COILS 180 +#define SENSOR_MODBUS_DISCRETE_INPUT 181 +#define SENSOR_MODBUS_HOLDING_REGS 182 +#define SENSOR_MODBUS_INPUT_REGS 183 +#define SENSOR_CANBUS_RPM 184 +#define SENSOR_CANBUS_VS 185 +#define SENSOR_CANBUS_FR 186 +#define SENSOR_CANBUS_FL 187 +#define SENSOR_CANBUS_TP 188 +#define SENSOR_CANBUS_FP 189 + // Common sensors #define SENSOR_DUST_PM1 70 @@ -425,9 +437,9 @@ const char str_frame_133[] PROGMEM = "COND"; const char str_frame_134[] PROGMEM = "WT"; const char str_frame_135[] PROGMEM = "TURB"; const char str_frame_136[] PROGMEM = "PH_A"; -const char str_frame_137[] PROGMEM = "PH_D"; +const char str_frame_137[] PROGMEM = "PH_E"; const char str_frame_138[] PROGMEM = "ORP_A"; -const char str_frame_139[] PROGMEM = "ORP_D"; +const char str_frame_139[] PROGMEM = "ORP_E"; const char str_frame_140[] PROGMEM = ""; // reserved const char str_frame_141[] PROGMEM = ""; // reserved const char str_frame_142[] PROGMEM = ""; // reserved @@ -474,6 +486,19 @@ const char str_frame_175[] PROGMEM = "CUR_A"; const char str_frame_176[] PROGMEM = "CUR_B"; const char str_frame_177[] PROGMEM = "CUR_C"; const char str_frame_178[] PROGMEM = "CUR_D"; +const char str_frame_179[] PROGMEM = ""; + +// Industrial protocols: Modbus & CAN bus +const char str_frame_180[] PROGMEM = "MB_COILS"; +const char str_frame_181[] PROGMEM = "MB_DI"; +const char str_frame_182[] PROGMEM = "MB_HR"; +const char str_frame_183[] PROGMEM = "MB_IR"; +const char str_frame_184[] PROGMEM = "CB_RPM"; +const char str_frame_185[] PROGMEM = "CB_VS"; +const char str_frame_186[] PROGMEM = "CB_FR"; +const char str_frame_187[] PROGMEM = "CB_FL"; +const char str_frame_188[] PROGMEM = "CB_TP"; +const char str_frame_189[] PROGMEM = "CB_FP"; @@ -665,6 +690,17 @@ const char* const FRAME_SENSOR_TABLE[] PROGMEM= str_frame_176, str_frame_177, str_frame_178, + str_frame_179, + str_frame_180, + str_frame_181, + str_frame_182, + str_frame_183, + str_frame_184, + str_frame_185, + str_frame_186, + str_frame_187, + str_frame_188, + str_frame_189, }; @@ -714,14 +750,14 @@ const uint8_t FRAME_SENSOR_TYPE_TABLE[] PROGMEM= 2, // 21 //// reserved - 0, // 22 - 0, // 23 - 0, // 24 - 0, // 25 - 0, // 26 - 0, // 27 - 0, // 28 - 0, // 29 + 0, // 22 + 0, // 23 + 0, // 24 + 0, // 25 + 0, // 26 + 0, // 27 + 0, // 28 + 0, // 29 //// Gases PRO v30 2, // 30 @@ -732,10 +768,10 @@ const uint8_t FRAME_SENSOR_TYPE_TABLE[] PROGMEM= 2, // 35 //// reserved - 0, // 36 - 0, // 37 - 0, // 38 - 0, // 39 + 0, // 36 + 0, // 37 + 0, // 38 + 0, // 39 //// Events v30 2, // 40 @@ -780,26 +816,26 @@ const uint8_t FRAME_SENSOR_TYPE_TABLE[] PROGMEM= 2, // 77 4, // 78 1, // 79 - 0, // 80 - 0, // 81 - 0, // 82 - 0, // 83 - 0, // 84 - 0, // 85 - 0, // 86 - 0, // 87 - 0, // 88 + 0, // 80 + 0, // 81 + 0, // 82 + 0, // 83 + 0, // 84 + 0, // 85 + 0, // 86 + 0, // 87 + 0, // 88 2, // 89 2, // 90 2, // 91 2, // 92 2, // 93 2, // 94 - 0, // 95 - 0, // 96 - 0, // 97 - 0, // 98 - 0, // 99 + 0, // 95 + 0, // 96 + 0, // 97 + 0, // 98 + 0, // 99 //// Smart Water Ions 2, // 100 @@ -823,12 +859,12 @@ const uint8_t FRAME_SENSOR_TYPE_TABLE[] PROGMEM= 2, // 118 2, // 119 2, // 120 - 0, // 121 - 0, // 122 + 0, // 121 + 0, // 122 //// Additional 4, // 123 - 0, // 124 + 0, // 124 0, // 125 0, // 126 0, // 127 @@ -848,16 +884,16 @@ const uint8_t FRAME_SENSOR_TYPE_TABLE[] PROGMEM= 2, // 137 2, // 138 2, // 139 - 0, // 140 - 0, // 141 - 0, // 142 - 0, // 143 - 0, // 144 - 0, // 145 - 0, // 146 - 0, // 147 - 0, // 148 - 0, // 149 + 0, // 140 + 0, // 141 + 0, // 142 + 0, // 143 + 0, // 144 + 0, // 145 + 0, // 146 + 0, // 147 + 0, // 148 + 0, // 149 //// Smart Agriculture 2, // 150 @@ -879,7 +915,7 @@ const uint8_t FRAME_SENSOR_TYPE_TABLE[] PROGMEM= 2, // 166 2, // 167 2, // 168 - 0, // 169 + 0, // 169 //// Ambient Control 2, // 170 @@ -893,6 +929,20 @@ const uint8_t FRAME_SENSOR_TYPE_TABLE[] PROGMEM= 2, // 176 2, // 177 2, // 178 + 0, // 179 + + //// Industrial protocols (ModBus & CAN bus) + 1, // 180 + 1, // 181 + 1, // 182 + 1, // 183 + 1, // 184 + 1, // 185 + 1, // 186 + 0, // 187 + 0, // 188 + 1, // 189 + }; @@ -1116,6 +1166,19 @@ const uint8_t FRAME_SENSOR_FIELD_TABLE[] PROGMEM= 1, // 176 1, // 177 1, // 178 + 1, // 179 + + //// Industrial protocols (ModBus & CAN bus) + 2, // 180 + 2, // 181 + 3, // 182 + 3, // 183 + 1, // 184 + 1, // 185 + 1, // 186 + 1, // 187 + 1, // 188 + 1, // 189 }; @@ -1336,7 +1399,19 @@ const uint8_t FRAME_DECIMAL_TABLE[] PROGMEM = 3, // 176 3, // 177 3, // 178 + 0, // 179 + //// Industrial protocols (ModBus & CAN bus) + 0, // 180 + 0, // 181 + 0, // 182 + 0, // 183 + 0, // 184 + 0, // 185 + 0, // 186 + 0, // 187 + 0, // 188 + 0, // 189 }; diff --git a/libraries/ModbusMaster/ModbusMaster.cpp b/libraries/ModbusMaster/ModbusMaster.cpp index a6a9b82..9b6446e 100755 --- a/libraries/ModbusMaster/ModbusMaster.cpp +++ b/libraries/ModbusMaster/ModbusMaster.cpp @@ -20,7 +20,7 @@ Copyright © 2009-2013 Doc Walker <4-20ma at wvfans dot net> Modified for Waspmote by Libelium, 2017 - Version: 3.2 + Version: 3.3 */ #include "ModbusMaster.h" @@ -123,14 +123,17 @@ void ModbusMaster::begin(unsigned long BaudRate , uint8_t socket) if (_protocol == RS232_COM) { - _u8SerialPort = socket; - beginSerial(BaudRate, _u8SerialPort); - if (socket == SOCKET0) Utils.setMuxSocket0(); - if (socket == SOCKET1) Utils.setMuxSocket1(); - // power on the socket - PWR.powerSocket(socket, HIGH); + // Configure the baud rate of the module + W232.setUART(socket); + W232.setBaudrate(BaudRate); + W232.ON(_u8SerialPort); + + // Configure the parity bit as disabled + W232.parityBit(DISABLE); + // Use one stop bit configuration + W232.stopBitConfig(1); } else { @@ -610,6 +613,9 @@ uint8_t ModbusMaster::ModbusMasterTransaction(uint8_t u8MBFunction) uint8_t u8BytesLeft = 8; uint8_t u8MBStatus = ku8MBSuccess; + // clear buffer + memset(u8ModbusADU, 0x00, sizeof(u8ModbusADU)); + // assemble Modbus Request Application Data Unit u8ModbusADU[u8ModbusADUSize++] = _u8MBSlave; u8ModbusADU[u8ModbusADUSize++] = u8MBFunction; @@ -706,30 +712,40 @@ uint8_t ModbusMaster::ModbusMasterTransaction(uint8_t u8MBFunction) if (_protocol == RS232_COM) { for (i = 0; i < u8ModbusADUSize; i++) { - printByte(u8ModbusADU[i], _u8SerialPort); + W232.send(u8ModbusADU[i], BYTE); } } else { for (i = 0; i < u8ModbusADUSize; i++) { - W485.send(u8ModbusADU[i], _u8SerialPort); + W485.send(u8ModbusADU[i], BYTE); } } - u8ModbusADUSize = 1; + //~ USB.print("Master send:"); + //~ USB.printHexln(u8ModbusADU, u8ModbusADUSize); + + // clear buffer + memset(u8ModbusADU, 0x00, sizeof(u8ModbusADU)); // loop until we run out of time or bytes, or an error occurs u32StartTime = millis(); int val = 0xFF; long cont = 0; - + + // wait for correct 'slave address' if (_protocol == RS232_COM) { while((val != _u8MBSlave) && (cont < 200)) { - val = serialRead(_u8SerialPort); - delay(5); + if (W232.available()) + { + val = W232.read(); + } + //~ val = W232.read(); + //~ delay(10); + W232.latencyDelay(); cont ++; } } @@ -742,24 +758,35 @@ uint8_t ModbusMaster::ModbusMasterTransaction(uint8_t u8MBFunction) cont ++; } } - - u8ModbusADU[u8ModbusADUSize] = val; - - while (u8BytesLeft && !u8MBStatus) + // check slave address + if (val != _u8MBSlave) { - + //~ USB.println("NO slave address found"); + return 1; + } + else + { + u8ModbusADU[0] = val; + } + + u8ModbusADUSize = 1; + + // receive rest of the packet + while (u8BytesLeft && !u8MBStatus) + { if (_protocol == RS232_COM) { - if (serialAvailable(_u8SerialPort)) + if (W232.available()) { - u8ModbusADU[u8ModbusADUSize] = serialRead(_u8SerialPort); + u8ModbusADU[u8ModbusADUSize] = W232.read(); u8BytesLeft--; u8ModbusADUSize ++; } else { - delay(10); + //~ delay(10); + W232.latencyDelay(); } } else @@ -821,10 +848,13 @@ uint8_t ModbusMaster::ModbusMasterTransaction(uint8_t u8MBFunction) } } - if (millis() > (u32StartTime + ku8MBResponseTimeout)) { + if (millis() > (u32StartTime + 1000)) { u8MBStatus = ku8MBResponseTimedOut; } } + + //~ USB.print("Master receive:"); + //~ USB.printHexln(u8ModbusADU, u8ModbusADUSize); // verify response is large enough to inspect further if (!u8MBStatus && u8ModbusADUSize >= 5) { diff --git a/libraries/ModbusMaster/ModbusMaster.h b/libraries/ModbusMaster/ModbusMaster.h index bf0ce8b..7dcbeab 100755 --- a/libraries/ModbusMaster/ModbusMaster.h +++ b/libraries/ModbusMaster/ModbusMaster.h @@ -19,9 +19,9 @@ Written by Doc Walker (Rx) Copyright © 2009-2013 Doc Walker <4-20ma at wvfans dot net> - Modified for Waspmote by Libelium, 2016 + Modified for Waspmote by Libelium, 2017 - Version: 3.0 + Version: 3.1 */ @@ -86,6 +86,7 @@ Macro to generate 32-bit integer from (2) 16-bit words. // Functions to calculate Modbus Application Data Unit CRC #include #include "Wasp485.h" +#include "Wasp232.h" //************************************************************************************************** // MODBUS MASTER CLASS DEFINITIONS diff --git a/libraries/ModbusSlave/ModbusSlave.cpp b/libraries/ModbusSlave/ModbusSlave.cpp index 130f3f5..98638cf 100755 --- a/libraries/ModbusSlave/ModbusSlave.cpp +++ b/libraries/ModbusSlave/ModbusSlave.cpp @@ -7,7 +7,7 @@ receive data from a device that communicates using the Modbus protocol. Copyright (C) 2000 Philip Costigan P.C. SCADA LINK PTY. LTD. - Modified for Waspmote by Libelium, 2016 + Modified for Waspmote by Libelium, 2017 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -31,7 +31,7 @@ paul@pmcrae.freeserve.co.uk (http://www.pmcrae.freeserve.co.uk) who wrote a small program to read 100 registers from a modbus slave. - Version: 3.0 + Version: 3.1 */ @@ -280,7 +280,7 @@ int ModbusSlave::send_reply(unsigned char *query, unsigned char string_length) { for (i = 0; i < string_length; i++) { - printByte(query[i], _socket); + W232.send(query[i], BYTE); } } else @@ -291,6 +291,9 @@ int ModbusSlave::send_reply(unsigned char *query, unsigned char string_length) } } + //~ USB.print("Slave send: "); + //~ USB.printHexln(query, string_length); + // It does not mean that the write was succesful return i; } @@ -308,11 +311,11 @@ int ModbusSlave::receive_request(unsigned char *received_string) if (_protocol == RS232_COM) { // FIXME: does Serial.available wait 1.5T or 3.5T before exiting the loop? - while (serialAvailable(_socket)) + while (W232.available()) { - received_string[bytes_received] = serialRead(_socket); + received_string[bytes_received] = W232.read(); bytes_received++; - + delay(1); if (bytes_received >= MAX_MESSAGE_LENGTH) { // Port error @@ -336,6 +339,9 @@ int ModbusSlave::receive_request(unsigned char *received_string) } } + //~ USB.print("Slave receive: "); + //~ USB.printHexln(received_string, bytes_received); + return (bytes_received); } @@ -376,7 +382,7 @@ int ModbusSlave::modbus_request(unsigned char *data) return NO_REPLY; } } - + return (response_length); } @@ -573,9 +579,17 @@ void ModbusSlave::configure(uint8_t _slave, long baud, uint8_t socket) if (_protocol == RS232_COM) { - //W232.ON(socket); - delay(10); - beginSerial(baud, socket); + //~ W232.ON(socket); + //~ delay(10); + //~ beginSerial(baud, socket); + _socket = socket; + W232.ON(_socket); + // Configure the baud rate of the module + W232.baudRateConfig(baud); + // Configure the parity bit as disabled + W232.parityBit(DISABLE); + // Use one stop bit configuration + W232.stopBitConfig(1); } else { @@ -625,13 +639,13 @@ int ModbusSlave::update(int *regs, unsigned int regs_size) if (_protocol == RS232_COM) { - length = serialAvailable(_socket); + length = W232.available(); } else { length = W485.available(); } - + if (length == 0) { lastBytesReceived = 0; @@ -644,16 +658,20 @@ int ModbusSlave::update(int *regs, unsigned int regs_size) Nowdt = now + T35; return 0; } - + if (now < Nowdt) + { return 0; + } lastBytesReceived = 0; length = modbus_request(query); if (length < 1) + { return length; + } exception = validate_request(query, length, regs_size); @@ -661,7 +679,6 @@ int ModbusSlave::update(int *regs, unsigned int regs_size) { build_error_packet( query[FUNC], exception, errpacket); send_reply(errpacket, EXCEPTION_SIZE); - return (exception); } diff --git a/libraries/SensorAmbient/WaspSensorAmbient.cpp b/libraries/SensorAmbient/WaspSensorAmbient.cpp index 896b067..9d61969 100755 --- a/libraries/SensorAmbient/WaspSensorAmbient.cpp +++ b/libraries/SensorAmbient/WaspSensorAmbient.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. + * Copyright (C) 2017 Libelium Comunicaciones Distribuidas S.L. * http://www.libelium.com * * This program is free software: you can redistribute it and/or modify @@ -15,7 +15,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * - * Version: 3.1 + * Version: 3.2 * Design: David Gascón * Implementation: Alberto Bielsa, Manuel Calahorra, Yuri Carmona, Jorge Casanova, Javier Siscart * @@ -50,7 +50,7 @@ WaspSensorAmbient::WaspSensorAmbient() digitalWrite(SENS_AMBIENT_SENSIRION_DATA,LOW); digitalWrite(SENS_AMBIENT_LDR_GND,LOW); - + WaspRegisterSensor |= REG_AMBIENT; } // Private Methods ////////////////////////////////////////////////////////////// diff --git a/libraries/SensorCities_PRO/WaspSensorCities_PRO.cpp b/libraries/SensorCities_PRO/WaspSensorCities_PRO.cpp index 4bee703..fce9d69 100755 --- a/libraries/SensorCities_PRO/WaspSensorCities_PRO.cpp +++ b/libraries/SensorCities_PRO/WaspSensorCities_PRO.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. + * Copyright (C) 2017 Libelium Comunicaciones Distribuidas S.L. * http://www.libelium.com * * This program is free software: you can redistribute it and/or modify @@ -15,7 +15,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * - * Version: 3.1 + * Version: 3.2 * Design: David Gascón * Implementation: Alejandro Gállego, Ahmad Saad */ @@ -82,7 +82,7 @@ void WaspSensorCitiesPRO::ON(uint8_t socket_sensor) if ((WaspRegister & REG_3V3) == 0) { #if CITIES_PRO_DEBUG>0 - USB.println(F("SCP.3V3 to ON")); + PRINTLN_CITIES_PRO(F("3V3 to ON")); #endif PWR.setSensorPower(SENS_3V3, SENS_ON); digitalWrite(SCP_I2C_MAIN_EN, HIGH); // I2C main pin @@ -129,13 +129,15 @@ void WaspSensorCitiesPRO::ON(uint8_t socket_sensor) // Set the flags pwrCitiesPRORegister |= 0x10; break; - + + default: + break; } #if CITIES_PRO_DEBUG>1 - USB.print(F("SCP.pwrCitiesPRORegister=")); + PRINT_CITIES_PRO(F("pwrCitiesPRORegister=")); USB.println(pwrCitiesPRORegister, BIN); - USB.print(F("SCP.pwrGasPRORegister=")); + PRINT_CITIES_PRO(F("pwrGasPRORegister=")); USB.println(pwrGasPRORegister, BIN); #endif @@ -157,7 +159,7 @@ void WaspSensorCitiesPRO::ON(uint8_t socket_sensor) void WaspSensorCitiesPRO::OFF(uint8_t socket_sensor) { uint8_t mask; - + switch(socket_sensor) { @@ -201,11 +203,13 @@ void WaspSensorCitiesPRO::OFF(uint8_t socket_sensor) pwrCitiesPRORegister &= 0xEF; break; + default: + break; } #if CITIES_PRO_DEBUG>1 - USB.print(F("SCP.pwrCitiesPRORegister=")); + PRINT_CITIES_PRO(F("pwrCitiesPRORegister=")); USB.println(pwrCitiesPRORegister, BIN); - USB.print(F("SCP.pwrGasPRORegister=")); + PRINT_CITIES_PRO(F("pwrGasPRORegister=")); USB.println(pwrGasPRORegister, BIN); #endif @@ -221,12 +225,97 @@ void WaspSensorCitiesPRO::OFF(uint8_t socket_sensor) ((WaspRegister & REG_3V3) != 0)) { #if CITIES_PRO_DEBUG>0 - USB.println(F("SCP.3V3 to OFF")); + PRINTLN_CITIES_PRO(F("3V3 to OFF")); #endif PWR.setSensorPower(SENS_3V3, SENS_OFF); } } + +/* + * Read BME temperature value + * Return: temperature value + * + */ +float WaspSensorCitiesPRO::getTemperature() +{ + float value = 0; + //Switch ON I2C + digitalWrite(SCP_I2C_MAIN_EN, HIGH); + //Configure the BME280 Sensor (Temperature, Humidity and Pressure) + BME.ON(); + delay(100); + value = BME.getTemperature(BME280_OVERSAMP_1X, 0); + #if CITIES_PRO_DEBUG>0 + PRINT_CITIES_PRO(F("Temperature:")); + USB.println(value); + PRINT_CITIES_PRO(F("BME280_OVERSAMP_1X")); + USB.println(BME280_OVERSAMP_1X); + #endif + delay(100); + // Switch OFF I2C + //~ digitalWrite(SCP_I2C_MAIN_EN, LOW); + + // Read the temperature from the BME280 Sensor + return value; +} + + +/* + * Read BME humidity value + * Return: humidity value + * + */ +float WaspSensorCitiesPRO::getHumidity() { + float value = 0; + //Switch ON I2C + digitalWrite(SCP_I2C_MAIN_EN, HIGH); + //Configure the BME280 Sensor (Temperature, Humidity and Pressure) + BME.ON(); + delay(100); + // Read the humidity from the BME280 Sensor + value = BME.getHumidity(BME280_OVERSAMP_1X); + #if CITIES_PRO_DEBUG>0 + PRINT_CITIES_PRO(F("Humidity:")); + USB.println(value); + PRINT_CITIES_PRO(F("BME280_OVERSAMP_1X")); + USB.println(BME280_OVERSAMP_1X); + #endif + delay(100); + // Switch OFF I2C + //~ digitalWrite(SCP_I2C_MAIN_EN, LOW); + // Read the temperature from the BME280 Sensor + return value; +} + + +/* + * Read BME pressure value + * Return: pressure value + * + */ +float WaspSensorCitiesPRO::getPressure() { + float value = 0; + //Switch ON I2C + digitalWrite(SCP_I2C_MAIN_EN, HIGH); + //Configure the BME280 Sensor (Temperature, Humidity and Pressure) + BME.ON(); + delay(100); + // Read the pressure from the BME280 Sensor + value = BME.getPressure(BME280_OVERSAMP_1X, 0); + #if CITIES_PRO_DEBUG>0 + PRINT_CITIES_PRO(F("Pressure:")); + USB.println(value); + PRINT_CITIES_PRO(F("BME280_OVERSAMP_1X")); + USB.println(BME280_OVERSAMP_1X); + #endif + delay(100); + // Switch OFF I2C + //~ digitalWrite(SCP_I2C_MAIN_EN, LOW); + // Read the temperature from the BME280 Sensor + return value; +} + WaspSensorCitiesPRO SensorCitiesPRO=WaspSensorCitiesPRO(); diff --git a/libraries/SensorCities_PRO/WaspSensorCities_PRO.h b/libraries/SensorCities_PRO/WaspSensorCities_PRO.h index 772fc7c..ad30b90 100755 --- a/libraries/SensorCities_PRO/WaspSensorCities_PRO.h +++ b/libraries/SensorCities_PRO/WaspSensorCities_PRO.h @@ -1,7 +1,7 @@ /*! \file WaspSensorCitiesPRO.h \brief Library for managing the Smart Cities PRO Sensor Board - Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. + Copyright (C) 2017 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com This program is free software: you can redistribute it and/or modify @@ -17,7 +17,7 @@ You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . - Version: 3.1 + Version: 3.2 Design: David Gascón Implementation: Alejandro Gállego, Ahmad Saad @@ -36,6 +36,7 @@ ******************************************************************************/ #include #include +#include /****************************************************************************** @@ -111,8 +112,11 @@ class WaspSensorCitiesPRO SENS_CITIES_PRO_GAS2 \return void */ - void OFF(uint8_t socket_sensor); + void OFF(uint8_t socket_sensor); + float getTemperature(); + float getHumidity(); + float getPressure(); }; extern WaspSensorCitiesPRO SensorCitiesPRO; diff --git a/libraries/SensorCities_PRO/keywords.txt b/libraries/SensorCities_PRO/keywords.txt index a964693..b57cae7 100644 --- a/libraries/SensorCities_PRO/keywords.txt +++ b/libraries/SensorCities_PRO/keywords.txt @@ -30,7 +30,8 @@ SCP_NOISE_ADC LITERAL1 FAST_MODE LITERAL1 SLOW_MODE LITERAL1 -WaspSensorCitiesPRO KEYWORD3 + +WaspSensorCities_PRO KEYWORD2 ON KEYWORD2 OFF KEYWORD2 setBoardMode KEYWORD2 diff --git a/libraries/SensorEvent_v30/WaspSensorEvent_v30.cpp b/libraries/SensorEvent_v30/WaspSensorEvent_v30.cpp index 1cbb66b..ddc155c 100755 --- a/libraries/SensorEvent_v30/WaspSensorEvent_v30.cpp +++ b/libraries/SensorEvent_v30/WaspSensorEvent_v30.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. + * Copyright (C) 2017 Libelium Comunicaciones Distribuidas S.L. * http://www.libelium.com * * This program is free software: you can redistribute it and/or modify @@ -15,7 +15,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * - * Version: 3.1 + * Version: 3.2 * Design: David Gascón * Implementation: Carlos Bello */ @@ -149,6 +149,8 @@ float WaspSensorEvent_v30::getPressure() { PRINT_EVENT(F("BME280_OVERSAMP_1X")); USB.println(BME280_OVERSAMP_1X); #endif + // Switch OFF I2C + digitalWrite(I2C_PIN_OE, LOW); // Read the temperature from the BME280 Sensor return value; } @@ -193,6 +195,7 @@ void WaspSensorEvent_v30::ON() { // Switch ON 3V3 and 5V for supplying the board PWR.setSensorPower(SENS_5V, SENS_ON); PWR.setSensorPower(SENS_3V3, SENS_ON); + delay(500); _intEnabled = true; if (_boot_version < 'H') @@ -202,7 +205,7 @@ void WaspSensorEvent_v30::ON() { USB.println(F("Your Waspmote version is v12.")); USB.println(F("*******************************************")); return (void)0; - } + } } //!********************************************************************* @@ -647,6 +650,8 @@ liquidLevelClass::liquidLevelClass(uint8_t socket){ //! Returns: int: 0 or 1 //!********************************************************************* uint8_t liquidLevelClass::read(){ + + return readInput(liquidLevelSocket); } //!********************************************************************* @@ -732,6 +737,7 @@ liquidPresenceClass::liquidPresenceClass(uint8_t socket){ uint8_t liquidPresenceClass::read(){ return readInput(liquidPresenceSocket); } + //!********************************************************************* //! Name: readliquidPresence() //! Description: Read digital information about liquid presence @@ -743,6 +749,91 @@ uint8_t liquidPresenceClass::readliquidPresence(){ return readInput(liquidPresenceSocket); } +//!********************************************************************* +//! Name: readVoltage() +//! Description: Read analog information about liquid presence +//! Param : void +//! Returns: float: volts value read +//!********************************************************************* +float liquidPresenceClass::readVoltage(){ + + int aux = 0; + // get actual interruption state flag + bool isEnabled = _intEnabled;// disable interruption + Events.detachInt(); + switch (liquidPresenceSocket){ + case SOCKET_1: + case SOCKET_C: + aux = analogRead(ANALOG5); + #if DEBUG_EVN > 1 + PRINT_EVENT(F("Read SOCKET_1 or SOCKET_C\r\n")); + #endif + break; + case SOCKET_2: + case SOCKET_D: + aux = analogRead(ANALOG4); + #if DEBUG_EVN > 1 + PRINT_EVENT(F("Read SOCKET_2 or SOCKET_D\r\n")); + #endif + break; + case SOCKET_3: + case SOCKET_E: + aux = analogRead(ANALOG3); + #if DEBUG_EVN > 1 + PRINT_EVENT(F("Read SOCKET_3 or SOCKET_E\r\n")); + #endif + break; + case SOCKET_4: + case SOCKET_A: + aux = analogRead(ANALOG7); + #if DEBUG_EVN > 1 + PRINT_EVENT(F("Read SOCKET_4 or SOCKET_A\r\n")); + #endif + break; + case SOCKET_6: + aux = analogRead(ANALOG1); + #if DEBUG_EVN > 1 + PRINT_EVENT(F("Read SOCKET_6\r\n")); + #endif + break; + + default: + #if DEBUG_EVN > 0 + PRINT_EVENT(F("Incorrect input\r\n")); + #endif + break; + } + // re-enable interruption if needed + if( isEnabled == true ) + { + delay(50); + Events.attachInt(); + } + float volts = ((float)aux * 3.3) / 1023.0; + return volts; +} + +//!********************************************************************* +//! Name: readResistance() +//! Description: Read the resistance of the sensor +//! Param : void +//! Returns: float: Resistance value read in KOhms +//!********************************************************************* +float liquidPresenceClass::readResistance(float volts){ + + if ( volts == 0.0 ) + { + // Max value of resistance can be detected is 10.5 MOhm + return 10500.0; + } + else + { + float resistance = (( 3.3 / volts ) - 1.0) * 10.0; + return resistance; + } +} + + //!********************************************************************* //! Name: getInt() //! Description: Get interruption from object diff --git a/libraries/SensorEvent_v30/WaspSensorEvent_v30.h b/libraries/SensorEvent_v30/WaspSensorEvent_v30.h index 0b2514f..4c554fb 100755 --- a/libraries/SensorEvent_v30/WaspSensorEvent_v30.h +++ b/libraries/SensorEvent_v30/WaspSensorEvent_v30.h @@ -1,7 +1,7 @@ /*! \file WaspSensorEvent_v30.h \brief Library for managing the Events Sensor Board - Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. + Copyright (C) 2017 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com This program is free software: you can redistribute it and/or modify @@ -17,7 +17,7 @@ You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . - Version: 3.1 + Version: 3.2 Design: David Gascón Implementation: Carlos Bello @@ -184,7 +184,9 @@ class liquidPresenceClass : public WaspSensorEvent_v30 liquidPresenceClass(uint8_t); uint8_t read(); uint8_t readliquidPresence(); - bool getInt(); + float readVoltage(); + float readResistance(float volts); + bool getInt(); private: uint8_t liquidPresenceSocket; }; diff --git a/libraries/SensorGas_PRO/WaspSensorGas_Pro.cpp b/libraries/SensorGas_PRO/WaspSensorGas_Pro.cpp index e6ea65e..4868dbf 100755 --- a/libraries/SensorGas_PRO/WaspSensorGas_Pro.cpp +++ b/libraries/SensorGas_PRO/WaspSensorGas_Pro.cpp @@ -1,7 +1,7 @@ /* * Library for managing the Gas Pro Sensor Board * - * Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. + * Copyright (C) 2017 Libelium Comunicaciones Distribuidas S.L. * http://www.libelium.com * * This program is free software: you can redistribute it and/or modify @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * - * Version: 3.1 + * Version: 3.2 * Design: David Gascón * Implementation: Alejandro Gállego */ @@ -35,9 +35,8 @@ //! Constructors ///////////////////////////////////////////////////////////// -/* Function: This function owers on the sensor and configures the AFE - * Returns: 1 if OK - * -1 no communication with LMP91000 +/* + * Constructor: This function powers on the sensor and configures the AFE */ Gas::Gas(int socket) { @@ -171,7 +170,7 @@ Gas::Gas(int socket, uint8_t sensor_type, int power_pin, int I2C_pin, float m_co digitalWrite(ANA1, LOW); memcpy(sensor_config.calibration, calibration_table, sizeof(calibration_table)); - + pwrGasPRORegister = 0; } @@ -1480,6 +1479,13 @@ uint8_t Gas::readSensorInfo() #endif return 0; } + + #if GAS_DEBUG>0 + USB.print(F("GP.Checksum generated 0x")); + USB.printHex(generated_checksum); + USB.print(F("; extracted 0x")); + USB.printHex(EEPROM_checksum); + #endif } return 1; diff --git a/libraries/SensorGas_v30/WaspSensorGas_v30.cpp b/libraries/SensorGas_v30/WaspSensorGas_v30.cpp index 9274577..6511211 100644 --- a/libraries/SensorGas_v30/WaspSensorGas_v30.cpp +++ b/libraries/SensorGas_v30/WaspSensorGas_v30.cpp @@ -1,7 +1,7 @@ /*! \file WaspSensorGas_v30.cpp * \brief Library for managing the Gas Sensor Board v30 * - * Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. + * Copyright (C) 2017 Libelium Comunicaciones Distribuidas S.L. * http://www.libelium.com * * This program is free software: you can redistribute it and/or modify @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * - * Version: 3.0 + * Version: 3.1 * Design: David Gascón * Implementation: Ahmad Saad */ @@ -633,6 +633,7 @@ void O2SensorClass::setMUX(void) CO2SensorClass::CO2SensorClass() { // Default gain of the stage + socket = SOCKET_2; gain = 1.08; } @@ -645,6 +646,7 @@ CO2SensorClass::CO2SensorClass() CO2SensorClass::CO2SensorClass(uint8_t _socket) { // Default gain of the stage + socket = _socket; gain = 1.08; } @@ -683,13 +685,13 @@ void CO2SensorClass::ON() { PRINTLN_GASES("CO2 Sensor configured in the SOCKET_E"); - } else if (socket == SOCKET_1) + } else if (socket == SOCKET_2) { PRINTLN_GASES("CO2 Sensor configured in the SOCKET_2"); } else { - PRINTLN_GASES("O2 Sensor wrong configured"); + PRINTLN_GASES("CO2 Sensor wrong configured"); PRINTLN_GASES("Use SOCKET_2 in OEM platform or SOCKET_E in Plug&Sense! platform"); } #endif diff --git a/libraries/WIFI_PRO/WaspWIFI_PRO.cpp b/libraries/WIFI_PRO/WaspWIFI_PRO.cpp index 37c417d..0f8f02a 100755 --- a/libraries/WIFI_PRO/WaspWIFI_PRO.cpp +++ b/libraries/WIFI_PRO/WaspWIFI_PRO.cpp @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * - * Version: 3.1 + * Version: 3.2 * Design: David Gascón * Implementation: Yuri Carmona */ @@ -1379,7 +1379,7 @@ uint8_t WaspWIFI_PRO::setPassword(uint8_t n, uint8_t securityMode, char* pass) // generate command name "WKYn" snprintf(gen_cmd_name, sizeof(gen_cmd_name), format, cmd_name, n); // generate "AT+iWKYn=\r" - GEN_ATCOMMAND1(cmd_name, pass); + GEN_ATCOMMAND1(gen_cmd_name, pass); break; case WPA: @@ -2737,23 +2737,22 @@ uint8_t WaspWIFI_PRO::sendFrameToMeshlium( char* protocol, uint16_t length ) { char cmd_name[20]; - char host_header[50]; - char aux[3]; + char host_header[150]; uint8_t status; uint16_t size = 0; // "\"%s://%s:%s/getpost_frame_parser.php?frame=" - strcpy_P( host_header, (char*)pgm_read_word(&(table_WiReach[10]))); + // "://:/getpost_frame_parser.php?frame=" + sprintf_P( host_header, (char*)pgm_read_word(&(table_WiReach[10])), protocol, host, port); // calculate total size of buffer - size = strlen(protocol) - + strlen(host) - + strlen(port) - + strlen(host_header) - + length*2; - - // define buffer + size = strlen(host_header) + + length*2 + + 1; + + // define buffers char url[size]; + char aux[3]; // clear buffer memset( url, 0x00, sizeof(url) ); @@ -2761,10 +2760,9 @@ uint8_t WaspWIFI_PRO::sendFrameToMeshlium( char* protocol, // init variable _errorCode = ERROR_CODE_0000; - - + // compose "://:/getpost_frame_parser.php?frame=" - snprintf( url, sizeof(url), host_header, protocol, host, port ); + strncat( url, host_header, strlen(host_header)); // make conversion and concatenate to url for (uint16_t i=0 ; i 256) - { - #if DEBUG_WIFI_PRO > 0 - PRINT_WIFI_PRO(F("ERROR. Max URL is 256. Current length: ")); - USB.println( strlen(url), DEC); - #endif + { + PRINT_WIFI_PRO(F("Error. Max URL size is 256. Current length: ")); + USB.println( strlen(url), DEC); + PRINT_WIFI_PRO(F("Current URL: ")); + USB.println(url); _errorCode = ERROR_CODE_0042; return 1; } @@ -5572,14 +5570,30 @@ uint8_t WaspWIFI_PRO::scan() // send command manually printString( _command, _uart ); + // wait for "at+irp20\r\n" status = waitFor( cmd_name, 1000 ); status = waitFor( EOL_CR_LF, 1000 ); if (status != 1) { + #if DEBUG_WIFI_PRO > 0 + PRINT_WIFI_PRO(F("No response from module\n")); + #endif return 1; } - delay(500); + + // check for incoming data while 3 seconds + previous = millis(); + while (serialAvailable(_uart) == 0) + { + if (millis()-previous > 3000) + { + break; + } + + // Condition to avoid an overflow (DO NOT REMOVE) + if (millis() < previous) previous = millis(); + } // update time counter previous = millis(); @@ -5614,7 +5628,7 @@ uint8_t WaspWIFI_PRO::scan() } // check elapsed time - if ((millis() - previous) > 10000) + if ((millis() - previous) > 5000) { // abort userAbort(); diff --git a/libraries/Wasp4G/Wasp4G.cpp b/libraries/Wasp4G/Wasp4G.cpp index 0970e24..bc028cf 100755 --- a/libraries/Wasp4G/Wasp4G.cpp +++ b/libraries/Wasp4G/Wasp4G.cpp @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * - * Version: 3.2 + * Version: 3.3 * Design: David Gascón * Implementation: A. Gállego, Y. Carmona */ @@ -1395,7 +1395,7 @@ uint8_t Wasp4G::checkConnection(uint8_t time) if( millis() < previous) previous = millis(); } - if (((answer != 1) && (answer != 5)) || ((millis() - previous) > (unsigned long)(time * 1000))) + if (((answer != 1) && (answer != 5)) || ((millis() - previous) > (uint32_t) time * 1000)) { if (answer == 0) { @@ -1493,7 +1493,7 @@ uint8_t Wasp4G::checkConnectionEPS(uint8_t time) if (millis() < previous) previous = millis(); // check timeout error - if ((millis() - previous) > (uint32_t)(time * 1000)) + if ((millis() - previous) > ((uint32_t)time * 1000)) { return status; } diff --git a/waspmote-api/WaspConstants.h b/waspmote-api/WaspConstants.h index 5c582c9..41ac1ea 100755 --- a/waspmote-api/WaspConstants.h +++ b/waspmote-api/WaspConstants.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. + Copyright (C) 2017 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com * This program is free software: you can redistribute it and/or modify @@ -15,7 +15,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * - * Version: 3.1 + * Version: 3.2 * Design: David Gascón * Implementation: David Cuartielles, Alberto Bielsa, Yuri Carmona */ @@ -39,7 +39,7 @@ /*! \def WASPMOTE_API_VERSION \brief Waspmote API version number */ -#define WASPMOTE_API_VERSION 26 +#define WASPMOTE_API_VERSION 28 @@ -370,13 +370,14 @@ static const uint16_t REG_WATER_IONS = 8; // bit 3 static const uint16_t REG_GASES = 16; // bit 4 static const uint16_t REG_CITIES_PRO = 32; // bit 5 static const uint16_t REG_EVENTS = 64; // bit 6 -static const uint16_t REG_CITIES_V14 = 128; // bit 7 +static const uint16_t REG_CITIES_V14 = 128; // bit 7 static const uint16_t REG_CITIES_V15 = 256; // bit 8 static const uint16_t REG_RADIATION = 512; // bit 9 static const uint16_t REG_PROTOTYPING = 1024; // bit 10 static const uint16_t REG_PARKING = 2048; // bit 11 static const uint16_t REG_VIDEO_CAMERA = 4096; // bit 12 static const uint16_t REG_WATER = 8192; // bit 13 +static const uint16_t REG_AMBIENT = 16384; // bit 14 /******************************************************************************* diff --git a/waspmote-api/WaspPWR.cpp b/waspmote-api/WaspPWR.cpp index c50493b..81d3ffd 100755 --- a/waspmote-api/WaspPWR.cpp +++ b/waspmote-api/WaspPWR.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. + * Copyright (C) 2017 Libelium Comunicaciones Distribuidas S.L. * http://www.libelium.com * * This program is free software: you can redistribute it and/or modify @@ -15,7 +15,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * - * Version: 3.0 + * Version: 3.2 * Design: David Gascón * Implementation: Alberto Bielsa, David Cuartielles, Yuri Carmona */ @@ -96,33 +96,33 @@ void WaspPWR::setSensorPower(uint8_t type, uint8_t mode) pinMode(SENS_PW_3V3,OUTPUT); pinMode(SENS_PW_5V,OUTPUT); - switch( type ) + switch (type) { case SENS_3V3: - if( mode == SENS_ON ) + if (mode == SENS_ON) { - digitalWrite(SENS_PW_3V3,HIGH); WaspRegister |= REG_3V3; + digitalWrite(SENS_PW_3V3,HIGH); } - else if( mode == SENS_OFF ) + else if (mode == SENS_OFF) { - digitalWrite(SENS_PW_3V3,LOW); WaspRegister &= ~REG_3V3; + digitalWrite(SENS_PW_3V3,LOW); } break; case SENS_5V: - if( mode == SENS_ON ) + if (mode == SENS_ON) { - digitalWrite(SENS_PW_5V,HIGH); WaspRegister |= REG_5V; + digitalWrite(SENS_PW_5V,HIGH); delay(1); } - else if( mode == SENS_OFF ) + else if (mode == SENS_OFF) { - digitalWrite(SENS_PW_5V,LOW); WaspRegister &= ~REG_5V; + digitalWrite(SENS_PW_5V,LOW); } break; @@ -288,6 +288,13 @@ void WaspPWR::switchesOFF(uint8_t option) // switch off monitoring pin pinMode(BAT_MONITOR,OUTPUT); digitalWrite(BAT_MONITOR,LOW); + + // check if an Cities PRO Sensor Board is used. + if (WaspRegisterSensor & REG_CITIES_PRO) + { + // disable I2C isolator + digitalWrite(ANA0, LOW); + } // check if a Smart Metering board has been switched and proceed to disable // the digital pins so as not to waste energy @@ -711,11 +718,18 @@ float WaspPWR::getBatteryVolts() analogReference(INTERNAL2V56); // enables the ADC - sbi(ADCSRA, ADEN); - + sbi(ADCSRA, ADEN); + + // check if it is necessary to turn on the 5v power supply + bool flag = WaspRegister & REG_5V; + + if (!flag) + { + PWR.setSensorPower(SENS_5V, SENS_ON); + } + // power on the components pinMode(BAT_MONITOR, INPUT); - PWR.setSensorPower(SENS_5V, SENS_ON); pinMode(BAT_MONITOR_PW, OUTPUT); digitalWrite(BAT_MONITOR_PW, HIGH); delay(1); @@ -753,8 +767,13 @@ float WaspPWR::getBatteryVolts() //get result result = m; - // power off - PWR.setSensorPower(SENS_5V, SENS_OFF); + // check if it is necessary to turn off the 5v power supply + if (!flag) + { + PWR.setSensorPower(SENS_5V, SENS_OFF); + } + + //turn off digitalWrite(BAT_MONITOR_PW, LOW); // change to DEFAULT diff --git a/waspmote-api/WaspXBeeCore.cpp b/waspmote-api/WaspXBeeCore.cpp index 8c4d493..5939826 100755 --- a/waspmote-api/WaspXBeeCore.cpp +++ b/waspmote-api/WaspXBeeCore.cpp @@ -15,7 +15,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * - * Version: 3.2 + * Version: 3.3 * Design: David Gascón * Implementation: Alberto Bielsa, Yuri Carmona */ @@ -674,7 +674,7 @@ uint8_t WaspXBeeCore::setAwakeTime(uint8_t* awake) int8_t error=2; char buffer[23]; - if( (protocol==XBEE_802_15_4) || (protocol==ZIGBEE) || (protocol==XBEE_868) ) + if( (protocol==XBEE_802_15_4) || (protocol==ZIGBEE) || (protocol==XBEE_868) || (protocol==XBEE_868LP) ) { error_AT=2; @@ -687,7 +687,7 @@ uint8_t WaspXBeeCore::setAwakeTime(uint8_t* awake) error=gen_send(buffer); } - if( (protocol==DIGIMESH) || (protocol==XBEE_900) || (protocol==XBEE_900HP)) + if( (protocol==DIGIMESH) || (protocol==XBEE_900) || (protocol==XBEE_900HP) ) { error_AT=2; @@ -702,7 +702,7 @@ uint8_t WaspXBeeCore::setAwakeTime(uint8_t* awake) if(!error) { - if( (protocol==XBEE_802_15_4) || (protocol==ZIGBEE) || (protocol==XBEE_868) ) + if( (protocol==XBEE_802_15_4) || (protocol==ZIGBEE) || (protocol==XBEE_868) || (protocol==XBEE_868LP) ) { awakeTime[0]=awake[0]; awakeTime[1]=awake[1]; @@ -733,7 +733,7 @@ uint8_t WaspXBeeCore::setSleepTime(uint8_t* sleep) int8_t error=2; char buffer[23]; - if( (protocol==XBEE_802_15_4) || (protocol==ZIGBEE) || (protocol==XBEE_868) ) + if( (protocol==XBEE_802_15_4) || (protocol==ZIGBEE) || (protocol==XBEE_868) || (protocol==XBEE_868LP) ) { error_AT=2; @@ -761,7 +761,7 @@ uint8_t WaspXBeeCore::setSleepTime(uint8_t* sleep) if(!error) { - if( (protocol==XBEE_802_15_4) || (protocol==ZIGBEE) || (protocol==XBEE_868) ) + if( (protocol==XBEE_802_15_4) || (protocol==ZIGBEE) || (protocol==XBEE_868) || (protocol==XBEE_868LP) ) { sleepTime[0]=sleep[0]; sleepTime[1]=sleep[1]; @@ -1041,10 +1041,11 @@ uint8_t WaspXBeeCore::setScanningTime(uint8_t* time) error=gen_send(buffer); } - if( ( protocol == XBEE_868 ) - || ( protocol == DIGIMESH ) - || ( protocol == XBEE_900 ) - || ( protocol == XBEE_900HP ) ) + if( ( protocol == XBEE_868) + || ( protocol == XBEE_868LP) + || ( protocol == DIGIMESH) + || ( protocol == XBEE_900) + || ( protocol == XBEE_900HP) ) { error_AT=2; // set_scanning_time_DM @@ -1063,7 +1064,11 @@ uint8_t WaspXBeeCore::setScanningTime(uint8_t* time) { scanTime[0]=time[0]; } - if( (protocol==DIGIMESH) || (protocol==XBEE_868)|| (protocol==XBEE_900)|| (protocol==XBEE_900HP) ) + if( (protocol==DIGIMESH) + || (protocol==XBEE_868) + || (protocol==XBEE_868LP) + || (protocol==XBEE_900) + || (protocol==XBEE_900HP) ) { scanTime[0]=time[0]; scanTime[1]=time[1]; @@ -1105,7 +1110,11 @@ uint8_t WaspXBeeCore::getScanningTime() { scanTime[0]=data[1]; } - if( (protocol==DIGIMESH) || (protocol==XBEE_868) || (protocol==XBEE_900)|| (protocol==XBEE_900HP)) + if( (protocol==DIGIMESH) + || (protocol==XBEE_868) + || (protocol==XBEE_868LP) + || (protocol==XBEE_900) + || (protocol==XBEE_900HP) ) { scanTime[0]=data[0]; scanTime[1]=data[1]; @@ -1586,7 +1595,7 @@ uint8_t WaspXBeeCore::getPowerLevel() /* Function: Get the Received Signal Strength Indicator of the last received packet - Returns: Returns: Integer that determines if there has been any error + Returns: Returns: Integer that determines if there has been any error error=2 --> The command has not been executed error=1 --> There has been an error while executing the command error=0 --> The command has been executed with no errors @@ -1598,63 +1607,61 @@ uint8_t WaspXBeeCore::getRSSI() uint8_t ByteIN[40]; uint8_t i=0; char buffer[20]; - + //clear buffer - memset( ByteIN, 0x00, sizeof(ByteIN) ); + memset( ByteIN, 0x00, sizeof(ByteIN) ); - if( (protocol == XBEE_802_15_4 ) || (protocol==ZIGBEE) || (protocol==XBEE_900HP) ) + if( (protocol == XBEE_802_15_4 ) || (protocol==ZIGBEE) || (protocol==XBEE_868LP) || (protocol==XBEE_900HP) ) { error_AT=2; - - // get_RSSI + + // get_RSSI strcpy_P(buffer, (char*)pgm_read_word(&(table_CORE[33]))); if(buffer==NULL) return 1; gen_data(buffer); error = gen_send(buffer); + + if (error == 0) + { + valueRSSI[0] = data[0]; + } } else if( (protocol== DIGIMESH) || (protocol==XBEE_868) || (protocol==XBEE_900) ) { - delay(200); - flush(); - printString("+++", uart); - delay(2000); - flush(); - printString("atdb\r\n", uart); - delay(1000); - error_AT = 2; - while(serialAvailable(uart)>0) - { - ByteIN[i]=serialRead(uart); - error = 0; - i++; - error_AT = 0; - if(i>=sizeof(ByteIN)-1) - { - break; - } - } - printString("atcn\r\n", uart); - - // in the case only one byte is read, compose a 2-byte hexadecimal - if(i==2) - { - ByteIN[1]=ByteIN[0]; - ByteIN[0]=0x30; - } - ByteIN[i]='\0'; - i=0; - valueRSSI[0]=Utils.str2hex(ByteIN); - - } - - if( error == 0 ) - { - if( (protocol==XBEE_802_15_4) || (protocol==ZIGBEE) || (protocol==XBEE_900HP) ) + delay(200); + flush(); + printString("+++", uart); + delay(2000); + flush(); + printString("atdb\r\n", uart); + delay(1000); + error_AT = 2; + while(serialAvailable(uart)>0) { - valueRSSI[0] = data[0]; - } - } + ByteIN[i]=serialRead(uart); + error = 0; + i++; + error_AT = 0; + if(i>=sizeof(ByteIN)-1) + { + break; + } + } + printString("atcn\r\n", uart); + + // in the case only one byte is read, compose a 2-byte hexadecimal + if(i==2) + { + ByteIN[1]=ByteIN[0]; + ByteIN[0]=0x30; + } + ByteIN[i]='\0'; + i=0; + valueRSSI[0]=Utils.str2hex(ByteIN); + + } + return error; } @@ -1865,7 +1872,8 @@ uint8_t WaspXBeeCore::setSleepOptions(uint8_t soption) || ( protocol == DIGIMESH ) || ( protocol == XBEE_900 ) || ( protocol == XBEE_868 ) - || ( protocol == XBEE_900HP ) ) + || ( protocol == XBEE_868LP) + || ( protocol == XBEE_900HP ) ) { error_AT = 2; @@ -1910,8 +1918,9 @@ uint8_t WaspXBeeCore::getSleepOptions() if(( protocol == ZIGBEE ) || ( protocol == DIGIMESH ) || ( protocol == XBEE_900 ) - || ( protocol == XBEE_868 ) - || ( protocol == XBEE_900HP ) ) + || ( protocol == XBEE_868 ) + || ( protocol == XBEE_868LP) + || ( protocol == XBEE_900HP ) ) { error_AT = 2; gen_data(buffer); @@ -2056,7 +2065,8 @@ uint8_t WaspXBeeCore::getDestinationAddress(uint8_t* naD) else if(( protocol == ZIGBEE ) || ( protocol == DIGIMESH ) || ( protocol == XBEE_900 ) - || ( protocol == XBEE_868) + || ( protocol == XBEE_868) + || ( protocol == XBEE_868LP) || ( protocol == XBEE_900HP) ) { naD[0]=0x00; @@ -3894,7 +3904,7 @@ int8_t WaspXBeeCore::parse_message(uint8_t* frame) { interval=20000; if(protocol==DIGIMESH) interval=40000; - else if( (protocol==XBEE_900) || (protocol==XBEE_868) ) + else if( (protocol==XBEE_900) || (protocol==XBEE_868) || ( protocol == XBEE_868LP) ) { interval=14000; } @@ -4186,6 +4196,7 @@ uint8_t WaspXBeeCore::atCommandResponse( uint8_t* data_in, if( (protocol == DIGIMESH || protocol == XBEE_900 || protocol == XBEE_868 || + protocol == XBEE_868LP || protocol == XBEE_900HP ) && data_in[start+7]==0x40 ) { // do nothing. it is a valid response because these protocols @@ -4881,6 +4892,7 @@ void WaspXBeeCore::treatScan() protocol == DIGIMESH || protocol == XBEE_900 || protocol == XBEE_868 || + protocol == XBEE_868LP || protocol == XBEE_900HP ) { if (data_length>19) @@ -5159,7 +5171,7 @@ uint8_t WaspXBeeCore::new_firmware_received() } /// 868 or 900 Multicast or Unicast with new encryption key setting - if( (packet_finished[pos-1]->data_length==63) && (protocol==XBEE_868 || protocol==XBEE_900)) + if( (packet_finished[pos-1]->data_length==63) && (protocol==XBEE_868 || protocol==XBEE_900 || protocol==XBEE_868LP)) { // Copy 'Encryption key' from packet for (it = 0; it < 16;it++) diff --git a/waspmote-api/Wire.cpp b/waspmote-api/Wire.cpp index 5cddc91..a030ebb 100755 --- a/waspmote-api/Wire.cpp +++ b/waspmote-api/Wire.cpp @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * - * Version: 3.1 + * Version: 3.2 */ extern "C" { @@ -364,12 +364,13 @@ void TwoWire::secureBegin() // this codeblock belongs to the performance of the I2C bus // check if any Sensor Board (with I2C components) is ON before using I2C - if ((WaspRegisterSensor & REG_METERING) || + if ((WaspRegisterSensor & REG_METERING) || (WaspRegisterSensor & REG_AGRICULTURE) || - (WaspRegisterSensor & REG_GASES) || + (WaspRegisterSensor & REG_GASES) || (WaspRegisterSensor & REG_EVENTS) || (WaspRegisterSensor & REG_CITIES_V14) || (WaspRegisterSensor & REG_CITIES_V15) || + (WaspRegisterSensor & REG_AMBIENT) || (WaspRegisterSensor & REG_PROTOTYPING)) { if (Wire.isBoard == false) @@ -379,7 +380,7 @@ void TwoWire::secureBegin() #endif // It is necessary to switch on the power supply if the Sensor Board is // connected to Waspmote so as not to cause intereferences in the I2C bus - if ((WaspRegisterSensor & REG_EVENTS) && !_3V3_ON) + if (((WaspRegisterSensor & REG_EVENTS)||(WaspRegisterSensor & REG_AMBIENT)) && !_3V3_ON) { PWR.setSensorPower(SENS_3V3, SENS_ON); delay(50); @@ -412,6 +413,7 @@ void TwoWire::secureEnd() (WaspRegisterSensor & REG_EVENTS) || (WaspRegisterSensor & REG_CITIES_V14) || (WaspRegisterSensor & REG_CITIES_V15) || + (WaspRegisterSensor & REG_AMBIENT) || (WaspRegisterSensor & REG_PROTOTYPING)) { // this codeblock belongs to the performance of the SD card @@ -420,17 +422,17 @@ void TwoWire::secureEnd() { #if DEBUG_I2C > 0 PRINT_I2C(F("Sensor Board power OFF\n")); - #endif + #endif // switch OFF sensor boards to previous state before 'secureBegin' - if (WaspRegisterSensor & REG_EVENTS) + if ((WaspRegisterSensor & REG_EVENTS)||(WaspRegisterSensor & REG_AMBIENT)) { - PWR.setSensorPower(SENS_3V3, SENS_OFF); + PWR.setSensorPower(SENS_3V3, SENS_OFF); } else { PWR.setSensorPower(SENS_3V3, SENS_OFF); - PWR.setSensorPower(SENS_5V, SENS_OFF); + PWR.setSensorPower(SENS_5V, SENS_OFF); } } else