/* * CAMETEO project * * This is a personnal project of weather station with * automatic photo taking. * This code is the weather station part and is meant * to be run on a PJRC Teensy 3.2 board. * * Author : Arofarn * * Licence : GPL v3 * */ #include #include "cameteo_teensy.h" #include "SerialMessages.cpp" #include "RaspBerryPi_COM.cpp" //sensors_event_t bme280_event; float seaLevelPressure = 1015.0; float bme280_press; float bme280_temp; float bme280_alti; float bme280_hum; enum strike_sources { UNKNOWN_SRC, LIGHTNING, PERTURBATION, NOISE }; volatile int8_t AS3935_ISR_Trig = 0; // Trigger for AS3935 lightning sensor void AS3935_ISR() { AS3935_ISR_Trig = 1; } PWF_AS3935 lightning(AS3935_CS_PIN, AS3935_IRQ_PIN, 33); int as3935_src; int as3935_distance; long lightning_nb_total = 0; int lightning_nb_hour = 0; int lightning_nb_day = 0; int as3935_perturb_total = 0; int as3935_noise_total = 0; int as3935_unknown_total = 0; char lightning_log_file[12] = "lghtnng.log"; //GPS //Adafruit_GPS GPS(&GPS_SERIAL_PORT); TinyGPS GPS; float gps_latitude, gps_longitude, gps_altitude; // returns +- latitude/longitude in degrees float gps_speed, gps_course; unsigned long gps_time, gps_date, gps_fix_age; int gps_year; byte gps_month, gps_day, gps_hour, gps_minutes, gps_second, gps_hundreths; unsigned long gps_chars, gps_hdop; unsigned short gps_sentences, gps_failed_checksum, gps_satellites; //Miscellaneous bool rpi_status; rpi_status = false; int batt_voltage; bool low_battery_flag = false; // Tasks timers elapsedMillis since_bme280; //elapsedMillis since_dht; elapsedMillis since_gps; elapsedMillis since_display; elapsedMillis since_serial_send; elapsedMillis since_sd_log; elapsedMillis since_batt_chk; //SD Card #define CONFIGFILE "config.txt" //Configuration char data_file[13] = "datalog.csv"; //Delays unsigned int bme280_delay = 500; //unsigned int dht_delay = 3000; unsigned int gps_delay = 100; unsigned int serial_send_delay = 5000; unsigned int sd_log_delay = 5000; unsigned int batt_chk_delay = 5000; //Date and time int TZ = 1; //Time zone /* * SETUP */ void setup() { //To be sure Raspberry-Pi won't be turned on unexpectedly stopRPI(); pinMode(LOW_BATT_PIN, INPUT_PULLUP); low_battery_flag = !digitalRead(LOW_BATT_PIN); pinMode(GPS_BUT_PIN, INPUT_PULLUP); pinMode(GPS_EN_PIN, OUTPUT); gps_power(); SERIAL_PORT.begin(SERIAL_BAUD_RATE); delay(1000); //while (!SERIAL_PORT) { }; //Wait for serial port to start SERIAL_PORT.printf("Serial Comm. OK\nNow booting...\n"); BootMessage("SDcard"); // see if the card is present and can be initialized: if (!SD.begin(SD_CS_PIN)) { BootError(); while(1); } BootOK(); BootMessage("RT Clock"); // set the Time library to use Teensy 3.0's RTC to keep time setSyncProvider(getTeensy3Time); if (timeStatus()!= timeSet) { BootError(); while(1); } BootOK(); // BootMessage("AM2302/DHT22 (Humidity and Temperature)"); // dht.begin(); // //sensor_t sensor; // BootOK(); BootMessage("BME280 (Pressure and Temperature)"); /* Initialise the sensor */ if(!bme.begin()) { /* There was a problem detecting the BMP085 ... check your connections */ BootError(); while(1); } BootOK(); BootMessage("AS3935 (Lightning)"); SPI.begin(); SPI.setClockDivider(SPI_CLOCK_DIV16); // SPI speed to SPI_CLOCK_DIV16/1MHz (max 2MHz, NEVER 500kHz!) SPI.setDataMode(SPI_MODE1); // MAX31855 is a Mode 1 device --> clock starts low, read on rising edge SPI.setBitOrder(MSBFIRST); // data sent to chip MSb first lightning.AS3935_DefInit(); // set registers to default // now update sensor cal for your application and power up chip lightning.AS3935_ManualCal(AS3935_CAPACITANCE, AS3935_INDOORS, AS3935_DIST_EN); // enable interrupt (hook IRQ pin to Arduino Uno/Mega interrupt input: 0 -> pin 2, 1 -> pin 3 ) attachInterrupt(AS3935_IRQ_PIN, AS3935_ISR, RISING); BootOK(); BootMessage("GPS"); GPS_SERIAL_PORT.begin(GPS_SERIAL_BAUD_RATE); while (!GPS_SERIAL_PORT) {} ; BootOK(); } /* * LOOP */ void loop() { //Power ON/OFF GPS gps_power(); //Lightning detection if (AS3935_ISR_Trig != 0) { AS3935_ISR_Trig = 0; time_t t = now(); int distance = -9999; int energy = -9999; switch (as3935_src) { case UNKNOWN_SRC: //source inconnue as3935_unknown_total++; SERIAL_PORT.printf("Interruption (AS3935) : unkown source (not lightning)\n"); break; case LIGHTNING: //Foudre !!! lightning_nb_total++; distance = lightning.AS3935_GetLightningDistKm(); energy = lightning.AS3935_GetStrikeEnergyRaw(); SERIAL_PORT.printf("Interruption (AS3935) : Lightningbolt !!!\n"); SERIAL_PORT.printf("Distance : %4d km | Energy : %d \n", distance, energy); break; case PERTURBATION: //Perturbation as3935_perturb_total++; SERIAL_PORT.printf("Interruption (AS3935) : perturbation...\n"); break; case NOISE: //Trop de bruit électromagnétique as3935_noise_total++; SERIAL_PORT.printf("Interruption (AS3935) : Too much electromagnetic noise!\n"); break; } writeLightningToSD(as3935_src, t, distance, energy); } if (since_batt_chk >= batt_chk_delay) { since_batt_chk -= batt_chk_delay; //Check battery status and voltage low_battery_flag = !digitalRead(LOW_BATT_PIN); batt_voltage = getBatteryVoltage(); } // if (since_dht >= dht_delay) { // since_dht = since_dht - dht_delay; // // Read temperature or humidity // dht.humidity().getEvent(&dht22_event_hum); // dht.temperature().getEvent(&dht22_event_temp); // } if (since_bme280 >= bme280_delay) { since_bme280 = since_bme280 - bme280_delay; /* Get a new sensor event */ bmp.getEvent(&bme280_event); /* Get the values (barometric pressure is measure in hPa) */ if (bme280_event.pressure) { bme280_press = bme280_event.pressure; bmp.getTemperature(&bme280_temp); bme280_alti = bmp.pressureToAltitude(seaLevelPressure, bme280_press); } } if (since_gps >= gps_delay) { since_gps = since_gps - gps_delay; while (GPS_SERIAL_PORT.available()) { char c = GPS_SERIAL_PORT.read(); if (GPS.encode(c)) { GPS.get_datetime(&gps_date, &gps_time, &gps_fix_age); GPS.crack_datetime(&gps_year, &gps_month, &gps_day, &gps_hour, &gps_minutes, &gps_second, &gps_hundreths, &gps_fix_age); GPS.f_get_position(&gps_latitude, &gps_longitude, &gps_fix_age); gps_altitude = GPS.f_altitude(); gps_speed = GPS.f_speed_kmph(); GPS.stats(&gps_chars, &gps_sentences, &gps_failed_checksum); gps_satellites = GPS.satellites(); gps_hdop = GPS.hdop(); } } } if (since_sd_log >= sd_log_delay) { since_sd_log = since_sd_log - sd_log_delay; writeDataToSD(); } if (since_serial_send >= serial_send_delay) { since_serial_send = since_serial_send - serial_send_delay; sendDataOnSerial(); } } /* * FUNCTIONS */ time_t getTeensy3Time() { return Teensy3Clock.get(); } void gps_power() { if (digitalRead(GPS_BUT_PIN) == 0) { digitalWrite(GPS_EN_PIN, LOW); } else { digitalWrite(GPS_EN_PIN, HIGH); } } int getBatteryVoltage() { long mean = 0; int U = 0; int n = 10; int res = 12; analogReadResolution(res); for (int i=0; i