2009-05-22 6 views
4

Je travaille sur un mobile contrôlé par le Web et j'utilise un port série pour communiquer avec un Arduino. J'ai écrit du PHP qui utilise juste fwrite() et écrit un ASCII 1 ou un ASCII 2 sur le port série. L'Arduino écoute ce port et fait des choses en fonction de ce qu'il entend. Je sais que mon PHP fonctionne, parce que chaque fois que je lui dis d'envoyer des choses, l'Arduino le reçoit. Voici le code Arduino:lecture de série Arduino

//This listens to the serial port (USB) and does stuff based on what it is hearing. 

int motor1Pin = 13; //the first motor's port number 
int motor2Pin = 12; //the second motor's port number 
int usbnumber = 0; //this variable holds what we are currently reading from serial 


void setup() { //call this once at the beginning 
    pinMode(motor1Pin, OUTPUT); 
    //Tell arduino that the motor pins are going to be outputs 
    pinMode(motor2Pin, OUTPUT); 
    Serial.begin(9600); //start up serial port 
} 

void loop() { //main loop 
    if (Serial.available() > 0) { //if there is anything on the serial port, read it 
     usbnumber = Serial.read(); //store it in the usbnumber variable 
    } 

    if (usbnumber > 0) { //if we read something 
     if (usbnumber = 49){ 
      delay(1000); 
      digitalWrite(motor1Pin, LOW); 
      digitalWrite(motor2Pin, LOW); //if we read an ASCII 1, stop 
     } 

     if (usbnumber = 50){ 
       delay(1000); 
       digitalWrite(motor1Pin, HIGH); 
       digitalWrite(motor2Pin, HIGH); //if we read an ASCII 2, drive forward 
     } 

     usbnumber = 0; //reset 
    } 
} 

Donc, cela devrait être assez simple. À l'heure actuelle, lorsque j'envoie un ASCII 1 ou un ASCII 2, la DEL avec laquelle je teste (sur la broche 13) s'allume et reste allumée. Mais, si j'envoie un autre ASCII 1 ou 2, il s'éteint puis se rallume. Le but est de l'allumer seulement si un ASCII 1 était la dernière chose envoyée et de rester jusqu'à ce que 2 soit la dernière chose envoyée.

Edit: Voici mon PHP:

<?php 
    $verz="0.0.2"; 
    $comPort = "com3"; /*change to correct com port */ 

    if (isset($_POST["rcmd"])) { 
     $rcmd = $_POST["rcmd"]; 
     switch ($rcmd) { 
      case Stop: 
       $fp =fopen($comPort, "w"); 
       fwrite($fp, chr(1)); /* this is the number that it will write */ 
       fclose($fp); 


       break; 
      case Go: 
       $fp =fopen($comPort, "w"); 
       fwrite($fp, chr(2)); /* this is the number that it will write */ 
       fclose($fp); 
       break; 
      default: 
       die('???'); 
     } 
    } 
?> 
<html> 
    <head><title>Rover Control</title></head> 
    <body> 
     <center><h1>Rover Control</h1><b>Version <?php echo $verz; ?></b></center> 

     <form method="post" action="<?php echo $PHP_SELF;?>"> 
      <table border="0"> 
       <tr> 
        <td></td> 
        <td> 

        </td> 
        <td></td> 
       </tr> 
       <tr> 
        <td> 
         <input type="submit" value="Stop" name="rcmd"><br/> 
        </td> 
        <td></td> 
        <td> 
         <input type="submit" value="Go" name="rcmd"><br /> 
        </td> 
       </tr> 
       <tr> 
        <td></td> 
        <td><br><br><br><br><br> 

        </td> 
        <td></td> 
       </tr> 
      </table> 
     </form> 
    </body> 
</html> 

Répondre

1

Si c'est C, alors vous avez cession au lieu de comparaison dans les deux essais, de sorte que les deux sont true, donc toutes les écritures sont faites à chaque fois. Compiler avec un niveau d'avertissement élevé (comme -Wall -pedantic dans GCC). Essayez ceci:


int a = 0; 
if (a == 1) printf("a is not one: %d\n", a); 
if (a = 1) printf("a is one: %d\n", a); 

à partir du code PHP que vous avez publié (je ne suis pas un expert ici), il semble que vous écrivez binaire 1 en tant que char, qui est non ASCII 49, mais ASCII 1 (SOH), même pour 2. Essayez de changer à '1' dans le code PHP

Voici un lien vers un certain article sur Controlling the Serial Port with PHP (ou 1 en code C.) - Je googlé, aucune idée de sa qualité - mais ne ressemble pas il suffit de il suffit d'écrire un entier dans "com1" - c'est hors de mon domaine, donc bonne chance :)

+0

J'ai changé cela et maintenant la led ne s'allume plus du tout. Cela doit signifier qu'il ne lit pas un ascii 1 ou 2 droit? – blueintegral

+0

Pouvez-vous vous connecter/imprimer en quelque sorte ce que vous recevez? Publiez également votre code PHP - cela aidera à affiner le problème. –

+0

Si j'essaie d'utiliser le moniteur série qui est intégré à l'environnement arduino, PHP se plaint que le port COM n'est pas disponible pour écrire, – blueintegral

1

Comme Nikolai mentionné, il semble que vous faites l'affectation (=) rat elle que la comparaison (==) dans vos "if" déclarations.

Une bonne habitude que certains programmeurs C prendre est de mettre rvalues ​​sur le côté gauche de comparaisons, de sorte que le compilateur génère une erreur si vous utilisez accidentellement l'opérateur d'affectation au lieu de l'opérateur de comparaison:

 
if (50 == usbnumber) { // This is okay. 
    ... 
} 

if (50 = usbnumber) { // The compiler will generate an error here. 
    ... 
} 

Cela fonctionne, quels que soient les indicateurs de compilation ou le niveau d'avertissement que vous utilisez, car l'affectation à une valeur rvalue est illégale.

Je devrais ajouter que ce «filet de sécurité» ne fonctionne pas si vous avez besoin de comparer deux valeurs.

+0

Oui, ça marche, même si pour une raison quelconque cette notation m'a toujours paru fausse :) –

+0

Comme je l'ai dit, c'est une bonne habitude que certains programmeurs * C rencontrent: P Certains programmeurs C n'entrent jamais dans cette habitude (même les bons). Il faut définitivement s'y habituer avant de ne plus se sentir «mal». –

0

Peut-être trop tard, mais je pense que votre problème est que serial.read() ne lit qu'un caractère à la fois. Si vous envoyez "49" du PC, quand vous appelez usbnumber = serial.read() vous obtiendriez "4" la première boucle et "9" la deuxième boucle. Aucun d'entre eux ne remplit les conditions, donc rien n'est fait et usbnumber est remis à 0.

Pour corriger, vous pouvez soit changer de série.état disponible pour être

if (Serial.available() == 2) 

puis faire quelque chose comme ce qui suit pour convertir en nombre:

usbnumber = Serial.read() * 10 + Serial.read(); 

Une autre option consiste à utiliser la bibliothèque TextFinder - J'ai écrit un bref tutoriel sur mon site http://mechariusprojects.com/thunderbolt/?p=60

Mech

+0

En fait, il suffit de relire votre question - il vaut probablement la peine de faire Serial.println (usbnumber) pour voir ce que vous obtenez, mais il peut être aussi simple que de vérifier si usbnumber == 1 ou usbnumber == 2 –

0

J'ai trouvé votre réponse à la recherche d'autres choses, de toute façon je viens de face (je suppose) le même problème que vous aviez.

Dans le cas où vous ne l'avez pas encore résolu, je pense que les problèmes ne sont pas votre code, mais le mécanisme de réinitialisation automatique sur la carte Arduino. C'est-à-dire qu'à chaque fois qu'une nouvelle connexion est établie sur le port série, la carte arduino est réinitialisée, ce qui permet de charger un nouveau firmware lors de la programmation via le port série.

Pour vérifier cela, essayez de faire clignoter une LED dans votre fonction setup(), si elle clignote chaque fois que vous chargez la page, cela confirme ma thèse.

Jetez un oeil ici: http://www.arduino.cc/playground/Main/DisablingAutoResetOnSerialConnection

Je résolu en collant la résistance 120 ohms entre + 5 V et RESET. N'oubliez pas de l'enlever chaque fois que vous voulez télécharger un nouveau firmware sur votre carte.