PPM or PPB

Enrique UCLM
Posts: 18
Joined: Wed Apr 24, 2019 11:13 am
Company: UCLM

Re: PPM or PPB

Post by Enrique UCLM » Thu Nov 07, 2019 9:37 am

Good morning

As I said in the previous POST, today it is impossible to show an exit console because they are 5 meters high placed in the streetlights of the city.

On the other hand, since August 15 one of our sensors has stopped working and yesterday another also stopped. The programming is the same in all the nodes we buy (total 4) and the only one that gives correct measures is the one we sent you to fix and that covered the warranty. Both sensors have been turned off for a day to see if it was the fault of the battery, however, remain unanswered.

I would like to get in touch with you to talk about the problems we are having with both the bad sensor measurements and the problems of shutdown and inactivity.

Greetings,

Enrique.

libelium-dev
Posts: 27967
Joined: Mon Sep 28, 2009 1:06 pm

Re: PPM or PPB

Post by libelium-dev » Fri Nov 08, 2019 10:39 am

Hi,

What is the battery level of the nodes? Could it be a coverage problem?

In order to debug the issue in more deep, it is necessary to access to the logs of the nodes. We can't analyze the problem without that information.

Regards

Enrique UCLM
Posts: 18
Joined: Wed Apr 24, 2019 11:13 am
Company: UCLM

Re: PPM or PPB

Post by Enrique UCLM » Tue Nov 12, 2019 9:13 am

There is no battery level problem as the sensor that stopped working 11 days ago was at 88 %.

The other node that has been stopped longer was 22% last measurement so it has no problem either. In addition, we turned off this sensor for 2 days with a lot of sun to see if it was a battery problem, however, it did not work at all. https://www.libelium.com/forum/viewtopi ... 780#p83780

As I have told you in previous POST, it is not possible to get the log of the sensors as they are placed in the streetlights. I would like to meet you by Skype and solve this problem as soon as possible. The only sensor that works perfectly is the sensor that we sent to repair and we fear that it is a defective batch because there are quite a few irregularities.

Greetings,

Enrique.

libelium-dev
Posts: 27967
Joined: Mon Sep 28, 2009 1:06 pm

Re: PPM or PPB

Post by libelium-dev » Wed Nov 13, 2019 9:16 am

Hi,

We know that you can't access the node now but you should take the node to try to solve the issue. We can't help you without check the log through the serial monitor, we need to know more information to know tha cause of the problem.

Does the node try to perform OTA? Maybe the process failed and the firmware of the node is corrupted. Without analyzing the node physically we can only make deductions, we can't know the real cause of the problem or how to repair it.

Regards

Enrique UCLM
Posts: 18
Joined: Wed Apr 24, 2019 11:13 am
Company: UCLM

Re: PPM or PPB

Post by Enrique UCLM » Tue Dec 03, 2019 12:00 am

Good night.

We've lowered the faulty sensors that were placed on the streetlights. I formatted the SDs as you suggested in a previous post. Also, I did a couple of tests to check if there were battery problems. They have no battery problem both have more than 40%.

On the other hand, at the time of executing the sketch and studying the output appears a problem when using the 4G module, "Operation not allowed". I enclose two code extracts and their corresponding output.

First code. This is the code that the 4 waspmote nodes that we buy from you have uploaded. 2 of them work perfectly with this programming and other 2 do not work because they have the this problem.

Code: Select all

/* @Enrique Brazalez --> ReTiCS - UCLM*/
// Include libraries
#include <Wasp4G.h>
#include <WaspSensorCities_PRO.h>
#include <WaspOPC_N2.h>

bool draft = true;
char warming_time[12];
char deep_sleep_time[12];


/* Error and time counters*/
uint8_t error;
uint32_t previous;
uint32_t previoOTA;
unsigned long PM_TimeOffset = 800000;//To take a pm measure every 5 minutes, i.e., 300 seconds approximately
unsigned long OTA_TimeOffset = 48000000;
/* OTA status */
int status;

/* PM measure variables */
bool pm = false;
int pm_measure;

/* APN settings (4G) */
char apn[] = "telefonica.es";
char login[] = "telefonica";
char password[] = "telefonica";

/* Server credentials */
char hostESB[] = "xxx.xxx.xxx.xxx";
char user[]="xxxx";
char pass[]="xxxx";
uint16_t portOTA = xxxx;
uint16_t portESB = xxxx;
char resourceESB[] = "/test";
char idStation[] = "WaspmoteUCLM";
uint8_t response;
uint8_t connection_status;

/* Gas Sockets */
Gas gas_sensor_CO(SOCKET_F);
Gas gas_sensor_NO2(SOCKET_B);
Gas gas_sensor_O3(SOCKET_C);
float concentration_CO = 0.0;  // Stores the CO concentration level in ppm
float concentration_NO2 = 0.0;  // Stores the NO2 concentration level in ppm
float concentration_O3 = 0.0;  // Stores the O3 concentration level in ppm

/* Basic sensor Sockets */
bmeCitiesSensor  bme(SOCKET_A);
luxesCitiesSensor  luxes(SOCKET_E);
float temperature;  // Stores the temperature in ºC
float humidity;   // Stores the realitve humidity in %RH
float pressure;   // Stores the pressure in Pa
uint32_t luminosity; // Stores the luminosity in Luxes (lx)

/* Waspmote's Serial ID */
char NumSerie[17];

void setup() {
  USB.println(F("---------------------------------------------------------------------------------------------------\n"));
  USB.println("                                         SETUP \n");
  USB.println(F("---------------------------------------------------------------------------------------------------\n"));
  /* Init the variables to sleep */
  initCalmVariables();
  /* We check the battery level */
  checkBattery();
  /* Extract Serial ID */
  initId();
  /* Boards ON: IT SWITHCS THE SENSOR BOARD TO 3,3 volts */
  PWR.setSensorPower(SENS_3V3, SENS_ON);
  /* Turn on the communication modules and turn on correctly the sensor clock*/
  checkModules();
  /* Init Watchdog for not be lazy */
  RTC.setWatchdog(30);
  USB.println(F("Watchdog settings:"));
  USB.println(RTC.getWatchdog());
  /* Show OTA Settings */
  USB.println(F("-------------------------------------------------------------------------------------------------------------------------------------------------------------------------"));
  USB.println("                               OTA CONFIGURATION");
  //Utils.setProgramVersion(1);
  status = Utils.checkNewProgram();
  USB.print(" Status : ");
  USB.println(status);
  USB.print(" Program version: ");
  USB.println(Utils.getProgramVersion(),DEC);
  switch(status){
    case 0:
      USB.println(F("REPROGRAMMING ERROR"));
      Utils.blinkRedLED(300, 3);
      break;
    case 1:
      USB.println(F("REPROGRAMMING OK"));
      Utils.blinkGreenLED(300, 3);
      break;
    default:
      USB.println(F("RESTARTING"));
      Utils.blinkGreenLED(500, 1); 
  }
  USB.println(F("-------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n\n\n"));
}

void loop() {
  USB.println(F("---------------------------------------------------------------------------------------------------\n"));
  USB.println("                                         LOOP \n");
  USB.println(F("---------------------------------------------------------------------------------------------------\n"));
  //PWR.deepSleep("00:00:10:00", RTC_OFFSET, RTC_ALM1_MODE1, ALL_ON); // Lo recomendado es que esté 2
  USB.ON();
  USB.print("@@ Wasp: Serial ID: ");
  USB.println(NumSerie);

  /*Preparing Version Request for Node State*/
  char ayudita[100];
  memset(ayudita, '\0', sizeof(ayudita));

  /* Init the character chain which is going to contain the data */
  char requestESB[300];
  memset(requestESB, '\0', sizeof(requestESB));
  /* Aux variable to get the measures */
  char measure[100];
  memset(measure, '\0', sizeof(measure));

  /* Aux variable to configure the reactive OTA callback*/
  int reactive;
  
  /* Add the serial ID */
  strcat(requestESB, "idStation=");
  strcat(requestESB, NumSerie);

  /* Add the timestamp */
  char timestamp[30];
  snprintf(timestamp, sizeof(timestamp)+sizeof("&timestamp=%lu"), "&timestamp=%lu", RTC.getEpochTime());
  strcat(requestESB, timestamp);
  USB.println("@@Wasp: The time is: ");
  USB.print("   ");
  USB.println(RTC.getTime());
  
  
  /* Control the times that we are going to measure the PM , each 5 minutes*/
  if ((millis() - previous) > PM_TimeOffset)
    pm = false;

  /* Make reactive OTA request */
  reactive = sendOtaReq();
  USB.print("@@Wasp: OTA PERMISSION ");
  USB.println(reactive);

  if(NumSerie!="154BAAE80593E46A"){ //Cambia la ultima A por D --> ese es id de Educacion --> este if entra siempre este id 154BAAE80593E46A no lo tiene ningún sensor
   
  /* Control the times that we are going to do the OTA REQUEST, each 6 hours*/
  USB.println("@@Wasp: OTA REQUEST each 6 hours...");
  if(((millis() - previoOTA) > OTA_TimeOffset*100000) || (reactive==49)){ //The number 49 is the ASCII code for "1" char
    USB.println(" @@Wasp: It is time for OTA REQUEST");
    error = _4G.ON();
    USB.println(F("   Enter PIN code..."));
    if (_4G.enterPIN("1234") == 0) {
      USB.println(F("     PIN code accepted"));
    } else {
      USB.println(F("     PIN code incorrect"));
    }
    
    sprintf(ayudita, "/ota/permission?version=%d&idStation=%s&bat=%d&pOta=%d&mil=%d", (uint8_t)Utils.getProgramVersion(), NumSerie,(uint8_t)PWR.getBatteryLevel(),previoOTA,millis());
    sendGetPost("xxx.xxx.xxx.xxx",xxxx,ayudita,NULL);

    /* Make the OTA request. It's implicit the comparation with the version in _4G.requestOTA(....) */
    USB.println("     ==> MAKING OTA REQUEST... \n");
    error = _4G.requestOTA(hostESB, portOTA, user, pass);
    if (error != 0){
      USB.print(F("OTA request failed. Error code: "));
      USB.println(error,DEC);
    }
    previoOTA = millis();
    _4G.OFF();

  }else{
    USB.print(" @@Wasp: It is NOT time for OTA REQUEST, ");
    USB.print((OTA_TimeOffset*100000)-(millis()-previoOTA));
    USB.println(" milliseconds left");
  }
  /* Timers for PM measures*/
  unsigned long result = millis() - previous;
  USB.print(F("   Millis: "));
  USB.println(millis());
  USB.print(F("   Previous: "));
  USB.println(previous);
  USB.print(F("   Substraction: "));
  USB.println(result);
  USB.print(F("   Offset: "));
  USB.println(PM_TimeOffset);

  /****************************************     PM measure     ****************************************************************/
  gas_sensor_CO.OFF();
  gas_sensor_NO2.OFF();
  gas_sensor_O3.OFF();
  USB.print("@@Wasp: ID = ");
  USB.println(NumSerie);
  /* If it's time for measure PMs EVERYTHING OK*/
  if (!pm) {
    status = OPC_N2.ON();
    if (status == 1)
    {
      USB.println("@@Wasp: Particle sensor start...");
      pm_measure = OPC_N2.getPM(5000, 5000);
      if (pm_measure == 1) {
        USB.print(F("   PM 1: "));
        USB.printFloat(OPC_N2._PM1, 3);
        USB.println(F(" ug/m3"));
        USB.print(F("   PM 2.5: "));
        USB.printFloat(OPC_N2._PM2_5, 3);
        USB.println(F(" ug/m3"));
        USB.print(F("   PM 10: "));
        USB.printFloat(OPC_N2._PM10, 3);
        USB.println(F(" ug/m3"));
        memset(measure, '\0', sizeof(measure));
        /* Add PM measures */
        dtostrf( OPC_N2._PM1, 1, 3, measure);
        strcat(requestESB, "&pm1=");
        strcat(requestESB, measure);
        dtostrf( OPC_N2._PM2_5, 1, 3, measure);
        strcat(requestESB, "&pm2_5=");
        strcat(requestESB, measure);
        dtostrf( OPC_N2._PM10, 1, 3, measure);
        strcat(requestESB, "&pm10=");
        strcat(requestESB, measure);
        /* Measure are only perform every certaing time defined by PM_TimeOffset */
        previous = millis();
      } else {
        USB.print(F("Error performing the measure. Error code:"));
        USB.println(pm_measure, DEC);
      }
    } else {
      USB.println(F("Error starting the particle sensor"));
    }
    OPC_N2.OFF();
    /* If it is not time we put -1 in every measure*/
  } else {
    strcat(requestESB, "&pm1=");
    strcat(requestESB, "-1.0");
    strcat(requestESB, "&pm2_5=");
    strcat(requestESB, "-1.0");
    strcat(requestESB, "&pm10=");
    strcat(requestESB, "-1.0");
  }
  USB.print("@@Wasp: PM measure request: ");
  USB.println(requestESB);
  OPC_N2.OFF();
  USB.println(F("---------------------------------------\n"));

  /****************************************    END PM measure     ****************************************************************/

  /****************************************    BASIC measure     ****************************************************************/

  ////////////////////////////IMPORTANT NOTICE/////////////////////////////////////////////////
  //It is important to set gas sensors off before measuring basic sensors
  //On the contrary measure is not correct and WaspMote does not wake up from deep sleep mode
  //////////////////////////////////////////////////////////////////////////////////////////////
  USB.println(F("@@Wasp: Basic sensors start... "));
  gas_sensor_CO.OFF();
  gas_sensor_NO2.OFF();
  gas_sensor_O3.OFF();
  
  /* Power on the Temperature Humidity and Pressure sensors */
  bme.ON();
  temperature = bme.getTemperature();
  humidity = bme.getHumidity();
  pressure = bme.getPressure();
  bme.OFF();
  
  /* Power on the Lumininosity sensor */
  luxes.ON();
  luminosity = luxes.getLuminosity();
  luxes.OFF();

  ////////////////////IMPORTANT NOTICE//////////////////////////////////////////////////
  //After basic sensors have been measured gas sensors can be powered on again.
  /////////////////////////////////////////////////////////////////////////////////////
  gas_sensor_CO.ON();
  gas_sensor_NO2.ON();
  gas_sensor_O3.ON();

  USB.print(F("   Temperature: "));
  USB.printFloat(temperature, 2);
  USB.println(F("   Celsius degrees"));
  USB.print(F("   RH: "));
  USB.printFloat(humidity, 2);
  USB.println(F(" %"));
  USB.print(F("   Pressure: "));
  USB.printFloat(pressure, 2);
  USB.println(F("  Pa"));
  USB.print(F("   Luminosity: "));
  USB.print(luminosity);
  USB.println(F("  luxes"));
  
  /* Number accuracy */
  // use dtostrf() to convert from float to string:
  // '1' refers to minimum width
  // '3' refers to number of decimals
  /* Add Basic measures */
  memset(measure, '\0', sizeof(measure));
  dtostrf( temperature, 1, 3, measure);
  strcat(requestESB, "&temperature=");
  strcat(requestESB, measure);

  dtostrf( humidity, 1, 3, measure);
  strcat(requestESB, "&humidity=");
  strcat(requestESB, measure);

  dtostrf( pressure, 1, 3, measure);
  strcat(requestESB, "&pressure=");
  strcat(requestESB, measure);

  snprintf( measure, sizeof(measure), "%lu", luminosity );
  strcat(requestESB, "&luminosity=");
  strcat(requestESB, measure);

  USB.print("@@Wasp: Basic measure request: ");
  USB.println(requestESB);

  USB.println(F("---------------------------------------\n"));

  /****************************************    END BASIC measure     ****************************************************************/

  /****************************************    GASES measure     ****************************************************************/
  USB.print("@@Wasp: Gas measure...");
  /* Power on the Gas Sensors and WARM UP them for measuring*/
  gas_sensor_CO.ON();
  gas_sensor_NO2.ON();
  gas_sensor_O3.ON();
  USB.println(F("Sleep mode for gas measure (electrochemical heating)..."));
  PWR.deepSleep("00:00:07:00", RTC_OFFSET, RTC_ALM1_MODE1, ALL_ON); // Lo recomendado es que esté 2
  //PWR.deepSleep("00:00:01:00", RTC_OFFSET, RTC_ALM1_MODE1, ALL_ON); // Lo recomendado es que esté 2
  //PWR.deepSleep(warming_time, RTC_OFFSET, RTC_ALM1_MODE1, ALL_ON);
  USB.ON();
  USB.println(F("     wake up!!"));

  /* Read the electrochemical sensor and compensate with the temperature internally --> We will make N measures for taking the median */
  int i = 0;
  float aux = 0.0;
  concentration_CO = 0.0;  // Stores the CO concentration level in ppm
  concentration_NO2 = 0.0;  // Stores the NO2 concentration level in ppm
  concentration_O3 = 0.0;  // Stores the O3 concentration level in ppm

  for (i=0; i<5 ; i++){
    USB.print(F("   Read CO!... "));
    aux = gas_sensor_CO.getConc(temperature);
    concentration_CO = concentration_CO + (aux/5.0);
    USB.println(aux);
    
    USB.print(F("   Read NO2!... "));
    aux = gas_sensor_NO2.getConc(temperature);
    concentration_NO2 = concentration_NO2 + (aux/5.0);
    USB.println(aux);

    USB.print(F("   Read O3!... "));
    aux = gas_sensor_O3.getConc(temperature);
    concentration_O3 = concentration_O3 + (aux/5.0);
    USB.println(aux);
  }
  /*
    gas_sensor_CO.OFF();
    gas_sensor_NO2.OFF();
    gas_sensor_O3.OFF();
  */
  USB.print(F("   CO gas concentration: "));
  USB.printFloat(concentration_CO, 12);
  USB.println(F(" ppm"));
  USB.print(F("   NO2 gas concentration: "));
  USB.printFloat(concentration_NO2, 12);
  USB.println(F(" ppm"));
  USB.print(F("   O3 gas concentration: "));
  USB.printFloat(concentration_O3, 12);
  USB.println(F(" ppm"));
  /* Add GAS measures */
  //dtostrf( concentration_CO, 1, 3, measure);
  //dtostrf( concentration_CO, 1, 12, measure);
  dtostrf( concentration_CO, 10, 7, measure);
  strcat(requestESB, "&coC=");
  strcat(requestESB, measure);
  //dtostrf( concentration_NO2, 1, 3, measure);
  //dtostrf( concentration_NO2, 1, 12, measure);
  dtostrf( concentration_NO2, 10, 7, measure);
  strcat(requestESB, "&no2C=");
  strcat(requestESB, measure);
  //dtostrf( concentration_O3, 1, 3, measure);
  //dtostrf( concentration_O3, 1, 12, measure);
    dtostrf( concentration_O3, 10, 7, measure);
  strcat(requestESB, "&o3C=");
  strcat(requestESB, measure);

  USB.print("@@Wasp: Gas measure request: ");
  USB.println(requestESB);
  USB.println(F("---------------------------------------\n"));

  /****************************************    END GASES measure     ****************************************************************/



  /**************************************** BATTERY measure     ******************************************************************/

  /* ANTES DEL GRAN CAMBIO */
  USB.print(F("Initialization battery_sensors: "));
  char battery2[20];
  snprintf(battery2, sizeof(battery2), "%u", PWR.getBatteryLevel());
  strcat(requestESB, "&batteryLevel=");
  strcat(requestESB, battery2);
  snprintf( battery2, sizeof(battery2), "%u", PWR.getBatteryCurrent());
  strcat(requestESB, "&batteryCurrent=");
  strcat(requestESB, battery2);
  Utils.float2String(PWR.getBatteryVolts(), battery2, 2);
  strcat(requestESB, "&baterryVolts=");
  strcat(requestESB, battery2);



  USB.print("@@Wasp: Battery measure request: ");
  USB.println(requestESB);
  USB.println(F("---------------------------------------"));

  /**************************************** END BATTERY measure   ******************************************************************/
  
  /***************************************** SENDING DATA *************************************************************/
  error = _4G.ON();
  /* If the module is well power on we can begin the sending */
  if (error == 0) {
    USB.println(F("@@Wasp: Turning on 4G MODULE..."));

    USB.println(F("   Enter PIN code..."));
    //Debe de dar pin incorrecto porque las tarjetas no tienen PIN
    if (_4G.enterPIN("1234") == 0) {
      USB.println(F("     PIN code accepted"));
    } else {
      USB.println(F("     PIN code incorrect"));
    }

    USB.println("@@Wasp: Sending data to ESB...");
    USB.print("   Time: ");
    USB.println(RTC.getTime());
  
    USB.print(" @@ HTTP post esb: ");
    USB.print(hostESB);
    USB.print(portESB);
    USB.print(resourceESB);
    USB.println(requestESB);
    sendGetPost(hostESB, portESB, resourceESB, requestESB);
  } else {
    USB.println(F("   4G module not started"));
    USB.print(F("   Error code: "));
    USB.println(error, DEC);
  }

  _4G.OFF();


    /***************************************** END SENDING DATA *************************************************************/

  /* NAP TIME!!! */
  
  USB.println(F("@@Wasp: Enter to a great NAP :) --> It is time for take the bed --> Nunca duermen 1 hora"));
  // Go to sleep disconnecting all switches and modules
  PWR.deepSleep("00:01:00:00", RTC_OFFSET, RTC_ALM1_MODE1, ALL_OFF);

  USB.ON();
  USB.println(F("\nWAKE UP"));

  // After wake up check interruption source
  if ( intFlag & RTC_INT )
  {
    // clear interruption flag
    intFlag &= ~(RTC_INT);

    USB.println(F("   ---------------------"));
    USB.println(F("   RTC INT captured"));
    USB.println(F("   ---------------------"));
  }

  USB.print(F("   free Memory (Bytes):"));
  USB.println(freeMemory()); // prints free RAM

  /* If there is not enough battery left to go to sleep 2 hours */
  //uint8_t battery = PWR.getBatteryLevel(); //lo quito
  if (PWR.getBatteryLevel() <= 7) {
    USB.println(F("************************************************"));
    USB.print(F("   WARNING: Battery issue. Battery level (%): "));
    USB.println(PWR.getBatteryLevel(), DEC);
    USB.println(F("   Entering in deep sleep mode for 6 hours..."));
    PWR.deepSleep(deep_sleep_time, RTC_OFFSET, RTC_ALM1_MODE1, ALL_OFF);
    USB.println(F("   ************************************************"));
  } else {
    USB.println(F("   ************************************************"));
    USB.print(F("   Battery level (%): "));
    USB.println(PWR.getBatteryLevel(), DEC);
    USB.println(F("   ************************************************"));
  }

    
  }else{
    
    // Parte para aislar comportamiento de algunos sensores de forma remota
      
  }
}

void sendGetPost(char* host, int port, char* resource, char* data) {
  if (data == NULL) {
    //If the data is NULL we will use GET 
    error = _4G.http( Wasp4G::HTTP_GET, host, port, resource);

  } else  {
    //If the data is not NULL we will use POST 
    error = _4G.http( Wasp4G::HTTP_POST, host, port, resource, data);
  }

  if (error == 0) {
    USB.print(F("Done. HTTP code: "));
    USB.println(_4G._httpCode);
    USB.print("Server response: ");
    USB.println(_4G._buffer, _4G._length);
  } else {
    USB.print(F("Failed. Error code: "));
    USB.println(error, DEC);
  }
}

int sendOtaReq(){
  _4G.ON();
  char reactive[8];
  memset(reactive, '\0', sizeof(reactive));

  _4G.set_APN(apn, login, password);
  _4G.show_APN();
  _4G.enterPIN("1234");

  USB.println("@@ Wasp: Making permission request for OTA upgrade...");
  sendGetPost(hostESB,xxxx,"/ota/permission",NULL);
  strcat(reactive,(char*)_4G._buffer);

  
  

  USB.print("@@ Wasp: The response of the server has been: ");
  USB.println(reactive);
  USB.println((int) *reactive);
  _4G.OFF();
  return (int) *reactive;
}











































void initCalmVariables() {
  if (draft)
  {
    memset(warming_time, '\0', sizeof(warming_time));
    strcpy(warming_time, "00:00:02:00");
    memset(deep_sleep_time, '\0', sizeof(deep_sleep_time));
    strcpy(deep_sleep_time, "00:06:00:00");
  }
  else
  {
    memset(warming_time, '\0', sizeof(warming_time));
    strcpy(warming_time, "00:00:02:00");
    memset(deep_sleep_time, '\0', sizeof(deep_sleep_time));
    strcpy(deep_sleep_time, "00:06:00:00");
  }

  USB.ON();

  USB.println(F("Starting Waspmote factory default program"));
}
void checkBattery() {
  uint8_t battery = PWR.getBatteryLevel();
  if (battery == 0)
  {
    USB.println(F("************************************************"));
    USB.print(F("ERROR: Battery issue. Battery level (%): "));
    USB.println(battery, DEC);
    USB.println(F("************************************************"));
    error |= 1 << 0x01;
  }
  else {
    USB.println(F("************************************************"));
    USB.print(F("Battery level (%): "));
    USB.println(battery, DEC);
    USB.println(F("************************************************"));
  }

  // get charging state and current
  bool chargeState = PWR.getChargingState();
  uint16_t chargeCurrent = PWR.getBatteryCurrent();


  // Show the battery charging state. This is valid for both USB and Solar panel
  // If any of those ports are used --> the charging state will be true
  USB.print(F("Battery charging state: "));
  if (chargeState == true)
  {
    USB.println(F("Battery is charging"));
  }
  else
  {
    USB.println(F("Battery is not charging"));
  }

  // Show the battery charging current (only from solar panel)
  USB.print(F("Battery charging current (only from solar panel): "));
  USB.print(chargeCurrent, DEC);
  USB.println(F(" mA"));
}
void initId() {
  
   Utils.readSerialID();
  snprintf(NumSerie, sizeof(NumSerie), "%02X%02X%02X%02X%02X%02X%02X%02X", 
    _serial_id[0], 
    _serial_id[1], 
    _serial_id[2], 
    _serial_id[3], 
    _serial_id[4], 
    _serial_id[5], 
    _serial_id[6], 
    _serial_id[7]);


}




void checkModules() {
  //////////////////////////////////////////////////
  // 1. Switch on the 4G module
  //////////////////////////////////////////////////
  previous = millis();
  previoOTA = 83246400;
  error = _4G.ON();
  if (error == 0)
  {
    USB.print(F("1. 4G module ready in "));
    USB.print(millis() - previous);
    USB.println(F(" ms"));
  }
  else
  {
    // Problem with the communication with the 4G module
    USB.println(F("1. 4G module not started"));
    USB.print(F("Error code: "));
    USB.println(error, DEC);
  }

  _4G.set_APN(apn, login, password);


  _4G.show_APN();
  USB.println("Show APN Hecho!");

  connection_status = _4G.checkDataConnection(60);
  if (connection_status == 0)
  {
    _4G.setTimeFrom4G();
    USB.println("LA HORA DE LOS RELOJES");
    USB.println(RTC.getTime());
    USB.println(RTC.getTimestamp());
    USB.println(RTC.getEpochTime());

  }
 
  USB.println("Hora introducida");

}
Output of the first code. Here you have the output of the first code.

Code: Select all

J#
---------------------------------------------------------------------------------------------------

                                         SETUP 

---------------------------------------------------------------------------------------------------

Starting Waspmote factory default program
************************************************
Battery level (%): 63
************************************************
Battery charging state: Battery is charging
Battery charging current (only from solar panel): 0 mA
[LE910] GPRS context activation:0
1. 4G module ready in 11024 ms
*****************************
APN: telefonica.es
LOGIN: telefonica
PASSWORD: telefonica
*****************************
Show APN Hecho!
[LE910] CREG: 0,3
[LE910] CREG: 0,4
[LE910] CREG: 0,4
[LE910] CREG: 0,2
[LE910] CREG: 0,3
Hora introducida
Watchdog settings:
Alarm matches [Date, hh:mm] --> [02, 23:46]
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
                               OTA CONFIGURATION
 Status : 2
 Program version: 69
RESTARTING
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------



---------------------------------------------------------------------------------------------------

                                         LOOP 

---------------------------------------------------------------------------------------------------

@@ Wasp: Serial ID: 0E23A2E80593E429
@@Wasp: The time is: 
   Mon, 19/12/02, 23:16:03
[LE910] GPRS context activation:0
*****************************
APN: telefonica.es
LOGIN: telefonica
PASSWORD: telefonica
*****************************
[LE910] ==> ERROR CODE: operation not allowed
@@ Wasp: Making permission request for OTA upgrade...
[LE910] CREG: 0,3
[LE910] CREG: 0,4
[LE910] CREG: 0,4
[LE910] CREG: 0,2
[LE910] CREG: 0,4
[LE910] CREG: 0,2
[LE910] CREG: 0,3
[LE910] CREG: 0,4
[LE910] CREG: 0,4
[LE910] CREG: 0,3
Failed. Error code: 1
@@ Wasp: The response of the server has been: 
0
@@Wasp: OTA PERMISSION 0
@@Wasp: OTA REQUEST each 6 hours...
 @@Wasp: It is time for OTA REQUEST
[LE910] GPRS context activation:0
   Enter PIN code...
[LE910] ==> ERROR CODE: operation not allowed
     PIN code incorrect
[LE910] CREG: 0,3
[LE910] CREG: 0,4
[LE910] CREG: 0,4
[LE910] CREG: 0,3
[LE910] CREG: 0,4
[LE910] CREG: 0,2
[LE910] CREG: 0,2
Failed. Error code: 1
     ==> MAKING OTA REQUEST... 

[LE910] Checking connection
[LE910] CREG: 0,3
[LE910] CREG: 0,4
[LE910] CREG: 0,2
[LE910] CREG: 0,3
[LE910] CREG: 0,4
[LE910] CREG: 0,2
[LE910] CREG: 0,3
[LE910] CREG: 0,4
[LE910] CREG: 0,2
[LE910] CREG: 0,3
[LE910] Open FTP session ERROR
OTA request failed. Error code: 3
   Millis: 295087
   Previous: 834
   Substraction: 294249
   Offset: 800000
@@Wasp: ID = 0E23A2E80593E429
@@Wasp: Particle sensor start...
   PM 1: 0.000 ug/m3
   PM 2.5: 0.000 ug/m3
   PM 10: 0.000 ug/m3
@@Wasp: PM measure request: idStation=0E23A2E80593E429&timestamp=1575328563&pm1=0.000&pm2_5=0.000&pm10=0.000
---------------------------------------

@@Wasp: Basic sensors start... 
   Temperature: 18.99   Celsius degrees
   RH: 46.78 %
   Pressure: 93721.99  Pa
   Luminosity: 0  luxes
@@Wasp: Basic measure request: idStation=0E23A2E80593E429&timestamp=1575328563&pm1=0.000&pm2_5=0.000&pm10=0.000&temperature=18.990&humidity=46.782&pressure=93721.984&luminosity=0
---------------------------------------

@@Wasp: Gas measure...Sleep mode for gas measure (electrochemical heating)...
     wake up!!
   Read CO!... 0.0000000000
   Read NO2!... 0.0000000000
   Read O3!... 0.0692954635
   Read CO!... 0.0000000000
   Read NO2!... 0.0000000000
   Read O3!... 0.0801565361
   Read CO!... 0.0000000000
   Read NO2!... 0.0000000000
   Read O3!... 0.0898956108
   Read CO!... 0.0000000000
   Read NO2!... 0.0000000000
   Read O3!... 0.0984677886
   Read CO!... 0.0000000000
   Read NO2!... 0.0000000000
   Read O3!... 0.1002181291
   CO gas concentration: 0.000000000000 ppm
   NO2 gas concentration: 0.000000000000 ppm
   O3 gas concentration: 0.087606716156 ppm
@@Wasp: Gas measure request: idStation=0E23A2E80593E429&timestamp=1575328563&pm1=0.000&pm2_5=0.000&pm10=0.000&temperature=18.990&humidity=46.782&pressure=93721.984&luminosity=0&coC= 0.0000000&no2C= 0.0000000&o3C= 0.0876067
---------------------------------------

Initialization battery_sensors: @@Wasp: Battery measure request: idStation=0E23A2E80593E429&timestamp=1575328563&pm1=0.000&pm2_5=0.000&pm10=0.000&temperature=18.990&humidity=46.782&pressure=93721.984&luminosity=0&coC= 0.0000000&no2C= 0.0000000&o3C= 0.0876067&batteryLevel=64&batteryCurrent=0&baterryVolts=3.91
---------------------------------------
[LE910] ==> ERROR CODE: operation not allowed
@@Wasp: Turning on 4G MODULE...
   Enter PIN code...
[LE910] ==> ERROR CODE: operation not allowed
     PIN code incorrect
@@Wasp: Sending data to ESB...
   Time: Mon, 19/12/02, 23:22:52
 @@ HTTP post esb:XXXXXXXXXXX:YYYYY/testidStation=0E23A2E80593E429&timestamp=1575328563&pm1=0.000&pm2_5=0.000&pm10=0.000&temperature=18.990&humidity=46.782&pressure=93721.984&luminosity=0&coC= 0.0000000&no2C= 0.0000000&o3C= 0.0876067&batteryLevel=64&batteryCurrent=0&baterryVolts=3.91
[LE910] CREG: 0,3
[LE910] CREG: 0,4
[LE910] CREG: 0,4
[LE910] CREG: 0,3
[LE910] CREG: 0,3
Failed. Error code: 1
@@Wasp: Enter to a great NAP :) --> It is time for take the bed

Second code. This code is proposed as an example to check the connectivity of the SIM and makes a request to an HTTP service that we have in a machine in the DMZ of the university (totally accessible from the previous one through that IP and port).

Code: Select all

#include <Wasp4G.h>


// define variables
uint8_t PIN_status;
char PIN_code[30];
uint8_t error;
int counter;
int temp;
uint32_t previous;

void setup()
{    
  USB.println(F("****************************************"));
  USB.println(F("This example inits the 4G module and"));
  USB.println(F("request the unlock codes if necessary"));
  USB.println(F("****************************************"));

  //////////////////////////////////////////////////
  // 1. Switch on the 4G module
  //////////////////////////////////////////////////
  previous = millis();
  error = _4G.ON();
  if (error == 0)  
  {
    USB.print(F("1. 4G module ready in "));  
    USB.print(millis()-previous);
    USB.println(F(" ms"));
  }
  else
  {
    // Problem with the communication with the 4G module
    USB.println(F("1. 4G module not started"));
    USB.print(F("Error code: "));
    USB.println(error, DEC);
  }
}



void loop()
{
  char ayudita[100];
  memset(ayudita, '\0', sizeof(ayudita));
  //////////////////////////////////////////////////
  // 2. Check PIN code
  //////////////////////////////////////////////////
  USB.println(F("2. Reading code..."));
  PIN_status = _4G.checkPIN();
  //Debe de salir error porque no tiene pin
  if (_4G.enterPIN("") == 0) {
      USB.println(F("     PIN code accepted"));
  } else {
      USB.println(F("     PIN code incorrect"));
  }

  sprintf(ayudita, "/ota/permission?version=%d&bat=%d&mil=%d", (uint8_t)Utils.getProgramVersion(),(uint8_t)PWR.getBatteryLevel(),millis());
  sendGetPost("XXX.XXX.XXX.XXX",XXXX,ayudita,NULL);



  
  switch (PIN_status)
  {
  case 0:
    USB.println(F("SIM and module unlocked. Ready to use"));
    USB.println(F("The sketch will stop here"));
    PWR.deepSleep("00:20:00:00", RTC_OFFSET, RTC_ALM1_MODE1, ALL_ON); // Lo recomendado es que esté 2
    break;

  case 1:
    USB.println(F("LE910 is awaiting SIM PIN."));
    USB.println(F("Please, enter the code: "));
    readString(PIN_code);
    break;

  case 2:
    USB.println(F("LE910 is awaiting SIM PUK"));
    USB.println(F("Please, enter the code: "));
    readString(PIN_code);
    break;

  case 3:
    USB.println(F("LE910 is awaiting phone-to-SIM card password."));
    USB.println(F("Please, enter the code: "));
    readString(PIN_code);
    break;

  case 4:
    USB.println(F("LE910 is awaiting phone-to-very-first-SIM card password."));
    USB.println(F("Please, enter the code: "));
    readString(PIN_code);
    break;

  case 5:
    USB.println(F("LE910 is awaiting phone-to-very-first-SIM card unblocking password."));
    USB.println(F("Please, enter the code: "));
    readString(PIN_code);
    break;

  case 6:
    USB.println(F("LE910 is awaiting SIM PIN2"));
    USB.println(F("Please, enter the code: "));
    readString(PIN_code);
    break;

  case 7:
    USB.println(F("LE910 is awaiting SIM PUK2"));
    USB.println(F("Please, enter the code: "));
    readString(PIN_code);
    break;

  case 8:
    USB.println(F("LE910 is awaiting network personalization password"));
    USB.println(F("Please, enter the code: "));
    readString(PIN_code);
    break;

  case 9:
    USB.println(F("LE910 is awaiting network personalization unblocking password"));
    USB.println(F("Please, enter the code: "));
    readString(PIN_code);
    break;

  case 10:
    USB.println(F("LE910 is awaiting network subset personalization password"));
    USB.println(F("Please, enter the code: "));
    readString(PIN_code);
    break;

  case 11:
    USB.println(F("LE910 is awaiting network subset personalization unblocking password"));
    USB.println(F("Please, enter the code: "));
    readString(PIN_code);
    break;

  case 12:
    USB.println(F("LE910 is awaiting service provider personalization password"));
    USB.println(F("Please, enter the code: "));
    readString(PIN_code);
    break;

  case 13:
    USB.println(F("LE910 is awaiting service provider personalization unblocking password"));
    USB.println(F("Please, enter the code: "));
    readString(PIN_code);
    break;

  case 14:
    USB.println(F("LE910 is awaiting corporate personalization password"));
    USB.println(F("Please, enter the code: "));
    readString(PIN_code);
    break;

  case 15:
    USB.println(F("LE910 is awaiting corporate personalization unblocking password"));
    USB.println(F("Please, enter the code: "));
    readString(PIN_code);
    break;

  default: 
    USB.print(F("Error code: "));
    USB.println(PIN_status, DEC);
    break;
  }


  //////////////////////////////////////////////////
  // 3. Set PIN code
  //////////////////////////////////////////////////
  if ((PIN_status != 0) && (PIN_status < 16))
  {
    USB.print(F("3. Entering PIN code..."));
    if (_4G.enterPIN(PIN_code) == 0) 
    {
      USB.println(F("3. done"));
    }
    else
    {
      USB.println(F("3. error"));
    }
  }
}


/******************************************************************
*
* readString 
*
*
*
*******************************************************************/
void readString(char* message)
{
  int x = 0;  

  // clean input buffer
  USB.ON();
  USB.flush();
  
  // wait for incoming data from keyboard
  while(USB.available() == 0);

  // Treat all incoming bytes
  while (USB.available() > 0)
  {
    message[x] = USB.read();

    if( (message[x] == '\r') || (message[x] == '\n') )
    {
      message[x]='\0';
    }
    else
    {
      x++;
    }
  }
}

void sendGetPost(char* host, int port, char* resource, char* data) {
  if (data == NULL) {
    //If the data is NULL we will use GET 
    error = _4G.http( Wasp4G::HTTP_GET, host, port, resource);

  } else  {
    //If the data is not NULL we will use POST 
    error = _4G.http( Wasp4G::HTTP_POST, host, port, resource, data);
  }

  if (error == 0) {
    USB.print(F("Done. HTTP code: "));
    USB.println(_4G._httpCode);
    USB.print("Server response: ");
    USB.println(_4G._buffer, _4G._length);
  } else {
    USB.print(F("Failed. Error code: "));
    USB.println(error, DEC);
  }
}

Output. Here you have the output of the second code.

Code: Select all

J#
****************************************
This example inits the 4G module and
request the unlock codes if necessary
****************************************
[LE910] GPRS context activation:0
1. 4G module ready in 11024 ms
2. Reading code...
[LE910] ==> ERROR CODE: UNKNOWN
     PIN code incorrect
[LE910] CREG: 0,3
[LE910] CREG: 0,4
[LE910] CREG: 0,4
[LE910] CREG: 0,3
[LE910] CREG: 0,4
[LE910] CREG: 0,4
[LE910] CREG: 0,2
Failed. Error code: 1
SIM and module unlocked. Ready to use
The sketch will stop here

How can I fix these errors?

Greetings,

Enrique.

libelium-dev
Posts: 27967
Joined: Mon Sep 28, 2009 1:06 pm

Re: PPM or PPB

Post by libelium-dev » Tue Dec 03, 2019 2:16 pm

Hi,

The first code consumes 77% of dynamic memory, this could cause stability problems. First of all, modify the print and println functions to be like this
USB.print(F("@@ Wasp: Serial ID: "));
instead of
USB.print("@@ Wasp: Serial ID: ");
Just that change decreases the dynamic memory used from 77% to 68%.

On the other hand, the following function is incorrect and it can cause that the node was blocked since the size of timestamp variable is 30 bytes an the function is permiting to create a string of 44 bytes.

Code: Select all

snprintf(timestamp, sizeof(timestamp) + sizeof("&timestamp=%lu"), "&timestamp=%lu", RTC.getEpochTime());
The next variables are used as global so you could declare them out of the loop to reserve that quantity of bytes.

Code: Select all

char ayudita[100];
char requestESB[300];
char timestamp[30];
char measure[100];
Anyway, the problem seems related to the 4G module. It seems that the module doesn't connect to the network. Could you check that the APN settings and pin code are correct? Could you please try to connect to the network using the example code?
http://www.libelium.com/development/was ... work-info/

The operation not allowed error is normal due to the module version used. don't worry about that error.

Regards

Enrique UCLM
Posts: 18
Joined: Wed Apr 24, 2019 11:13 am
Company: UCLM

Re: PPM or PPB

Post by Enrique UCLM » Wed Dec 04, 2019 11:50 am

Sorry I'm late answering. I've been remodeling the code with your feedback and doing other tests, but there's no way to get him to send any data.
The APN is correct as it is used in the 4 nodes we buy. However, I have checked it and the configuration is correct.
The test code you have suggested presents the following output on the node with ID=154BA...:

Code: Select all

J# 
Start program 

***************************** 
APN: telefonica.es 
LOGIN: telephone 
PASSWORD: telephone 
***************************** 
4G module not started 
Error code: 1
2. Switch OFF 4G module
3. Enter deep sleep...
4. Wake up!
The other node with ID=0E23...:

Code: Select all

J#
Start program

*****************************
APN: telefonica.es
LOGIN: telephone
PASSWORD: telephone
*****************************
[LE910] GPRS context activation:0
1. 4G module ready
LE910] CREG: 0,3
LE910] CREG: 0,4
LE910] CREG: 0,4
LE910] CREG: 0,2
2. Switch OFF 4G module
3. Enter deep sleep...
In the last one, if you notice the connection_status is not good and the module does not connect to the network.

I hope you can help me.

Greetings,

Enrique.

libelium-dev
Posts: 27967
Joined: Mon Sep 28, 2009 1:06 pm

Re: PPM or PPB

Post by libelium-dev » Thu Dec 05, 2019 10:03 am

Hi,

It seems that the 4G module of the 154BA node is damaged since it doesn't turn ON. Did you try with the last API v043? We included a modification in the way to turn ON the 4G modules a few versions before. If it doesn't turn ON, please fill the RMA form and our tech support team will contact you to solve the issue.
https://www.libelium.com/contact/#rma

Regarding the second problem, could you please test the sim card with another P&S? It seems that the network is denying the connection.

Regards

Enrique UCLM
Posts: 18
Joined: Wed Apr 24, 2019 11:13 am
Company: UCLM

Re: PPM or PPB

Post by Enrique UCLM » Thu Dec 05, 2019 12:42 pm

Following your instructions I have reinstalled the IDE and the API (which were already updated) but it still gives the same problems in both nodes.
I've also exchanged SIM cards between the nodes and they don't work either. I have tested the SIM cards in my personal phone and they work correctly. Finally, I took another SIM card from another company but it always gives the same error.

I just filled in the RMA form to contact technical service and find a solution.

Greetings,

Enrique.

libelium-dev
Posts: 27967
Joined: Mon Sep 28, 2009 1:06 pm

Re: PPM or PPB

Post by libelium-dev » Wed Dec 11, 2019 12:50 pm

Apologies for the inconvenience. Hope that our collegues from tech solves the problem as soon as possible.

Regards

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest