Local Build Argon using po-util with OpenThread

Where did you find:

ot_api.h

and does anyone know how to do a monolithic build with po-util?

The ot_api.h header in the firmware repository, but you need to have checked out the mesh-develop branch, be building monolithic, and be targeting a mesh device.

1 Like

Hey @rickkas7 you familiar with po-util? I am using it on cloud9 Pro and very impressed

I think doing the following before building should work:

export MODULAR=n

I just tried it with a xenon build and it works.

It does take a little bit longer to compile of course.

1 Like

Is that just a command line statement before

po argon build

how to set it back to regular build?

1 Like

Yes.

You can set it back to modular (non-monolithic builds) with:

export MODULAR=y
1 Like

Hey @nrobinson2000 I am trying to get this really cool bit of code running on po-util using a monolithic build and the mesh-develop branch. I will keep trying but do you have any ideas?

#include "ot_api.h"
extern "C" {
	int8_t otPlatRadioGetRssi(otInstance *aInstance);
};

… hold on, I think it is working

Instead of exporting the MODULAR variable, you can do it temporarily on a command-by-command basis by just setting it right before your normal build command, all in one statement:

MODULAR=n po argon build

This will let you do the monolithic build, without resetting your environment for future commands.

2 Likes

I just tried to monolithically build the following and it worked:

#include "Particle.h"
#include "ot_api.h"
extern "C" {
	int8_t otPlatRadioGetRssi(otInstance *aInstance);
};


void setup() // Put setup code here to run once
{

}

void loop() // Put code here to loop forever
{

}
1 Like

Going to make my own thread since we moved away from range testing.

2 Likes

Or @rickkas7 or one of the Elites could move some of the replies to a new thread…

I did as well. Now what to do with it? Looks like this is the 2nd part to get the RSSI

int8_t rssi = otPlatRadioGetRssi(0);
snprintf(buf, sizeof(buf), “>%d <%d”, (int)rssi, lastRssi);

// where buf is an output string.

So this is working for me

#include "Particle.h"
// Easiest RSSI test program
// By Jeremy Ellis


#include "ot_api.h"
extern "C" {
	int8_t otPlatRadioGetRssi(otInstance *aInstance);
};


void setup() {
  
}

void loop() {

  int8_t rssi = otPlatRadioGetRssi(0);
  //snprintf(buf, sizeof(buf), “>%d <%d”, (int)rssi, lastRssi);
  
  Particle.publish("RSSI ", "#" + String(rssi), 60, PRIVATE);  //shows printing an integer variable
  Particle.publish("----------------","-------------", 60, PRIVATE);    // just to show a space between samples
  delay(10000); // wait about 10 seconds

}

Getting this published printout

This is on the Argon, Will now try flashing to a Xenon

Note: RSSI is a negative scale so -1 is a strong signal and -100 is a very weak signal
0 should be a very strong signal but I think I get a result of 0 when no other thread devices are connected.

I originally thought OTA was a really sstable flash. even in the school environment if it took about 15 minutes. I now have changed to flashing using DFU since the OTA does not give proof of success and just reverts to the old version of firmware if the OTA fails without giving you any idea if it worked or not.

A trick here is to change something in your publish statement even add a version to an output string so you can confirm if the upload was a success.

2 Likes

So I tried the program on the Xenon and nothing worked. So I put my Mesh Hello program back on the xenon and things worked again.

Probably because the program I was putting on the Xenon had no mesh.publish only a particle.publish

Anyway, things were kind of interesting. The strongest RSSI value I could get was -19 RSSI with both devices an inch apart. The first meter away from each other the RSSI values fell to about -60 and then they slowly fell more. The lowest reading I got was -93. I have not done any major range testing yet. Antennae testing that @rickkas7 was doing at Mesh range testing would be very interesting.

At one point, I reported that holding the devices vertically really increased the distance measurements. I am not seeing that confirmed with digital values at close range, but perhaps at longer ranges the orientation of the Mesh devices becomes important.

2 Likes

I’d advise recommending the method @dougal mentioned, so you can choose to build monolithically when building instead of exporting it.

## For a normal build
po argon build

## For a monolithic build
MODULAR=n po argon build
1 Like

Hey @rickkas7 or @will What is the strongest RSSI value (where -1 is strong and -100 is weak) that a Xenon will be allowed to connect to an Argon? I am seeing some weird data, where my Xenon is flashing cyan or even green but still registering that the mesh.publish is communicating, almost as if the Mesh will not allow a proper connection between a Xenon and an Argon unless it has a good RSSI value lets say of about -75.

The experiment:

So if I walk with my Xenon far enough away from my Argon, I lose connectivity, but my program shows the RSSI values using a mesh.publish, so as I walk back to the Argon I prove that Mesh.publish is working but my Xenon will not reconnect to the Argon until I get quiet a bit closer.

Data:

The Code:

I changed the code around a bit but loaded similar versions on both the Argon and the Xenon.


#include "Particle.h"
// Particle Mesh Devices RSSI distance testing 
// By Jeremy Ellis
// needs po-util

// po init argon myArgonProject
// cd myArgonProject

// po config mesh-develop 
// po setup-mesh

// MODULAR=n po argon build

// particle login
// particle list
// po argon ota myArgonName



#include "ot_api.h"
extern "C" {
	int8_t otPlatRadioGetRssi(otInstance *aInstance);
};




// Event listener for "mySendToAll" event from Xenons
void myHandler(const char *event, const char *data) {
    delay(5);  // sends the data so an RSSI value is registered
}




/////////////////////////// important globals here ///////////////////////////////

int  myCode = 1;  // Integer to identify this device
int  myCutoffInterest = 18;    // which positive version of RSSI should be fast flash. default 18
bool myXenonAntennaAttached = false;  
bool myArgonBothAntennaAttached = false;  
bool myPublishToConsole = true;        // set true for Argon or debugging

/////////////////////////////// end globals ////////////////////////////

void setup() {
   
   pinMode(D7, OUTPUT);
   Mesh.subscribe("mySendToAll", myHandler);
   if (myXenonAntennaAttached){
       #if (PLATFORM_ID == PLATFORM_XENON) 
	       digitalWrite(ANTSW1, 0);
	       digitalWrite(ANTSW2, 1);
       #endif  
   }
    if (myArgonBothAntennaAttached){
       #if (PLATFORM_ID == PLATFORM_ARGON) 
	       digitalWrite(ANTSW1, 1);
	       digitalWrite(ANTSW2, 0);
       #endif  
   }
     
}

void loop() {
    
     
    // here need to get the RSSI as myCode
    
    
    int8_t rssi = otPlatRadioGetRssi(0);   // activate on monolithic build

    Mesh.publish("mySendToAll", String(rssi));

    //int rssi = myCode;   // for testing 
    

    
    int myNumber;
 
     myNumber = ((int(rssi) * -1)  * 100) - (myCutoffInterest * 100);    // for testing, makes positive and larger
   
   
    if (int(rssi) == 0) {
        digitalWrite(D7, HIGH);  // D7 permanently on,  no connection
    }  else {
    
        if (myNumber <= 50){
            myNumber = 50;   // very fast flashing
        }   
 
        if (myNumber > 0){ 
            digitalWrite(D7, HIGH);
            delay(50);   // very quick flash
            digitalWrite(D7, LOW);
            delay(myNumber);   
        }  else {
       
            Particle.publish("Weird "+ String(myNumber), ", #" + String(rssi) , 60, PRIVATE);  //shows printing an integer variable
            delay(2000);
        }
    
    
    }
    
    if (myPublishToConsole){  // mainly for Argon gateway unless debugging
        Particle.publish("delay #" + String(myNumber), "Device #"+String(myCode) + ", RSSI #" + String(rssi), 60, PRIVATE);  //shows printing an integer variable
        delay(2000); // wait about 2 seconds
    }  
    

}
3 Likes

This may sound like a silly question, but where exactly is ot_api.h?

Good question, I thought it was on the OpenThread github but it is in the https://github.com/particle-iot/device-os/tree/mesh-develop github

Permanent link to ot_api.h here and the ot_api.cpp

Live link to the particle openthread mesh-develop folder https://github.com/particle-iot/device-os/tree/mesh-develop/hal/network/openthread

Lots of interesting stuff in that file and the accompanying .cpp file.

1 Like

Hey @rickkas7 or @dougal you guys got any more example main.cpp monolithic builds I can look at?

I am a javascript programmer lost in C++ :persevere:

This defines a property:

#include "ot_api.h"
extern "C" {
	int8_t otPlatRadioGetRssi(otInstance *aInstance);
};

which is then used by

int8_t rssi = otPlatRadioGetRssi(0);

I want to define lots of methods, as an easy example, how would I define and then use the following from cli.cpp

void Interpreter::ProcessFactoryReset(int argc, char *argv[])

I’m not really an expert (though I play one on TV – jk :rofl:). But searching around the OpenThread repo, it looks like that ProcessFactoryReset method just calls void otInstanceFactoryReset(otInstance *aInstance), which is defined in instance_api.cpp.

I’m assuming that the instance_api.cpp file is part of the build, so I’m guessing that just adding that function’s forward declaration to your extern "C" block will let you use it? But I’m not really positive. Give it a try! :slight_smile:

1 Like