Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
QQting committed Jul 6, 2023
1 parent b4ce410 commit 46b20be
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 1 deletion.
42 changes: 41 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,42 @@
# arduino_pps_gprmc_time_sync
Use Arduino Uno to simulate a GPS module, sending PPS pulse and GPRMC to Lidar

Use Arduino Uno to simulate a GPS module, sending PPS pulse and GPRMC message to Lidar.

## Verified Platform
- Arduino Uno
- Velodyne Lidar VLP-16
- ROS 2 Foxy with VLP-16 driver https://github.com/ros-drivers

## Wiring Connection

| VLP-16 | Arduino |
| ---- | ---- |
| Ground | GND |
| GPS PULSE | Pin#8 |
| GPS RECEIVE | Pin#11 |

## VLP-16 Configuraition

Make sure the parameter `gps_time` in yaml file is set to **true** to enable time sync.

![](resource/vlp16_gps_time.png)

## Test Result

- VLP-16 web interface

It is successfully synchronized if you see the coordinates of **GPS Position** and locked **PPS** status.

![](resource/vlp16_pps_locked.jpg)

- VLP-16 ROS 2 timestamp

If the `gps_time` parameter is set, then you will see the time jump after time synchronized.

![](resource/vlp16_time_sync_stamp.jpg)

- GPRMC debug message

You can enable the debug messages in Arduino code to monitor the GPRMC.

![](resource/arduino_serial_monitor.png)
Binary file added resource/arduino_serial_monitor.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resource/vlp16_gps_time.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resource/vlp16_pps_locked.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resource/vlp16_time_sync_stamp.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
112 changes: 112 additions & 0 deletions src/pps_gprmc_time_sync/pps_gprmc_time_sync.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#include <SoftwareSerial.h>

const byte pps_pin = 8;
const byte msg_pin = 9;
const byte rx_pin = 10;
const byte tx_pin = 11;
const bool inverse_logic = true;
SoftwareSerial gprmc_conn(rx_pin, tx_pin, inverse_logic);

const unsigned int trigger_freq = 1;
const unsigned long dt = 1000000 / trigger_freq; // => dt = 1 sec
const unsigned long dt_pps_pull_low = dt + 100000; // => dt + 100ms
const unsigned long dt_sent_gprmc = dt_pps_pull_low + 250000; // => dt_pps_pull_low + 100ms
unsigned long timestamp;
unsigned long trigger_start_time;
unsigned long ts_pps_high;
unsigned long ts_pps_low;
unsigned long ts_msg_high;
unsigned long ts_msg_low;
unsigned long i;

// Start timestamp: HH:MM:SS
int hh = 00;
int mm = 01;
int ss = 02;
// GPS coordinates from Taipei
char pos_latitude[] = "25.04776";
char pos_longitude[] = "121.53185";

void setup() {
pinMode(rx_pin, INPUT);
pinMode(tx_pin, OUTPUT);
pinMode(pps_pin, OUTPUT); // PPS
pinMode(msg_pin, OUTPUT); // Indicator of msg_sent
Serial.begin(9600);
gprmc_conn.begin(9600);
// gprmc_conn.println("Hello World!");
trigger_start_time = micros();
}

void loop() {
char buffer[128];
byte CRC = 0;

timestamp = micros() - trigger_start_time;
if (timestamp >= dt*i + dt_sent_gprmc)
{
digitalWrite(msg_pin, HIGH);
i += 1;
if (ss == 59)
{
ss = 0;
if (mm == 59)
{
mm = 0;
hh += 1;
}
else mm += 1;
}
else ss += 1;

ts_msg_high = micros();

// Prepare GPRMC msg
sprintf(buffer, "GPRMC,%02d%02d%02d,A,%s,N,%s,E,022.4,084.4,070423,,A", hh, mm, ss, pos_latitude, pos_longitude);
for (byte x = 0; x < strlen(buffer); x++) {
// XOR every character in between '$' and '*'
CRC = CRC ^ buffer[x];
}

// Send GPRMC msg
gprmc_conn.print("$");
gprmc_conn.print(buffer);
gprmc_conn.print("*");
gprmc_conn.print(CRC, HEX);
gprmc_conn.println();

digitalWrite(msg_pin, LOW);
ts_msg_low = micros();

#if 0
// Print Debug Messages
Serial.print("PPS at: ");
Serial.print(ts_pps_high);
Serial.print(" PPS low after: ");
Serial.print(ts_pps_low-ts_pps_high);
Serial.print(" MSG high after: ");
Serial.print(ts_msg_high-ts_pps_high);
Serial.print(" MSG low after: ");
Serial.print(ts_msg_low-ts_pps_high);
Serial.print(" $");
Serial.print(buffer);
Serial.print("*");
Serial.print(CRC, HEX);
Serial.println();
#endif

}
else if (timestamp >= dt*i + dt_pps_pull_low)
{
// Pull pps to low
digitalWrite(pps_pin, LOW);
ts_pps_low = micros();
}
else if (timestamp >= dt*i)
{
// Pull pps to high
digitalWrite(pps_pin, HIGH);
ts_pps_high = micros();
}

}

0 comments on commit 46b20be

Please sign in to comment.