DIR-320 + Freeduino: выводим системную информацию на LCD

Я долго думал, как можно сделать простой и удобный мониторинг роутера, а именно нагрузку, свободную память, аптайм и др. В этой статье я расскажу как можно подключить Freeduino к D-Link DIR-320 для вывода системной информации на LCD-дисплей. Всё не так трудно, как может показаться на первый взгляд.
dscf3017

Роутер содержит внутренний последовательный порт, который можно использовать для сервисных функций и отладки.
dscf2807
Его-то мы и задействуем. Его распиновка следующая:
pins
Слева направо:

  • RX — приём
  • NC — не подключается (ключ)
  • VCC — питание (3.3 вольта)
  • GND — земля
  • TX — передача

Для наших нужд нужно только два контакта — GND и TX. Подключаем их к Freeduino: GND к GND, TX к RX (второй контакт).
connect_scheme
LCD подключим к цифровым пинам с 8 по 13.
У меня всё это выглядело так:
dscf2368
dscf2370
dscf2374

Теперь необходимо выяснить скорость порта роутера. Для этого в консоли по SSH/telnet даём команду:
[shell]
root@Router-DIR320:/# cat /proc/tty/driver/serial
[/shell]
Должны увидеть что-то подобное:
serial_ports
Нас интересует строчка
[shell]
0: uart:16550A port:B8000300 irq:3 baud:9585 tx:1009317 rx:0 CTS|DSR|CD
[/shell]
В данном случае скорость порта составляет 9585 бод.

Напишем скетч, который зальём в микроконтроллёр:
[cpp]
#include

// инициализируем библиотеку LCD
LiquidCrystal lcd(12, 13, 11, 10, 9, 8);

void ScreenSaver()
{
int i;
lcd.clear();
lcd.setCursor(0,0);
lcd.print(» D-Link DIR-320 «);
lcd.setCursor(0,1);
lcd.print(» & Freeduino «);
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(16, 2); // инициализируем последовательный порт: Serial.begin(9585); //здесь не забываем указать скорость вашего порта роутера } 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);
}
}
}
}
[/cpp]

Команды, подаваемые на микроконтроллёр будут такими:
^c: — очистить дисплей
^0:text — вывести text на первой строке
^1:text — вывести text на второй строке
^s: — вывести небольшую заставочку 🙂

Проверим работу. Введём в консоли роутера команду:
[shell]
echo «Hello, world!» > /dev/tts/0
[/shell]
На экране должна появиться надпись.
dscf2371
Уже хорошо:)
Теперь необходимо научить маршрутизатор выводить информацию о своём состоянии. Для этого служит следующий скрипт:
lcdduino.sh
[shell]
#!/bin/sh

port=»/dev/tts/0″

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 «Load CPU»
lcdWrite 1 «$s»
}

WidgetWiFiClientsCount() {
#Виджет, показывающий количество подключенных WiFi клиентов
s=`wl assoclist | wc -l`
lcdClear
lcdWrite 0 «Wi-Fi Clients»
lcdWrite 1 «$s»
}

WidgetUptime() {
#Аптайм роутера
s=`/usr/bin/uptime`
s2=»l»
n=`expr index «$s» «$s2″`
n=`expr $n — 3`
s=»${s:0:$n}»
s2=»u»
n=`expr index «$s» «$s2″`
n=`expr $n + 2`
s=»${s:$n}»
lcdClear
lcdWrite 0 «Uptime»
lcdWrite 1 «$s»
}

WidgetRAM() {
#Свободная память
set `cat /proc/meminfo | grep «Mem:»`
n=`expr $4 + $6 + $7`
p=`expr 100 ‘*’ $n / $2`
n=`expr $n / 1024`
lcdClear
lcdWrite 0 «FreeRAM»
lcdWrite 1 «$n Kb ${p}%»
}

WidgetHDD() {
#Свободное место в /opt
set `df | grep «/opt»`
p=`expr 100 ‘*’ $3 / $1`
n=`expr $3 / 1024`
lcdClear
lcdWrite 0 «Free HDD»
lcdWrite 1 «$n Mb ${p}%»
}

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

#Main script
while [ : ]
do
WidgetRAM
sleep 3
WidgetLoad
sleep 3
WidgetUptime
sleep 3
WidgetWiFiClientsCount
sleep 3
WidgetHDD
sleep 3
WidgetDateTime
sleep 3
done
[/shell]

Запускаем скрипт, проверяем.

Скрипт добавляем в автозагрузку. Например, в файл /opt/etc/init.d/rc.firewall , который мы создали ранее.
[shell]
/opt/etc/scripts/lcdduino.sh &
[/shell]