วันอังคารที่ 19 มีนาคม พ.ศ. 2556

[Raspberry Pi] ทำเครื่อง รับ ส่ง รหัส morse



หลังจากที่ควบคุมขา GPIO กันได้แล้ว ต่อมา เนื่องจากว่าผมไม่รู้จะทำอะไรกับเจ้าขา GPIO ดี ก็เลยนึกเล่นๆไป ได้เครื่อง รับ-ส่ง รหัสมอสมาครับ

โดยในภาพ (และในสคริป) จะใช้ไฟจากขา #24 แล้วก็จากอีกขาหนึ่งที่มันจ่ายไฟ 3V ได้ เรียกไม่ถูกว่าอะไร 555

GPIO #24 -> ตั้งค่าเป็น output สำหรับจ่ายไฟ จากสคริป
3V -> สำหรับจ่ายไฟ ถ้าเราต้องการกดส่งรหัสมอสเอง
GPIO #23 -> ตั้งค่าเป็น input สำหรับรับรหัสมอส



มาดูที่ฝั่งตัวส่งรหัสมอสกันก่อน

#!/usr/bin/perl
$gpio=24;
$delay=0.25;                   #Delay of send speed
$pause=1*$delay;
$dot_pause=1*$delay;
$dash_pause=3*$delay;
$character_pause=3*$delay;
$word_pause=7*$delay;

print "\n\n";
print " Message >> ";
chomp($text=);
$original_text=$text;
@original_text=split //,$original_text;

$text=~s/ /\//ig;
$text=~s/\./.-.-.- /ig;
$text=~s/,/--..-- /ig;
$text=~s/\?/..-.. /ig;
$text=~s/a/.- /ig;
$text=~s/b/.--- /ig;
$text=~s/c/-.-. /ig;
$text=~s/d/-.. /ig;
$text=~s/e/. /ig;
$text=~s/f/..-. /ig;
$text=~s/g/--. /ig;
$text=~s/h/.... /ig;
$text=~s/i/.. /ig;
$text=~s/j/.--- /ig;
$text=~s/k/-.- /ig;
$text=~s/l/.-.. /ig;
$text=~s/m/-- /ig;
$text=~s/n/-. /ig;
$text=~s/o/--- /ig;
$text=~s/p/.--. /ig;
$text=~s/q/--.- /ig;
$text=~s/r/.-. /ig;
$text=~s/s/... /ig;
$text=~s/t/- /ig;
$text=~s/u/..- /ig;
$text=~s/v/...- /ig;
$text=~s/w/.-- /ig;
$text=~s/x/-..- /ig;
$text=~s/y/-.-- /ig;
$text=~s/z/--.. /ig;
$text=~s/1/.---- /ig;
$text=~s/2/..--- /ig;
$text=~s/3/...-- /ig;
$text=~s/4/....- /ig;
$text=~s/5/..... /ig;
$text=~s/6/-.... /ig;
$text=~s/7/--... /ig;
$text=~s/8/---.. /ig;
$text=~s/9/----. /ig;
$text=~s/0/----- /ig;

print " Sending >> $original_text[0]";
$count_text=1;
foreach (split //,$text) {
    if ($_ eq '.') {
        system("echo \"0\" > /sys/class/gpio/gpio$gpio/value");
        select undef,undef,undef,$pause;
        system("echo \"1\" > /sys/class/gpio/gpio$gpio/value");
        select undef,undef,undef,$dot_pause;
    }
    elsif ($_ eq '-') {
        system("echo \"0\" > /sys/class/gpio/gpio$gpio/value");
        select undef,undef,undef,$pause;
        system("echo \"1\" > /sys/class/gpio/gpio$gpio/value");
        select undef,undef,undef,$dash_pause;
    }
    elsif ($_ eq ' ') {
        system("echo \"0\" > /sys/class/gpio/gpio$gpio/value");
        select undef,undef,undef,$character_pause;
        print "$original_text[$count_text]";
        $count_text++;
    }
    elsif ($_ eq '/') {
        system("echo \"0\" > /sys/class/gpio/gpio$gpio/value");
        select undef,undef,undef,$word_pause;
        print "$original_text[$count_text]";
        $count_text++;
    }
    else { print "\nERROR: $_\n"; exit; }
}
print "\n";




หลักการของมันก็คือ รับตัวอักษรจากเราเข้า แล้วก็แปลงเป็น >> . - 'ช่องว่าง' / << แล้วก็ส่งค่า 0 กับ 1 ออกไปตามจังหวะ พอส่งค่า 1 ออกไปจากขา #24 ไฟ LED ก็จะติด แล้วก็ยังส่งค่าไปที่ขา #23 อีกด้วย(ซึ่งจะเป็นของฝั่งรับสัญญาณ ถ้าต้องการดูแค่ LED กระพริบเป็นสัญญาณ ขา #23 ก็ไม่ต้องใช้)
หรือถ้าเรา จะส่งรหัสมอสเอง อยากได้อารมณ์ของการนั่งกดปุ่มจริงๆ 5555 ก็กดจากสวิตได้เลย เพราะมีไฟจ่ายให้ทาง switch จากแหล่งจ่ายไฟ 3V ตลอดอยู่แล้ว



ทีนี้ มาดูทางฝั่งรับ รหัสมอส

#!/usr/bin/perl
$delay=0.1; #second
$timeout=60;  #loop for exit if didnt get any morse code
$text='';
$gpio=23;

print " Geting >> ";

do {
    open READ,"cat /sys/class/gpio/gpio$gpio/value |";
    $value=;
    close READ;
    select undef,undef,undef,$delay;
    $end=0;
} until ($value == 1);

while (1) {
    open READ,"cat /sys/class/gpio/gpio$gpio/value |";
    $value=;
    close READ;
    if ($value == 1) {
        print '1';
        select undef,undef,undef,$delay;
        $text.='1';
        $end=0;
    }
    else {
        print ',';
        select undef,undef,undef,$delay;
        $text.=',';
        ++$end;
    }
    if ($end > $timeout) {
        print "\n Morse >> ",analys($text);
        print "\n Text >> ",convert(analys($text));
        print "\n";
        exit;
    }
}


sub analys {
    my $text=$_[0];
#    $text=~s/1{3,}/-/g;            #For send speed = 0.125
#    $text=~s/1{1,2}/./g;           #For send speed = 0.125
#    $text=~s/,{11,}/  \/  /g;      #For send speed = 0.125
#    $text=~s/,{4,10}/  /g;         #For send speed = 0.125
#    $text=~s/,{1,3}//g;            #For send speed = 0.125
    $text=~s/1{4,}/-/g;            #For send speed = 0.25
    $text=~s/1{1,3}/./g;           #For send speed = 0.25
    $text=~s/,{11,}/  \/  /g;      #For send speed = 0.25
    $text=~s/,{5,10}/  /g;         #For send speed = 0.25
    $text=~s/,{1,4}//g;            #For send speed = 0.25
    return " ".$text." ";
}

sub convert {
    my $text=$_[0];
    $text=~s/ \.- /a/ig;
    $text=~s/ \.--- /b/ig;
    $text=~s/ -\.-\. /c/ig;
    $text=~s/ -\.\. /d/ig;
    $text=~s/ \. /e/ig;
    $text=~s/ \.\.-\. /f/ig;
    $text=~s/ --\. /g/ig;
    $text=~s/ \.\.\.\. /h/ig;
    $text=~s/ \.\. /i/ig;
    $text=~s/ \.--- /j/ig;
    $text=~s/ -\.- /k/ig;
    $text=~s/ \.-\.\. /l/ig;
    $text=~s/ -- /m/ig;
    $text=~s/ -\. /n/ig;
    $text=~s/ --- /o/ig;
    $text=~s/ \.--\. /p/ig;
    $text=~s/ --\.- /q/ig;
    $text=~s/ \.-\. /r/ig;
    $text=~s/ \.\.\. /s/ig;
    $text=~s/ - /t/ig;
    $text=~s/ \.\.- /u/ig;
    $text=~s/ \.\.\.- /v/ig;
    $text=~s/ \.-- /w/ig;
    $text=~s/ -\.\.- /x/ig;
    $text=~s/ -\.-- /y/ig;
    $text=~s/ --\.\. /z/ig;
    $text=~s/ \.---- /1/ig;
    $text=~s/ \.\.--- /2/ig;
    $text=~s/ \.\.\.-- /3/ig;
    $text=~s/ \.\.\.\.- /4/ig;
    $text=~s/ \.\.\.\.\. /5/ig;
    $text=~s/ -\.\.\.\. /6/ig;
    $text=~s/ --\.\.\. /7/ig;
    $text=~s/ ---\.\. /8/ig;
    $text=~s/ ----\. /9/ig;
    $text=~s/ ----- /0/ig;
    $text=~s/ \.-\.-\.- /./ig;
    $text=~s/ --\.\.-- /,/ig;
    $text=~s/ \.\.-\.\. /?/ig;
    $text=~s/ //ig;
    $text=~s/\// /ig;
    return $text;
}

หลักการทำงานคือ หลังจากรันสคริป มันจะรอเรื่อยๆ จนกว่าจะมีไฟจ่ายเข้าทาง #23 มันถึงจะเริ่มทำงาน โดยมันจะนับเวลาที่มีไฟจ่ายเข้า
  • ถ้าจ่ายเข้าสั้นๆ ก็นับเป็น . (dot)
  • ถ้าจ่ายเข้ายาวๆก็นับเป็น - (dash)
  • ถ้าเว้นว่างระยะหนึ่ง แล้วจ่ายไฟเข้าใหม่ ก็นับเป็นสิ้นๆสุดหนึ่งตัวอัก
  • ถ้าเว้นว่างยาวอีกหน่อย แล้วจ่ายไฟเข้าใหม่ ก็นับเป็นหนึ่งคำ
  • ถ้าเว้นว่างยาวเรื่อยๆ ก็ถือว่าสิ้นสุดการรับส่ง
พอรับมาเป็น . - 'ช่องว่าง' / แล้ว ก็เอามาแปลงเป็นตัวอักษรอีกทีนึง



จบละครับ หลักการง่ายๆ ตอนนี้ยังไม่รู้ว่าทำเสร็จ จะเอาประโยชน์อะไรดี ทำเอาเล่นๆสนุกๆก่อน ใครมีไอเดียวแจ่มๆ ก็มาแชร์กันบ้างนะครับ :P

Download morse-send.pl >> http://pastebin.com/Zi8WKn0L
Download morse-receive.pl >> http://pastebin.com/SidGeJtD

1 ความคิดเห็น: