🛠 Dialoguer avec un GPS (ou tout module TTL) sur Serial1 sans bloquer la boucle
Objectives
The Due has 4 hardware UARTs: Serial (pins 0/1, connected to the Programming port), Serial1 (USART0, pins 18/19), Serial2 (16/17), and Serial3 (14/15) — not to mention SerialUSB. You will connect a GPS module (or any TTL serial device) to Serial1, which is free from USB usage, and learn asynchronous reading using available/read with NMEA frame parsing, to avoid blocking the loop with readString.
Hardware
- 1 Arduino Due
- 1 GPS module with TTL output (e.g., NEO-6M/7M) — warning: power it with 3.3 V, as the Due only accepts 3.3 V on its pins; a 5 V module requires a level shifter on the module's TX line
- 4 male-to-male jumper wires, micro-USB cable
- Optionally, a USB-to-serial adapter to test the GPS beforehand
Complete Code
// Lecteur de ligne non bloquant sur Serial1 (RX=18, TX=19)
char ligne[128];
size_t len = 0;
uint32_t dernierOctetMs = 0;
void setup {
SerialUSB.begin(115200); // debug sur le port Native
Serial1.begin(9600); // typical GPS baud (NEO-6M : 9600)
}
void loop {
// 1) Vider le FIFO sans jamais bloquer
while (Serial1.available) {
char c = (char)Serial1.read;
dernierOctetMs = millis;
if (c == '\n' || len == sizeof(ligne) - 1) { // fin de trame
ligne[len] = '\0';
if (len > 6 && strncmp(ligne, "$GNGGA", 6) == 0) {
SerialUSB.printf("trame GGA (%u octets)\n", (unsigned)len);
}
len = 0;
continue;
}
if (c != '\r') ligne[len++] = c;
}
// 2) Clôturer une trame orpheline après 100 ms de silence
if (len && millis - dernierOctetMs > 100) {
ligne[len] = '\0';
SerialUSB.printf("flush timeout: %s\n", ligne);
len = 0;
}
// 3) Ici, toute autre logique : l'attente série ne vous bloque jamais
}
Expected Verification
Outdoors (with a clear view of the sky) or near a window, the Native monitor displays complete NMEA frames; the $GNGGA frame appears as soon as the GPS has a fix. Unplugging the GPS does not freeze the loop: the program continues to run (test this with an LED). The module's TX LED blinks during reception.
Common Errors
- Using
readStringorreadStringUntil: these are blocking functions that cause the loop to miss iterations for seconds if the module goes silent — hence theavailable/readpattern above. - Wiring a 5 V module directly to RX1: the pin supports a maximum of 3.3 V; the module's TX must go through a level shifter (or choose a 3.3 V module).
- Swapping TX/RX: the module transmits, but the Due hears nothing; cross-connect TX(module)→RX1(18) and RX(module)←TX1(19).
- Confusing Serial (0/1, occupied by the Programming port) with Serial1: writing to the wrong serial port is the classic mistake with the Due's 4 UARTs.
- Expecting valid frames indoors: without a fix, many frames arrive empty or without position data.
- Forgetting that SerialUSB blocks if no host has enumerated the CDC: in standalone operation, protect large
printstatements withif (SerialUSB).
Other tutorials for this board
- Faire clignoter la LED de l'Arduino Due et apprivoiser ses deux ports USB
- Lire un potentiomètre avec le vrai ADC 12 bits de la Due
- Allumer une LED externe en respectant les broches 3,3 V et 9 mA de la Due
- Générer une vraie tension analogique avec les DAC 12 bits (broches 66 et 67)
- Scanner les deux bus I2C de la Due (Wire sur 20/21, Wire1 sur 70/71)
- Monter la Due sur un bus CAN 500 kbit/s avec un transceiver externe
Code examples for this board
clignotante.inoArduinobouton-led.inoArduinodac-onde.inoArduinoadc-12-bits.inoArduinopwm-12-bits.inoArduinogps-serial1.inoArduino