WiFiシールドでWebサーバーを作っている際DHCPで割り当てられているIPアドレスを確認するのにいちいちシリアルモニターを開くのは面倒なのでLCDに表示できないかと考えていたが、通常の16×2 LCDシールドだとピンがWiFiシールドと競合してしまう。そこでI2C接続のLCDディスプレイを探していたところ、SwitchScienceから小型で使い勝手がよさそうな商品が出ていたので買ってみた。
クッション封筒で届いたので割れていないか心配になったが、大丈夫だった。
ピンが付属していないので、まずは手持ちのピンを半田付けする。
左からVDD、GND、SDA、SCLのピンアサインになっているので、SwitchScienseさんの説明ページにある様にA2~A5のピンにさくっと挿しこむ。幸いWiFiシールドはアナログピンを使っていないので競合しない。
LCD表示は楽に使える様にSwitchScienseさんのブログを元にクラス化した。
(2015/5/1追記) 改良版のクラスとサンプルコードも作成してみた。
ダウンロード後ライブラリとして追加したら使える、と思う。ただ、何故かライブラリを取り込んでビルドするとWire.hが見つからないと怒られてしまう謎現象が発生するのでメインコードのi2c_8x2lcd.hのincludeの前にWire.hをincludeする必要がある。
先日のWiFiシールドでWebサーバーごっこを元に、起動時、アクセスポイント接続時、DHCP接続時のタイミングでLCDにメッセージを表示し、IPアドレス取得後IPアドレスを表示する様に修正した。さらに、Webページはテキスト入力を受け付ける様にして、ブラウザから適当なテキスト(半角英数)を入力するとその文字をLCDに表示する様にしてみた。
これはなかなか便利である。小型で邪魔にならないし手軽に使える。
モバイルバッテリーで電源オン、起動後タブレットからWebアクセスして「Hi! (^-^」の文字を入力、LCDに反映される流れを動画に撮ってみた。ついでに先日購入して気に入っているUSB電流計も一緒に撮ってみた。
以下、ソースコード。
#include <Adafruit_CC3000.h>
#include <Wire.h>
#include <i2c_8x2lcd.h>
#include <SPI.h>
#include "utility/debug.h"
#include "utility/socket.h"
#define ADAFRUIT_CC3000_IRQ 3 // MUST be an interrupt pin!
#define ADAFRUIT_CC3000_VBAT 5
#define ADAFRUIT_CC3000_CS 10
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT, SPI_CLOCK_DIV2);
#define WLAN_SSID "yourssid" // cannot be longer than 32 characters!
#define WLAN_PASS "mypassword"
#define WLAN_SECURITY WLAN_SEC_WPA2
#define LISTEN_PORT 80
char in_buffer[96];
int in_size = 0;
char req_page[64];
char in_ch;
char last_ch;
char subch[64];
char decch[64];
char *cmd;
Adafruit_CC3000_Server httpServer(LISTEN_PORT);
I2C_8X2LCD lcd(16,17);
void setup(void)
{
lcd.init(35);
lcd.printStr("Booting");
pinMode(6, OUTPUT);
Serial.begin(115200);
Serial.println(F("Hello, CC3000!\n"));
Serial.print("Free RAM: "); Serial.println(getFreeRam(), DEC);
Serial.println(F("\nInitializing..."));
if (!cc3000.begin()) {
Serial.println(F("Couldn't begin()! Check your wiring?"));
while (1);
}
lcd.printStr(0,0,"Connect");
lcd.printStr(6,1,"AP");
if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) {
Serial.println(F("Failed!"));
while (1);
}
lcd.printStr(6,1,"OK");
Serial.println(F("Connected!"));
Serial.println(F("Request DHCP"));
delay(500);
lcd.printStr(4,1,"DHCP");
while (!cc3000.checkDHCP()) {
delay(100); // ToDo: Insert a DHCP timeout!
}
while (! displayConnectionDetails()) {
delay(1000);
}
Serial.println(F("\r\nNOTE: This sketch may cause problems with other sketches"));
Serial.println(F("since the .disconnect() function is never called, so the"));
Serial.println(F("AP may refuse connection requests from the CC3000 until a"));
Serial.println(F("timeout period passes. This is normal behaviour since"));
Serial.println(F("there isn't an obvious moment to disconnect with a server.\r\n"));
httpServer.begin();
Serial.println(F("Listening for connections..."));
digitalWrite(6, HIGH);
}
void loop(void)
{
Adafruit_CC3000_ClientRef client = httpServer.available();
if (client) {
digitalWrite(6, LOW);
if (client.available() > 0) {
in_ch = client.read();
if (in_size < 95 && in_ch != '\r' && in_ch != '\n')
in_buffer[in_size++] = in_ch;
if (in_ch == '\r') {
in_buffer[in_size] = '\0';
Serial.println(in_buffer);
cmd = getparam(in_buffer, ' ', 0);
if (strcmp(cmd, "GET") == 0)
strcpy(req_page, getparam(in_buffer, ' ', 1));
in_size = 0;
if (last_ch == '\r') //double linefeed, end of request
replypage(&client);
}
if (in_ch == '\r' || in_ch == '\n')
last_ch = '\r';
else
last_ch = ' ';
}
digitalWrite(6, HIGH);
}
}
//return n-th char array separated with specified character
char *getparam(char *txt, char seperator, int index) {
int strcnt = 0;
int indcnt = 0;
memset(subch, 0, 64);
for (int i = 0; i < strlen(txt); i++) {
if (txt[i] == seperator) {
indcnt++;
if (indcnt > index)
break;
} else if (indcnt == index) {
subch[strcnt++] = txt[i];
}
}
return &subch[0];
}
char *decodechar(char *txt){
memset(decch,0,64);
int deccnt = 0;
char hexbuf[3] = {0,0,0};
for (int i=0;i<strlen(txt);i++){
if (txt[i] == '+'){
decch[deccnt++] = ' ';
}else if (txt[i] == '%'){
hexbuf[0] = txt[i+1];
hexbuf[1] = txt[i+2];
decch[deccnt++] = strtol(hexbuf,NULL,16);
i+=2;
}else{
decch[deccnt++] = txt[i];
}
}
return decch;
}
void replypage(Adafruit_CC3000_ClientRef *pclient) {
Serial.print("req:");
Serial.println(req_page);
if (strcmp(getparam(req_page, '=', 0), "/?text") == 0) {
char char_param[10];
strcpy(char_param,decodechar(getparam(req_page, '=', 1)));
Serial.print("text:");
Serial.println(char_param);
lcd.clear();
lcd.printStr(0,1,char_param);
}
pclient->println("HTTP/1.1 200 OK");
pclient->println("Content-Type: text/html");
pclient->println("");
pclient->fastrprint("<html><title>Arduino Web</title><body>");
char buffer[96];
sprintf(buffer, "Requested : %s", req_page);
pclient->fastrprint(buffer);
pclient->fastrprint("<BR><form method=\"GET\" action=\"/\">");
pclient->fastrprint("<input type=\"text\" maxlength=\"8\" name=\"text\"><input type=\"submit\" value=\"Go\"></form>");
pclient->fastrprint("</body></html>");
delay(1000);
pclient->close();
}
bool displayConnectionDetails(void)
{
uint32_t ipAddress, netmask, gateway, dhcpserv, dnsserv;
if (!cc3000.getIPAddress(&ipAddress, &netmask, &gateway, &dhcpserv, &dnsserv)) {
Serial.println(F("Unable to retrieve the IP Address!\r\n"));
lcd.clear();
lcd.printStr(0,0,"FAIL IP");
return false;
} else {
Serial.print(F("\nIP Addr: ")); cc3000.printIPdotsRev(ipAddress);
Serial.print(F("\nNetmask: ")); cc3000.printIPdotsRev(netmask);
Serial.print(F("\nGateway: ")); cc3000.printIPdotsRev(gateway);
Serial.print(F("\nDHCPsrv: ")); cc3000.printIPdotsRev(dhcpserv);
Serial.print(F("\nDNSserv: ")); cc3000.printIPdotsRev(dnsserv);
Serial.println();
lcd.clear();
char ipadd[9];
sprintf(ipadd,"%3d.%3d.",(uint8_t)(ipAddress >> 24),(uint8_t)(ipAddress >> 16));
lcd.printStr(0,0,&ipadd[0]);
sprintf(ipadd,"%3d.%3d",(uint8_t)(ipAddress >> 8),(uint8_t)(ipAddress));
lcd.printStr(1,1,&ipadd[0]);
return true;
}
}
![[GPG] Arduino CC3000 WiFiシールド SDカードスロット付](https://images-na.ssl-images-amazon.com/images/I/51gM4PrJ6IL._SL160_.jpg)
[GPG] Arduino CC3000 WiFiシールド SDカードスロット付















