-
//#include <DHT.h>
#include <TinyGPS.h> // http://arduiniana.org/libraries/tinygpsplus/
#include <SD.h>
//SoftwareSerial SerialGPS(9,10); // RX, TX
TinyGPS gps; // create a TinyGPS object
//#define DHTPIN 3
//#define DHTTYPE DHT22
int chipSelect=4;
int LED=7;
unsigned long t1, fix_age;
float lat, lon, alti, vitesse;
int annee,fix,i;
byte c,mois, jour, seconde, minute, heure, centiemes;
String date ="";
void setup()
{
Serial.begin(9600);
Serial1.begin(9600); // GPS devices frequently operate at 4800 baud
Serial.println("Initialisation...");
pinMode(chipSelect, OUTPUT);
pinMode(5,OUTPUT);
pinMode(10,OUTPUT); // Carte Ethernet
digitalWrite(chipSelect,LOW);
digitalWrite(5,HIGH);
digitalWrite(10,HIGH); // désactiver Carte SD
pinMode(LED,OUTPUT);
if (!SD.begin(chipSelect)) Serial.println("Erreur carte SD"); else Serial.println("Carte presente");
t1=millis();
}
void loop()
{
while (Serial1.available()&&millis()-t1>4000)
{
c = Serial1.read();
Serial.write(c);
if (gps.encode(c)&&millis()-t1>5000) lireGPS(); // tempo pour lire une trame RMC
if (millis()-t1>6000) { // Attente du Fix
fix++;
Serial.println();
Serial.println("Attente du FIX... ");
Serial.print(6*fix); Serial.println(" s");
t1=millis();}
}
}
void lireGPS()
{
gps.f_get_position(&lat, &lon); // Fonction de la bibliothèque TinyGPS
gps.crack_datetime(&annee, &mois, &jour, &heure, &minute, &seconde, ¢iemes, &fix_age);
date =String(jour) + "/" + String(mois) + "/" + String(annee) + " "+ String (heure+1) + ":" + String (minute) + ":" + String (seconde);
Serial.println();
Serial.println(date);
Serial.print("Mesure ");Serial.println(i);
Serial.print("Latitude = ");Serial.println(lat,5);
Serial.print("Longitude = ");Serial.println(lon,5);
alti = gps.f_altitude(); // +/- altitude in meters
Serial.print("Altitude = ");Serial.print(alti,1);Serial.println(" m");
vitesse = gps.f_speed_mps();
Serial.print("Vitesse = ");Serial.print(vitesse,1);Serial.println(" m/s");
Serial.print(lat,5);Serial.print(",");Serial.println(lon,5);
Serial.println();
digitalWrite(LED,1);
if (i==0) entete();
ecritureSD();
digitalWrite(LED,0);
t1=millis();
i++;
fix=0;
}
void entete(){ // Pour utiliser Google table de fusion séparateur
File GPStab = SD.open("GPS_Tab.csv", FILE_WRITE);
if (GPStab) {
GPStab.print("date");
GPStab.print(";");
GPStab.print("latitude");
GPStab.print(";");
GPStab.print("longitude");
GPStab.print(";");
GPStab.print("Altitude");
GPStab.print(";");
GPStab.println("Mesure");
GPStab.close();
}
}
void ecritureSD() {
File GPStab = SD.open("GPS_Tab.csv", FILE_WRITE);
if (GPStab) {
GPStab.print(date);
GPStab.print(";");
GPStab.print(lat,5);
GPStab.print(";");
GPStab.print(lon,5);
GPStab.print(";");
GPStab.print(alti,1);
GPStab.print(";");
GPStab.println(i);
GPStab.close();
}
else {
Serial.print("Erreur GPS_Tab.csv");}
}---------------------------------------------------------------------------
Cette fois, c'est au tour du GPS, ce programme devrait permettre de le tester. Je ne l'ai pas encore programmé, mais
je vous le soumet pour le tester. Si vous voulez le fichier .ino pour ce programme ou pour les autres,
ainsi que les librairies, je peux vous les faire parvenir par mail, mais sans garantie si non testé.
J'aurai l'occasion de commenter dans un article, ce que vous pouvez récupérer avec votre GPS. En gros, vous pouvez
obtenir dans l'ordre :
la date, l'heure, la latitude, la longitude, et l'altitude.
Si votre GPS ne convient pas pour les vols sur un ballon haute altitude, l'indication d'altitude sera bloquée en vol, en
général vers 18 km.
Merci pour votre participation et vos commentaires.
Alain F6AGV - BHAF - f6agv (@) free.fr Ballons Haute Altitude France
votre commentaire -
/* test RTTY BEACON du module NTX2B
*/
//définir la pin de sortie vers NTX2B
#define RADIOPIN 9
//définir les bibliothèques
#include <string.h>
#include <util/crc16.h>
//définir la taille du texte à transmettre en balise
char datastring[80];
void setup(){
pinMode(RADIOPIN,OUTPUT);
Serial.begin(9600);
}
void loop(){
snprintf(datastring,80,"$$$$$F6AGV-11,RTTY,TEST,BEACON"); //placer le texte dans datastring
unsigned int CHECKSUM=gps_CRC16_checksum(datastring); //calcul du checksum pour ce texte
char checksum_str[6];
sprintf(checksum_str,"*%04X\n",CHECKSUM);
strcat(datastring,checksum_str);
rtty_txstring(datastring);
}
void rtty_txstring(char*string){
//envoyer des caractéres d'un octet de 8 bits (byte)
char c;
c=*string++;
while (c !='\0'){
rtty_txbyte(c);
c=*string++;
}
}
void rtty_txbyte(char c){
//envoyer chaque bit d'un caractére
//le LSB est transmit en premier
//chaque octet est précédé d'un zéro (start)
//chaque octet est suivi d'un ou deux un (stop)
int i;
rtty_txbit(0); //start bit
//envoyer les bits avec LSB en premier
for (i=0;i<7;i++) { //
if(c&1) rtty_txbit(1);
else rtty_txbit(0);
c = c>>1;
}
rtty_txbit(1); //stop bit
rtty_txbit(1); //stop bit
}
void rtty_txbit (int bit) {
if (bit) {
// high
analogWrite(RADIOPIN,110);
}
else {
// low
analogWrite(RADIOPIN,100);
}
delayMicroseconds(10000);
delayMicroseconds(10150);
/* pour 300 bauds (3370)
pour 50 bauds (20150)
*/
}
uint16_t gps_CRC16_checksum (char*string){
size_t i;
uint16_t crc;
uint8_t c;
crc = 0xFFFF;
//calcul du checksum les deux premiers $$ ne comptent pas
for(i=2; i <strlen(string);i++) {
c=string[i];
crc=_crc_xmodem_update (crc, c);
}
return crc;
}
------------------------------------------------------------
Petit commentaire : ce programme écrit par Anthony M0UPU, vous permettra de tester votre émetteur NTX2 ou NTX2B.
Ainsi que la réception du message "$$$$$F6AGV-11,TEST,RTTY,BEACON". Pour recevoir, cette émission, il vous faut
un récepteur UHF sur la bande 434 MHz en USB, une antenne verticale quart d'onde (ou 7 éléments pour recevoir des
émissions de ballons plus lointains). Il vous faut un ordinateur avec le logiciel DL-FLDIGI HAB ou normal.
Ce logiciel vous permet de recevoir d'autres modes numériques utilisés par les ballons haute altitude.
Je recommande une interface d'isolement entre le PC et le récepteur UHF. Si vous n'en avez pas encore, il suffit
d'alimenter le récepteur avec une batterie 12 volts. La configuration à placer sur DL-FLDIGI pour recevoir ces trames
de test en mode balise est RTTY ---> custom ---> 50 bauds 7 bits ascii none et 2 bits de stop.
Ce programme a été testé avec succès, si vous avez une erreur à cause d'une mauvaise librairie, je pourrai vous
faire parvenir les miennes qui sont dans le programme.
Merci pour votre participation et vos commentaires.
Alain F6AGV : f6agv (@) free.fr
votre commentaire -
#include <NewSoftSerial.h>
#include <TinyGPS.h>
#include <SD.h>
#include <OneWire.h>
#include <util/crc16.h>
//capteur de temperature
#define DS18B20 0x28
OneWire ds(5);
OneWire ds2(6);
int temperature_val_ext=0;
int temperature_val=0;
//GPS
TinyGPS gps;
NewSoftSerial mySerial(2, 3);
char msg[80];
int count = 1;
long lat, lon;
unsigned long time;
//carte memoire
File theFile;
//radio
char datastring[80];
#define RADIOPIN 8
//variable globale
int pression_val=0;
int altitude_val=0;
void setup()
{
Serial.begin(115200);
mySerial.begin(9600);
pinMode(10, OUTPUT);
if (!SD.begin(10))
{
Serial.println(" Card failed, or not present");
return;
}
pinMode(RADIOPIN,OUTPUT);
}
////////////////////////////////////////////////////////////////////////////////////////////RADIO
void rtty_txstring (char * string)
{
/* Simple function to sent a char at a time to
** rtty_txbyte function.
** NB Each char is one byte (8 Bits)
*/
char c;
c = *string++;
while ( c != '\0')
{
rtty_txbyte (c);
c = *string++;
}
}
void rtty_txbyte (char c)
{
/* Simple function to sent each bit of a char to
** rtty_txbit function.
** NB The bits are sent Least Significant Bit first
**
** All chars should be preceded with a 0 and
** proceded with a 1. 0 = Start bit; 1 = Stop bit
**
*/
int i;
rtty_txbit (0); // Start bit
// Send bits for for char LSB first
for (i=0;i<7;i++) // Change this here 7 or 8 for ASCII-7 / ASCII-8
{
if (c & 1) rtty_txbit(1);
else rtty_txbit(0);
c = c >> 1;
}
rtty_txbit (1); // Stop bit
rtty_txbit (1); // Stop bit
}
void rtty_txbit (int bit)
{
if (bit)
{
// high
digitalWrite(RADIOPIN, HIGH);
}
else
{
// low
digitalWrite(RADIOPIN, LOW);
}
// delayMicroseconds(3370); // 300 baud
delayMicroseconds(10000); // For 50 Baud uncomment this and the line below.
delayMicroseconds(10150); // You can't do 20150 it just doesn't work as the
// largest value that will produce an accurate delay is 16383
// See : http://arduino.cc/en/Reference/DelayMicroseconds
}
uint16_t gps_CRC16_checksum (char *string)
{
size_t i;
uint16_t crc;
uint8_t c;
crc = 0xFFFF;
// Calculate checksum ignoring the first two $s
for (i = 2; i < strlen(string); i++)
{
c = string[i];
crc = _crc_xmodem_update (crc, c);
}
return crc;
}
////////////////////////////////////////////////////////////////////////////////////////////TEMPERATURE
boolean getTemperature(int *temperature_val){
byte data[9], addr[8];
if (!ds.search(addr)) {
ds.reset_search();
return false;
}
if (OneWire::crc8(addr, 7) != addr[7])
return false;
if (addr[0] != DS18B20)
return false;
ds.reset();
ds.select(addr);
ds.write(0x44, 1);
delay(800);
ds.reset();
ds.select(addr);
ds.write(0xBE);
for (byte i = 0; i < 9; i++)
data[i] = ds.read();
// Calcul de la température en degré Celsius
*temperature_val = ((data[1] << 8) | data[0]) * 0.0625;
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////TEMPERATURE EXTERIEUR
boolean getTemperature_ext(int *temperature_val_ext){
byte data[9], addr[8];
if (!ds2.search(addr)) {
ds2.reset_search();
return false;
}
if (OneWire::crc8(addr, 7) != addr[7])
return false;
if (addr[0] != DS18B20)
return false;
ds2.reset();
ds2.select(addr);
ds2.write(0x44, 1);
delay(800);
ds2.reset();
ds2.select(addr);
ds2.write(0xBE);
for (byte i = 0; i < 9; i++)
data[i] = ds2.read();
// Calcul de la température en degrée Celsius
*temperature_val_ext = ((data[1] << 8) | data[0]) * 0.0625;
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////CARTE MEMOIRE
void sd(int temperature_val,int temperature_val_ext, int altitude_val, int pression_val, long lat, long lon, long altGPS)
{
File theFile = SD.open("fichier.txt", FILE_WRITE);
theFile.print(lat);
theFile.print(" ");
theFile.print(lon);
theFile.print(" ");
theFile.print(altGPS);
theFile.print(" ");
theFile.print(pression_val);
theFile.print(" ");
theFile.print(altitude_val);
theFile.print(" ");
theFile.print(temperature_val);
theFile.print(" ");
theFile.println(temperature_val_ext);
theFile.close();
Serial.println("carte sd ecrit !");
}
////////////////////////////////////////////////////////////////////////////////////////////PRESSION
float pression()
{
int val = analogRead(0);
float tension = ((val-10)*0.0049);
// Calcul de la pression réel
int pression_val = (100.1-(((tension/5)-0.04) / 0.009))*10;
return pression_val;
}
////////////////////////////////////////////////////////////////////////////////////////////ALTITUDE
int getAltitude(long pression_val)
{
pression_val=pression_val/0.01;
// Pression au niveau de la mer (Pa)
const float p0 = 101325;
int altitude = (float)44330 * (1 - pow(((float) pression_val/p0), 0.190295))+230;
return altitude;
}
////////////////////////////////////////////////////////////////////////////////////////////GPS
void GPS(){
if (mySerial.available()) {
if(!gps.encode(mySerial.read())) return;
gps.get_position(&lat, &lon, NULL);
gps.get_datetime(NULL, &time, NULL);
snprintf(msg, 80,
"heure : %02li:%02li:%02li lat/lon : %s%li.%05li,%s%li.%05li altitude : %li",
time / 1000000, time / 10000 % 100, time / 100 % 100,
(lat >= 0 ? "" : "-"), labs(lat / 100000), labs(lat % 100000),
(lon >= 0 ? "" : "-"), labs(lon / 100000), labs(lon % 100000),
gps.altitude() / 100
);
Serial.println(msg);
delay(1000);
}
}
////////////////////////////////////////////////////////////////////////////////////////////LOOP
void loop()
{
for (unsigned long start = millis(); millis() - start < 1000;)
GPS();
pression_val=pression();
Serial.print("pression = ");
Serial.println(pression_val);
altitude_val=getAltitude(pression_val);
Serial.print("altitude = ");
Serial.println(altitude_val);
getTemperature(&temperature_val);
Serial.print("Temperature : ");
Serial.println(temperature_val);
getTemperature_ext(&temperature_val_ext);
Serial.print("Temperature exterieur : ");
Serial.println(temperature_val_ext);
sd(temperature_val,temperature_val_ext, altitude_val, pression_val, lat, lon, gps.altitude());
noInterrupts();
snprintf(datastring, 250,
"T : %02li:%02li:%02li lat/lon : %s%li.%05li,%s%li.%05li altGPS : %li P = %dHpa alt = %dm temp = %d tempext = %d",
time / 1000000, time / 10000 % 100, time / 100 % 100,
(lat >= 0 ? "" : "-"), labs(lat / 100000), labs(lat % 100000),
(lon >= 0 ? "" : "-"), labs(lon / 100000), labs(lon % 100000),
gps.altitude() / 100,
pression_val,
altitude_val,
temperature_val,
temperature_val_ext
);
unsigned int CHECKSUM = gps_CRC16_checksum(datastring);
char checksum_str[6];
sprintf(checksum_str, "\n", CHECKSUM);
strcat(datastring,checksum_str);
rtty_txstring (datastring);
interrupts();
delay(5000);
asm volatile (" jmp 0");
}
-----------------------------------------------------------------------------------Ce programme semble complet pour un vol de ballon, mais je ne l'ai pas encore testé !
Je vous le livre quand même, et si vous pouvez le faire fonctionner sur un Arduino Uno ou un Méga,
je serai très intéressé ainsi que les lecteurs de savoir si il fonctionne et quelques remarques.
Merci pour votre participation.
Alain F6AGV - BHAF - Ballons Haute Altitude France - 7 avril 2016
votre commentaire
Suivre le flux RSS des articles
Suivre le flux RSS des commentaires