Skip to content
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

mJs UART API performance problems #22

Closed
aifer2007 opened this issue Apr 11, 2017 · 4 comments
Closed

mJs UART API performance problems #22

aifer2007 opened this issue Apr 11, 2017 · 4 comments
Assignees

Comments

@aifer2007
Copy link

aifer2007 commented Apr 11, 2017

I try the mJs UART APIs to receive datas on ESP32 uart port.

Data rate: 46 bytes per 20ms, total 23000 bytes in 10s.

There are some performance problems.

let rxAcc = ""; // to store all the bytes received
let rx_total = 0; // total number of received bytes
// Configure UART at 115200 baud
UART.setConfig(1,{
  baudRate: 115200,
});

UART.setDispatcher(1, function(uartNo, ud) {
  let ra = UART.readAvail(uartNo);
  if (ra > 0) {
    let data = UART.read(uartNo);
    rxAcc += data;
    rx_total += data.length;  
  }
}, null);

// Enable Rx
UART.setRxEnabled(1, true);

UART.write(1,"go");  // signal, a nodejs serialport connected to EPS32 will start 
                        sending data

Timer.set(15000 /* milliseconds */, false /* repeat */, function() {
  print("rxAcc lent: "); // =>13150, some datas are lost by rxAcc += data; !!!
  print(rxAcc.length);
  print("rx_total: ");  // =>23000, all the datas are transfered from C to mJs.
  print(rx_total);
}, null);

Here, rx_total = 23000 means that all the datas are received and transfered to mJs by mongoose os kernel.
And, rxAcc.length = 13510 means some datas are lost when "rxAcc += data" is executed !!!

If I change the data rate to 46 bytes per 40ms , rxAcc.length = 23000 all the time, no bytes are lost.

If I delete the "rxAcc += data" line, no data will be lost at the MAX data rate: 46 bytes per 7ms, about 52500bps. Code is here:

UART.setDispatcher(1, function(uartNo, ud) { let ra = UART.readAvail(uartNo); if (ra > 0) { let data = UART.read(uartNo); // rxAcc += data; rx_total += data.length; } }, null);

I have tried to tune the rx buffer size to 1024/2048, the same result.

My questions are:

  1. How can I store datas without losing at data rate: 46 bytes per 20ms?

  2. Is 52500bps the TOP speed of mJs UART APIs?

  3. Is there some way to improve the performance of mJs UART APIs?

@dimonomid
Copy link
Contributor

@aifer2007 , could you please also share the code which sends the data? So that I can reproduce the issue easily.

@aifer2007
Copy link
Author

aifer2007 commented Apr 11, 2017

Yes, thanks.
Nodejs code here:

var SerialPort = require("serialport").SerialPort
var serialPort = new SerialPort("/dev/tty.usbserial-A94JN1PL", {
  baudrate: 115200, autoOpen: false,
});

serialPort.open(function (error) {
  if ( error ) {
    console.log('failed to open: '+error);
  } else {
    console.log('open');
    serialPort.on('data', function(data) {
      console.log('data received: ' + data);
      if(data.indexOf('talkstart')> -1) {
        let vd = "1234567890123456789012345678901234567890123456";
        console.log("data packet len: " + vd.length);
        let pktNum = 0;
        let id = setInterval(function(){
          serialPort.write(vd, function(err, results) {
            if(err) {
              console.log('err ' + err);
            } else {
              pktNum++;
              if(pktNum>499) clearInterval(id);
            }
          });
        }, 20); // 46bytes/20ms, 23000 bytes total
      }
    });

  }
});

@dimonomid
Copy link
Contributor

dimonomid commented Apr 12, 2017

Honestly, failed to reproduce. I used your scripts, and the only (seemingly unrelated) modification I had to do is the following: since I upload init.js to the device and restart it with the following command:

mos put init.js && mos call Sys.Reboot && mos console

we shouldn't emit go in the beginning of device execution, because that could lead to multiple go being emitted (the first one could be emitted right before device reboot), so node script starts two sequences of data. So I emit go after 2 seconds.

All in all, here are the scripts I use:

init.js on esp32:

// Load Mongoose OS API
load('api_timer.js');
load('api_uart.js');
load('api_sys.js');

let rxAcc = ""; // to store all the bytes received
let rx_total = 0; // total number of received bytes
// Configure UART at 115200 baud
UART.setConfig(1,{
  baudRate: 115200,
});

UART.setDispatcher(1, function(uartNo, ud) {
  let ra = UART.readAvail(uartNo);
  if (ra > 0) {
    let data = UART.read(uartNo);
    rxAcc += data;
    rx_total += data.length;  
    print("len:", data.length, "total:", rx_total);
  }
}, null);

// Enable Rx
UART.setRxEnabled(1, true);

// Start communication after 2 seconds
Timer.set(2000 /* milliseconds */, false /* repeat */, function() {
  // signal, a nodejs serialport connected to EPS32 will start sending data
  UART.write(1,"go");
}, null);

Timer.set(17000 /* milliseconds */, false /* repeat */, function() {
  print("==================");
  print("rxAcc lent:", rxAcc.length, "rx_total:", rx_total);
}, null);

Node.js script:

'use strict';

var SerialPort = require("serialport")
var serialPort = new SerialPort("/dev/ttyUSB1", {
  baudRate: 115200, autoOpen: false,
});

serialPort.open(function (error) {
  if ( error ) {
    console.log('failed to open: '+error);
  } else {
    console.log('open');
    serialPort.on('data', function(data) {
      console.log('data received: ' + data);
      if(data.indexOf('go')> -1) {
        let vd = "1234567890123456789012345678901234567890123456";
        console.log("data packet len: " + vd.length);
        let pktNum = 0;
        let id = setInterval(function(){
          serialPort.write(vd, function(err, results) {
            if(err) {
              console.log('err ' + err);
            } else {
              pktNum++;
              if(pktNum>499) clearInterval(id);
            }
          });
        }, 20); // 46bytes/20ms, 23000 bytes total
      }
    });

  }
});

In the end, device always prints:

================== 
rxAcc lent: 23000 rx_total: 23000

@dimonomid
Copy link
Contributor

Closing this one. If you believe that the issue is still here, feel free to provide more details and reopen.

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

2 participants