[经验分享] 【Follow me第二季第2期】+ 作品提交整合贴

LTLyaoni   2024-10-23 00:01 楼主

大家好,我是LTLyaoni非常荣幸能参与到电子工程世界和得捷电子联合举办的“Follow me”第二期活动中来。今天,我将和大家分享我的项目进展和心得体会。

物料展示

这次我拿到的开发板是Arduino Uno R4 WiFi,还有LTR-329光照传感器、SHT40温湿度传感器。

cecdb94bfd927df93b149d1b6d52cc9.jpg  

视频如下


 

设计思路

入门任务(任务1)

  • 目标:在原理图中确认IO端口,使用GPIO控制LED闪烁。

基础任务(任务2)

  • 目标:读懂Arduino官方文档,掌握LED矩阵、ADC和运算放大器的使用。

进阶任务(任务3)

  • 目标:掌握ESP32S3 WiFi库和MQTT库的使用,配置HA实体。

 

任务实现详情

入门任务一:搭建环境并开启第一步Blink / 串口打印Hello EEWorld!

物料:

Arduino Uno R4 WiFi。后面的所有的任务都用到Arduino Uno R4 WiFi,实物上图有

流程图

image.png  

image.png  

代码如下

// 定义LED连接的引脚
int ledPin = 13;
void setup() {
  Serial.begin(9600);          // 初始化串口通信
  pinMode(ledPin, OUTPUT);
}

void loop() {
  Serial.println("LED状态: ON");
  digitalWrite(ledPin, HIGH);
  Serial.println("Hello World!");
  Serial.println("Hello DigiKey and EEWorld!");
  delay(500);
  Serial.println("LED状态: OFF");
  digitalWrite(ledPin, LOW);
  Serial.println("Hello World!");
  Serial.println("Hello DigiKey and EEWorld!");
  delay(500);
}

串口打印HelloWorld

上述代码同时做了串口打印功能,以便我们可以看到LED灯的状态和Hello world的输出:

代码编译烧录后,打开IDE自带的串口监视器,设置和代码相同的波特率,即可看到相应的串口输出

基础任务:

驱动12x8点阵LED;用DAC生成正弦波;用OPAMP放大DAC信号;用ADC采集并且打印数据到串口等其他接口可上传到上位机显示曲线

帖子地址:【Follow me第二季第2期】+ 基础任务【点亮LED矩阵, 使用运算放大器放大DAC信号】

流程图:

image.png  

Task 1 : 点亮板载Led matrix

    Step 1 :  打开Arduino 的 demo, 选择LED matrix.

第一个代码是使用LED的frame的方式进行点亮的, 即在数组中定义每一个LED灯的状态, 通过加载帧的方式实现的. 相关的数组在frames.h 

const uint32_t chip[] = {
	0x1503f811,
	0x3181103,
	0xf8150000
};

const uint32_t danger[] = {
	0x400a015,
	0x1502082,
	0x484047fc
};

const uint32_t happy[] = {
	0x19819,
	0x80000001,
	0x81f8000
};

const uint32_t heart[] = {
	0x3184a444,
	0x44042081,
	0x100a0040
};

Task 2: 使用 DAC 输出正弦波

    Step 1 : 在Arduino IDE中并没有发现,关于DAC输出的Demo程序, 因此我们需要查询一下官方文档看下如何使用Arduino 的DAC功能, 根据官方文档提供的代码,我们可以很快的实现DAC输出的功能

流程图:

image.png  

/*
  SineWave

  Generates a pre-generated sawtooth-waveform.

  See the full documentation here:
  https://docs.arduino.cc/tutorials/uno-r4-wifi/dac
*/

#include "analogWave.h" // Include the library for analog waveform generation

analogWave wave(DAC);   // Create an instance of the analogWave class, using the DAC pin

int freq = 10;  // in hertz, change accordingly

void setup() {
  Serial.begin(115200);  // Initialize serial communication at a baud rate of 115200
  wave.sine(freq);       // Generate a sine wave with the initial frequency
}

void loop() {
  // Read an analog value from pin A5 and map it to a frequency range
  freq = map(analogRead(A5), 0, 1024, 0, 10000);

  // Print the updated frequency to the serial monitor
  Serial.println("Frequency is now " + String(freq) + " hz");

  wave.freq(freq);  // Set the frequency of the waveform generator to the updated value
  delay(1000);      // Delay for one second before repeating
}

由于DAC的输出是A0 端口, 我们可以手动调整A5的ADC电压来动态调整A0的DAC输出频率. 如果使用示波器连接A0的话, 那么A0的输出将会是如下图所示

Task 3 : 对DAC信号使用运算放大器进行放大, 然后使用ADC进行采集并且展示.

    Arduino uno 4的官方文档写的比较详细, 如果想使用运算放大器对信号进行放大的话只需要构建好以下的电路.

我们在官方的代码上稍微做一点修改(仅仅是在代码的第八行开启了运算放大器)

#include "analogWave.h" // Include the library for analog waveform generation
#include <OPAMP.h>
analogWave wave(DAC);   // Create an instance of the analogWave class, using the DAC pin

int freq = 10;  // in hertz, change accordingly

void setup() {
  OPAMP.begin(OPAMP_SPEED_HIGHSPEED);
  Serial.begin(115200);  // Initialize serial communication at a baud rate of 115200
  wave.sine(freq);       // Generate a sine wave with the initial frequency
}

void loop() {
  // Read an analog value from pin A5 and map it to a frequency range
  freq = map(analogRead(A5), 0, 1024, 0, 10000);

  // Print the updated frequency to the serial monitor
  Serial.println("Frequency is now " + String(freq) + " hz");

  wave.freq(freq);  // Set the frequency of the waveform generator to the updated value
  delay(50);      // Delay for one second before repeating
}

之后我们讲代码烧录到系统中之后再使用示波器进行电压的采集的时候发现现在的平均电压已经被运算放大器放大到了之前的两倍左右

Task 3 : 使用ADC 采集DAC输出,并且显示.

        我们可以在上述代码上做一点简单的修改使其DAC的输出作为ADC的输入(电路), 这样的话,当我们打印出数据的时候, 串口绘图功能则会自动绘制ADC的采集曲线,代码如下所示

#include "analogWave.h" // Include the library for analog waveform generation
#include <OPAMP.h>
analogWave wave(DAC);   // Create an instance of the analogWave class, using the DAC pin

int freq = 10;  // in hertz, change accordingly
int reading = 0;
void setup() {
  OPAMP.begin(OPAMP_SPEED_HIGHSPEED);
  Serial.begin(115200);  // Initialize serial communication at a baud rate of 115200
  analogWriteResolution(14); 
  wave.sine(freq);       // Generate a sine wave with the initial frequency
}

void loop() {
  // Read an analog value from pin A5 and map it to a frequency range
  freq = map(analogRead(A5), 0, 1024, 0, 10000);

  // Print the updated frequency to the serial monitor
  Serial.println("Frequency is now " + String(freq) + " hz");
  reading = analogRead(A4);
  Serial.print(reading);
  wave.freq(freq);  // Set the frequency of the waveform generator to the updated value
  delay(50);      // Delay for one second before repeating
}

进阶任务:通过Wi-Fi,利用MQTT协议接入到开源的智能家居平台HA(HomeAssistant)

帖子地址:【Follow me第二季第2期】+ 进阶任务 :使用Arduino uno r4 接入Home assistant

Task 1 : 使用Uno r4 连接Wifi

        Arduino IDE 提供了Arduino uno r4 的wifi连接的example, 我们可以根据下面的截图进行查找

在上述的提供的代码中我们只需要修改wifi的 ssid 和 pass 即可连接到WIFI上, 我这里连接的是2.4G的wifi

当我们把代码烧录到开发版中之后,我们会发现串口控制台已经可以正确的获取到IP地址.

当你控制台出现IP地址的时候即为连接WIFI成功.

Task 2 : 使用MQTT连接到HA

        由于MQTT的便携性和容易集成等优点,因为我们可以在HA中集成MQTT服务,使其监视某一个主题从而实现消息的上报和下发. 因为我们本章节的任务非常简单, 即使用UNO r4 连接到MQTT的某个Topic 然后在HA中监视这个主题就算成功.

我们只需要在配置集成中, 监视这个test的主题,然后使用Uno r4 向这个主题发送消息即可.

Task 3 : 使用UNO R4 ,连接MQTT发送消息. 

        但是很不巧Arduino uno r4 并没有提供MQTT的Demo, 所以我们需要看看官方有没有什么推荐的. 好巧不巧, 我在https://docs.arduino.cc/tutorials/uno-wifi-rev2/uno-wifi-r2-mqtt-device-to-device/上找到了如何使用MQTT的方式, 即使用Mqtt Client.  

虽然它代码写的比较长,但是其核心的逻辑还是使用ArduinoMqttClientt对象使用WIFI client 对象来连接MQTT. 那么我们便可以在上述的代码中做出以下的修改

#include <ArduinoMqttClient.h>
#include <WiFiS3.h>
#include <WiFiClient.h>

char ssid[] = "你的Wi-Fi名称";        
char pass[] = "你的wifi密码";  
int status = WL_IDLE_STATUS;   

const char broker[] = "你的MQTT地址";
int        port     = 端口;
const char topic[]  = "主题";

WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);

void setup() {
  Serial.begin(115200);
  while (!Serial) {

  }

  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
    Serial.println("Please upgrade the firmware");
  }

  // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }

  Serial.print("You're connected to the network");
  printCurrentNet();
  printWifiData();
  if (!mqttClient.connect(broker, port)) {
    Serial.print("MQTT connection failed! Error code = ");
    Serial.println(mqttClient.connectError());
    while (1);
  }
  Serial.println("You are connected to MQTT");

}


void printCurrentNet() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print the MAC address of the router you're attached to:
  byte bssid[6];
  WiFi.BSSID(bssid);
  Serial.print("BSSID: ");
  printMacAddress(bssid);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.println(rssi);

  // print the encryption type:
  byte encryption = WiFi.encryptionType();
  Serial.print("Encryption Type:");
  Serial.println(encryption, HEX);
  Serial.println();
}

void printMacAddress(byte mac[]) {
  for (int i = 0; i < 6; i++) {
    if (i > 0) {
      Serial.print(":");
    }
    if (mac[i] < 16) {
      Serial.print("0");
    }
    Serial.print(mac[i], HEX);
  }
  Serial.println();
}

void printWifiData() {
  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  
  Serial.println(ip);
  // print your MAC address:
  byte mac[6];
  WiFi.macAddress(mac);
  Serial.print("MAC address: ");
  printMacAddress(mac);
}



void loop() {
    mqttClient.beginMessage(topic);
    mqttClient.print("Message from UNO R4");
    mqttClient.endMessage();
    delay(500);
}



注意上述的代码是在匿名的情况下连接到MQTT服务器的,如果你的MQTT服务器不支持匿名连接的话你需要自己调用mqttclinen的设置用户名和密码的function来认证你的连接. 此时我们打开HA的话我们开启监听即可收到来自Uno r4的消息 (注意HA中MQTT监视的topic是test主题,但是上述代码中我并没有写, 方便大家复用我的代码)

我们有一个智能灯,我们可以通过发送命令来控制它。如果我们想让灯关掉,我们就发送一个“OFF”的指令;如果我们想让灯打开,我们就发送一个“ON”的指令。

现在,虽然我们可以通过这些指令来控制灯的开关,但是家里的智能家居系统(我们称之为HA)并不知道灯的状态已经改变了。为了让HA知道灯的状态,我们还需要发送一个额外的指令,告诉它灯现在是关着的(“OFF”)。

为了解决这个问题,我们可以稍微调整一下代码,让它每隔一秒钟就自动切换灯的状态。这样,灯就会自动地一会儿开,一会儿关,同时HA也会实时更新灯的状态,知道灯现在是开着还是关着。这样,我们就可以确保灯的状态和HA中的显示是一致的。

#include <ArduinoMqttClient.h>
#include <WiFiS3.h>
#include <WiFiClient.h>

char ssid[] = "ssid";        
char pass[] = "pass";  
int status = WL_IDLE_STATUS;   

const char broker[] = "broker";
int        port     = 1883;
const char command_topic[]  = "home/bedroom/switch1/set";
const char state_topic[]  = "home/bedroom/switch1";

WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);

bool index = true;

void setup() {
  Serial.begin(9600);
  while (!Serial) {

  }

  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
    Serial.println("Please upgrade the firmware");
  }

  // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }

  Serial.print("You're connected to the network");
  printCurrentNet();
  printWifiData();
  mqttClient.setUsernamePassword("","");
  if (!mqttClient.connect(broker, port)) {
    Serial.print("MQTT connection failed! Error code = ");
    Serial.println(mqttClient.connectError());
    while (1);
  }
  Serial.println("You are connected to MQTT");

}


void printCurrentNet() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print the MAC address of the router you're attached to:
  byte bssid[6];
  WiFi.BSSID(bssid);
  Serial.print("BSSID: ");
  printMacAddress(bssid);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.println(rssi);

  // print the encryption type:
  byte encryption = WiFi.encryptionType();
  Serial.print("Encryption Type:");
  Serial.println(encryption, HEX);
  Serial.println();
}

void printMacAddress(byte mac[]) {
  for (int i = 0; i < 6; i++) {
    if (i > 0) {
      Serial.print(":");
    }
    if (mac[i] < 16) {
      Serial.print("0");
    }
    Serial.print(mac[i], HEX);
  }
  Serial.println();
}

void printWifiData() {
  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  
  Serial.println(ip);
  // print your MAC address:
  byte mac[6];
  WiFi.macAddress(mac);
  Serial.print("MAC address: ");
  printMacAddress(mac);
}



void loop() {
  if(index)
  {
    mqttClient.beginMessage(command_topic);
    mqttClient.print("ON");
    mqttClient.endMessage();
    mqttClient.beginMessage(state_topic);
    mqttClient.print("ON");
    mqttClient.endMessage();
    Serial.print("ON\n");
  }else {
    mqttClient.beginMessage(command_topic);
    mqttClient.print("OFF");
    mqttClient.endMessage();
    mqttClient.beginMessage(state_topic);
    mqttClient.print("OFF");
    mqttClient.endMessage();
    Serial.print("OFF\n");
  }
  index = !index;
  delay(1000);

}




拓展任务一:扩展任务一  使用LTR-329 环境光传感器,上传到HA并显示

3f55e2a0f276f0a9acaec7becda3842.jpg  

流程图如下:

image.png  

这个拓展任务听起来挺有意思的,我们可以一步步来搞定。这个任务主要就是三件事:

  1. 读取LTR-329传感器数据:首先,我们要用我们的Arduino R4来读取LTR-329光照传感器的数据。这个传感器能帮我们测量环境光和红外光,我们需要用到专门的库来和它通信,获取数据。

  2. 配置HA实体:然后,我们要在Home Assistant(HA)里设置实体。实体就是HA用来识别和控制设备的一种方式。我们需要告诉HA,我们有一个光照传感器,并且告诉它这个传感器的数据要怎么显示。

  3. 上传数据到HA:最后,我们要做的是把从LTR-329传感器读取到的数据上传到HA。这样,我们就可以在HA的界面上实时看到光照数据,还可以用这些数据来控制家里的其他智能设备。

既然我们已经在进阶任务里搞定了MQTT和WIFI,这次我们可以直接用那些代码,不用再从头开始。这样我们就可以更高效地完成任务了。

 

读取LTR-329传感器数据和上传数据到HA的代码如下

#include "Adafruit_LTR329_LTR303.h"
#include <ArduinoMqttClient.h>
#include <WiFiS3.h>
#include <WiFiClient.h>
#include <Arduino_JSON.h>
Adafruit_LTR329 ltr = Adafruit_LTR329();

char ssid[] = "ssid";        
char pass[] = "pass";  
int status = WL_IDLE_STATUS;   

const char broker[] = "broker";
int        port     = 1883;
const char command_topic[]  = "LTR303";

WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);

JSONVar dataObj;

void setup() {
  Serial.begin(115200);
  Serial.println("Adafruit LTR-329 advanced test");


  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
    Serial.println("Please upgrade the firmware");
  }

  // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }

  Serial.print("You're connected to the network");
  printCurrentNet();
  printWifiData();
  mqttClient.setUsernamePassword("","");
  if (!mqttClient.connect(broker, port)) {
    Serial.print("MQTT connection failed! Error code = ");
    Serial.println(mqttClient.connectError());
    while (1);
  }
  Serial.println("You are connected to MQTT");
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }

  if ( ! ltr.begin(&Wire1) ) {
    Serial.println("Couldn't find LTR sensor!");
    while (1) delay(10);
  }
  Serial.println("Found LTR sensor!");

  ltr.setGain(LTR3XX_GAIN_2);
  Serial.print("Gain : ");
  switch (ltr.getGain()) {
    case LTR3XX_GAIN_1: Serial.println(1); break;
    case LTR3XX_GAIN_2: Serial.println(2); break;
    case LTR3XX_GAIN_4: Serial.println(4); break;
    case LTR3XX_GAIN_8: Serial.println(8); break;
    case LTR3XX_GAIN_48: Serial.println(48); break;
    case LTR3XX_GAIN_96: Serial.println(96); break;
  }

  ltr.setIntegrationTime(LTR3XX_INTEGTIME_100);
  Serial.print("Integration Time (ms): ");
  switch (ltr.getIntegrationTime()) {
    case LTR3XX_INTEGTIME_50: Serial.println(50); break;
    case LTR3XX_INTEGTIME_100: Serial.println(100); break;
    case LTR3XX_INTEGTIME_150: Serial.println(150); break;
    case LTR3XX_INTEGTIME_200: Serial.println(200); break;
    case LTR3XX_INTEGTIME_250: Serial.println(250); break;
    case LTR3XX_INTEGTIME_300: Serial.println(300); break;
    case LTR3XX_INTEGTIME_350: Serial.println(350); break;
    case LTR3XX_INTEGTIME_400: Serial.println(400); break;
  }

  ltr.setMeasurementRate(LTR3XX_MEASRATE_200);
  Serial.print("Measurement Rate (ms): ");
  switch (ltr.getMeasurementRate()) {
    case LTR3XX_MEASRATE_50: Serial.println(50); break;
    case LTR3XX_MEASRATE_100: Serial.println(100); break;
    case LTR3XX_MEASRATE_200: Serial.println(200); break;
    case LTR3XX_MEASRATE_500: Serial.println(500); break;
    case LTR3XX_MEASRATE_1000: Serial.println(1000); break;
    case LTR3XX_MEASRATE_2000: Serial.println(2000); break;
  }
}


void printCurrentNet() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print the MAC address of the router you're attached to:
  byte bssid[6];
  WiFi.BSSID(bssid);
  Serial.print("BSSID: ");
  printMacAddress(bssid);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.println(rssi);

  // print the encryption type:
  byte encryption = WiFi.encryptionType();
  Serial.print("Encryption Type:");
  Serial.println(encryption, HEX);
  Serial.println();
}

void printMacAddress(byte mac[]) {
  for (int i = 0; i < 6; i++) {
    if (i > 0) {
      Serial.print(":");
    }
    if (mac[i] < 16) {
      Serial.print("0");
    }
    Serial.print(mac[i], HEX);
  }
  Serial.println();
}

void printWifiData() {
  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  
  Serial.println(ip);
  // print your MAC address:
  byte mac[6];
  WiFi.macAddress(mac);
  Serial.print("MAC address: ");
  printMacAddress(mac);
}


void loop() {
  bool valid;
  uint16_t visible_plus_ir, infrared;
  if (ltr.newDataAvailable()) {
    valid = ltr.readBothChannels(visible_plus_ir, infrared);
    if (valid) {
      dataObj["brightness"] = visible_plus_ir;
      dataObj["ir_data"] = infrared;
      Serial.print("brightness: ");
      Serial.print(infrared);
      Serial.print("\n");
      Serial.print("ir_data: ");
      Serial.print(visible_plus_ir);
      Serial.print("\n");


      String jsonString = JSON.stringify(dataObj);
      mqttClient.beginMessage(command_topic);
      mqttClient.print(jsonString);
      mqttClient.endMessage();
    }
  }

  delay(500);
}

而配置HA实体的,有些版本不一样,我是如下们可以作为参考

sensor:
  - platform: mqtt
    name: "光传感器IR"
    value_template: "{{ value_json.ir_data }}"
    state_topic: "LTR303"
    unit_of_measurement: "LTR303"
    unique_id: "LTR303_IR"
  - platform: mqtt
    name: "光传感器brightness"
    value_template: "{{ value_json.brightness }}"
    state_topic: "LTR303"
    unit_of_measurement: "LTR303"
    unique_id: "LTR303_brightness"  

效果

image.png  

拓展任务一:扩展任务二  通过外部SHT40温湿度传感器,上传温湿度到HA

3894dce37cc4f843d489a124e7c0b22.jpg  

流程图如下:

image.png  

这个流程就和弄光传感器的一样,只是换成了温湿度传感器和HA实体配置中MQTT主题

HA实体

sensor:
  - platform: mqtt
    name: "光传感器IR"
    value_template: "{{ value_json.ir_data }}"
    state_topic: "LTR303"
    unit_of_measurement: "LTR303"
    unique_id: "LTR303_IR"
  - platform: mqtt
    name: "光传感器brightness"
    value_template: "{{ value_json.brightness }}"
    state_topic: "LTR303"
    unit_of_measurement: "LTR303"
    unique_id: "LTR303_brightness"  
  - platform: mqtt
    name: "温湿度传感器-温度"
    value_template: "{{ value_json.temperature }}"
    state_topic: "SHT4"
    unit_of_measurement: "°C"
    unique_id: "SHT4_temperature"  
  - platform: mqtt
    name: "温湿度传感器-湿度"
    value_template: "{{ value_json.humidity }}"
    state_topic: "SHT4"
    unit_of_measurement: "%"
    unique_id: "SHT4_humidity" 

代码如下

#include "Adafruit_SHT4x.h"
#include <ArduinoMqttClient.h>
#include <WiFiS3.h>
#include <WiFiClient.h>
#include <Arduino_JSON.h>

Adafruit_SHT4x sht4;

char ssid[] = "ssid";        
char pass[] = "pass";  
int status = WL_IDLE_STATUS;   

const char broker[] = "ip";
int        port     = 1883;
const char command_topic[]  = "SHT4";

WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);

JSONVar dataObj;

void setup() {
  Serial.begin(115200);
    sht4.setPrecision(SHT4X_HIGH_PRECISION);

  
  switch (sht4.getPrecision()) {
     case SHT4X_HIGH_PRECISION: 
       Serial.println(F("SHT40 set to High precision"));
       break;
     case SHT4X_MED_PRECISION: 
       Serial.println(F("SHT40 set to Medium precision"));
       break;
     case SHT4X_LOW_PRECISION: 
       Serial.println(F("SHT40 set to Low precision"));
       break;
  }   
  //*********************************************************************
  //*************ADVANCED SETUP - SAFE TO IGNORE!************************       
  
  // The SHT40 has a built-in heater, which can be used for self-decontamination.
  // The heater can be used for periodic creep compensation in prolongued high humidity exposure.
  // For normal operation, leave the heater turned off.

  sht4.setHeater(SHT4X_NO_HEATER);

  
  switch (sht4.getHeater()) {
     case SHT4X_NO_HEATER: 
       Serial.println(F("SHT40 Heater turned OFF"));
       break;
     case SHT4X_HIGH_HEATER_1S: 
       Serial.println(F("SHT40 Heater: High heat for 1 second"));
       break;
     case SHT4X_HIGH_HEATER_100MS: 
       Serial.println(F("SHT40 Heater: High heat for 0.1 second"));
       break;
     case SHT4X_MED_HEATER_1S: 
       Serial.println(F("SHT40 Heater: Medium heat for 1 second"));
       break;
     case SHT4X_MED_HEATER_100MS: 
       Serial.println(F("SHT40 Heater: Medium heat for 0.1 second"));
       break;
     case SHT4X_LOW_HEATER_1S: 
       Serial.println(F("SHT40 Heater: Low heat for 1 second"));
       break;
     case SHT4X_LOW_HEATER_100MS: 
       Serial.println(F("SHT40 Heater: Low heat for 0.1 second"));
       break;
  }

  
  //*********************************************************************
  //*************ADVANCED SETUP IS OVER - LET'S CHECK THE CHIP ID!*******

  
  if (! sht4.begin(&Wire1)) {
    Serial.println(F("SHT40 sensor not found!"));
    while (1) ;
  }
   else
  {
    Serial.print(F("SHT40 detected!\t"));
    Serial.print(F("Serial number:\t"));
    Serial.println(sht4.readSerial(), HEX);    
  } 
  Serial.println(F("----------------------------------"));
 

  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
    Serial.println("Please upgrade the firmware");
  }

  // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }

  Serial.print("You're connected to the network");
  printCurrentNet();
  printWifiData();
  mqttClient.setUsernamePassword("","");
  if (!mqttClient.connect(broker, port)) {
    Serial.print("MQTT connection failed! Error code = ");
    Serial.println(mqttClient.connectError());
    while (1);
  }
  Serial.println("You are connected to MQTT");
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }

 
 
}


void printCurrentNet() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print the MAC address of the router you're attached to:
  byte bssid[6];
  WiFi.BSSID(bssid);
  Serial.print("BSSID: ");
  printMacAddress(bssid);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.println(rssi);

  // print the encryption type:
  byte encryption = WiFi.encryptionType();
  Serial.print("Encryption Type:");
  Serial.println(encryption, HEX);
  Serial.println();
}

void printMacAddress(byte mac[]) {
  for (int i = 0; i < 6; i++) {
    if (i > 0) {
      Serial.print(":");
    }
    if (mac[i] < 16) {
      Serial.print("0");
    }
    Serial.print(mac[i], HEX);
  }
  Serial.println();
}

void printWifiData() {
  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  
  Serial.println(ip);
  // print your MAC address:
  byte mac[6];
  WiFi.macAddress(mac);
  Serial.print("MAC address: ");
  printMacAddress(mac);
}



void loop() {

  sensors_event_t humidity, temp;
  sht4.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data
  
  float t = temp.temperature;
  Serial.println("Temp *C = " + String(t)); 
  float h = humidity.relative_humidity;
  Serial.println("Hum. % = " + String(h)); 

  dataObj["temperature"] = t;
  dataObj["humidity"] = h;
  String jsonString = JSON.stringify(dataObj);
  mqttClient.beginMessage(command_topic);
  mqttClient.print(jsonString);
  mqttClient.endMessage();
  delay(500);
}

任务效果:

image.png  

 

代码下载:https://download.eeworld.com.cn/detail/LTLyaoni/634885

 

心得体会:

这次活动我主要是抱着学习的心态去的。不得不说,Arduino的那些固件真的超级丰富,特别适合用来验证各种功能。我得说,论坛上那些大佬们和网友们的分享真的是太精彩了,给了我好多灵感和帮助。真的很感谢他们!

希望能有更多不同使用R4板子项目的帖子,可以加深学习Arduino

本帖最后由 LTLyaoni 于 2024-11-4 00:14 编辑

回复评论 (2)

祝贺楼主获得活动机会,希望楼主能分享活动心得及技术体验

点赞  2024-10-23 23:20

LTR-329光照传感器、SHT40温湿度传感器,直接来两个传感器很明智

在爱好的道路上不断前进,在生活的迷雾中播撒光引
点赞  2024-10-25 13:30
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复