-
ARDUINO UNO nos (et vos) premières applications pour ballons haute altitude
#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
-
Commentaires