学习记录
单片机入门
初次接触物联网,记录一下学习过程
2024-04-20 01:26:07
38

准备材料

  • 一块 ESP8266 板子
  • 一根 android 数据线
  • 开发环境准备

本篇实现开发环境的搭建,并测试板子成功连接。

ESP8266

这是我在 某宝 花了 ¥11.70 购买的 ESP8266 CH340 串口wifi模块(升级款)



最下方是一个 android 接口

android 数据线

这个就不用过多介绍了

开发环境

严格按照下方PDF教程使用,PDF中所需要的软件及驱动在下方列出。

PDF教程

  1. 下载安装 arduino
    【百度网盘】
  2. 下载 CH341SER.EXE 驱动
    【百度网盘】

LED灯闪烁

将开发板与电脑通过 android 数据线连接后,并按照第一节所述设置端口号,再进行后续操作。

LED灯闪烁


选择此示例之后,会给出示例代码,直接上传示例代码到板子上。

void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  // 设置led灯引脚编号,设置模式为输出
  pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
// 循环函数
void loop() {
  // 高电平亮灯
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  //  延迟1秒
  delay(1000);                       // wait for a second
  // 低电平亮灯
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  // 延迟1秒
  delay(1000);                       // wait for a second
}


程序上传到板子之后,板子上的 led灯 将会 亮灯1秒 重新 亮灯,达到闪烁的效果。

LED灯常亮

通过上述代码我们发现,将延迟函数去掉,就能实现常亮效果。修改 loop函数 如下:

void loop() {
  digitalWrite(LED_BUILTIN, LOW);
}

重新上传程序到板子上,就实现了常亮的效果。

OLED屏显示HelloWorld

  • 准备SPI接口的7针引脚OLED显示屏
  • 准备7跟母对母杜邦线

元件

SPI接口的7针引脚OLED显示屏

母对母杜邦线

接线

OLED针脚 连线 ESP8266针脚
GND <---> G
VCC <---> 3V
D0 <---> D5
D1 <---> D7
RES <---> D2
DC <---> D1
CS <---> D0

安装库

Arduino 的管理库中安装 U8g2U8g2_for_Adafruit_GFX 两个库。

编写代码

// 引入U8g2图形库,用于驱动OLED显示屏
#include <U8g2lib.h> 

// 定义SPI接口上OLED模块的相关引脚
// OLED片选信号(Chip Select)连接至D0引脚
#define OLED_CS D0 
// 数据/命令选择信号(Data/Command)连接至D1引脚
#define OLED_DC D1 
// OLED复位信号(Reset)连接至D2引脚(可选,如果没有物理连接复位引脚,则不需要此定义)
#define OLED_RST D2

// 创建一个U8g2对象实例,指定OLED型号为SSD1306,分辨率为128x64,采用4线软件SPI模式及对应的引脚配置
U8G2_SSD1306_128X64_NONAME_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ D5, /* data=*/ D7, /* cs=*/ OLED_CS, /* dc=*/ OLED_DC, /* reset=*/ OLED_RST);

// 设置函数:初始化串口通信以及OLED模块相关引脚
void setup() {
    // 初始化Serial串口通信,波特率为115200
    Serial.begin(115200);

    // 将OLED的片选和数据/命令选择引脚设为输出模式
    pinMode(OLED_CS, OUTPUT);
    pinMode(OLED_DC, OUTPUT);

    // 若OLED有连接复位引脚,则对其进行初始化操作
    if (OLED_RST != NOT_A_PIN) {
        pinMode(OLED_RST, OUTPUT);
        
        // 先将复位引脚拉高,然后短暂拉低以完成OLED模块的硬件复位
        digitalWrite(OLED_RST, HIGH);
        delay(100);
        digitalWrite(OLED_RST, LOW);
        delay(100);
        digitalWrite(OLED_RST, HIGH);
    }

    // 开始初始化U8g2库与OLED显示屏之间的通信
    u8g2.begin();
}

// 循环函数:在此函数内编写循环执行的代码,如更新OLED显示内容
void loop() {
    // 清除OLED显示缓存
    u8g2.clearBuffer();

    // 设置字体为ncenB14_tr样式
    u8g2.setFont(u8g2_font_ncenB14_tr);

    // 在坐标(0, 20)处写入英文字符串"HelloWorld"
    u8g2.drawStr(0, 20, "HelloWorld");

    // 将缓冲区中的内容发送至OLED显示屏进行显示
    u8g2.sendBuffer();

    // 延迟2秒后再进行下一轮显示更新
    delay(2000);
}

最终成功显示了文字!

完整代码参考码云地址

缺陷

目前只能显示英文文字,并且不会自动换行,后续处理。。。

连接wifi并显示当前时间 + 电量图标

安装库

关键代码

// 创建一个U8g2对象实例,指定OLED型号为SSD1306,分辨率为128x64,采用4线软件SPI模式及对应的引脚配置
U8G2_SSD1306_128X64_NONAME_F_4W_SW_SPI u8g2(
  U8G2_R0, 
  /* clock=*/ D5, 
  /* data=*/ D7, 
  /* cs=*/ OLED_CS, 
  /* dc=*/ OLED_DC, 
  /* reset=*/ OLED_RST
);
// 绘制时间
void drawYmdhms() {
  // 设置字体为ncenB14_tr样式
  u8g2.setFont(u8g2_font_ncenB08_tr);
  // 获取当前时间  
  time_t localTime = getLocalTime(timeClient, 8);
  // 定义时间buffer
  char timeBuffer[20];
  // 格式化时间
  formatDateTime(localTime,timeBuffer,sizeof(timeBuffer), "%Y-%m-%d %H:%M:%S");
  // 绘制年月日时分秒 
  u8g2.drawStr(5, 15, timeBuffer);
}

// 绘制电量
void drawBattery() {
  // 绘制电量
  u8g2.setFont(u8g2_font_battery19_tn);
  u8g2.drawStr(110, 20, "5");
}

/**
 * 自定义格式化函数,格式化后的结果会覆盖第二个参数buffer
 * @property {time_t} t - 时间对象
 * @property {char*} buffer - 时间对象的buffer
 * @property {size_t} bufferSize - 事件对象buffer的大小
 * @property {char*} formatStr - 格式化字符串
*/
void formatDateTime(time_t t, char* buffer, size_t bufferSize, const char* formatStr) {
  struct tm timeinfo;
  // 转换为本地时间
  localtime_r(&t, &timeinfo); 
  // 时间格式化
  strftime(buffer, bufferSize, formatStr, &timeinfo);
}

/**
 * 获取本地时间
 * @property {NTPClient} ntpClient - NTP客户端
 * @property {int} timeZoneOffsetHours - 时区偏移量,中国大陆偏移8小时
 * @return {time_t} 返回时间对象
*/
time_t getLocalTime(NTPClient ntpClient, int timeZoneOffsetHours){
  // 时间更新
  ntpClient.update();
  // 获取UTC时间戳
  time_t utcTime = ntpClient.getEpochTime(); 
  // 将UTC时间转换为本地时间
  struct tm *timeInfo = gmtime(&utcTime);
  // 增加时区偏移小时数
  timeInfo->tm_hour += timeZoneOffsetHours; 
  // 转换回Unix时间戳(此时已经是调整过时区后的本地时间戳)
  return mktime(timeInfo);
}

完整代码参考码云地址

效果图

未完待续...