前面几篇介绍了一些传感器和代码,这篇介绍一下把它们组合起来。之因此单独列出这部分,缘由在于组合更多功能的时候发现使用软串口库驱动ESP8266时因为内存太小致使发送失败甚至整个系统没法工做的状况。因此,我只组合了DHT十一、火焰传感、MQ-9这几个传感器。今天优化了ESP8266部分的代码以后,实际测试时还能够用起一个GP2Y10,再多就不行了,并且包括DHT十一、GP2Y10都不是使用现成的库文件,而是本身写了一些代码。暂时确实没有更多精力去本身写软串口通信的部分了。首先看一下DHT11的代码:git
// DHT11SimpleRead.h #ifndef _DHT11SIMPLEREAD_h #define _DHT11SIMPLEREAD_h #if defined(ARDUINO) && ARDUINO >= 100 #include "arduino.h" #else #include "WProgram.h" #endif class DHT11SimpleRead { public: DHT11SimpleRead(unsigned int p); bool read(); float temperature=5.0; float humidity=50.0; private: unsigned int pin; unsigned int bits[5]; }; #endif
// // // #include "DHT11SimpleRead.h" DHT11SimpleRead::DHT11SimpleRead(unsigned int p) { pin = p; } bool DHT11SimpleRead::read() { int cnt = 7; int idx = 0; //发送命令开始工做 pinMode(pin, OUTPUT); digitalWrite(pin, LOW); delay(20); //至少18毫秒拉低 digitalWrite(pin, HIGH); delayMicroseconds(40); //20-40微秒拉高 //转换到主机接收 pinMode(pin, INPUT); unsigned int loopCnt = 10000; //等待80微秒左右的拉高结束 while (digitalRead(pin) == LOW) if (loopCnt-- == 0) return; loopCnt = 10000; //等待80微秒左右的拉低结束 while (digitalRead(pin) == HIGH) if (loopCnt-- == 0) return; //开始接收40位数据 for (int i = 0; i<40; i++) { loopCnt = 10000; while (digitalRead(pin) == LOW) //每一位都是从低开始,当低结束时,根据电平长短来肯定是0仍是1 if (loopCnt-- == 0) return; unsigned long t = micros(); //开始计时 loopCnt = 10000; while (digitalRead(pin) == HIGH) //等待新号变低的时间决定了位的高低 if (loopCnt-- == 0) return; if ((micros() - t) > 40) bits[idx] |= (1 << cnt); //通常,26-28微秒是0,29-70微秒是1 //接收满8位开始下一字节 if (cnt == 0) { cnt = 7; idx++; } else cnt--; } //传输完成以后,DHT11会拉低单总线50微秒。不处理了。 //接收完成写入数据 temperature = bits[2]; humidity= bits[0]; //进行校验 return (unsigned int)bits[0] + bits[1] + bits[2] + bits[3] == (unsigned int)bits[4]; }
根据时序写驱动并非很麻烦。这样就获得了两个数值,今天在测试的时候发现有时读取的值并不正确,可是刚刚上电的时候是正确的,反复检查并优化了一些代码以后没有再出现这个问题,若是再出现可能就是电路设计有问题了。oop
而后针对ESP8266发送数据比较长进行了一点优化,固然这部分彻底能够作的更好一些,可是感受没有什么必要了,毕竟就是当一个玩意玩的,即便付出更多努力结果可能也只是多加一个传感器——而我并不打算获得温湿度、火焰、燃气之外的数据。包括颗粒物传感器,我也只是打算放到另外一块Arduino上,与语音识别和红外发射放到一块儿作一个简单的语音控制器来控制一些红外遥控的设备,例如自动开关空气净化,语音控制电视、窗帘等。这个优化主要是针对POST部分的数据比较长,把它按行拆开透传;也能够限定每次透传的数据量。固然,不管如何,减小字符串占用的堆栈、尽早的回收它们是努力的方向:post
bool ESP8266SoftwareSerialHTTPPOST::postString(String line) { if (doATCommand("AT+CIPSEND=" + (String)(line.length()+2), ">", deffStr, 1000)) { if (doATCommand(line, "SEND OK", "FAIL", 1000)) { return true; } else { Serial.println("Send:err"); Serial.println(resultLine); } } else { Serial.println("Post:ERROR" + Crlf + line + Crlf + line.length()); Serial.println(resultLine); } return false; }
须要注意的是,长度的计算多2字节,由于我使用的是println,而line并无加上\r\n。测试
另外,为了加速处理,除了原来对正确返回值"OK“等、超时处理以外,也对"ERROR"、"No AP"等进行了处理,这样能够快速从对串口的等待中返回。优化
最后,对这些功能进行组合,获得的结果仍是比较使人满意的,它已经连续工做了12小时以上,并无出现什么其余问题。ui