|
- #include <WiFi.h>
- #include <WiFiClient.h>
- #include <ArduinoJson.h>
- #include <HTTPClient.h>
- #include <EEPROM.h>
- #include <Ticker.h>
- #include "DHT.h" //加载DHT11的库
- #include "esp_http_client.h"
- #include "esp_camera.h"
- #include "configuration.h"
- #include "camera_pins.h"
- char config_flag = 0; //配网成功标识
- //tcp客户端相关
- String TcpClient_Buff = "";
- unsigned int TcpClient_BuffIndex = 0;
- unsigned long TcpClient_preTick = 0;
- unsigned long preHeartTick = 0;//心跳
- unsigned long preTCPStartTick = 0;//连接
- String over_int = "false";
- bool preTCPConnected = false;
- String UID = "c124bafd03ba4909b1f7794c3e38af32"; //巴法云私钥
- String TOPIC = "mytrash"; //主题名字
- //图像拍照上传相关
- int capture_interval = 5 * 1000; // 20秒上传一次
- const char* uid = "c124bafd03ba4909b1f7794c3e38af32"; //私钥
- const char* topic = "mytrash"; //主题
- const char* wechatMsg = ""; //如果不为空,会推送到
- const char* wecomMsg = ""; //如果不为空,会推送到企业,推送到企业的消息
- const char* urlPath = ""; //如果不为空,会生成自定义图片链接,自定义图片上传后返回的图片url,url前一部分为巴法云域名,第二部分:私钥+主题名的md5值,第三部分为设置的图片链接值。
- bool flashRequired = true; //闪光灯,true是打开闪光灯
- const int brightLED = 4; //闪光灯引脚
- const int sensorPin = 14; // 溢出检测引脚
- unsigned char sendp = 0;
- int sensorValue = 0;
- int connect_time = 0;
- const char* post_url = "imagesbemfa/upload/v1/upimages.php"; // 默认上传地址
- static String httpResponseString; //接收服务器返回信息
- bool internet_connected = false;
- long current_millis;
- long last_capture_millis = 0;
- // Bright LED (Flash)
- const int ledFreq = 50; // PWM settings
- const int ledChannel = 15; // camera uses timer1
- const int ledRresolution = 8; // resolution (8 = from 0 to 255)
- struct config_type
- {
- char stassid[32];
- char stapsw[64];
- char cuid[40];
- char ctopic[32];
- uint8_t reboot;
- uint8_t magic;
- };
- config_type config;
- WiFiClient TCPclient;
- Ticker delayTimer;
- DHT dht(DHTPIN, DHTTYPE);//声明 dht 函数
- /**
- * 存储配网信息
- */
- void saveConfig()
- {
- int rand_key;
- uint8_t mac[6];
- WiFi.macAddress(mac);
- config.reboot = 0;
- EEPROM.begin(512);
- uint8_t *p = (uint8_t*)(&config);
- for (int i = 0; i < sizeof(config); i++)
- {
- EEPROM.write(i, *(p + i));
- }
- EEPROM.commit();
- }
-
- void delayRestart(float t)
- {
- delayTimer.attach(t, []()
- {
- ESP.restart();
- });
- }
- /**
- * airkiss配网
- */
- void doSmartconfig()
- {
- Serial.println("waiting for WeChat Config.....");
- Serial.print("*");
- Serial.print("*");
- Serial.print("*");
- Serial.print("*");
- Serial.print("*");
- Serial.println("*");
- WiFi.mode(WIFI_STA);
- WiFi.stopSmartConfig();
- WiFi.beginSmartConfig();
- int cnt = 0;
- bool flag_ok = false;
- while (!WiFi.smartConfigDone())
- {
- delay(300);
- if (flag_ok == true) continue;
- if (WiFi.smartConfigDone())
- {
- strcpy(config.stassid, WiFi.SSID().c_str());
- strcpy(config.stapsw, WiFi.psk().c_str());
- config.magic = MAGIC_NUMBER;
- saveConfig();
- flag_ok = true;
- }
- cnt++;
- if (cnt >= 600)
- {
- delayRestart(0);
- }
- }
- }
- /**
- * 设置SmartConfig
- */
- void setConfig()
- {
- String mac = WiFi.macAddress().substring(8);//取mac地址做主题用
- mac.replace(":", "");//去掉:号
- WiFiClient client_bemfa_WiFiClient;
- HTTPClient http_bemfa_HTTPClient;
- http_bemfa_HTTPClient.begin(client_bemfa_WiFiClient,"//probemfa/vv/setSmartConfig?version=1&user="+mac);
- int httpCode = http_bemfa_HTTPClient.GET();
- if (httpCode == 200)
- {
- Serial.println("wifi smartconfig ok");
- }
- http_bemfa_HTTPClient.end();
- }
- /**
- * 初始化wifi信息,并连接路由器网络
- */
- void initWiFi()
- {
- char temp[32];
- uint8_t mac[6];
- WiFi.macAddress(mac);
- //sprintf(temp, "%s_%02X%02X%02X", HOST_NAME, mac[3], mac[4], mac[5]);
- WiFi.hostname(temp);
- if(WiFi.status() != WL_CONNECTED)
- {
- WiFi.disconnect();//断开连接
- WiFi.mode(WIFI_STA);//STA模式
- WiFi.begin(config.stassid, config.stapsw);//连接路由器
- }
- Serial.print("Waiting for connect");
- while (WiFi.status() != WL_CONNECTED)
- {//检查是否连接成功
- delay(500);
- Serial.print(".");
- connect_time++;
- if(connect_time >= 360)
- {
- connect_time = 0;
- Serial.println("wifi connect faild");
- }
- }
- if(config_flag == 1)
- {
- setConfig();
- }
- Serial.println("wifi is connected");
- //Serial.print("ssid:");
- //Serial.println(WiFi.SSID());
- //Serial.print("psw:");
- //Serial.println(WiFi.psk());
- WiFi.softAP(temp);
- }
- /**
- * 加载存储的信息,并检查是否进行了反复5次重启恢复出厂信息
- */
- uint8_t *p = (uint8_t*)(&config);
- void loadConfig()
- {
- uint8_t mac[6];
- WiFi.macAddress(mac);
- EEPROM.begin(512);
- for (int i = 0; i < sizeof(config); i++)
- {
- *(p + i) = EEPROM.read(i);
- }
- config.reboot = config.reboot + 1;
- if(config.reboot>=4)
- {
- restoreFactory();
- }
- if(config.magic != MAGIC_NUMBER)
- {
- config_flag = 1;
- }
- EEPROM.begin(512);
- for (int i = 0; i < sizeof(config); i++)
- {
- EEPROM.write(i, *(p + i));
- }
- EEPROM.commit();
- delay(2000);
- EEPROM.begin(512);
- config.reboot = 0;
- for (int i = 0; i < sizeof(config); i++)
- {
- EEPROM.write(i, *(p + i));
- }
- EEPROM.commit();
- delay(2000);
- }
- /**
- * 恢复出厂设置,清除存储的wifi信息
- */
- void restoreFactory(){
- Serial.println("Restore Factory.......");
- config.magic = 0x00;
- strcpy(config.stassid, "");
- strcpy(config.stapsw, "");
- config.magic = 0x00;
- saveConfig();
- delayRestart(1);
- while (1)
- {
- delay(100);
- }
- }
- /**
- * 检查是否需要airkiss配网
- */
- void waitKey()
- {
- if(config_flag == 1)
- {
- doSmartconfig();
- }
- }
- /*
- *发送数据到TCP服务器
- */
- void sendtoTCPServer(String p)
- {
- if (!TCPclient.connected())
- {
- //Serial.println("Client is not readly");
- return;
- }
- TCPclient.print(p);
- //Serial.println("[Send to TCPServer]:String");
- }
- /*
- *初始化和服务器建立连接
- */
- void startTCPClient()
- {
- if(TCPclient.connect(TCP_SERVER_ADDR, atoi(TCP_SERVER_PORT)))
- {
- //Serial.print("\nINFO:Connected to server:");
- //Serial.printf("%s:%d\r\n",TCP_SERVER_ADDR,atoi(TCP_SERVER_PORT));
- preTCPConnected = true;
- preHeartTick = millis();
- TCPclient.setNoDelay(true);
- sendtoTCPServer("cmd=1&uid="+UID+"&topic="+TOPIC+"\r\n");
- }
- else
- {
- //Serial.print("INFO:Failed connected to server:");
- //Serial.println(TCP_SERVER_ADDR);
- TCPclient.stop();
- preTCPConnected = false;
- }
- preTCPStartTick = millis();
- }
- /*
- *检查数据,发送数据
- */
- void doTCPClientTick()
- {
- //检查是否断开,断开后重连
- if(WiFi.status() != WL_CONNECTED) return;
- if (!TCPclient.connected())
- {//断开重连
- if(preTCPConnected == true)
- {
- preTCPConnected = false;
- preTCPStartTick = millis();
- Serial.println("TCP Client disconnected");
- TCPclient.stop();
- }
- else if(millis() - preTCPStartTick > 1*1000)//重新连接
- startTCPClient();
- }
- else
- {
- if (TCPclient.available())
- {//收数据
- char c =TCPclient.read();
- TcpClient_Buff +=c;
- TcpClient_BuffIndex++;
- TcpClient_preTick = millis();
- if(TcpClient_BuffIndex>=MAX_PACKETSIZE - 1)
- {
- TcpClient_BuffIndex = MAX_PACKETSIZE-2;
- TcpClient_preTick = TcpClient_preTick - 200;
- }
- preHeartTick = millis();
- }
- if(millis() - preHeartTick >= upDataTime)
- {//上传数据
- preHeartTick = millis();
- float h = dht.readHumidity();//读取湿度
- float t = dht.readTemperature();//读取摄氏度
- if (isnan(h) || isnan(t))
- {
- Serial.println("Failed to read from DHT sensor!");
- return;
- } //检查抓取是否成功
- /*********************数据上传*******************/
- String upstr = "";
- String uart_str = "";
- upstr = "cmd=2&uid="+UID+"&topic="+TOPIC+"&msg=#"+over_int+"#"+t+"#"+h+"\r\n";
- sendtoTCPServer(upstr);
- uart_str = "DATA#"+over_int+"#"+t+"#"+h+"\r\n";
- Serial.print(uart_str);
- upstr = "";
- }
- }
- if((TcpClient_Buff.length() >= 1) && (millis() - TcpClient_preTick>=200))
- {//data ready
- TCPclient.flush();
- //Serial.print("Buff:");
- //Serial.println(TcpClient_Buff);
- TcpClient_Buff="";
- TcpClient_BuffIndex = 0;
- }
- }
- // change illumination LED brightness
- void brightLed(byte ledBrightness) {
- ledcWrite(ledChannel, ledBrightness); // change LED brightness (0 - 255)
- }
- // ----------------------------------------------------------------
- // set up PWM for the illumination LED (flash)
- // ----------------------------------------------------------------
- // note: I am not sure PWM is very reliable on the esp32cam - requires more testing
- void setupFlashPWM() {
- ledcSetup(ledChannel, ledFreq, ledRresolution);
- ledcAttachPin(brightLED, ledChannel);
- brightLed(0);
- }
- void Setint(){
- sendp = 1;
- }
- void setup() {
- Serial.begin(115200);
- pinMode(brightLED, OUTPUT); // flash LED
- pinMode(sensorPin, INPUT); // 将引脚设置为输入模式
- digitalWrite(brightLED, LOW); // led off = Low
- attachInterrupt(2, Setint, FALLING); //当电平发生变化时,触发中断
- attachInterrupt(13, restoreFactory, FALLING); //当电平发生变化时,触发中断
- dht.begin(); //启动传感器
- camera_config_t config;
- config.ledc_channel = LEDC_CHANNEL_0;
- config.ledc_timer = LEDC_TIMER_0;
- config.pin_d0 = Y2_GPIO_NUM;
- config.pin_d1 = Y3_GPIO_NUM;
- config.pin_d2 = Y4_GPIO_NUM;
- config.pin_d3 = Y5_GPIO_NUM;
- config.pin_d4 = Y6_GPIO_NUM;
- config.pin_d5 = Y7_GPIO_NUM;
- config.pin_d6 = Y8_GPIO_NUM;
- config.pin_d7 = Y9_GPIO_NUM;
- config.pin_xclk = XCLK_GPIO_NUM;
- config.pin_pclk = PCLK_GPIO_NUM;
- config.pin_vsync = VSYNC_GPIO_NUM;
- config.pin_href = HREF_GPIO_NUM;
- config.pin_sscb_sda = SIOD_GPIO_NUM;
- config.pin_sscb_scl = SIOC_GPIO_NUM;
- config.pin_pwdn = PWDN_GPIO_NUM;
- config.pin_reset = RESET_GPIO_NUM;
- config.xclk_freq_hz = 20000000;
- config.frame_size = FRAMESIZE_UXGA;
- config.pixel_format = PIXFORMAT_JPEG; // for streaming
- config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
- config.fb_location = CAMERA_FB_IN_PSRAM;
- config.jpeg_quality = 10;
- config.fb_count = 1;
- // if PSRAM IC present, init with UXGA resolution and higher JPEG quality
- // for larger pre-allocated frame buffer.
- if (config.pixel_format == PIXFORMAT_JPEG) {
- if (psramFound()) {
- config.jpeg_quality = 10;
- config.fb_count = 2;
- config.grab_mode = CAMERA_GRAB_LATEST;
- } else {
- // Limit the frame size when PSRAM is not available
- config.frame_size = FRAMESIZE_SVGA;
- config.fb_location = CAMERA_FB_IN_DRAM;
- }
- } else {
- // Best option for face detection/recognition
- config.frame_size = FRAMESIZE_240X240;
- #if CONFIG_IDF_TARGET_ESP32S3
- config.fb_count = 2;
- #endif
- }
- #if defined(CAMERA_MODEL_ESP_EYE)
- pinMode(13, INPUT_PULLUP);
- pinMode(14, INPUT_PULLUP);
- #endif
- // camera init
- esp_err_t err = esp_camera_init(&config);
- if (err != ESP_OK) {
- //Serial.printf("Camera init failed with error 0x%x", err);
- return;
- }
- sensor_t* s = esp_camera_sensor_get();
- // initial sensors are flipped vertically and colors are a bit saturated
- if (s->id.PID == OV3660_PID) {
- s->set_vflip(s, 1); // flip it back
- s->set_brightness(s, 1); // up the brightness just a bit
- s->set_saturation(s, -2); // lower the saturation
- }
- #if defined(CAMERA_MODEL_M5STACK_WIDE) || defined(CAMERA_MODEL_M5STACK_ESP32CAM)
- s->set_vflip(s, 1);
- s->set_hmirror(s, 1);
- #endif
- #if defined(CAMERA_MODEL_ESP32S3_EYE)
- s->set_vflip(s, 1);
- #endif
- loadConfig();
- waitKey();
- initWiFi();
- //Serial.print("Camera Ready!:");
- //Serial.println(WiFi.localIP());
- setupFlashPWM(); // configure PWM for the illumination LED
- }
- /********http请求处理函数*********/
- esp_err_t _http_event_handler(esp_http_client_event_t* evt) {
- if (evt->event_id == HTTP_EVENT_ON_DATA) {
- httpResponseString.concat((char*)evt->data);
- }
- return ESP_OK;
- }
- static esp_err_t take_send_photo() {
- if (flashRequired) {
- brightLed(255);
- delay(300);
- }
- //Serial.println("take_send_photo...");
- camera_fb_t* fb = NULL;
- esp_err_t res = ESP_OK;
- fb = esp_camera_fb_get();
- if (flashRequired) brightLed(0); // change LED brightness back to previous state
- if (!fb) {
- //Serial.println("Camera capture failed...");
- return ESP_FAIL;
- }
- httpResponseString = "";
- esp_http_client_handle_t http_client;
- esp_http_client_config_t config_client = { 0 };
- config_client.url = post_url;
- config_client.event_handler = _http_event_handler;
- config_client.method = HTTP_METHOD_POST;
- http_client = esp_http_client_init(&config_client);
- esp_http_client_set_post_field(http_client, (const char*)fb->buf, fb->len); //设置http发送的内容和长度
- esp_http_client_set_header(http_client, "Content-Type", "image/jpg"); //设置http头部字段
- esp_http_client_set_header(http_client, "Authorization", uid); //设置http头部字段
- esp_http_client_set_header(http_client, "Authtopic", topic); //设置http头部字段
- esp_http_client_set_header(http_client, "wechatmsg", wechatMsg); //设置http头部字段
- esp_http_client_set_header(http_client, "wecommsg", wecomMsg); //设置http头部字段
- esp_http_client_set_header(http_client, "picpath", urlPath); //设置http头部字段
- esp_err_t err = esp_http_client_perform(http_client); //发送http请求
- if (err == ESP_OK) {
- //json数据解析
- StaticJsonDocument<200> doc;
- DeserializationError error = deserializeJson(doc, httpResponseString);
- if (error) {
- //Serial.print(F("deserializeJson() failed: "));
- //Serial.println(error.c_str());
- }
- }
- //Serial.println("Taking picture END");
- esp_camera_fb_return(fb);
- esp_http_client_cleanup(http_client);
- return res;
- }
- void loop()
- {
- sensorValue = digitalRead(sensorPin); // 读取引脚的电平
- if (sensorValue == HIGH)
- {
- over_int = "true";
- }
- else
- {
- over_int = "false";
- }
- doTCPClientTick();
- // current_millis = millis();
- // if (current_millis - last_capture_millis > capture_interval)
- // {
- // last_capture_millis = millis();
- // take_send_photo();
- // }
- if (sendp == 1)
- { // Take another picture
- take_send_photo();
- sendp = 0;
- }
- }
复制代码
|
评分
-
查看全部评分
|