Australia
Asked — Edited

How To Use Javascript For Saving Data Through UART Port?

Hi I need some help with "Terminal EZB" panel under general skills. I have got a few sensors added at JD's hands through an Arduino board. The sensors are expected to transmit some data and I am able to see it like below.

User-inserted image

Now, I'm trying to save this data to a text file and I've written the following code.

// Add the filename and use double \\ for the folder separator
var filename = "c:\\temp\\mylog.txt";

while(true){
  UART.initHardwareUart(1,9600,0);
  var uart_data = UART.hardwareUartReadStringAvailable(1,0);
  
    var d = new Date();
    var outStr = d.getHours().toString().padStart(2, '0') + ":" + 
                 d.getMinutes().toString().padStart(2, '0') + ":" + 
                 d.getSeconds().toString().padStart(2, '0') + ":" + 
                 d.getMilliseconds().toString().padStart(3, '0') + "," +
             uart_data;
      
    File.appendStringLine(filename,outStr);
}

However, I suspect that this piece of code is not correct as it prints only the timestamps and nothing else. So, can anyone please please point the error in this code?

Quote:

13:35:52:357, 13:35:52:370, 13:35:52:380, 13:35:52:392, 13:35:52:403, 13:35:52:414, 13:35:52:425, 13:35:52:437, 13:35:52:448, 13:35:52:459,
Thanks.


Related Hardware JD Humanoid
Related Control Serial Terminal

ARC Pro

Upgrade to ARC Pro

Your robot can be more than a simple automated machine with the power of ARC Pro!

PRO
Synthiam
#1  
  1. The hardware init needs to be outside of the loop. Otherwise you're initializing the uart (and clearing incoming buffer) every time it loops. That'll be happening hundreds of times per second. You only need to initialize once.

  2. The incoming data seems to be terminated by a new line. Do you know if it's a decimal 10, a decimal 13, or both? Because you'll have to parse the data based on the new line character. Look at the arduino code and tell me what terminator it's using.

  3. Because the data is pouring in at some unknown rate, the hardware uart read may only have half a line of data. OR will most likely have many lines of data. So the idea is to add the data to a buffer and then parse through the buffer.

I'll post something more detailed

PRO
Synthiam
#2   — Edited

Okay  here you go. I tested this and it works...

// Add the filename and use double \\ for the folder separator
var filename = "c:\\temp\\mylog.txt";

// init the uart 
UART.initHardwareUart(1,9600,0);

// define the buffer variable we'll use for all incoming data
var inBuffer = "";

// the main loop for the program
while(true){

  // add all available data to the input buffer
  inBuffer += UART.hardwareUartReadStringAvailable(1);

  // only process data if the input buffer has a terminator
  // and loop while there's still terminators
  while (inBuffer.indexOf("\n") >= 0) {

      // get the index of first instance of terminator character
     var len = inBuffer.indexOf("\n") + 1;
    
    // get the line of data up to the terminator
    var data = inBuffer.substring(0, len);
        
    // remove the bit from the buffer that we're processing
    inBuffer = inBuffer.substring(len);
               
     var d = new Date();
   
     var outStr = d.getHours().toString().padStart(2, '0') + ":" + 
                  d.getMinutes().toString().padStart(2, '0') + ":" + 
                  d.getSeconds().toString().padStart(2, '0') + ":" + 
                  d.getMilliseconds().toString().padStart(3, '0') + "," +
                  data;
         
      File.appendStringLine(filename, outStr);
   }
  
  // be friendly on resources
  sleep(250);
}

PRO
Synthiam
#3  

I updated my code sniplet to include a \n as terminator because that is what the arduino serial.println() uses

Australia
#4  

Thank you DJ Sures. I tested the code with my JD. Now it's working perfectly. I'm getting the proper output as follows:

Quote:

16:17:51:261,0, 140, 73, 0

16:17:51:273,1, 145, -176, 0

16:17:51:281,6, 97, 576, Release...

16:17:51:290,5, 176, -176, Touch!

16:17:51:299,0, 139, 52, 0

This is the Arduino code that I'm mainly using.

#define WIRE Wire //For teensyLC and Arduino Uno
//#define WIRE Wire1 //For others

#include  //For Arduino Uno
//#include  //Use  for Teensy

#include 

#define LOOP_TIME 10  // loop duration in ms

// Touch/release detection
#define EA 0.3  // exponential average weight parameter / cut-off frequency for high-pass filter

/***** GLOBAL VARIABLES *****/
#define NUMBER_OF_SENSORS 4
unsigned int proximity_value[NUMBER_OF_SENSORS]; // current proximity reading
unsigned int average_value[NUMBER_OF_SENSORS];   // low-pass filtered proximity reading
signed int fa2[NUMBER_OF_SENSORS];              // FA-II value
signed int fa2derivative[NUMBER_OF_SENSORS];     // Derivative of the FA-II value;
signed int fa2deriv_last[NUMBER_OF_SENSORS];     // Last value of the derivative (for zero-crossing detection)
signed int sensitivity[NUMBER_OF_SENSORS];  // Sensitivity of touch/release detection, values closer to zero increase sensitivity
int fingers[] = {0,1,6,5};
int touch_analysis = 1; //Default on

void setup()
{
  Serial.begin(115200);
  Serial.println("Robotic finger sensor eval online");

  WIRE.begin();
 
  for (int y = 0 ; y < NUMBER_OF_SENSORS ; y++)
  {
    int x = fingers[y];
    enableMuxPort(x);

    Serial.print("Finger ");
    Serial.print(x);
    if (testVCNL4040() == false)
      Serial.println(" failed to init. Check wiring.");
    else
      Serial.println(" online!");

    initVCNL4040(); //Configure sensor

    //delay(100);
    proximity_value[x] = readProximity(); //Get proximity values
    average_value[x] = proximity_value[x];
    fa2[x] = 0;

    sensitivity[x] = 50; //Set sensitivity for every finger to 50.

    disableMuxPort(x);
  }
}

void loop()
{
  unsigned long startTime = millis();

  for (int y = 0 ; y < NUMBER_OF_SENSORS ; y++)
  {
    int x = fingers[y];
    enableMuxPort(x); //Talk to this specific finger, and only this finger

    proximity_value[x] = readProximity(); //Get proximity values
    fa2deriv_last[x] = fa2derivative[x];
    fa2derivative[x] = (signed int) average_value[x] - proximity_value[x] - fa2[x];
    fa2[x] = (signed int) average_value[x] - proximity_value[x];

    //Serial.print(startTime);
    //Serial.print(", ");
    Serial.print(x);
    Serial.print(", ");
    Serial.print(proximity_value[x]);
    Serial.print(", ");
    Serial.print(fa2[x]);
    Serial.print(", ");

    //Serial.print(",");
    //Serial.print(fa2derivative);

    if ((fa2deriv_last[x] < -sensitivity[x] && fa2derivative[x] > sensitivity[x]) || (fa2deriv_last[x] > sensitivity[x] && fa2derivative[x] < -sensitivity[x])) { // zero crossing detected
      // Serial.print(proximity_value); Serial.print(","); Serial.print(fa2); Serial.print(","); Serial.println(fa2derivative);
      if (fa2[x] < -sensitivity[x]) // minimum
      {
        Serial.print("Touch!");
      }
      else if (fa2[x] > sensitivity[x]) // maximum
      {
        Serial.print("Release...");
      }
    }
    else
      Serial.print("0");

    Serial.println();

    average_value[x] = EA * proximity_value[x] + (1 - EA) * average_value[x];

    disableMuxPort(x); //Stop talking to this finger
  }

  // Do this last
  while (millis() < startTime + LOOP_TIME); //  enforce constant loop time
}