Display-Betrieb bricht regelmäßig ab

Seit einiger Zeit funktioniert ein Programm nicht mehr richtig. Nach Kompilation und Upload läuft zunächst das Programm ganz normal. Eine kleine Änderung am Programm und die Anzeige bleibt dunkel, die Funktion, der Datenaustausch mit TTN, bleibt aber erhalten. Nach nochmaliger Änderung wird das OLED-Display wieder aktiv und so fort.
Was kann das sein?

Hi @altprog,

kannst du uns den Programmcode zeigen? Sonst wird es schwierig das Problem zu finden.

Viele Grüße
Mario

@mario

ich versuche es einmal. Der Code ist ziemlich lang,

/*  mobiler Cayenne Tiger
     Version 0.94 vom 22.06.2022
     nur GPS-Daten wenn GPS-Status o.k.
     versuch die einfache Lösung im GPS-Teil von AS342 zu übernehmen
     gpsSearch mit parameterübergabe Dauer der Suche
     aus gehender Version 0.41 und Neurunegen aus 0.70
     Neuerungen Serieller GP-Sensor
     mit neuen Verbindungsdaten (APPEUI und APKEY
     mit GPS und SD-Karte
     Statt seriellem CO2-Sensor SCD30 mit I2C
     GPS wahlweise
     mit 2. Displayjob ala Felix
     mit PM, Sound, CO2
     mit sleep-Routinen von Hackair
     aufbauend auf der Funktionierende Version 4.1e
     mit Umrechnung Luftdruck auf Meereshöhe
     sowie  debugSDS für SDS-Status
     Messung und Schalterabfrage in die Displayroutine
     Messung des Solarladestroms mittels INA162

*/
#include "SenseBoxMCU.h"
//#include <SPI.h>
#include <lmic.h>
#include <hal/hal.h>
#include <CayenneLPP.h>
//#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "SparkFun_SCD30_Arduino_Library.h"


#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#define GROVE_CO2 (Serial2)   // CO2-Sensor an Serial2
// CO2 alternativ
#define GROVE_CO2_CONNECTED

#ifdef GROVE_CO2_CONNECTED
int temperature_co2;
int CO2PPM;
#endif

// SDS011 Sensor
#define SDS011_CONNECTED

#ifdef SDS011_CONNECTED
#define  SDS_UART_PORT (Serial2)
#endif

//--------------------Betriebsmodi-Variable-------------

bool txlora;   //LoRa
bool sat;      //GPS
bool sd;       //SD-Karte

//-------------------------------------------------------

// Schaltermapping
#define sdsSchalterpin 1   // an pin 1 ist der Schalter für SDS-Sensor angeschlosse
#define akkuPin 2         // an pin 2 wird die Akkuspannung gemessen
#define soundmeterpin 3    // Pin 3 ist den Soundmesser vorgesehen

#define isolarpin 5       // an 5 ist der Ausgang des Strommoduls angesclossen
#define dispSchalterpin 6 // ist nicht angeschlossen
bool sdsSchalterstatus;    // Zustand des sdsSchalters
bool dispSchalterstatus;   // Zustand des DispSchalters
bool sdsStatus;           // Zustand der Feinstaubmessung
bool dispStatus;          // Anzeigemodus an oder aus
bool gpsStatus = true;         // GPS-Empfang erstmal o.k.

CayenneLPP lpp(51);

String fileName = "SenseBox.txt";
const int chipSelect = 28; //  CS laut Mario
uint8_t attempt = 0;    // Zähler für Versuche
int CO2;              //  "    CO2
//Kommandostring für CO2-Sensor
const unsigned char cmd_get_sensor[] = {0xff, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79 };
// Antwort des Sensors
unsigned char dataReviced[9];
bool debugSDS = false;      // Debug für SDSStatus
bool debug = false ;
bool debug1=false;
//AllgemeinDebug-Infos
float temperature;
float temperaturbmp;      //Vergleichsmessung der Temperatur
float temperatursdc;       // Temperatur Airsensor
float humidity;
double pressure;
uint32 lux;
uint16 uv;
float dez;
float val;    //Rohwert der Akkuspannung
float uAkku;
float pm10;
float pm25;
long counter = 0;
long nr = 0;
int tries = 0;
int dauer;    // Dauer der GPS-Suche
int grenze = 500;
double psea;   // Druck auf Meereshöhe reduziert
float usolar;  // Ausgangsspannung des Strommoduls
float isolar; //  Ladestrom des Solarmoduls
// Varaiablen für GPS
float lat, lon, alt;
float breite, laenge;
float calcDegrees(String input);
//String calcLocator(float lat, float lon);

unsigned long time, date, speed;
String data;
/*long lat, lon;
  unsigned long fix_age, time, date, speed, course;
  unsigned long chars;
  unsigned short sentences, failed_checksum;
*/
//0x00, 0x0D, 0x7E, 0x50, 0x0D, 0xB3, 0x00, 0x07  //lsb

static const u1_t PROGMEM APPEUI[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} ; //Neue APPEUI
void os_getArtEui (u1_t* buf) {
  memcpy_P(buf, APPEUI , 8);
}


static const u1_t PROGMEM DEVEUI[8] = {0x5A, 0x3F, 0x04, 0xD0, 0x7E, 0xD5, 0xB3, 0x70}; //neue DEVEUI
void os_getDevEui (u1_t* buf) {
  memcpy_P(buf, DEVEUI , 8);
}

// This key should be in big endian format (or, since it is not really a
// number but a block of memory, endianness does not really apply). In
// practice, a key taken from ttnctl can be copied as-is.
// The key shown here is the semtech default key. //0x02, 0x30, 0xAC, 0x09, 0xE0, 0xD0, 0x0C, 0x50, 0x32, 0x02, 0xA0, 0x64, 0x02, 0xD0, 0x34, 0x04
//0x02, 0x30, 0xAC, 0x09, 0xE0, 0xD0, 0x0C, 0x50, 0x32, 0x02, 0xA0, 0x64, 0x02, 0xD0, 0x34, 0x04    // msb
static const u1_t PROGMEM APPKEY[16] = {0xC6, 0x99, 0x1F, 0x84, 0xAD, 0xED, 0x2C, 0xF4, 0xE2, 0xB9, 0x24, 0x3E, 0x74, 0xA3, 0xA7, 0x68};// Neuer Appkey
void os_getDevKey (u1_t* buf) {
  memcpy_P(buf, APPKEY , 16);
}

//----------------------------- Definition der Job's --------------

static osjob_t sendjob;
static osjob_t displayjob;

// Schedule TX every this many seconds (might become longer due to duty
// cycle limitations).
const unsigned TX_INTERVAL = 300;
const unsigned DISPLAY_INTERVAL = 3; //update Display each 3.second
//----------------------------------------------------------

// Pin mapping
const lmic_pinmap lmic_pins = {
  .nss = PIN_XB1_CS,
  .rxtx = LMIC_UNUSED_PIN,
  .rst = LMIC_UNUSED_PIN,
  .dio = {PIN_XB1_INT, PIN_XB1_INT, LMIC_UNUSED_PIN},
};

//----------------------------- Sensor instances ----------
HDC1080 hdc;
BMP280 bmp_sensor;
TSL45315 tsl;
VEML6070 veml;
#ifdef SDS011_CONNECTED
SDS011 SDS(SDS_UART_PORT);
#endif
SCD30 airSensor;
File myFile;
TinyGPSPlus gps;

//----------------------- Unterprogramme ----------------/

void zeit(unsigned long zk) {
  unsigned long i;
  zk = zk * 1000;
  for (i = 0; i < zk; i++) {
    //nix
  }
}

//Diese Funktion stellt sicher, dass das GPS-Modul weiterhin ausgelesen wird.
static void smartDelay(unsigned long ms) {
  unsigned long start = millis();
  do
  {
    Wire.requestFrom(0x42, 10);
    while (Serial1.available()) 
      gps.encode(Serial1.read()); //Stlllegen wegen Kompabilität zu gps-Test
  } while (millis() - start < ms);
  
}


void showData() {
  if (gps.location.isValid()) {
    SerialUSB.print("Breite: "); SerialUSB.println(gps.location.lat(), 6);
    lat = gps.location.lat();
    SerialUSB.print("Länge: "); SerialUSB.println(gps.location.lng(), 6);
    lon = gps.location.lng();
    gpsStatus = true;
  }
  else {
    SerialUSB.println("Location is not available");
    gpsStatus = false;
  }
}


// NMEA Format (d)ddmm.mmmmm....... UPG zur Gradberechnung
// (d)dd + (mm.mmmmm / 60) = degrees
float calcDegrees(String input) {
  String direction = input.substring(input.length() - 1);
  String dddSt = input.substring(0, input.indexOf('.'));
  dddSt.remove(dddSt.length() - 2, dddSt.length() - 1);
  int ddd = dddSt.toInt();
  String mSt = input.substring(input.indexOf('.') - 2, input.length() - 1);
  float m = mSt.toFloat();
  float result = ddd + (m / 60);
  if (direction.equals("W") || direction.equals("S")) {
    result *= (-1);
  }
  return result;
}

void gpsSearch(int dauer) {   //Übergabe wie lange UPG sucht

  //Den Nutzer über die Satellitensuche informieren
  Serial.println("Beginning GPS Satellite Search:");
  display.setCursor(0, 0);
  display.setTextSize(1);
  display.setTextColor(WHITE, BLACK);
  display.println("Searching Satellites");
  display.display();

  smartDelay(1000);

  //Warten, bis ein Satellit gefunden wird
  long jetzt = millis();
  if (debug) {
    Serial.println(" In GpsSearch ");
  }
  while ((millis() - jetzt) < dauer ) {
    if (debug) {
      Serial.print(".");
    }

    if (Serial1.available() > 0) {
      String input = Serial1.readStringUntil('\n');
      input.remove(input.length() - 1, 1);

      if (debug1) {
        Serial.println(input);
      }
      if (input.startsWith("$GPGGA")) {
        if (debug) {
        Serial.print("in $GPGGA ");Serial.println (input);
        delay(1000);
      }
        input.remove(0, input.indexOf(',') + 1);
        String utc = input.substring(0, input.indexOf('.'));
        input.remove(0, input.indexOf(',') + 1);
        String late = input.substring(0, input.indexOf(','));
        input.remove(0, input.indexOf(',') + 1);
        late.concat(input.substring(0, input.indexOf(',')));
        input.remove(0, input.indexOf(',') + 1);
        String lone = input.substring(0, input.indexOf(','));
        input.remove(0, input.indexOf(',') + 1);
        lone.concat(input.substring(0, input.indexOf(',')));
        input.remove(0, input.indexOf(',') + 1);
        String quality = input.substring(0, input.indexOf(','));
        input.remove(0, input.indexOf(',') + 1);
        String numOfSat = input.substring(0, input.indexOf(','));
        input.remove(0, input.indexOf(',') + 1);
        input.remove(0, input.indexOf(',') + 1);
        String alte = input.substring(0, input.indexOf(','));
        input.remove(0, input.indexOf(',') + 1);
        alte.concat(input.substring(0, input.indexOf(',')));

        if (quality.equals("1")) {
          breite = calcDegrees(late);
          laenge = calcDegrees(lone);
          lat = calcDegrees(late);
          lon= calcDegrees(lone);
          Serial.println(breite);
          Serial.println(laenge);
          Serial.println(utc);
        }


        printOnDisplay( "Breite", String(lat), "", "UTC", utc, "");
        delay(5000);

        /*
          if ((millis() - jetzt) > 9000) {
          gpsStatus = false;
          Serial.print("GPS-Status: ");Serial.println(gpsStatus);
          return;
          }
        */
      }
    }
  }
}




// UPG um den Feinstaub-Sensor schlafen zu legen
void sleep() {
  // SDS011 uses the built-in power saving function

  // Send sleep command
  uint8_t sleep_command[] = {0xAA, 0xB4, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x05, 0xAB};
  for (uint8_t i = 0; i < 19; i++) {
    Serial2.write(sleep_command[i]);
  }

  // Discard response
  Serial2.flush();
  while (Serial.read() != -1) {}
}

// PG zum Aufwachen des Feinstaub-Sensaors
void wakeup() {
  // SDS011 uses the built-in power saving function
  uint8_t wakeup_command[] = {0xAA, 0xB4, 0x06, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x06, 0xAB};  // Checksum von 05 auf 06 geändert
  for (uint8_t i = 0; i < 19; i++) {
    Serial2.write(wakeup_command[i]);
  }

  // Discard response
  Serial2.flush();
  while (Serial.read() != -1) {}
  //Serial2.write(0x01); // alter Kommandostring
  delay(2000);
}

void initLora() {
  delay(2000);
  // LMIC init
  os_init();
  // Reset the MAC state. Session and pending data transfers will be discarded.
  LMIC_reset();

  // Start job (sending automatically starts OTAA too)
  do_send(&sendjob);
  update_display(&displayjob);
}

void printOnDisplay(String title1, String measurement1, String unit1, String title2, String measurement2, String unit2) {
  display.clearDisplay();
  display.setCursor(0, 0);
  display.setTextSize(1);
  display.setTextColor(WHITE, BLACK);
  display.println(title1);
  display.setCursor(0, 10);
  display.setTextSize(2);
  display.print(measurement1);
  display.print(" ");
  display.setTextSize(1);
  display.println(unit1);
  display.setCursor(0, 30);
  display.setTextSize(1);
  display.println(title2);
  display.setCursor(0, 40);
  display.setTextSize(2);
  display.print(measurement2);
  display.print(" ");
  display.setTextSize(1);
  display.println(unit2);
  display.display();
}

void update_display(osjob_t* ) { // enthält aus Präsenzgründen auch die Aufrufe der Messwerte


  sdsSchalterstatus = digitalRead(sdsSchalterpin);
  dispSchalterstatus = digitalRead(dispSchalterpin);
  if (sdsStatus == 1) {         //ein?
    if (sdsSchalterstatus == 0) {   // ausschalten
      sleep();            // SDS aus
      sdsStatus = 0;
    }
  } else {
    // nix
  }
  if (sdsStatus == 0) {         //aus?
    if (sdsSchalterstatus == 1) {  // ein
      wakeup();
      delay(1000);         // warten
      sdsStatus = 1;

    }
  }
  else {
    //nix
  }
  if (debugSDS) {
    Serial.print("SDS-Status: "); Serial.print(sdsStatus);
    Serial.println();
  }


  // Messwerte aufrufen ----------------------------------------

  val = analogRead(akkuPin);
  uAkku = ((val / 1023.0) * 5.0); //war mal 3.6
  uAkku = uAkku * 1.14;       // Korrekturfaktor für nicht genaua Teilerwiderstände
  if (debug) {
    Serial.print("Messwert Akku: ");
    Serial.println(uAkku);
  }
  //usolar = analogRead(isolarpin) * (5.0 / 1024.0); // Ausgangsspannung des Strommoduls
  //isolar = usolar * 1000 / (100);               // Umrechnung in mA
  temperatursdc = airSensor.getTemperature();
  // temperature=temperature-1,7;                   // minus Korrekturfaktor
  //humidity = airSensor.getHumidity();
  //temperaturbmp=bmp_sensor.getTemperature();
  //temperaturhdc=hdc.getTemperature();
  temperature = hdc.getTemperature();
  humidity = hdc.getHumidity();
  pressure = bmp_sensor.getPressure() / 100;
  lux = tsl.getIlluminance();
  uv = veml.getUvIntensity();
  dez = getSoundValue();
  CO2 = airSensor.getCO2();
  pm10 = SDS.getPm10();
  pm25 = SDS.getPm25();
  psea = pressure + 100 / 8.5; // Umrechnung auf Meereshöhe


  if (debug) {

    Serial.print("Temperatur "); Serial.println(temperature);
    Serial.print("Temperatur BMP "); Serial.println(temperaturbmp);
    Serial.print("Temperatur Airsensor "); Serial.println(temperatursdc);
    Serial.print("Feuchte "); Serial.println(humidity);
    Serial.print("Luftdruck "); Serial.println(pressure);
    Serial.print("Helligkeit "); Serial.println(lux);
    Serial.print("UV "); Serial.println(uv);
    Serial.print("Lautstärke "); Serial.println(dez);
    Serial.print("PM2,5 "); Serial.println(pm25);
    Serial.print("PM10 "); Serial.println(pm10);
    Serial.print("uakku:"); Serial.println(uAkku);
    Serial.print("CO2 "); Serial.println(CO2);
    Serial.print("GPS-Status: "); Serial.println(gpsStatus);
    Serial.print("SDS-Status: "); Serial.println(sdsStatus);
    if (gpsStatus) {
      Serial.print("Breite: "), Serial.println(lat);
      Serial.print("Länge: "), Serial.println(lon);
    }
    Serial.println();


  }
  counter++;
  //display.clearDisplay;
  switch (counter) {
    case 1:
      printOnDisplay("Temperatur", String(temperature), "*C", "rel. Luftfeuchte", String(humidity), "%");
      break;
    case 2:
      printOnDisplay("Luftdruck", String(pressure), "hPa", "Auf Meeresh.", String(psea), "hPa");
      break;
    case 3:
      printOnDisplay("Helligkeit", String(lux), "lux", "UV-Intensitaet", String(uv), "uW/cm2");
      break;
    case 4:
      printOnDisplay("PM10", String(pm10), "ug/m3", "PM2.5", String(pm25), "ug/m3");
      break;
    case 5:
      printOnDisplay("Lautst.", String(dez), "dBa", "GPS", String(gpsStatus) , "");
      break;
    case 6:
      printOnDisplay("CO2", String(CO2), "ppm", "Temp.SCD", String(temperatursdc) , "C");
      break;
    case 7:
      printOnDisplay("Akkusp.", String(uAkku), "V", "Ladestrom", String(isolar), "mA");
      break;
    case 8:
      printOnDisplay("Breite ", String(lat), "°", "Länge ", String(lon), "°");
      counter = 0;    // Zähler wieder zurücksetzen
      break;

  }

  //os_setTimedCallback(&displayjob, os_getTime() + sec2osticks(DISPLAY_IN
  os_setTimedCallback(&displayjob, os_getTime() + sec2osticks(DISPLAY_INTERVAL), update_display);


}




void onEvent (ev_t ev) {
  Serial.print(os_getTime());
  Serial.print(": ");
  switch (ev) {
    case EV_SCAN_TIMEOUT:
      Serial.println(F("EV_SCAN_TIMEOUT"));
      break;
    case EV_BEACON_FOUND:
      Serial.println(F("EV_BEACON_FOUND"));
      break;
    case EV_BEACON_MISSED:
      Serial.println(F("EV_BEACON_MISSED"));
      break;
    case EV_BEACON_TRACKED:
      Serial.println(F("EV_BEACON_TRACKED"));
      break;
    case EV_JOINING:
      Serial.println(F("EV_JOINING"));
      break;
    case EV_JOINED:
      Serial.println(F("EV_JOINED"));

      // Disable link check validation (automatically enabled
      // during join, but not supported by TTN at this time).
      LMIC_setLinkCheckMode(0);
      break;
    case EV_RFU1:
      Serial.println(F("EV_RFU1"));
      break;
    case EV_JOIN_FAILED:
      Serial.println(F("EV_JOIN_FAILED"));
      break;
    case EV_REJOIN_FAILED:
      Serial.println(F("EV_REJOIN_FAILED"));
      break;
      break;
    case EV_TXCOMPLETE:
      Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)"));
      if (LMIC.txrxFlags & TXRX_ACK)
        Serial.println(F("Received ack"));
      if (LMIC.dataLen) {
        Serial.println(F("Received "));
        Serial.println(LMIC.dataLen);
        Serial.println(F(" bytes of payload"));
      }
      // Schedule next transmission
      os_setTimedCallback(&sendjob, os_getTime() + sec2osticks(TX_INTERVAL), do_send);
      break;
    case EV_LOST_TSYNC:
      Serial.println(F("EV_LOST_TSYNC"));
      break;
    case EV_RESET:
      Serial.println(F("EV_RESET"));
      break;
    case EV_RXCOMPLETE:
      // data received in ping slot
      Serial.println(F("EV_RXCOMPLETE"));
      break;
    case EV_LINK_DEAD:
      Serial.println(F("EV_LINK_DEAD"));
      break;
    case EV_LINK_ALIVE:
      Serial.println(F("EV_LINK_ALIVE"));
      break;
    default:
      Serial.println(F("Unknown event"));
      break;
  }
}

SDS011 my_sds(Serial2);


float getSoundValue() {
  float v = analogRead(soundmeterpin) * (3.3 / 1024.0);
  float decibel = v * 50;
  return decibel;
}

//--------------- Hauptroutine do_sebd -----------
//------------------------------------------------

void do_send(osjob_t* j) {
  // Check if there is not a current TX/RX job running
  if (LMIC.opmode & OP_TXRXPEND) {
    Serial.println(F("OP_TXRXPEND, not sending"));
  } else {

    if (sat) {
      // Each provides methods to examine its current value, sometimes in multiple formats and units. Here’s a complete list:
      // Hier könnte ein nochmaliger verkürzter Aufruf der GPS-Routine stehen um die Orts- und zeit-Daten zu aktualisieren

      Serial.println(gps.location.lat(), 6); // Latitude in degrees (double)
      Serial.println(gps.location.lng(), 6); // Longitude in degrees (double)
      Serial.print(gps.location.rawLat().negative ? "-" : "+");
      Serial.println(gps.location.rawLat().deg); // Raw latitude in whole degrees
      Serial.println(gps.location.rawLat().billionths);// ... and billionths (u16/u32)
      Serial.print(gps.location.rawLng().negative ? "-" : "+");
      Serial.println(gps.location.rawLng().deg); // Raw longitude in whole degrees
      Serial.println(gps.location.rawLng().billionths);// ... and billionths (u16/u32)
      Serial.println(gps.date.value()); // Raw date in DDMMYY format (u32)
      Serial.println(gps.date.year()); // Year (2000+) (u16)
      Serial.println(gps.date.month()); // Month (1-12) (u8)
      Serial.println(gps.date.day()); // Day (1-31) (u8)
      Serial.println(gps.time.value()); // Raw time in HHMMSSCC format (u32)
      Serial.println(gps.time.hour()); // Hour (0-23) (u8)
      Serial.println(gps.time.minute()); // Minute (0-59) (u8)
      Serial.println(gps.time.second()); // Second (0-59) (u8)
      Serial.println(gps.time.centisecond()); // 100ths of a second (0-99) (u8)
      Serial.println(gps.speed.value()); // Raw speed in 100ths of a knot (i32)
      Serial.println(gps.speed.knots()); // Speed in knots (double)
      Serial.println(gps.speed.mph()); // Speed in miles per hour (double)
      Serial.println(gps.speed.mps()); // Speed in meters per second (double)
      Serial.println(gps.speed.kmph()); // Speed in kilometers per hour (double)
      Serial.println(gps.course.value()); // Raw course in 100ths of a degree (i32)
      Serial.println(gps.course.deg()); // Course in degrees (double)
      Serial.println(gps.altitude.value()); // Raw altitude in centimeters (i32)
      Serial.println(gps.altitude.meters()); // Altitude in meters (double)
      Serial.println(gps.altitude.miles()); // Altitude in miles (double)
      Serial.println(gps.altitude.kilometers()); // Altitude in kilometers (double)
      Serial.println(gps.altitude.feet()); // Altitude in feet (double)
      Serial.println(gps.satellites.value()); // Number of satellites in use (u32)
      Serial.println(gps.hdop.value()); // Horizontal Dim. of Precision (100ths-i32)
    }
    if (sd) {
      // Abspeichern der Umweltdaten
      myFile = SD.open(fileName, FILE_WRITE);
      myFile.print("Neu:");
      myFile.print(",");
      myFile.print(nr);
      myFile.print(",");
      myFile.print(temperature);
      myFile.print(",");
      // myFIle.println(timestamp)
      // zweiter Messwert
      //myFile.print(HUMI_ID);
      myFile.print(humidity);
      myFile.print(",");
      //myFIle.println(timestamp)
      myFile.print(pressure);
      myFile.print(",");
      myFile.print(lux);
      myFile.print(",");
      myFile.print(uv);
      myFile.print(",");
      myFile.print(CO2);
      myFile.print(",");
      myFile.print(uAkku);
      myFile.print(",");
      if (gpsStatus) {
        myFile.print("GPS:");
        myFile.print(",");
        myFile.print(lat);
        myFile.print(",");
        myFile.print(lon);
        myFile.print(",");
        myFile.print(date);
        myFile.print(",");
        myFile.print(time);
        //myFile.print(",");  // laut dem Projekt Station ohne Internet kommt
        // nach dem letzten Messwert kein Komma !

      }



      // Datei nachher schliessen
      myFile.close();
      nr++;
      if (debug) {
        Serial.print("Nummer: ");
        Serial.println(nr);
      }
    }

    lpp.reset();
    lpp.addTemperature(1, temperature);
    lpp.addRelativeHumidity(2, humidity);
    lpp.addBarometricPressure(3, pressure);
    lpp.addLuminosity(4, tsl.getIlluminance());
    lpp.addLuminosity(5, veml.getUvIntensity());
    lpp.addAnalogInput(6, pm25);
    lpp.addAnalogInput(7, pm10);
    lpp.addAnalogInput(8, getSoundValue());
    lpp.addLuminosity(9, CO2);    // soll CO2 werden
    lpp.addAnalogInput(10, uAkku); // Platzhalter für Akkuspannung
    if (gpsStatus) {      // GPS-Übertragung nur wenn GPS-Empfang
    lpp.addGPS(1, lat, lon, alt);
    }
    // Prepare upstream data transmission at the next possible time.
    LMIC_setTxData2(1, lpp.getBuffer(), lpp.getSize(), 0);
    Serial.println(F("Packet queued"));
  }
  dauer = 2000; //kurz prüfen o noch GPS besteht
  gpsSearch(dauer);
  // Next TX is scheduled after TX_COMPLETE event.
}  //-------------------------- Ende von do_send ----


void setup() {

  Serial.begin(9600);
  Serial1.begin(9600);
  Serial2.begin(9600);
  sat = true; // GPS-Modul aktiv
  sd = true; //abspeichern auf SD-Karte
  sdsStatus = 0;   //SDS aus für den  Anfang
  dispStatus = 1;  // Anzeige an
  pinMode(8, OUTPUT); // eingebaute Grüne LED
  Wire.begin();
  
  delay(2000);
  if (airSensor.begin() == false)
  {
    while (1)
      Serial.println("Kein SCD30");
    ;
  }

  Serial.println("Setup beginnt");

  display.begin(SSD1306_SWITCHCAPVCC, 0x3D);
  display.setCursor(0, 0);
  display.setTextSize(2);
  display.setTextColor(WHITE, BLACK);
  display.clearDisplay();
  //delay(1000);
  zeit (100);
  display.println("mobil.Cayn");
  display.println("   Tiger");
  display.println();
  display.println(" V 0.93");
  display.display();

  zeit(9900);
  display.clearDisplay();
  delay(3000);

  dauer = 39000;  //39 Sekunden zeit für die GPS-Suche
  if (sat) {
    gpsSearch(dauer);   //Satelitten suchen
  }

  if (sd) {     // Nur wenn SD-Modus gewählt
    //--------------------Speichern auf SD----------------

    // Starten der SD-Bee
    SD.begin(28);

    // see if the card is present and can be initialized:
    if (!SD.begin(chipSelect)) {
      Serial.println("Card failed, or not present");
      // don't do anything more:
      while (1);
    }
    // Öffnen der Datei auf der SD-Karte
    myFile = SD.open(fileName, FILE_WRITE);
    myFile.close();
  }
  //---------------------------------------------------


  //  Serial.println("Nach Displayroutine");
  //void statusGreen();


  //------------------------Sensoren initialisieren --
  bmp_sensor.begin();
  hdc.begin();
  tsl.begin();
  veml.begin();
  
  initLora();

}  // ---------------------------- Ende von Setup -----------------------------



void loop() {

  os_runloop_once();

}