Pages: [1] 2   Go Down
Author Topic: [Aide] Comment structurer mon programme  (Read 1301 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 37
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonjour (bonsoir) à vous,
j'aurais besoin de vos lumière pour structurer mon programme parce que je tourne un peu en rond...

Voici a quoi ça doit ressembler (version courte pour le principe)

Code:
...
switch (results.value) {
  case 175: AA();
  break;
  case 695: BB();
  break;
}

void AA() {
  analogWrite (ledA, 0);
  analogWrite (ledB, 255);
  delay(1000);
  analogWrite (ledA, 255);
  analogWrite (ledB, 0);
  delay(1000);
}

void BB() {
 ...
}

Je souhaiterai que quand j’appelle la fonction AA, elle s'exécute en boucle tant que je ne fais pas appel à une autre fonction.
Idem si j'appelle la fonction BB.

Si une âme charitable veut bien me donner une solution ;-)

Merci à vous.
« Last Edit: February 18, 2012, 04:56:25 pm by Vortof » Logged

0
Offline Offline
God Member
*****
Karma: 2
Posts: 802
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Yep!

Cà depend si tu veux rester dans la boucle ou si tu veux que ton programme continue les instructions suivantes.

Dans le premier cas, un simple while devrait suffire. Dans le second, il faudra gérer une ou plusieurs interruptions.

Decris nous un peu la nature de la condition qui doit te faire sortir de la boucle : digital, analogique, serial, tempo, compteur ???

@+

Zoroastre.

Logged

Veuillez indiquer [RESOLU] dans l'entête du titre en éditant votre premier message smiley-wink

0
Offline Offline
Newbie
*
Karma: 0
Posts: 37
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Description du système:

une télécommande IR envoie le code de la touche pressée sur la Pin digitale 11 (-> results.value)
à chaque code IR correspond une fonction qui doit s'exécuter en boucle tant qu'un autre code IR n'est pas reçu.
à la réception d'un nouveau code IR, on passe à une autre fonction, en boucle jusqu’au prochain code IR.

merci pour ton aide.
« Last Edit: February 18, 2012, 05:36:10 pm by Vortof » Logged

Forum Moderator
Geneva
Offline Offline
Faraday Member
*****
Karma: 30
Posts: 3227
Yoplait... le pt'it suisse
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Dans la boucle principale qui va gérer l'IR, je mettrais une variable en char et qui changerait avec l'IR.
Ensuite tu appelles tes fonctions comme ça :

Void loop()
{
IR;
char();
}

Void char ()
{
}
« Last Edit: February 19, 2012, 01:55:56 am by Jean-François » Logged

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

0
Offline Offline
God Member
*****
Karma: 2
Posts: 802
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Yep!

L'idée de Jean-François (simple et efficace) est de renvoyer le resultat dans une fonction à chaque cycle (loop).

Code:
void loop() {

  // Récuperation de results.value via Ir
...
  routine(results.value);
...
}

void routine(int value) {
  switch(value) {
    case 175 : ...; break;
    case 695 : ...; break;
  }
}

@+

Zoroastre.
Logged

Veuillez indiquer [RESOLU] dans l'entête du titre en éditant votre premier message smiley-wink

0
Offline Offline
Newbie
*
Karma: 0
Posts: 37
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hmm... merci à vous deux.
je vais essayer de tester ça cet après-midi et je vous tiens au courant.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 37
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

bon j'ai suivi l'exemple, ça donne si je ne me suis pas trompé:

Code:
...
void loop() {

if (irrecv.decode(&results)) {
  routine(results.value);
...
}

void routine(int value) {
  switch(value) {
    case 175 :
      analogWrite (ledA, 0);
      analogWrite (ledB, 255);
      delay(1000);
      analogWrite (ledA, 255);
      analogWrite (ledB, 0);
      delay(1000);
    break;
    case 695 : ...; break;
  }
}

Dans le cas où le récepteur IR reçoit la valeur 175, on exécute bien case 175 mais qu'une seule fois. Il faudrait que case 175 tourne en boucle jusqu'à ce que le récepteur reçoive une autre valeur.

J'ai essayé avec des while. Ca boucle bien, mais j'arrive plus à sortir de la boucle du coup :-(
Logged

Made in Belgium
Offline Offline
God Member
*****
Karma: 1
Posts: 756
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

utilise plutôt une variable global pour conservé la dernière valeur reçue ("if (irrecv.decode(&results))" bloque un second appel à "routine()") de ton récepteur comme ça tu peux comparé la dernière valeur tout au long et partout dans ton programme et donc ici boucler cette valeur via loop.
Utilise également des if plutôt que du switch case (ça revient au même) , ça te permettra également d'ajouter d'autres critères dans tes conditions if si besoin.
Évite également la fonction delay qui risque de bloqué ton code (dans ce delay), donc la bonne réception de commandes.
Voir: http://arduino.cc/en/Tutorial/BlinkWithoutDelay

Code:
int value // en global
...
void setup()
{
  ...
}

void loop()
{
  if(irrecv.decode(&results))
  {
    value = results.value;
  }
  routine();
...
}

void routine()
{
  if(value == 175)
  {
      analogWrite (ledA, 0);
      analogWrite (ledB, 255);
      delay(1000);
      analogWrite (ledA, 255);
      analogWrite (ledB, 0);
      delay(1000);
  }
  else if(value == 695)
  {
    ...
  }
  else if(value == ...)
  {
    ...
  }

...

}
« Last Edit: February 19, 2012, 12:31:51 pm by osaka » Logged


0
Offline Offline
Newbie
*
Karma: 0
Posts: 37
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ne trouvant pas de solution à mon problème, je vais le laisser un peu de coté et poursuivre sur le reste de mon projet.

Je pense qu'il doit y avoir un problème avec   irrecv.resume();   dans le loop(), ça doit bloquer un truc...
Plus tard donc.

Merci quand même.
Logged

France
Offline Offline
Faraday Member
**
Karma: 36
Posts: 3425
There is an Arduino for that
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

en variable globale tu déclares un pointeur vers une fonction
Code:
void (*func)(void);  // pointeur vers une fonction qui ne reçoit pas d'argument et ne retourne rien

dans loop tu appelles func

Code:
void loop() {

if (irrecv.decode(&results)) {
  routine(results.value);
}

func();
...
}

et dans ta gestion du code reçu tu affectes les fonction AA, BB, .... à func en fonction du code reçu

Code:
void routine(int code){
   switch(code){
      case xx: func=(void*)AA;break;
      case xx: func=(void*)BB;break;
      case xx: func=(void*)CC;break;
   }
}

edit
ATTENTION: il ne faut pas oublier de faire pointer func vers une fonction par défaut (une fonction qui ne fait rien par exemple)
« Last Edit: March 04, 2012, 06:25:14 am by fdufnews » Logged

France
Offline Offline
Faraday Member
**
Karma: 36
Posts: 3425
There is an Arduino for that
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

On peut aussi imaginer une variante utilisant un tableau de pointeurs vers des fonctions.
Cela permets des "fantaisies" comme la création de séquences par exemple
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 37
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

merci fdufnews pour ton aide, je vais tenter ton exemple.
J'ai du mal avec les pointeurs, je n'ai toujours pas compris comment ça fonctionne, comment ça s'écrit... pourquoi * est des fois dans la parenthèse des fois non... enfin c'est un truc obscur pour moi.


Code:
void routine(long code){
   switch(code){
      case 16775175: func=(void*)AA; break;
      case 16750695: func=(void*)BB; break;
      case 16767015: func=(void*)CC; break;

error: invalid conversion from 'void*' to 'void (*)()'     pour les 3 lignes

je dois bien déclarer AA comme ça ?
Code:
void AA() {
  analogWrite (ledR, 255);
  analogWrite (ledG, 0);
  analogWrite (ledB, 0);


OK pour la fonction par défaut.

« Last Edit: March 05, 2012, 03:08:01 am by Vortof » Logged

France
Offline Offline
Faraday Member
**
Karma: 36
Posts: 3425
There is an Arduino for that
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
void AA(void) {
  analogWrite (ledR, 255);
  analogWrite (ledG, 0);
  analogWrite (ledB, 0);
...
}
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 37
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hmmm... la subtilité...
je teste en rentrant, merci.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 37
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ca ne fonctionne toujours pas :-(
fdufnews si t'as une idée et un peu de temps, merci à toi.

Voici le code, c'est juste pour tester et quand ça fonctionnera... pour un projet plus gros
Code:
#include <IRremote.h>

int receiver = 11; // pin Data du recepteur IR
int ledR = 3; // pin led Rouge
int ledG = 5; // pin led Verte
int ledB = 6; // pin led Bleue

IRrecv irrecv(receiver); // crée une intance de 'irrecv'
decode_results results;

// pointeur vers une fonction qui ne reçoit pas d'argument et ne retourne rien
void (*func)(void);

void setup(){
  Serial.begin(9600);
  irrecv.enableIRIn(); // démarre le receiver
 
  pinMode(ledR, OUTPUT); // pin en sortie
  pinMode(ledG, OUTPUT);
  pinMode(ledB, OUTPUT);
}

void loop() {

  if (irrecv.decode(&results)) {
    routine(results.value);
   
    Serial.println(results.value); // affiche le code en décimal
   
    irrecv.resume(); // reçoit la valeur suivante
  }

  func();

}

void routine(long code){
   switch(code){
      case 16775175: func=(void*)AA; break;
      case 16750695: func=(void*)BB; break;
      case 16767015: func=(void*)CC; break;
      case 16746615: func=(void*)DD; break;
      case 16734375: func=(void*)EE; break;
      defaut: RGB(0,0,0);
   }
}

// affichage RGB
void RGB(int R, int G, int B) {
  analogWrite (ledR, R);
  analogWrite (ledG, G);
  analogWrite (ledB, B);
}
 
void AA(void){ RGB(0,0,0);}
void BB(void){ RGB(255,0,0);}
void CC(void){ RGB(0,255,0);}
void DD(void){ RGB(0,0,255);}

void EE(void){
  RGB(0,0,255);
  RGB(0,255,0);
  RGB(0,255,255);
  RGB(255,0,0);
  RGB(255,0,255);
  RGB(255,255,0);
  RGB(255,255,255);
  RGB(0,0,255);
  RGB(0,255,0);
  RGB(0,255,255);
  RGB(255,0,0);
  RGB(255,0,255);
  RGB(255,255,0);
}

Et les erreurs:
In function 'void routine(long int)'
error: invalid conversion from 'void*' to 'void (*)()' -> pour les 5 lignes commençant par 'case'
Logged

Pages: [1] 2   Go Up
Jump to: