• Sky
  • Blueberry
  • Slate
  • Blackcurrant
  • Watermelon
  • Strawberry
  • Orange
  • Banana
  • Apple
  • Emerald
  • Chocolate
  • Charcoal

Уроки

Sign in to follow this  
Followers 0
  • entries
    10
  • comments
    14
  • views
    36070

Contributors to this blog

9. Управление светодиодом через браузер и Omega2

Sign in to follow this  
Followers 0
Админ

2037 views

Всем привет!

Сегодня я расскажу, как сделать простую PHP-страницу, закинуть ее на Omega2, и управлять на этой странице подключенным светодиодом (а по сути GPIO пинами).
Для начала обязательно расширьте память омеги, если вы это еще не сделали, инструкция здесь. Также рекомендую установить какой-нибудь файл-менеджер по типу WinSCP, инструкция здесь.

Итак, приступим.

Для чистоты эксперимента, я сделал полный сброс омеги до системных настроек, для этого я через терминал выполнил поочередно три команды (либо можно было зажать на 10 секунд кнопку перезагрузки на док-станции):

firstboot -y
sync
reboot

1. Устанавливаем PHP на Omega2

Я постараюсь написать все понятно, но если что, вот официальная документация: https://docs.onion.io/omega2-docs/installing-and-using-php.html 
Для начала обновляем список пакетов:

opkg update

И за тем устанавливаем необходимые пакеты:

opkg install php7 php7-cgi

2. Настраиваем PHP на Omega2

Отлично, теперь идем и открываем файл /etc/config/uhttpd (еще раз напоминаю про файловый менеджер WinSCP из начала статьи). Добавляем в раздел config uhttpd ‘main’ две строчки, которые содержат адрес расположения PHP-интерпретатора, а также имя страницы по-умолчанию.

list interpreter ".php=/usr/bin/php-cgi"
option index_page 'index.php'

Должно получиться примерно так:

config uhttpd 'main'
    list listen_http '0.0.0.0:80'
    list listen_http '[::]:80'
    list listen_https '0.0.0.0:443'
    list listen_https '[::]:443'
    option redirect_https '1'
    option home '/www'
    option rfc1918_filter '1'
    option max_requests '3'
    option max_connections '100'
    option cert '/etc/uhttpd.crt'
    option key '/etc/uhttpd.key'
    option cgi_prefix '/cgi-bin'
    option script_timeout '60'
    option network_timeout '30'
    option http_keepalive '20'
    option tcp_keepalive '1'
    option ubus_prefix '/ubus'
    list interpreter ".php=/usr/bin/php-cgi"
    option index_page 'index.php'

config cert 'defaults'
    option days '730'
    option bits '2048'
    option country 'ZZ'
    option state 'Somewhere'
    option location 'Unknown'
    option commonname 'LEDE'

Сохраняем файл и перезапускаем WEB-сервер Omega2 через консоль следующей командой:

/etc/init.d/uhttpd restart

3. Тестируем

Если вы знакомы с серверами, хостингами и прочими словами, то знаете, что все файлы хранятся в папке www. Omega2, как маленький сервер не стал исключением. 
Заходим в папку /www , создаем там папку test, и в ней файл index.php cо следующим содержимым:

<?php
  echo "Hello, World!";
?>

Все, теперь открываем браузер, переходим по адресу http://192.168.3.1/test/ и видим следующее:

1.JPG

Если нет, возможно вы допустили ошибку где-то здесь:

  1. Не сделали рестарт сервера (описано выше)
  2. Не туда дописали код в файле uhttpd (надо писать не в конец файла, а в конец первого блока)
  3. По каким-то причинам выставлены не те права доступа на папку test, они должны быть 755 (можно задавать в том же WinSCP либо через терминал)

Поздравляю, PHP успешно установлено и функционирует на вашей омеге. Теперь переходим к практическому применению.

4. Управляем светодиодом через PHP

Для начала соберем супер сложнейшую схему:

2.jpg

Как видите, плюс светодиода подключили на первый GPIO-контакт Omega 2, а минус на землю (GND). Соответственно включать/выключать светодиод мы будем устанавливая логические 0 и 1 на первом пине омеги.

4.1 Создаем Python файл для вкл/выкл светодиода
Если вы ранее не устанавливали питоновский интерпретатор, то сделайте это последовательно введя 3 команды в консоль (посмотреть установленные пакеты можно командой opkg list-installed):

opkg update
opkg install python
opkg install pyOnionGpio

Заходим в папку /root и в ней создаем файл text.py. Пишем в него следующий код:
 

import onionGpio

# define pins
PIN_NUMBER   = 1

# define states
ON      = 1
OFF     = 0

# instantiate gpio objects
NASH_PIN = onionGpio.OnionGpio(PIN_NUMBER)

# initialize to output
status = int(NASH_PIN.getValue())
NASH_PIN.setOutputDirection(status)

# body
if status == 1:
    status = OFF
else:
    status = ON   
NASH_PIN.setValue(status)
print "LED Status = "+str(status) 

Сохраняем файл.

Краткое описание кода: подключаем библиотеку onionGpio, затем устанавливаем 3 константы (номер пина и статусы ON, OFF), обзываем объект третьего пина как NASH_PIN, считываем уровень третьего пина, указываем OUTPUT направление третьего пина (в скобках указано значение по-умолчанию, если не указать будет ошибка). Ну и на последок узнаем статус пина (0 или 1) и устанавливаем обратное.

Распространенные ошибки:

  • Иногда требуется добавлять str() и int(), чтобы преобразовать переменные в текстовые и числовые. Если это не сделать, в чем ошибка, иногда можно не понять. 
  • В языке Python условия и циклы создаются не с помощью символов { } или begin end, а с помощью равных отступов, то есть если внутри IF’а будет одна строка с отступом в 4 пробела, а другая в 1 таб (что визуально выглядит одинаково), то условие работать не будет.

Чтобы проверить код, открываем консоль и пишем:

python /root/test.py

Должно получиться так:

3.JPG

4.2 Создаем HTML и PHP файлы

Отлично, научились включать светодиод скриптом. Теперь открываем папку /www и создаем там 2 файла go.html – по сути оболочка, и knopka.php – файл, который будет связывать «оболочку» и файл test.py. Сразу скажу, что в JavaScript я не силен, поэтому заимствовал код с просторов интернета и подкорректировал под свои нужды.

Содержимое go.html:

<title>Omega2 Control</title>
 
<script type="text/javascript">
function getXmlHttpRequestObject()    // функция создания нового объекта XMLHttpRequest
{    var x;
    if (window.XMLHttpRequest)    // мы в нормальном браузере?
    {    // если в нормальном (IE7+, Firefox,Chrome, Opera, Safari) - создаём объект
        x=new XMLHttpRequest();    // создаём объект XMLHttpRequest
    }
    else x=false;    // если в ненормальном - болт
    return x;    // возвращаем указатель на созданный объект
}
 
// глобальные переменные
var top_http;        // здесь будем хранить указатель на объект XMLHttpRequest
var stat;        // эта переменная нужна чтобы опознать, что ответ получен и обработан
var elements_col;    // количество переменных, которые мы будем запрашивать/получать
 
function handleTop()    // обработчик ответа сервера
{    if(top_http.readyState == 4)    // если запрос выполнен (4 - состояние complete)
    {    if(top_http.status == 200)    // если статус ответа - 200 ( Ok! )
        {    var value = top_http.responseText;    // получаем в переменную текст ответа
            var ArrVal=value.split(';');        // разделяем ответ на массив параметров (параметры пришли через 
            var obj_tag;                // здесь будет указатель на контейнер
            var i=0;                // это просто счётчик
            elements_col=ArrVal[0];    // количество элементов, которые нужно обработать 
                                // первый переданный элемент - это общее кол-во параметров
                                // (пар id/значение), а далее сами пары id/значение
            while(i<elements_col)
            {    // проверяем, есть ли на странице контейнер с нужным id?
                obj_tag=document.getElementById(ArrVal[2*i+1]);
                if(obj_tag)                    // если есть
                {    // меняем текст внутри него на принятый от сервера
                    obj_tag.innerHTML = ArrVal[2*i+2];
                }
                i=i+1;    // проверяем следующий элемент
            }
            stat=1;    // меняем статус (1 - ответ получен и обработан)
        }
    }
}
 
function sendTop()    // В этой функции мы формируем запрос и отправляем его на сервер
{    stat=0;    // сбрасываем статус (0 - ответ не получен и не обработан)
    top_http = getXmlHttpRequestObject();    // вызываем функцию создания объекта XMLHttpRequest
    top_http.onreadystatechange = handleTop;// цепляем на onreadystatechange обработчик ответа
                        // (когда он придёт - автоматически запустится функция handle_top)
    var url='/knopka.php';        // строка запроса (запустить на сервере файл /knopka.php)
 
    top_http.open('GET', url, true);    // настраиваем асинхронный запрос с адресом url
                        // (это url от корня того сервера, с которого загружена страница)
    top_http.setRequestHeader('If-Modified-Since','0');    // добавляем заголовки
    top_http.setRequestHeader('Cache-Control','no-cache');    
    top_http.send(null);    // отправляем пустой запрос (поскольку у GET запроса
                            // нет тела, всё, что нужно, - запихано в url)
}
</script>
 
<!-- добавим глобальный стиль для таблиц и для кнопок -->
<style type="text/css">
    td    {    border: 1px solid blue; 
            padding: 10px; 
        }
    td.button
        {    background-color: #CF12F1;
            box-shadow: 0 -3px #35A76E inset;
        }
    td.button:hover
        {    background-color: #35A76E;
        }
    td.button:active
        {    background-color: #21935A;
            box-shadow: 0 3px #21935A inset;
        }
</style>
 
<table style="border: 1px solid blue">
<tbody>
<tr>
<td class="button" onclick="sendTop()">Omega2 LED Click</td>
<td id="result"></td>
</tr>
</tbody>
</table>

Содержимое knopka.php:

<?php
$result = shell_exec('python /root/test.py');
$answer = "1;result;".$result;    // записываем в переменную строку ответа
echo $answer;    // вывод ответа (он будет отправлен обратно на страницу, с которой вызван скрипт)
?>

Сохраняем файлы.

5. Запуск!

Теперь открываем браузер, переходим по адресу http://192.168.3.1/go.html и молимся :)

После нажатия кнопки должно получиться так:

5.JPG 

4.jpg

Таким образом, go.html при нажатии кнопки вызывает knopka.php, а та в свою очередь инициализирует запуск test.py, получает от нее ответ и передает его обратно в go.html (текст “LED Status = …”). 

Для закрепления результата еще приконектился с телефона:

На этом все! Надеюсь у вас все получилось!


Sign in to follow this  
Followers 0


0 Comments


There are no comments to display.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now