1350|2

175

帖子

1

资源

一粒金砂(高级)

【Beetle ESP32-C3】六、OLED、AHT10和TCP(Arduino) [复制链接]

       本篇记录一个较复杂案例的实现,ESP32 C3的硬I2C驱动OLED和AHT10,测得温湿度显示到OLED上,并且连接WiFi,建立TCP连接向远端TCP Server发送温湿度值。

1、ESP32 C3的硬I2C

      ESP32 C3的硬I2C默认为IO8-SDA和IO9-SCL,本例就不做改动了。具体的管脚分配,可以在Arduino-ESP32 Package的源码中找到,位于:“..\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.4\variants\esp32c3\pins_arduino.h”——一般Arduino的开发板管脚定义都在对应开发板目录(路径中的esp32c3)的pins_arduino.h头文件中。

 

image-20220817134810-1.png

图6-1 pins_arduino.h中的I2C管脚定义

 

      C3管脚资源有限,所以OLED和AHT10连接到同一个I2C上,通过器件地址相互区分就可以了。实际这个案例初始是受到DFROBOT在线文档的示例启发,只不过文档用的SHT30(https://wiki.dfrobot.com.cn/_SKU_DFR0868_Beetle_ESP32_C3#target_17)。本人没有这个传感器,所以换成AHT10。正好AHT10和OLED的线序一致,在面包板上连接还挺方便。

 

image-20220817134810-2.png

图6-2 管脚连接

 

image-20220817134810-3.png

图6-3 实物连接

 

2、AHT10库和u8g2库

      AHT10和OLED的驱动直接下载的库,AHT10是Adafruit_AHTX0 V2.0.2,u8g2是V2.31.2。

 

image-20220817134810-4.png

 

image-20220817134810-5.png

图6-4 库安装

 

3、完整代码

      项目采取每秒测量温湿度,同时板载LED闪烁以指示程序运行中。每测量6次求平均值,然后分别在OLED、串口和TCP Server三端输出。

      测试过程发现一个问题,就是6次测量中,第一次的温度值总是很离谱,都在四十七、八度的样子。结果平均值就达到32度,一度让本人怀疑是不是空调坏了。解决方法也很简单粗暴,6次测量直接舍去第一次,改5次求平均。

      当然原因本人没有研究,猜想可能是没有在6次测量开始时进行AHT10启动引起的。

      另一个情况就是求平均值后,小数位数会增加(单次测量仅两位),使用u8g2.print()函数会出错造成ESP32重启,这个猜想可能是位数增加造成的内存溢出问题。于是改用dtostrf()函数将float类型平均值转为字符串,再用u8g2.drawStr()函数显示。

 

#include <Arduino.h>
#include <WiFi.h>
#include <WiFiClient.h>
#include <U8g2lib.h>
#include <Wire.h>
#include <Adafruit_AHTX0.h>

#define LED 10                      //板载LED管脚
#define LEN 6                       //测量LEN次求平均

float temp = 0;                     //温度平均值
float humi = 0;                     //湿度平均值
float temparr[LEN] = {0};           //LEN次温度测量值数组
float humiarr[LEN] = {0};           //LEN次湿度测量值数组
char str[6] = {0};                  //字符串缓存用于OLED显示
uint8_t times = 0;                  //测量计数器,每LEN次求平均
Adafruit_AHTX0 aht;                 //aht实例
const char *ssid = "yourssid";      //WIFI名称
const char *password = "yourpsw";   //密码
const uint16_t port = 1234;         //TCP Server端口
const char *host = "192.168.31.74"; //TCP Server IP

/*
---显示屏硬件I2C接口---
U8G2_R0 不旋转,横向,绘制方向从左到右
U8G2_R1 顺时针旋转90度,绘制方向从上到下
U8G2_R2 顺时针旋转180度,绘制方向从右到左
U8G2_R3 顺时针旋转270度,绘制方向从下到上
U8G2_MIRROR 正常显示镜像内容(v2.6.x版本以上使用)   
            注意:U8G2_MIRROR需要与setFlipMode()配搭使用.
U8x8_PIN_NONE 表示引脚为空,不会使用复位引脚
---显示屏硬件SPI接口---
cs 按引脚接上即可(引脚可自己选择)
dc 按引脚接上即可(引脚可自己选择)
*/
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);

void setup() {
/* 初始化LED(板载 IO10控制)  */
  pinMode(LED, OUTPUT);
  
/* 初始化UART0(板载USB-UART)*/
  Serial.begin(115200);
  
/* 初始化u8g2及OLED          */
  u8g2.begin();
/* 
  drawStr()默认字符的左下角为坐标标准,
  setFontPosTop()改为左上角为坐标标准。
*/  
  u8g2.setFontPosTop();
  
/* AHT10初始化               */
  if(!aht.begin()) {
    Serial.println("Could not find AHT");
    u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_osb18_tf);
    u8g2.drawStr(5,10,"no AHT");
    u8g2.sendBuffer();
    while(1) delay(10);
  }
  Serial.println("AHT10 or AHT20 found");

/* WiFi初始化,连接AP         */
  WiFi.begin(ssid, password);
  while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("WiFi connected!");
}

void loop() {
/* 读取温湿度                */
  sensors_event_t aht_humi, aht_temp;
  aht.getEvent(&aht_humi, &aht_temp);
  temparr[times] = aht_temp.temperature;
  humiarr[times] = aht_humi.relative_humidity;

/* 每LEN次计算平均值,做三端输出*/
  if(times++ >= LEN) {   
    times = 0;         //计数器复位  
    
  /* 求得平均值          */
    temp = 0;
    humi = 0;
    for(int i=0; i<LEN; i++) { //LEN次测量值求和
      temp += temparr;
      humi += humiarr;
      Serial.print("temp: ");  //输出每次温度值及当前和
      Serial.print(temparr); 
      Serial.print(", tempsum: "); 
      Serial.print(temp); 
      Serial.println("");
      Serial.print("humi: ");  //输出每次湿度值及当前和
      Serial.print(humiarr); 
      Serial.print(", humisum: "); 
      Serial.print(humi); 
      Serial.println("");
      Serial.println("-----------------------------");
    }
    temp = (temp-temparr[0]) / 5.0;//第一次温度值总是很大,所以减掉
    humi = (humi-humiarr[0]) / 5.0;//为了保持一致,湿度也减掉第一次
    memset(temparr, 0, LEN);
    memset(humiarr, 0, LEN);
  
  /* 串口显示温湿度       */
    Serial.print("Temperature: "); 
    Serial.print(temp); 
    Serial.println(" degrees C");
    Serial.print("Humidity: "); 
    Serial.print(humi); 
    Serial.println("% rH");

  /* TCP发送温湿度值      */
    WiFiClient client;                //TCP Client 实例
    if(!client.connect(host, port)) { //连接失败串口消息
      Serial.println("Connection failed.");
    } else {                          //连接成功发送到TCP Server
      client.print("Temperature: "); 
      client.print(temp); 
      client.println(" degrees C");
      client.print("Humidity: "); 
      client.print(humi); 
      client.println("% rH");
      client.stop();                  //断开连接
    }

  /* OLED显示温湿度       */
    u8g2.clearBuffer();//清屏幕
    
  //  OLED显示温度  
    u8g2.setFont(u8g2_font_osb18_tf); //选择字体
    u8g2.drawStr(5, 10, "Temp");      //显示Temp字符
    u8g2.setFont(u8g2_font_t0_18b_tr);
    memset(str, 0, 6);
    dtostrf(temp, 6, 2, str);
    u8g2.drawStr(75, 15, str);
//    u8g2.setCursor(75, 15);
//    u8g2.print(temp);//temp平均值若小数部分长,会出错

  //  OLED显示湿度
    u8g2.setFont(u8g2_font_osb18_tf);    
    u8g2.drawStr(5, 40, "Humi");
    u8g2.setFont(u8g2_font_t0_18b_tr);
    memset(str, 0, 6);
    dtostrf(humi, 6, 2, str);
    u8g2.drawStr(75, 45, str);
//    u8g2.setCursor(75, 45);
//    u8g2.print(humi);

  //  此句使得OLED真正显示出来
    u8g2.sendBuffer();      
  }

/* 指示灯翻转                */
  digitalRead(LED) ? digitalWrite(LED, LOW) : digitalWrite(LED, HIGH);
/* 延时1s                   */
  delay(1000);
}

 

此帖出自RF/无线论坛

回复

2601

帖子

3

资源

版主

两个结合在一起,画的图很美,怎么摆弄出来的?

点评

GUI是DFROBOT的案例给出的,都是u8g2库的预制字体  详情 回复 发表于 2022-8-17 19:59

回复

175

帖子

1

资源

一粒金砂(高级)

lugl4313820 发表于 2022-8-17 16:27 两个结合在一起,画的图很美,怎么摆弄出来的?

GUI是DFROBOT的案例给出的,都是u8g2库的预制字体


回复
您需要登录后才可以回帖 登录 | 注册

相关帖子
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
    关闭
    站长推荐上一条 1/7 下一条

    About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

    站点相关: 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

    北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

    电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2022 EEWORLD.com.cn, Inc. All rights reserved
    快速回复 返回顶部 返回列表