Bandwidth mesh Argon / Xenon

xenon
argon
Tags: #<Tag:0x00007f1cae711598> #<Tag:0x00007f1cae711430>

#1

Hello,

I have a Argon and Xenon connected together in mesh.

It’s work well, but I would like to estimate the bandwidth in different condition : Indoor, outdoor …
I’m not expecting thousand of megabyte, my goal is to have a better idea of the real capacity.

Currently, I did some first test with “marco-polo” script, it’s good for known the latency and maximum range available… but not for the capacity.

Do you know how can I do it ? Or the best way to do it.

Regards,

Thomas.


#2

@Tlams, the raw (low level) 802.15.4 6Lowpan top speed is 250Kbps. With OpenThread and Particle’s protocol overhead, the data rate will most likely be below 25KB/s.


#3

Hi @peekay123,

Thanks for your answer.
Any way to prove it ?


#4

You could create a very basic app that transmits data as fast as possible using mesh.publish(). Then have another node or gateway with another basic app that received those publishes and aggregates the statistics.

Here’s something I threw together. I am testing this out now.

Transmit Node:

unsigned long counter = 0;
char msg[20];

int LED = D7;               

unsigned long lastPub = 0;
unsigned long pubInterval = 0;

unsigned long lastLED = 0;
unsigned long LEDInterval = 1;

void setup()
{
    Serial.begin();
    pinMode(LED, OUTPUT); 
}

void loop() {
    if (millis() - lastPub > pubInterval) {
        if (Mesh.ready()) {
            snprintf(msg, sizeof(msg), "%010lu", counter);
            Mesh.publish("BT",msg);
        }
        counter++;
        digitalWrite(LED, HIGH);
        lastLED = millis();
        lastPub = lastLED;
        
        //Serial.printlnf("%u", counter);
    }
    
    if (digitalRead(LED) && millis() - lastLED > LEDInterval) {
        digitalWrite(LED, LOW);
    }
}

Receive Node:



SYSTEM_THREAD(ENABLED);

//Average Bytes/Second tracking variables.
unsigned long counter = 0;          //Payload data from the XMit node.
unsigned long lastCounter = 0;      //Last payload received from the xmit node.
int missedCounter = 0;              //Number of missed publishes.

float intervalAvg = 0;              //Average bytes/second over the interval.
unsigned long intervalCount = 0;    //Number of received payloads over the interval.

float bwAvg = 0;                    //Average bytes/second since starting the application.
unsigned long bwSamples = 0;        //Number of samples used to obtain the average (adds "weight" to the older data points.)

const int bwLength = 10; //Bytes per payload recevied via Mesh.subscribe.

//Millis timer variables.
unsigned long lastMath = 0;         //Last time we calculated the interval.
unsigned long mathInterval = 1000;  //Sampling/calculation interval.

unsigned long lastPub = 0;          //Last time stats were published.
unsigned long pubInterval = 5000;   //Publishing interval.

bool resetFlag = false;

//Debugging Variables
char msg[50];

void setup() {
    Mesh.subscribe("BT", speedTestHandler);
}

void loop() {
    if (resetFlag) {
        Serial.println("Xmit node reset.");
        resetFlag = false;
    }
    
    //Calculate the statistics at the math interval.
    if (millis() - lastMath >= mathInterval) {
        lastMath = millis(); //Reset the millis timer.
        
        //Debugging Only
        Serial.printlnf("Last msg: %s", msg);
        
        if (intervalCount == 0) { return; }  //Divide by zero safeguard.
        intervalAvg = (intervalCount * bwLength) / (mathInterval / 1000);   //Calculate the average bytes/second for this interval.
        intervalCount = 0;  //Reset interval counter.
        
        if (bwSamples = -1) { return; } //Divide by zero safeguard.
        bwAvg = ( (bwAvg * bwSamples) + intervalAvg ) / bwSamples++;    //Calculate the overall (since start) average bytes/second.

    }
    
    //Publish the statistical data at the publish interval (using serial at the moment.)
    if (millis() - lastPub >= pubInterval) {
        Serial.printlnf("BWTest; Interval Avg: %6.2f; Missed: %i, Avg: %6.2f; c/lc: %u/%u", intervalAvg, missedCounter, bwAvg, counter, lastCounter);
        lastPub = millis(); //Reset the millis timer.
    }
}

//This gets called everytime a Bandwidth Test "BT" message is received via Mesh.publish().
void speedTestHandler(const char *event, const char *data)
{
    //Set the counter variable to the message payload.
    counter = atol(data);
    
    //Debugging only.
    strcpy(msg,data);
    
    //Safeguard for the starting condition.
    if (lastCounter == 0) {
        lastCounter = counter;
        return;
    }
    
    //Program was restarted on xmit node, reset the counters.
    if (counter < lastCounter) {
        resetCounters();
        resetFlag = true;
        return;
    }

    missedCounter += (counter - lastCounter) - 1; //Track if there are gaps the in the sequential payload data. (i.e. missed publishes or subscribes)
    lastCounter = counter;  //Update last counter variable.
    intervalCount++;    //Increment the counter for this interval (number of publishes received.)
}

void resetCounters() {
    lastCounter = counter;
    bwAvg = 0;
    bwSamples = 0;
    intervalAvg = 0;
    intervalCount = 0;
    missedCounter = 0;
}

#5

I debugged the above code and just updated it.

Realistically, I can’t get more than about 2 kbytes/sec. With the pubinterval set to 0 on the xmit node, I am seeing an interval average of about 2 kbytes/s but the “missed” packets is on the order of 2000-3000 for each receive node publish interval. When I set the publish interval on the xmit node to about 5ms, I get about 1.5 kbytes/s and the “missed” packets is only about 1-10 per receive node publish interval.

I should also note that I’m only measuring the payload bytes and I’m transmitting 10 characters (= 10 bytes) for each payload (the length of a long integer padded with zeros). The event name and any other overhead is ignored.