2

Ì am building speedometer with NEO-6M and have some problems with my code. The scenario is that I send some data from our Arduino to another device via a TX pin with a delay of 50 ms. This delay of 50 ms needs to be maintained and should not exceed. The issue with GPS data, which arrives from the device, is that it is received every 1 second. This issue will cause the 50ms delay to be longer and exceed to 1050 ms. In my last code change delay is not maintained on 50 ms, it is all 1000 ms. Not sure what I did wrong. My code is

original

#include <AD9850.h>
#include <TinyGPS++.h>
#include <SoftwareSerial.h>

static const int RXPin = 0, TXPin = 1;
static const uint32_t GPSBaud = 9600;

const int W_CLK_PIN = 8;
const int FQ_UD_PIN = 9;
const int DATA_PIN = 10;
const int RESET_PIN = 11;

double freq = 1;
double trimFreq = 124999500;

int phase = 0;

unsigned int speed = 0;

TinyGPSPlus gps;
SoftwareSerial ss(RXPin, TXPin);

void setup()
{
  Serial.begin(115200);
  ss.begin(GPSBaud);
  DDS.begin(W_CLK_PIN, FQ_UD_PIN, DATA_PIN, RESET_PIN);
  DDS.calibrate(trimFreq);
}

void loop()
{
  // Dispatch incoming characters
  while (ss.available() > 0)
    gps.encode(ss.read());

  {
    digitalWrite(outPin, HIGH);   // sets the pin on
    delayMicroseconds(50);        // pauses for 50 microseconds
    digitalWrite(outPin, LOW);    // sets the pin off
    delayMicroseconds(50);        // pauses for 50 microseconds
  }

  if (gps.speed.isUpdated())
  {
    Serial.print(F("SPEED      Fix Age="));
    Serial.print(gps.speed.age());
    Serial.print(F("ms Raw="));
    Serial.print(gps.speed.value());
    Serial.print(F(" km/h="));
    Serial.println(gps.speed.kmph());
    speed = gps.speed.kmph();
    //calculate the frequency with map()
    freq = map(speed, 0, 100, 0, 160);
    DDS.setfreq(freq, phase);
  }
}

revised

(replying to https://arduino.stackexchange.com/a/45657) Thank you for help. Is it possible to put GPS speed in this code? https://pastebin.com/LdT7UHBQ I used your code and it works but my boss demands that we modify his code and make it maintain delay with it.

long prevTxTime = 0;
const int delayTime = 51;


void setup()
{
  Serial1.begin(115200);
  Serial2.begin(115200);
}

void loop()
{


  int b, chunk = 0;

  if (Serial2.available())
  {
    b = Serial2.read();
    chunk = b >> 6;
    if (chunk == syncc)
    {
      bytes[syncc] = b & 63;
      syncc++;
      if (syncc == 4)
      {
        syncc = 0;
        tach = bytes[0] + (bytes[1] << 6);
        velocityfreq = bytes[2] + (bytes[3] < delayTime)
        {
          //speed from gps would most likely need to be set here as "speedfromgps"

          SendData();
          prevTxTime = millis();
        }
      }


      void SendData()
      {
        sprintf(charToSend, "%d|%d|%d|%d|%d\n\r",
                data1, data2, data3, data4, speedfromgps);

        Serial1.print(charToSend);
      }
  • Thank you for help. Is it possible to put gps speed in this code? pastebin.com/LdT7UHBQ I used your codeand it it works but my boss demands that we modify his code and make it maintain delay with it. long prevTxTime=0; const int delayTime=51; void setup() { Serial1.begin(115200); Serial2.begin(115200); } void loop() { int b, chunk = 0; if (Serial2.available()) { b = Serial2.read(); chunk = b >> 6; if (chunk == syncc) { bytes[syncc] = b & 63; syncc++; if (syncc == 4) { syncc = 0; tach = bytes[0] + (bytes[1]<<6); velocityfreq = bytes[2] + (bytes[3]< delayTime) { //speed from gps would most likel – user38974 Oct 16 '17 at 17:20
1
  • What is outPin?

  • Don't start a SoftwareSerial object on the Serial port. Just use Serial

  • The Serial Monitor window will have to use the GPS baud rate if the GPS is connected to pins 0 & 1. This is a good choice, but you'll have to disconnect pin 0 to upload a new sketch over USB.

  • Don't use delay. This prevents the sketch from reading GPS characters. Eventually, the input buffer will overflow and characters will be lost. Instead, save a timestamp and compare the current time with the timestamp. When the difference is 50ms, simply toggle the pin and save another timestamp.

  • Try NeoGPS. It's smaller, faster, more reliable and more accurate than all other GPS libraries. There are many tips on the Installation and Troubleshooting pages, and the examples are structured properly. If you want to use pins other than 0 & 1, be sure the read the section about choosing a serial port. SoftwareSerial is the worst choice.

Here is your sketch, modified to use Serial and NeoGPS:

#include <AD9850.h>
#include <NMEAGPS.h>
NMEAGPS gps;

#define gpsPort Serial  // GPS on pins 0 & 1
static const uint32_t GPSBaud = 9600;

const int OUT_PIN   = 4; ???
const int W_CLK_PIN = 8;
const int FQ_UD_PIN = 9;
const int DATA_PIN  = 10;
const int RESET_PIN = 11;

const double trimFreq = 124999500.0;

int phase = 0;

unsigned long lastToggle;

void setup()
{
  //Serial.begin(115200);  // NOT needed if gpsPort *is* Serial (pins 0 & 1)
  gpsPort.begin( GPSBaud );

  DDS.begin(W_CLK_PIN, FQ_UD_PIN, DATA_PIN, RESET_PIN);
  DDS.calibrate(trimFreq);

  pinMode( OUT_PIN, OUTPUT ); // must be set to output mode
  lastToggle = millis();
}

void loop()
{
  // Toggle the OUT_PIN every 50ms
  if (millis() - lastToggle > 50) {
    digitalWrite( OUT_PIN, !digitalRead(OUT_PIN) );   // toggle the pin
    lastToggle += 50; // step to the next toggle time
  }

  // Dispatch incoming characters
  if (gps.available( gpsPort )) {
    gps_fix fix = gps.read(); // get a fix structure with all GPS fields

    Serial.print(F("SPEED km/h="));

    // for testing, use some random values (comment this out later)
    fix.valid.speed = true;
    fix.spd.whole   = random( 0, 35 );

    if (fix.valid.speed) {
      float speed=fix.speed_kph();
      Serial.print( speed );

      double freq = map(speed, 0, 100, 0, 160);
      DDS.setfreq(freq, phase);

      Serial.print( ' ' ); // for debugging, show the DDS frequency
      Serial.print( freq );
    }
    Serial.println();
  }

}

Notice that it checks to see if there is a valid speed. The GPS device may not know the speed, depending on satellite reception.

If you want to try it, NeoGPS is available from the Arduino IDE Library Manager, under the menu Sketch -> Include Library -> Manage Libraries.


UPDATE

For the code you posted (which is not a complete program) in an Answer (instead of editing your question :-/), you could do something like this:

#include <NMEAGPS.h>
NMEAGPS gps;
gps_fix fix;

#define gpsPort Serial  // GPS on pins 0 & 1 or whatever
static const uint32_t GPSBaud = 9600;

void setup()
{
  Serial1.begin(115200);
  Serial2.begin(115200);

  gpsPort.begin( 9600 );

    ...other things?
}

void loop()
{
  // Constantly read GPS characters
  if (gps.available( gpsPort )) {

    // Update the global fix structure with the latest GPS info.
    //   The speed will be used later by SendData.
    fix = gps.read(); 
  }

  // Constantly read Serial2 characters (a sensor?)
  if (Serial2.available())
  {
    int b     = Serial2.read();
    int chunk = b >> 6;
    if (chunk == syncc)
    {
      bytes[syncc] = b & 63;
      syncc++;

      if (syncc == 4)
      {
        syncc = 0;
        tach = bytes[0] + (bytes[1]<<6);
        velocityfreq = bytes[2] + (bytes[3]< delayTime)  ??? "<" ???

        SendData();
        prevTxTime = millis();
      }
    }
  }
}

void SendData()
{
  // No need to use sprintf, just print the pieces.

  Serial1.print( data1 );
  Serial1.print( '|' );
  Serial1.print( data2 );
  Serial1.print( '|' );
  Serial1.print( data3 );
  Serial1.print( '|' );
  Serial1.print( data4 );
  Serial1.print( '|' );

  // use the current GPS speed, as set in loop
  Serial1.print( fix.speed_kph() );
  Serial1.print( F("\r\n") ); // F macro saves RAM for doubled-quoted string constants
}

I had to guess at the nesting of curly braces because IT IS NOT INDENTED, nor do the CURLY BRACES MATCH. sad.

  • Hi. Thank you for help. Is it possible to put gps speed in this code? pastebin.com/LdT7UHBQ I used your codeand it it works but my boss demands that we modify his code and make it maintain delay with it. – user38974 Oct 16 '17 at 17:16
  • Nope, not even. His code is wrong in all the ways I described, especially regarding delay. It is ok to use a delay on a PC where there is an OS to manage multiple tasks, but it is the worst thing to use in an embedded program where there is no OS. If your boss cannot learn new techniques to solve his problems, then you need a new boss. – slash-dev Oct 16 '17 at 18:22
  • Hahaha that is what i am telling to myself last 5 months – user38974 Oct 16 '17 at 19:29

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.