Canada
Asked — Edited
Resolved Resolved by DJ Sures!

UART Javascript Help

While programming a little bit of this and that over the years and understanding the concepts of programming, I'm actually not that well-practiced. Syntax and nuances usually get me. I have gone over the Javascript UART section up and down but couldn't find the answers I was looking for.

While doing some UART Javascript code, sending a packet of information I found myself using the following code lines:

UART.hardwareUartWrite(1, 0xFF);
UART.hardwareUartWrite(1, 0xFF);
UART.hardwareUartWrite(1, 0x01);
UART.hardwareUartWrite(1, 0x05);
UART.hardwareUartWrite(1, 0x03);
UART.hardwareUartWrite(1, 0x20);
UART.hardwareUartWrite(1, 0x99);
UART.hardwareUartWrite(1, 0x04);
UART.hardwareUartWrite(1, 0x39);

Is there a more efficient way to send multiple bytes to the UART than to re-write UART.hardwareUartWrite()  for every byte?

I tried the following, but it didn't compile:

UART.hardwareUartWrite(1, 0xFF + 0xFF + 0x01 + 0x05 + 0x03 + 0x20 + 0x99 + 0x04 + 0x39);

I received the following error: "Execution Error Line 1 Col 0 - No public methods with the specified arguments were found."

I have been also writing some UART receive code and was wondering if there is a hidden way to flush (clear) the receive buffer?

I've successfully grabbed the bytes I need from the received data array but I want to clear the buffer and start again to receive a fresh reading after I loop. I don't think the receive buffer is flushed (cleared) when I do a new reading, correct? Here's an example:

var g = 0;
var q = 0;
var r = 0;

while(true){

g = UART.hardwareUartAvailable(0);

  if(g > 0){

    q = UART.hardwareUartRead(0, 4);  //read 4 bytes from the receive buffer
    r = (q[1] * 256) + q[2];          //Multiply 2nd byte by 256 and add 3rd byte
    print("Distance(mm):" + r);       //print distance value
    sleep(250);
    g = 0;
    q = 0;
  
  }
}

Grateful for any help! Thanks!


Related Hardware EZ-B v4
Related Control Script

ARC Pro

Upgrade to ARC Pro

Experience early access to the latest features and updates. You'll have everything that is needed to unleash your robot's potential.

PRO
Synthiam
#1  

Create an array. See the documentation for the command here: https://synthiam.com/Support/javascript-api/UART/hardwareUartWrite

It accepts either a single byte or an array of bytes. Here's an example...


UART.initHardwareUart(0, 9600);

UART.hardwareUartWrite(0, [0xff, 0xf0, 0x30]);


Here's information about what an array is: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array

PRO
Synthiam
#2   — Edited

PS, your code could be written more efficiently like so...


while(true) {

  if (UART.hardwareUartAvailable(0) > 3) {

    var q = UART.hardwareUartRead(0, 4);  //read 4 bytes from the receive buffer
    var r = (q[1] * 256) + q[2];          //Multiply 2nd byte by 256 and add 3rd byte
    print("Distance(mm):" + r);       //print distance value
  }

  sleep(250);
}

PRO
Canada
#3  

Excellent! Thank you @DJ

I knew there had to be something I was missing for the first question! Sometimes I wish the JavaScript support section had proper syntax examples for newbs like me :D

Thanks for the code clean-up, I do need help from mentors such as yourself to help me make my code more efficient.

As for the second part of my question, I read somewhere that it's proper just to read everything into an array from the UART buffer, take what you need, and then read it again. You don't have to worry about flushing (clearing) the buffer. Is this true?

PRO
Synthiam
#4  

Don’t read everything because you might be in between packets. Take what you expect based on what’s available.

don’t flush the uart (ie re-init). That’s also gonna end up with half a packet.

PRO
Synthiam
#5  

I'll expand since i'm on my pc now.

A properly designed protocol has either

  1. a consistent known packet length
  2. a header that defines the packet length

*Note: There are some people who implement poor communication by using "termination". That means you send a bunch of characters and it is "terminated" with a specified token.

So if you are reading, the two examples I provided above allow you to know how much data to read.

1) Consistent known packet length I use the word consistent because it means the receiver ALWAYS knows the packet length. Although there could be an exception in the header that if a specific header value is sent, that means the next value is "the length of data". So you can mix the two together. The EZB protocol does that - but don't worry about it because it's beyond the scope of your question.

A consistent length means you know every packet is 2 bytes. So, therefore, you only need to read when there are MORE or EQUAL TO 2 bytes in the buffer.


// Are there at least two bytes available?
 if (UART.hardwareUartAvailable(0) >= 2) {

  // read 2 bytes from the buffer
  var q = UART.hardwareUartRead(0, 2);

 // Do something with the received data
}

2) Packet Header specifies data length This is when the transmitter has a specific header that specifies how much data is to follow. Funny enough, many protocols also include "parity" bytes when using TCP or even Bluetooth serial (haha). That's redundant and quite ridiculous, but software engineers get off by making things confusing. You know, the more confusing it is, the smarter the programmer was? (no but they think so).

Anyway, back on track. You never need a parity byte with tcp or Bluetooth serial because it's already built into the underlying communication protocol. Even with hardware UART, i wouldn't bother...

So if you designed a protocol and needed to transmit a variable length of data, you do this...

Transmitter


var str = "some random amount of data";

// write the amount of data we're gonna send
UART.hardwareUartWrite(0, str.length);

// now send the data
UART.hardwareUartWriteString(0, str);

Receiver


while (true) {

  var availableBytes = UART.hardwareUartAvailable(0);

  // must be more than one byte available because the packet length can't be 0
  if (availableBytes > 1) {

    // we have data so let's grab the header which tells us the packet length    
    var len = UART.hardwareUartRead(0, 1);
    
    // get all the data (it will block until all data is sent to ezb)
    var data = UART.hardwareUartReadString(0, len);
    
    // do something with data
  }
  
  sleep(100);
}

PRO
Synthiam
#6  

And here is the same thing above but with bytes rather than a string..

Transmitter


var str = [0xff, 0xfe, 0xfa, 0x35, 0xaf];

// write the amount of data we're gonna send
UART.hardwareUartWrite(0, str.length);

// now send the data
UART.hardwareUartWrite(0, str);

Receiver


while (true) {

  var availableBytes = UART.hardwareUartAvailable(0);

  // must be more than one byte available because the packet length can't be 0
  if (availableBytes > 1) {

    // we have data so let's grab the header which tells us the packet length    
    var len = UART.hardwareUartRead(0, 1);
    
    // get all the data (it will block until all data is sent to ezb)
    var data = UART.hardwareUartRead(0, len);
    
    // do something with data
  }
  
  sleep(100);
}

PRO
Canada
#7  

Thank you DJ for taking the time to answer and explain this question, it definitely helped!