树荫下交错的摩斯电码

摩斯电码(Morse code),想必大家都是听说过的,虽然是一种相对古老的编码,但即使是在今天,也被众多业余无线电爱好者使用。

那么我们可以拿它来怎么玩呢?报一下IP吧!

上一篇post写了树莓派自动发送IP到邮箱这种方式,那么这次就来演示一下摩斯电码的方式吧。

你只需要一个树莓派、一个小小的蜂鸣器,另加几根导线,就可以开工了!自然,这一次我们也会使用wiringPi这个第三方库,安装过程什么的就略去吧。

我们这里取的时间标准是:滴=1t,嗒=3t,滴嗒间=1t,每个字符间=3t,.(IPv4中每段分隔的点号)、:(IPv6中每段分隔的冒号)=7t。

既然是使用Morse code,那么我们总得有个表吧。考虑到可能会有IPv6地址,我们的表就是0-9A-F了。

/**
 *  @brief Part of morse code table
 *
 *  1 .----
 *  2 ..---
 *  3 ...--
 *  4 ....-
 *  5 .....
 *  6 -....
 *  7 --...
 *  8 ---..
 *  9 ----.
 *  0 -----
 *  A .-
 *  B -...
 *  C -.-.
 *  D -..
 *  E .
 *  F ..-.
 */
int table[16][5] = {
                    {3, 3, 3, 3, 3},
                    {1, 3, 3, 3, 3},
                    {1, 1, 3, 3, 3},
                    {1, 1, 1, 3, 3},
                    {1, 1, 1, 1, 3},
                    {1, 1, 1, 1, 1},
                    {3, 1, 1, 1, 1},
                    {3, 3, 1, 1, 1},
                    {3, 3, 3, 1, 1},
                    {3, 3, 3, 3, 1},
                    {1, 3},
                    {3, 1, 1, 1},
                    {3, 1, 3, 1},
                    {3, 1, 1},
                    {1},
                    {1, 1, 3, 1}
                   };

表中的1便是滴对应的1t,3则是嗒对应的3t。接下来便是获取IP地址。

void get_ip_from(const char * interface) {
    struct ifaddrs * interfaces;
    char str[INET_ADDRSTRLEN] = { 0 };
    if (getifaddrs(&interfaces)) return;
    
    struct ifaddrs * address = interfaces;
    while (address) {
        if(address->ifa_addr->sa_family == AF_INET) {
            if (strcmp(address->ifa_name, interface) == 0) {
                inet_ntop(AF_INET, &((struct sockaddr_in *)address->ifa_addr)->sin_addr, str, INET_ADDRSTRLEN);
                sprintf(ip, "%s", str);
                break;
            }
        }
        address = address->ifa_next;
    }
    freeifaddrs(interfaces);
}

IP拿到手之后,就可以开始发送Morse code了!

#define BUZZER_PIN 0 // 我们的蜂鸣器接在GPIO0
#define INTERVAL_BASE 300 // ms
#define CHARS 3
#define DI_DA 1
#define SEPARATOR 7

void ring(int duration) {
    digitalWrite (BUZZER_PINHIGH);
    delay(INTERVAL_BASE * duration);
}

void quiet(int duration) {
    digitalWrite (BUZZER_PINLOW);
    delay(INTERVAL_BASE * duration);
}

void buzz() {
    for (int i = 0; ; i++) {
        char text = ip[i];
        if (text == '\0') {
            break;
        } else if (text == '.' || text == ':') {
            quiet(SEPARATOR);
        } else if (text >= '0' && text <= '9') {
            int * durations = table[text - '0'];
            for (int t = 0; t < 4; t++) {
                ring(durations[t]);
                quiet(DI_DA);
            }
            ring(durations[5]);
        } else if (text >= 'A' && text <= 'F') {
            int * durations = table[text - 'A' + 10];
            for (int t = 0; t < 4; t++) {
                ring(durations[t]);
                quiet(DI_DA);
            }
            ring(durations[5]);
        }  else if (text >= 'a' && text <= 'f') {
            int * durations = table[text - 'A' + 10];
            for (int t = 0; t < 4; t++) {
                ring(durations[t]);
                quiet(DI_DA);
            }
            ring(durations[5]);
        }
        quiet(CHARS);
    }
}

最后的main~

int main(){
    wiringPiSetup() ;
    pinMode(BUZZER_PIN, OUTPUT);
    ip = (char *)malloc(sizeof(char) * 64);
    memset(ip, 0, sizeof(char) * 64);
    get_ip_from("wlan0");
    printf("wlan0: %s\n",ip);
    buzz();
    quiet(0);
    free(ip);
    return 0;
}

你可以在我的Github上下载完整代码,buzzer_ip

Leave a Reply

Your email address will not be published. Required fields are marked *

20 − eleven =