Управляем цветом блока на странице сайта с помощью ардуины

Тема в разделе "Глядите, что я сделал", создана пользователем uniudra, 17 фев 2013.

  1. uniudra

    uniudra Нерд

    Не знаю, можно ли назвать проектом то, что я опишу ниже.

    Меня, как программиста, очень зацепила фраза "С помощью ардуины можно программно менять реальный мир", или наоборот "Реальный мир может менять ход логики программы с помощью ардуины". Попытаюсь сделать первые шаги в этом направлении.

    Дано: Ардуина, переменный резистор, настроенный LAMP сервер.
    Задача: При прокручивании ручки переменного резистора менять цвет блока на странице сайта.

    И так, начнем.
    Среднюю ногу резистора прикручиваем к аналоговому входу A0.
    Крайние ноги резистора присоединяем к 5V и земле.
    Присоединяем USB шнур к компьютеру на котором работает LAMP.
    Скетч для Arduino очень прост:
    Код (Text):
    void setup() {
      Serial.begin(9600);
    }
     
    void loop() {
      int sensorValue = analogRead(A0);
      Serial.println(sensorValue);
    }
    Все просто, считываем показатели входа и отправляем на последовательный порт.

    А вот и HTML-код странички с блоком.
    HTML:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
            "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
     
    <head>
      <title>SerialChangeColor</title>
      <meta http-equiv="content-type" content="text/html;charset=utf-8" />
      <link rel="stylesheet" href="style.css" />
      <script src="jquery.js"></script>
      <script src="script.js"></script>
    </head>
     
    <body>
      <div id="square"></div>
    </body>
     
    </html>
    Мы будем менять цвет блока #square.

    style.css
    Код (Text):
    #square {
      height: 200px;
      width: 200px;
      margin: 10px;
      border: 1px solid #000;
    }
    Все, страничка готова, ардуина готова. Самое интересное начинается тут. Забирать данные с ардуины мы будем с помощью php-класса php_serial. Напишем файл json.php, который будет брать данные с порта, приводить их в нужный нам вид и выдавать результат в JSON-данные.
    PHP:
    include "php_serial.class.php";
     
    // setup serial communication
    $serial = new phpSerial;
    $serial->deviceSet("/dev/ttyACM0");
    $serial->confBaudRate(9600);
    $serial->confParity("none");
    $serial->confCharacterLength(8);
    $serial->confStopBits(1);
    $serial->confFlowControl("none");
    $serial->deviceOpen();
     
    // wait sime time to get the data and read it.
    usleep(100000);
    $data = $serial->readPort();
     
    // get data, normalize it and echo JSON.
    $array = explode("\r\n", $data);
    $values = array_count_values($array);
    arsort($values);
    $key = (reset(array_flip($values)));
    $result = round(($key * 255) / 1023);
    echo json_encode(array($result));
     
    $serial->deviceClose();
    Тут все просто. Первый блок открывает соединение. Второй ждет 100 миллисекунд пока данные прийдут от ардуины.

    Третий блок интереснее. За 100 миллисекунд ардуина успевает передать на скрипт около 10-15 значений, разделенных разрывом строки. Интересно то, что значения всега идут с погрешностью +1 или -1, например 100 101 100 100 101 100. Именно поэтому я высчитываю количество каждого значения и принимаю наибольшее как верное.

    Немного о цвете. Для формирования цвета я буду просто менять значение зеленого канала. Аналоговый вход ардуины принимает число от 0 до 1023, которое я преобразую в 0-255 в третьем блоке.

    Готово. Итоговое значение я запаковываю в JSON.

    Ну а вот сам JavaScript, который каждые 500 миллисекунд запрашивает JSON и окрашивает блок в нужный цвет.
    Код (Text):
    $(document).ready(function() {
      var $container = $("#square");
     
      // automatically refresh containter every 0.5 second.
      var refreshId = setInterval(function() {
        $.getJSON("json.php", function(data){
          var $color = 'rgb(0,' + data[0] + ',0)';
          $container.css("background-color", $color);
        });
      }, 500);
     
    });
     
    Все работает отлично! Реальный мир меняет программу :)

    Единственное, что у меня как-то странно работает переменный резистор. Значения от 700 до 1023 он меняет плавно. Все что ниже скачет, например от 0 до 100, потом от 100 до 200. Пока не знаю как это обьяснить.
     
    karagad, nailxx, Danilovdom и ещё 1-му нравится это.
  2. triada13

    triada13 Нуб

    потенциометр в конечных положениях может "искрить'
    лучше всего отступать от конечных положений немного, тогда изменения будут плавными.
     
  3. uniudra

    uniudra Нерд

    Спасибо за ответ. Но мне не совсем понятно как вы предлагаете отступать отступать от конечных значений.
     
  4. hibiki

    hibiki Гик

    не учитывать значения, меньшие и большие какой-то величины, например
     
  5. uniudra

    uniudra Нерд

    Ну меня такой результат не совсем устраивает. Выходит больше четверти полного оборота ручки никак не будет влиять на цвет. Это как-то не совмем правильно. Хотелось бы как в магнитофоне - плавно.

    А почему резисторы искрят? Может надо подобрать правильно сопротивление? Может это резистор плохой у меня? Буду благодарен за подсказки.
     
  6. Unixon

    Unixon Оракул Модератор

    Резистор у вас какой, многооборотный? Если сопротивление меняется резко, значит либо он слишком грубый by design, либо был испорчен большим током через среднюю ногу. Можно воспользоваться оптическим энкодером, хотя бы от той же старой шариковой мыши. Конструкцию это сильно не усложнит, но от шума избавит кардинально.