Denis Yuriev

Записки бездельника

Главная » Linux » OpenWRT » OpenWRT - эксперимент с Arduino

OpenWRT — эксперимент с Arduino

Сегодняшняя статья поистине уникальна для этого блога.
Дело в том, что впервые автор не я, а читатель. Некоторое время, еще осенью, я помогал человеку советами в обмен на компенсацию кофем, в итоге получили интересный эксперимент, который на практике трудно применим, но ознакомиться с ним думаю многим будет интересно.
Эксперимент проводился на базе D-Link DIR-320 Rev.A1
Итак, ниже то что прислал мне тот самый читатель, Андрей Глинчиков

Симбиоз OpenWRT и Arduino

Суть сей небольшой статьи — доработка DIR-320 для вывода системной информации на LCD-дисплей с помощью Arduino.

Подключаем Arduino к OpenWRT

Роутер имеет последовательный порт (UART), который мы и будем использовать для вывода данных.
Нам необходимо два пина — GND и TX
Подключаем их к Arduino:

DIR-320 | Arduino
--------+--------
GND     | GND
TX      | RX

LCD подключаем через I2C шилд:

Arduino | I2C
--------+----
GND     | GND
5V      | VCC
A4      | SDA
A5      | SCL

Для совместимости роутера и Arduino необходимо задать скорость порта UART. Для этого через SSH необходимо сначала прочитать скорость порта:

# stty -F /dev/ttyS0 -a|grep speed
speed 115200 baud; rows 0; columns 0; line = 0;

Итак, у нас скорость 115200. Если отличается, то задаем нужную:

# stty -F /dev/ttyS0 115200 clocal cread cs8 -cstopb -parenb

Программируем Arduino

Далее необходимо прошить скетч в нашу Arduino для вывода информации.

#include 
#include 
 
// инициализируем библиотеку LCD
LiquidCrystal_I2C lcd(0x27,16,2);
 
void ScreenSaver()
{
 int i;
 lcd.clear();
 lcd.setCursor(0,0);
 lcd.print(" D-Link DIR-320 ");
 lcd.setCursor(0,1);
 lcd.print("  &   Arduino   ");
 delay(3000);
 lcd.clear();
 for (i=0;i<8;i++)
  {
   lcd.setCursor(i,0);
   lcd.print("=");
   lcd.setCursor(16-i-1,0);
   lcd.print("=");
   delay(200);
  }
 lcd.clear();
}
 
void setup(){
 // устанавливаем параметры дисплея: 
 lcd.begin();
 // инициализируем последовательный порт:
 Serial.begin(115200); //здесь не забываем указать скорость вашего порта роутера
}
 
void loop()
{
 char s;
 if (Serial.available()) 
 {
  delay(100);
  while (Serial.available() > 0) 
  {
   s=Serial.read();

   if (s=='^') {
    switch (Serial.read()) {
     case '1':  
      lcd.setCursor(0,1);
      Serial.read();
      break;
     case '0':
      lcd.setCursor(0,0); 
      Serial.read();
      break;
     case 'c':
      lcd.clear(); 
      Serial.read();
      break;
     case 's':
      Serial.read();
      ScreenSaver();
      break;
     } //switch
    }
   else {
    // Выводим каждый символ на LCD
    lcd.write(s);
   }
  }
 }
}

Для проверки работоспособности вывода на роутере:

# echo "Hello, world!" > /dev/ttyS0

Работает? Замечательно! Продолжаем.

Выводим необходимые нам данные на LCD-экран

Далее нам необходим создать скрипт для вывода интересующей нас информации на LCD-экран.

Пример для получения погоды для Белокаменной Столицы нашей необъятной Российской федерации.

Создаем скрипт /root/lcd:

#!/bin/sh

wget http://xml.meteoservice.ru/export/gismeteo/point/37.xml -O /root/37.xml
port="/dev/ttyS0"

lcdWrite() {
 #Вывод на экран
 echo -n "^"${1}:$2 > $port
}

lcdClear() {
 #Очистка экрана
 echo -n "^c:" > $port
}

lcdScreenSaver() {
 #Запуск заставки
 echo -n "^s:" > $port
}

WidgetLoad() {
 #Отображение загрузки процессора
 s=`/usr/bin/uptime`
 s2=":"
 for i in 1 2 3 4 5 6
 do #Удаляем всё лишнее до последнего двоеточия
  n=`expr index "$s" "$s2"`
  s="${s:$n}"
 done
 s="${s:1}" #Удаляем первый символ (пробел)
 lcdClear
 lcdWrite 0 "CPU"
 lcdWrite 1 "$s"
}

WidgetUptime() {
 #Аптайм роутера
 set `/usr/bin/uptime`
 lcdClear
 lcdWrite 0 "Uptime"
 lcdWrite 1 "$3 ${4/,/}"
}

WidgetRAM() {
 #Свободная память
 set `free | grep "Mem:"`
 lcdClear
 lcdWrite 0 "RAM (KB)"
 lcdWrite 1 "U:$3 F:$4"
}

WidgetHDD() {
 #Свободное место в /opt
 set `df -h | grep "/dev/sda2"`
 lcdClear
 lcdWrite 0 "HDD"
 lcdWrite 1 "U:$3 F:$4"
}

WidgetDateTime() {
 #Дата и время
 set `date`
 lcdClear
 lcdWrite 0 "Date:$3 $2 $6"
 lcdWrite 1 "Time:$4"
}

WidgetWeather() {
 #Погода
 set `cat /root/37.xml | grep "TEMPERATURE"`
 lcdClear
 lcdWrite 0 "Temp (Morning)"
 ind=`expr index "$6" "/>"` #определяет позицию "/>" в строке
 ind=`expr $ind - 1` #отнимаем единицу
 k=`expr substr "$6" 1 $ind` #в переменную k записываем часть строки до "/>"
 lcdWrite 1 "${k/min/Mn} ${5/max/Mx}"
 sleep 5
 lcdClear
 lcdWrite 0 "Temp (Day)"
 ind=`expr index "$9" "/>"` #определяет позицию "/>" в строке
 ind=`expr $ind - 1` #отнимаем единицу
 k=`expr substr "$9" 1 $ind` #в переменную k записываем часть строки до "/>"
 lcdWrite 1 "${k/min/Mn} ${8/max/Mx}"
 sleep 5
 lcdClear
 lcdWrite 0 "Temp (Night)"
 ind=`expr index "$12" "/>"` #определяет позицию "/>" в строке
 ind=`expr $ind - 1` #отнимаем единицу
 k=`expr substr "$12" 1 $ind` #в переменную k записываем часть строки до "/>"
 lcdWrite 1 "${k/min/Mn} ${11/max/Mx}"
 sleep 5
}

#Main script
while [ : ]
do
 WidgetUptime
 sleep 5
 WidgetLoad
 sleep 5
 WidgetRAM
 sleep 5
 WidgetHDD
 sleep 5
 WidgetDateTime
 sleep 5
 WidgetWeather
done

Проверяем

# /root/lcd

Работает? Отлично!
Добавляем оба скрипта в автозагрузку.
(Я использовал CRON)

Теперь необходимо все наше оборудование разместить в корпусе!

Сделай приятное автору - поделись статьей в социальной сети.

5 Комментариев

  1. Вот вы зря сказали, что трудноприменимо. Взять шестибаксовый роутер с ибея на RT5350, ЮСБ-звукашку, какойнибудь Picoduino (вполне можно обойтись и голой атмелиной или ПИКом, но тут тупо дешевле по комплектухе и удобней в монтаже), и LCD по вкусу — и будет чудесный интернет-радиоприёмник с названиями композиций и погодой :)
    Ту же Ардуинку можно заставить опрашивать кнопки и управлять приёмником — переключать станции или регулировать громкость.

    При обдумывании похожей хотелки поначалу было нежелание цеплять внешние «мозги» и управлять напрямую с GPIO SoC. Но китайцы упорно не выводят неиспользуемые пины наружу, а подцепиться напрямую на брюхо BGA практически нереально. Иногда даже жалею за всякими TQFP/SSOP, к которым уцепиться — пара пустяков :)

  2. Тогда уж проще взять китайский планшет (что-то из тех, что в корпусе Q88 за 40баксов) или самый дешёвый смарт, и успокоиться :)

    Но как гриться, этим в основном занимаются ради самого процесса :D

  3. Equus

    Equus

    Хм, а можно ли запустить на openwrt реальный графический интерфейс через VNC? :D

Оставьте комментарий

Войти с помощью: 
Denis Yuriev DMOZ Индекс цитирования

© 2017