IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++Builder Discussion :

Problèmes avec Chart


Sujet :

C++Builder

  1. #1
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Juin 2006
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2006
    Messages : 122
    Points : 89
    Points
    89
    Par défaut Problèmes avec Chart
    Bonjour, le problème d'aujourd'hui réside dans l'ajout de donnée dans un graphique.

    Je travail avec l'acquisition de données a partir d'une source RS232 (8bits/1 stop bit/19200 bps) et lors de l'ajout de mes données dans le graphique, il met une erreur de pointeur, alors que lorsque je met en commentaires ces deux lignes (1 par graphique) le programme tourne nikel)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    void __fastcall TFormMEC::CPortRxChar(TObject *Sender, int Count)
    {
        char *cRx = new char [Count];
        CPort->Read(cRx, Count);
        int index = 0;
        do
        {
            if((cRx[index++] == CHAR(0xFF))&&(Count >= 5))
            {
                int iVal1;
                int iVal2;
                double dVal;
                //Débit
                iVal1 = (int) cRx[index++];
                iVal1 += 128;
                iVal2 = (int) cRx[index++];
                iVal2 += 128;
                iVal2 *= 256;
                iVal2 += iVal1;
                dVal = (double)iVal2;
                //Ajout du debit dans le graphique
    //Erreur 1-> SerieDebit->AddXY(iTrame, dVal, "", clRed);
                //Pression
                iVal1 = (int) cRx[index++];
                iVal1 += 128;
                iVal2 = (int) cRx[index++];
                iVal2 += 128;
                iVal2 *= 256;
                iVal2 += iVal1;
                dVal = (double)iVal2;
                //Ajout du debit dans le graphique
    //Erreur 2-> SeriePression->AddXY(iTrame,iVal2, "", clRed);
                iTrame++;
                //Ajustement des echelles des graphiques
                if(iTrame > iEchelle)
                {
                    ChartDebit->BottomAxis->Maximum = iTrame;
                    ChartPression->BottomAxis->Maximum = iTrame;
                    ChartDebit->BottomAxis->Minimum = iTrame - iEchelle;
                    ChartPression->BottomAxis->Minimum = iTrame - iEchelle;
                    if(!iEchelle)
                    {
                        ChartDebit->BottomAxis->Maximum = iTrame;
                        ChartPression->BottomAxis->Maximum = iTrame;
                        ChartDebit->BottomAxis->Minimum = 0;
                        ChartPression->BottomAxis->Minimum = 0;
                    }
                }
                else
                    InitEchelle();
            }
            else
                index++;
        }
        while(index < Count);
    }
    Quelqu'un sais si les graphiques ont une fréquence de rafraichissement limite, ou alors ou est-ce que j'aurais fait mon erreur (aussi idiote soit-elle).

    Merci

  2. #2
    Membre éprouvé
    Avatar de bandit boy
    Profil pro
    Inscrit en
    Février 2006
    Messages
    916
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 916
    Points : 1 007
    Points
    1 007
    Par défaut
    Salut,
    Il n'y a pas de limite de temps ou quoique ce soit dans l'ajout de point. Au pire, il ne rafraichit pas le TChart tant qu'il n'a pas la main.

    Je pense qu'il faut que tu mettes un point d'arrêt et que tu regardes la valeurs de iTrame.
    Quel est l'erreur que tu as?
    Quel est la valeur des variables avant l'erreur?
    Si c'est une question de temps, en pas à pas, tu ne devrais pas avoir d'erreur. Est ce le cas?

  3. #3
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Juin 2006
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2006
    Messages : 122
    Points : 89
    Points
    89
    Par défaut
    en fait j'ai mis un tit label pour visualiser la valeur de dVal, elle varie de 0 à 65535 (0x00 à 0xFF)

    le problème viendrait de la multiplication par 256 qui ne conviendrai pas.

    l'erreur est une erreur de pointeur (je peux pas retester maintenant mais je le ferais des que possible)

    Par contre, j'ai remarqué qu'avec ce code, j'utilisais 100% du CPU (un 2.80 GHz P4) ce qui me parrait énorme pour un simple bvoucle de calculs(je supose que les deux chart prennent énormément de ressources)

  4. #4
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Juin 2006
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2006
    Messages : 122
    Points : 89
    Points
    89
    Par défaut
    L'erreur que j'obtien est :
    Le projet MesureEnContinue.exe a provoqué une classe d'exception EInvalidPointer avec le message 'Opération de pointeur incorrecte'. Processus stoppé. Utilisez Pas-à-pas ou Exécuter pour continuer.
    Pour quelques precisions, le programme scrute le port COM pour recevoir des trames de 8 octets (0xFF quatres octets utilisé, puis 3 octets non utilsé pour l'instant)
    Il y a un nombre de 100 trames par secondes (un mode 200 trame par secondes est envisagé, mais la n'est pas le problème) donc on a au moins 8000 bits par secondes de transféré (1 bit start, 1 bit stop et 8 bits de donnees, le tout sur 8 octets)

  5. #5
    Membre actif Avatar de Baxter67
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 270
    Points : 216
    Points
    216
    Par défaut
    Citation Envoyé par Galkir Voir le message
    en fait j'ai mis un tit label pour visualiser la valeur de dVal, elle varie de 0 à 65535 (0x00 à 0xFF)

    le problème viendrait de la multiplication par 256 qui ne conviendrai pas.

    l'erreur est une erreur de pointeur (je peux pas retester maintenant mais je le ferais des que possible)

    Par contre, j'ai remarqué qu'avec ce code, j'utilisais 100% du CPU (un 2.80 GHz P4) ce qui me parrait énorme pour un simple bvoucle de calculs(je supose que les deux chart prennent énormément de ressources)


    avec un tel code tu prendra 100% de ton uc meme si ta le tous dernier processeur.
    Sa vien du fait que tu boucle un grand nombre de fois (je présume) ... combien vaut iCount?

    Pour palier a ce prob met un Sleep(10); juste avant le while

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     else
                index++;
     
    Sleep(10);
        }
        while(index < Count);
    }

  6. #6
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Juin 2006
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2006
    Messages : 122
    Points : 89
    Points
    89
    Par défaut
    Count (et non pas iCount) est le nombre d'octets présents dans le buffer du port (le nombre d'octets a lire), et il a une valeur de 8 (normalement) mais plus le graphique a de point, plus il prend du temps a calculer (même pour un 2800 MHz) et le buffer augmente, pour passer de 8 à 16 vers les 10 secondes, et à 24 de temps en temps.

    Pour le Sleep(10) (ou tout autre valeur) ca fout la marde totale! donc solution non envisageable

  7. #7
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Juin 2006
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2006
    Messages : 122
    Points : 89
    Points
    89
    Par défaut
    Je vais simplifier ma demande (j'espere que c'est la clé du problème) :

    J'ai deux octets (char1 et char2) en entrée, et je souhaite avoir un double en sortie. (char2 étant le LSB et char1 le MSB, cad double = char1*256 + char2 le tout allant de 0 à 65535 [0x0000 à 0xFFFF])

    Comment faire cete conversion avec le moins d'instructions possibles?

    Code de la solution utilisé : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
                iVal1 = (int) cRx[index++];
                iVal1 += 128;
                iVal2 = (int) cRx[index++];
                iVal2 += 128;
                iVal2 *= 256;
                iVal2 += iVal1;
                dVal1 = (double)iVal2;

    Edit : l'utilisation de TFastLine améliore la rapidité de la fonction

  8. #8
    Membre actif Avatar de Baxter67
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 270
    Points : 216
    Points
    216
    Par défaut
    moi avec des unsigned short j'avais fais comme sa :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
      unsigned short  usVal;
      unsigned char ucChar1, ucChar2;
     
     
        usVal  =  (unsigned short)(ucChar1<<8) | (unsigned short)ucChar2;
    avec des double sa donnerais sa je pense (jai pas tester)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
      double  dVal;
      char cChar1, cChar2;
     
       dVal = (double)(cChar1<<8) | (double)cChar2;
    voila, comment moi je vois la chose
    En esperant que sa peut t'aider

    Cordialement Baxter

  9. #9
    Membre éprouvé
    Avatar de bandit boy
    Profil pro
    Inscrit en
    Février 2006
    Messages
    916
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 916
    Points : 1 007
    Points
    1 007
    Par défaut
    Un conseil:
    Si tu multiplies ta valeurs iVal2 par 256, vérifie bien qu'avant ta multiplication, elle est inférieur à 256 (256*256 = 65535), pour ne pas avoir de dépassement.

    Sinon, pour la méthode:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
                int iVal1 = (int)cRx[index++] + 128;
                int iVal2 = (((int)cRx[index++] + 128)&0xFF )<<8;
     
                iVal1 += iVal2;
    NB: Il est aussi important de vérifier que l'index ne dépasse pas du tableau, d'où un problème de pointeur.

  10. #10
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Juin 2006
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2006
    Messages : 122
    Points : 89
    Points
    89
    Par défaut
    Citation Envoyé par bandit boy Voir le message
    Un conseil:
    Si tu multiplies ta valeurs iVal2 par 256, vérifie bien qu'avant ta multiplication, elle est inférieur à 256 (256*256 = 65535), pour ne pas avoir de dépassement.


    NB: Il est aussi important de vérifier que l'index ne dépasse pas du tableau, d'où un problème de pointeur.
    Alors, a ma connaissance, un unsigned char (ou juste char) ne peu dépasser la valeur base 10 de 256.

    en fait, ce problème survient quand je met "Application->ProcessMessage()" ou "Chart->Refresh()".
    Si je ne met pas une de ces deux méthodes dans mon code, il passe nikel, sauf qu'au bout de 5-10 s, le premier chart s'arrete de s'afficher, et je commence a voir le buffer d'entré accumuler les données (au début que des trames de 8 octets, puis ensuite, 16, etc etc) et le processeur est utilisé a 100% (enfin au max), ce que je trouve bizar, et surttout ennuyeux, car par la suite, je suis ammené a avoir 4 chart dans la même fenêtre.

    mais je vien de penser a un truc, est-ce qu'on peu avoir deux graph distinct dans un meme objet Chart? (comme avec TeeChart) ca éviterais peut-etre de traiter les deux objets actuels, et permettre au procs de moins raler.

  11. #11
    Membre actif Avatar de Baxter67
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 270
    Points : 216
    Points
    216
    Par défaut
    comme je l'ai dis précédement, met un petit Sleep et ton utilisation CPU baisseras beaucoup

    Cordialement Baxter

  12. #12
    Membre éprouvé
    Avatar de bandit boy
    Profil pro
    Inscrit en
    Février 2006
    Messages
    916
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 916
    Points : 1 007
    Points
    1 007
    Par défaut
    Avec Builder, il est possible d'avoir des dépassements. Je m'explique: il se peut que la variable soit ré-assigné en int pour pouvoir stocker la valeur(déjà vu), d'où l'utilité d'un test.

    Peux tu faire un affichage dans des Tlabels des valeurs en direct et voir si elles cloches?

    Pour le TChart, tu peux afficher d'autres courbes, ou affilier des composants aux TChart (composant enfant du TChart), donc au pire, avoir un TChart dans un TChart, mais pas 2 graphes distinct dans le même TChart à ma connaissance.

  13. #13
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Juin 2006
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2006
    Messages : 122
    Points : 89
    Points
    89
    Par défaut
    mais si je met un Sleep, il me bloque mon programme
    Si j'ajoute une processMessage, il me fout en caraf le progrmme
    faut-il que je passe par un thread et juste envoyer les données venant du buffer?

    ---

    Les données sont cohérantes, souvent autour de 8000 elles ne depassent pas les 60k.

  14. #14
    Membre actif Avatar de Baxter67
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 270
    Points : 216
    Points
    216
    Par défaut
    ben c sur, que si tu utilise un sleep il fo créer un thread qui fera cette gestion.
    Comme sa, le programme ne sera jamais freezer et ton utilisation CPU va chuter en fleche

  15. #15
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Juin 2006
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2006
    Messages : 122
    Points : 89
    Points
    89
    Par défaut
    bon, bah me reste plus qu'a potasser les thread, rdv a la prochaine expérience

  16. #16
    Membre actif Avatar de Baxter67
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 270
    Points : 216
    Points
    216
    Par défaut
    ta un bon tutorial sur les thread dans la FAQ

  17. #17
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Juin 2006
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2006
    Messages : 122
    Points : 89
    Points
    89
    Par défaut
    J'ai pas fait attention dans la FAQ mais dans les tuto proposé par CGI j'ai trouvé ce qui devrais me convenir : http://chgi.developpez.com/thread/

    Par contre, faut que je trouve comment on se sert de l'outils ComDataPacket car ca pourrais m'éviter pas mal de conditions, et donc améliorer la rapidité d'execution de ma fonction.

    Edit : juste une question, comment récupérer la valeur (de 0x00 à 0xFF) d'un caractère AnsiString?

  18. #18
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Juin 2006
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2006
    Messages : 122
    Points : 89
    Points
    89
    Par défaut
    Alors, finalement, pas besoin de faire un thread spécialisé, un simple ComDataPacket suffit largement.

    J'ai même pu réduire le code de façon assez intéréssante, ce qui me permet de ne plus avoir de problème de saturation de buffer (enfin j'en vois plus)

    L'utilisation du processeur est toujours de 100% mais ce n'est pas grave (le logiciel est destiné a des poste de travail dédié a son utilisation (pas de programme qui tourne a coté)

    Merci pour l'aide.

    Pour info, voici mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    void __fastcall TFormMEC::CDPackPacket(TObject *Sender,
          const AnsiString Str)
    {
        char *cChar = new char [Str.Length()];
        cChar = Str.c_str();
        double dVal1, dVal2;
        dVal1 = (double)(cChar[1] << 8) + (double)cChar[0];
        dVal2 = (double)(cChar[3] << 8) + (double)cChar[2];
        //Ajustement des echelles des graphiques
        ChartDebit->BottomAxis->Maximum = iTrame;
        ChartPression->BottomAxis->Maximum = iTrame;
        if(iEchelle)
        {
            ChartDebit->BottomAxis->Minimum = iTrame - iEchelle;
            ChartPression->BottomAxis->Minimum = iTrame - iEchelle;
        }
        //Ajout du debit dans le graphique
        SerieDebit->AddXY(iTrame, dVal1);
        //Ajout du debit dans le graphique
        SeriePression->AddXY(iTrame,dVal2);
        iTrame++;
    }

  19. #19
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Juin 2006
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2006
    Messages : 122
    Points : 89
    Points
    89
    Par défaut
    Une erreur, ou plutot un problème persiste.

    Sur ma fiche, j'y ai inséré deux composant Chart, avec chacun deux série de points.
    Mais le problème est que au bout de quelques secondes d'acquisition et de traitement, le premier Chart ne se rafraichis plus.
    Si j'ajoute la méthode ->Refresh(), je n'ai plus la main du tout, malgrès le problème résolu.
    Si enfin j'ajoute Application->ProcessMessage(), j'ai la main, les graph tournent bien, mais le temps de traitement étant trop long, j'en arrive a avoir plusieurs secondes de retard entre le changement de données d'acquisitions et l'affichage dans les graphiques.

    Y a-t-il une autre méhode que Refresh() qui soit moins gourmande, et qui me laisse la main pour agir sur ma fiche?

  20. #20
    Membre actif Avatar de Baxter67
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 270
    Points : 216
    Points
    216
    Par défaut
    le thread

    a part sa personnelement je voie pas

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Problème avec Charts rickshaw
    Par toufik135 dans le forum Général JavaScript
    Réponses: 0
    Dernier message: 04/01/2015, 08h16
  2. Problème avec chart
    Par magil dans le forum FastReport
    Réponses: 1
    Dernier message: 13/06/2014, 18h17
  3. Problème avec chart en vb 2010
    Par Nnahaa dans le forum VB.NET
    Réponses: 2
    Dernier message: 02/05/2011, 19h20
  4. Probléme avec chart échelle log
    Par Mloody2000 dans le forum Débuter
    Réponses: 0
    Dernier message: 14/08/2008, 00h40
  5. problème avec l'insertion de chart
    Par rades2006 dans le forum iReport
    Réponses: 2
    Dernier message: 18/04/2007, 15h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo