Серийное чтение Arduino - PullRequest
4 голосов
/ 22 мая 2009

Я работаю на веб-управляемом ровере и использую последовательный порт для связи с Arduino . Я написал PHP, который просто использует fwrite() и записывает ASCII 1 или ASCII 2 в последовательный порт. Arduino слушает этот порт и делает то, что слышит. Я знаю, что мой PHP работает, потому что всякий раз, когда я говорю, чтобы он отправлял что-то, Arduino получает его. Вот код 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
    }
}

Так что это должно быть довольно просто. Прямо сейчас, когда я отправляю ASCII 1 или ASCII 2, светодиод, с которым я тестирую (на выводе 13), включается и остается включенным. Но если я отправлю другой ASCII 1 или 2, он выключится, а затем снова включится. Цель состоит в том, чтобы включить его, только если ASCII 1 был последней отправленной вещью, и оставаться включенным до тех пор, пока 2 не будет последней отправленной вещью.

Редактировать: вот мой 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>

Ответы [ 4 ]

1 голос
/ 22 мая 2009

Как уже упоминал Николай, похоже, что вы выполняете присваивание (=), а не сравнение (==) в своих выражениях "if".

Хорошая привычка, в которую входят некоторые программисты на С, - помещать значения r в левой части сравнений, чтобы компилятор выдавал ошибку, если вы случайно используете оператор присваивания вместо оператора сравнения:

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

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

Это работает, независимо от того, какие флаги компилятора или уровень предупреждения вы используете, поскольку присвоение rvalue недопустимо.

Я должен добавить, что эта «сеть безопасности» не работает, если вам нужно сравнить два значения.

1 голос
/ 22 мая 2009

Если это C, то у вас есть назначение вместо сравнение в обоих тестах, поэтому оба - true, поэтому все записи выполняются каждый раз. Компилировать с высоким уровнем предупреждения (например, -Wall -pedantic в GCC). Попробуйте это:


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

Из PHP-кода, который вы разместили (я здесь не эксперт), похоже, что вы пишете двоичный 1 как символ, который не ASCII 49, а ASCII 1 (soh), то же самое для 2. Попробуйте изменить его на '1' в коде PHP (или 1 в коде C).

Вот ссылка на статью о Управление последовательным портом с помощью PHP - Я погуглил, понятия не имею о его качестве - но не похоже, что достаточно просто написать целое число в «com1» - это вне моего домена, так что удачи:)

0 голосов
/ 02 января 2012

Я нашел ваш ответ, ища другие вещи, в любом случае, я просто столкнулся (наверное) с той же проблемой, что и у вас.

Если вы еще не решили эту проблему, я думаю, что проблема не в вашем коде, а в механизме автоматического сброса на плате Arduino. То есть: каждый раз, когда на последовательном порте устанавливается новое соединение, плата arduino сбрасывается, что позволяет загружать новую прошивку при программировании через последовательный порт.

Чтобы убедиться в этом, попробуйте мигать светодиодом в функции setup(), если он мигает при каждой загрузке страницы, это подтверждает мой тезис.

Посмотрите здесь: http://www.arduino.cc/playground/Main/DisablingAutoResetOnSerialConnection

Я решил, вставив резистор на 120 Ом между +5 В и RESET. Не забывайте удалять его каждый раз, когда вы хотите загрузить новую прошивку на свою плату.

0 голосов
/ 03 декабря 2010

Может быть слишком поздно, но я думаю, что ваша проблема в том, что serial.read () читает только один символ за раз. Если вы отправите «49» с ПК, при вызове usbnumber = serial.read () вы получите «4» в первом цикле и «9» во втором цикле. Ни один из них не удовлетворяет условиям, поэтому ничего не делается, и номер USB сбрасывается до 0.

Чтобы исправить, вы можете изменить условие serial.available на

if (Serial.available() == 2)

, а затем выполните что-то вроде следующего, чтобы преобразовать в число:

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

Другой вариант - использовать библиотеку TextFinder - я написал краткое руководство на своем веб-сайте http://mechariusprojects.com/thunderbolt/?p=60

Мех

...