Caractères non pris en compte dans un test "if"

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 :

<?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 :

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);
    }
  }
}

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.

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).

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()
$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 :

// ...
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);
  }
}

Je pense que skywodd voulait dire:

// ...
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);
  }
}

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 :

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."
";
						  }
						  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.

fdufnews:
Je pense que skywodd voulait dire:

// ...

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 :grin:

clemjere:
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 ?

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.

clemjere:
Comment se fait il que certains caractères ne soient pas pris en compte par certains test conditionnels ?

-> code actuel (arduino et PHP) ?

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

Non.

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.

clemjere:
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 :

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