0

I'm trying to get an arduino sending data to node but with no success. I'm connecting to an ar-drone 2.0 as in https://gist.github.com/maxogden/4152815

Here is my Arduino code:

    #include <TinyGPS++.h>
    #include <SoftwareSerial.h>
    #include <Wire.h>
    #include "Adafruit_HTU21DF.h"
    /*
      Sketch per creare json contenente
      lat,lon,data,ora,temp, hum
    */
    static const int GPS_RXPin = 16, GPS_TXPin = 10;
    static const uint32_t GPSBaud = 9600;


    Adafruit_HTU21DF htu = Adafruit_HTU21DF();

    // The TinyGPS++ object
    TinyGPSPlus gps;

    // The serial connection to the GPS device
    SoftwareSerial ss(GPS_RXPin, GPS_TXPin);

    //JSON
    const size_t bufferSize = JSON_OBJECT_SIZE(6);
    DynamicJsonBuffer jsonBuffer(bufferSize);
    JsonObject& oData = jsonBuffer.createObject();

    void setup()
    {
      Serial1.begin(9600);
      Serial.begin(9600);
      ss.begin(GPSBaud);
      if (!htu.begin()) {
        Serial1.println("Couldn't find Adafruit_HTU21DF!");
        while (1);
      }
    }

    void loop()
    {
      float lat = gps.location.lat();
      float lon = gps.location.lng();
      float date = gps.date.value();
      float timestamp = gps.time.value();
      float temp = htu.readTemperature();
      float hum = htu.readHumidity();

      Serial1.print(lat);
      Serial1.print(";");
      Serial1.print(lon);
      Serial1.print(";");
      Serial1.print(date);
      Serial1.print(";");
      Serial1.print(timestamp);
      Serial1.print(";");
      Serial1.print(temp);
      Serial1.print(";");
      Serial1.print(hum);
      Serial1.print(";\n");

      //////

      Serial.print(lat);
      Serial.print(";");
      Serial.print(lon);
      Serial.print(";");
      Serial.print(date);
      Serial.print(";");
      Serial.print(timestamp);
      Serial.print(";");
      Serial.print(temp);
      Serial.print(";");
      Serial.print(hum);
      Serial.print(";\n")

      smartDelay(1000);
      if (millis() > 5000 && gps.charsProcessed() < 10)
        Serial1.println(F("No GPS data received: check wiring"));
    }

    // This custom version of delay() ensures that the gps object
    // is being "fed".
    static void smartDelay(unsigned long ms)
    {
      unsigned long start = millis();
      do
      {
        while (ss.available())
          gps.encode(ss.read());
      } while (millis() - start < ms);
    }

and this my NodeJS code:

    var serialport = require('node-serialport');
    var WebSocketServer = require('ws').Server;

    var wss = new WebSocketServer({host:'0.0.0.0',port: 9999});
    var sp = new serialport.SerialPort("/dev/ttyO3", {
      parser: serialport.parsers.readline("\n"),
      baud: 9600,
      buffersize: 65536
    });

    wss.on('connection', function(ws) {
      ws.send('connected');
      ws.on('message', function(message) {
        console.log('received: %s', message);
      });
      sp.on('data', function(chunk) {
        var fromArduino = chunk.toString();
        ws.send(fromArduino);
        console.log(fromArduino);
      });
    });

While the CSV comes out nice on Arduino IDE serial monitor, it is all messed up both on ws and node console.

drone console shows messed up strings, adruino ide monitor shows them fine

I'm using this version of NodeJS and node-serial: https://github.com/felixge/node-cross-compiler/downloads

and set ttyO3 as in https://gist.github.com/maxogden/4152815

A voltage diveder is set between drone RX and Arduino TX1 to lower signal from 5v to 1.8v.

Thanks for any help!

Lorenzo


UPDATE 2 JUN 2018 I managed to make things a little bettere with the following code: ARDUINO: #include #include #include "Adafruit_HTU21DF.h" /* Sketch per creare json contenente lat,lon,data,ora,temp, hum */ static const uint32_t GPSBaud = 9600;

    Adafruit_HTU21DF htu = Adafruit_HTU21DF();

    // The TinyGPS++ object
    TinyGPSPlus gps;

    void setup()
    {
      Serial1.begin(9600);
      //  Serial.begin(9600);
      if (!htu.begin()) {
        Serial1.println("Couldn't find Adafruit_HTU21DF!");
        while (1);
      }
    }

    void loop()
    {
      while (Serial1.available()) {
        gps.encode(Serial1.read());
      }
      float lat = gps.location.lat();
      float lon = gps.location.lng();
      int date = gps.date.value();
      float timestamp = gps.time.value();
      float temp = htu.readTemperature();
      float hum = htu.readHumidity();

      Serial1.print(lat);
      Serial1.print(";");
      Serial1.print(lon);
      Serial1.print(";");
      Serial1.print(date);
      Serial1.print(";");
      Serial1.print(timestamp);
      Serial1.print(";");
      Serial1.print(temp);
      Serial1.print(";");
      Serial1.print(hum);
      Serial1.print(";_");
      Serial1.println();
    }

NODE JS:

    var serialport = require('node-serialport');
    var WebSocketServer = require('ws').Server;

    var wss = new WebSocketServer({host:'0.0.0.0',port: 9999});
    var sp = new serialport.SerialPort("/dev/ttyO3", {
      parser: serialport.parsers.readline("_"),
      // parser: serialport.parsers.raw,
      baud: 9600,
      buffersize: 1024
    });
    wss.on('connection', function(ws) {

      sp.on('data', function(chunk) {
        var fromArduino = chunk.toString();
        // console.log(fromArduino);
        ws.send(fromArduino);
        sp.flush();
      });
    });

Now data comes out tidy on both console and ws for most of the times: I guess the problem was the serialport buffersize.

I also removed serial software from Arduino code.

  • 2
    Can't see what's wrong, but a few simplifications could help you nail down the problem: 1. Get rid of SoftwareSerial and use only the hardware serial port: RX from the GPS and TX to the drone. 2. Remove the HTU and JSON code from the Arduino. 3. Remove the WebSockets code from the Node.js. 4. Use parsers.readline("\r\n"), as that's what Serial.println() sends. – Edgar Bonet May 30 '18 at 20:27
  • 1
    since the serial monitor shows correct data, i suspect that your NodeJS code has a bug .... therefore this is not an Arduino question – jsotola May 30 '18 at 23:58
  • @lbrutti try getting rid of your parser and directly print every received character from the UART device (/dev/ttyO3) to the console as fast as possible. Maybe a UART buffer is overflowing when it isn't read fast enough. Did you also try Edgar's suggestion? – Maximilian Gerhardt Jun 1 '18 at 13:17
  • Hello, i tried removing ws and software serial. Still node output comes out chunked. I'll try to bypass parsers and let you know. Thanks – lbrutti Jun 2 '18 at 9:33
  • @maximilian-gerhardt: i simplified the code by removing software serial and using a smaller buffer. data comes out tidy most of the times: not always but it is accepteable for this early prototyping stage. – lbrutti Jun 2 '18 at 20:34
2
  Serial.print(lat);
  Serial.print(";");
  Serial.print(lon);
  Serial.print(";");
  Serial.print(date);
  Serial.print(";");
  Serial.print(timestamp);
  Serial.print(";");
  Serial.print(temp);
  Serial.print(";");
  Serial.print(hum);
  Serial.println(";");

Serial.println will print an \r\n at the end (source). \r is a "carriage return" which will move the curser back to the beginning of the line.

Since you are reading your data with a parser that looks for \n and removes that, you are left with a string that looks like [csv data..]\r. Once you print that to console verbatim you get the behaviour you are looking at.

Replace Serial.println(";"); by Serial.print(";\n"); (same for Serial1) and see what happens.

  • hello, unfortunately adding "\n" char at the end of last print didn't help: both console and ws output are messed. Serial Monitor output works well as before. – lbrutti May 31 '18 at 7:07
  • @lbrutti edit your question to show the updated code, then. – Maximilian Gerhardt May 31 '18 at 9:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.