Arduscope

 Разжился я на просторах ebay платой Arduino Duemilanove и LCD-Keypad Module. Сразу же захотелось сделать что-нибудь полезное. В результате появилась простая пинговалка на Perl (его я знаю плохо, больше не знаю ничего вообще), которая по USB отправляет на Arduino результаты, полученные ICMP. Может, кто-то захотет исправить ошибки и дополнить функционалом.

 Соответственно, скетч:


#include
LCD4Bit_mod lcd = LCD4Bit_mod(2);

#define INPUT_ARR 16

char resultInt;
int lcdrow = 1;
char inputBytes [17];
char msgs[5][15] = {"R",
"U",
"D",
"L",
"S" };
int adc_key_val[5] ={30, 150, 360, 535, 760 };
int NUM_KEYS = 5;
int adc_key_in;
int key=-1;

void setup(){
pinMode(13, OUTPUT); //we'll use the debug LED to output a heartbeat
lcd.init();
lcd.clear();
lcd.printIn("Arduscope v0.1");
Serial.begin(9600);
}

void loop()
{
//Reciev data from PC
if (Serial.available()>0) {
serReadInt();
switch (lcdrow) {
case 1:
lcd.clear();
lcd.cursorTo(lcdrow, 0);
lcd.printIn(inputBytes);
lcdrow = 2;
break;
case 2:
lcd.cursorTo(lcdrow, 0);
lcd.printIn(inputBytes);
lcdrow = 1;
break;
}
}
delay(600);
//Read key
adc_key_in = analogRead(0); // read the value from the sensor
digitalWrite(13, HIGH);
key = get_key(adc_key_in); // convert into key press
if (key >=0){
Serial.write(msgs[key]);
lcdrow = 1;
}

}

// Procedure
void serReadInt()
{
int i, serAva;
char inputBytesPtr = 0; // указатель на первый элемент массива
while(Serial.available()&&inputBytesPtr!=INPUT_ARR)
{
inputBytes[inputBytesPtr]= Serial.read();
inputBytesPtr++;
}
inputBytes[inputBytesPtr]='\0';
}

int get_key(unsigned int input)
{
int k;
for (k = 0; k < NUM_KEYS; k++) { if (input < adc_key_val[k]) { return k; } } if (k >= NUM_KEYS)
k = -1; // No valid key pressed
return k;
}

 И код на Perl (ActivePerl, для Windows):


use Win32::PingICMP;
use Data::Dumper;
use Win32::SerialPort;
use File::Temp;

use strict;
use warnings;

my (%User_Preferences); #Параметры настройки COM порта
my (@DataPing); #Массив с хостами для пинга
my ($ArraySource); #IP адреса и имена
my (@ArrayRow);
my ($i);
my ($failping); #Количество неудачных пингов
my ($winping); #Количество удачных пингов
my ($totalping); #Общее количество хостов
my ($pingresult); #Результат пинга
my ($count_out); #Вывод в порт
my ($rtt);
my ($keypress);
my $p = Win32::PingICMP->new();

# MAIN

# Read config file
open (CONFIG, "config.txt") or die "can`t open config file";
while () {
chomp;
s/#.*//;
s/~\s+//;
s/\s+$//;
next unless length;
my ($var, $value) = split(/\s*=\s*/, $_, 2);
$User_Preferences{$var} = $value;
}

# COM init
my $port = new Win32::SerialPort ($User_Preferences{"DEVICE"});
$port->databits($User_Preferences{"BIT"});
$port->baudrate($User_Preferences{"RATE"});
$port->parity($User_Preferences{"PARITY"});
$port->stopbits($User_Preferences{"STOPBIT"});

START:

SendResultToArd(); #Создаем файл с результатами пингов
RecieveKeyFromArd();
KeyAction($keypress);

$p->close();

# FUNCTION

sub SendResultToArd {

# Read data file
@DataPing=();
open (DATAFILE, "data.txt") or die "can`t open data file";
@DataPing = ; #Читаем файл в массив
@DataPing = sort @DataPing; #Сортируем

# Create tmp file
my $tmp_fname = File::Temp::tempnam("TMP", "ardus");
print "tmp_name = $tmp_fname\n";

# Open tmp file for write
open (RESULT, ">$tmp_fname") || die "EPIC FAIL $!";

# Ping
foreach $ArraySource (@DataPing) {
chomp $ArraySource; #Убираем перевод строки
@ArrayRow = split(/ /,$ArraySource); #Разделяем имя и IP-адрес
$p->ping($ArrayRow[1]);
if ($p->details()->{status} eq 'IP_SUCCESS') {
$pingresult="OK";
$winping++;
} else {
$pingresult="FAIL";
$failping++;
}
$rtt = $p->details->{roundtriptime};
if ($rtt > 0) {
print RESULT $ArrayRow[0], " ",$pingresult," ",$rtt,"\n"; #Печатаем результат во временный файл
} else {
print RESULT $ArrayRow[0], " ",$pingresult,"\n"; #Печатаем результат во временный файл
}
}

close (RESULT);

# Open tmp file for read
open (RESULT, "$tmp_fname") || die "EPIC FAIL $!";
while () {
print $_;
chomp; #Убираем перевод строки
@ArrayRow = split(/ /,$_); #Разделяем имя и результат
$count_out = $port->write("$ArrayRow[0]"); #отправляется в COM порт
sleep(2);
if ($#ArrayRow == 2) { #Проверяем размер массива
$count_out = $port->write("$ArrayRow[1] $ArrayRow[2]"); #отправляется в COM порт
}
else {
$count_out = $port->write("$ArrayRow[1]");
}
sleep(2);
}
$totalping = $winping+$failping;
$count_out = $port->write("Total: $totalping"); #отправляется в COM порт
sleep(2);
$count_out = $port->write("Fail: $failping"); #отправляется в COM порт
close (RESULT);
} #Конец функции SendResultToArd

sub RecieveKeyFromArd {
$port->read_interval(100);
$keypress = $port->read(1); #Читаем 1 символ
return ($keypress);
} #Конец функции RecieveKeyFromArd

sub KeyAction {
if ($keypress eq "U") {
$totalping = 0;
$winping = 0;
$failping = 0;
goto START;
}
} #Конец функции KeyAction

 В настоящее время, при нажатии кнопки «Up» происходит повторный опрос хостов.

 В качестве файлов конфигурации выступает файл config.txt, следующего содержания:


# Serial
DEVICE = COM5
RATE = 9600
BIT = 8
PARITY = NONE
STOPBIT = 1

 И файл data.txt, содержащий список хостов:


server-1 127.0.0.1
server-2 127.0.0.1

27.05.2011

 Понимаю, что это весьма сырая поделка, буде у кого возникнет желание что-то дополнить или исправить — добро пожаловать.




 Уважайте труд автора, сохраняйте копирайты.
Реклама на сайте висит не просто так и если статья Вам понравилась, с ее помощью Вы можете отблагодарить автора за проделанную работу. Спасибо!

Один комментарий в Arduscope

  1. You’re a real deep thinker. Thanks for shanrig.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *


*