Подружим PHP и Arduino

Тема в разделе "Arduino & Shields", создана пользователем Denis.cpp, 9 дек 2012.

  1. Витя

    Витя Гик

    Это не важно - php просто получает набор байт вот и все. fread указано читать по 1 байту вот он и читает по одному. А даже один байт можно по разному воспринимать. Например как целое число от 0 до 255. Или как число со знаком, тогда получится 1 бит уйдет на знак а остальные 7 на само число и получится от -128 до 128. И даже тут может быть еще разница, например в какой последовательности биты записаны. Т.е. бит знака старший или младший? А еще один байт можно считать как символ и тогда нужно смотреть таблицу ASCII чтобы знать что показать. А может кто то передал символ в unicode тогда символ может быть из двух байт и из четырех. В каждом языке программирования есть описание того как у него устроены его типы данных и соответвено как он будет их понимать. И тут могут быть ошибки. Например в одних языках строки состоят из длины+сама строка. Причем длина может быть 1, 2, 4 байта. А в других строка это строка+нулевой байт. А еще в одних и то и другое вместе. Поэтому записав набор байт в одном очень вероятно что в другом просто так строку нельзя будет прочитать сходу. Нужно специально написать код который ее правильно распознает и создаст.
     
  2. hibiki

    hibiki Гик

    мда, о считанном нуле я не подумал, сорри :(

    попробуйте
    Код (Text):
    echo bin2hex($c);
    в цикл вставить
     
  3. Denis.cpp

    Denis.cpp Нерд

    PHP:
    <?php
    $content = "";
    $handle = fopen("com6", "rb+");
    if (!$handle) die ("Печалька! Порт не открылся!");
    {
        echo "Порт открыт!";
            while ($c = fread($handle,1))
            {
                $content .= $c;
                echo "Я тут!";
            }
    }  
    fclose($handle);
    ?>
    Выводит порт открыт, но не попадает в тело цикла.
     
  4. Denis.cpp

    Denis.cpp Нерд

    По идее как я понял у меня должна быть до цикла проверка на 0?А до проверки на 0 проверка на данные?
     
  5. hibiki

    hibiki Гик

    вместо цикла while поставьте
    Код (PHP):
    echo bin2hex( fread($handle,1) );
    очень хочется посмотреть, считывается ли хоть что-то
     
  6. Denis.cpp

    Denis.cpp Нерд

    PHP:
    <?php
    $content = "";
    $handle = fopen("com6", "rb+");
    if (!$handle) die ("Печалька! Порт не открылся!");
    {
        echo "Порт открыт!";
        echo bin2hex( fread($handle,1) );  
    }  
    fclose($handle);
    ?>
    выводит порт открыт, и всё больше кроме этой фразы ничего не появляется
     
  7. hibiki

    hibiki Гик

    красота. а оно завершается или висит на fread()?
     
  8. Витя

    Витя Гик

    Наверное просто события отсылки данных и их приема не совпадают?

    По правилам нужно ОС попросить сообшить когда там данные появятся но у php я не нашел таких функций. Значит нужно просто сделать вечный цикл:
    PHP:
    do {
      echo bin2hex( fread($handle,1) );
    } while (1);
    И предусмотреть сигнал от ардуино по которому выходить из цикла. И по таймеру чтобы навечно там не застрять.
     
  9. Denis.cpp

    Denis.cpp Нерд

    PHP:
    <?php
    $content = "";
    $handle = fopen("com6", "rb+");
    if (!$handle) die ("Печалька! Порт не открылся!");
    {
        echo "Порт открыт!";
        echo bin2hex( fread($handle,1) );  
    }  
    echo "Вышел!";
    fclose($handle);
    echo "Закрылся!";
    ?>
    Выводит :Порт открыт!Вышел!Закрылся!
     
  10. hibiki

    hibiki Гик

    да в php тоже тайм-ауты чтения настраиваются как-то, только платформоспецифично. не помню.

    классно, ничего не прочитал, что ли?
    точно ком-порт тот?
     
  11. Denis.cpp

    Denis.cpp Нерд

    ОООООО смотрите!!!Оно что то пишет!
    PHP:
    <?php
    $content = "";
    $handle = fopen("com6", "rb+");
    if (!$handle) die ("Печалька! Порт не открылся!");
    {
        do
        {
        echo bin2hex( fread($handle,1) );
        }  
        while (1);
    }  
    echo "Вышел!";
    fclose($handle);
    echo "Закрылся!";
    ?>
    выдаёт следущее :

    0d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932330d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932330d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932330d0a3932330d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a3932330d0a3932320d0a3932320d0a3932320d0a3932330d0a3932320d0a3932320d0a3932330d0a3932320d0a3932320d0a3932320d0a3932330d0a3932320d0a3932320d0a3932320d0a3932320d0a3932320d0a393232

    и ещё 5 листов вот сверху приведенных символов потом говорит вот эту строчку снизу

    Fatal error: Maximum execution time of 30 seconds exceeded in Z:\home\defzone.ru\www\process3.php on line 8

    В это время постоянно падал луч лазера на фоторезистор собственно с которого мы считываем информацию, на моиторе порта они около 920-930 я вот что думаю оно ввыдаёт что то похожее только что со всем теперь этим делать ? как это привести к нормальным цифрам?
     
  12. Denis.cpp

    Denis.cpp Нерд

    Что интересно то то что когда я выключаю лазер выдаёт уже другое, а это говорит о том что он действитель что то читает!
    0a3132340d0a3132340d0a3132340d0a3132340d0a3132340d0a3132340d0a3132340d0a3132340d0a3132340d0a3132340d0a3132340d0a3132340d0a3132340d0a3132340d0a313
    и потом опять
    Fatal error: Maximum execution time of 30 seconds exceeded in Z:\home\defzone.ru\www\process3.php on line 8
     
  13. hibiki

    hibiki Гик

    ну, лимит на время выполнения скрипта у вас 30 секунд просто.

    а что в цифры? за один проход цикла вы читаете из порта один байт. собственно, в этих строках каждые два символа - шестнадцатиричное представление этого самого байта.

    как байты собирать в число зависит от того, как вы записываете его в порт. можно код посмотреть?
     
    Denis.cpp нравится это.
  14. Denis.cpp

    Denis.cpp Нерд

    PHP:
    <?
    $fp =fopen("com6", "w");
    fwrite($fp, chr(49));
    fclose($fp);
    ?>
    так осуществляется запись в порт.

    скетч ардуины выглядит вот так:

    Код (Text):
    int sensor_pin = 0;
    int laser_pin = 13;
    int pir_pin = 2;
    int pir_led_pin = 4;
    int laser_led_pin = 3;
    int usbnumber = 0;
    void setup()
    {
      analogReference(DEFAULT);
      pinMode(laser_pin, OUTPUT);
      pinMode(pir_led_pin, OUTPUT);
      pinMode(sensor_pin, INPUT);
      pinMode(pir_pin, INPUT);
      pinMode(laser_led_pin, OUTPUT);
      Serial.begin(9600);
    }
     
    void loop()
    {
      Serial.println(analogRead(sensor_pin));
     
      if(Serial.available()>0)
      {
        usbnumber = Serial.read()-'0';
        Serial.println(usbnumber);
      }
      if(usbnumber > 0)
      {
        if(usbnumber == 1)
        {
          digitalWrite(laser_pin, HIGH);
        }
        else
        {
          digitalWrite(laser_pin, LOW);
        }
      }
     
     
    if(digitalRead(pir_pin) == HIGH)
    {
      digitalWrite(pir_led_pin, HIGH);
    }
    else
    {
      digitalWrite(pir_led_pin, LOW);
    }
     
    if(analogRead(sensor_pin) < 900)
    {
      digitalWrite(laser_led_pin, HIGH);
    }
    else
    {
      digitalWrite(laser_led_pin, LOW);
    }
     
    }
    код чтения с сенсора выглядит вот так
    PHP:
    <?php
    $content = "";
    $handle = fopen("com6", "rb+");
    if (!$handle) die ("Печалька! Порт не открылся!");
    {
        do
        {
        echo bin2hex( fread($handle,1) );
        }  
        while (1);
    }  
    echo "Вышел!";
    fclose($handle);
    echo "Закрылся!";
    ?>
     
  15. Витя

    Витя Гик

    0d0a - это "перевод каретки" типа enter короче. Он появляется из-за println в скетче. А остальное - это число. Например 39 32 32 в hex значит 922 в dec т.е. число передается в виде строки.

    План:
    1. нужно сначала дождаться когда ардуино закончит писать какое-то значение, которое он у вас постоянно пишет. Для этого надо ждать пока не прийдет символ с кодом 0xA.
    PHP:
    while (fread($handle, 1) != 0xA) { }
    как только он будет прочитан, дальше нужно прочитать строку.
    PHP:
    $a = fgets($handle);
    Теперь с ней можно работать как с числом тоже.
     
    Denis.cpp нравится это.
  16. Denis.cpp

    Denis.cpp Нерд

    PHP:
    <?php
    $content = "";
    $handle = fopen("com6", "rb+");
    if (!$handle) die ("Печалька! Порт не открылся!");
    {
        while (fread($handle, 1) != 0xA)
        {
            $a = fgets($handle);
            echo $a;
        }
    }  
    echo "Вышел!";
    fclose($handle);
    echo "Закрылся!";
    ?>
    29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 92 9 29 929 2 9 30 929 2 29 929 2 9 29 929 2 9 29 929 3 9 29 92 9 29 929 2 9 29 929 2 9 29 929 2 9 29 2 9 29 929 2 9 29 929 2 9 29 929 2 29 929 2 9 29 929 2 9 29 929 2 9 29 92 9 29 929 2 9 29 929 2 9 29 929 2 9 929 2 9 29 929 2 9 29 929 2 9 29 929 9 29 929 2 9 29 929 2 9 29 929 2 9 29 2 9 29 929 2 9 29 929 2 9 29 929 2 29 929 2 9 29 929 2 9 29 929 2 9 29 92 9 29 929 2 9 29 929 2 9 29 929 2 9 29 2 9 29 929 2 9 29 929 2 9 29 929 2 29 929 2 9 29 929 2 9 29 9 вот такое печатает) всё правильно только почему то некоторые печатает 929 целым числом каким оно должно быть а некоторые 29 к его правильно отформматировать но уже напоминает как мой пример c HT... ещё есть куча интересных вопросов а как поступить например если у тебя два датчика или более как обрабатывать значения с нескольких датчиков?
     
  17. Denis.cpp

    Denis.cpp Нерд

    Парни БОЛЬШОЕ ВАМ ЧЕЛОВЕЧЕСКОЕ СПАСИБО!!!Я неделю колдовал с записью в порт и неделю с чтением хорошо что вы мне помогли, вот где бы про всё это дело по подробнее почитать?
     
  18. Denis.cpp

    Denis.cpp Нерд

    Я походу начал понимать почему происходят такие обрывы вот я точно знаю что у меня приходит с порта значение 929(посмотрел в мониторе порта) , но у меня то приём данных идёт по байтно, значит может получаться что в одном байте может уехать уехать пол значения, а другая часть приедет в другом байте я правильно понимаю?
     
  19. Витя

    Витя Гик

    Не! Мой код должен быть как я написал с пустыми скобками. Фишка в чем скрипт подключается к ардуине в непонятный момент и она там может слать что угодно. Т.е. подключится можно с середины например числа которое она посылает. Поэтому нужно пропустить всё пока не появится символ 0xA это значит что дальше будет нормальное значение. Поэтому мы типа читаем все до этого символа и больше ничего не делаем.

    PHP:
    <?php
    $content = "";
    $handle = fopen("com6", "rb+");
    if (!$handle) die ("Печалька! Порт не открылся!");
    {
        while (fread($handle, 1) != 0xA) { }
        $a = fgets($handle);
        echo $a;
    }
    echo "Вышел!";
    fclose($handle);
    echo "Закрылся!";
    ?>
    Не полбайта не может прочитаться. Это по идее так все поломалось из за того что fgets читала 0xD символ.

    Чтобы читать два значения их нужно как-то разделить. Послать например первое число, пробел, второе число. Например я вот нашел в php функцию fscanf. Она может делать разбор строки.

    PHP:
    $a = fscanf($handle, "%d %d\n");
    list ($datchik1, $datchik2) = $a;
     
    Вот заменить fgets этим. В переменных $datchik1 и $datchik2 будут значения нужные.
     
  20. Denis.cpp

    Denis.cpp Нерд

    PHP:
    <?php
    $content = "";
    $handle = fopen("com6", "rb+");
    if (!$handle) die ("Печалька! Порт не открылся!");
    {
        while (fread($handle, 1) != 0xA) { }
        $a = fgets($handle);
        echo $a;
    }
    echo "Вышел!";
    fclose($handle);
    echo "Закрылся!";
    ?>
    Вот этот код не работает! Я всё же думаю что это {} операторные скобки , которые нужны для выделения цикла и выдаеёт ошибку Fatal error: Maximum execution time of 30 seconds exceeded in Z:\home\defzone.ru\www\process3.php on line 8 вообще она постоянно её выдаёт... просто в этот раз без каких либо значений.