For-Schleife läuft ohne printf nicht durch...


  • Mod

    Woah! entscheide dich mal, ob du C oder C++ machst. Kein Wunder, dass du da irgendwo undefiniertes Verhalten bekommst, denn Mischung von C und C++ geht praktisch immer schief.

    Das ist immer noch kein vollständiges Programm. Lies dir mal den dritten Link in meiner Signatur durch und halte dich da dran.

    Verdächtig sind hier die Zeilen -50 bis 80, ganz besonders stechen folgende heraus:
    80: Irgendwo fehlt eine Klammer
    6: Höchst ungewöhnlicher Umgang mit einem vector
    9: Häh?
    15: Merkwürdiger Kommentar
    17: Sinn?
    21-28: sinnlos?
    29: Sinn?
    31: Mathematisch korrekt?
    36-60: Oh, ein for-switch Idiom als if getarnt!
    64-69: Richtig geklammert?
    69-75: sinnlos?



  • pet wird am anfang inkrementiert.
    Rhetorische Frage:
    messwerte ist also ein double messwerte[devInfo.numberOfChannels][ARRAYSIZE+1] ?

    Und ich hatte recht: der Code wurde superverkompliziert. Versuch da nochmal ein paar logische Umformungen zur Vereinfachung durchzuführen.



  • SeppJ schrieb:

    Woah! entscheide dich mal, ob du C oder C++ machst. Kein Wunder, dass du da irgendwo undefiniertes Verhalten bekommst, denn Mischung von C und C++ geht praktisch immer schief.

    Das ist immer noch kein vollständiges Programm. Lies dir mal den dritten Link in meiner Signatur durch und halte dich da dran.

    Verdächtig sind hier die Zeilen -50 bis 80, ganz besonders stechen folgende heraus:
    80: Irgendwo fehlt eine Klammer
    6: Höchst ungewöhnlicher Umgang mit einem vector
    9: Häh?
    15: Merkwürdiger Kommentar
    17: Sinn?
    21-28: sinnlos?
    29: Sinn?
    31: Mathematisch korrekt?
    36-60: Oh, ein for-switch Idiom als if getarnt!
    64-69: Richtig geklammert?
    69-75: sinnlos?

    Okay, legen wir mal los:
    80 - Nein, es wirkt vielleicht so, weil es unkonsistent eingerückt war. Ich hab das mal in meinem Code verbessert. Mit kdevelop sehe ich beim anklicken eienr Klammer immer farblich zwischen den Bereich zwischen den Klammern hervorgehoben. Von daher kann ich sehr schnell und genau sehn, wozu jede Klammer gehört.
    6 - Das entspringt dem Beispielcode des Sensorherstellers aus der OakLib.
    9 - net = Anzahl der Gesamtmesswerte, damit ich prüfen kann, ob nach evtl. 30000 Messungen der Code abricht. Ist mehr ne Hilfestellung. pet = heir triffts die Bezeichnung Arrayposition eher. Die Größe ist als Preprozessor-Definition festgelegt. pet durchwandert das Array zur Auffüllung des Arrays.
    15 - naja, hier gehts um die Channels des Sensors. Channel 0 = frame in Sekunden. sollte hier i=1 sein, wird die erste Spalte des Arrays nicht gefüllt. Ich habe mich inzwischen entschieden, alle Spalten zu füllen und lediglich die Sekunden nicht auszuwerten.
    17 - Ich habs nicht geschafft, das i der For-Schleife, in der wir uns befinden, auszulesen. Statt dessen bekomme ich als i immer den chanInfo.channelName.c_str() ausgegeben. Den Grund konnte ich nicht finden.
    21-28 - stimmt, hab ich gelöscht. Stammte noch aus dem Beispielcode, sonstige Codefragmente darin hatte ich wegrationalisiert, daher nun kein Sinn mehr.
    29 - auch hier muss ich dir Recht geben. Hab die Abfrage gelöscht.
    31 - japp, hab ich extra getestet, da ich hiermit unlesbare Sensorwerte in verständliche Werte konvertiere.
    36-60 - hast ja wieder mal recht. Das war mir zwischendrin auch aufgefallen, aber ich hielt es vorläufig nicht relevant genug, es zu ändern, da ich noch nicht sicher war, ob der Code bestehen bleibt.
    69-75 - Warum sinnlos? Ich möchte ja wissen, ob der Code hier ankommt. Das diente der Fehlersuche. die Auswertungs des Arrays habe ich wieder gelöscht, weil sie nicht funktioneirte - wie ich hiermit rausgefunden habe, liegt das daran, dass ich hier gar nicht erst ankomme, wenn ich den Zeilenumbruch in der printf-Anweisung lösche.

    So viel Mühe du dir bei der Suche nach potentiellen Fehlern gemacht hast...besteht das Problem leider immer noch. Ich schreib mal grade die If-Abfragen zum Switch um und dann poste ich den bereinigten Code.

    Die Entscheidung, ob ich C oder C++ schreibe, liegt nicht bei mir. Ich kann kein C++...und kenne nur Basics in C. Aber die OakLib mit dem Beispielcode basiert auf C++. Da C wohl vollständig kompatibel zu C++ sein soll, müsste es also eigentlich keine Probleme geben - zumindest nich bei so 'einfachen' Anwendungsfällen.



  • So, hier der etwas sauberere Code, der jedoch noch immer noch den selben Fehler enthält:

    for (;;)			// Starten des Auslesens
    {
    
      usleep(SLEEPVALUE);
      std::vector<int> values;
      CHECK_OAK_CALL(readInterruptReport(deviceHandle, values));
    
      net++;	// Gesamtdurchläufe
      pet++;	// Arrayposition
    
    //  printf ("\nn: %d\t", net);
    
    				// Auslesen aller Kanäle
      for (int i = 0; i < devInfo.numberOfChannels; i++) // i=0 wenn man den Sekundenwert anzeigen möchte...
      {
        j++;
        double neuwert;
        double multiplikator;
        ChannelInfo& chanInfo = channelInfos[i];
        neuwert = values[i];
        multiplikator = pow(10.00, chanInfo.unitExponent);
    
    				// Umrechnung der Werte und Abspeichern im Array
    switch (i)
    {
            case 0:
                messwerte[i][pet] = neuwert;
                break;
            case 1:
                messwerte[i][pet] = neuwert;
                break;
    	case 2:
                messwerte[i][pet] = neuwert/M_PI * 180 * multiplikator;
    //	    printf(" \n", messwerte[i][pet]);
                break;
            case 3:
                messwerte[i][pet] = neuwert/M_PI * 180 * multiplikator;
                break;
            default:
                printf("Fehler beim Switch");
                break;
    }
    
    				  // Zählvariable zurücksetzen und Array auswerten
        if (pet == ARRAYSIZE)
        {
          pet = 0;
          for (int i=0; i<devInfo.numberOfChannels-3; i++)
          {
    	printf("check!");
          }
        }
      }
    }
    

    Wenn ich die Werte im Switch direkt ausgebe, funktionierts:

    switch (i)
    {
            case 0:
                messwerte[i][pet] = neuwert;
    	    printf("0: %lf\t", messwerte[i][pet]);
                break;
            case 1:
                messwerte[i][pet] = neuwert;
    	    printf("1: %lf\t", messwerte[i][pet]);
                break;
    	case 2:
                messwerte[i][pet] = neuwert/M_PI * 180 * multiplikator;
    	    printf("2: %lf\t", messwerte[i][pet]);
    //	    printf(" \n", messwerte[i][pet]);
                break;
            case 3:
                messwerte[i][pet] = neuwert/M_PI * 180 * multiplikator;
    	    printf("3: %lf\n", messwerte[i][pet]);
                break;
            default:
                printf("Fehler beim Switch");
                break;
    }
    
    0: 133.000000	1: 9856.000000	2: 89.570492	3: 179.834263
    0: 470.000000	1: 9746.000000	2: 89.610599	3: 179.679565
    0: 490.000000	1: 9790.000000	2: 89.513196	3: 180.097824
    0: 510.000000	1: 9746.000000	2: 89.513196	3: 179.943125
    0: 530.000000	1: 9842.000000	2: 89.570492	3: 180.097824
    0: 550.000000	1: 9746.000000	2: 89.438712	3: 179.903018
    0: 570.000000	1: 9834.000000	2: 89.347039	3: 180.000421
    

    usw.

    In diesem Fall kann ich den Zeilenumbruch auch weglassen und ich bekomme problemlos eine Ausgabe.

    Was mich jedoch verwirrt ist die Tatsache, dass in den ersten beiden Spalten des Arrays Werte gespeichert sind, die länger als 8 Zeichen sind. Der Dateityp double sollte doch 8 Stellen lang wein, oder?!

    double messwerte[4][ARRAYSIZE];
    

  • Mod

    Cysign schrieb:

    80 - Nein, es wirkt vielleicht so, weil es unkonsistent eingerückt war. Ich hab das mal in meinem Code verbessert. Mit kdevelop sehe ich beim anklicken eienr Klammer immer farblich zwischen den Bereich zwischen den Klammern hervorgehoben. Von daher kann ich sehr schnell und genau sehn, wozu jede Klammer gehört.

    Das habe ich doch nicht von Hand gezählt, sondern ebenfalls von meiner IDE machen lassen. Folglich hast du einen anderen Code vorliegen als du uns gezeigt hast. Ich wiederhole noch einmal meinen dringenden Verweis auf den dritten Link in meiner Signatur. Ohne ausführbaren Code können wir dir nicht helfen, Fehler zu finden, die erst bei der Ausführung auftreten.
    Noch drei Bemerkungen:
    1. Da du eine exotische Bibliothek benutzt, wäre es gut, wenn du für uns die Aufrufe an diese Bibliothek ersetzt, z.B. den vector mit irgendwelchen Dummywerten füllst.
    2. Höchstwahrscheinlich liegt der Fehler sowieso ganz woanders. Was du beschreibst ist ein lupenreiner Fall von undefiniertem Programmverhalten. Es kann gut sein, dass die eigentliche Ursache lange vor dem gezeigten Codeabschnitt liegt. Daher ist es hochgradig wichtig, dass du bei der Erstellung eines ausführbaren Beispiels darauf achtest, dass der Fehler nach jeder Kürzung des Codes tatsächlich noch auftritt.
    3. Mit dem Code den du gezeigt hast, kann ich auch nicht mehr machen, als die verdächtigen Stellen zu markieren. Insgesamt habe ich mir schon Mühe dabei gegeben, kann aber aufgrund des fehlenden Kontextes nicht absolut sicher sein, ob es wirklich echte Fehler sind. Du solltest dir jedoch wirklich absolut sicher sein, dass es wirklich richtig ist, wenn du eine der von mir genannten Stellen für richtig erklärst. Deine Antwort kam dann doch ein bisschen schnell, ich denke, bei einigen Stellen hast du nicht ganz verstanden, was mich störte:

    80: Siehe oben
    6: Sicher? Ganz sicher? Es ist höchst ungewöhnlich und wäre kein gutes Zeichen für die Bibliothek. Wobei es durchaus viele schlechte Bibliotheken gibt, daher nicht ausgeschlossen, dass es so sein soll.
    9: Eine sich verändernde Arraygröße macht keinen Sinn. Die Beschreibung ist mindestens schlecht. Oder du hast etwas an deinem eigenen Code nicht verstanden. Außerdem: Ist net nicht gleich pet?
    15: Was ist denn die semantische Bedeutung von dem i? Diese scheint wild zu wechseln. Nenn die Variable mal nicht i, sondern gib ihr einen beschreibenden Namen. Dann wird entweder dem Leser klar, was du meinst, oder du merkst, dass da selber etwas nicht stimmt. Je nachdem, was richtig ist.
    17: Noch ein weitere Hinweis für undefiniertes Verhalten, wenn du dieses sinnlose j als Ersatz für i brauchst.
    31: Ok, glaube ich dir mal. Ich hoffe, du bist wirklich sicher, dass es richtig ist.
    64-69: Also soll die check-Schleife wirklich in dem Block zum if (pet == ARRAYSIZE) stehen?
    69: Wozu überhaupt die Schleife?

    P.S.: Bezüglich deines neuen Codes, habe ich nur kurz überflogen: Ich glaube du hast das mit dem for-switch nicht verstanden. Das war Sarkasmus. Ohne Sarkasmus gesagt: Das ist kompletter Unsinn, egal ob mit switch oder if.



  • Hmm...okay, vielleicht ist der komplette Code aussagekräftiger:

    /// \file  
    /// \date 2008-10-10
    /// \author Xavier Michelon, Toradex SA 
    ///  
    /// \brief Sample program for using Oak device in Linux
    
    #include "OakHidBase.h"
    #include "OakFeatureReports.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <string>
    #include <math.h>
    #include <unistd.h>
    
    #define SAMPLEDELAY 20		// Set Report- und Sample-Rate - 20 
    #define ARRAYSIZE 50		// Anzahl der Werte
    #define SLEEPVALUE 23000	// Sleeptime zwischen Messwerten - 25000 evtl. 	2300
    
    using namespace std;
    using namespace Toradex::Oak;
    int net = 0;			// Anzahl der Gesamtmessungen im kompletten Programmverlauf
    int pet = 0;			// Array-Position
    int arraysize = 0;
    
    // Number of Samples
    double messwerte[4][ARRAYSIZE]; // 0: Framenumber [s]	1: Acceleration [m/m²] 2: Zenith [grad] 3: Azimuth [grad]
    
    // define some local constants
    namespace {
       string const& kDefaultDevice("/dev/usb/hiddev0"); ///< Default device, if not specified as an argument
    }
    
    /// \brief wrapper function for error report that add file, line and function in which an error occured
    #define CHECK_OAK_CALL(status) checkOakCall(status, __FILE__, __LINE__, __FUNCTION__)
    
    //************************************************************************************************* 
    /// \brief Check the status code of a Oak library call. 
    ///
    /// If the status is not OK, this function display an error message to the standard error output
    /// then quit the application
    ///
    /// Note This function is not to be called directly, but via the CHECK_OAK_CALL macro that
    /// insert the line, file and function where the error occured
    ///
    /// \param[in] status the status code to check
    /// \param[in] file The file where the error occured
    /// \param[in] line The line number where the error occured
    /// \param[in] function The name of the function where the error occured
    //************************************************************************************************* 
    void checkOakCall(EOakStatus status, const char *file, int line, const char* function)
    {
       if (eOakStatusOK != status)
       {
          fprintf(stderr, "Error: %s in function %s (file %s, line %d)\n", getStatusString(status).c_str(), 
                  function, file, line);
          exit(1);
       }
    }
    
    //************************************************************************************************* 
    /// \brief The program entry point
    ///
    /// \param[in] argc The number of arguments of the program
    /// \param[in] argv The argument list of the program
    //************************************************************************************************* 
    int main(int argc, char **argv)
    {
      printf("\n \n \n");
      // if the device file is not provided as an argument, we use a default value
       std::string device(argc >= 2 ? argv[1] : kDefaultDevice);
    
       int deviceHandle;
       CHECK_OAK_CALL(openDevice(device, deviceHandle));
    
       // get the device informations
       DeviceInfo devInfo;
       CHECK_OAK_CALL(getDeviceInfo(deviceHandle, devInfo));
    
       // Set the report Mode
       CHECK_OAK_CALL(setReportMode(deviceHandle, eReportModeAfterSampling, true));
       EOakReportMode reportMode;
       CHECK_OAK_CALL(getReportMode(deviceHandle, reportMode, true));
    
       // Set the LED Mode
       CHECK_OAK_CALL(setLedMode(deviceHandle, eLedModeOff, true));
       EOakLedMode ledMode;
       CHECK_OAK_CALL(getLedMode(deviceHandle, ledMode, true));
    
       // Set the report rate
       CHECK_OAK_CALL(setReportRate(deviceHandle, SAMPLEDELAY, true));
       unsigned int reportRate;
       CHECK_OAK_CALL(getReportRate(deviceHandle, reportRate, true));
       printf("Report rate: %u\n", reportRate);
    
       // Set the sample rate
       CHECK_OAK_CALL(setSampleRate(deviceHandle, SAMPLEDELAY, true));
       unsigned int sampleRate;
       CHECK_OAK_CALL(getSampleRate(deviceHandle, sampleRate, true));
       printf("Sample rate: %u\n", sampleRate);
    
       // Retrieve Channel infos
       std::vector<ChannelInfo> channelInfos(devInfo.numberOfChannels);
       for (int i = 0; i < devInfo.numberOfChannels; i++)
       {
          ChannelInfo& chanInfo = channelInfos[i]; 
          CHECK_OAK_CALL(getChannelInfo(deviceHandle, i, chanInfo));
          printf("   Name: %s\n", chanInfo.channelName.c_str());
       }
    
    for (;;)			// Starten des Auslesens
    {
      usleep(SLEEPVALUE);
      std::vector<int> values;
      CHECK_OAK_CALL(readInterruptReport(deviceHandle, values));
    
      net++;	// Gesamtdurchläufe
      pet++;	// Arrayposition
    
    //  printf("Anzahl der Messungen: %d\t", net);
    
    				// Auslesen aller Kanäle
      for (int i = 0; i < devInfo.numberOfChannels; i++)
      {
        double neuwert;
        double multiplikator;
        ChannelInfo& chanInfo = channelInfos[i];
        neuwert = values[i];
        multiplikator = pow(10.00, chanInfo.unitExponent);
    
    				// Umrechnung der Werte und Abspeichern im Array
        switch (i)
        {
    	case 0:
    	      messwerte[i][pet] = neuwert;
    //	      printf("Ch0: %.0lf\t", messwerte[i][pet]);
    	      printf("%lf\t", neuwert);
    	      break;
    	case 1:
    	      messwerte[i][pet] = neuwert;
    //	      printf("Ch1: %.0lf\t", messwerte[i][pet]);
    	      printf("%lf\t", neuwert);
    	      break;
    	  case 2:
    	      printf("%lf\t", neuwert);
    	      messwerte[i][pet] = neuwert/M_PI * 180 * multiplikator;
    //	      printf("Ch2: %.2lf\t", messwerte[i][pet]);
    //	    printf(" \n", messwerte[i][pet]);
    	      break;
    	  case 3:
    	      printf("%lf \n", neuwert);
    	      messwerte[i][pet] = neuwert/M_PI * 180 * multiplikator;
    //	      printf("Ch3: %.2lf\n", messwerte[i][pet]);
    	      break;
    	  default:
    	      printf("Fehler beim Switch");
    	      break;
        }
    
    				  // Zählvariable zurücksetzen und Array auswerten
        if (pet == ARRAYSIZE)
        {
          pet = 0;
          for (int kanal=0; kanal<devInfo.numberOfChannels-3; kanal++)
          {
    	printf("\n	check!	\n\n");
          }
        }
      }
    }
    
        // Cleanup
      CHECK_OAK_CALL(closeDevice(deviceHandle));
      return 0;
    }
    

    Hierzu mal die Ausgabe beim Aufruf der makefile:

    cysign@hp-lubuntu:~/Dropbox/aeros/oak/kdevelop/src$ make
    g++ -DHAVE_CONFIG_H -I. -I..     -g -O2 -MT oaklinux.o -MD -MP -MF .deps/oaklinux.Tpo -c -o oaklinux.o oaklinux.cpp
    mv -f .deps/oaklinux.Tpo .deps/oaklinux.Po
    /bin/bash ../libtool --tag=CXX   --mode=link g++  -g -O2    -o oaklinux OakFeatureReports.o OakHidBase.o oaklinux.o  
    g++ -g -O2 -o oaklinux OakFeatureReports.o OakHidBase.o oaklinux.o
    

    Die Ausgabe lautet nun (Unveränderte Wiedergabewerte des Lib) :

    cysign@hp-lubuntu:~/Dropbox/aeros/oak/kdevelop/src$ ./oaklinux
    
    Report rate: 20
    Sample rate: 20
       Name: Frame Number [s]
       Name: Acceleration [m/s2]
       Name: Zenith [rad]
       Name: Azimuth [rad]
    664.000000	9768.000000	12559.000000	31399.000000 
    983.000000	9717.000000	12549.000000	31389.000000 
    1023.000000	9797.000000	12556.000000	31416.000000 
    1043.000000	9709.000000	12575.000000	31423.000000 
    1063.000000	9753.000000	12556.000000	31433.000000 
    1083.000000	9746.000000	12546.000000	31377.000000 
    1103.000000	9731.000000	12578.000000	31406.000000 
    1123.000000	9761.000000	12566.000000	31389.000000 
    1163.000000	9775.000000	12598.000000	31380.000000 
    1183.000000	9753.000000	12595.000000	31380.000000 
    1203.000000	9761.000000	12536.000000	31389.000000 
    1223.000000	9731.000000	12549.000000	31367.000000 
    1243.000000	9731.000000	12578.000000	31377.000000 
    1263.000000	9717.000000	12588.000000	31399.000000 
    1283.000000	9724.000000	12585.000000	31341.000000 
    1323.000000	9783.000000	12549.000000	31433.000000 
    1343.000000	9753.000000	12566.000000	31341.000000 
    1363.000000	9753.000000	12546.000000	31416.000000 
    1383.000000	9775.000000	12529.000000	31389.000000 
    1403.000000	9753.000000	12546.000000	31380.000000 
    1423.000000	9797.000000	12520.000000	31416.000000 
    1463.000000	9753.000000	12556.000000	31380.000000 
    1483.000000	9761.000000	12578.000000	31389.000000 
    1503.000000	9724.000000	12598.000000	31399.000000 
    1523.000000	9753.000000	12546.000000	31416.000000 
    1543.000000	9775.000000	12578.000000	31380.000000 
    1563.000000	9797.000000	12556.000000	31399.000000 
    1603.000000	9746.000000	12578.000000	31399.000000 
    1623.000000	9753.000000	12566.000000	31399.000000 
    1643.000000	9717.000000	12549.000000	31389.000000 
    1663.000000	9717.000000	12539.000000	31399.000000 
    1683.000000	9753.000000	12529.000000	31389.000000 
    1703.000000	9724.000000	12546.000000	31380.000000 
    1723.000000	9746.000000	12559.000000	31389.000000 
    1763.000000	9797.000000	12556.000000	31416.000000 
    1783.000000	9709.000000	12529.000000	31399.000000 
    1803.000000	9753.000000	12556.000000	31389.000000 
    1823.000000	9739.000000	12559.000000	31389.000000 
    1843.000000	9775.000000	12556.000000	31389.000000 
    1863.000000	9731.000000	12566.000000	31377.000000 
    1903.000000	9746.000000	12568.000000	31399.000000 
    1923.000000	9775.000000	12595.000000	31406.000000 
    1943.000000	9717.000000	12559.000000	31389.000000 
    1963.000000	9731.000000	12556.000000	31377.000000 
    1983.000000	9739.000000	12588.000000	31406.000000 
    2003.000000	9761.000000	12588.000000	31416.000000 
    2023.000000	9694.000000	12614.000000	31399.000000 
    15.000000	9797.000000	12568.000000	31446.000000 
    35.000000	9768.000000	12510.000000	31406.000000 
    55.000000	
    	check!	
    
    9746.000000	12585.000000	31377.000000 
    75.000000	9775.000000	12566.000000	31377.000000 
    95.000000	9775.000000	12566.000000	31380.000000 
    115.000000	9724.000000	12546.000000	31423.000000 
    155.000000	9761.000000	12566.000000	31380.000000 
    175.000000	9783.000000	12559.000000	31399.000000 
    195.000000	9761.000000	12559.000000	31406.000000 
    215.000000	9724.000000	12585.000000	31367.000000 
    235.000000	9761.000000	12536.000000	31367.000000 
    255.000000	9717.000000	12588.000000	31406.000000 
    295.000000	9739.000000	12566.000000	31399.000000 
    315.000000	9797.000000	12529.000000	31446.000000 
    335.000000	9739.000000	12595.000000	31341.000000 
    355.000000	9702.000000	12568.000000	31380.000000 
    375.000000	9768.000000	12536.000000	31377.000000 
    395.000000	9694.000000	12549.000000	31399.000000 
    415.000000	9761.000000	12539.000000	31389.000000 
    455.000000	9709.000000	12595.000000	31399.000000 
    475.000000	9709.000000	12539.000000	31389.000000 
    495.000000	9731.000000	12595.000000	31360.000000 
    515.000000	9775.000000	12539.000000	31433.000000 
    535.000000	9694.000000	12588.000000	31380.000000 
    555.000000	9739.000000	12575.000000	31416.000000 
    594.000000	9775.000000	12529.000000	31423.000000 
    615.000000	9709.000000	12549.000000	31399.000000 
    635.000000	9709.000000	12595.000000	31406.000000 
    655.000000	9775.000000	12546.000000	31389.000000 
    675.000000	9731.000000	12566.000000	31399.000000 
    695.000000	9702.000000	12595.000000	31367.000000 
    715.000000	9731.000000	12588.000000	31406.000000 
    755.000000	9790.000000	12527.000000	31433.000000 
    775.000000	9746.000000	12529.000000	31389.000000 
    795.000000	9753.000000	12529.000000	31399.000000 
    815.000000	9775.000000	12520.000000	31389.000000 
    835.000000	9768.000000	12536.000000	31399.000000 
    855.000000	9753.000000	12578.000000	31389.000000 
    895.000000	9739.000000	12566.000000	31380.000000 
    915.000000	9820.000000	12556.000000	31399.000000 
    935.000000	9731.000000	12529.000000	31350.000000 
    955.000000	9775.000000	12546.000000	31380.000000 
    975.000000	9753.000000	12595.000000	31416.000000 
    995.000000	9761.000000	12549.000000	31446.000000 
    1035.000000	9724.000000	12578.000000	31357.000000 
    1055.000000	9731.000000	12556.000000	31423.000000 
    1075.000000	9805.000000	12539.000000	31389.000000 
    1095.000000	9724.000000	12529.000000	31377.000000 
    1115.000000	9709.000000	12500.000000	31380.000000 
    1135.000000	9746.000000	12585.000000	31399.000000 
    1155.000000	9672.000000	12627.000000	31399.000000 
    1195.000000	9753.000000	12578.000000	31406.000000 
    1215.000000	
    	check!
    

    Welche IDE nutzt du denn, die dir die Klammerfehler anzeigt?
    Ich vermute, dass der Wurm im Datentyp steckt.
    Sollte ich das Array vielleicht mit "long double" erstellen?

    Die Arraygröße verändert sich nicht. Sie wird vom Preprozessor mit dem Wert von

    #devine ARRAYSIZE
    

    festgelegt. Sollte ich später feststellen, dass diese Anzahl an Messwerten nicht ausreicht, brauche ich so nur diesen Definewert zu verändern.

    Ich hab j mal rausgeschmissen (wieder auch ein altes Codefragment...).

    Bzgl. 31: Ja, da bin ich mir sicher. Wie du an diesen Rohwerten sehen kannst, wird da kein Mensch schlau. Wenn ich durch Pi teile und mit 180° Multipliziere, erhalte ich Kugelkoordinaten von 0-360° bzw. von 0-180° als Rückgabewert. Beim Drehen des Sensors sehe ich, dass das mit wen Werten passt.

    Die Schleife im Block, in dem bisher "check" steht, dient der Auswertung des Arrays.

    Warum soll Switch oder die If-Abfrage hier Schwachsinn sein? Ich muss doch die jeweiligen Daten dem Array richtig zuordnen und umrechnen.
    Dies würde ich gerbe beim Eintragen ins Array machen.

    Da die Werte, die ich ins Array schreibe scheinbar länger sind als double, könnte dies den Fehler verursachen. Ich versuche es mal durch ein long double zu ersetzen.
    Oder gibt es eine Möglichkeit, den genauen Datentyp herauszufinden?
    Um ehrlich zu sein blicke ich bei der Lib selbst nicht durch...ich steh halt noch am Anfang meiner...langen Lernkurve 😉



  • Ah, es lag tatsächlich am long double.
    Jetzt funktionierts.
    Danke, dass ihr euch die Mühe gemacht habt um mir auf die Sprünge zu helfen 🙂
    Ich verzweifelte hier schon seit Stunden 👍



  • Schau dir dein switch nochmal an stichwort dry (don't repeat yourself)


  • Mod

    Vereinfache mal folgenden Code:

    for (int i = 0; i < 2; ++i)
    {
      switch (i)
      {
        case 0: puts("Hello"); break;
        case 1: puts("World"); break;
      }
    }
    

    P.S.: Dein Problem liegt übrigens so gut wie sicher nicht an dem Datentyp. Du schreibst irgendwo über Arraygrenzen oder ähnliches. Ohne ausführbaren Code ist das Programm jedoch zu lang, um das nachzuvollziehen. Da du geschrieben hast, dass du kdevelop benutzt, nehme ich mal an, dass du unter einem Linux mit GCC als Compiler entwickelst.

    - Compiliere dein Programm mit den Compilerschaltern:

    -O0 -g -D_GLIBCXX_DEBUG -Wall -Wextra
    

    Jede Warnung des Compilers ist als Fehler anzusehen und zu beheben.
    - Wenn dies geschehen ist: Lasse das Programm laufen. Wahrscheinlich bekommst du Fehlermeldungen. Vielleicht reichen diese schon zur Behebung des Problems.
    - Falls keine Fehler auftraten oder du die Ursache nicht finden konntest, dann installiere das Programm valgrind (ist möglciherweise schon installiert). Starte dein Programm mit:

    valgrind --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes dein_programm
    

    Behebe alle gemeldeten Fehler (nicht die unterdrückten). Falls Fehler bezüglich uninitialisierter Werte auftreten, deren Ursache du nicht finden kannst, dann starte das Programm mit

    valgrind --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes --track-origins=yes dein_programm
    

    (ist sehr langsam, daher nur bei Bedarf. Verringere eventuell die Anzahl der Berechnungen, falls es zu langsam ist.)
    Behebe alle gemeldeten Fehler.
    - Falls keine Fehler mehr gefunden werden, aber das Programm immer noch falsch läuft, kannst du noch die valgrind-Option --tool=exp-sgcheck ausprobieren.



  • puts("Hello World"); 😃

    Ich weiß ehrlich nicht, wie ihr das meint.
    Es gibt da bestimmt ne Möglichkeit, das kompakter darzustellen.
    Aber ich wüsste nicht, wie das diesen Switch vereinahen soll.



  • Cysign schrieb:

    Ich weiß ehrlich nicht, wie ihr das meint.

    Ich wage mal zu behaupten, dass folgendes reicht:

    for (;;)
        {
          usleep(SLEEPVALUE);
          std::vector<int> values;
          CHECK_OAK_CALL(readInterruptReport(deviceHandle, values));
    
          const double mult2 = 180 / M_PI * pow(10.00, channelInfos[2].unitExponent);
          const double mult3 = 180 / M_PI * pow(10.00, channelInfos[3].unitExponent);
          messwerte[0][pet] = values[0];
          messwerte[1][pet] = values[1];
          messwerte[2][pet] = values[2] * mult2;
          messwerte[3][pet] = values[3] * mult3;
          ++net;
          pet=(pet+1) % ARRAYSIZE)
        }
    

    Was auch immer das ursprüngliche Problem mit long double zu tun hatte...
    Mein Einwand, dass Du am letzten Arrayelement vorbeigreifst gilt übrigens immer noch - ist aber untergegangen. Alldieweil ist pet im Code oben im Intervall [0, ARRAYSIZE).


  • Mod

    Cysign schrieb:

    puts("Hello World"); 😃

    Ich weiß ehrlich nicht, wie ihr das meint.
    Es gibt da bestimmt ne Möglichkeit, das kompakter darzustellen.
    Aber ich wüsste nicht, wie das diesen Switch vereinahen soll.

    Wie hast du es denn beim Hello World geschafft? Hast du mal den Link gelesen, den ich dir am Anfang von Seite 2 gegeben habe?

    Ich habe dir in meinem letzten Beitrag übrigens noch wichtige Hinweise reineditiert, während du schon geantwortet hast. Solltest du mal lesen.



  • Puh, gar nicht so einfach, das alles aufzunehmen.
    Aber der Codeblock von Furble Wurble sieht interessant aus. Probier ich mal aus^^

    Linker für -Wall z.B. ist mir bekannt. Aber ich werd aus der Makefile nicht ganz schlau.
    Bisher kenn ich nur makefiles mit <10 Zeilen. Hier jedoch wurde die Makefile über automake generiert. Ich weiß nicht, wie ich die Linker richtig hinzufügen kann. Und mir 637 Zeilen ist diese nicht grade kompakt und leicht zu verstehen für mich.

    Programmieren müsste man können 😉


  • Mod

    Da ist bestimmt ein configure-Programm dabei.

    Außerdem: 😕 Hast du das Programm denn nicht selber geschrieben? Dann musst du doch auch wissen, wie man es übersetzt. Du sollst nicht nach Fehlern in der Bibliothek suchen, sondern du sollst dein Programm mit diesen Optionen übersetzen und starten.

    Mit Linkern hat dies auch überhaupt nichts zu tun. Alles sehr wirr. Vielleicht führst du dir noch ein bisschen mehr Anfängerliteratur zu Gemüte (zweiter Link in meiner Signatur). Ich habe den Eindruck, viel Verwirrung in diesem Thread entsteht, weil du dich nicht richtig ausdrücken kannst und Wörter benutzt, deren Bedeutung du nicht richtig verstehst.



  • Genau, die Make-Datei wird erst mit dem configure-Programm erstellt.

    Wie ich bereits erwähnte, kenne ich nur ein paar C-Basics. Ich nage mich da quasi irgendwie durch und hoffe, dass ich das Ergebnis bekomme, das ich wünsche 😉

    Ich hab mir gestern ein O'Reilly C++-Buch gekauft, das ich mir ein wenig zu Gemüte führen werde. Aber das braucht halt alles seine Zeit.

    Der Grundcode für den Sensor stammt aus dem verlinkten Beispiel von Toradex (siehe Eröffnungspost), dem Sensorhersteller.
    Ich versuche es so anzupassen, dass es den von mir gewünschten Zweck erfüllt.
    Und dabei nehme ich so viele Stolperfallen mit, wie es nur geht 😃


  • Mod

    Tipp: Erst programmieren lernen, dann das Programm anpassen. Glaub mir, das ist die wesentlich schnellere Methode und das Ergebnis ist am Ende auch viel besser. Denk nur, wie weit du in deinem Buch schon wärst, wenn du die letzten drei Tage nicht mit unbeholfener Fehlersuche verbracht hättest.

    Such dir erst einmal einfache Probleme. Lerne an diesen die Grundlagen, die wichtigsten Strukturen und wie man Fehler findet. Wenn du das erst einmal drauf hast, dann funktioniert es auch bei scheinbar schwierigen Problemen ganz von alleine. Komplexe Probleme sind nämlich gar nicht schwer, sie bestehen bloß aus vielen einfachen Problemen 🙂 . Wenn du diese erst einmal selbstständig, sicher und gut angehen kannst, dann ist das komplexe Problem bloß eine Frage der mehrfachen Anwendung. Wenn du hingegen gleich das schwierige Problem angehst, erschlägt es dich, da du noch nicht gelernt hast, in kleinen, einfachen Problemstellungen zu denken.

    Gutes Beispiel ist dein for-switch. Ein Antipattern über das hier jeder heimlich lacht. Aber da du keine Übung in einfachen Ablaufplänen hast, weißt du weder, wie es besser geht, noch was die anderen Forennutzer daran so komisch finden.

    configure, make, make install ist übrigens auch wieder kein C, sondern eine allgemein übliche Art und Weise, Software vom Quellcode an zu verteilen:
    Google: configure make make install



  • Ja, das stimmt, mein Problem ist eine Ansammlung von vielen kleinen Problemen, aber dennoch möchte ich mich da durch beißen.
    Versuch macht kluch, wie man so schön sagt 😉

    @Furble:

    Ich bin positiv überrascht. Klein, smart, funktioniert.
    Einen Haken hat die Sache jedoch.
    Der erste Messdurchlauf spuckt ne Reihe von 0.000000 aus.
    Danach funktioneirt das aber problemlos.

    Als nächstes möchte ich das Array auswerten und Ausreißer rausschmeißen.
    Mein Plan ist:
    Das Array mit "qsort" (http://stackoverflow.com/questions/1787996/c-library-function-to-do-sort) auf- oder absteigend sortieren.

    Danach nehme ich einen Wert aus der Mitte des Arrays und vergleiche alle Werte des kompletten Arrays, ob sie eine Abweichung haben, die größer als ein gewisser Betrag ist. Da ich einen maximalen Anteill an Ausreißern von 10% habe, sollte ich hiermit gut arbeiten können.

    Gibt es eine empfehlenswertere Methode um das Array zu sortieren, als das, was ich auf Stackoverflow gefunden habe?

    Außerdem habe ich mich mal mit dem Hersteller des Sensors in Verbindung gesetzt, da der Sensor auch ein Temperatursignal liefert.
    Ich wollte wissen, ob ich dies auch abgreifen kann, da die OakLibary standardmäßig lediglich die Werte
    Frame[s],Acceleration[m/s²],Zenith [rad],Azimuth[rad] liefert.

    Daraufhin wurde ich auf das Datenblatt des intern verwendeten "SCA3000-D01" verwiesen.

    Das Datenblatt des kompletten USB-Geräts wäre hier: http://docs.toradex.com/100095-oak-tilt-inclination-datasheet.pdf

    Und das Datenblatt des verwendeten ICs auf der Platine befindet sich hier:
    https://www.sparkfun.com/datasheets/Sensors/Accelerometer/SCA3000-D01.pdf

    Laut OakTilt-Datasheet:

    3.2.7
    Direct access to Sensor Registers
    
    This command allow to directly read and write registers of the sensor. This can be used for
    example to change the measurement mode (sensor bandwidth).
    Byte#
    Content
    GnS:
    0 1 2 3 4 5
    GnS 0x03 0x01 RegAddr 0x00 RegValue
    0 = Set
    1 = Get
    RegAddr: Register Address (refer to the SCA3000 datasheet for details)
    RegValue: Register content (refer to the SCA3000 datasheet for details)
    

    Laut Sensor-IC-Datasheet hat der verwendete SCA3000-D01 auch einen "Temperature output".

    Hat hier vielleicht jemand eine Idee, wie ich nun die ausgewertete Temperatur abgreifen kann?
    Im Datenblatt finde ich leider keine Infos, die mir in irgendeiner Weise einen Ansatz zum Googeln liefern.

    PS: Ists vielleicht sinnvoller, wenn ich für diese zwei Problemchen nen neuen Threat aufmache? Ich weiß noch nicht so recht, wie ihr das hier im Board bevorzugt handhabt 😉



  • Cysign schrieb:

    Ich bin positiv überrascht. Klein, smart, funktioniert.
    Einen Haken hat die Sache jedoch.
    Der erste Messdurchlauf spuckt ne Reihe von 0.000000 aus.
    Danach funktioneirt das aber problemlos.

    Dafür wird es sicher einen Grund geben - k.A. wo und wie Du jetzt eine Ausgabe gebaut hast.
    Evtl. poste nochmal den aktuellen Stand des gesamten Programms.
    Das ist aber auch schon alles, was von Deinen Problemen noch in diesen Thread gehört.

    Cysign schrieb:

    Als nächstes möchte ich das Array auswerten und Ausreißer rausschmeißen.
    Mein Plan ist:
    Das Array mit "qsort" (http://stackoverflow.com/questions/1787996/c-library-function-to-do-sort) auf- oder absteigend sortieren.

    Danach nehme ich einen Wert aus der Mitte des Arrays und vergleiche alle Werte des kompletten Arrays, ob sie eine Abweichung haben, die größer als ein gewisser Betrag ist. Da ich einen maximalen Anteill an Ausreißern von 10% habe, sollte ich hiermit gut arbeiten können.

    Gibt es eine empfehlenswertere Methode um das Array zu sortieren, als das, was ich auf Stackoverflow gefunden habe?

    Meiner Meinung nach solltest Du Dir die Möglichkeiten zur Sortierung von C++ ansehen.
    Wenn Du in Deinem Kontext dazu Fragen hast, frag bitte im C++-Bereich - am Besten Du hast dann auch gleich ein Array mit Beispieldaten zur Hand.

    Zur Sache mit dem Datenblatt/Hardware usw. gilt das gleiche: richtiges Unterforum suchen, dort posten.


Anmelden zum Antworten