单片机教程网

电脑版
提示:原网页已由神马搜索转码, 内容由www.51hei.com提供.
查看:102|回复:0
打印上一主题下一主题

用esp32-cam向巴法云发送图片,同时小程序获取

[复制链接]
跳转到指定楼层
楼主
ID:1089516发表于 2024-5-6 21:24|只看该作者|只看大图回帖奖励
  1. #include< WiFi.h>
  2. #include< WiFiClient.h>
  3. #include< ArduinoJson.h>
  4. #include< HTTPClient.h>
  5. #include< EEPROM.h>
  6. #include< Ticker.h>
  7. #include "DHT.h" //加载DHT11的库
  8. #include "esp_http_client.h"
  9. #include "esp_camera.h"
  10. #include "configuration.h"
  11. #include "camera_pins.h"

  12. char config_flag = 0;   //配网成功标识
  13. //tcp客户端相关
  14. String TcpClient_Buff = "";
  15. unsigned int TcpClient_BuffIndex = 0;
  16. unsigned long TcpClient_preTick = 0;
  17. unsigned long preHeartTick = 0;//心跳
  18. unsigned long preTCPStartTick = 0;//连接
  19. String over_int = "false";
  20. bool preTCPConnected = false;
  21. String UID = "c124bafd03ba4909b1f7794c3e38af32";   //巴法云私钥
  22. String TOPIC = "mytrash";   //主题名字
  23. //图像拍照上传相关
  24. int capture_interval = 5 * 1000;                 // 20秒上传一次
  25. const char* uid = "c124bafd03ba4909b1f7794c3e38af32";  //私钥
  26. const char* topic = "mytrash";                 //主题
  27. const char* wechatMsg = "";                   //如果不为空,会推送到
  28. const char* wecomMsg = "";                     //如果不为空,会推送到企业,推送到企业的消息
  29. const char* urlPath = "";                     //如果不为空,会生成自定义图片链接,自定义图片上传后返回的图片url,url前一部分为巴法云域名,第二部分:私钥+主题名的md5值,第三部分为设置的图片链接值。
  30. bool flashRequired = true;                   //闪光灯,true是打开闪光灯
  31. const int brightLED = 4;                     //闪光灯引脚
  32. const int sensorPin = 14; // 溢出检测引脚
  33. unsigned char sendp = 0;
  34. int sensorValue = 0;
  35. int connect_time = 0;

  36. const char* post_url = "imagesbemfa/upload/v1/upimages.php";  // 默认上传地址
  37. static String httpResponseString;                             //接收服务器返回信息
  38. bool internet_connected = false;
  39. long current_millis;
  40. long last_capture_millis = 0;

  41. // Bright LED (Flash)
  42. const int ledFreq = 50;       // PWM settings
  43. const int ledChannel = 15;     // camera uses timer1
  44. const int ledRresolution = 8;  // resolution (8 = from 0 to 255)

  45. struct config_type
  46. {
  47.   char stassid[32];
  48.   char stapsw[64];
  49.    char cuid[40];
  50.    char ctopic[32];
  51.   uint8_t reboot;
  52.   uint8_t magic;
  53. };
  54. config_type config;

  55. WiFiClient TCPclient;
  56. Ticker delayTimer;
  57. DHT dht(DHTPIN, DHTTYPE);//声明 dht 函数

  58. /**
  59. * 存储配网信息
  60. */
  61. void saveConfig()
  62. {
  63.   int rand_key;
  64.   uint8_t mac[6];
  65.   WiFi.macAddress(mac);
  66.   config.reboot = 0;
  67.   EEPROM.begin(512);
  68.   uint8_t *p = (uint8_t*)(&config);
  69.   for (int i = 0; i< sizeof(config); i++)
  70.   {
  71.    EEPROM.write(i, *(p + i));
  72.   }
  73.   EEPROM.commit();
  74. }

  75. void delayRestart(float t)
  76. {
  77.   delayTimer.attach(t, []()
  78.   {
  79.    ESP.restart();
  80.   });
  81. }

  82. /**
  83. * airkiss配网
  84. */
  85. void doSmartconfig()
  86. {
  87.   Serial.println("waiting for WeChat Config.....");
  88.   Serial.print("*");
  89.   Serial.print("*");
  90.   Serial.print("*");
  91.   Serial.print("*");
  92.   Serial.print("*");
  93.   Serial.println("*");
  94.   WiFi.mode(WIFI_STA);
  95.   WiFi.stopSmartConfig();
  96.   WiFi.beginSmartConfig();
  97.   int cnt = 0;
  98.   bool flag_ok = false;
  99.   while (!WiFi.smartConfigDone())
  100.   {
  101.    delay(300);
  102.    if (flag_ok == true) continue;
  103.    if (WiFi.smartConfigDone())
  104.    {
  105.        strcpy(config.stassid, WiFi.SSID().c_str());
  106.        strcpy(config.stapsw, WiFi.psk().c_str());
  107.        config.magic = MAGIC_NUMBER;
  108.        saveConfig();
  109.        flag_ok = true;
  110.    }
  111.    cnt++;
  112.    if (cnt >= 600)
  113.    {
  114.      delayRestart(0);
  115.    }
  116.   }
  117. }

  118. /**
  119. * 设置SmartConfig
  120. */
  121. void setConfig()
  122. {
  123.    String mac = WiFi.macAddress().substring(8);//取mac地址做主题用
  124.    mac.replace(":", "");//去掉:号
  125.    WiFiClient client_bemfa_WiFiClient;
  126.    HTTPClient http_bemfa_HTTPClient;
  127.    http_bemfa_HTTPClient.begin(client_bemfa_WiFiClient,"//probemfa/vv/setSmartConfig?version=1&user="+mac);
  128.    int httpCode = http_bemfa_HTTPClient.GET();
  129.    if (httpCode == 200)
  130.    {
  131.      Serial.println("wifi smartconfig ok");
  132.    }
  133.    http_bemfa_HTTPClient.end();
  134. }

  135. /**
  136. * 初始化wifi信息,并连接路由器网络
  137. */
  138. void initWiFi()
  139. {
  140.   char temp[32];
  141.   uint8_t mac[6];
  142.   WiFi.macAddress(mac);
  143.   //sprintf(temp, "%s_%02X%02X%02X", HOST_NAME, mac[3], mac[4], mac[5]);
  144.   WiFi.hostname(temp);
  145.   if(WiFi.status() != WL_CONNECTED)
  146.   {
  147.    WiFi.disconnect();//断开连接
  148.    WiFi.mode(WIFI_STA);//STA模式
  149.    WiFi.begin(config.stassid, config.stapsw);//连接路由器
  150.   }
  151.   Serial.print("Waiting for connect");
  152.   while (WiFi.status() != WL_CONNECTED)
  153.   {//检查是否连接成功
  154.    delay(500);
  155.    Serial.print(".");
  156.    connect_time++;
  157.    if(connect_time >= 360)
  158.    {
  159.      connect_time = 0;
  160.      Serial.println("wifi connect faild");
  161.    }
  162.   }
  163.   if(config_flag == 1)
  164.   {
  165.    setConfig();
  166.   }
  167.   Serial.println("wifi is connected");
  168.   //Serial.print("ssid:");
  169.   //Serial.println(WiFi.SSID());
  170.   //Serial.print("psw:");
  171.   //Serial.println(WiFi.psk());
  172.   WiFi.softAP(temp);
  173. }

  174. /**
  175. * 加载存储的信息,并检查是否进行了反复5次重启恢复出厂信息
  176. */
  177. uint8_t *p = (uint8_t*)(&config);
  178. void loadConfig()
  179. {
  180.    uint8_t mac[6];
  181.    WiFi.macAddress(mac);
  182.    EEPROM.begin(512);
  183.    for (int i = 0; i< sizeof(config); i++)
  184.    {
  185.      *(p + i) = EEPROM.read(i);
  186.    }
  187.    config.reboot = config.reboot + 1;
  188.    if(config.reboot>=4)
  189.    {
  190.        restoreFactory();
  191.    }
  192.    if(config.magic != MAGIC_NUMBER)
  193.    {
  194.      config_flag = 1;
  195.    }
  196.    EEPROM.begin(512);
  197.    for (int i = 0; i< sizeof(config); i++)
  198.    {
  199.      EEPROM.write(i, *(p + i));
  200.    }
  201.    EEPROM.commit();
  202.    delay(2000);
  203.    EEPROM.begin(512);
  204.    config.reboot = 0;
  205.    for (int i = 0; i< sizeof(config); i++)
  206.    {
  207.      EEPROM.write(i, *(p + i));
  208.    }
  209.    EEPROM.commit();
  210.    delay(2000);
  211. }

  212. /**
  213. * 恢复出厂设置,清除存储的wifi信息
  214. */
  215. void restoreFactory(){
  216.    Serial.println("Restore Factory.......");
  217.    config.magic = 0x00;
  218.    strcpy(config.stassid, "");
  219.    strcpy(config.stapsw, "");
  220.    config.magic = 0x00;
  221.    saveConfig();
  222.    delayRestart(1);
  223.    while (1)
  224.    {
  225.      delay(100);
  226.    }
  227. }

  228. /**
  229. * 检查是否需要airkiss配网
  230. */
  231. void waitKey()
  232. {
  233.   if(config_flag == 1)
  234.   {
  235.    doSmartconfig();
  236.   }
  237. }

  238. /*
  239.   *发送数据到TCP服务器
  240. */
  241. void sendtoTCPServer(String p)
  242. {
  243.   if (!TCPclient.connected())
  244.   {
  245.    //Serial.println("Client is not readly");
  246.    return;
  247.   }
  248.   TCPclient.print(p);
  249.   //Serial.println("[Send to TCPServer]:String");
  250. }

  251. /*
  252.   *初始化和服务器建立连接
  253. */
  254. void startTCPClient()
  255. {
  256.   if(TCPclient.connect(TCP_SERVER_ADDR, atoi(TCP_SERVER_PORT)))
  257.   {
  258.    //Serial.print("\nINFO:Connected to server:");
  259.    //Serial.printf("%s:%d\r\n",TCP_SERVER_ADDR,atoi(TCP_SERVER_PORT));
  260.    preTCPConnected = true;
  261.    preHeartTick = millis();
  262.    TCPclient.setNoDelay(true);
  263.    sendtoTCPServer("cmd=1&uid="+UID+"&topic="+TOPIC+"\r\n");
  264.   }
  265.   else
  266.   {
  267.    //Serial.print("INFO:Failed connected to server:");
  268.    //Serial.println(TCP_SERVER_ADDR);
  269.    TCPclient.stop();
  270.    preTCPConnected = false;
  271.   }
  272.   preTCPStartTick = millis();
  273. }

  274. /*
  275.   *检查数据,发送数据
  276. */
  277. void doTCPClientTick()
  278. {
  279. //检查是否断开,断开后重连
  280.   if(WiFi.status() != WL_CONNECTED) return;
  281.   if (!TCPclient.connected())
  282.   {//断开重连
  283.    if(preTCPConnected == true)
  284.    {
  285.      preTCPConnected = false;
  286.      preTCPStartTick = millis();
  287.      Serial.println("TCP Client disconnected");
  288.      TCPclient.stop();
  289.    }
  290.    else if(millis() - preTCPStartTick > 1*1000)//重新连接
  291.      startTCPClient();
  292.   }
  293.   else
  294.   {
  295.    if (TCPclient.available())
  296.    {//收数据
  297.      char c =TCPclient.read();
  298.      TcpClient_Buff +=c;
  299.      TcpClient_BuffIndex++;
  300.      TcpClient_preTick = millis();
  301.      if(TcpClient_BuffIndex>=MAX_PACKETSIZE - 1)
  302.      {
  303.        TcpClient_BuffIndex = MAX_PACKETSIZE-2;
  304.        TcpClient_preTick = TcpClient_preTick - 200;
  305.      }
  306.      preHeartTick = millis();
  307.    }
  308.    if(millis() - preHeartTick >= upDataTime)
  309.    {//上传数据
  310.      preHeartTick = millis();
  311.      float h = dht.readHumidity();//读取湿度
  312.      float t = dht.readTemperature();//读取摄氏度
  313.      if (isnan(h) || isnan(t))
  314.      {
  315.        Serial.println("Failed to read from DHT sensor!");
  316.        return;
  317.      } //检查抓取是否成功
  318.      /*********************数据上传*******************/
  319.      String upstr = "";
  320.      String uart_str = "";
  321.      upstr = "cmd=2&uid="+UID+"&topic="+TOPIC+"&msg=#"+over_int+"#"+t+"#"+h+"\r\n";
  322.      sendtoTCPServer(upstr);
  323.      uart_str = "DATA#"+over_int+"#"+t+"#"+h+"\r\n";
  324.      Serial.print(uart_str);
  325.      upstr = "";
  326.    }
  327.   }
  328.   if((TcpClient_Buff.length() >= 1)&& (millis() - TcpClient_preTick>=200))
  329.   {//data ready
  330.    TCPclient.flush();
  331.    //Serial.print("Buff:");
  332.    //Serial.println(TcpClient_Buff);
  333.    TcpClient_Buff="";
  334.    TcpClient_BuffIndex = 0;
  335.   }
  336. }

  337. // change illumination LED brightness
  338. void brightLed(byte ledBrightness) {
  339.   ledcWrite(ledChannel, ledBrightness);  // change LED brightness (0 - 255)
  340. }

  341. // ----------------------------------------------------------------
  342. //     set up PWM for the illumination LED (flash)
  343. // ----------------------------------------------------------------
  344. // note: I am not sure PWM is very reliable on the esp32cam - requires more testing
  345. void setupFlashPWM() {
  346.   ledcSetup(ledChannel, ledFreq, ledRresolution);
  347.   ledcAttachPin(brightLED, ledChannel);
  348.   brightLed(0);
  349. }

  350. void Setint(){
  351.   sendp = 1;
  352. }

  353. void setup() {
  354.   Serial.begin(115200);
  355.   pinMode(brightLED, OUTPUT);   // flash LED
  356.   pinMode(sensorPin, INPUT); // 将引脚设置为输入模式
  357.   digitalWrite(brightLED, LOW);  // led off = Low
  358.   attachInterrupt(2, Setint, FALLING);  //当电平发生变化时,触发中断
  359.   attachInterrupt(13, restoreFactory, FALLING);  //当电平发生变化时,触发中断
  360.   dht.begin(); //启动传感器
  361.   camera_config_t config;
  362.   config.ledc_channel = LEDC_CHANNEL_0;
  363.   config.ledc_timer = LEDC_TIMER_0;
  364.   config.pin_d0 = Y2_GPIO_NUM;
  365.   config.pin_d1 = Y3_GPIO_NUM;
  366.   config.pin_d2 = Y4_GPIO_NUM;
  367.   config.pin_d3 = Y5_GPIO_NUM;
  368.   config.pin_d4 = Y6_GPIO_NUM;
  369.   config.pin_d5 = Y7_GPIO_NUM;
  370.   config.pin_d6 = Y8_GPIO_NUM;
  371.   config.pin_d7 = Y9_GPIO_NUM;
  372.   config.pin_xclk = XCLK_GPIO_NUM;
  373.   config.pin_pclk = PCLK_GPIO_NUM;
  374.   config.pin_vsync = VSYNC_GPIO_NUM;
  375.   config.pin_href = HREF_GPIO_NUM;
  376.   config.pin_sscb_sda = SIOD_GPIO_NUM;
  377.   config.pin_sscb_scl = SIOC_GPIO_NUM;
  378.   config.pin_pwdn = PWDN_GPIO_NUM;
  379.   config.pin_reset = RESET_GPIO_NUM;
  380.   config.xclk_freq_hz = 20000000;
  381.   config.frame_size = FRAMESIZE_UXGA;
  382.   config.pixel_format = PIXFORMAT_JPEG;  // for streaming
  383.   config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
  384.   config.fb_location = CAMERA_FB_IN_PSRAM;
  385.   config.jpeg_quality = 10;
  386.   config.fb_count = 1;

  387.   // if PSRAM IC present, init with UXGA resolution and higher JPEG quality
  388.   //               for larger pre-allocated frame buffer.
  389.   if (config.pixel_format == PIXFORMAT_JPEG) {
  390.    if (psramFound()) {
  391.      config.jpeg_quality = 10;
  392.      config.fb_count = 2;
  393.      config.grab_mode = CAMERA_GRAB_LATEST;

  394.    } else {
  395.      // Limit the frame size when PSRAM is not available
  396.      config.frame_size = FRAMESIZE_SVGA;
  397.      config.fb_location = CAMERA_FB_IN_DRAM;
  398.    }
  399.   } else {
  400.    // Best option for face detection/recognition
  401.    config.frame_size = FRAMESIZE_240X240;
  402. #if CONFIG_IDF_TARGET_ESP32S3
  403.    config.fb_count = 2;
  404. #endif
  405.   }

  406. #if defined(CAMERA_MODEL_ESP_EYE)
  407.   pinMode(13, INPUT_PULLUP);
  408.   pinMode(14, INPUT_PULLUP);
  409. #endif

  410.   // camera init
  411.   esp_err_t err = esp_camera_init(&config);
  412.   if (err != ESP_OK) {
  413.    //Serial.printf("Camera init failed with error 0x%x", err);
  414.    return;
  415.   }

  416.   sensor_t* s = esp_camera_sensor_get();
  417.   // initial sensors are flipped vertically and colors are a bit saturated
  418.   if (s->id.PID == OV3660_PID) {
  419.    s->set_vflip(s, 1);       // flip it back
  420.    s->set_brightness(s, 1);   // up the brightness just a bit
  421.    s->set_saturation(s, -2);  // lower the saturation
  422.   }


  423. #if defined(CAMERA_MODEL_M5STACK_WIDE) || defined(CAMERA_MODEL_M5STACK_ESP32CAM)
  424.   s->set_vflip(s, 1);
  425.   s->set_hmirror(s, 1);
  426. #endif

  427. #if defined(CAMERA_MODEL_ESP32S3_EYE)
  428.   s->set_vflip(s, 1);
  429. #endif

  430.   loadConfig();
  431.   waitKey();
  432.   initWiFi();
  433.   //Serial.print("Camera Ready!:");
  434.   //Serial.println(WiFi.localIP());
  435.   setupFlashPWM();  // configure PWM for the illumination LED
  436. }

  437. /********http请求处理函数*********/
  438. esp_err_t _http_event_handler(esp_http_client_event_t* evt) {
  439.   if (evt->event_id == HTTP_EVENT_ON_DATA) {
  440.    httpResponseString.concat((char*)evt->data);
  441.   }
  442.   return ESP_OK;
  443. }

  444. static esp_err_t take_send_photo() {
  445.   if (flashRequired) {
  446.    brightLed(255);
  447.    delay(300);
  448.   }
  449.   //Serial.println("take_send_photo...");
  450.   camera_fb_t* fb = NULL;
  451.   esp_err_t res = ESP_OK;
  452.   fb = esp_camera_fb_get();
  453.   if (flashRequired) brightLed(0);  // change LED brightness back to previous state

  454.   if (!fb) {
  455.    //Serial.println("Camera capture failed...");
  456.    return ESP_FAIL;
  457.   }

  458.   httpResponseString = "";
  459.   esp_http_client_handle_t http_client;
  460.   esp_http_client_config_t config_client = { 0 };
  461.   config_client.url = post_url;
  462.   config_client.event_handler = _http_event_handler;
  463.   config_client.method = HTTP_METHOD_POST;
  464.   http_client = esp_http_client_init(&config_client);
  465.   esp_http_client_set_post_field(http_client, (const char*)fb->buf, fb->len);  //设置http发送的内容和长度
  466.   esp_http_client_set_header(http_client, "Content-Type", "image/jpg");       //设置http头部字段
  467.   esp_http_client_set_header(http_client, "Authorization", uid);           //设置http头部字段
  468.   esp_http_client_set_header(http_client, "Authtopic", topic);             //设置http头部字段
  469.   esp_http_client_set_header(http_client, "wechatmsg", wechatMsg);         //设置http头部字段
  470.   esp_http_client_set_header(http_client, "wecommsg", wecomMsg);           //设置http头部字段
  471.   esp_http_client_set_header(http_client, "picpath", urlPath);             //设置http头部字段
  472.   esp_err_t err = esp_http_client_perform(http_client);                 //发送http请求
  473.   if (err == ESP_OK) {
  474.    //json数据解析
  475.    StaticJsonDocument<200> doc;
  476.    DeserializationError error = deserializeJson(doc, httpResponseString);
  477.    if (error) {
  478.      //Serial.print(F("deserializeJson() failed: "));
  479.      //Serial.println(error.c_str());
  480.    }
  481.   }
  482.   //Serial.println("Taking picture END");
  483.   esp_camera_fb_return(fb);
  484.   esp_http_client_cleanup(http_client);
  485.   return res;
  486. }

  487. void loop()
  488. {
  489.   sensorValue = digitalRead(sensorPin); // 读取引脚的电平
  490.   if (sensorValue == HIGH)
  491.   {
  492.    over_int = "true";
  493.   }
  494.   else
  495.   {
  496.    over_int = "false";
  497.   }
  498.   doTCPClientTick();
  499.   // current_millis = millis();
  500.   // if (current_millis - last_capture_millis > capture_interval)
  501.   // {
  502.   //   last_capture_millis = millis();
  503.   //   take_send_photo();
  504.   // }
  505.   if (sendp == 1)
  506.   {  // Take another picture
  507.    take_send_photo();
  508.    sendp = 0;
  509.   }
  510. }
复制代码

图片1.png(688.86 KB, 下载次数: 0)

图片1.png

6.9 KB, 下载次数: 2, 下载积分: 黑币 -5

esp32-cam代码

trash.zip

7.63 KB, 下载次数: 2, 下载积分: 黑币 -5

小程序代码

评分

黑币 +50
收起理由
+ 50
共享资料的黑币奖励!

查看全部评分

手机版|小黑屋|51黑电子论坛|51黑电子论坛6群QQ管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网