itbrainpower.net
THE ALPHABET PROJECT - professional Arduino, BeagleBone & Raspberry PI shields

LTE CATM1 or GSM temperature and humidity IOT CLOUD monitoring using xyz-mIOT

 

LTE CATM1 or GSM temperature and humidity IOT CLOUD monitoring using xyz-mIOT :: how to

 

About project

LTE CATM1 or GSM temperature and humidity IOT CLOUD monitoring using xyz-mIOT :: xyz-mIOT equipped with BG96, top side - size representation
Use of-the-self xyz-mIOT shield temperature and humidity sensors as CLOUD sensor data loggers. T minus 15 minutes.

At April 08th 2018, R&D Software Solutions srl [itbrainpower.net] revealed to the public the announcement of the xyz-mIoT by itbrainpower.net shield - the first, and the most compact, IoT board that combines the versatility of ARM0 micro-controller (Microchip/Atmel ATSAMD21G in Arduino Zero compatible design), the comfortable use of the embedded sensors bundle with conectivity provided by LPWR LTE CAT M1 or NB-IoT long-range & low-power modems or legacy 3G / GSM modems.

The xyz-mIoT shield may have up to 5 integrated sensors, as: THS (temperature and humidity sensors) - HDC2010, tVOC & eCO2 (air quality sensor - CO2 total volatile organic compounds- CO2 equivalent) - CCS811 , HALL (magnetic sensor) - DRV5032 sau or IR (infrared sensor) KP-2012P3C , secondary IR (infrared sensor) - KP-2012P3C , TILT (movement vibration sensor) or REED (magnetic sensor) - SW200D.
Embedded sensors that populates the xyz-mIoT shield are dependent on PN ordered (check here for available PN).

Required time: 10-15 minutes.
The implementation time may vary depending on previous user experience. Arduino environment installing and manual Arduino class installing are not covered by this how to; try google it. Support libraries and the source code used in this how to are available for download, for registered users here.

Difficulty: beginner - intermediate.

 

Bill of materials

  • xyz-mIoT shield having integrated HDC2010 sensor, as following PN:
    XYZMIOT209#BG96-UFL-1100000 [LTE CAT M1 and GSM modem],
    or
    XYZMIOT209#M95FA-UFL-1100000 [GSM only modem]
  • micro-sze [4FF] LTE CATM1 or 2G SIM card [having data plan enabled]
  • small LiPo battery
  • GSM embedded antenna with uFL [check xyz-mIoT accesories] or,
  • GSM antenna with SMA plus u.FL to SMA pigtail [check xyz-mIoT accesories]

 

Step1 [hardware, soldering]:

LTE CATM1 or GSM temperature and humidity IOT CLOUD monitoring using xyz-mIOT :: xyz-mIoT via USB powering

Enable 5V from USB to be as primary power supply for the board as described up here. Alternative: solder both connectors rows, place the board into one breadboard and connect between Vusb and Vraw using one male-male breadboard wire.

Solder the LiPo connector. Keep in mind the LiPO polarity!

DOUBLE CHECK YOUR SOLDERINGS!!!.

 

Step2 [hardware, bring all together]:

Insert the micro-SIM in his slot [the SIM must have the PIN check procedure removed]. Connect the antenna, then connect the USB cable to xyz-mIoT USB port and to your computer. Connect the LiPo battery. LTE CATM1 or GSM temperature and humidity IOT CLOUD monitoring using xyz-mIOT :: all hardware wired together

 

Step 3 [software download and install, preliminarii settings]

a. Download and install "xyz-mIoT shields Arduino class", then download the last version of classes: "xyz-mIOT shield IoT Rest support" and "xyz-mIOT shield sensors support class" from here.
b. Install the classes. Uncompress the archives and install the classes - in a nutshell:
- copy the "xyz-mIoT shields Arduino class" files in Arduino local hardware folder (mine is: "C:\Users\dragos\Documents\Arduino\hardware"), then
- copy the the support classes folders into your Arduino local user folder [mine is: "C:\Users\dragos\Documents\Arduino\libraries"] and
- restart Arduino environment.
More detail about manual library installing, read Arduino library manual installation.

c. Make a folder named "xyz_mIoT_v41_temp_humidity".

d. Copy the code bellow, paste it one new file and save the file as "xyz_mIoT_v41_temp_humidity.ino" in the folder created in previous step. Alternate, you can download from here (right click & save as):
LTE CATM1 or GSM temperature and humidity IOT CLOUD monitoring using xyz-mIOT - Arduino main code

xyz_mIoT_v41_temp_humidity.ino

1/*
2xyz_mIoT_cloud_demo.ino v 0.41a/20180712 - SOFTWARE EXAMPLE
3COPYRIGHT (c) 2015-2018 Dragos Iosub / R&D Software Solutions srl
4
5You are legaly entitled to use this SOFTWARE ONLY IN CONJUNCTION WITH xyz-mIOT by itbrainpower.net DEVICES USAGE. Modifications, derivates and 
6redistribution of this software must include unmodified this COPYRIGHT NOTICE. You can redistribute this SOFTWARE and/or modify it under the terms 
7of this COPYRIGHT NOTICE. Any other usage may be permited only after written notice of Dragos Iosub / R&D Software Solutions srl.
8
9This SOFTWARE is distributed is provide "AS IS" in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied 
10warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
12Dragos Iosub, Bucharest 2018.
13https://itbrainpower.net
14*/
15/*IMPORTANT NOTICE 1: check in itbpGSMdefinition.h, line 69 set __itbpModem__    xyzmIoT and choose __xyzmIoTmodem__ from lines 70-71*/
16/*IMPORTANT NOTICE 2: for BG96 variants --> CATM1/GSM configuration mode and priority search ...see function call at lines 246->254*/
17/*IMPORTANT NOTICE 3: temperature and humidity data available only for variants having HDC2010 sensor embedded (PN sufix file: 1xxxxxx);
18variants w/o HDC2010 sensor embedded - dummy values are generated... you may like to implement something with rand() function?*/
19
20/*REST cloud specific, more parameters in itbpGPRSIPdefinition.h*/
21#define cloudURL        "http://iot.robofun.ro/api/v1/senzor/"
22#define sensorValURL    "/input?value="
23#define tempTocken      "74g0rvibt3cskrpb5457r4jv45"    //replace with your temperature sensor tocken
24#define humiTocken      "mp86hppb262b832df1vecrsg5g"    //replace with your humidity sensor tocken
25
26int samplingPeriod = 60;       //interval in seconds between scans... keep it > 60 sec
27
28/*local vars, sensors and actuators exchanged with the cloud*/
29//char dttime [31];
30char IMEI [16];  
31double temperature = 0;
32double humidity = 0;
33/*local vars, sensors and actuators exchanged with the cloud*/
34
35
36#include <itbpGSMClass.h>
37
38#define DEBUG(x)    {__itbpDebugPort__.print(millis());__itbpDebugPort__.print(" - ");__itbpDebugPort__.println(x);}
39#define DEBUGP(x,y) {__itbpDebugPort__.print(millis());__itbpDebugPort__.print(" - ");__itbpDebugPort__.print(x);__itbpDebugPort__.println(y);}
40
41#if (__itbpModem__ != xyzmIoT)
42+  int freeRam () {
43    extern int __heap_start, *__brkval; 
44    int v; 
45    return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
46  }
47#endif
48
49// initialize the library instance
50aGsmClient client;
51
52
53/* sensor side here */
54#include <HDC2010.h>    //I2C THS HDC2010 from Texas [option for xyz-mIoT]
55/*following definitions [used in software] are placed in xyz-mIoT variant.h
56HDC2010 related:
57- I2C_HDC2010_ADDRESS 0x40        //default HDC2010 I2C address
58- HDC2010_INTERRUPT_PIN 5         //pin mapped as IRQ for HDC2010. Confort zone example. Read HDC2010 documentation for more.
59
60HALL related:
61- HALL_IRQ_PIN 6                  //IRQ used for HALL. Or read this pin value for pulling mode.
62- HALL_PULLUP_PIN 25              //pullup this pin in order to enable HALL sensor readings.
63
64Voltage measurments:
65- VbatPin A5
66- VrawPin A4
67
68Modem control assigned digital pis:
69- CTRL_PIN_MODEMPOWER         38        //Digital pin used enable/disable modem power
70- lprCtrlPIN                  26        //Digital pin used to control the modem on/off
71- CTRL_PIN_GNSSANTENNAPOWER   4         //Digital pin used to control the active GNSS antenna power
72*/
73HDC2010 sensor(I2C_HDC2010_ADDRESS);
74/* sensor side here */
75
76
77unsigned long startTime = 0;
78
79bool ledState = 0;
80
81
82/*
83  Function to parse the server responce
84  Vars:
85    Type     ==> GETACTUATOR / POSTSENSOR
86    value    ==> int [send this value for SENSOR, update this for ACTUATOR]
87    timeout  ==> int, timeout in seconds to wait for and parse the server responce
88  Returns:
89    1 on success
90    0 on error [found closed socket or PDP deactivation]
91    -1 on server timeout
92*/
93int readServerResponse(int timeout){
94
95  unsigned long startTime;
96  int ret =0;
97  startTime = millis(); 
98  delay(10);
99  __itbpDebugPort__.println(F("start read..."));
100  while(true){
101    client.readline(1000);
102    __itbpDebugPort__.println(client.resp);//just to see the server response
103    if (strstr(client.resp, "1;"))
104    {
105        __itbpDebugPort__.println(F("found confirmation..."));
106        ret = 1;
107    }
108
109    if (strstr(client.resp, "0;"))
110    {
111        __itbpDebugPort__.println(F("error returned..."));
112        ret = -1;
113    }
114    
115    if (strstr(client.resp, sockDisconnected0)||strstr(client.resp, sockDisconnected1)||strstr(client.resp, sockDisconnected2))
116    {
117        __itbpDebugPort__.println(F("sk disconnected..."));
118        client.stop();  //4 LTE and 3G
119        return ret;
120    }//sockDisconnected0
121    
122    if(millis() - startTime > (unsigned long)timeout*1000 )
123    {
124       __itbpDebugPort__.println(F("mark to..."));
125        client.stop(); //need to clean DATA interface and return the to AT command interface 
126        return -2;        
127    }  
128 }
129  return -3;//never here
130}
131
132
133
134
135void sendGetRequest(char * sensorTocken, double sensorData){
136    String data;
137    //data = String(cloudURL) + String(sensorTocken) + String(sensorValURL) + String(humidity, DEC);
138    data = String(cloudURL) + String(sensorTocken) + String(sensorValURL) + String(sensorData);
139    __itbpDebugPort__.println(data);
140
141    client.print("GET ");
142    client.print(data);
143    client.println(" HTTP/1.1");
144    client.println(F("Host: " SERVER_ADDRESS));
145    client.println(F("Connection: close"));
146    client.println();
147}
148
149
150
151void sendData( void){
152    //send temperture data
153    if (client.connected() || client.connect()){
154
155      sendGetRequest(tempTocken, temperature);
156
157      readServerResponse(SERVER_REPLY_TIMEOUT);
158    }else{
159      __itbpDebugPort__.println(F("Socket/GPRS error...")); 
160    }
161    //send humidity data
162    if (client.connected() || client.connect()){
163      //client.print(demoData);
164      sendGetRequest(humiTocken, humidity);
165      //client.println("\r\n");
166      readServerResponse(SERVER_REPLY_TIMEOUT);
167    }else{
168      __itbpDebugPort__.println(F("Socket/GPRS error...")); 
169    }
170}
171
172
173void setup(){
174#if (__itbpModem__ == xyzmIoT)
175 delay(10000);
176
177  /*
178  pinMode(HALL_PULLUP_PIN, OUTPUT);
179  digitalWrite(HALL_PULLUP_PIN, HIGH);   // power the HALL sensor
180  */
181
182#endif
183
184  __itbpDebugPort__.begin(115200);   //start debug port connection
185  //configure led
186 pinMode(LED_BUILTIN, OUTPUT);               //embedded LED status indicator  
187 digitalWrite(LED_BUILTIN, LOW);   
188  ledState = 0;
189
190 /*sensor side*/
191 sensor.begin();                  //I2C THS sensor init
192  sensor.reset();                     //reset H2010
193
194  //sensor.setTemperatureOffset(0b11000000);  //-10.32
195  sensor.setTemperatureOffset(0b11010111);    //-6.64
196  
197  // Set up the comfort zone
198  sensor.setHighTemp(28);         // High temperature of 28C
199  sensor.setLowTemp(22);          // Low temperature of 22C
200  sensor.setHighHumidity(55);     // High humidity of 55%
201  sensor.setLowHumidity(40);      // Low humidity of 40%
202
203  // Configure interrupt pin
204  /*sensor.enableInterrupt();                   // Enable the Interrupt/DRDY pin
205  sensor.enableThresholdInterrupt();          // Enable Interrupt triggering based on comfort zone
206  sensor.setInterruptPolarity(ACTIVE_HIGH);   // Set Interrupt pin to Active High
207  sensor.setInterruptMode(COMPARATOR_MODE);   // Set Interrupt to return to inactive state when in bounds
208  */
209    // Configure Measurements
210  sensor.setMeasurementMode(TEMP_AND_HUMID);  // Set measurements to temperature and humidity
211  //sensor.setRate(ONE_HZ);                     // Set measurement frequency to 1 Hz
212  sensor.setRate(MANUAL);                     // Set measurement frequency to 1 Hz
213  sensor.setTempRes(FOURTEEN_BIT);
214  sensor.setHumidRes(FOURTEEN_BIT);
215
216  /*
217  // Configure Measurements
218  //sensor.setRate(ONE_HZ);                     // Set measurement frequency to 1 Hz
219
220  // Configure THS Interrupt Pin
221  pinMode(HDC2010_INTERRUPT_PIN, INPUT);                   // HDC2010_INTERRUPT_PIN will be the interrupt input
222  attachInterrupt(digitalPinToInterrupt(HDC2010_INTERRUPT_PIN), alertTHS, CHANGE);  //ISR "alertTHS" will be triggered by changes in ALERTTHSPIN
223  // Configure HALL Interrupt Pin
224  pinMode(HALL_IRQ_PIN, INPUT_PULLUP);                   // HALL_IRQ_PIN will be the interrupt input
225  attachInterrupt(digitalPinToInterrupt(HALL_IRQ_PIN), alertHALL, CHANGE);  //ISR "alertHALL" will be triggered by changes in ALERTHALLPIN
226
227  */
228  //begin measuring
229  sensor.triggerMeasurement();
230  temperature = /*100**/(double)sensor.readTemp();
231  humidity = /*100**/(double)sensor.readHumidity();
232 /*sensor side*/
233
234
235
236#if __itbpModem__ != xyzmIoT
237 DEBUGP(F("Free RAM: "), freeRam());
238#endif
239__itbpDebugPort__.println(F("...let's rock"));
240__itbpDebugPort__.flush();
241 
242 client.begin();
243
244 
245 #if __xyzmIoTmodem__ == CATM1 // for BG96 modems
246    //Set bands, scan mode, scan sequence for BG96 only!!! Only just after client.begin()!        
247    //client.setScanSequence(SCANSEQ_CATM1, SCANSEQ_GSM, SCANSEQ_NBIOT ); //left to right priority
248    client.setScanSequence(SCANSEQ_GSM, SCANSEQ_CATM1, SCANSEQ_NBIOT );
249
250    //client.setRegistrationMode(RegisterGSM);                  //GSM only registration mode allowed
251    //client.setRegistrationMode(RegisterCATM1);                //CAT-M1 only registration mode allowed
252    client.setRegistrationMode(RegisterBOTH);                   //CAT-M1 or GSM registration mode allowed
253    
254    client.setBands(GSM_ALL, LTE_CATM1_ALL, LTE_NBIOT_ALL);     //definitions in itbpGSMdefinition.h
255#endif
256
257 client.enableClockUpdate(1); //update available at next GSM boot
258
259 client.getIMEI(); //IMEI value in client.resp
260 memset(IMEI,0x00, sizeof(IMEI));
261 strcpy(IMEI,client.resp);
262 DEBUGP(F("IMEI: "), IMEI);
263
264 client.attachGPRS();
265 __itbpDebugPort__.println("connecting...");
266 
267 
268  startTime = millis() + (unsigned long)samplingPeriod*1000;//force send on the spot
269}
270
271
272
273
274void loop(){
275 if (millis() - startTime < (unsigned long)samplingPeriod*1000){//waiting period
276    //__itbpDebugPort__.println(F("..."));
277    //digitalWrite(25, LOW);  
278    //digitalWrite(26, HIGH);  
279
280  ledState = ! ledState;
281  if(ledState != 0)
282    digitalWrite(LED_BUILTIN, HIGH); 
283  else
284    digitalWrite(LED_BUILTIN, LOW); 
285  delay(500);
286   
287 }
288 else{
289    //digitalWrite(25, HIGH);  
290    //digitalWrite(26, LOW);  
291
292  startTime = millis();
293  digitalWrite(LED_BUILTIN, HIGH);   //show sampling + uploadto cloud
294
295  __itbpDebugPort__.println(F(""));
296  
297  
298  sensor.triggerMeasurement();
299    delay(500);
300    temperature = /*100**/(double)sensor.readTemp();
301    humidity = /*100**/(double)sensor.readHumidity();
302    DEBUGP(F("Temp: "),temperature);
303    DEBUGP(F("Hum%: "),humidity);
304    /*
305  alarmHALL = digitalRead(ALERTHALLPIN);
306    DEBUGP(F("Hall: "),alarmHALL);
307  
308  if (client.connected()) client.transparentescape();         //switch to AT mode - not really neaded, but just to be sure
309  
310  client.getVoltage(); //Vbat value in client.resp
311  VBAT = atof(client.resp);
312  DEBUGP(F("Voltage: "),VBAT);
313
314  client.getRTC(); //RTC value in client.resp
315  memset(dttime, 0x00, sizeof(dttime));
316  strcpy(dttime,client.resp);
317  DEBUGP(F("Time: "),dttime);
318  */
319  if (!client.connected()) client.transparent(); //switch to transparent socket mode, if available
320  
321  DEBUG(F("send sensors start"));
322  sendData();     //push sensors to the cloud
323  DEBUG(F("send sensors stop"));
324  
325    digitalWrite(LED_BUILTIN, LOW);     //show sampling + uploadto cloud
326  ledState = 0;
327 }
328
329}
330

e. Make some settings in some files contained inside "xyz-mIOT shield IoT Rest support" class
- in "itbpGPRSIPdefinition.h" set the APN value, using the APN value of your GSM provider (Eg: NET for RO Orange)
- in "itbpGPRSIPdefinition.h" set the SERVER_ADDRESS address for CLOUD Robofun
#define SERVER_ADDRESS "iot.robofun.ro"
#define SERVER_PORT "80"

- in "itbpGSMdefinition.h" comment default option for "__itbpModem__" and choose (delete comment sign) option
"#define __itbpModem__ xyzmIoT" (line 69)
- in "itbpGSMdefinition.h" choose the right modem for your xyz-mIoT flavour: for M95FA choose
"#define __xyzmIoTmodem__ TWOG" (line 71)
or for BG96 choose
"#define __xyzmIoTmodem__ CATM1" (line 70)

 

Step4 [Robofun cloud - define new sensors and copy TOKEN settings.]

Open https://iot.robofun.ro.

Create new account.
LTE CATM1 or GSM temperature and humidity IOT CLOUD monitoring using xyz-mIOT :: CREATE NEW CLOUD ACCOUNT

Add two new sensors (xyzmIOT_temperature and xyzmIOT_humidity).
LTE CATM1 or GSM temperature and humidity IOT CLOUD monitoring using xyz-mIOT :: create new sensor
Scroll down the page until "TOKEN" chapter.
LTE CATM1 or GSM temperature and humidity IOT CLOUD monitoring using xyz-mIOT :: copy cloud sensor token id


For each sensor, retain the "Tocken" id values. Those values will be used, next, to set sensors id[token id] in Arduino code.

In same page, a little bit above you will find the public Internet address where you will find the sensor data (observe marked in above picture).

 

Step5 [Arduino - sensors Tocken id, compile and upload IOT code]

Open in Arduino[(arduino.cc v >= 1.8.5] the xyz_mIoT_v41_temp_humidity.ino project.
LTE CATM1 or GSM temperature and humidity IOT CLOUD monitoring using xyz-mIOT :: ARDUINO SET SENSOR TOKEN a. Set tempTocken and humiTocken values with the one retained in previous step [created in the CLOUD].

HINT: If you use xyz-mIoT shield equipped with Quectel BG96 module you may like to set the network scan sequence, set/restrict the LTE and GSM bands used or to select the network registration mode as "RegisterGSM", "RegisterBOTH" or as "RegisterCATM1" (to be able to access LTE CAT-M1 services the mobile network used and the SIM card must support LTE CATM1*) ...see functions calls at lines 246->254, right after client.begin() in function setup().
* we use for tests RO Orange LTE CATM1 enabled SIM.

b. Press twice (fast) the xyz-mIoT shield RESET button [the board will switch into programming mode]. LTE CATM1 or GSM temperature and humidity IOT CLOUD monitoring using xyz-mIOT :: ARDUINO SET xyz-mIoT board and port Select "itbrainpower.net xyz-mIoT" board and "itbrainpower.net xyz-mIoT" programming port in Arduino menu.

c. Compile and upload the code.

The xyz-mIoT shield will start to sample the temperature and humidity data (at 1min. rate) and to upload sampled values to the CLOUD.

LTE CATM1 or GSM temperature and humidity IOT CLOUD monitoring using xyz-mIOT :: debug messages In order to visualize the debug output use the Arduino Serial Monitor or other terminal by selecting the debug port with following settings: 115200bps, 8N, 1.

The temperature logged data can be visualized in Robofun cloud sensor page or, in public (shared) page as we specified in Step4 .
LTE CATM1 or GSM temperature and humidity IOT CLOUD monitoring using xyz-mIOT :: CLOUD SENSOR DATASET

 

ENJOY!

 

 

TUTORIAL PROVIDED WITHOUT ANY WARRANTY!!! USE IT AT YOUR OWN RISK!!!!

 

 

 

Dragos Iosub & itbrainpower.net team original how to.

 

 

 

 

document version 0.911 / 2018-07-12 © R&D Software Solutions srl