ESP32CAM连接阿里云物联网平台

搭建arduino开发环境

这里不多说,网上有很多教程。简单说下我在搭建环境时踩的一些坑。

1.在arduino库管理器中下载esp32的库出错

解决方法:搭个梯子下载就行了

2.上传项目报错

在这里插入图片描述
这个问题出现的原因是板子连线有问题,在烧录的时候必须使用5V电压供电。上传后运行之前,断开GPIO0与GND的连接,并且使用3.3V电压供电,就可以跑起来了。

3.文件太大无法上传

工具-Partition Scheme-Huge APP,选这个就可以上传了

MQTT连接阿里云物联网平台

建议使用mqtt fx工具,方便模拟设备连接平台。
在设置的过程中要填一些id,密码之类的东西。
Broker Address是阿里云官方给出的,用上海这个就可以。
Broker Port填1883。
后面那三个推荐一个工具,技小新-MQTT单片机编程小工具。直接用这个工具可以计算出来。
在这里插入图片描述
在这里插入图片描述
SN/NAC随便填,product_key、device_name、device_secret这三个是物联网平台创建设备就会给出的信息复制过来就行,点生成基本信息,后面的数据就计算出来了,直接在mqtt fx中填就行了。

连接成功的话mqtt fx灯的颜色是绿色的。这样就可以模拟板子给平台上报或者订阅属性,目的是用来测试通信的。

图片数据上传

esp32cam抓拍的图片数据先保存在sd卡中,再上传。图片数据必须分包发送,要不然板子会崩溃,直接复位。data[4104]差不多是板子内存的极限了,我设置的物联网平台接收的数据格式是字符串,范围是0-2048字节,所以每次分包的大小必须在2048字节之下。但是,在上传的过程中,经过多次试验,每次数据大小只能在800字节,超过800字节就只上传最后一个包的数据,其余数据全部无法上传。

另一种方法是把jpg图片的数据大小降下来,导师说试试灰度处理。我感觉大小这方面已经是极限了,再降图片可能就无法看了。如果有更好的方法,可以私信我哦 ^ _ ^

最终完整代码

按键设置:GPIO15

#include "esp_camera.h"
#include "Arduino.h"
#include "FS.h"                // SD Card ESP32
#include "SD_MMC.h"            // SD Card ESP32
#include "soc/soc.h"           // Disable brownour problems
#include "soc/rtc_cntl_reg.h"  // Disable brownour problems
#include "driver/rtc_io.h"
#include <EEPROM.h>  
#include"camera_pins.h"
#include <WiFi.h>
#include <ArduinoJson.h>
#include <aliyun_mqtt.h>

#define EEPROM_SIZE 1
int pictureNumber = 0;
String msg;
int buttonState =0;
int btnHold=0;

// 你的wifi账号密码
const char* ssid     = "";
const char* password = "";

//阿里云三元组
#define PRODUCT_KEY "a1mAaYPL2Qf"
#define DEVICE_NAME "haote216"
#define DEVICE_SECRET "YgQ5MMv4wgnROBLQqInLpj6eZy0UTAkZ"

//订阅和发布时所需的主题
#define ALINK_BODY_FORMAT "{\"id\":\"1189401707\",\"version\":\"1.0.0\",\"method\":\"%s\",\"params\":%s}"
#define ALINK_TOPIC_PROP_POST "/sys/a1mAaYPL2Qf/haote216/thing/event/property/post"
#define ALINK_TOPIC_PROP_POSTRSP "/sys/a1mAaYPL2Qf/haote216/thing/event/property/post_reply"
#define ALINK_TOPIC_PROP_SET "/sys/a1mAaYPL2Qf/haote216/thing/service/property/set"
#define ALINK_METHOD_PROP_POST "thing.event.property.post"

//创建WiFiClient实例
WiFiClient espClient;

//创建MqttClient实例
PubSubClient mqttClient(espClient);

//连接Mqtt订阅属性设置Topic
void mqttCheckConnect()
{
    bool connected = connectAliyunMQTT(mqttClient, PRODUCT_KEY, DEVICE_NAME, DEVICE_SECRET);
    if (connected)
    {
        Serial.println("MQTT connect succeed!");
        //订阅属性设置Topic
        mqttClient.subscribe(ALINK_TOPIC_PROP_SET); 
        Serial.println("subscribe done");
    }
}

void camera_init()
{
  // Camera initOV2640 camera module
  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.pixel_format = PIXFORMAT_JPEG;
  if (psramFound()) {
    config.frame_size = FRAMESIZE_UXGA;
    config.jpeg_quality = 10;
    config.fb_count = 2;
  } else {
    config.frame_size = FRAMESIZE_SVGA;
    config.jpeg_quality = 12;
    config.fb_count = 1;
  }
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    return;
  }
}

void sd_init(void)
{
    //SD card init
    if (!SD_MMC.begin()) {
        Serial.println("Card Mount Failed");
        return;
    }
    uint8_t cardType = SD_MMC.cardType();
    if (cardType == CARD_NONE) {
        Serial.println("No SD_MMC card attached");
        return;
    }  
}

void SPIFFS_init()
{
  //初始化SPIFFS
  if (!SPIFFS.begin(true)) {   
  Serial.println("An Error has occurred while mounting SPIFFS");}
  else {
    delay(500);
    Serial.println("SPIFFS mounted successfully");
  }
  //Turn-off the 'brownout detector'
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
}

void setup() {
  Serial.begin(115200);         //串口初始化
  pinMode(KEY, INPUT);        //按键初始化
  WiFi.begin(ssid, password);   //连接wifi
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi...");
  }
   camera_init();
   sd_init();
   SPIFFS_init();
   Serial.print("IP Address: http://");  //打印IP地址用于服务器连接
   Serial.println(WiFi.localIP());
   mqttCheckConnect(); //初始化首次链接
}

void loop() {
    //=====按键扫描=====
    buttonState=digitalRead(KEY);
    if(buttonState==LOW && btnHold ==0)
    {
      delay(100);
      if(buttonState ==LOW)
      btnHold =1;
      Serial.print("按钮触发成功\n");    
      Serial.print( "进行拍照\n");
      camera_fb_t * fb = esp_camera_fb_get();
      if (!fb)
      {
          Serial.print( "Camera capture failed");
          return;
      }
      else
      { 
           EEPROM.begin(EEPROM_SIZE);
           pictureNumber = EEPROM.read(0) + 1;       
           // Path where new picture will be saved in SD Card
           String path = "/picture" + String(pictureNumber) +".jpg";

           fs::FS &fs = SD_MMC; 
           Serial.printf("文件名字: %s\n", path.c_str());
           File file = fs.open(path.c_str(), FILE_WRITE);
           if(!file){
           Serial.println("Failed to open file in writing mode");
           } 
           else {
           file.write(fb->buf, fb->len); // payload (image), payload length 
           Serial.println(fb->len);
           Serial.print("抓拍成功并保存\n");
           Serial.printf("保存路径: %s\n\n", path.c_str());
           EEPROM.write(0, pictureNumber);
           EEPROM.commit();
           }          
          //上报属性Topic数据
          //char jsonBuf[]="{\"id\":\"1189401707\",\"version\":\"1.0.0\",\"method\":\"%s\",\"params\":{\"Data\":\"12\"}}";
          String a1="{\"id\":\"1189401707\",\"version\":\"1.0.0\",\"method\":\"%s\",\"params\":{\"Data\":\"";
          String a2;
          String a3 ="\"}}";
          char data[4104];
          for(int i=0;i<fb->len;i++)
          {
              sprintf(data, "%02X", *(fb->buf + i));
              a2+=data;
              if(a2.length() == 800)  
              {                                            
                  String a4 = a1+a2;
                  String a = a4+a3;
                  char jsonBuf[a.length()+1];
                  for(int i=0;i<a.length();i++)
                      jsonBuf[i] = a[i];
                  jsonBuf[a.length()]='\0';
                  Serial.println(jsonBuf);
                  mqttClient.publish(ALINK_TOPIC_PROP_POST, jsonBuf); 
                  a2="",a="",a4="";
              }
          }
          if(a2.length() > 0)
          {
              String a4=a1+a2;
              String a=a4+a3;
              char jsonBuf[a.length()+1];
              for(int i=0;i<a.length();i++)
                   jsonBuf[i] = a[i];
              jsonBuf[a.length()]='\0';
              Serial.println(jsonBuf);
              mqttClient.publish(ALINK_TOPIC_PROP_POST, jsonBuf);
              a2="",a="",a4=""; 
          }
          file.close(); 
          esp_camera_fb_return(fb);              
          }     
    } 
    if(buttonState ==HIGH)
       btnHold=0;                         
}
发布了19 篇原创文章 · 获赞 18 · 访问量 3597

猜你喜欢

转载自blog.csdn.net/haote216/article/details/105762808