OTA - Scan range with Meshlium & 802.15.4

Using OTA functions with Waspmote
Post Reply
fransalcas
Posts: 8
Joined: Mon Nov 07, 2016 3:13 pm

OTA - Scan range with Meshlium & 802.15.4

Post by fransalcas » Tue Nov 08, 2016 10:16 pm

Hi. this question might be obvious for some of you but I wanted to know if the range of coverage of the Meshlium's antenna is the same as the Waspmote's (Plug & Sense!) one.

I'll explain, I have two waspmote plug an sense nodes and one meshlium, everything running with 802.15.4.
The nodes measure and send the data correctly to meshlium. With the current conditions, I have been able to place the nodes at 100 m or more away from meshlium.

However, when I want to perform OTA, the same nodes are no longer found when I search for them (-scan_nodes). I have had to move the waspmotes very close to the meshlium in order to scan and found them to send new programs.

In summary, if I place a node within X meters away from meshlium, and receive data correctly, I would expect the meshlium to find (scan) them at the same distance. But apparently that's not happening.

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

Re: OTA - Scan range with Meshlium & 802.15.4

Post by libelium-dev » Thu Nov 10, 2016 11:18 am

Hi,

It's a weird issue. Didn't success discovering nodes at all?

Did you attach the white antenna for 802.15.4 at meshlium correctly?

Regards

fransalcas
Posts: 8
Joined: Mon Nov 07, 2016 3:13 pm

Re: OTA - Scan range with Meshlium & 802.15.4

Post by fransalcas » Thu Nov 10, 2016 3:49 pm

Hi,

It's a weird issue. Didn't success discovering nodes at all?

Did you attach the white antenna for 802.15.4 at meshlium correctly?

Regards
Yes because meshlium receives data correctly from the waspmote nodes, but the scan seems to fail at that distance and I have to move the nodes closer. It should scan them at the same distance right?

Another question please. if I want to send a new program to the nodes with OTA, does it work if the loop of the code is too long? For example as in these lines of code:

Code: Select all

void loop()
{

  // Check if new data is available
  [b]if( xbee802.available() )
  {
    xbee802.treatData();
    // Keep inside this loop while a new program is being received
    while( xbee802.programming_ON  && !xbee802.checkOtapTimeout() )
    {
      if( xbee802.available() )
      {
        xbee802.treatData();
      }
    }
  }
[/b]

    readSensors();

     sendData();

     sleep(); // NO OTA HERE?

    
}
I have these 2 doubts: scan range and loop/sleep duration.

Thanks

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

Re: OTA - Scan range with Meshlium & 802.15.4

Post by libelium-dev » Fri Nov 11, 2016 1:16 pm

Hi,

Are you scanning in broadcast or unicast mode? The distance may be lower in broadcast mode due to packets collision.

If the code to be sent to the node is too long, it is more likely to failures in OTA. If the code is long, more packages are sent, so there would be more chances that one would fail. OTA is a complicated process.

Regards.

fransalcas
Posts: 8
Joined: Mon Nov 07, 2016 3:13 pm

Re: OTA - Scan range with Meshlium & 802.15.4

Post by fransalcas » Sat Nov 12, 2016 12:02 am

Hi,

Are you scanning in broadcast or unicast mode? The distance may be lower in broadcast mode due to packets collision.

If the code to be sent to the node is too long, it is more likely to failures in OTA. If the code is long, more packages are sent, so there would be more chances that one would fail. OTA is a complicated process.

Regards.
I tried scanning in broadcast and also in unicast mode. However, no nodes are found. I don't know if it is because of the long program that's currently running in the nodes or because of the distance, or both.

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

Re: OTA - Scan range with Meshlium & 802.15.4

Post by libelium-dev » Mon Nov 14, 2016 9:46 am

Hi,

Could you try with the OTA example code in order to check if there is a problem with the length of your code?

Regards

fransalcas
Posts: 8
Joined: Mon Nov 07, 2016 3:13 pm

Re: OTA - Scan range with Meshlium & 802.15.4

Post by fransalcas » Tue Nov 15, 2016 2:56 pm

Hi,

Could you try with the OTA example code in order to check if there is a problem with the length of your code?

Regards
This code basically measures and sends data for 15 minutes and then sleeps for 45 minutes aproximately.

Code: Select all

#include <WaspSensorCities.h>
#include <WaspXBee802.h>
#include <WaspFrame.h>

#define key_access "LIBELIUM"
#define id_mote "WASPMOTE00000001"

//Destination MAC addresss
//////////////////////////////////////////
char MESHLIUM_ADDRESS[] = "0013A20041022FBE";
//////////////////////////////////////////

// PAN (Personal Area Network) Identifier
uint8_t  panID[2] = {
  0x33,0x32};

// Define Freq Channel to be set: 
// Center Frequency = 2.405 + (CH - 11d) * 5 MHz
//   Range: 0x0B - 0x1A (XBee)
//   Range: 0x0C - 0x17 (XBee-PRO)
uint8_t  channel = 0x0C;

// Define the Encryption mode: 1 (enabled) or 0 (disabled)
uint8_t encryptionMode = 1;

// Define the AES 16-byte Encryption Key
char  encryptionKey[] = "Bf0Se1jA45EwJW71"; 

// define variable
uint8_t error;

//////////////////////////////////////////////////
// Define different period to sleep depending 
// on battery level and battery level thresholds
// (time must be in seconds)
//////////////////////////////////////////////////
uint8_t CRITIC_BAT_THRESHOLD = 30;
uint8_t LOW_BAT_THRESHOLD = 60;
uint32_t TIME_CRITIC_BAT =  60*60;
uint32_t TIME_LOW_BAT =  30*60;
uint32_t TIME_GOOD_BAT =  45*60 + 898;

// Dynamic battery control variables     
uint32_t time_to_sleep;
uint32_t iterTime;
uint32_t iterTimeb;
timestamp_t time;
char time_to_sleep_string[]= "00:00:04:55";

// Variable to store the read value
float temperature;
float humidity;
float luminosity;
float noise = 0.0;
int measuring_time=5000;
uint8_t battery=0;
//Variable to visualize all the process with the serial monitor if debugging
char debug = 1;

//Variable to distingish between waking up for ACC interruption or RTC int
char isACCint = 0;
int accFlag = 0;

char node_ID [] = "SC_NODE";


//Variables for measuring loop
long loop_time = 875000;
unsigned long t;

void setup()
{

  // Write Authentication Key to EEPROM memory
  Utils.setAuthKey(key_access);

  // Write Mote ID to EEPROM memory
  Utils.setID(id_mote);

  // Initialize XBee module
  //xbee802.ON();

  // CheckNewProgram is mandatory in every OTA program
  //xbee802.checkNewProgram();  


  // Turn on the USB and print a start message
  USB.ON();
  if(debug)     USB.println(F("\t\t****************************"));
  if(debug)     USB.println(F("\t\t          SETUP"));
  if(debug)     USB.println(F("\t\t****************************"));  
  delay(100);

  USB.println(F("Smart Cities"));
  // Set Waspmote ID
  frame.setID(node_ID);

  // Turn on the sensor board
  SensorCities.ON();

  // Turn on the RTC
  RTC.ON();

  //Init Xbee module  
  xbee802.ON();

  setXbeeParameters();

  //1.0. Set time from meshlium
  set_time_from_meshlium();  

  // CheckNewProgram is mandatory in every OTA program
  xbee802.checkNewProgram();

  iterTime=RTC.getEpochTime();
}

void loop()
{

  if(isACCint==2){
    //Step 1: Read suitables sensors

    //PWR.setWatchdog(WTD_ON,3*60);
    t = millis();
    while(millis() - t < loop_time){

      if( xbee802.available() )
      {
        xbee802.treatData();
        // Keep inside this loop while a new program is being received
        while( xbee802.programming_ON  && !xbee802.checkOtapTimeout() )
        {
          if( xbee802.available() )
          {
            xbee802.treatData();
          }
        }
      }

      readSensors();

      //Step 2: Create & send a Libelium frame to the meshlium gateway
      SendData();
      if(t > millis()) t = millis();
    }

    //Step 3: Change the time to sleep depending on the battery level and sleeps
    dynamicBatteryControl();
    USB.print(F("entering sleep mode for "));
    USB.print(time_to_sleep_string);
    USB.println(F(" -->[dd:hh:mm:ss]"));
    accFlag = 0;

  }
  else {
    update_time_to_sleep();
  }
  ACC.ON();
  ACC.setIWU(); 
  iterTimeb = RTC.getEpochTime();
  // USB.print(F("iterTimeb: "));
  // USB.println(iterTimeb);    
  PWR.deepSleep(time_to_sleep_string,RTC_OFFSET,RTC_ALM1_MODE1,ALL_OFF);
  ACC.ON();
  ACC.unsetIWU();
  RTC.ON();
  USB.ON();
  if( intFlag & ACC_INT ){

    // difference = RTC.getEpochTime() - iterTimeb;
    // USB.print(F("difference:"));
    // USB.println(difference);
    isACCint = 1;
    accFlag += 1;
    USB.println(F("++++++++++++++++++++++++++++"));
    USB.println(F("++ ACC interrupt detected ++"));
    USB.println(F("++++++++++++++++++++++++++++")); 
    USB.println(); 
  }
  else if ( intFlag & RTC_INT ){
    isACCint = 2;
    // difference = 0;
  }
  else{
    isACCint = 0;
  }
  iterTime=RTC.getEpochTime();
  // USB.print(F("iterTime:"));
  // USB.println(iterTime);    
  clearIntFlag(); 
  PWR.clearInterruptionPin();
}

void readSensors(void)
{ 
  USB.println(F("Reading Sensors"));
  // Turn on the sensor board
  SensorCities.ON();
  if(debug)
  {
    USB.println(F("[readSensors]    INIT"));
  }

  // Part 1: Sensor reading


  if(debug)
  {
    USB.println(F("[readSensors]    MEASURING TEMPERATURE SENSOR"));
  }
  SensorCities.setSensorMode(SENS_ON, SENS_CITIES_TEMPERATURE);    
  temperature = SensorCities.readValue(SENS_CITIES_TEMPERATURE);
  SensorCities.setSensorMode(SENS_OFF, SENS_CITIES_TEMPERATURE);
  USB.print(F("Temperature: "));
  USB.print(temperature);
  USB.println(F("ºC"));

  if(debug)
  {
    USB.println(F("[readSensors]    MEASURING HUMIDITY SENSOR"));
  }
  SensorCities.setSensorMode(SENS_ON, SENS_CITIES_HUMIDITY);    
  delay(15000); //Humidity sensor takes about 15 sec to stabilize    
  humidity = SensorCities.readValue(SENS_CITIES_HUMIDITY);
  SensorCities.setSensorMode(SENS_OFF, SENS_CITIES_HUMIDITY);    
  USB.print(F("Humidity: "));
  USB.print(humidity);
  USB.println(F("%RH"));

  if(debug)
  {
    USB.println(F("[readSensors]    MEASURING LDR SENSOR"));
  }
  SensorCities.setSensorMode(SENS_ON, SENS_CITIES_LDR);    
  luminosity = SensorCities.readValue(SENS_CITIES_LDR);  
  SensorCities.setSensorMode(SENS_OFF, SENS_CITIES_LDR);
  USB.print(F("Luminosity: "));
  USB.print(luminosity);
  USB.println(F("%"));    

  if(debug)
  {
    USB.println(F("[readSensors]    MEASURING AUDIO SENSOR"));
  }
  // Part2: Read the audio sensor during 5 seconds 
  double aux = 0.0;
  unsigned long timer;
  int count = 0;
  timer=millis();
  SensorCities.setSensorMode(SENS_ON, SENS_CITIES_AUDIO);

  while(millis() - timer < measuring_time)
  {
    delay(10);
    aux += SensorCities.readValue(SENS_CITIES_AUDIO);
    count++; 
    //No overloaded condition
    delay(10);
    if(timer > millis())	timer = millis();
  }
  noise = aux/count;
  SensorCities.setSensorMode(SENS_OFF, SENS_CITIES_AUDIO);
  USB.print(F("Audio= "));
  USB.print(noise);
  USB.println(F(" dBA")); 
}

void SendData(void)
{
  xbee802.ON();
  USB.println(F("Sending Data"));
  //////////////////////////
  // 1. create frame
  //////////////////////////  

  //1.0. Set time from meshlium
  set_time_from_meshlium();

  // 1.1. create new frame
  frame.createFrame(ASCII); 
  frame.setID(node_ID);

  // 1.2. add frame fields
  // 1.2.1 Add temperature
  frame.addSensor(SENSOR_TCA, temperature);
  // 1.2.2 Add humidity
  frame.addSensor(SENSOR_HUMA, humidity);
  // 1.2.3 Add LDR value
  frame.addSensor(SENSOR_LUM, luminosity);
  // 1.2.4 Add noise measurement
  frame.addSensor(SENSOR_MCP, noise); 
  // 1.2.5 Add Battery level
  frame.addSensor(SENSOR_BAT, PWR.getBatteryLevel());
  if (accFlag >= 1){
    char msg[30]; 
    snprintf(msg,sizeof(msg),"ACC interruptions %d",accFlag);		 
    frame.addSensor(SENSOR_STR, msg);
  }

  USB.println(F("\n1. Created frame to be sent"));
  frame.showFrame();

  //////////////////////////
  // 2. send packet
  //////////////////////////  

  // send XBee packet
  error = xbee802.send( MESHLIUM_ADDRESS, frame.buffer, frame.length );   

  if(debug)      USB.println(F("\n2. Send a packet to the RX node: "));

  if( error == 0 )
  {
    USB.println(F("send ok"));
    // blink green LED
    Utils.blinkRedLED(); 
  }
  else 
  {
    USB.println(F("send error"));     		
    // blink red LED
    Utils.blinkRedLED();  
  }   	

}

void dynamicBatteryControl()
{
  ///////////////////////////////////////////
  // 5. Sleep
  /////////////////////////////////////////// 
  // Get the iteration time
  iterTime = RTC.getEpochTime()-iterTime;
  USB.print(F("Total iteration seconds: "));
  USB.println(iterTime, DEC);

  battery = PWR.getBatteryLevel();

  ///////////////////////////////////////////
  // select time to sleep depending on battery level
  //        				 bat > LOW_BAT_THRESHOLD %  --> Good
  //   LOW_BAT_THRESHOLD % > bat > CRITIC_BAT_THRESHOLD %  --> Low 
  //        				 bat < CRITIC_BAT_THRESHOLD %  --> Critic 
  ///////////////////////////////////////////
  if( battery > LOW_BAT_THRESHOLD )
  {
    time_to_sleep = TIME_GOOD_BAT - iterTime;
    USB.println(F("Good battery level"));
  }
  else if( battery > CRITIC_BAT_THRESHOLD )
  {
    time_to_sleep = TIME_LOW_BAT - iterTime;
    USB.println(F("Low battery level"));
  }
  else
  {
    time_to_sleep = TIME_CRITIC_BAT - iterTime;
    USB.println(F("Critic battery level"));        
  }
  // Prevent problems
  if (time_to_sleep < 1) {
    time_to_sleep = 1; 
  } 
  else if (time_to_sleep > TIME_CRITIC_BAT) {
    time_to_sleep = TIME_CRITIC_BAT; 
  }

  // Convert the time to string
  RTC.breakTimeOffset(time_to_sleep, &time );
  snprintf(time_to_sleep_string, sizeof(time_to_sleep_string), 
  "%02d:%02d:%02d:%02d", time.date, time.hour, time.minute, time.second);

}

void update_time_to_sleep(){
  // USB.print(F("1. iterTime: "));
  // USB.println(iterTime);  

  iterTime = RTC.getEpochTime()-iterTimeb;

  // USB.print(F("2. iterTime: "));
  // USB.println(iterTime);  

  if(time_to_sleep<iterTime)
  {
    //no toco time to Sleep, ya que no queremos dormir mas de lo que hay actualmente
    // USB.print(F("Check 1 "));
  }
  else
  {
    time_to_sleep-=iterTime;
    // USB.print(F("Check 2 "));        
  }

  if(time_to_sleep<=0)
  {
    time_to_sleep=1;
    // USB.print(F("Check 3 "));
  }   

  // Convert the time to string
  RTC.breakTimeOffset(time_to_sleep, &time );
  snprintf(time_to_sleep_string, sizeof(time_to_sleep_string),
  "%02d:%02d:%02d:%02d", time.date, time.hour, time.minute, time.second);
  USB.print(F("New time to sleep: "));
  USB.println(time_to_sleep_string);

}

void set_time_from_meshlium(void)
{
  USB.println(F("[set_time_from_meshlium]		Started "));
  //	Set RTC time
  error = xbee802.setRTCfromMeshlium(MESHLIUM_ADDRESS);

  //	Check flag
  if(debug)
  {
    if( error == 0 )
    {
      USB.println(F("[set_time_from_meshlium]		SET RTC ok. "));
    }
    else 
    {
      USB.println(F("[set_time_from_meshlium]		SET RTC error. "));
    }  
  }

  delay(1500);
}

void setXbeeParameters(void)
{
  /////////////////////////////////////
  // 1. set channel 
  /////////////////////////////////////
  xbee802.setChannel( channel );

  // check at commmand execution flag
  if( xbee802.error_AT == 0 ) 
  {
    USB.print(F("1. Channel set OK to: 0x"));
    USB.printHex( xbee802.channel );
    USB.println();
  }
  else 
  {
    USB.println(F("1. Error calling 'setChannel()'"));
  }

  /////////////////////////////////////
  // 2. set PANID
  /////////////////////////////////////
  xbee802.setPAN( panID );

  // check the AT commmand execution flag
  if( xbee802.error_AT == 0 ) 
  {
    USB.print(F("2. PAN ID set OK to: 0x"));
    USB.printHex( xbee802.PAN_ID[0] ); 
    USB.printHex( xbee802.PAN_ID[1] ); 
    USB.println();
  }
  else 
  {
    USB.println(F("2. Error calling 'setPAN()'"));  
  }

  /////////////////////////////////////
  // 3. set encryption mode (1:enable; 0:disable)
  /////////////////////////////////////
  xbee802.setEncryptionMode( encryptionMode );

  // check the AT commmand execution flag
  if( xbee802.error_AT == 0 ) 
  {
    USB.print(F("3. AES encryption configured (1:enabled; 0:disabled):"));
    USB.println( xbee802.encryptMode, DEC );
  }
  else 
  {
    USB.println(F("3. Error calling 'setEncryptionMode()'"));
  }

  /////////////////////////////////////
  // 4. set encryption key
  /////////////////////////////////////
  xbee802.setLinkKey( encryptionKey );

  // check the AT commmand execution flag
  if( xbee802.error_AT == 0 ) 
  {
    USB.println(F("4. AES encryption key set OK"));
  }
  else 
  {
    USB.println(F("4. Error calling 'setLinkKey()'")); 
  }

  /////////////////////////////////////
  // 5. write values to XBee module memory
  /////////////////////////////////////
  xbee802.writeValues();

  // check the AT commmand execution flag
  if( xbee802.error_AT == 0 ) 
  {
    USB.println(F("5. Changes stored OK"));
  }
  else 
  {
    USB.println(F("5. Error calling 'writeValues()'"));   
  }

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

}

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

Re: OTA - Scan range with Meshlium & 802.15.4

Post by libelium-dev » Wed Nov 16, 2016 8:24 am

Hi,

Did you test with the OTA example code?

Also could you please tell to us the instructions you send trough OTA Shell application.

Regards

fransalcas
Posts: 8
Joined: Mon Nov 07, 2016 3:13 pm

Re: OTA - Scan range with Meshlium & 802.15.4

Post by fransalcas » Wed Nov 16, 2016 3:30 pm

Hi,

Did you test with the OTA example code?

Also could you please tell to us the instructions you send trough OTA Shell application.

Regards

Yes, I did test the example code and it only worked when the nodes were very close to Meshlium.

The instructions are:

Code: Select all

sensorParserD.sh stop
capturer S0 38400 
 +++OK   ATAP1   ATWR  ATWR
Then I have tried the following with no success at a distance of ~100m:

Code: Select all

./otap -scan_nodes --mode UNICAST --mac 0013a20040d7ec20 --time 30
./otap -scan_nodes --mode UNICAST --mac 0013a20040d7ee6a  --time 30
./otap -scan_nodes --mode BROADCAST  --time 30

./otap -send --file OTA_SEP.hex --mac 0013a20040d7ec20 --mode UNICAST --pid prosep1
./otap -send --file OTAF_SC.hex --mac 0013a20040d7ee6a --mode UNICAST --pid otafsc2

I have also checked Meshlium's antenna and everything looks fine.
Thanks for your help.

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

Re: OTA - Scan range with Meshlium & 802.15.4

Post by libelium-dev » Thu Nov 17, 2016 10:19 am

Hi,

Could you please check the power level of the 802.15.4 at the Meshlium manager system?
Which exactly Meshlium type do you have?

Also could you please try to increase the scanning time? We're trying to figure out why the difference between sending from the nodes and when scanning. Approximately at what distance you are able to find the nodes when scanning?

Regards

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest