Skip to content

More than 10 messages a second gives error LmacRxBlk:1 #12

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
NardJ opened this issue Oct 10, 2015 · 9 comments
Closed

More than 10 messages a second gives error LmacRxBlk:1 #12

NardJ opened this issue Oct 10, 2015 · 9 comments

Comments

@NardJ
Copy link

NardJ commented Oct 10, 2015

Using the server example and the html in the test subfolder, the updates (time messages) come in at 1 update every second. If I lower the html polling interval to <100ms it crashes with a message LmacRxBlk:1, which as I understand is a full buffer, but can't find a way to circumvent this. Is this maybe a bug?

I can't figure out what is wrong. Any help appreciated!
I tried to attach the html code but can't. Below the html with all <> replaced by []

[html]
[head]

[script]
var connection = new WebSocket('ws://192.168.0.13:81/test', ['arduino']);

connection.onopen = function () {
connection.send('Message from Browser to ESP8266 yay its Working!! ' + new Date());
connection.send('ping');
setTimeout(refresh,3000);
};

connection.onerror = function (error) {
console.log('WebSocket Error ', error);
};

connection.onmessage = function (e) {
console.log('Server: ', e.data);
};

function refresh(){
connection.send('Time: ' + new Date());
setTimeout(refresh,50);
}
[/script]

[/head]
[body]
Test Websocket.
[/body]
[/html]

@Links2004
Copy link
Owner

yes LmacRxBlk:1 means the buffer of the SDK is full, and there is new data incoming.
Basic the data rate is to much for the ESP to handle.

you can try to clock the ESP at 160Mhz to get more processing power, if that is failing too,
we can´t do anything, the problem comes form the WiFi handling in the SDK from espressif.
unfortunately all the WiFi parts are closed source.

github supports markdown for posting code see:
https://guides.github.com/features/mastering-markdown/

@starlino
Copy link

Markus, in WebSockets::sendFrame , you are currently making 2 client->tcp.write() calls:

// send header
client->tcp.write(&buffer[0], i);

if(payload && length > 0) {
    // send payload
    client->tcp.write(&payload[0], length);
}

These "writes" take approximately 200ms even if you send 1 byte !. They are expensive. I think , for advanced users we may offer ability to reserve a pre-buffer of 16 bytes before payload. This can be for example set with a flag : payload_has_prebufer16, then if this flag is set we know there's space reserved by advanced user before payload:

Then we can copy the buffer[i] before payload[0] and do a single write :

client->tcp.write(&payload[0] - i, length + i);

This way we don't need to copy payload and buffer to another common location, although this could be another option !

@Links2004
Copy link
Owner

@starlino yes a implementation like this is possible, and we save the second package.
will do some change for it.

@Links2004
Copy link
Owner

thanks @starlino for the idea.
a message faster then 20ms is unfortunately still is overkill for the ESP.

example:

  case WStype_TEXT:
        {
            Serial1.printf("[%u] get Text: %s\n", num, payload);

            uint8_t * buffer = (uint8_t *) malloc(lenght + 14);

            if(buffer) {
                memcpy((buffer+14), payload, lenght);
                // send data to all connected clients
                webSocket.broadcastTXT(buffer, lenght, true);
                free(buffer);
            }
        }
            break;

@NardJ
Copy link
Author

NardJ commented Oct 11, 2015

A message every 40ms (25 frames per sec) would also be acceptable.(about the minimum for the human eye to perceive it as motion). Is this feasible?

@Links2004
Copy link
Owner

i can send a message every 20ms from browser to the ESP. the ESP send it back to the browser.
in normal applications you not need the echo, then you can may go even faster.

@starlino
Copy link

Markus, wow ,20ms per packet is great ! Can it be because you're sending packets from computer and it is grouping them into single TCP packet ? But then I can't explain how the response comes back. From my experiments ESP cannot send packets faster then 200ms. However I can send large packets , so I can transfer a lot of data as long as I group them in large packets. It could be because of my router and frame size.

To test the real throughput of your ESP I wrote a little test, it basically sends small, then larger and larger packets from ESP to your computer. You must connect to your ESP via telnet and it will run the test. It also shows how you can use a timer (Ticker) to do things in the background while you wait for your packet to be sent. In this example we're simply increment the ticker_count every 10ms.

If anyone can run this test and share the results for different packet sizes , it would be great to compare.

P.S. I found that server.setNoDelay(false); and serverClient.setNoDelay(false); makes no significant difference for me , does it do anything for you ?

#include <ESP8266WiFi.h>
#include <Ticker.h>

//how many clients should be able to telnet to this ESP8266
#define MAX_SRV_CLIENTS 1
const char* ssid = "PUT_YOUR_SSID_HERE";
const char* password = "PUT_YOUR_PASS_HERE";

WiFiServer server(23);
WiFiClient serverClient;

#define BASE_LEN 200
#define STEP_COUNT 8
#define PACKET_COUNT 10
#define BUF_LEN (BASE_LEN*STEP_COUNT)
uint8_t buf[BUF_LEN];
int step_num = 1;
int packet_num = 1;

Ticker ticker;
volatile unsigned long ticker_count; 

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, password);

  Serial.print("\nConnecting to "); Serial1.println(ssid);
  unsigned long i = 0;
  while (WiFi.status() != WL_CONNECTED && i++ < 20) delay(500);
  if(i == 21){
    Serial.print("Could not connect to"); Serial.println(ssid);
    while(1) delay(500);
  }

  server.begin();
  server.setNoDelay(false);

  Serial.print("Ready! Use 'telnet ");
  Serial.print(WiFi.localIP());
  Serial.println(" 23' to connect");

  for(i=0;i<BUF_LEN;i++){
    buf[i] = 'A' + i % 25;
    if(0 == i % BASE_LEN) buf[i] = '0' + (i / BASE_LEN) % 10 ; 
    if((BASE_LEN-2) == i % BASE_LEN) buf[i] = '\r'; 
    if((BASE_LEN-1) == i % BASE_LEN) buf[i] = '\n';
  }

}


unsigned long time_start ;

void ticker_callback(){
  ticker_count++; 
}

void loop() {
  uint8_t i;
  //check if there are any new clients
  if (!serverClient && server.hasClient()){
    serverClient = server.available();
    serverClient.setNoDelay(false);
  }
  if(step_num > 0 && serverClient && serverClient.connected()){
    size_t len = BASE_LEN*step_num;
    if(1 == packet_num) time_start = millis();

    ticker_count = 0;
    ticker.attach_ms(10,ticker_callback);
    serverClient.write((const uint8_t *)buf, len);
    ticker.detach();

    packet_num++;
    if(PACKET_COUNT < packet_num){
        unsigned long time_delta = millis() - time_start;
        unsigned long BytesPS = PACKET_COUNT* len * 1000;
        BytesPS /= time_delta; 
        String str = "\r\n\r\n**Packet len="+String(len) + " ms=" + String(time_delta) + " Bytes/sec=" + String(BytesPS) + " ticker_count=" + String(ticker_count) +"\r\n\r\n";

        serverClient.write(str.c_str(), str.length());


        packet_num = 1;
        step_num++;
        if(STEP_COUNT < step_num){
          str = "Done\r\n";
          serverClient.write(str.c_str(), str.length());
          step_num = -1; 
          serverClient.stop();
        }  
    }
  }
  delay(0);
}

@Links2004
Copy link
Owner

I am not sure if I understand why you have the ticker in there.

test result

setNoDelay(false);

**Packet len=200 ms=13 Bytes/sec=153846 ticker_count=0
**Packet len=400 ms=22 Bytes/sec=181818 ticker_count=0
**Packet len=600 ms=23 Bytes/sec=260869 ticker_count=0
**Packet len=800 ms=25 Bytes/sec=320000 ticker_count=0
**Packet len=1000 ms=101 Bytes/sec=99009 ticker_count=4
**Packet len=1200 ms=407 Bytes/sec=29484 ticker_count=3
**Packet len=1400 ms=410 Bytes/sec=34146 ticker_count=3
**Packet len=1600 ms=431 Bytes/sec=37122 ticker_count=4

setNoDelay(true);

**Packet len=200 ms=17 Bytes/sec=117647 ticker_count=0
**Packet len=400 ms=24 Bytes/sec=166666 ticker_count=0
**Packet len=600 ms=20 Bytes/sec=300000 ticker_count=0
**Packet len=800 ms=24 Bytes/sec=333333 ticker_count=0
**Packet len=1000 ms=102 Bytes/sec=98039 ticker_count=3
**Packet len=1200 ms=404 Bytes/sec=29702 ticker_count=3
**Packet len=1400 ms=400 Bytes/sec=35000 ticker_count=4
**Packet len=1600 ms=35 Bytes/sec=457142 ticker_count=0

setup:

  • ESP12
  • Router with openWrt and 300Mbit Wifi

@NardJ
Copy link
Author

NardJ commented Oct 11, 2015

My test results.

setNoDelay(false):

*_Packet len=200 ms=538 Bytes/sec=3717 ticker_count=5
*_Packet len=400 ms=543 Bytes/sec=7366 ticker_count=5
*_Packet len=600 ms=564 Bytes/sec=10638 ticker_count=5
*_Packet len=800 ms=576 Bytes/sec=13888 ticker_count=5
*_Packet len=1000 ms=549 Bytes/sec=18214 ticker_count=5
*_Packet len=1200 ms=571 Bytes/sec=21015 ticker_count=5
*_Packet len=1400 ms=545 Bytes/sec=25688 ticker_count=5
*_Packet len=1600 ms=1106 Bytes/sec=14466 ticker_count=11

setNoDelay(true):

*_Packet len=200 ms=540 Bytes/sec=3703 ticker_count=5
*_Packet len=400 ms=548 Bytes/sec=7299 ticker_count=5
*_Packet len=600 ms=559 Bytes/sec=10733 ticker_count=5
*_Packet len=800 ms=546 Bytes/sec=14652 ticker_count=5
*_Packet len=1000 ms=549 Bytes/sec=18214 ticker_count=5
*_Packet len=1200 ms=553 Bytes/sec=21699 ticker_count=5
*_Packet len=1400 ms=547 Bytes/sec=25594 ticker_count=5
*_Packet len=1600 ms=1086 Bytes/sec=14732 ticker_count=10

Setup:

  • ESP-01
    -Router WGT624 v3 / 108Mbps Wifi

Maybe usefull: With the same setup, I also experimented with xmlhttp requests(xhr) and keeping the connection open, adding packets of data to the message (by the esp-01), reading partial message info (in html), I could achieve 18-20 additions per second (almost independent of block size). The test results above indicate the same number of packets per second..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants