Hirdetés

Keresés

Új hozzászólás Aktív témák

  • Blasius

    tag

    válasz vargalex #19710 üzenetére

    Na, tálalhatóbb formába hoztam a kódot. Íme:

    const byte numChars = 128;
    char receivedChars[numChars];
    bool newData = false;

    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
      Serial.println("<Johet>");
    }

    void loop() {
      // put your main code here, to run repeatedly:
      recvWithStartEndMarkers();
      showNewData();
      }

    void showNewData() {
        if (newData == true) {      
        Serial.print("new data came:");
        Serial.println(receivedChars);
        newData = false;
        }
    }

    void recvWithStartEndMarkers() {
        static boolean recvInProgress = false;
        static byte ndx = 0;
        static byte ndxmea = 0;
        byte endKa = 0x0a;
        byte startKa = 0x24;
        byte starKa = 0x2a;
        byte nmea = 0x00;
        char rc;
        char nmeaRd[2];
        long nmeaRdL;
        bool inhibi = false;
        while (Serial.available() > 0 && newData == false) {
            rc = Serial.read();
            if (recvInProgress == true) {
                if (rc != endKa) {//delay(2);//?????????????????????????????????????????????????????????????????
                if (inhibi == true) {nmeaRd[ndxmea]=rc; ndxmea++;}
                  else if (rc == starKa) {inhibi = true;}
                  else if (inhibi == false){nmea ^=rc; receivedChars[ndx] = rc; ndx++;
                    //delay(1);//?????????????????????????????????????????????????????????????????
                    if (ndx >= numChars) {ndx = numChars - 1;}
                    }
                  }
                if (rc==endKa) {
                  nmeaRd[2] = '\0';
                  char * pEnd;
                  nmeaRdL = strtol(nmeaRd, &pEnd, 16);
                  if (nmeaRdL==nmea){receivedChars[ndx] = '\0';} // terminate the string
                  else {memset(receivedChars, '0', 6); receivedChars[7] = '\0';}             
                  recvInProgress = false;
                  ndx = 0;
                  ndxmea = 0;
                  newData = true;
                  nmea =0;
                  inhibi=false;
                }
            }
            else if (rc == startKa) {recvInProgress = true;}
        }
    }

    A második függvényben lévő késleltetések (...delay(x)/???...) nélkül a kód nem megy rendesen. Viszont, ahogy Aryes tippelte, a késleltetéssel jól megy. Ha késleltetések helyett sorosra írás lenne akkor is menne jól. Hát, kicsit tákolt, de megy. Gondolom erre mondják hogy nem egy robosztus kód :B. De most már kíváncsi vagyok hogy mi lehet ennek a furcsa viselkedésnek az oka :F .
    (nmea ...^=rc... az egyfajta crc számítás. A startKa karakter utáni karakterekre kell számolni. Aztán a soroson jön egy * (starKa), egy byte két karakter hex ascii-ként (00-FF, ez a crc) majd egy 0x0a karakter (sorvég). Ha a számolt és fogadott crc egyezik, akkor kiírja sorosra ami jött ahogy van. Ha a crc nem stimmel akkor kinullázza az első pár karaktert.)
    Ez egy rendes arduino unon fut (atmega chip).

  • Blasius

    tag

    válasz Aryes #19704 üzenetére

    Igen, egy delay(5) segített. Még egy másik helyen a kódban előfordult egy hasonló eset. Azta... itt ilyenek vannak?

    @Janos250
    volatile char receivedChars[numChars]; el nem fordult le. (A volatile nem tudom pontosan mit csinál).

    A kód soros partról olvas. Van egy függvény ami karakterenként beolvassa ami a soros porton van. Ezeket hozzá csapja char receivedChars[numChars] -hoz (még néhány más dolog is történik, crc számítás stb) Ha jött egy 0x0a a soroson, az adat fogadás befejezettnek tekintett, és a függvény egy boolt átvált igazról hamisra. Egy másik függvény kezd valamit a beolvasott receivedCharsal, majd visszaváltja a boolt. A második függvénynél reklamált a fordító a volatile miatt. A hármas példa alapján indultam el. https://forum.arduino.cc/t/serial-input-basics-updated/382007

  • Blasius

    tag

    Sziasztok,

    Nagyon különös problémával találkoztam. Nézzétek meg az alábbi kódrészletet. Ha a kódot úgy futtatom hogy a soroson író részeket kikommentelem, "nmea" nem számolódik jól. Ha a sorosra írás nincs kikommentelve, akkor "nmea" jól számolódik :Y . Erre nem tudok gombot varrni. Jópár órám ráment mire rájöttem hogy ezzel van a hiba... Van valakinek esetleg ötlete hogy mi történik itt?

    ...
            else if (inhibi == false){nmea ^=rc; receivedChars[ndx] = rc; ndx++;
                Serial.print(" nmea in calc ");
                Serial.println(nmea, HEX);
                Serial.print(" inhibi in nmeabuild: ");
                Serial.println(inhibi);
                Serial.print(" rc recorded ");
                Serial.println(rc);
                 if (ndx >= numChars) {ndx = numChars - 1;}
                 }
    ...

    A kódrészlet egy függvény része.
    Az érintett változók a függvényen belül vannak definiálva a következõképpen:

        bool inhibi = false;
        byte nmea = 0x00;
        char rc;
        static byte ndx = 0;

    Kivéve ez, ami a kód legelején van, mert máshol is elérhetõ kell hogy legyen:

    char receivedChars[numChars];

Új hozzászólás Aktív témák