Updates along with SDK1.3.0 release (#181)
Bug fixes and new examples Co-authored-by: Paulo Marques <pm@quant-insight.com> Co-authored-by: martin <admin@crossleys.biz> Co-authored-by: matiasilva <matias.silva@raspberrypi.com> Co-authored-by: Uri Shaked <uri@urishaked.com> Co-authored-by: Diego Solano <diegosolano@gmail.com> Co-authored-by: Andrew Scheller <andrew.scheller@raspberrypi.com> Co-authored-by: Adrian Hesketh <a-h@users.noreply.github.com> Co-authored-by: Emircan Gündoğdu <58917386+emircangun@users.noreply.github.com> Co-authored-by: Josef Wegner <80200012+josefwegner@users.noreply.github.com> Co-authored-by: pmarques-dev <72901351+pmarques-dev@users.noreply.github.com> Co-authored-by: Paulo Marques <pm@quant-insight.com> Co-authored-by: mjcross <mjcross@users.noreply.github.com> Co-authored-by: martin <admin@crossleys.biz>
This commit is contained in:
12
i2c/pa1010d_i2c/CMakeLists.txt
Normal file
12
i2c/pa1010d_i2c/CMakeLists.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
add_executable(pa1010d_i2c
|
||||
pa1010d_i2c.c
|
||||
)
|
||||
|
||||
# pull in common dependencies and additional i2c hardware support
|
||||
target_link_libraries(pa1010d_i2c pico_stdlib hardware_i2c)
|
||||
|
||||
# create map/bin/hex file etc.
|
||||
pico_add_extra_outputs(pa1010d_i2c)
|
||||
|
||||
# add url via pico_set_program_url
|
||||
example_auto_set_url(pa1010d_i2c)
|
||||
42
i2c/pa1010d_i2c/README.adoc
Normal file
42
i2c/pa1010d_i2c/README.adoc
Normal file
@@ -0,0 +1,42 @@
|
||||
= Attaching a PA1010D Mini GPS module via I2C
|
||||
|
||||
This example code shows how to interface the Raspberry Pi Pico to the PA1010D Mini GPS module
|
||||
======
|
||||
This allows you read basic location and time data from the Recommended Minimum Specific GNSS Sentence (GNRMC protocol) and displays it in a user-friendly format. The datasheet for the module can be found on https://cdn-learn.adafruit.com/assets/assets/000/084/295/original/CD_PA1010D_Datasheet_v.03.pdf?1573833002. The output sentence is read and parsed to split the data fields into a 2D character array, which are then individually printed out. The commands to use different protocols and change settings are found on https://www.sparkfun.com/datasheets/GPS/Modules/PMTK_Protocol.pdf. Additional protocols can be used by editing the init_command array.
|
||||
======
|
||||
[NOTE]
|
||||
======
|
||||
Each command requires a checksum after the asterisk. The checksum can be calculated for your command using the following website: https://nmeachecksum.eqth.net/.
|
||||
|
||||
The GPS needs to be used outdoors in open skies and requires about 15 seconds to acquire a satellite signal in order to display valid data. When the signal is detected, the device will blink a green LED at 1 Hz.
|
||||
======
|
||||
|
||||
|
||||
== Wiring information
|
||||
|
||||
Wiring up the device requires 4 jumpers, to connect VDD, GND, SDA and SCL. The example here uses I2C port 0, which is assigned to GPIO 4 (SDA) and 5 (SCL) in software. Power is supplied from the 3V pin.
|
||||
|
||||
|
||||
[[pa1010d_i2c_wiring]]
|
||||
[pdfwidth=75%]
|
||||
.Wiring Diagram for PA1010D.
|
||||
image::pa1010d_i2c.png[]
|
||||
|
||||
== List of Files
|
||||
|
||||
CMakeLists.txt:: CMake file to incorporate the example in to the examples build tree.
|
||||
pa1010d_i2c.c:: The example code.
|
||||
|
||||
== Bill of Materials
|
||||
|
||||
.A list of materials required for the example
|
||||
[[pa1010d-bom-table]]
|
||||
[cols=3]
|
||||
|===
|
||||
| *Item* | *Quantity* | Details
|
||||
| Breadboard | 1 | generic part
|
||||
| Raspberry Pi Pico | 1 | https://www.raspberrypi.com/products/raspberry-pi-pico/
|
||||
| PA1010D board| 1 | https://shop.pimoroni.com/products/pa1010d-gps-breakout
|
||||
| M/M Jumper wires | 4 | generic part
|
||||
|===
|
||||
|
||||
156
i2c/pa1010d_i2c/pa1010d_i2c.c
Normal file
156
i2c/pa1010d_i2c/pa1010d_i2c.c
Normal file
@@ -0,0 +1,156 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "pico/stdlib.h"
|
||||
#include "pico/binary_info.h"
|
||||
#include "hardware/i2c.h"
|
||||
#include "string.h"
|
||||
|
||||
/* Example code to talk to a PA1010D Mini GPS module.
|
||||
|
||||
This example reads the Recommended Minimum Specific GNSS Sentence, which includes basic location and time data, each second, formats and displays it.
|
||||
|
||||
Connections on Raspberry Pi Pico board, other boards may vary.
|
||||
|
||||
GPIO PICO_DEFAULT_I2C_SDA_PIN (On Pico this is 4 (physical pin 6)) -> SDA on PA1010D board
|
||||
GPIO PICO_DEFAULT_I2C_SCK_PIN (On Pico this is 5 (physical pin 7)) -> SCL on PA1010D board
|
||||
3.3v (physical pin 36) -> VCC on PA1010D board
|
||||
GND (physical pin 38) -> GND on PA1010D board
|
||||
*/
|
||||
|
||||
const int addr = 0x10;
|
||||
const int max_read = 250;
|
||||
|
||||
#ifdef i2c_default
|
||||
|
||||
void pa1010d_write_command(const char command[], int com_length) {
|
||||
// Convert character array to bytes for writing
|
||||
uint8_t int_command[com_length];
|
||||
|
||||
for (int i = 0; i < com_length; ++i) {
|
||||
int_command[i] = command[i];
|
||||
i2c_write_blocking(i2c_default, addr, &int_command[i], 1, true);
|
||||
}
|
||||
}
|
||||
|
||||
void pa1010d_parse_string(char output[], char protocol[]) {
|
||||
// Finds location of protocol message in output
|
||||
char *com_index = strstr(output, protocol);
|
||||
int p = com_index - output;
|
||||
|
||||
// Splits components of output sentence into array
|
||||
int no_of_fields = 14;
|
||||
int max_len = 15;
|
||||
|
||||
int n = 0;
|
||||
int m = 0;
|
||||
|
||||
char gps_data[no_of_fields][max_len];
|
||||
memset(gps_data, 0, sizeof(gps_data));
|
||||
|
||||
bool complete = false;
|
||||
while (output[p] != '$' && n < max_len && complete == false) {
|
||||
if (output[p] == ',' || output[p] == '*') {
|
||||
n += 1;
|
||||
m = 0;
|
||||
} else {
|
||||
gps_data[n][m] = output[p];
|
||||
// Checks if sentence is complete
|
||||
if (m < no_of_fields) {
|
||||
m++;
|
||||
} else {
|
||||
complete = true;
|
||||
}
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
// Displays GNRMC data
|
||||
// Similarly, additional if statements can be used to add more protocols
|
||||
if (strcmp(protocol, "GNRMC") == 0) {
|
||||
printf("Protcol:%s\n", gps_data[0]);
|
||||
printf("UTC Time: %s\n", gps_data[1]);
|
||||
printf("Status: %s\n", gps_data[2][0] == 'V' ? "Data invalid. GPS fix not found." : "Data Valid");
|
||||
printf("Latitude: %s\n", gps_data[3]);
|
||||
printf("N/S indicator: %s\n", gps_data[4]);
|
||||
printf("Longitude: %s\n", gps_data[5]);
|
||||
printf("E/W indicator: %s\n", gps_data[6]);
|
||||
printf("Speed over ground: %s\n", gps_data[7]);
|
||||
printf("Course over ground: %s\n", gps_data[8]);
|
||||
printf("Date: %c%c/%c%c/%c%c\n", gps_data[9][0], gps_data[9][1], gps_data[9][2], gps_data[9][3], gps_data[9][4],
|
||||
gps_data[9][5]);
|
||||
printf("Magnetic Variation: %s\n", gps_data[10]);
|
||||
printf("E/W degree indicator: %s\n", gps_data[11]);
|
||||
printf("Mode: %s\n", gps_data[12]);
|
||||
printf("Checksum: %c%c\n", gps_data[13][0], gps_data[13][1]);
|
||||
}
|
||||
}
|
||||
|
||||
void pa1010d_read_raw(char numcommand[]) {
|
||||
uint8_t buffer[max_read];
|
||||
|
||||
int i = 0;
|
||||
bool complete = false;
|
||||
|
||||
i2c_read_blocking(i2c_default, addr, buffer, max_read, false);
|
||||
|
||||
// Convert bytes to characters
|
||||
while (i < max_read && complete == false) {
|
||||
numcommand[i] = buffer[i];
|
||||
// Stop converting at end of message
|
||||
if (buffer[i] == 10 && buffer[i + 1] == 10) {
|
||||
complete = true;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int main() {
|
||||
stdio_init_all();
|
||||
#if !defined(i2c_default) || !defined(PICO_DEFAULT_I2C_SDA_PIN) || !defined(PICO_DEFAULT_I2C_SCL_PIN)
|
||||
#warning i2c/mpu6050_i2c example requires a board with I2C pins
|
||||
puts("Default I2C pins were not defined");
|
||||
#else
|
||||
|
||||
char numcommand[max_read];
|
||||
|
||||
// Decide which protocols you would like to retrieve data from
|
||||
char init_command[] = "$PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29\r\n";
|
||||
|
||||
// This example will use I2C0 on the default SDA and SCL pins (4, 5 on a Pico)
|
||||
i2c_init(i2c_default, 400 * 1000);
|
||||
gpio_set_function(PICO_DEFAULT_I2C_SDA_PIN, GPIO_FUNC_I2C);
|
||||
gpio_set_function(PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C);
|
||||
gpio_pull_up(PICO_DEFAULT_I2C_SDA_PIN);
|
||||
gpio_pull_up(PICO_DEFAULT_I2C_SCL_PIN);
|
||||
|
||||
// Make the I2C pins available to picotool
|
||||
bi_decl(bi_2pins_with_func(PICO_DEFAULT_I2C_SDA_PIN, PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C));
|
||||
|
||||
printf("Hello, PA1010D! Reading raw data from module...\n");
|
||||
|
||||
pa1010d_write_command(init_command, sizeof(init_command));
|
||||
|
||||
while (1) {
|
||||
// Clear array
|
||||
memset(numcommand, 0, max_read);
|
||||
// Read and re-format
|
||||
pa1010d_read_raw(numcommand);
|
||||
pa1010d_parse_string(numcommand, "GNRMC");
|
||||
|
||||
// Wait for data to refresh
|
||||
sleep_ms(1000);
|
||||
|
||||
// Clear terminal
|
||||
printf("\e[1;1H\e[2J");
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
BIN
i2c/pa1010d_i2c/pa1010d_i2c.fzz
Normal file
BIN
i2c/pa1010d_i2c/pa1010d_i2c.fzz
Normal file
Binary file not shown.
BIN
i2c/pa1010d_i2c/pa1010d_i2c.png
Normal file
BIN
i2c/pa1010d_i2c/pa1010d_i2c.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 155 KiB |
Reference in New Issue
Block a user