Arduino和esp32的SPI通信:温湿度数据的发送与接收

一、项目描述

Arduino Uno R3没有联网的功能,借助esp32,可以将Arduino获取的信息传输到网络上。

Arduino和esp32能够通过RX/TX、I2C和SPI进行通信。其中,RX/TX用于连接计算机以烧录程序,I2C通常作为传感器接口,SPI很少被使用,因此,本项目使用的是SPI。

SPI(Serial Peripheral Interface,串行外设接口)是一种同步外设接口,可以使单片机以串行方式实现双工通信。SPI的特点如下。

(1)主从架构:SPI通信基于主从架构。在这个架构中,有一个主设备(如Arduino)和一个或多个从设备。主设备控制通信流程,包括时钟信号的生成。

(2)四线连接:SPI通常使用四条线进行通信:MISO(主设备输入,从设备输出)、MOSI(主设备输出,从设备输入)、SCK(时钟线)、SS(从设备选择)。SS线用于选择通信的从设备,因为一个主设备可以连接多个从设备。

(3)全双工通信:SPI支持全双工通信,这意味着数据可以同时双向传输(发送和接收)。

(4)高速:SPI是一种高速通信协议,适用于需要快速数据传输的应用。

(5)灵活:SPI协议的实现在不同的设备间可能有所不同,包括数据位宽、时钟极性和相位配置的不同。

(6)简单:与其他通信协议(如I2C或UART)相比,SPI结构相对简单,易于实现和调试。

本项目旨在使用SPI,将Arduino获取的温度值和湿度值(温湿度传感器DHT11)传输给esp32,作为“数据上网”的前提。

二、硬件连接

如下表所示,esp32和Arduino均具有SPI,只是引脚序号不同。按照下表将相同功能的引脚连接起来,即可完成SPI通信的硬件连接。例如,esp32的MISO在GPIO19引脚,Arduino的MISO在D12引脚,只需要将这两个引脚连接起来即可,其它引脚类推。

Arduinoesp32
SSD10GPIO5
MOSID11GPIO23
MISOD12GPIO19
SCKD13GPIO18

三、软件编程

Arduino和esp32基于两种不同的芯片,但都支持由Arduino IDE上传程序。因此,本项目使用Arduino IDE作为编程软件。

为了平衡Arduino和esp32的工作量,使两个硬件的程序长度不要相差太远,本项目将arduino作为SPI的从设备,将esp32作为SPI的主设备。

首先,新建一个arduino_slave.ino,负责读取温湿度传感器(DHT11)获取的温度值和湿度值,并且以字符的格式发送出去。DHT11库在通过Arduino IDE中的“库管理”进行安装。

#include <DHT11.h>
#include <SPI.h>

DHT11 dht11(2);
String dataToSend;
volatile int index = 0;

void setup() {
  // 设置串口波特率
  Serial.begin(9600);
  // 启动SPI,设置为SPI从设备
  pinMode(MISO, OUTPUT);
  // 启动SPI的中断例程ISR
  SPCR |= _BV(SPE);
  SPI.attachInterrupt();
}

ISR(SPI_STC_vect) {
  if (index < dataToSend.length()) {
    // 发送当前字符,具体的数据处理由主设备实现
    SPDR = dataToSend[index++];
  } else {
    // 发送结束字符
    SPDR = 0;
    // 重置索引
    index = 0;
  }
}

void loop() {
  // 从DHT11读取温度和湿度
  int temperature = dht11.readTemperature();
  int humidity = dht11.readHumidity();

  if (temperature != DHT11::ERROR_CHECKSUM && temperature != DHT11::ERROR_TIMEOUT && humidity != DHT11::ERROR_CHECKSUM && humidity != DHT11::ERROR_TIMEOUT) {
    // 创建带有标志位的字符串
    dataToSend = "<Temperature:" + String(temperature) + ",Humidity:" + String(humidity) + ">";
    Serial.println(dataToSend);
  } else {
    // 打印错误信息
    dataToSend = "<Error: Sensor Read Failed>";
    Serial.println(dataToSend);
  }
  // 重置索引,准备下一次发送
  index = 0;
  // 延时
  delay(1000);
}

然后,新建一个esp32_master.ino,接收来自Arduino发送过来的字符。

#include <SPI.h>

const int ssPin = 5;
String receivedData;

void setup() {
  // 设置串口波特率
  Serial.begin(9600);
  // 启动SPI,设置为SPI主设备
  SPI.begin();
  pinMode(ssPin, OUTPUT);
}

void loop() {
  // 开始通信
  digitalWrite(ssPin, LOW);
  // 准备接收数据
  receivedData = "";
  bool isMessageStarted = false;
  char receivedChar = 0;
  //
  while (true) {
    // 接收字符
    receivedChar = (char)SPI.transfer(0x00);
    // 整合数据,不包括标志位<>
    if (receivedChar == '<') {
      isMessageStarted = true;
    } else if (receivedChar == '>' && isMessageStarted) {
      break;
    } else if (isMessageStarted) {
      receivedData += receivedChar;
    }
  }
  // 结束通信
  digitalWrite(ssPin, HIGH);
  // 打印接收到的数据
  Serial.println(receivedData);
  // 延时
  delay(1000);
}

在上述两个程序中,发送的数据内容和接收的数据内容一致,“<”是开始标志,“>”是结束标志。之所以采用开始标志和结束标志,是为了保障收发数据的完整性和统一性。

发送的数据内容是:<Temperature:temperature,Humidity:humidity>

接收的数据内容是:<Temperature:temperature,Humidity:humidity>

当运行程序时,可以观察到esp32的串口监视器打印出如下信息。这是因为esp32接收到数据后,丢弃开始标志“<”和结束标志“>”,只保留真正需要的信息。

Temperature:temperature,Humidity:humidity

由此,Arduino通过DHT11获取了当前环境的温度值和湿度值,并通过SPI传送给esp32,使Arduino获取的数据可以借助esp32上传到网络。

  • 26
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
好的,这是一个关于Arduino Uno和ESP-01S模块的项目,主要用于接收DHT11温湿度传感器的数据并将其通过ESP-01S模块发送到远程服务器上。以下是具体的步骤: 1. 将DHT11温湿度传感器连接到Arduino Uno上,可以参考以下连接方式: DHT11 VCC - Arduino 5V DHT11 GND - Arduino GND DHT11 DATA - Arduino Digital Pin 2 2. 下载并安装ESP8266库,这里我们使用的是ESP8266WiFi库和ESP8266HTTPClient库。打开Arduino IDE,选择菜单栏:Sketch -> Include Library -> Manage Libraries,搜索并安装这两个库。 3. 连接ESP-01S模块到Arduino Uno上,可以参考以下连接方式: ESP-01S VCC - Arduino 3.3V ESP-01S GND - Arduino GND ESP-01S RX - Arduino Digital Pin 3 ESP-01S TX - Arduino Digital Pin 4 4. 编写Arduino代码,实现从DHT11传感器读取数据并将其发送到远程服务器上,可以参考以下代码: ``` #include <DHT.h> #include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h> #define DHTPIN 2 #define DHTTYPE DHT11 const char* ssid = "your_SSID"; const char* password = "your_PASSWORD"; const char* serverName = "your_SERVER_NAME"; DHT dht(DHTPIN, DHTTYPE); void setup() { Serial.begin(9600); dht.begin(); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi..."); } Serial.println("Connected to WiFi"); } void loop() { float temp = dht.readTemperature(); float humidity = dht.readHumidity(); if (isnan(temp) || isnan(humidity)) { Serial.println("Failed to read from DHT sensor!"); return; } Serial.print("Temperature: "); Serial.print(temp); Serial.print("C, Humidity: "); Serial.print(humidity); Serial.println("%"); if (WiFi.status() == WL_CONNECTED) { HTTPClient http; String serverPath = serverName + "/temperature=" + String(temp) + "&humidity=" + String(humidity); http.begin(serverPath.c_str()); int httpCode = http.GET(); if (httpCode > 0) { String payload = http.getString(); Serial.println(payload); } else { Serial.println("Error on HTTP request"); } http.end(); } delay(5000); } ``` 5. 将代码上传到Arduino Uno板子上。 到这里,你已经完成了将温湿度传感器数据发送到远程服务器的过程。如果你有一个Web服务器,你可以将其部署到服务器上并收集数据

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值