ESP8266实战(一)

您所在的位置:网站首页 实时时钟原理图 ESP8266实战(一)

ESP8266实战(一)

2023-09-04 01:04| 来源: 网络整理| 查看: 265

目录 1.设计概述2.硬件设计2.1整体设计和功能介绍2.2相关硬件介绍 3.电路设计3.1自动下载电路3.2 完整的esp8266应用电路3.3PCB设计 4.程序设计4.1程序流程图4.2参考程序 5.效果展示

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 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 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 Serial.print(":"); if (digits 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 Serial.println("Receive NTP Response"); Udp.read(packetBuffer, NTP_PACKET_SIZE); //从缓冲区读取数据 unsigned long secsSince1900; secsSince1900 = (unsigned long)packetBuffer[40] 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 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 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); } } //头文件 #ifndef __MAIN_H__ #define __MAIN_H__ #include #include #include #include #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 5.效果展示

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

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



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3