WiDo 实现HTTP Server 的例子

最近在研究如何搭建一个 WIFI HTTP Server ,本打算使用ESP8266,但是购买了板子才发现资料比较少,联系卖家也没有结果。后来只得入手了一块 CC3000 的 WIFI 板子。这个芯片是 Arduino IDE 原生自带的,所以资料方面不是问题。入手的是 DFRobot 出品的 WiDo,主控芯片是 32U4,这意味着有足够的串口可供Debug之类使用, 更具体的说:主控芯片用 SPI 和 WIFI芯片CC3000打交道,然后多出来一个串口,USB上还有一个串口。

image001

根据【参考1】编写一个简单的程序,控制板子上 Pin 13 上面的LED亮灭。【参考1】的程序会向浏览器端发送一个 HTTP 的页面,上面有2个按钮,能够通过按下按钮控制亮灭。经过我的测试发现浏览器打卡会很慢,很多时候会卡死,并且打开之后页面是错乱的。我猜测原因可能是HTTP代码并不标准,有兼容性问题(我用的Chrome),另外用浏览器访问有可能会负载过高,比如,我偶然发现浏览器打开网站之后还有 GET favorite.ico 的动作。因此,我对程序做了一下简单的修改。修改之后HTTP页面只是简单显示一行字符。使用 http://ip/open 打开 LED,http://ip/close关闭LED。

1.直接访问 http://192.168.0.103 可以看到下面的信息

image002

具体的控制可以用 http://192.168.1.103/open 点亮,http://192.168.1.103/close 熄灭。
image003

2.此外,还可以用 curl 工具在控制台进行操作,和方法1 相比,这样的更简单可靠,避免浏览器“暗箱操作”

image004

#include <Adafruit_CC3000.h>
#include <SPI.h>
#include "utility/debug.h"
#include "utility/socket.h"

// These are the interrupt and control pins
#define ADAFRUIT_CC3000_IRQ   7  // MUST be an interrupt pin!
// These can be any two pins
#define ADAFRUIT_CC3000_VBAT  5
#define ADAFRUIT_CC3000_CS    10
// Use hardware SPI for the remaining pins
// On an UNO, SCK = 13, MISO = 12, and MOSI = 11
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
SPI_CLOCK_DIVIDER); // you can change this clock speed


#define WLAN_SSID       "ChinaNet-73"           //这里填写你的 WIFI  名称
#define WLAN_PASS       "adminp1988"            //这里填写你的 WIFI 密码  
// Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2
#define WLAN_SECURITY   WLAN_SEC_WPA2

#define LISTEN_PORT           80   // What TCP port to listen on for connections.

Adafruit_CC3000_Server webServer(LISTEN_PORT);
boolean led_state;
//
void setup(void) {
        //简单起见,我们只用板载的 13pin 上的 LED 演示
        pinMode (13, OUTPUT);
		//默认是灭的
        digitalWrite (13, LOW);
        
		//使用串口输出Debug信息
        Serial.begin(115200);
        Serial.println(F("Hello, CC3000!\n")); 
        //while (!Serial);
        //Serial.println ("Input any key to start:");
        //while (!Serial.available ());
		//输出当前可用内存
        Serial.print("Free RAM: "); 
        Serial.println(getFreeRam(), DEC);

        /* Initialise the module */
        Serial.println(F("\nInitializing..."));
        if (!cc3000.begin()) {
                Serial.println(F("Couldn't begin()! Check your wiring?"));
                while(1);
        }

        Serial.print(F("\nAttempting to connect to ")); 
        Serial.println(WLAN_SSID);
        if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) {
                Serial.println(F("Failed!"));
                while(1);
        }

        Serial.println(F("Connected!"));

		//使用 DHCP 分配的IP 
        Serial.println(F("Request DHCP"));
        while (!cc3000.checkDHCP()) {
                delay(100); // ToDo: Insert a DHCP timeout!
        }  
		
        //显示当前的IP信息
        /* Display the IP address DNS, Gateway, etc. */
        while (! displayConnectionDetails()) {
                delay(1000);
        }

        // Start listening for connections
        webServer.begin();
        Serial.println(F("Listening for connections..."));
}

//
void loop(void) {
        // Try to get a client which is connected.
        Adafruit_CC3000_ClientRef client = webServer.available();
        if (client) {
		        //处理输入的 GET 信息,对于 GET 方法来说,Url中既有传递的信息
                processInput (client);
				//对发送 HTTP 请求的浏览器发送HTTP代码
                sendWebPage (client);
        }
        client.close();
}

//分析收到的 GET 方法的参数
void processInput (Adafruit_CC3000_ClientRef client) {
        char databuffer[45];
      //安全起见,保证截断
       databuffer[44]=’\0’;
        while (client.available ()) {
                client.read (databuffer, 40);
	
	  //下面这个代码是查找PC端发送的数据中的换行,以此作为字符串的结尾
                char* sub = strchr (databuffer, '\r');
                if (sub > 0)
                        *sub = '\0';
                Serial.println (databuffer);
				
                //下面是解析 GET 方法提供的参数
	    //如果是 open 命令,那么点亮 LED
                if (strstr (databuffer, "open") != 0) {
                        Serial.println (F("clicked open"));
                        digitalWrite (13, HIGH); 
                        led_state = true;
                } 
	     //如果是 close 命令,那么熄灭 LED 
                else if (strstr (databuffer, "close") != 0) {
                        Serial.println (F("clicked close"));
                        digitalWrite (13, LOW);
                        led_state = false;
                }
                break;
        }
}

void sendWebPage (Adafruit_CC3000_ClientRef client) {
        //为了节省空间,这里只发送简单的提示字符
        webServer.write ("Waiting for command");
        delay (20);
        client.close();
}

//输出当前WIFI 设备通过 DHCP 取得的基本信息
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"));
                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();
                return true;
        }
}

 

最后,对于初学者来说个人强烈不推荐使用“深圳四博智联科技有限公司开发的一款基于乐鑫ESP8266的各种板子“,原因是:资料很少,基本上没有Support,初学者使用的话很可能走很多弯路。
对于WiDo 来说,因为使用的是 CC3000,这也是 Arduino 官方用的 Wifi 使用的芯片,因此资料很全。不得不承认一点,国内Arduino方面的硬件价格便宜,但是软件还是很弱,特别是基础性的研究。如果你的项目比较急,或者对于稳定性要求高,首选官方支持的设备。

参考:
1. 通过网页按钮控制台灯,wido做服务器http://www.dfrobot.com.cn/community/forum.php?mod=viewthread&tid=10001&highlight=wido

WiDo 实现HTTP Server 的例子》上有 2 条评论

    1. ziv2013 文章作者

      最开始我选择的就是 8266 价格便宜……问题是资料不多,另外,估计需要特别的固件才可以支持。最后还是放弃了,没搞定。

      回复

发表评论

电子邮件地址不会被公开。 必填项已用*标注