As discussed in previous blog posts here, there is a 3rd party Arduino Board Support Package for The Raspberry Pi Pico W. A port of the Azure SDK for C Arduino for the RPi Pico with that BSP was also implemented and discussed here. The Pico W has built-in WiFi and Bluetooth capabilities although Bluetooth wasn’t implemented in the original BSP. The BSP has been updated this year to support Bluetooth. A suite of sketches have been developed invoking the simple use of Bluetooth to echo characters, the sending of parsed GPS location data over Bluetooth and sending location data to an Azure IoT Hub.

The Arduino RPi Pico W with GPS

The Repository on GitHub

djaus2/RPI Pico W GPS and Bluetooth

BSP

Other

The Sketches

  1. USART1 Echo
  2. Basic GPS
  3. InteractiveGPS
  4. LocationGPS
  5. BTSerialUppercase.
  6. BluetoothGPS
  7. Azure_IoT_Hub_GPS
  8. read_d2c_messages

As can be seen, there is a sequential build up to sending the location data, as json, over Bluetooth. For example, the first Sketch exercises the second serial port on the Pico that is subsequently connected to the GPS device. The second gets and separates the GPS sentences. The third allows stopping and starting the reception of messages as well as filtering the accepted messages, with a focus upon location messages. The fourth parses and interprets the location data displaying it optionally as a tuple or as a json string. The fifth implements a simple example of using Bluetooth as a text echo. The sixth completes the sending of location data as a json string over Bluetooth. The seventh Sketch doesn’t use Bluetooth but sends that location json string to an Azure IoT Hub using the Azure SDK for C Arduino as ported and discussed on this blog site. read_d2c_messages is a C# Console app monitoring telemtry sent to the IoT Hub.

Bluetooth

The Bluetooth supported by the BSP is Classic as well as BLE. Classic is used here. When installed, samples in the Arduino IDE the BT samples are :

  • Classic: Files-Examples-SerialBT-SerialBluuetoothUppercase
  • BLE: Files-Examples-BTStack-_(there are 6 examples.)_

The BT Sketches here only require a Bluetooth terminal on a device paired to the Pico. Whilst I could get it to work on my Windows 11 desktop, I did find it problematic. Would pair or connect sometimes but not others. I found a BT Serial Terminal app on my Android phone work OK each time it was called upon: Android phone app Serial Bluetooth Terminal.

GPS

The Arduino GPS Receiver

  • Arduino Compatible GPS Receiver Module Jaycar (Australia) CAT.NO: XC3710
  • https://www.jaycar.com.au/arduino-compatible-gps-receiver-module/p/XC3710
  • nblox NEO-7M Module BAUD is 9600
  • There are a number of similar devices that could be seamlessly substituted.

This supplies streams of NMEA sentences serially as text over RS232. The connectivity info is:

// // Nb: GPn pin numbers not package pin numbers
#define TXD2 4  // Not used
#define RXD2 5  // Connect to GPS Unit TX

// Pins Ceramic Antenna side of GPS device:
// =========================================
// PPS nc
// RXD nc
// TXD --> RXD2
// GND --> GND
// Vcc --> 3.3V

// Note: USART1 is Serial2
// RPI Pico has has 2 USART, USART0 is Serial/Serial1/USB

NMEA sentence processing

Whilst the second Sketch demonstrates the reception of all GPS NMEA sentences, the latter Sketches target:

  • $GPGLL
  • $GPAGG
  • $GPGSV

The sixth Sketch uses the $GPAGG sentences to get location latitude, longitude and height.

In parsing these, use is made of string processing rather than any GPS libraries, such as TinyGPSPlus:

  • Ignore NMEA text until $ then read until end of line (/n and /r accommodated).
  • Filter out all sentences except those that start with “$GPGGa”
  • Split the sentence using a comma delimiter, into SplitNMEA
// Locations in GPAGG of entities
#define latIndex 2
#define longIndex 4
#define heightIndex 9

So, for example, SplitNMEA[latIndex] is the latitude as string.

The latitude is made negative, by prepending a ‘-‘, if SplitNMEA[latIndex+1] direction is ‘S’ and the longitude is made negative if SplitNMEA[longIndex+1] is ‘W’.

Also latitude and longitude are 100x so their decimal points are shifted left by 2 decimal places by string manipulations.

This algorithm has been corrected. See the next blog post: GPS:NMEA101

Rather than use an existing library such as ArduinoJson (that is used in the 7th Sketch), the tuple and json strings are “manually” created by explicitly adding values in sequence with fixed strings naming the properties.

This processing was subsequently refactored in Sketch 4 into a separate function to simplify reuse in Sketch 6. This could be separately published.

Sketch Outputs

$GPGSV,2,1,07,10,45,304,30,13,15,136,28,15,39,113,34,23,83,248,27*7A
$GPGSV,2,2,07,26,23,295,,27,25,224,32,29,31,038,35*46
$GPGLL,3744.81246,S,14453.73910,E,120341.00,A,A*77
$GPRMC,120342.00,A,3744.81238,S,14453.73880,E,0.139,,160823,,,A*69
$GPVTG,,T,,M,0.139,N,0.257,K,A*28
$GPGGA,120342.00,3744.81238,S,14453.73880,E,1,04,2.97,47.0,M,-1.7,M,,*60
$GPGSA,A,3,23,15,29,13,,,,,,,,,4.64,2.97,3.57*05
$GPGSV,2,1,07,10,45,304,30,13,15,136,28,15,39,113,33,23,83,248,27*7D
$GPGSV,2,2,07,26,23,295,,27,25,224,32,29,31,038,35*46
$GPGLL,3744.81238,S,14453.73880,E,120342.00,A,A*75

NMEA Messages

$GPGGA,110037.00,3744.81445,S,14453.73857,E,1,06,1.69,58.0,M,-1.7,M,,*6A
$GPGGA,110038.00,3744.81450,S,14453.73859,E,1,06,1.69,58.1,M,-1.7,M,,*6E
$GPGGA,110039.00,3744.81448,S,14453.73862,E,1,06,1.69,58.1,M,-1.7,M,,*6E
$GPGGA,110040.00,3744.81453,S,14453.73868,E,1,06,1.69,58.4,M,-1.7,M,,*65
$GPGGA,110041.00,3744.81466,S,14453.73875,E,1,06,1.69,58.8,M,-1.7,M,,*62
$GPGGA,110042.00,3744.81465,S,14453.73876,E,1,06,1.69,58.6,M,-1.7,M,,*6F
$GPGGA,110043.00,3744.81464,S,14453.73876,E,1,06,1.69,58.5,M,-1.7,M,,*6C
$GPGGA,110044.00,3744.81462,S,14453.73880,E,1,06,1.69,58.5,M,-1.7,M,,*64

GPGGA NMEA Messages

  • $GPGGA is the first entity on each line
  • Latitude is 4th
  • Longitude is 6th
  • Altitude is 12th
Mode: Display Location as a tuple
(37.4481439S,144.5373679E,46.9M)
(37.4481440S,144.5373679E,46.7M)
(37.4481446S,144.5373678E,46.3M)
(37.4481448S,144.5373680E,46.1M)

Location Data as a tuple

Mode: Display Location as Json Telemetry string
{"geolocation":{"lat":-37.4481162,"lon":144.5373954,"alt":51.9}}
{"geolocation":{"lat":-37.4481160,"lon":144.5373954,"alt":52.0}}
{"geolocation":{"lat":-37.4481160,"lon":144.5373953,"alt":52.0}}

Location Data as json string

Bluetooth Terminal on Phone displaying raw NMEA Data

Bluetooth Terminal on Phone displaying json location Data

............................
Connecting to WIFI SSID APQLZM
............WiFi connected, IP address: 192.168.0.13
Setting time using SNTP.done!
Current time: Wed Aug 16 13:20:15 2023
Client ID: DDDDDDDD
Username: HHHHHHHH.azure-devices.net/DDDDDDDD/?api-version=2020-09-30&DeviceClientType=c%2F1.5.0-beta.1(ard;rpipico)
MQTT connecting ... connected.
GPS is Setup
13084 RPI Pico (Arduino) Sending telemetry . . . 
{"geolocation":{"lat":-37.4481392,"lon":144.5373746,"alt":56.7}
OK
{"geolocation":{"lat":-37.4481385,"lon":144.5373805,"alt":56.9}

RPi Pico connecting to an Azure IoT Hub and sending telemetry using MQTT

Listening for messages on: 0
Message received on partition 0:
  {"geolocation":{"lat":-37.4481320,"lon":144.5373761,"alt":39.2}:
Application properties (set by device):
Listening for messages on: 0
Message received on partition 0:
  {"geolocation":{"lat":-37.4481327,"lon":144.5373973,"alt":38.3}:
Application properties (set by device):
Listening for messages on: 0
Message received on partition 0:
  {"geolocation":{"lat":-37.4481305,"lon":144.5374033,"alt":42.2}:
Application properties (set by device):

Console app monitoring telemetry sent to IoT Hub


 TopicSubtopic
  Next: > GPS
<  Prev:   Jekyll
   
 This Category Links 
Category:Pico W AzSDK Index:Pico W AzSDK
<  Prev:   RPI-Pico-Arduino-AzSDK