arduino esp32 读福申甲醛传感器

arduino esp32 读福申甲醛传感器

想法

arduino库丰富,几行代码即可完成需求描述。
缺点是不能Debug。
想持续监测甲醛变化。
使用杜邦线连接,需要将传感器的输出线焊接杜邦线做转换。
杜邦线是一公一母。

源代码

可以开启软AP,也可以连到无线路由器。
买到的UNO D1 R32 ,无线性能不好,距离路由器2米,信号强度都到-90多了。
这里,将网络改为AP。

#include <HTTPServer.hpp>
#include <HTTPRequest.hpp>
#include <HTTPResponse.hpp>
#include <WebsocketHandler.hpp>
#include <WiFi.h>

#define ESP_getChipId()   ((uint32_t)ESP.getEfuseMac())
#define MAX_CLIENTS 4

// http
using namespace httpsserver;
HTTPServer secureServer = HTTPServer();
void handleRoot(HTTPRequest * req, HTTPResponse * res);
char crc(String s);

int data = 0;
float value = 0;
String buffer = "";
String buffer2 = "";
String result;

class ChatHandler : public WebsocketHandler {
  public:
    static WebsocketHandler* create();
    void onClose();
};
ChatHandler* activeClients[MAX_CLIENTS];

void setup() {
  // Initialize the slots
  for (int i = 0; i < MAX_CLIENTS; i++) activeClients[i] = nullptr;

  Serial.begin(9600);
  Serial2.begin(9600);

  // wifi
  IPAddress ip(192, 168, 3, 1);
  IPAddress gw(192, 168, 3, 1);
  IPAddress mask(255, 255, 255, 0);
  WiFi.softAPConfig(ip, gw, mask);
  String chip_id = "ESP_" + String(ESP_getChipId());
  const char *ssid = chip_id.c_str();
  WiFi.softAP(ssid);

  // http
  ResourceNode * nodeRoot = new ResourceNode("/", "GET", &handleRoot);
  secureServer.registerNode(nodeRoot);
  // chat register
  WebsocketNode * chatNode = new WebsocketNode("/chat", &ChatHandler::create);
  secureServer.registerNode(chatNode);

  secureServer.start();

  //
}

void loop() {
  // 读甲醛传感器
  while (Serial2.available() > 0) {
    data = Serial2.read();
    Serial.println(data);

    buffer += (char)data;
    buffer2 += String(data, HEX) + " ";

  }  // while 0

  if (buffer.charAt(0) == 0xff && buffer.length() == 9) {
    // 验证crc
    char crcValue = crc(buffer);
    if (crcValue == buffer.charAt(8))
      value = (float)(buffer.charAt(4) * 256 + buffer.charAt(5)) / 1000.0;
    else
      Serial.println("crc not equal");
    buffer = "";
    result = "结果:" + String(value) + ",数据:" + buffer2;
    buffer2 = "";
  }  // if 1

  if (buffer.length() >= 9)
    buffer = "";

  Serial2.flush();

  // web
  secureServer.loop();

  // 发送数据
  for (int i = 0; i < MAX_CLIENTS; i++) {
    if (activeClients[i] != nullptr) {
      activeClients[i]->send(result.c_str(), WebsocketHandler::SEND_TYPE_TEXT);
    }
  }

  // delay
  delay(100);

  // loop
}


void handleRoot(HTTPRequest * req, HTTPResponse * res) {
  // Status code is 200 OK by default.
  // We want to deliver a simple HTML page, so we send a corresponding content type:
  res->setHeader("Content-Type", "text/html");

  // The response implements the Print interface, so you can use it just like
  // you would write to Serial etc.
  res->println("<!DOCTYPE html>");
  res->println("<html  lang=\"en\">");
  res->println("<head><meta charset=\"UTF-8\"><title>Hello World!</title></head>");
  res->println("<body>");
  res->println("<h3>甲醛读数</h3>");

  res->print("<p>服务器已运行 ");
  res->print((int)(millis() / 1000 / 60), DEC);
  res->println(" 分.</p>");

  res->println("<p>数值(毫克/立方米.): </p>");
  res->print("<div id=\"id_value\">");
  res->print(value, DEC);
  res->println("</div>");

  res->println("</body>");
  res->println("</html>");

  res->print(
    "    <script type=\"text/javascript\">\n"
    "        const divOut =  document.getElementById(\"id_value\");\n"
    "\n"
    "        class Chat {\n"
    "            constructor() {\n"
    "                this.connecting = false;\n"
    "                this.connected = false;\n"
    "                this.ws = null;\n"
    "            };\n"
    "            connect() {\n"
    "                if (this.ws === null) {\n"
    "                    this.connecting = true;\n"
    "                    this.ws = new WebSocket(\"ws://\" + document.location.host + \"/chat\");\n"
    "                    this.ws.onopen = e => {\n"
    "                        this.connecting = false;\n"
    "                        this.connected = true;\n"
    "                    };\n"
    "                    this.ws.onmessage = e => {\n"
    "                        divOut.innerHTML =\"<p>\"+e.data+\"</p>\";\n"
    "                        //console.log(e.data);\n"
    "                    }\n"
    "                    this.ws.onclose = e => {\n"
    "                        this.disconnect();\n"
    "                    }\n"
    "                }\n"
    "            };\n"
    "            disconnect() {\n"
    "                if (this.ws !== null) {\n"
    "                    this.ws.close();\n"
    "                    this.ws = null;\n"
    "                }\n"
    "                if (this.connected) {\n"
    "                    this.connected = false;\n"
    "                }\n"
    "            }};\n"
    "        let chat = new Chat();\n"
    "        if (!chat.connected && !chat.connecting) {\n"
    "                chat.connect();\n"
    "            }\n"
    "    </script>\n"
  );
}

WebsocketHandler * ChatHandler::create() {
  Serial.println("Creating new chat client!");
  ChatHandler * handler = new ChatHandler();
  for (int i = 0; i < MAX_CLIENTS; i++) {
    if (activeClients[i] == nullptr) {
      activeClients[i] = handler;
      break;
    }
  }
  return handler;
}

// When the websocket is closing, we remove the client from the array
void ChatHandler::onClose() {
  for (int i = 0; i < MAX_CLIENTS; i++) {
    if (activeClients[i] == this) {
      activeClients[i] = nullptr;
    }
  }
}

// CRC计算
char crc(String s) {
  int sum = 0;
  for (int i = 1; i < s.length() - 1; i++)
    sum += s[i];
  int value = ~sum + 1;
  return value & 0xff;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

容沁风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值