tweede serieele poort d.m.v. SoftwareSerial.h

Arduino specifieke Software
Berichten: 17
Geregistreerd: 06 Feb 2013, 19:30

Re: tweede serieele poort d.m.v. SoftwareSerial.h

Berichtdoor retlawrobbe » 21 Feb 2013, 16:14

Na heel wat zoekwerk om twee GPSen aan te sluiten op een arduino is er volgende oplossing uit de bus gekomen.
Probleem 1. Om twee GPSen te kunnen uitlezen is er in principe een tweede serieele poort nodig , hiervoor kan een tweede serieele SOFTWARE poort
bijgemaakt worden , volgens de testen welke ik gedaan heeft deze Software seriepoort geen problemen om karakters binnen te lezen zolang
de baudrate beperkt blijft tot 9600 en het aantal karakters beperkt is tot 64 , vanaf het 65ste begint het probleem,
65 wordt gelezen 66 komt niet voor 67 wordt gelezen 68 verdwijnt enz, enz,
De oplossing om toch twee GPSen uit te lezen (weliswaar niet tegelijkertijd) heb ik gevonden in het gebruik van een electronische switch
SCL4016BE deze wordt aangestuurd met twee arduino poorten welke softwarematig wisselen tussen de GPS in het model
en deze in het basis station.
Hierdoor is nu mogelijk om beide GPSen uit lezen met 38400 baud en een rate snelheid van 10Hz.
Het programma blijft in een while loop tot wanneer de benodigde info strings binnen zijn waarbij na verwerking van de gegevens de poorten op
de electronische switch omgeschakeld worden naar de andere GPS.

Code: Alles selecteren
void getGps(){ //---START getGpsData ---------------------------------
 
   GPGGA = false;   GPRMC = false;   
   switch (GPS_use) {
    case GPS_earth_only:
      Init_GPS(HIGH,LOW); // earth ON , air OFF
      break;
    case GPS_air_only:
      Init_GPS(LOW,HIGH); // earth OFF , air ON
      break;
    case GPS_earth:
      GPS_use = GPS_air;          // from EARTH TO AIR
      Init_GPS(LOW,HIGH);         // earth OFF , air ON
      break;
    case GPS_air:
      GPS_use = GPS_earth;        // from AIR to EARTH
      Init_GPS(HIGH,LOW);         // earth ON , air OFF
      break; 
  }
   getGPSdata();
   store_GPS_inf();
   
}//END getGpsData  ---------------------------------

//--- START INIT GPS -------------------------
void Init_GPS(boolean earth,boolean air) {
 
   digitalWrite(Earth_Sw_pin,LOW);
   digitalWrite(Air_Sw_pin,LOW) ;
   
   digitalWrite(Earth_Sw_pin,earth);
   digitalWrite(Air_Sw_pin,air) ;  delay(5);

//--- END INIT GPS ----------------------------

void getGPSdata(){ //---START getGpdata ---------------------------------
  checking = false;
  checksum = 0;  checkHex1 = 0;  checkHex2 = 0;
  checkDigit = 0;
  GPS_info_Indx = 0;  // resetting all variables
  long timeoutGPS = millis()+ 100;
   
 while (  (GPGGA == false) || (GPRMC == false ) ) {
   while (Serial.available()) {
    // When there's no data available this function quits.
    GPS_char = Serial.read(); // get a single character
 
    switch (GPS_char) { // decide based on the character received
     case 10: // 33=! uitroepteken      10: // ASCII line feed 'LF'
      continue;  // just ignore it, restart at while()
    case 13: // 34=" dubbel quote      13: // ASCII carriage return 'CR'
      // This is the end of the sentence. Process the entire
      // sentence and restart for the next sentence.
      if (isValid()) { // see function below
       // Serial.print("Valid:___");
       //    printGPS_info(GPS_info, GPS_info_Indx);
        Valid_GPS_info();
        GPS_info_Indx = 0; checksum = 0;
        break; //continue;
      } else {
          //  Serial.print("INVALID:_");
          //   printGPS_info(GPS_info, GPS_info_Indx);
        GPS_info_Indx = 0;  // restart the sentence position
        checksum = 0;  // reset the checksum
      }
      continue; // go back to while()
    case 42: // ASCII asterisk '*'
      // Stop adding characters to the sentence and instead
      // collect the check digit information.
      checking = false; // don't add remaining characters to 'checksum'
      checkDigit = 1; // next character will be first check digit
      continue;
    }
    if (checkDigit == 1) {
      checkHex1 = GPS_char;
      checkDigit++; // next character will be checkDigit 2
    } else {
       if (checkDigit == 2) {
         checkHex2 = GPS_char;
         checkDigit = 0; // no more check digits
       } else { // Append the current character to the sentence
         GPS_info[GPS_info_Indx++] = GPS_char; }
    }
   
    if (GPS_info_Indx == GPS_info_Size){
      // Check we haven't overrun the sentence array, if so, restart
      GPS_info_Indx = 0; checksum = 0;
      continue;  }
     
    if (checking) {checksum ^= GPS_char;}  // X-OR character with previous X-OR sum
   
    if (GPS_char == 36) {checking = true;} // ASCII Dollar '$'
      // Leading $ is not included in checksum calculation, but
      // does indicate when to start calculating the checksum.
   } // end while available
   
   if ( millis() > timeoutGPS ) {
  //walter    if (digitalRead(Earth_Sw_pin)) { Reset_Earth_par();} //Reset Initialize Earth GPS parameters
  //walter    if (digitalRead(Air_Sw_pin)  ) { Reset_Air_par();  } //Reset Initialize Air GPS parameters 
     break;
   }
 } // end while GPS_avail
}// end void getGPSext

// END getGPSdata --------------------------------------------------


// START Function isValid-------------------------------------------
boolean isValid(){
// Compares the calculated [chechsum] to the check digits [checkHex1, checkHex2]
// supplied by the GPS. If the calculation matches the sentence is valid.
  return (charToHex(checkHex1) == (checksum >> 4) && charToHex(checkHex2) == (checksum & 0x0F));
}

// END Function isValid --------------------------------------------

// START Function charToHex-----------------------------------------
byte charToHex(char in){
// Converts a hexadecimal character
// {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}
// into its numeric equivalent
// { 0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15}
  if (in >= '0' && in <= '9') return in - '0';
  if (in >= 'A' && in <= 'F') return in - 'A' + 10;
  return 0;
}
// ENDT Function charToHex-----------------------------------------

// START Valid_GPS_info ------------------------------------------
 void Valid_GPS_info(){
  boolean applic = false;
   
   for (byte i=0;i<GPS_info_Indx;i++){
     if ( GPS_info[i] == 36){ // If  $ = 36 search valable data GGA or RMC
       if ( GPS_info[i+4] == 'G') {
         GPGGA = true; applic = true;
         GGA_RMC_Indx = GGA_info;
         indxcomma    = GGAcomm;
       } else { 
          if ( GPS_info[i+4] == 'M') {
            GPRMC = true; applic = true;
            GGA_RMC_Indx = RMC_info;
            indxcomma    = RMCcomm;
         //   Serial.print("__RMC__");Serial.print(GPS_use);Serial.print("__");
          }
       }
     } // if check 36 = $ sign
     if ( applic ) {
       GGA_RMC_info[GGA_RMC_Indx] = GPS_info[i];
       if (GGA_RMC_info[GGA_RMC_Indx] == ',' ) {
         commaindx[indxcomma] = GGA_RMC_Indx;
         indxcomma ++;
       }
       GGA_RMC_Indx++;
     } 
   } // end for 
   
 
} // end void
// END Valid_GPS_info ------------------------------------------


Probleem 2. de NEO-6M GPS welke ik in mijn bezit heb heeft wel een batterijtje aan boord om de ingestelde gegevens vast te houden maar aangezien er
waarschijnlijk (blijkbaar) een fout in het circuit zit blijft de spanning van de ingebouwde lithium batterij niet behouden.
zie INFORMATIE
aangezien de layout van mijn GPS niet hetzelfde is ga ik er geen soldeerwerk op uitvoeren.
Het probleem ,de default Rate waarde staat op 1Hz (=1 sec) en om sneller informatie binnen te krijgen zou deze op 10Hz moeten staan.
Dit probleem is opgelost door de Hex string naar de GPS te zenden bij opstarten van het grondstation.
String send for RATE(rates) 10Hz HEX : B5 62 6 8 6 0 64 0 2 0 1 0 7B 16 B5 62 6 8 0 0 E 30
ter informatie : String send for a Baudrate of 38400 Baud
HEX : B5 62 6 0 14 0 1 0 0 0 D0 8 0 0 0 96 0 0 7 0 7 0 0 0 0 0 97 A8 B5 62 6 0 1 0 1 8 22
Deze strings heb ik bekomen door met het U-center programma de setup strings te laten sturen waarbij ik deze met een tweede com poort
gecapteerd heb

Advertisement

Gebruikers-avatar
Berichten: 116
Geregistreerd: 23 Dec 2011, 00:11
Woonplaats: Enschede

Re: tweede serieele poort d.m.v. SoftwareSerial.h

Berichtdoor bigred » 21 Feb 2013, 20:11

Al eens gekeken naar de arduino mega, die is wel wat duurder maar je hebt direct 4 hardware serial poorten ter beschikking.
Op ebay zijn ook imitaties te koop voor een redelijke prijs.

Berichten: 17
Geregistreerd: 06 Feb 2013, 19:30

Re: tweede serieele poort d.m.v. SoftwareSerial.h

Berichtdoor retlawrobbe » 21 Feb 2013, 20:30

Inderdaad met de mega zijn "die" problemen van de baan, o.a. ook het probleem van max +/-19000 bytes gecompileerd programma te kunnen maken dit door
de beperkte grootte van SRAM.
Ik heb bepaalde delen ( nice to have zoals de GPS tijd en datum ) uit het programma weggelaten om een een werkbaar programma over te houden nl. meten van hoogte, snelheid, afstand , externe batterij controle, richting bepalen waarin men moet gaan om een verloren ( crash ) model terug te vinden, bijhouden van de laatste positie.
De keuze voor een ARDUINO Fio is voornamelijk omdat hierop direct een XBEE kan geplaatst worden voor draadloze communicatie.

Vorige

Terug naar Arduino software

Wie is er online?

Gebruikers in dit forum: erapibetem en 21 gasten