当前位置:   article > 正文

ESP8266实战(一)--wifi时钟的制作_esp8266时钟

esp8266时钟

1.设计概述

esp8266是一款性价比极高的wifi蓝牙芯片。它不光集成了wifi蓝牙模组,同时内部集成了单片机内核,可以把它当普通的单片机使用。同时它支arduino编程,micropython编程和自带的idf库编程,使用起来非常方便。

这次设计以esp8266为主控,通过wifi读取ntp时间,来实现wifi时钟。

2.硬件设计

2.1整体设计和功能介绍

整体设计如下图:
在这里插入图片描述
硬件电路主要是由以下几个部分组成: WIFI模块(ESP8266)、USB转串口电路、供电电路、外设电路(包括OLED显示屏、MPU-6050模块和SHT31温湿度采集模块)。
主要功能:
1.显示日期
2.通过重力感应切换显示
3.显示温湿度

2.2相关硬件介绍

1.esp8266
在这里插入图片描述
其支持802.11b/g/n WIFI协议,内部的微处理器主频范围在80Mhz到160Mhz,有32Mbit的FLASH存储。具体的资料参见其数据手册。
2.mpu6050
在这里插入图片描述
MPU-6050对陀螺仪和加速度计分别用了三个16位的ADC, 将其测量的模拟量转化为可输出的数字量。陀螺仪可测范围为±250,上500,1000,±2000°/秒(dps), 加速度计可测范围为±2,±4,±8,±16g。
3.SHT31
在这里插入图片描述
它有两个型号(见下图),他们只是量程不一样,使用起来是完全一样的。它比DHT11好用。
在这里插入图片描述
4.oled
在这里插入图片描述
这是一个四线的oled,建议用1.3存的,这个例子中用了0.96寸的。时间的显示可以通用。图片的显示需要改像素。

3.电路设计

整体的电路设计如下图:
在这里插入图片描述

3.1自动下载电路

在这里插入图片描述
这里使用了G版本的CH340,所以需要晶振,但它便宜!!!C版本的不需要晶振。其实这部分电路可以省去,接外部的下载器下载也可以。

3.2 完整的esp8266应用电路

在这里插入图片描述
运行模式说明如下图:
在这里插入图片描述

3.3PCB设计

在这里插入图片描述
觉得麻烦没有敷铜。
在这里插入图片描述
在这里插入图片描述

4.程序设计

4.1程序流程图

在这里插入图片描述
采用Smart Config/AirKiss 配置网络。

4.2参考程序

这里采用的是arduino IDE开发。

//**********************************************************************
//主程序:用来显示网络时间,并显示温湿度数据
//**********************************************************************
#include "main.h"

bool autoConfig()                             //用之前的配网参数自动联网
{
  WiFi.mode(WIFI_STA);
  u8g2.setCursor(0, 12);
  u8g2.print("Connect to Ap ...");
  u8g2.sendBuffer();
  WiFi.begin();
  for (int i = 0; i < 20; i++)
  {
    int wstatus = WiFi.status();
    if (wstatus == WL_CONNECTED)
    {
      Serial.println("AutoConfig Success");
      Serial.printf("SSID: %s\r\n", WiFi.SSID().c_str());
      Serial.printf("PSW:  %s\r\n", WiFi.psk().c_str());
      Serial.print("IP:   ");
      Serial.println(WiFi.localIP());         //得到IP地址
      return true;
    }
    else
    {
      Serial.print("AutoConfig Waiting......");
      Serial.println(wstatus);
      delay(1000);
    }
  }
  Serial.println("AutoConfig Faild!" );
  return false;
}

void smartConfig()
{
  u8g2.clearBuffer();
  u8g2.setCursor(0, 12);
  u8g2.print("Waiting smartcfg....");
  u8g2.sendBuffer();
  WiFi.mode(WIFI_STA);
  Serial.println("\r\nWaiting for Smartconfig");
  delay(2000);
  WiFi.beginSmartConfig();                  //等待配网
 
  while (1)
  {
    Serial.print(".");
    delay(400);
    if (WiFi.smartConfigDone())             //配网完成
    {
      Serial.println("SmartConfig Success");
      Serial.printf("SSID:%s\r\n", WiFi.SSID().c_str());
      Serial.printf("PSW:%s\r\n", WiFi.psk().c_str());
      WiFi.setAutoConnect(true);            //设置自动连接
      break;
    }
  }
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());           //得到IP地址
}

void digitalClockDisplay()                //打印时间
{
  int years, months, days, hours, minutes, seconds, weekdays;
  years = year();
  months = month();
  days = day();
  hours = hour();
  minutes = minute();
  seconds = second();
  weekdays = weekday();
  if (seconds == 0){                     //一分钟打印一次时间
    Serial.printf("%d/%d/%d %d:%d:%d Weekday:%d\n", years, months, days, hours, minutes, seconds, weekdays);
  }
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_unifont_t_chinese2);
  u8g2.setCursor(0, 14);

  int temp1, humi1;
  temp1 = rtemp * 10; 
  humi1 = rhumi; 
  u8g2.print("H:");
  if (humi1 < 10){
    u8g2.print(" "); 
    u8g2.print(humi1); 
  }else
    u8g2.print(humi1); 
  u8g2.print("%");

  u8g2.setCursor(64, 14);
  u8g2.print("T:");
  if (temp1 < 100){
    u8g2.print(" "); 
    u8g2.print(temp1 / 10); 
  }else
    u8g2.print(temp1 / 10); 
  u8g2.print(".");
  u8g2.print(temp1 % 10); 
  u8g2.drawXBM(112, 0, 16, 16, du);
  
  String currentTime = "";
  if (hours < 10)
    currentTime += 0;
  currentTime += hours;
  currentTime += ":";
  if (minutes < 10)
    currentTime += 0;
  currentTime += minutes;
  currentTime += ":";
  if (seconds < 10)
    currentTime += 0;
  currentTime += seconds;
  String currentDay = "";
  currentDay += years;
  currentDay += "/";
  if (months < 10)
    currentDay += 0;
  currentDay += months;
  currentDay += "/";
  if (days < 10)
    currentDay += 0;
  currentDay += days;

  u8g2.setFont(u8g2_font_logisoso24_tr);
  u8g2.setCursor(0, 44);
  u8g2.print(currentTime);
  u8g2.setCursor(0, 61);
  u8g2.setFont(u8g2_font_unifont_t_chinese2);
  u8g2.print(currentDay);
  u8g2.drawXBM(80, 48, 16, 16, xing);
  u8g2.setCursor(95, 62);
  u8g2.print("期");   //必须是u8g2_font_unifont_t_chinese2里有的字
  if (weekdays == 1)
    u8g2.print("日");
  else if (weekdays == 2)
    u8g2.print("一");
  else if (weekdays == 3)
    u8g2.print("二");
  else if (weekdays == 4)
    u8g2.print("三");
  else if (weekdays == 5)
    u8g2.print("四");
  else if (weekdays == 6)
    u8g2.print("五");
  else if (weekdays == 7)
    u8g2.drawXBM(111, 49, 16, 16, liu);
  u8g2.sendBuffer();
}
void displayimage()
{
  u8g2.clearBuffer();
  u8g2.drawXBM(0, 0, 128, 64, bmp2);
  u8g2.sendBuffer();
}
void printDigits(int digits)                  //打印时间数据
{
  Serial.print(":");
  if (digits < 10)                            //打印两位数字
    Serial.print('0');
  Serial.print(digits);
}
time_t getNtpTime()                           //获取NTP时间
{
  bool Time_Recv_Flag = false;
  IPAddress ntpServerIP;                      //NTP服务器的IP地址
  
  while (Udp.parsePacket() > 0) ;             //之前的数据没有处理的话一直等待 discard any previously received packets
  WiFi.hostByName(ntpServerName, ntpServerIP);//从网站名获取IP地址
  if (PowerOn_Flag == 0)                      //第一次才打印
  {
    Serial.println("Transmit NTP Request");
    Serial.print(ntpServerName);
    Serial.print(": ");
    Serial.println(ntpServerIP);
  }

  while (Time_Recv_Flag == false)               //如果是上电第一次获取数据的话,要一直等待,直到获取到数据,不是第一次的话,没获取到数据,直接返回
  {
    sendNTPpacket(ntpServerIP);                 //发送数据包
    uint32_t beginWait = millis();
    while (millis() - beginWait < 1500) 
    {
      int size = Udp.parsePacket();             //接收数据
      if (size >= NTP_PACKET_SIZE) 
      {
        Serial.println("Receive NTP Response");
        Udp.read(packetBuffer, NTP_PACKET_SIZE);  //从缓冲区读取数据
        
        unsigned long secsSince1900;
        secsSince1900 =  (unsigned long)packetBuffer[40] << 24;
        secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
        secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
        secsSince1900 |= (unsigned long)packetBuffer[43];
        if (PowerOn_Flag == 0)                    //第一次收到数据
        {
          u8g2.setCursor(0, 36);
          u8g2.print("Ntp data get ok");
          u8g2.sendBuffer();
        }
        Time_Recv_Flag = true;
        return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
      }
    }
    if (PowerOn_Flag == 1)                        //不是第一次
    {
      return 0;
    }
  }
  Serial.println("No NTP Response :-(");
  return 0;                                         //没获取到数据的话返回0
}
  

void sendNTPpacket(IPAddress &address)              //发送数据包到NTP服务器
{
  memset(packetBuffer, 0, NTP_PACKET_SIZE);         //缓冲区清零

  packetBuffer[0] = 0b11100011;                     // LI, Version, Mode   填充缓冲区数据
  packetBuffer[1] = 0;                              // Stratum, or type of clock
  packetBuffer[2] = 6;                              // Polling Interval
  packetBuffer[3] = 0xEC;                           // Peer Clock Precision
  packetBuffer[12] = 49;
  packetBuffer[13] = 0x4E;
  packetBuffer[14] = 49;
  packetBuffer[15] = 52;

  Udp.beginPacket(address, 123);                    //NTP服务器端口123
  Udp.write(packetBuffer, NTP_PACKET_SIZE);         //发送udp数据
  Udp.endPacket();                                  //发送结束
  
  if (PowerOn_Flag == 0)
  {
    Serial.println("Send Ntp data...");
  }
}

void imuupdate()
{
   imu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz); //读取六轴原始数值
   ax = ax - axo;
   ay = ay - ayo;
   az = az - azo;
 //判断姿态,当左摇或者右摇时,改变状态变量
  if (millis() - last_update_time > interval)
  {
    if (ay > 3000 && flag)
    {
      i--;
      if(i<0)
      {
        i= 5;
        }
      flag = 0;
    }
    else if (ay < -3000 && flag)
    {
      i++;
      flag = 0;
    }
    else
    {
      flag = 1;
    }

    if (az > 5000)
    {
      j++;
      if(j >4)
      {
        j = 0;
        }
    }
    if(i >5)
    {
       i = 0;
    }

    last_update_time = millis();
  }
}

void setup() 
{

  Serial.begin(115200);             //初始化串口
  Serial.println();                 //打印回车换行

  u8g2.begin();
  u8g2.enableUTF8Print(); 
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_wqy12_t_gb2312a);
  ESP.wdtEnable(8000);              //使能软件看门狗的触发间隔MS
  ESP.wdtFeed();                    //喂狗

  if (!autoConfig())                //如果自动联网失败的话,就启动smartconfig
  {
    Serial.println("Start smartconfig");
    smartConfig();
  }
  u8g2.setCursor(0, 24);
  u8g2.print("Connted to AP ok");
  u8g2.setCursor(0, 64);
  u8g2.print("IP: " + WiFi.localIP().toString());//显示本机的IP
  u8g2.sendBuffer();
  delay(1000);                      //延时1S
 
  Serial.println("Starting UDP");               //连接时间服务器
  Udp.begin(localPort);
  Serial.print("Local port: ");
  Serial.println(Udp.localPort());
  Serial.println("waiting for sync");
  
  setSyncProvider(getNtpTime);
  setSyncInterval(300);
  
  pinMode(LEDB, OUTPUT);   
  pinMode(LEDR, OUTPUT);
  pinMode(LEDG, OUTPUT); 
  digitalWrite(LEDB, LOW); 
  digitalWrite(LEDG, LOW); 
  digitalWrite(LEDR, HIGH); 
  
  Serial.println("SHT31 test");
  if (!sht31.begin(0x44)) 
  { // Set to 0x45 for alternate i2c addr
   Serial.println("Couldn't find SHT31");
   while (1) delay(1);
  }
  
  Wire.begin();
  Wire.setClock(400000);
  imu.initialize();                 //初始化
  Serial.println(imu.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
  unsigned short times = 200;             //采样次数
  for(int i=0;i<times;i++)
  {
        imu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz); //读取六轴原始数值
        axo += ax; ayo += ay; azo += az;      //采样和
        gxo += gx; gyo += gy; gzo += gz;
    
   }
   axo /= times; ayo /= times; azo /= times; //计算加速度计偏移
   gxo /= times; gyo /= times; gzo /= times; //计算陀螺仪偏移
}

void loop() 
{
  now1 = millis();
  if ((now1 - LastTime1 >= 20000) || (LastTime1 == 0)){ //定时读取数据
    LastTime1 = now1;
    rtemp = sht31.readTemperature(); 
    rhumi = sht31.readHumidity(); 
    Serial.printf("湿度:%.3f, 温度:%.3f\r\n" ,rhumi,rtemp);
  }
  imuupdate();
  if(i == 0)
  {
  if (timeStatus() != timeNotSet)               //已经获取到数据的话
  {
    if (now() != prevDisplay)                   //如果本次数据和上次不一样的话,刷新
    {
      prevDisplay = now();
      digitalClockDisplay();
    }
  }
  }
  if(i == 1)
  {
   u8g2.clearBuffer();
   u8g2.drawXBM(0, 0, 128, 64, bmp1);
   u8g2.sendBuffer();
  }
  if(i == 2)
  {
   u8g2.clearBuffer();
   u8g2.drawXBM(0, 0, 128, 64, bmp2);
   u8g2.sendBuffer();
  }
  if(i == 3)
  {
   u8g2.clearBuffer();
   u8g2.drawXBM(0, 0, 128, 64, bmp3);
   u8g2.sendBuffer();
  }
  if(i == 4)
  {
   u8g2.clearBuffer();
   u8g2.drawXBM(0, 0, 128, 64, bmp4);
   u8g2.sendBuffer();
  }
  if(j == 0)
  {
    digitalWrite(LEDB, LOW); 
    digitalWrite(LEDG, LOW); 
    digitalWrite(LEDR, LOW); 
  }
   if(j == 1)
  {
    digitalWrite(LEDB, HIGH); 
    digitalWrite(LEDG, LOW); 
    digitalWrite(LEDR, LOW); 
  }
   if(j == 2)
  {
    digitalWrite(LEDB, HIGH); 
    digitalWrite(LEDG, HIGH); 
    digitalWrite(LEDR, LOW); 
  }
   if(j == 3)
  {
    digitalWrite(LEDB, HIGH); 
    digitalWrite(LEDG, HIGH); 
    digitalWrite(LEDR, HIGH); 
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 397
  • 398
  • 399
  • 400
  • 401
  • 402
  • 403
  • 404
  • 405
  • 406
  • 407
  • 408
  • 409
  • 410
  • 411
  • 412
  • 413
  • 414
  • 415
  • 416
  • 417
  • 418
//头文件
#ifndef __MAIN_H__
#define __MAIN_H__

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <TimeLib.h>
#include <U8g2lib.h>
#include "Wire.h"
#include "Adafruit_SHT31.h"
#include "MPU6050.h"

MPU6050 imu;    //定义对象
int16_t ax, ay, az, gx, gy, gz;             //加速度计陀螺仪原始数据
long axo = 0, ayo = 0, azo = 0;             //加速度计偏移量
long gxo = 0, gyo = 0, gzo = 0;             //陀螺仪偏移量
int flag = 0;                               //imu移动标志变量
long  last_update_time;
int interval = 400;

#define SCL  14                     //GPIO14
#define SDA  12                     //GPIO12
#define LEDB 16  
#define LEDR 13
#define LEDG 2  

U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, SCL, SDA, U8X8_PIN_NONE);   //scl,sda,rst

float rtemp;
float rhumi;

Adafruit_SHT31 sht31 = Adafruit_SHT31();

//---------------------NTP相关参数---------------------
static const char ntpServerName[] = "cn.ntp.org.cn";      //NTP服务器
  
const int timeZone = 8;               //时区,东八区为北京时间
  
WiFiUDP Udp;
unsigned int localPort = 8888;        //连接时间服务器的本地端口号

time_t prevDisplay = 0;               //上一次获取到的时间
const int NTP_PACKET_SIZE = 48;       //NTP发送数据包长度
byte packetBuffer[NTP_PACKET_SIZE];   //NTP数据包缓冲区


//---------------------Time 相关参数---------------------
int Led_Flag = HIGH;                  //默认当前灭灯
bool Led_State = false;               //灯状态
unsigned long LastTime1 = 0;
unsigned long now1;
int i = 0;  //按键标志变量, 控制切换图片
int j = 1;  //控制切换灯
typedef struct
{
  uint8_t Month;                      //RTC Date Month (in BCD format).0x01-0x12
  uint8_t Date;                       //RTC Date.1-31
  uint16_t Year;                      //RTC Date Year.2000-2099    
  uint8_t Hour;
  uint8_t Minute;
  uint8_t Second;
  uint8_t Week;
}RTC_DateTypeDef;                     //时间结构体

uint8_t PowerOn_Flag = 0;             //上电标志位
RTC_DateTypeDef Time;                 //本次读到的时间
RTC_DateTypeDef Last_Time;            //上次读到的时间

boolean isNTPConnected = false;

const unsigned char xing[] U8X8_PROGMEM = {
  0x00, 0x00, 0xF8, 0x0F, 0x08, 0x08, 0xF8, 0x0F, 0x08, 0x08, 0xF8, 0x0F, 0x80, 0x00, 0x88, 0x00,
  0xF8, 0x1F, 0x84, 0x00, 0x82, 0x00, 0xF8, 0x0F, 0x80, 0x00, 0x80, 0x00, 0xFE, 0x3F, 0x00, 0x00
};  /*星*/
const unsigned char liu[] U8X8_PROGMEM = { 
  0x40, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00,
  0x20, 0x02, 0x20, 0x04, 0x10, 0x08, 0x10, 0x10, 0x08, 0x10, 0x04, 0x20, 0x02, 0x20, 0x00, 0x00
};  /*六*/
const unsigned char du[] U8X8_PROGMEM = { 
0x06,0x00,0x89,0x2F,0x69,0x30,0x36,0x20,0x10,0x20,0x18,0x00,0x18,0x00,0x18,0x00,
0x18,0x00,0x18,0x00,0x18,0x00,0x10,0x00,0x30,0x20,0x60,0x10,0x80,0x0F,0x00,0x00,//℃
}; 
//自定义图片 128 X 64 
//添加自己的图片数组
static const unsigned char bmp1[] U8X8_PROGMEM  = {};
static const unsigned char bmp2[] U8X8_PROGMEM  = {};
static const unsigned char bmp3[] U8X8_PROGMEM  ={};
static const unsigned char bmp4[] U8X8_PROGMEM  ={};

time_t getNtpTime();
void digitalClockDisplay();
void printDigits(int digits);
void sendNTPpacket(IPAddress &address);
void displayimage();
void imuupdate();

#endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97

5.效果展示

在这里插入图片描述
这个里的led灯买错了,本来是一个RGD彩灯,结果买成了三阶亮度的白灯。上摇可以调节灯的显示状态。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
左摇和右摇可以切换图片显示。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/211504
推荐阅读
相关标签
  

闽ICP备14008679号