Pergunta

Eu estou trabalhando em um rover controlado web e estou usando uma porta serial para se comunicar com um Arduino . Eu escrevi alguns PHP que usa apenas fwrite() e escreve um ASCII 1 ou um ASCII 2 à porta serial. O Arduino é ouvir que a porta e faz coisas com base no que ouve. Eu sei que meu PHP está funcionando, porque sempre que eu diga a ele para enviar o material, o Arduino faz recebê-lo. Aqui está o código 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
    }
}

Portanto, este deve ser bastante para a frente. Agora, quando eu mandar qualquer um ASCII 1 ou um ASCII 2, o LED estou testando com (no pino 13) acende e permanece acesa. Mas, se eu enviar outro ASCII 1 ou 2, ele desliga e depois liga novamente. O objetivo é tê-lo ligar apenas se um ASCII 1 era a última coisa que enviou e ficar no cargo até a 2 era a última coisa enviado.

Edit: Aqui está a minha 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>
Foi útil?

Solução

Se é C, então você tem atribuição em vez de comparação em ambos os testes, então ambos são true, então todas as gravações são feitas a cada vez. Compilar com nível de aviso de alta (como -Wall -pedantic no GCC). Tente isto:


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

A partir de código PHP você postou (eu não sou um perito aqui) parece que você está escrevendo 1 binário como um char, que não é ASCII 49, mas ASCII 1 (soh), mesmo para 2. Tente mudá-lo para '1' em código PHP (ou 1 em código C.)

Aqui está um link para algum artigo sobre Controlando a porta serial com o PHP - Eu pesquisei, nenhuma idéia de sua qualidade - mas não parece que é apenas o suficiente para escrever um inteiro em "com1" - que está fora do meu domínio, então boa sorte:)

Outras dicas

Como Nikolai mencionado, parece que você está fazendo de atribuição (=) em vez de comparação (==) no seu "se" declarações.

Um bom hábito que alguns programadores C entrar é colocar rvalues ??no lado da mão esquerda de comparações, de modo que o compilador irá gerar um erro se você acidentalmente usar o operador de atribuição em vez do operador de comparação:

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

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

Isso funciona, independentemente do que bandeiras do compilador ou nível de aviso que você está usando desde atribuir a um rvalue é ilegal.

Devo acrescentar que esta "rede de segurança" não funciona se você precisa comparar dois lvalues.

Pode ser tarde demais, mas eu acho que o problema é que serial.read () só lê um carácter de cada vez. Se você enviar "49" a partir do PC, quando você chamar usbnumber = serial.read () você estaria recebendo "4" do primeiro loop e "9", o segundo loop. Nenhum destes satisfazer as condições para que nada seja feito e usbnumber é reposto a 0.

Para correção, você pode alterar a condição Serial.available ser

if (Serial.available() == 2)

e, em seguida, fazer algo como o seguinte para converter para um número:

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

Outra opção é usar a biblioteca TextFinder - Eu escrevi um breve tutorial no meu site http: //mechariusprojects.com/thunderbolt/?p=60

Mech

Eu achei a sua resposta à procura de outras coisas, de qualquer maneira eu só enfrentou (eu acho) o mesmo problema que você teve.

No caso de você ainda não tiver resolvido, acho que os problemas não é o seu código, mas o mecanismo de auto-reset na placa arduino. Ou seja:. Cada vez que uma nova ligação é estabelecida na porta serial, a placa Arduino é reposto, este permitindo que um novo firmware a ser carregado ao programar-lo através da porta serial

Para verificar isso, tente piscar um LED em sua função setup(), se ela pisca cada vez que você carregar a página, isso confirma minha tese.

Dê uma olhada aqui: http://www.arduino.cc/playground/Main/DisablingAutoResetOnSerialConnection

I resolvido colando a 120 ohm entre + 5V e RESET. Basta lembrar de removê-lo cada vez que você quer carregar um novo firmware para o seu conselho.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top