Bonjour, j'essaie de recevoir des données de différents capteurs et d'un GPS en même temps sur une carte Arduino Nano, sauf que le GPS que j'utilise envoie des données seulement si le serial est disponible, seul soucis il n'est jamais disponible vu qu'il envoie les données des capteurs. Je voulais savoir si vous aviez des idées pour m'aider à résoudre ce problème sans utiliser une autre carte nano.
Salut.
Tout dépend de la vitesse de transmission.
Pour ouvrir un port supplémentaire sur une NANO : SoftwareSerial.
Attention, limité à ~ 9600 baud.
Il est à 9600 baud.
Postez le code, le schéma de montage et les infos sur vos composants.
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_BMP280.h>
#include <DFRobot_DHT11.h>
DFRobot_DHT11 DHT;
#include <SD.h>
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
// Connect the GPS Power pin to 5V
// Connect the GPS Ground pin to ground
// Connect the GPS TX (transmit) pin to Digital 8
// Connect the GPS RX (receive) pin to Digital 7
// You can change the pin numbers to match your wiring:
SoftwareSerial mySerial(8, 7);
#define BMP_SCK (13)
#define BMP_MISO (12)
#define BMP_MOSI (11)
#define BMP_CS (10)
#define DHT11_PIN 5
Adafruit_BMP280 bmp; // I2C
//Adafruit_BMP280 bmp(BMP_CS); // hardware SPI
//Adafruit_BMP280 bmp(BMP_CS, BMP_MOSI, BMP_MISO, BMP_SCK);
#define PMTK_SET_NMEA_UPDATE_1HZ "$PMTK220,1000*1F"
#define PMTK_SET_NMEA_UPDATE_5HZ "$PMTK220,200*2C"
#define PMTK_SET_NMEA_UPDATE_10HZ "$PMTK220,100*2F"
// turn on only the second sentence (GPRMC)
#define PMTK_SET_NMEA_OUTPUT_RMCONLY "$PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"
// turn on GPRMC and GGA
#define PMTK_SET_NMEA_OUTPUT_RMCGGA "$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28"
// turn on ALL THE DATA
#define PMTK_SET_NMEA_OUTPUT_ALLDATA "$PMTK314,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0*28"
// turn off output
#define PMTK_SET_NMEA_OUTPUT_OFF "$PMTK314,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28"
#define PMTK_Q_RELEASE "$PMTK605*31"
File myFile;
void setup() {
// while (!Serial); // wait for Serial to be ready
Serial.begin(9600); // The serial port for the Arduino IDE port output
mySerial.begin(9600);
delay(2000);
Serial.println("Software Serial GPS Test Echo Test");
// you can send various commands to get it started
//mySerial.println(PMTK_SET_NMEA_OUTPUT_RMCGGA);
mySerial.println(PMTK_SET_NMEA_OUTPUT_ALLDATA);
mySerial.println(PMTK_SET_NMEA_UPDATE_1HZ);
Serial.println("Get version!");
mySerial.println(PMTK_Q_RELEASE);
Serial.print("Initializing SD card...");
if (!SD.begin(10)) {
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");
Serial.println(F("BMP280 test"));
if (!bmp.begin()) {
Serial.println(F("Could not find a valid BMP280 sensor, check wiring!"));
while (1);
}
/* Default settings from datasheet. */
bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. */
Adafruit_BMP280::SAMPLING_X2, /* Temp. oversampling */
Adafruit_BMP280::SAMPLING_X16, /* Pressure oversampling */
Adafruit_BMP280::FILTER_X16, /* Filtering. */
Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */
analogRead(A0); //MPX the sensor'll be connected to the a0 arduino pin
}
void loop() {
myFile = SD.open("SPACEY.txt", FILE_WRITE);
// if the file opened okay, write to it:
if (myFile) {
// Serial.print(F("Temperature = "));
Serial.print(bmp.readTemperature());
myFile.print(bmp.readTemperature());
// Serial.println(" *C");
Serial.print(", ");
myFile.print(", ");
// Serial.print(F("Pressure = "));
Serial.print(bmp.readPressure());
myFile.print(bmp.readPressure());
//Serial.println(" Pa");
Serial.print(", ");
myFile.print(", ");
//Serial.print(F("Approx altitude = "));
Serial.print(bmp.readAltitude(1037)); /* Adjusted to local forecast! */
myFile.print(bmp.readAltitude(1037));
//Serial.println(" m");
Serial.print(", ");
myFile.print(", ");
DHT.read(DHT11_PIN);
Serial.print(DHT.temperature);
Serial.print(", ");
myFile.print(DHT.temperature);
myFile.print(", ");
float tension = analogRead(A0) * 5.0 / 1023.0;
float P = tension / 0.0045 + 105.5;
Serial.print(P);
myFile.print(P);
if (mySerial.available()) {
char c = mySerial.read();
Serial.write(c);
Serial.println();
myFile.println();
myFile.close();
delay(1000);
} else {
// if the file didn't open, print an error:
Serial.println("error opening SPACEY.txt");
}
}
}
Assurez vous d'indenter le code dans l'IDE. Cela se fait dans l'IDE en pressant ctrlT sur PC ou cmdT sur un Mac
vous verrez que votre
} else {
// if the file didn't open, print an error:
Serial.println("error opening SPACEY.txt");
}
n'est pas le else du if (myFile) {
mettre un delay(1000);
c'est une garantie de perdre une partie des messages de votre GPS. à 9600 bauds vous pouvez recevoir jusqu'à 960 caractères pendant cette seconde d'attente et le buffer ne fait que 64 octets... Vous n'écrivez pas l'info du GPS dans le fichier c'est voulu ??
➜ il ne faut aucun délai
➜ augmentez la vitesse de Serial pour que ce ne ralentisse pas trop (115200 par exemple)
utilisez millis() pour décider quand lire les capteurs et séparément gérez l'arrivée des données depuis votre GPS
la loop pourrait ressembler à cela
void loop() {
static unsigned long lastSampleTime = 0;
myFile = SD.open("SPACEY.txt", FILE_WRITE);
if (myFile) {
// traiter les données du GPS s'il y en a
while (mySerial.available()) {
char c = mySerial.read();
// ...
}
// traiter les capteurs si c'est le moment
if (millis() - lastSampleTime >= 5000) { // toutes les 5 secondes
// ...
lastSampleTime += 5000;
}
myFile.close();
} else {
// if the file didn't open, print an error:
Serial.println("error opening SPACEY.txt");
}
}
si la lecture des capteurs ou l'écriture sur la carte SD est trop lente vous risquez de perdre une partie de la communication série du GPS. passer sur un port matériel (un arduino avec plusieurs port comme la MEGA ou ESP ou MKR) ou utiliser Serial pour le GPS et ne plus avoir de traces de débug pourrait aider à limiter les dégâts car SoftwareSerial rajouter aussi de la lenteur en bloquant les interruptions
Merci beaucoup pour tous ses détailles mais je ne peux pas enlever le delay car c'est une des contraintes du travail. Je dois recevoir les données et la localisation de ma "fusée".
La contrainte c'est de bloquer le système pendant une seconde ou bien c'est d'attendre une secondes entre chaque émission de la position.
En plus, si tu comptes le delay() d'une seconde plus le temps d'acquisition des paramètres tu vas passer plus d'une seconde entre 2 acquisitions et au final tu seras de plus en plus décalé par rapport à l'heure réelle.
Au lieu de mettre une constante pour la pression locale, ce serait mieux de faire cette acquisition pendant une phase de calibration à la mise sous tension ou de la rentrer le jour où tu vas faire ton tir. Sinon tu n'auras pas l'altitude réelle.
si c'est 1 seconde au lieu de 5 secondes, changez
if (millis() - lastSampleTime >= 5000) { // toutes les 5 secondes
en
if (millis() - lastSampleTime >= 1000) { // toutes les 5 secondes
et ça se fait toutes le secondes. Mais en attendant la fin de cette seconde on a lu les caractères qui arrivent du GPS au lieu de ne rien faire
D'accord merci, je changerai ça le jour du lancement.
Je teste ça et je vous donne mon file back.
Donc j'ai essaié le programme n'a pas eu de problème au niveau du téléversement mais les données que j'ai ressue ont un problème.
17.65, 98964.11, 392.59, 255, 987.44
17.66, 98964.96, 392.52, 255, 987.44
17.66, 98964.85, 392.53, 255, 987.44
17.67, 98965.06, 392.51, 255, 987.44
17.67, 98964.99, 392.52, 255, 987.44
17.67, 98965.19, 392.50, 255, 987.44
17.68, 98965.16, 392.50, 255, 986.35
17.68, 98966.00, 392.43, 255, 987.44
17.69, 98966.53, 392.39, 255, 987.44
17.69, 98966.89, 392.36, 255, 987.44
17.69, 98966.82, 392.36, 255, 987.44
17.70, 98967.50, 392.31, 255, 987.44
17.70, 98968.35, 392.23,
Le 255 je ne vois pas du tout d'où il vient.
La première colonne c'est la t° donnée par le capteur BMP280, la deuxième colonne celle de la pression tjs donnée par le même capteur. Normalement la troisième colonne donne l'altitude donner par le capteur BMP280. Cependant, la 4me colonne, elle doit normalement donner la t° qui est cette fois envoyer par le DH11 mais voila...
La première ligne de monteur série, le DHT11 avait envoyer 17C° mais les lignes après ça a donné ça.
et je ne reçois toujours pas les données du gps.
postez le code
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_BMP280.h>
#include <DFRobot_DHT11.h>
DFRobot_DHT11 DHT;
#include <SD.h>
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
// Connect the GPS Power pin to 5V
// Connect the GPS Ground pin to ground
// Connect the GPS TX (transmit) pin to Digital 8
// Connect the GPS RX (receive) pin to Digital 7
// You can change the pin numbers to match your wiring:
SoftwareSerial mySerial(8, 7);
#define BMP_SCK (13)
#define BMP_MISO (12)
#define BMP_MOSI (11)
#define BMP_CS (10)
#define DHT11_PIN 5
Adafruit_BMP280 bmp; // I2C
//Adafruit_BMP280 bmp(BMP_CS); // hardware SPI
//Adafruit_BMP280 bmp(BMP_CS, BMP_MOSI, BMP_MISO, BMP_SCK);
#define PMTK_SET_NMEA_UPDATE_1HZ "$PMTK220,1000*1F"
#define PMTK_SET_NMEA_UPDATE_5HZ "$PMTK220,200*2C"
#define PMTK_SET_NMEA_UPDATE_10HZ "$PMTK220,100*2F"
// turn on only the second sentence (GPRMC)
#define PMTK_SET_NMEA_OUTPUT_RMCONLY "$PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"
// turn on GPRMC and GGA
#define PMTK_SET_NMEA_OUTPUT_RMCGGA "$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28"
// turn on ALL THE DATA
#define PMTK_SET_NMEA_OUTPUT_ALLDATA "$PMTK314,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0*28"
// turn off output
#define PMTK_SET_NMEA_OUTPUT_OFF "$PMTK314,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28"
#define PMTK_Q_RELEASE "$PMTK605*31"
File myFile;
void setup() {
// while (!Serial); // wait for Serial to be ready
Serial.begin(9600); // The serial port for the Arduino IDE port output
mySerial.begin(9600);
delay(1000);
Serial.println("Software Serial GPS Test Echo Test");
// you can send various commands to get it started
//mySerial.println(PMTK_SET_NMEA_OUTPUT_RMCGGA);
mySerial.println(PMTK_SET_NMEA_OUTPUT_ALLDATA);
mySerial.println(PMTK_SET_NMEA_UPDATE_1HZ);
Serial.println("Get version!");
mySerial.println(PMTK_Q_RELEASE);
Serial.print("Initializing SD card...");
if (!SD.begin(10)) {
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");
Serial.println(F("BMP280 test"));
if (!bmp.begin()) {
Serial.println(F("Could not find a valid BMP280 sensor, check wiring!"));
while (1)
;
}
/* Default settings from datasheet. */
bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. */
Adafruit_BMP280::SAMPLING_X2, /* Temp. oversampling */
Adafruit_BMP280::SAMPLING_X16, /* Pressure oversampling */
Adafruit_BMP280::FILTER_X16, /* Filtering. */
Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */
analogRead(A0); //MPX the sensor'll be connected to the a0 arduino pin
}
//void loop() {
// myFile = SD.open("SPACEY.txt", FILE_WRITE);
void loop() {
static unsigned long lastSampleTime = 0;
myFile = SD.open("SPACEY.txt", FILE_WRITE);
if (myFile) {
// traiter les données du GPS s'il y en a
while (mySerial.available()) {
char c = mySerial.read();
// ...
}
// traiter les capteurs si c'est le moment
if (millis() - lastSampleTime >= 1000) { // toutes les 5 secondes
// ...
lastSampleTime += 1000;
}
// if the file opened okay, write to it:
//if (myFile) {
// Serial.print(F("Temperature = "));
Serial.print(bmp.readTemperature());
myFile.print(bmp.readTemperature());
// Serial.println(" *C");
Serial.print(", ");
myFile.print(", ");
// Serial.print(F("Pressure = "));
Serial.print(bmp.readPressure());
myFile.print(bmp.readPressure());
//Serial.println(" Pa");
Serial.print(", ");
myFile.print(", ");
//Serial.print(F("Approx altitude = "));
Serial.print(bmp.readAltitude(1037)); /* Adjusted to local forecast! */
myFile.print(bmp.readAltitude(1037));
//Serial.println(" m");
Serial.print(", ");
myFile.print(", ");
DHT.read(DHT11_PIN);
Serial.print(DHT.temperature);
Serial.print(", ");
myFile.print(DHT.temperature);
myFile.print(", ");
float tension = analogRead(A0) * 5.0 / 1023.0;
float P = tension / 0.0045 + 105.5;
Serial.print(P);
myFile.print(P);
//if (mySerial.available()) {
// char c = mySerial.read();
//Serial.write(c);
Serial.println();
myFile.println();
myFile.close();
//delay(1000);
//} else {
// if the file didn't open, print an error:
//Serial.println("error opening SPACEY.txt");
myFile.close();
} else {
// if the file didn't open, print an error:
Serial.println("error opening SPACEY.txt");
}
}
vous pensiez que les ... c'était pour faire beau ?
Oui, je les ai vu après et je les ai modifié et ça fonctionne maintenant. Je vous remercie !!
en nettoyant un peu le code, essayez un truc comme cela
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_BMP280.h>
#include <DFRobot_DHT11.h>
#include <SD.h>
#include <SoftwareSerial.h>
// DHT
#define DHT11_PIN 5
DFRobot_DHT11 DHT;
// BMP
Adafruit_BMP280 bmp; // I2C
#define PRESSION_LOCALE 1037
// GPS
SoftwareSerial gpsSerial(8, 7);
#define PMTK_SET_NMEA_UPDATE_1HZ "$PMTK220,1000*1F"
#define PMTK_SET_NMEA_OUTPUT_ALLDATA "$PMTK314,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0*28"
#define PMTK_Q_RELEASE "$PMTK605*31"
void setup() {
Serial.begin(115200); // The serial port for the Arduino IDE port output
gpsSerial.begin(9600);
Serial.print("Initializing SD card...");
if (!SD.begin(10)) {
Serial.println("failed!");
while (true) yield();
}
Serial.println("OK");
Serial.print(F("Initializing BMP280..."));
if (!bmp.begin()) {
Serial.println(F("failed! (check wiring)"));
while (true) yield();
}
Serial.println("OK");
/* Default settings from datasheet. */
bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. */
Adafruit_BMP280::SAMPLING_X2, /* Temp. oversampling */
Adafruit_BMP280::SAMPLING_X16, /* Pressure oversampling */
Adafruit_BMP280::FILTER_X16, /* Filtering. */
Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */
gpsSerial.println(F(PMTK_SET_NMEA_OUTPUT_ALLDATA));
gpsSerial.println(F(PMTK_SET_NMEA_UPDATE_1HZ));
Serial.println("Software Serial GPS Test Echo Test");
Serial.println("Get version!");
gpsSerial.println(F(PMTK_Q_RELEASE));
}
void loop() {
const unsigned long deltaSampleTime = 1000;
static unsigned long lastSampleTime = 0;
static const size_t gpsBufferSize = 80;
static char gpsBuffer[gpsBufferSize + 1]; // +1 pour le caractère nul de fin
static size_t gpsBufferPosition = 0;
File myFile = SD.open("SPACEY.txt", FILE_WRITE);
if (myFile) {
// traiter les données du GPS s'il y en a
while (gpsSerial.available()) {
char c = gpsSerial.read();
if (c == '\n') { // on a finit de recevoir le message GPS
gpsBuffer[gpsBufferPosition] = '\0';
Serial.print("GPS: ");
Serial.println(gpsBuffer);
gpsBufferPosition = 0; // prêt pour la prochaine Trames NMEA
} else {
if (gpsBufferPosition < gpsBufferSize) gpsBuffer[gpsBufferPosition++] = c;
}
}
// traiter les capteurs si c'est le moment
if (millis() - lastSampleTime >= deltaSampleTime) {
float bmpTempC = bmp.readTemperature();
float pression = bmp.readPressure();
float altitude = bmp.readAltitude(PRESSION_LOCALE);
DHT.read(DHT11_PIN);
float dhtTempC = DHT.temperature;
float P = (analogRead(A0) * 5.0 / 1023.0) / 0.0045 + 105.5;
Serial.print(bmpTempC); Serial.print(", ");
Serial.print(pression); Serial.print(", ");
Serial.print(altitude); Serial.print(", ");
Serial.print(dhtTempC); Serial.print(", ");
Serial.println(P);
myFile.print(bmpTempC); myFile.print(", ");
myFile.print(pression); myFile.print(", ");
myFile.print(altitude); myFile.print(", ");
myFile.print(dhtTempC); myFile.print(", ");
myFile.println(P);
lastSampleTime += deltaSampleTime;
}
myFile.close();
} else {
// if the file didn't open, print an error:
Serial.println("error opening SPACEY.txt");
}
}
ça agrège le message du GPS dans un buffer avant de l'imprimer sinon vous pourriez avoir des bouts de message du GPS entrecoupés par des lectures des capteurs
Mettez la console série à 115200 bauds, ne la laissez pas à 9600 bauds (à moins que ce ne soit pas connecté par câble USB à votre PC)
oui, il est connecté à mon pc et il sera connecté à un pc lors du lancement. Merci pour votre programme nettoyer cependant les données viennent sur une seule ligne. Je voulais savoir si c'était fait exprès ou non et si c'était fait exprès est-ce que vous pouvez faire que ça passe à la ligne, s'il vous plait.