Go Down

Topic: Problème de rapidité (Read 1 time) previous topic - next topic

Flanker47

Feb 14, 2009, 10:33 am Last Edit: Feb 14, 2009, 10:34 am by Flanker47 Reason: 1
Bonjour, je poste un nouveau sujet car le problème de communication est résolu. Mais un nouveau imprévu a fait surface:

Le programme auquel j'essaye d'aboutir est une télécommande, il y a donc des impératifs de vitesse à respecter.

Actuellement il envois des données toutes les 140 ms ce qui est bien trop long (3 fois trop long )

le trame (temps durant le quel le decimaila renvois les données dure 20ms maximum)

d'où la problématique
il faudrait donc que j'arrive à un temps de réception inférieur au 30 ms (actuellement mon temps de réception est de 110 ms )


le problème principale vient (du moins c'est l'hypothèse que j'émets)
des boucles de détection de ma liaison série.


en code ça donne :

coté  arduino :

Quote

//profondeur
           do
            {
              Serial.println (8, DEC);
              }while(Serial.read()!= 56);
           
           do
            {
              Serial.println (9, DEC);
             }while(Serial.read()== 56);

           y1 =  1000*(Serial.read()/255 + 1);


            do
            {
             Serial.print (5,DEC);
             }while(Serial.read()!= 53);



coté PC:

Quote

//profondeur
               do                                                                  //on attend que le processeur soit prêt à recevoir
               {
                   j=j+1;
                   Arduino->ReadData(recu,1);

               }while(recu[0]!=56);
               //fprintf(stderr,"la première boucle p a fait %ld tours \n",j);
               j = 0;
               envois[0] = 56;
               do                                                                  //on dit au processeur de passer en mode réception
               {
                   j=j+1;
                   Arduino->WriteData(envois,1);
                   Arduino->ReadData(recu,1);
               }while(recu[0] != 57);
               //fprintf(stderr,"la deuxième boucle p a fait %ld tours \n",j);
               j = 0;
               envois[0] = Profondeur;
               do                                                                  // on envois les donnés
               {
                   j=j+1;
                   Arduino->WriteData(envois,1);
                   Arduino->ReadData(recu,1);
               }while(recu[0] != 53);
               //fprintf(stderr,"la troisième boucle p a fait %ld tours \n",j);
               j = 0;
               envois[0] = 53;
               do                                                                  //le processeur confirme qu'il a bien recu les donnés
               {
                   Arduino->WriteData(envois,1);
                   Arduino->ReadData(recu,1);
                   j=j+1;
               }while(recu[0]!=53);
               //fprintf(stderr,"la quatrième boucle p a fait %ld tours \n",j);
               j = 0;
               //fprintf(stderr,"confirmation %ld\n Profondeur a ét envoyée\n\n\n",recu[0]);





ce protocole est composé de 4 boucles coté PC et je peut être sur qu'à chaque fois j'aurais 1 boucle qui s'exécutera plus de 2000 fois
et si je lis les valeurs reçues par cette boucles (c'est le grand carnaval)
si j'enlève les 10 et les 13 il y a du -62, 20 , 30 , -6 ..... enfin plein de valeurs qui ne figures à aucun endroit dans les lignes de code
donc à moins d'avoir créé une chose nouvelle et complètement inédite  ::)
je pense qu'il y a un problème dans mes lignes de codes  :o

Luj06

Oui, il y a un problème, on ne comprend rien à ce que tu veux faire. Simplifie ton énoncé, explique nous ce que tu veux faire sans écrire de code et fais un schéma.

Flanker47

Tout à fait d'accord, c'est un problème récurent chez moi  ;D

bon je fait une bonne présentation et je reposte

Jean-François

#3
Feb 14, 2009, 11:47 am Last Edit: Feb 14, 2009, 11:48 am by jfs Reason: 1

Ici, suivant l'affichage, j'arrive à moins de 10 ms par lecture, mais c'est sur un mac.
MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

Flanker47

J'ai lu ce que vous m'avez envoyé mais de nombreuses fonction me sont inconnues (encore un débutant ^ ^) donc ça semble rapide mais je ne pourrais pas le mettre en ?uvre


mais je suis tombé sur un code de Luj06 en cherchant dans le forum. Ce code si il est applicable peut diviser par 4 le nombre d'opération et me faire gagner le temps recherché

de Luj06 dans http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1232673534
Code: [Select]
// pour stocker la chaine de caractère envoyée par la liaison série
byte commande[32];

// enregistre la chaine de caractère et indique le nombre de caractères lus
int readCommand()
{
 if(!Serial.available())
 {
   return 0;
 }
 int i = 0;
 // il faut lire chaque caractère 1 par 1
 while(Serial.available())
 {
   commande[i] = Serial.read();
   i++;
 }
 commande[i] = 0;  // toujours terminer par un 0
 return i;
}

void executeCommande()
{
 if (commande[0] == 'X')
 {
   motorX.step(commande[1], commande[2], commande[3]);
 }
 if (commande[0] == 'Y')
 {
   motorY.step(commande[1], commande[2], commande[3]);
 }
}

void loop()
{
 if (readCommande() != 0)
 {
   // si une commande complète est arrivée, on l'exécute
   executeCommande();
 }
}


si ce code permet d'envoyer plusieurs données "d'un coup" alors le problème est réglé (pour l'instant j'essaye de la mettre en ?uvre).

Luj06

C'est bien pour ça que je te demandais de simplifier ton problème en repartant de ton besoin. Ce serait plus simple pour nous ensuite de te proposer un code, plutôt que de deboguer celui que tu nous proposes.

Flanker47

#6
Feb 14, 2009, 06:06 pm Last Edit: Feb 14, 2009, 06:07 pm by Flanker47 Reason: 1
je vois ce que tu veux dire, s'extraire du problème, prendre du recule...
on me le dit trop souvent  :-[

en tout cas pour le code ça marche avec un temps de 20 ms

essayons un autre problème ;D:

existe-t-il des fonctions permettant de faire

décimal -> ASCII

ASCII -> Décimal

j'ai entendu parler de "char toto" :o mais malgré google  je ne vois pas encore à quoi cela correspond.

Jean-François



Ici

ça doit être les lignes :

Code: [Select]
...
         printf("ASCII Input: ");
...


...
              printf("Decimal Ouput:");
              ...
              printf("%d ", string[length]);
              ...              


               ...
             printf("Hexadecimal Output: ");
             ...
                 printf("%x ", string[length]);
               ...                  


              ...
                 printf("Octal Output:");
               ...
               printf("%o ", string[length]);
              ...
MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

Flanker47

#8
Feb 15, 2009, 09:41 am Last Edit: Feb 15, 2009, 11:56 am by Flanker47 Reason: 1
petite clarification:

en entré on a un décimal  (par exemple  123)de 0 à 255  

que je veux convertir en ASCII, (ce qui donne 49/50/51)

pour ensuite l'envoyer caractère par caractère à travers la liaison série

une fois sur l'arduino on récupère les caractères dans l'ordre d'arrivée
(y1 = (100*(49-48)+10*(50-48)+1*(51-48))


donc
une choses est inconnue:
      - la convertion décimal vers ASCII


pour cette conversion je pensait utiliser ce genre de formule:

       pro1 = Profondeur/100 +48;                      
       pro2 = Profondeur/10 - 10* pro1 +48;
       pro3 = Profondeur - 100*pro1- 10*pro2 +48;

Profondeur = 100*(pro1-48) + 10*(pro2-48)+ 1*(pro3-48)

mais cette solution multiplie le nombre de données à envoyer et  il y a surement plus rapide.

Jean-François

Ici

Est-ce ce que tu cherches ?
MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

Flanker47

#10
Feb 15, 2009, 02:19 pm Last Edit: Feb 15, 2009, 02:43 pm by Flanker47 Reason: 1
ça pourrait être ce que je cherche, mais un doute subsiste:
quel est la nature la la valeur x dans char(x) ?



jusque là j'ai comme code:

du côté PC
Code: [Select]
       pro1 = Profondeur/100 +48;                      // conversion décimal vers ASCII
       pro2 = Profondeur/10 - 10* pro1 +48;
       pro3 = Profondeur - 100*pro1- 10*pro2 +48;

       go1 = Gauchissement/100 +48;                      // conversion décimal vers ASCII
       go2 = Gauchissement/10 - 10* go1 +48;
       go3 = Gauchissement - 100*go1- 10*go2 +48;

       la1 = Lacet/100 +48;                      // conversion décimal vers ASCII
       la2 = Lacet/10 - 10* la1 +48;
       la3 = Lacet - 100*la1- 10*la2 +48;

       p1 = Puissance/100 +48;                      // conversion décimal vers ASCII
       p2 = Puissance/10 - 10* p1 +48;
       p3 = Puissance - 100*p1- 10*p2 +48;

       envois[0] = 47;
       envois[1] = pro1;
       envois[2] = pro2;
       envois[3] = pro3;
       envois[4] = go1;
       envois[5] = go2;
       envois[6] = go3;
       envois[7] = la1;
       envois[8] = la2;
       envois[9] = la3;
       envois[10] = p1;
       envois[11] = p2;
       envois[12] = p3;
       envois[13] = 46;
       do
       {
           Arduino->WriteData(envois,14);
           Arduino->ReadData(recu,5);
           fprintf(stderr,"on recois %ld\n",recu[0]);
           j = j+1;
       }while(recu[0]!=56);


et du côté Arduino

Code: [Select]
int readCommand()
{
 for(int l=0;l<=10;l++)
{ commande[l] = 0;}
 if(!Serial.available())
 {
   return 0;
 }
 int i = 0;
 // il faut lire chaque caractère 1 par 1
 while(Serial.available())
 {
   commande[i] = Serial.read();
   i++;
 }
 commande[i] = 0;  // toujours terminer par un 0
 return i;
}





dans le programme principale  
if (readCommand() != 0)
                 {
                   int j=0;
                       // si une commande complète est arrivée, on l'exécute
                   do
                   {
                     j=j+1;
                   }while(commande[j]!=47);
                  y1 = 100*(commande[j+1] -48)+10*( commande[j+2] - 48)+ commande[j+3];
                  y2 = 100*(commande[j+4] - 48)+10*(commande[j+5] - 48)+ commande[j+6];
                  y3 = 100*(commande[j+7] - 48)+10*(commande[j+8] - 48)+ commande[j+9];
                  y4 = 100*(commande[j+10] - 48)+10*(commande[j+11]-48)+ commande[j+12];
                  j=j+12;
                  do
                   {
                     j=j+1;
                   }while(commande[j]!=46);

                   Serial.print(8, DEC);  



donc je pourrais alléger de beaucoup le programme si char(x)
fonctionne

Jean-François

C'est mentionné :

Quote
Parameters

x: a value of any type
MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

Luj06

Bonjour,

On croit rêver, encore du code et du code et du code.

Déjà, l'hypothèse de départ est fausse : "un décimal entre 0 et 255", pour moi ça s'appelle un entier.

Pourquoi faire une conversion en ASCII alors que le seul usage mentionné (le peu d'explication qu'on ait) est de l'envoyer à l'Arduino ?

Cela oblige à faire un redécodage qui prend du temps et de la place sur l'Arduino. Le code proposé est sans doute exact, mais à quoi sert-il ?

Sur le PC :
Code: [Select]

envois[0] = 47;
envois[1] = Gauchissement;
envois[2] = Lacet;
envois[3] = Puissance;
Arduino->WriteData(envois,14);


Et côté Arduino :
Code: [Select]

int gauch;
int lacet;
int puissance;
while (Serial.available())
{
  if (Serial.read() == 47)
  {
      gauch = Serial.read();
      lacet = Serial.read();
      puissance = Serial.read();
  }
  Serial.flush();
}


Et puis c'est tout, tu as tes 3 entiers dans des variables sans tout ce décodage inutile. Mais si tu nous avais expliqué ton besoin au lieu de copier du code, on aurait pu t'aider dès le premier post.

A bon entendeur ;)


Luj06

Salut,

Il fallait lire : Arduino->WriteData(envois,4);
Et pas 14, j'espère que Flanker aura corrigé.

Au fait, ça a donné quoi ? ça fonctionne ?

Go Up