Pages: [1]   Go Down
Author Topic: Caractères non pris en compte dans un test "if"  (Read 725 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonjour,

Nous travaillons actuellement sur un projet de "mail notifier" en utilisant un Arduino Uno. Concrètement il s'agit d'allumer des leds quand on reçoit des nouveaux mails.

Pour déterminer le nombre de mails non lus, on allume parmi 4 leds la valeur équivalente en binaire. On passe par un script php pour récupérer le nombre de mails. Pour cette variable, chaque nombre entre 0 et 15 correspond à l'envoie d'un caractère en particulier.
Nous avons essayé d'envoyer directement la valeur de la variable "mails" mais celle-ci n'est pas prise en compte dans le programme Arduino.
Par la suite nous avons envoyé un caractère, mais nous nous sommes confrontés à un problème puisque certains caractères ne sont pas traités dans le test du programme Arduino (par exemple le caractère 'L', ou tous les chiffres alpha-numériques).
Nous avons aussi essayé une structure switch / case qui ne marche ni dans le PHP ni dans le code Arduino.

Est-ce quelqu'un a déjà rencontré ces problèmes et les a résolu?

En vous remerciant par avance pour vos réponses !


PS : Ci-dessous le code php et Arduino que nous utilisons.

PHP :
Code:
<?php
include ("php_serial.class.php");

function 
Arduino($str){
$serial = new phpSerial();
$serial->deviceSet("COM4");
$serial->confBaudRate(19200);
$serial->confParity("none");
$serial->confCharacterLength(1);
$serial->confStopBits(1);
$serial->confFlowControl("none");
$serial->deviceOpen();
if($str==0)
$serial->sendMessage('A');
if($str==1)
$serial->sendMessage('B');
if($str==2)
$serial->sendMessage('D');
if($str==3)
$serial->sendMessage('G');
if($str==4)
$serial->sendMessage('H');
if($str==5)
$serial->sendMessage('K');
if($str==6)
$serial->sendMessage('M');
if($str==7)
$serial->sendMessage('N');
if($str==8)
$serial->sendMessage('P'); 
if($str==9)
$serial->sendMessage('S'); 
if($str==10)
$serial->sendMessage('U'); 
if($str==11)
$serial->sendMessage('V'); 
if($str==12)
$serial->sendMessage('w'); 
if($str==13)
$serial->sendMessage('x'); 
if($str==14)
$serial->sendMessage('Y');
if($str==15)
$serial->sendMessage('Z');
        
$serial->deviceClose();
}
Arduino($mail);
?>


ARDUINO :
Code:
const int ledPin1 = 2;
const int ledPin2 = 4;
const int ledPin3 = 7;
const int ledPin4 = 8;
int incomingByte;

void setup() {
  Serial.begin(19200);
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);
  pinMode(ledPin4, OUTPUT);
}

void loop() {
  if (Serial.available() > 0) {
    incomingByte = Serial.read();
   
    //switch(incomingByte) {
   
    if (incomingByte == 'A') {
      digitalWrite(ledPin1, LOW);
      digitalWrite(ledPin2, LOW);
      digitalWrite(ledPin3, LOW);
      digitalWrite(ledPin4, LOW);
    }
   
   else if (incomingByte == 'B') {
      digitalWrite(ledPin1, HIGH);
      digitalWrite(ledPin2, LOW);
      digitalWrite(ledPin3, LOW);
      digitalWrite(ledPin4, LOW);
   }
   
     else if (incomingByte == 'D') {
      digitalWrite(ledPin1, LOW);
      digitalWrite(ledPin2, HIGH);
      digitalWrite(ledPin3, LOW);
      digitalWrite(ledPin4, LOW);
    }
   
     else if (incomingByte == 'G') {
      digitalWrite(ledPin1, HIGH);
      digitalWrite(ledPin2, HIGH);
      digitalWrite(ledPin3, LOW);
      digitalWrite(ledPin4, LOW);
    }
   
     else if (incomingByte == 'H') {
      digitalWrite(ledPin1, LOW);
      digitalWrite(ledPin2, LOW);
      digitalWrite(ledPin3, HIGH);
      digitalWrite(ledPin4, LOW);
    }
    else if (incomingByte == 'K') {
      digitalWrite(ledPin1, HIGH);
      digitalWrite(ledPin2, LOW);
      digitalWrite(ledPin3, HIGH);
      digitalWrite(ledPin4, LOW);
    }
     else if (incomingByte == 'M') {
      digitalWrite(ledPin1, LOW);
      digitalWrite(ledPin2, HIGH);
      digitalWrite(ledPin3, HIGH);
      digitalWrite(ledPin4, LOW);
    }
     else if (incomingByte == 'N') {
      digitalWrite(ledPin1, HIGH);
      digitalWrite(ledPin2, HIGH);
      digitalWrite(ledPin3, HIGH);
      digitalWrite(ledPin4, LOW);
    }
     else if (incomingByte == 'P') {
      digitalWrite(ledPin1, LOW);
      digitalWrite(ledPin2, LOW);
      digitalWrite(ledPin3, LOW);
      digitalWrite(ledPin4, HIGH);
    }
     else if (incomingByte == 'S') {
      digitalWrite(ledPin1, HIGH);
      digitalWrite(ledPin2, LOW);
      digitalWrite(ledPin3, LOW);
      digitalWrite(ledPin4, HIGH  );
    }
     else if (incomingByte == 'U') {
      digitalWrite(ledPin1, LOW);
      digitalWrite(ledPin2, HIGH);
      digitalWrite(ledPin3, LOW);
      digitalWrite(ledPin4, HIGH);
    }
     else if (incomingByte == 'V') {
      digitalWrite(ledPin1, HIGH);
      digitalWrite(ledPin2, HIGH);
      digitalWrite(ledPin3, LOW);
      digitalWrite(ledPin4, HIGH);
    }
     else if (incomingByte == 'w') {
      digitalWrite(ledPin1, LOW);
      digitalWrite(ledPin2, LOW);
      digitalWrite(ledPin3, HIGH);
      digitalWrite(ledPin4, HIGH);
    }
     else if (incomingByte == 'x') {
      digitalWrite(ledPin1, HIGH);
      digitalWrite(ledPin2, LOW);
      digitalWrite(ledPin3, HIGH);
      digitalWrite(ledPin4, HIGH);
    }
     else if (incomingByte == 'Y') {
      digitalWrite(ledPin1, LOW);
      digitalWrite(ledPin2, HIGH);
      digitalWrite(ledPin3, HIGH);
      digitalWrite(ledPin4, HIGH);
    }
   
   else if (incomingByte == 'Z') {
      digitalWrite(ledPin1, HIGH);
      digitalWrite(ledPin2, HIGH);
      digitalWrite(ledPin3, HIGH);
      digitalWrite(ledPin4, HIGH);
    }
  }
}
Logged

Offline Offline
Edison Member
*
Karma: 17
Posts: 1967
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

bonjour,
déjà as tu essayé d'afficher ce que tu recois via un Serial.print(incomingByte) ?

tu ne dis pas si tu recois ou non les caractères, donc un peu difficile de répondre.

change ton A par 65 pour tester.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Par quels moyens peut-on voir ce que l'on reçoit dans le code Arduino puisque l'on n'utilise pas d'afficheur ?

Nous avons remplacé le caractère C par 67, et ça ne marche pas quand même (Le caractère A fonctionne de base).
Logged

France
Offline Offline
Faraday Member
**
Karma: 55
Posts: 5347
Arduino Hacker
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonjour,

Le code PHP et le code Arduino sont un peu bancales ...

Concernant le code PHP :
- tout tes if imbriqué peuvent ce réduire à un tableau + un sendMessage()
Code:
$cmd = Array('A', 'B', 'D', 'G', 'H', 'K', 'M', 'N', 'P', 'S', 'U', 'V', 'W', 'X', 'Y');
$serial->sendMessage($cmd[intval($str)]);
- si tu n'active pas "l'auto flush" ou que tu n'appelles pas serialFlush() rien n'est envoyé sur le port série (buffer interne)
- la variable $mail de ton code d'exemple n'est pas assigné avant d'être utilisé

Concernant le code Arduino :
- remplace tes if imbriqués par un switch/case
- incomingByte n'as pas besoin d'être une variable globale
- si tu utilisais des commandes d'un caractère qui se suivent vraiment (A, B, C, D, ...) il te suffirait d'une soustraction + test binaire pour faire tout tes digitalWrite().
(même plus besoin de switch)

Exemple :
Code:
// ...
void loop() {
  if (Serial.available() > 0) {
    byte value = Serial.read() - 'A';
    digitalWrite(ledpin1, (value & 1) ? HIGH : LOW);
    digitalWrite(ledpin2, (value & 2) ? HIGH : LOW);
    digitalWrite(ledpin3, (value & 4) ? HIGH : LOW);
    digitalWrite(ledpin4, (value & 8) ? HIGH : LOW);
  }
}
« Last Edit: February 06, 2013, 02:44:40 am by skywodd » Logged

Des news, des tuto et plein de bonne chose sur http://skyduino.wordpress.com !

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

Je pense que skywodd voulait dire:
Code:
// ...
void loop() {
  if (Serial.available() > 0) {
    byte value = Serial.read() - 'A';
    digitalWrite(ledpin1, (value & 1)? HIGH : LOW);
    digitalWrite(ledpin2, (value & 2)? HIGH : LOW);
    digitalWrite(ledpin3, (value & 4)? HIGH : LOW);
    digitalWrite(ledpin4, (value & 8)? HIGH : LOW);
  }
}
« Last Edit: February 05, 2013, 03:59:17 pm by fdufnews » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Merci pour ces réponses ! Concernant le point sur la variable $mail. Elle est en fait définie juste en dessus dans le code qui permet de se connecter à la boite mail :

Code:
if ($mail_cnx = imap_open ("{".$serveur_entrant.$port.$protocole."}".$boite, $identifiant, $mot_de_passe) ) {
                                          $status = imap_mailboxmsginfo($mail_cnx);
  $mail = $status->Unread;
  echo "Unread message(s) in your mailbox : ".$status->Unread."</br>";
  }
  imap_close($mail_cnx);

L'astuce du tableau dans le code PHP est très intéressante je n'y avais pas pensé ! Je conçois également que le code soit bancale. En fait j'ai à peu près tout tester et seule cette version donnait un résultat satisfaisant malgré le fait qu'elle ne soit pas très élégante.

Je vais donc essayer de mettre en place ces propositions et de faire appel à serialFlush(). C'est peut-être de là que vient mon problème au niveau des caractères qui ne sont pas reconnus dans les tests.

En vous remerciant encore pour ces réponses rapides !

Bonne soirée.
Logged

France
Offline Offline
Faraday Member
**
Karma: 55
Posts: 5347
Arduino Hacker
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Je pense que skywodd voulait dire:
Code:
// ...
void loop() {
  if (Serial.available() > 0) {
    byte value = Serial.read() - 'A';
    digitalWrite(ledpin1, (value & 1) ? HIGH : LOW);
    digitalWrite(ledpin2, (value & 2) ? HIGH : LOW);
    digitalWrite(ledpin3, (value & 4) ? HIGH : LOW);
    digitalWrite(ledpin4, (value & 8) ? HIGH : LOW);
  }
}
Oui ... si je commence à foirer mes if inline ça va pas le faire smiley-mr-green

Je vais donc essayer de mettre en place ces propositions et de faire appel à serialFlush(). C'est peut-être de là que vient mon problème au niveau des caractères qui ne sont pas reconnus dans les tests.
À voir aussi si la librairie phpSerial ajoute un retour ligne ou non à la fin des messages ?
Logged

Des news, des tuto et plein de bonne chose sur http://skyduino.wordpress.com !

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonjour,

Nous avons essayé la fonction Serial.flush() mais celle ci ne résout pas nos problèmes... Plus précisément lorsque l'on envoie le caractère 'B', par exemple, le caractère est reconnu par Arduino et la boucle if s'effectue correctement. Si l'on décide d'envoyer un autre caractère à la place (par exemple L) les commandes à l'intérieur de la boucle "if" ne sont pas exécutées...

Comment se fait il que certains caractères ne soient pas pris en compte par certains test conditionnels ? (Y a-t-il des affectations de caractères réservées de base ?).

Merci d'avance.

Logged

France
Offline Offline
Faraday Member
**
Karma: 55
Posts: 5347
Arduino Hacker
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Comment se fait il que certains caractères ne soient pas pris en compte par certains test conditionnels ?
-> code actuel (arduino et PHP) ?

(Y a-t-il des affectations de caractères réservées de base ?).
Non.
Logged

Des news, des tuto et plein de bonne chose sur http://skyduino.wordpress.com !

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

J'ai pu tester le code Arduino seul avec le moniteur série et après avoir casté la variable "incomingbyte", le fonctionnement est correct et tous les caractères sont bien pris en comptes. Cela doit donc venir du PHP quand j'envoie la commande sur le port série (ou à la réception de l'Arduino mais c'est surement moins probable).

Il faut que je trouve un moniteur qui puisse me permettre de voir les éléments qui transit sur le port série. Car afficher les variables de session sur une page PHP ne semble pas suffisant car en amont de l'envoi sur le port série.
Logged

France
Offline Offline
Faraday Member
**
Karma: 55
Posts: 5347
Arduino Hacker
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Il faut que je trouve un moniteur qui puisse me permettre de voir les éléments qui transit sur le port série. Car afficher les variables de session sur une page PHP ne semble pas suffisant car en amont de l'envoi sur le port série.
Outils windows semi-officiel pour sniffé le trafic d'un port série :
http://technet.microsoft.com/en-us/sysinternals/bb896644.aspx
Logged

Des news, des tuto et plein de bonne chose sur http://skyduino.wordpress.com !

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Super ! Merci beaucoup ! Je vais tester ça du coup !
Logged

Pages: [1]   Go Up
Jump to: