Hello, I have made an "analog style" speedometer using the Adafruit Ultimate GPS Module, an Arduino Uno, and a Switec/Juken X25 stepper motor (to move the needle).
I have it working, but the movement of the needle is very jerky. It looks like it only "updates" its position at a rate of about 1hz, despite knowing it's actually updating at a rate of 10hz.
I contribute this to the GPS not sending knots data fast enough, though I read the datasheet and got more confused. I think the issue will be solved by increasing the baud rate (serial between GPS and Arduino), but I can't seem to get it to run at all at anything other than 9600kbps.
Here is my current code:
//using this module https://www.adafruit.com/product/746
#include <SoftwareSerial.h>
#include <NMEAGPS.h>
#include "SwitecX25.h"
int GPSb = 0;
unsigned long startMillis; //some global variables available anywhere in the program
unsigned long currentMillis;
const unsigned long period = 100; //the value is a number of milliseconds
float speed_mph = 0;
SoftwareSerial gpsSerial(8, 7); //connect digital 8 to tx and digital 7 to rx
NMEAGPS gps;
SwitecX25 motor1(315*3, 3,4,5,6); //create instance of first stepper
float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) //creating a map function that works with floats but still returns an int
{
return round( (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min );
}
const unsigned char SET_BAUD_38400[] PROGMEM = {
0xB5, 0x62, 0x06, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD0, 0x08, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x23, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAF, 0x70
}; // This is an example for 38400 baud, checksum included.
void sendUBX(const unsigned char *progmemBytes, size_t len) {
for (size_t i = 0; i < len; i++) {
gpsSerial.write(pgm_read_byte(progmemBytes + i));
}
}
void setup()
{
gpsSerial.begin(9600);
//IF I UNCOMMENT THE BELOW LINES, IT DOESN'T WORK. THE NEEDLE DOES NOT MOVE.
// sendUBX(SET_BAUD_38400, sizeof(SET_BAUD_38400));
// delay(100); // Give the module time to process
// gpsSerial.end();
// gpsSerial.begin(38400); // Change to the new baud rate
// gps.send_P( &gpsSerial, F("PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0") ); // RMC only
gps.send_P( &gpsSerial, F("PMTK220,50") ); //set update rate
motor1.zero(); //zero the needle
}
void loop()
{
motor1.update(); //send motor to the last poisition determined by motor1.setPosition
// Process GPS chars
while (gps.available( gpsSerial ))
{
// A new fix has been assembled from processed chars
gps_fix fix = gps.read();
if (fix.valid.speed) {
//get the floating point (with decimals) MPH like this:
float speed_mph = fix.speed_mph();
//float speed_mph_filtered = adcFilter1.filter(speed_mph);
GPSb = mapfloat(speed_mph, 0, 120, 0, 945); //scale the voltage to represent steps of the motor instead
}
}
currentMillis = millis();
if (currentMillis - startMillis >= period) {
startMillis = currentMillis;
motor1.setPosition(GPSb); //update the motor's target position
}
}
Note the section that's commented out, which is supposed to increase the baud rate.
I read through other topics similar to this, and none of the advice in those has worked for me. Please help!