mbedでhttpの返事を液晶に表示してみた


前回、Ethernetに接続するところまで進捗したmbedですが、その後DHCPでIPアドレスを貰ってきて、SPI接続の液晶に表示するところまで実現できました。



SPIの液晶は、AD-12864-SPIというものです。以前、つい安かったので購入してしまった(だって、128×64のグラフィック液晶が1,250円ですよ)のですが、3.3VでArduinoと接続するのが面倒になって放置していたものです。だって、情報少ないんだもん。
この液晶について調べていたところ、mbedに接続している方が居たので成果物を利用させていただきました。 :-)
mbed でaitendoのSPI液晶に出力してみました – Sim’s blog
この方の書いたコードは、mbedのサイトにあります。
SJISの漢字ROM(いや、今はROMじゃないか)も用意していらっしゃってものすごく楽をさせていただきました。

DHCPで取ってきたIPアドレスを表示するのには、ちょっと苦労しました。今まではlwipというライブラリのお手軽APIを使っていましたが、変数にアクセスするために、もう少しローレベルなAPIを使うことにしました。
コードは、mbedサイトの Pure lwip HTTP Client – Using lwIP direct to build a http client を参考にしました。

    /* Create and initialise variables */
    struct netif   *netif = &netif_data;
    struct ip_addr  ipaddr;
    struct ip_addr  target;
    struct ip_addr  netmask;
    struct ip_addr  gateway;
    Ticker tickFast, tickSlow, tickARP, eth_tick, dns_tick, dhcp_coarse, dhcp_fine;
    char *hostname = "mbed";
    /* Start Network with DHCP */
    IP4_ADDR(&netmask, 255,255,255,255);
    IP4_ADDR(&gateway, 0,0,0,0);
    IP4_ADDR(&ipaddr, 0,0,0,0);
    /* Initialise after configuration */
    lwip_init();
    netif->hwaddr_len = ETHARP_HWADDR_LEN;
    device_address((char *)netif->hwaddr);
    netif = netif_add(netif, &ipaddr, &netmask, &gateway, NULL, device_init, ip_input);
    netif->hostname = hostname;
    netif_set_default(netif);
    dhcp_start(netif); // <-- Use DHCP

    /* Initialise all needed timers */
    tickARP.attach_us( &etharp_tmr,  ARP_TMR_INTERVAL  * 1000);
    tickFast.attach_us(&tcp_fasttmr, TCP_FAST_INTERVAL * 1000);
    tickSlow.attach_us(&tcp_slowtmr, TCP_SLOW_INTERVAL * 1000);
    dns_tick.attach_us(&dns_tmr, DNS_TMR_INTERVAL * 1000);
    dhcp_coarse.attach_us(&dhcp_coarse_tmr, DHCP_COARSE_TIMER_MSECS * 1000);
    dhcp_fine.attach_us(&dhcp_fine_tmr, DHCP_FINE_TIMER_MSECS * 1000);

    // Wait for an IP Address
    while (!netif_is_up(netif)) {
        device_poll();
    }
&#91;/cpp&#93;
とまぁ、随分長くなってしまいました。
で、肝心のIPアドレスの変数を読むにはこんな感じにしました。
&#91;cpp&#93;
    // print ip address
    char localip&#91;19&#93;;
    sprintf(localip, "IP: %hhu.%hhu.%hhu.%hhu\n", (netif->ip_addr.addr)&0xFF, (netif->ip_addr.addr>>8)&0xFF, (netif->ip_addr.addr>>16)&0xFF, (netif->ip_addr.addr>>24)&0xFF);
    draws ((unsigned char*)localip);

めっちゃあっけないですが、ドキュメントなど情報が少ないので、ソースコード読んで結構に苦労しました……
httpdから返ってきた内容は、次のようにしてAD-12864-SPI(SPI液晶)に表示しています。

/* Struct with hold the Ethernet Data */
struct netif    netif_data;
/* Every time called if a packet is received for a */
/* TCPConnection which registerd this Callback. */
err_t recv_callback(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) {
    if (p==NULL) {
        draws ("Connection closed by server\n");
        return ERR_OK;
    }

    while (p) {
        char * ch = (char*)p->payload;
        draws(">>>\n");
        for (int i=0; i < p->len; i++) {
        drawc ((unsigned char)ch[i]);
        wait(0.1);
        }
        draws("<<<\n");
        p = p->next;
    }
    tcp_recved(pcb, p->tot_len);
    pbuf_free(p);
    return ERR_OK;
}

現状、HTTPレスポンスヘッダも表示してしまうので、レスポンスヘッダと本文を分離して扱うようにしたり、本文をparseして利用したりできるようにするのが残課題です。