macpherson 发表于 2024-11-17 21:33

求ESP32通过mqtt和android进行图片传输代码

求ESP32通过mqtt和android进行图片传输代码提供apk的编译文件。代码运行成功截图。
提供运行机制说明,自己修改的说明。

3472076282 发表于 2024-11-26 09:32

求ESP32通过mqtt和android进行图片传输代码

本帖最后由 3472076282 于 2024-11-26 09:42 编辑

ESP32 端代码首先,确保你已经安装了所需的库,例如 PubSubClient 和 WiFi。#include <WiFi.h>#include <PubSubClient.h> // WiFi credentialsconst char* ssid = "your_SSID";const char* password = "your_PASSWORD"; // MQTT Brokerconst char* mqtt_server = "broker.hivemq.com"; WiFiClient espClient;PubSubClient client(espClient); void setup() {Serial.begin(115200);setup_wifi();client.setServer(mqtt_server, 1883);} void setup_wifi() {delay(10);Serial.println();Serial.print("Connecting to ");Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) {    delay(500);    Serial.print(".");} Serial.println("");Serial.println("WiFi connected");Serial.println("IP address: ");Serial.println(WiFi.localIP());} void reconnect() {while (!client.connected()) {    Serial.print("Attempting MQTT connection...");    if (client.connect("ESP32Client")) {      Serial.println("connected");    } else {      Serial.print("failed, rc=");      Serial.print(client.state());      Serial.println(" try again in 5 seconds");      delay(5000);    }}} void loop() {if (!client.connected()) {    reconnect();}client.loop();}           Android 端代码在Android端,你可以使用Paho MQTT库来连接到MQTT Broker并发送/接收消息。以下是一个基本的示例:1. 添加依赖项到你的 build.gradle 文件:      dependencies {    implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5'    implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'}    2. 创建一个服务来处理MQTT连接:      import android.app.Service;import android.content.Intent;import android.os.IBinder;import org.eclipse.paho.android.service.MqttAndroidClient;import org.eclipse.paho.client.mqttv3.IMqttActionListener;import org.eclipse.paho.client.mqttv3.IMqttToken;import org.eclipse.paho.client.mqttv3.MqttCallback;import org.eclipse.paho.client.mqttv3.MqttMessage; public class MqttService extends Service {    private static final String MQTT_BROKER_URL = "tcp://broker.hivemq.com:1883";    private static final String CLIENT_ID = "AndroidClient";    private MqttAndroidClient mqttAndroidClient;     @Override    public void onCreate() {      super.onCreate();      mqttAndroidClient = new MqttAndroidClient(this, MQTT_BROKER_URL, CLIENT_ID);      mqttAndroidClient.setCallback(new MqttCallback() {            @Override            public void connectionLost(Throwable cause) {                // handle connection loss            }             @Override            public void messageArrived(String topic, MqttMessage message) throws Exception {                // handle incoming message            }             @Override            public void deliveryComplete(IMqttDeliveryToken token) {                // handle message delivery complete            }      });    }     @Override    public int onStartCommand(Intent intent, int flags, int startId) {      connectToMqttBroker();      return START_STICKY;    }     private void connectToMqttBroker() {      try {            mqttAndroidClient.connect(null, new IMqttActionListener() {                @Override                public void onSuccess(IMqttToken asyncActionToken) {                  // subscribe to a topic or publish a message                }                 @Override                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {                  // handle failure to connect                }            });      } catch (Exception e) {            e.printStackTrace();      }    }     @Override    public IBinder onBind(Intent intent) {      return null;    }}     3. 启动服务:      Intent serviceIntent = new Intent(this, MqttService.class);startService(serviceIntent);     4. 发布或订阅消息:           // To publish a messageString topic = "test/topic";String message = "Hello from Android";try {    mqttAndroidClient.publish(topic, message.getBytes(), 0, false);} catch (Exception e) {    e.printStackTrace();} // To subscribe to a topicString topic = "test/topic";try {    mqttAndroidClient.subscribe(topic, 0);} catch (Exception e) {    e.printStackTrace();}       图片传输示例假设你要传输一张图片,可以将图片转换为字节数组并通过MQTT发送。以下是一个简单的例子:ESP32 端接收图片数据:void callback(char* topic, byte* payload, unsigned int length) {// Assuming the payload is the image data in bytesfor (int i = 0; i < length; i++) {    Serial.print((char)payload);}Serial.println();}     Android 端发送图片数据:Bitmap bitmap = ... // your bitmap imageByteArrayOutputStream baos = new ByteArrayOutputStream();bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos); // bmp is your Bitmap instancebyte[] bytes = baos.toByteArray();String base64Image = Base64.encodeToString(bytes, Base64.DEFAULT);try {    mqttAndroidClient.publish("image/topic", base64Image.getBytes(), 0, false);} catch (Exception e) {    e.printStackTrace();}    以上代码展示了如何在ESP32和Android之间通过MQTT进行图片传输的基本方法。根据你的具体需求,你可能需要进一步优化和调整代码。

gaochy1126 发表于 2024-11-30 21:23

求ESP32通过mqtt和android进行图片传输代码

// send_img_aliyun.ino

#include <WiFi.h>
#include <Wire.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>

// #include "aliyun_mqtt.h"
#include "aliyunmqtt.h"

#include "esp_camera.h"

#include <SPIFFS.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>

// 内存存储相关配置
#define EEPROM_SIZE 1
int pictureNumber = 0;
String msg;
int buttonState = 0;
int btnHold = 0;


// #define SENSOR_PIN 10
//以下信息需要自己修改
#define WIFI_SSID "TP-LINK_1760"//替换自己的WIFI
#define WIFI_PASSWD "987654321"   //替换自己的WIFI密码

// 阿里云物联网 三元组
#define PRODUCT_KEY "k0xxxxxIM"                         //替换自己的PRODUCT_KEY
#define DEVICE_NAME "esp001_001"                     //替换自己的DEVICE_NAME
#define DEVICE_SECRET "589xxxxxxxxxxxxxxxxxxxe0f"//替换自己的DEVICE_SECRET \


//以下不需修改
#define ALINK_BODY_FORMAT "{\"id\":\"123\",\"version\":\"1.0\",\"method\":\"%s\",\"params\":%s}"
#define ALINK_TOPIC_PROP_POST "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/event/property/post"
#define ALINK_TOPIC_PROP_POSTRSP "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/event/property/post_reply"
#define ALINK_TOPIC_PROP_SET "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/service/property/set"
#define ALINK_METHOD_PROP_POST "thing.event.property.post"
#define ALINK_TOPIC_DEV_INFO "/ota/device/inform/" PRODUCT_KEY "/" DEVICE_NAME ""
#define ALINK_VERSION_FROMA "{\"id\": 123,\"params\": {\"version\": \"%s\"}}"
unsigned long lastMs = 0;
// 测试 初始温度
int i = 15;

WiFiClient espClient;
PubSubClient mqttClient(espClient);

//CAMERA_MODEL_AI_THINKER类型摄像头的引脚定义
#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 0
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27

#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 21
#define Y4_GPIO_NUM 19
#define Y3_GPIO_NUM 18
#define Y2_GPIO_NUM 5
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22

static camera_config_t camera_config = {
.pin_pwdn = PWDN_GPIO_NUM,
.pin_reset = RESET_GPIO_NUM,
.pin_xclk = XCLK_GPIO_NUM,
.pin_sscb_sda = SIOD_GPIO_NUM,
.pin_sscb_scl = SIOC_GPIO_NUM,

.pin_d7 = Y9_GPIO_NUM,
.pin_d6 = Y8_GPIO_NUM,
.pin_d5 = Y7_GPIO_NUM,
.pin_d4 = Y6_GPIO_NUM,
.pin_d3 = Y5_GPIO_NUM,
.pin_d2 = Y4_GPIO_NUM,
.pin_d1 = Y3_GPIO_NUM,
.pin_d0 = Y2_GPIO_NUM,
.pin_vsync = VSYNC_GPIO_NUM,
.pin_href = HREF_GPIO_NUM,
.pin_pclk = PCLK_GPIO_NUM,

.xclk_freq_hz = 20000000,
.ledc_timer = LEDC_TIMER_0,
.ledc_channel = LEDC_CHANNEL_0,

.pixel_format = PIXFORMAT_JPEG,
// .frame_size = FRAMESIZE_VGA,
// FRAMESIZE_UXGA (1600 x 1200)
// FRAMESIZE_QVGA (320 x 240)
// FRAMESIZE_CIF (352 x 288)
// FRAMESIZE_VGA (640 x 480)
// FRAMESIZE_SVGA (800 x 600)
// FRAMESIZE_XGA (1024 x 768)
// FRAMESIZE_SXGA (1280 x 1024)
.frame_size = FRAMESIZE_QVGA,
.jpeg_quality = 10,
// 图像质量(jpeg_quality) 可以是 0 到 63 之间的数字。数字越小意味着质量越高
.fb_count = 1,
};

void init_wifi(const char *ssid, const char *password) {
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
    Serial.println("WiFi does not connect, try again ...");
    delay(500);
}

Serial.println("Wifi is connected.");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}

void mqtt_callback(char *topic, byte *payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
payload = '\0';
Serial.println((char *)payload);

if (strstr(topic, ALINK_TOPIC_PROP_SET)) {
    StaticJsonBuffer<100> jsonBuffer;
    JsonObject &root = jsonBuffer.parseObject(payload);
    if (!root.success()) {
      Serial.println("parseObject() failed");
      return;
    }
}
}

void mqtt_check_connect() {
while (!mqttClient.connected())//
{
    while (connect_aliyun_mqtt(mqttClient, PRODUCT_KEY, DEVICE_NAME, DEVICE_SECRET)) {
      Serial.println("MQTT connect succeed!");
      //client.subscribe(ALINK_TOPIC_PROP_POSTRSP);
      mqttClient.subscribe(ALINK_TOPIC_PROP_SET);

      Serial.println("subscribe done");
    }
}
}

void mqtt_interval_post() {
//static int i=0;
char param;
char jsonBuf;
sprintf(jsonBuf, "{\"id\":\"1189401707\",\"version\":\"1.0.0\",\"method\":\"%s\",\"params\":{\"img\":\"END\"}}");
Serial.println(jsonBuf);
mqttClient.publish(ALINK_TOPIC_PROP_POST, jsonBuf);
Serial.println("发送结束符");
delay(1000);
}



// 摄像头、SD卡与 SPIFFS 初始化
esp_err_t camera_init() {
//initialize the camera
esp_err_t err = esp_camera_init(&camera_config);
if (err != ESP_OK) {
    Serial.println("Camera Init Failed");
    return err;
}
sensor_t *s = esp_camera_sensor_get();
//initial sensors are flipped vertically and colors are a bit saturated
if (s->id.PID == OV2640_PID) {
    //      s->set_vflip(s, 1);//flip it back
    //      s->set_brightness(s, 1);//up the blightness just a bit
    //      s->set_contrast(s, 1);
}
Serial.println("Camera Init OK!");
return ESP_OK;
}


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);
}
// 摄像头、SD卡与 SPIFFS 初始化 end



void setup() {
Serial.begin(115200);
Serial.println("程序 Start");
init_wifi(WIFI_SSID, WIFI_PASSWD);

camera_init();
sd_init();
SPIFFS_init();

mqttClient.setCallback(mqtt_callback);
}

// the loop function runs over and over again forever
void loop() {

// 程序开始拍照并保存
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();
    }


    String a1 = "{\"id\":\"1189401707\",\"version\":\"1.0.0\",\"method\":\"123\",\"params\":{\"img\":\"";
    String a2;
    String a3 = "\"}}";
    char data;
    // 将图片分为不超过 800 通过 MQTT 发送出去
    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;
      for (int i = 0; i < a.length(); i++)
          jsonBuf = a;
      jsonBuf = '\0';
      Serial.println(jsonBuf);
      mqttClient.publish(ALINK_TOPIC_PROP_POST, jsonBuf);
      a2 = "", a = "", a4 = "";
      // ms
      delay(200);
      }
    }
    if (a2.length() > 0) {
      String a4 = a1 + a2;
      String a = a4 + a3;
      char jsonBuf;
      for (int i = 0; i < a.length(); i++)
      jsonBuf = a;
      jsonBuf = '\0';
      Serial.println(jsonBuf);
      mqttClient.publish(ALINK_TOPIC_PROP_POST, jsonBuf);
      a2 = "", a = "", a4 = "";
    }
   // 将图片分为不超过 800 通过 MQTT 发送出去end
    //
    char endBuf;
    sprintf(endBuf, "{\"id\":\"1189401707\",\"version\":\"1.0.0\",\"method\":\"123\",\"params\":{\"img\":\"END\"}}");
    Serial.println(endBuf);
    mqttClient.publish(ALINK_TOPIC_PROP_POST, endBuf);
    Serial.println("发送结束符");

}
Serial.println("图片发送完成了......");
delay(1000);
// 图片发送结束后发送 END


if (millis() - lastMs >= 10000) {
    lastMs = millis();
    mqtt_check_connect();
    // Postinterval 间隔
    // mqtt_interval_post();
}

mqttClient.loop();

unsigned int WAIT_MS = 2000;
delay(WAIT_MS);// ms
Serial.println(millis() / WAIT_MS);
}

gaochy1126 发表于 2024-11-30 21:24

求ESP32通过mqtt和android进行图片传输代码

const container = require('rhea');
const crypto = require('crypto');
const fs = require("fs");

// 请根据实际情况修改下面的参数
// host,在物联网平台首页,查看开发配置中查看
var YourHost="iot-06z00xxxxt6xc.amqp.iothub.aliyuncs.com"
// 客户端ID,可自定义,长度不可超过64个字符
var YourClientId="esp32_001"
// 账号的 AccessKey。将鼠标移至账号头像上,然后单击AccessKey管理,获取AccessKey ID和AccessKey Secret。
var YourAccessKeyId="LTAI5tXXXXXXXXXXxLEMGYL2"
var YourAccessKeySecret="6vi2Txxxw9xxxrwig"
// 在对应实例的消息转发 > 服务端订阅 > 消费组列表查看您的消费组ID。
var YourConsumerGroupId="DEFAULT_GROUP"
// 物联网平台首页实例 ID
var YourIotInstanceId="iot-0600uxtxxsx"

// 存放完整的图片字符串
var imgStr = ""

// 16进制图片转base64
function to_base64(str) {
    var digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    var base64_rep = "";
    var cnt = 0;
    var bit_arr = 0;
    var bit_num = 0;

    for (var n = 0; n < str.length; ++n) {
      if (str >= 'A' && str <= 'Z') {
            ascv = str.charCodeAt(n) - 55;
      }
      else if (str >= 'a' && str <= 'z') {
            ascv = str.charCodeAt(n) - 87;
      }
      else {
            ascv = str.charCodeAt(n) - 48;
      }
      bit_arr = (bit_arr << 4) | ascv;
      bit_num += 4;
      if (bit_num >= 6) {
            bit_num -= 6;
            base64_rep += digits;
            bit_arr &= ~(-1 << bit_num);
      }
    }
    if (bit_num > 0) {
      bit_arr <<= 6 - bit_num;
      base64_rep += digits;
    }
    var padding = base64_rep.length % 4;
    if (padding > 0) {
      for (var n = 0; n < 4 - padding; ++n) {
            base64_rep += "=";
      }
    }
    return base64_rep;
}

//创建Connection。
var connection = container.connect({
    //接入域名,请参见AMQP客户端接入说明文档。
    'host': YourHost,
    'port': 5671,
    'transport':'tls',
    'reconnect':true,
    'idle_time_out':60000,
    //userName组装方法,请参见AMQP客户端接入说明文档。
    'username':YourClientId+'|authMode=aksign,signMethod=hmacsha1,timestamp=1573489088171,authId='+YourAccessKeyId+',iotInstanceId='+YourIotInstanceId+',consumerGroupId='+YourConsumerGroupId+'|',
    //计算签名,password组装方法,请参见AMQP客户端接入说明文档。
    'password': hmacSha1(YourAccessKeySecret, 'authId='+YourAccessKeyId+'&timestamp=1573489088171'),
});

//创建Receiver Link
var receiver = connection.open_receiver();

//接收云端推送消息的回调函数。
container.on('message', function (context) {
    var msg = context.message;
    var messageId = msg.message_id;
    var topic = msg.application_properties.topic;
    var content = Buffer.from(msg.body.content).toString();

    // 输出内容。
    console.log(content);

    // 将接收到的mqtt消息中内容转为json
    var imgBody = JSON.parse(content).items.img.value
    console.log('-------')
    // 如果图片没有传输完毕,则拼接图片
    if (imgBody != 'END') {
      imgStr += imgBody
    } else {
      // 如果图片传输完毕,则将图片转为base64
      console.log('imgStr:')
      console.log(to_base64(imgStr))
      // 配置图片保存路径
      var path = './img/' + new Date().getTime() + '.jpg';
      var dataBuffer = new Buffer(to_base64(imgStr), 'base64'); //把base64码转成buffer对象,
      //用fs将图片写入本地文件
      fs.writeFile(path, dataBuffer, function (err) {
            if (err) {
                console.log(err);
            } else {
                console.log('写入成功!');
            }
      });
      // 图片转换完毕后,清空imgStr,准备接受下一张图片
      imgStr = ""

    }
    //发送ACK,注意不要在回调函数有耗时逻辑。
    context.delivery.accept();
});


//计算password签名。
function hmacSha1(key, context) {
    return Buffer.from(crypto.createHmac('sha1', key).update(context).digest())
      .toString('base64');
}

gaochy1126 发表于 2024-11-30 21:29

求ESP32通过mqtt和android进行图片传输代码

https://github.com/xianjimli/esp32cam_mqtt_aliyun_iot.git

钓鱼大师 发表于 2025-3-9 16:18

ESP32和海思芯片比起来,哪个性能或者功能更全面?哪个成本低?
页: [1]
查看完整版本: 求ESP32通过mqtt和android进行图片传输代码