Go Down

Topic: Trop if / else if ? (Read 677 times) previous topic - next topic

ProgramFiles

Bonjour, je travail actuellement sur le développement d'un programme permettant de contrôler des leds RGB par infrarouge, j'ai donc fais ce programme cependant mes conditions ne font pas correctement quand je décommante toutes les touches, bug du compilo ?
Code: [Select]
//2.4 > Envoi d'un signal IR ON/OFF Téléviseur Philips.

int IRledPin =  13; //Variable IRledPin associée à broche n°13
String inputString = "";         // a string to hold incoming data
boolean stringComplete = false;  // whether the string is complete

/**** ICI je déclare mes int[] qui définissent les boutons (on_key,off_key,etc...).****/

void setup() {                
 pinMode(IRledPin, OUTPUT);   //Broche N°13 est une sortie.  
 Serial.begin(9600);          //Initialisation Serial Monitor.
 inputString.reserve(200);
}

void send_key(int sizeKey,int key[])
{
 for(int i = 0; sizeKey >= i; i++)
 {
   if ( (i % 2) == 0) {
      pulseIR(key[i]);
   } else {
     delayMicroseconds(key[i]);
   }
 }
}

void loop() {
  if (stringComplete) {
   Serial.println(inputString);
   if(inputString == "on\n")
   {
     send_key(sizeof(on_key),on_key);
   }
   if(inputString == "off\n")
   {
     send_key(sizeof(off_key),off_key);
   }
   if(inputString == "reset\n")
   {
     send_key(sizeof(reset_key),reset_key);
   }
   if(inputString == "time-\n")
   {
     send_key(sizeof(clock_left_key),clock_left_key);
   }
   if(inputString == "time+\n")
   {
     send_key(sizeof(clock_right_key),clock_right_key);
   }
   if(inputString == "run\n")
   {
     send_key(sizeof(run_key),run_key);
   }
   if(inputString == "rgb\n")
   {
     send_key(sizeof(rgb_key),rgb_key);
   }
   if(inputString == "dimmer-\n")
   {
     send_key(sizeof(dimmer_down_key),dimmer_down_key);
   }
   if(inputString == "dimmer+\n")
   {
     send_key(sizeof(dimmer_up_key),dimmer_up_key);
   }
   if(inputString == "r\n")
   {
     send_key(sizeof(r_key),r_key);
   }  
   if(inputString == "g\n")
   {
     send_key(sizeof(g_key),g_key);
   }
   /*if(inputString == "b\n")
   {
     send_key(sizeof(b_key),b_key);
   }
   if(inputString == "orange\n")
   {
     send_key(sizeof(orange_key),orange_key);
   }
   if(inputString == "green\n")
   {
     send_key(sizeof(green_key),green_key);
   }
   if(inputString == "blue\n")
   {
     send_key(sizeof(blue_key),blue_key);
   }
   if(inputString == "rose\n")
   {
     send_key(sizeof(rose_key),rose_key);
   }
   if(inputString == "yellow\n")
   {
     send_key(sizeof(yellow_key),yellow_key);
   }
   if(inputString == "blue_light\n")
   {
     send_key(sizeof(blue_light_key),blue_light_key);
   }
   if(inputString == "rose_light\n")
   {
     send_key(sizeof(rose_light_key),rose_light_key);
   }
   if(inputString == "yellow_light\n")
   {
     send_key(sizeof(yellow_light_key),yellow_light_key);
   }
   if(inputString == "blank\n")
   {
     send_key(sizeof(blank_key),blank_key);
   }*/
   
   // clear the string:
   inputString = "";
   stringComplete = false;
 }
}

void serialEvent() {
 while (Serial.available()) {
   // get the new byte:
   char inChar = (char)Serial.read();
   // add it to the inputString:
   inputString += inChar;
   // if the incoming character is a newline, set a flag
   // so the main loop can do something about it:
   if (inChar == '\n') {
     stringComplete = true;
   }
 }
}

// Cette fonction envoie une impulsion d'une fréquence de 38 kHz à la broche n°13.
void pulseIR(long microsecs) {


 cli();

 while (microsecs > 0) {
   // 38 kHz correspond environ à 13 microsecondes à l'état haut et 13 à l'état bas.
  digitalWrite(IRledPin, HIGH);  // Cette instruction met environ 3 microsecondes à s'effectuer.
  delayMicroseconds(10);         // On attend 10 microsecondes
  digitalWrite(IRledPin, LOW);   // Cette instruction met environ 3 microsecondes à s'effectuer.
  delayMicroseconds(10);         // On attend 10 microsecondes

  // En tout, cela met 26 microsecondes.
  microsecs -= 26;
 }

 sei();
}
 

lorsque je décommante les autres touches rien ne fonctionne, le simple faite d'ajouter UNE SEUL touche fais buger, comme s'il y avait une limite, que faire ?
Merci

fdufnews

Quote
bug du compilo ?

Quel bug du compilo?
Le message retourné?

skywodd

Bonjour,

Le compilateur a toujours raison, c'est toujours le dév qui fait de la merde !
Et ton code ne fait pas exception à cette règle ;)

On test l'égalité de 2 String via String.compareTo(string) et non avec un ==.
http://arduino.cc/en/Reference/StringCompareTo
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

ProgramFiles

Il n'y a pas de réponse via le debug, c'est le programme qui s'exécute mal, tout les if / else if ne sont pas fonctionnel si yen a trop...

Sinon j'ai essayé avec compareTo

Code: [Select]
    if(inputString.compareTo("on\n") == 0)
    {
      send_key(sizeof(on_key),on_key);
    }
    else if( inputString.compareTo("off\n") == 0)
    {
      send_key(sizeof(off_key),off_key);
    }
    else if( inputString.compareTo("reset\n") == 0)
    {
      send_key(sizeof(reset_key),reset_key);
    }
    else if( inputString.compareTo("time-\n") == 0)
    {
      send_key(sizeof(clock_left_key),clock_left_key);
    }
    else if( inputString.compareTo("time+\n") == 0)
    {
      send_key(sizeof(clock_right_key),clock_right_key);
    }
    else if( inputString.compareTo("run\n") == 0)
    {
      send_key(sizeof(run_key),run_key);
    }
    else if( inputString.compareTo("rgb\n") == 0)
    {
      send_key(sizeof(rgb_key),rgb_key);
    }
    else if( inputString.compareTo("dimmer-\n\n") == 0)
    {
      send_key(sizeof(dimmer_down_key),dimmer_down_key);
    }
    else if( inputString.compareTo("dimmer+\n\n") == 0)
    {
      send_key(sizeof(dimmer_up_key),dimmer_up_key);
    }
    /*else if( inputString.compareTo("r\n") == 0)
    {
      send_key(sizeof(r_key),r_key);
    } 
    else if( inputString.compareTo("g\n")== 0)
    {
      send_key(sizeof(g_key),g_key);
    }
    if( inputString.compareTo("b\n"))
    {
      send_key(sizeof(b_key),b_key);
    }
    if( inputString.compareTo("orange\n"))
    {
      send_key(sizeof(orange_key),orange_key);
    }
    if( inputString.compareTo("green\n"))
    {
      send_key(sizeof(green_key),green_key);
    }
    if( inputString.compareTo("blue\n"))
    {
      send_key(sizeof(blue_key),blue_key);
    }
    if( inputString.compareTo("rose\n"))
    {
      send_key(sizeof(rose_key),rose_key);
    }
    if( inputString.compareTo("yellow\n"))
    {
      send_key(sizeof(yellow_key),yellow_key);
    }
    if( inputString.compareTo("blue_light\n"))
    {
      send_key(sizeof(blue_light_key),blue_light_key);
    }
    if( inputString.compareTo("rose_light\n"))
    {
      send_key(sizeof(rose_light_key),rose_light_key);
    }
    if( inputString.compareTo("yellow_light\n"))
    {
      send_key(sizeof(yellow_light_key),yellow_light_key);
    }
    if( inputString.compareTo("blank\n"))
    {
      send_key(sizeof(blank_key),blank_key);
    }*/


J'ai la même chose, j'en décommente un de plus et ça fonctionne plus

fdufnews

Quote
J'ai la même chose, j'en décommente un de plus et ça fonctionne plus

C'est pas pour être blessant mais la méthode des if ... then ... else ..., ça va pour 2 ou 3 cas mais après c'est vraiment bourrin comme procédé.
Je pense qu'avec un tableau tu pourrais faire quelque chose de beaucoup plus propre.

MiGaNuTs

Mon avis qui n'engage que moi m'autorise a penser que déjà un type "String" sur un microcontrôleur qui n'a que quelques octets de mémoire ça ne devrais même pas exister.

Une fois compilé ça fait du code qui bouffe de la place et de la mémoire a foison (et du temps de calcul aussi) le plus souvent pour faire des trucs qui auraient été bien plus efficients avec des tableaux de char.

ProgramFiles

#6
Sep 04, 2013, 09:49 pm Last Edit: Sep 04, 2013, 10:00 pm by ProgramFiles Reason: 1
Peut-être bien, mais le code est quand même aux "normes" non ? ça devrait fonctionner ?
J'vais utiliser une autre solution cependant j'aimerais quand même comprendre le problème vu que le compilo à toujours raison...

Quand vous parlez de tableaux de char c'est faire la même chose en utilisant des type char ?

fdufnews


Quand vous parlez de tableaux de char c'est faire la même chose en utilisant des type char ?

Ce que propose MiGaNuTs c'est de remplacer les Strings par des tableaux de char. Cela utilise moins de mémoire. Les objets Strings sont associés à une librairie conséquente.

De mon coté ce que je suggérais c'était de modifier la structure du programme pour le rendre plus simple, plus lisible.
Tu fais un tableau avec tous les mots clés que tu attends. Si tes mots clés sont des chaînes c'est effectivement un tableau de tableau de char
Une boucle parcourt le tableau et compare la chaîne reçue avec les différents mots clés. Lorsqu'il y a correspondance, l'index courant te permet de retrouver dans un second tableau le message à envoyer.
Au final, tu as juste une boucle et une comparaison de chaînes au lieu d'en avoir plusieurs. Et les tableaux sont plus faciles à maintenir si tu dois faire des modifications.

ProgramFiles

C'est pas mes premières heures de dev en C/ arduino pourtant c'est vrai que j'arrive pas à me mettre en tête une solution plus light
Le tableau de char + la boucle ça je saurais faire, mais quand la boucle correspond comment faire ?

Code: [Select]
int on_key[]={8960,4380,600,520,580,520,580,520,580,520,580,520,580,520,580,520,580,520,580,1620,600,1600,600,1620,580,1620,600,1600,600,1620,580,540,560,1620,600,520,580,520,580,520,560,540,560,540,560,540,560,540,560,540,560,1620,600,1600,600,1620,580,1620,580,1620,600,1600,600,1620,600,1600,600,40660,8940,2180,580};

void setup() {                
 pinMode(IRledPin, OUTPUT);   //Broche N°13 est une sortie.  
 Serial.begin(9600);          //Initialisation Serial Monitor.
 inputString.reserve(200);
}

void send_key(int sizeKey,int key[])
{
 for(int i = 0; sizeKey >= i; i++)
 {
   if ( (i % 2) == 0) {
      pulseIR(key[i]);
   } else {
     delayMicroseconds(key[i]);
   }
 }
}

Ce code contient la fonction d'envoi + un tableau de int qui défini la touche "on"

Le seul moyen serait des variables à nom dynamique mais c'est pas possible...
Je sais qu'il y a une astuce pour le faire, mais j'ai plus l'exemple en tête.

skywodd


Mon avis qui n'engage que moi m'autorise a penser que déjà un type "String" sur un microcontrôleur qui n'a que quelques octets de mémoire ça ne devrais même pas exister.

Cette classe ne devrait tout simplement pas exister, c'est un caprice de la team Arduino qui voulait faire "comme Java", en moins bien.


Une fois compilé ça fait du code qui bouffe de la place et de la mémoire a foison (et du temps de calcul aussi) le plus souvent pour faire des trucs qui auraient été bien plus efficients avec des tableaux de char.

Ça bouffe plus de place (RAM / flash), ça incite à l'utilisation de méthode de codage suicidaire (str += c; par exemple) et histoire de bien foutre en l'air le tout ça fait de l'allocation dynamique de mémoire à tout bout de champ.


Peut-être bien, mais le code est quand même aux "normes" non ? ça devrait fonctionner ?

Il n'y as pas de "normes" en soit, mais quand on voit qu'un code n'est pas lisible c'est qu'il y a un probléme.


ça devrait fonctionner ?

La preuve que non.

Quote
Le seul moyen serait des variables à nom dynamique mais c'est pas possible...
Je sais qu'il y a une astuce pour le faire, mais j'ai plus l'exemple en tête.

Oula ...

Les grandes lignes :
- une structure "IrCommand" contenant deux champs :
-- int ircode
-- char command[16]
- un tableau de struct "irCmdTable" (ci dessus) contenant les associations commande => code IR
-- ce tableau est mis en flash grâce via "const PROGMEM ..."

Setup()
- pinMode(IRledPin, OUTPUT)
- Serial.begin(9600)

Loop()
- char buffer[32]
- struct IrCommand tmp
- n = Serial.readBytesUntil('\n', buffer, 32)
- Si n == 0 : return
- buffer[n] = '\0'
- pour i = 0 à i = NB_CODE_IR par pas de +1:
-- chargement du contenu de irCmdTable dans tmp (voir la fonction memcpy_PF())
-- test si strcmp(tmp.command, buffer) == 0
--- vrai -> send_ir(tmp.ircode)
-- fin boucle

A toi de faire la suite ;)
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

ProgramFiles

Oulà, les struct j'ai appris à en faire mais je m'en suis jamais servi pour le moment j'ai ça:

Code: [Select]
struct IrCommand {
  int ircode;
  char command[16];
};

struct IrCommand irCmdTable[21];

irCmdTable[1].ircode = 1;
irCmdTable[1].command = "on";


mais ça fonctionne pas, pourtant d'après les exemples ça correspond mais je trouve pas ou est le problème, ircode contient bien un numéro de commande et non pas un tableau de int contenant les pulsations Ir ?

Go Up