数码之家

 找回密码
 立即注册
搜索
查看: 3849|回复: 7

[Arduino] 1.3 OLED ESP8266网络时钟温湿度计

[复制链接]
发表于 2021-4-29 16:11:32 来自手机浏览器 | 显示全部楼层 |阅读模式
我是小白,不会自己写,只能抄了,用的7线oled屏 spi接口,最早是想去某创开源那里找个4线的板子去打板,然后看见了这个

网络上的教程都是4线的屏,奈何没有啊,手头又正好有这个7线的,跟着做物联网烙铁用的,正好用上,不用再花银子了,


屏幕和8266的接线
测温模块数据接的D6
网上抄了2个程序,一个是网络时钟的程序,一个是测温的程序,给整合到一块儿了,有个问题,2秒一更新,不加测温的程序显示是正常的,测温的程序里面有几个延时,现在给整到2秒一更新了,取消那几个延时程序应该就只在测温里循环了,显示不更新,要不就是程序重启
某创  https://lceda.cn/search?wd=1.3%20oled&indextype=projects
某b https://www.bilibili.com/video/BV1eJ411H7LN

即使下面这段代码里有几个延时没整明白,好像也跟下面的程序有关系,下面的不会改,这块注释掉的是不行
void get_humiture() {
  bgn:
  delay(940);
  //设置2号接口模式为:输出
  //输出低电平20ms(>18ms)
  //输出高电平40μs
  pinMode(pin,OUTPUT);
  digitalWrite(pin,LOW);
  delay(20);
  digitalWrite(pin,HIGH);
  delayMicroseconds(40);
  digitalWrite(pin,LOW);
  //设置2号接口模式:输入
  pinMode(pin,INPUT);
  //高电平响应信号
  loopCnt=10000;












下面是全部程序

#include <TimeLib.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <SPI.h>
#include <DYWiFiConfig.h>
#include <U8g2lib.h>

//测温
int temp = 0;//温度
int humi = 0;//湿度
unsigned int loopCnt;
int chr[40] = {0};
unsigned long timer;
#define pin D6

/**
* 获取温湿度
*/
void get_humiture() {
  bgn:
  delay(940);
  //设置2号接口模式为:输出
  //输出低电平20ms(>18ms)
  //输出高电平40μs
  pinMode(pin,OUTPUT);
  digitalWrite(pin,LOW);
  delay(20);
  digitalWrite(pin,HIGH);
  delayMicroseconds(40);
  digitalWrite(pin,LOW);
  //设置2号接口模式:输入
  pinMode(pin,INPUT);
  //高电平响应信号
  loopCnt=10000;
  while(digitalRead(pin) != HIGH)
  {
    if(loopCnt-- == 0)
    {
      //如果长时间不返回高电平,输出个提示,重头开始。
//      Serial.println("HIGH");
      goto bgn;
    }
  }
  //低电平响应信号
  loopCnt=30000;
  while(digitalRead(pin) != LOW)
  {
    if(loopCnt-- == 0)
    {
      //如果长时间不返回低电平,输出个提示,重头开始。
//      Serial.println("LOW");
      goto bgn;
    }
  }
    //开始读取bit1-40的数值  
    for(int i=0;i<40;i++)
  {
    while(digitalRead(pin) == LOW)
    {}
    //当出现高电平时,记下时间“timer”
    timer = micros();
    while(digitalRead(pin) == HIGH)
    {}
    //当出现低电平,记下时间,再减去刚才储存的timer
    //得出的值若大于50μs,则为‘1’,否则为‘0’
    //并储存到数组里去
    if (micros() - timer >50)
    {
      chr=1;
    }else{
      chr=0;
    }
  }

  //湿度,8位的bit,转换为数值
  humi=chr[0]*128+chr[1]*64+chr[2]*32+chr[3]*16+chr[4]*8+chr[5]*4+chr[6]*2+chr[7];

  //温度,8位的bit,转换为数值
  temp=chr[16]*128+chr[17]*64+chr[18]*32+chr[19]*16+chr[20]*8+chr[21]*4+chr[22]*2+chr[23];
}


//若屏幕使用SH1106,只需把SSD1306改为SH1106即可
//U8G2_SSD1306_128X64_NONAME_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/4, /* dc=*/5, /* reset=*/3);
U8G2_SSD1306_128X64_NONAME_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/15, /* dc=*/5, /* reset=*/0);
//U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
//U8G2_SSD1106_128X64_NONAME_F_HW_SPI u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
//U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ 4, /* data=*/ 5); //D-duino

DYWiFiConfig wificonfig;
ESP8266WebServer webserver(80);
#define DEF_WIFI_SSID     "RONBON"
#define DEF_WIWI_PASSWORD "longbang2015"
#define AP_NAME "Monkey" //dev
void wificb(int c)
{
  Serial.print("=-=-=-=-");
  Serial.println(c);
}

static const char ntpServerName[] = "ntp1.aliyun.com"; //NTP服务器,阿里云
const int timeZone = 8;                                //时区,北京时间为+8

WiFiUDP Udp;
unsigned int localPort = 8888; // 用于侦听UDP数据包的本地端口

time_t getNtpTime();
void sendNTPpacket(IPAddress& address);
void oledClockDisplay();
void sendCommand(int command, int value);
void initdisplay();

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 wen[] U8X8_PROGMEM = {
  0x00,0x00,0xC4,0x1F,0x48,0x10,0x48,0x10,0xC1,0x1F,0x42,0x10,0x42,0x10,0xC8,0x1F,
  0x08,0x00,0xE4,0x3F,0x27,0x25,0x24,0x25,0x24,0x25,0x24,0x25,0xF4,0x7F,0x00,0x00
};  /*温*/
const unsigned char shi[] U8X8_PROGMEM = {
  0x00,0x00,0xE4,0x1F,0x28,0x10,0x28,0x10,0xE1,0x1F,0x22,0x10,0x22,0x10,0xE8,0x1F,
  0x88,0x04,0x84,0x04,0x97,0x24,0xA4,0x14,0xC4,0x0C,0x84,0x04,0xF4,0x7F,0x00,0x00
};  /*湿*/

void setup()
{
  //测温
  pinMode(D4, OUTPUT);
  delay(10);

  Serial.begin(115200);
  while (!Serial)
    continue;
  Serial.println("NTP Clock oled version v1.1");
  Serial.println("Designed by flyAkari");
  initdisplay();
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_unifont_t_chinese2);
  u8g2.setCursor(0, 14);
  u8g2.print("Waiting for WiFi");
  u8g2.setCursor(0, 30);
  u8g2.print("connection...");
  u8g2.setCursor(0, 47);
  u8g2.print("flyAkari");
  u8g2.setCursor(0, 64);
  u8g2.print("192.168.4.1");
  u8g2.sendBuffer();
  Serial.println("OLED Ready");

  Serial.print("Connecting WiFi...");
  wificonfig.begin(&webserver, "/");
  DYWIFICONFIG_STRUCT defaultConfig = wificonfig.createConfig();
  strcpy(defaultConfig.SSID, DEF_WIFI_SSID);
  strcpy(defaultConfig.SSID_PASSWORD, DEF_WIWI_PASSWORD);
  strcpy(defaultConfig.HOSTNAME, AP_NAME);
  strcpy(defaultConfig.APNAME, AP_NAME);
  wificonfig.setDefaultConfig(defaultConfig);
  wificonfig.enableAP();
  while (WiFi.status() != WL_CONNECTED)
  {
    wificonfig.handle();   //若不需要Web后台,可以注释掉此行
    //Serial.println("Waiting for Connection...");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.println("Starting UDP");
  Udp.begin(localPort);
  Serial.print("Local port: ");
  Serial.println(Udp.localPort());
  Serial.println("waiting for sync");
  setSyncProvider(getNtpTime);
  setSyncInterval(30); //每300秒同步一次时间
  isNTPConnected = true;
}

time_t prevDisplay = 0;   //当时钟已经显示

void loop()
{
  if (timeStatus() != timeNotSet)
  {
    if (now() != prevDisplay)
    { //时间改变时更新显示
      prevDisplay = now();
      oledClockDisplay();
    }
  }
  wificonfig.handle(); //若不需要Web后台,可以注释掉此行
  get_humiture();
}

void initdisplay()
{
  u8g2.begin();
  u8g2.enableUTF8Print();
}

void oledClockDisplay()
{
  int years, months, days, hours, minutes, seconds, weekdays;
  years = year();
  months = month();
  days = day();
  hours = hour();
  minutes = minute();
  seconds = second();
  weekdays = weekday();
  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(24, 14);
  if (isNTPConnected)
    {//u8g2.print("当前时间 (UTC+8)");
    u8g2.drawXBM(8, 0, 16, 16, wen);
    u8g2.print("度");
    u8g2.print(temp);
    u8g2.drawXBM(72, 0, 16, 16, shi);
    u8g2.setCursor(88, 14);
    u8g2.print("度");
    u8g2.print(humi);
    }
  else
    u8g2.print("无网络!"); //如果上次对时失败,则会显示无网络
  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(8, 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("期");
  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();
}

/*-------- NTP 代码 ----------*/

const int NTP_PACKET_SIZE = 48;     // NTP时间在消息的前48个字节里
byte packetBuffer[NTP_PACKET_SIZE]; // 输入输出包的缓冲区

time_t getNtpTime()
{
  IPAddress ntpServerIP;          // NTP服务器的地址

  while (Udp.parsePacket() > 0);  // 丢弃以前接收的任何数据包
  Serial.println("Transmit NTP Request");
  // 从池中获取随机服务器
  WiFi.hostByName(ntpServerName, ntpServerIP);
  Serial.print(ntpServerName);
  Serial.print(": ");
  Serial.println(ntpServerIP);
  sendNTPpacket(ntpServerIP);
  uint32_t beginWait = millis();
  while (millis() - beginWait < 1500)
  {
    int size = Udp.parsePacket();
    if (size >= NTP_PACKET_SIZE)
    {
      Serial.println("Receive NTP Response");
      isNTPConnected = true;
      Udp.read(packetBuffer, NTP_PACKET_SIZE); // 将数据包读取到缓冲区
      unsigned long secsSince1900;
      // 将从位置40开始的四个字节转换为长整型,只取前32位整数部分
      secsSince1900 = (unsigned long)packetBuffer[40] << 24;
      secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
      secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
      secsSince1900 |= (unsigned long)packetBuffer[43];
      Serial.println(secsSince1900);
      Serial.println(secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR);
      return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
    }
  }
  Serial.println("No NTP Response :-("); //无NTP响应
  isNTPConnected = false;
  return 0; //如果未得到时间则返回0
}

// 向给定地址的时间服务器发送NTP请求
void sendNTPpacket(IPAddress& address)
{
  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
  // 8 bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12] = 49;
  packetBuffer[13] = 0x4E;
  packetBuffer[14] = 49;
  packetBuffer[15] = 52;
  Udp.beginPacket(address, 123); //NTP需要使用的UDP端口号为123
  Udp.write(packetBuffer, NTP_PACKET_SIZE);
  Udp.endPacket();
}


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

打赏

参与人数 1家元 +40 收起 理由
家睦 + 40

查看全部打赏

发表于 2021-4-29 17:19:42 | 显示全部楼层
现在这种小屏都没动力搞了,看着太累,可能年纪变大了吧:sweat:
回复 支持 反对

使用道具 举报

发表于 2021-4-29 21:09:20 | 显示全部楼层
本帖最后由 fryefryefrye 于 2021-4-29 21:11 编辑
ww5223017240 发表于 2021-4-29 17:19
现在这种小屏都没动力搞了,看着太累,可能年纪变大了吧

是的,这一个小屏还要10多元。还不如搞个LED阵列,二手的也就10多元。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复 支持 反对

使用道具 举报

发表于 2021-4-29 22:51:26 | 显示全部楼层


这个研究了好久了,时间容易,和风天气那个不会刷:sweat:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复 支持 1 反对 0

使用道具 举报

发表于 2021-4-29 23:03:01 | 显示全部楼层
fryefryefrye 发表于 2021-4-29 21:09
是的,这一个小屏还要10多元。还不如搞个LED阵列,二手的也就10多元。

抱歉,阵列的更不喜欢,点点恐惧症,还是喜欢用老手机改,除了费电没啥坏处
回复 支持 反对

使用道具 举报

发表于 2021-4-29 23:04:28 | 显示全部楼层
3797 发表于 2021-4-29 22:51
这个研究了好久了,时间容易,和风天气那个不会刷

那个简单啊,不是有图像转换辅助软件嘛
回复 支持 反对

使用道具 举报

发表于 2021-4-29 23:19:36 | 显示全部楼层
ww5223017240 发表于 2021-4-29 23:04
那个简单啊,不是有图像转换辅助软件嘛


我只会刷进去时间这个样子的——

上面楼的图,带天气的上面那个死活搞不定,库也都装了

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复 支持 反对

使用道具 举报

发表于 2021-6-15 22:27:07 | 显示全部楼层
fryefryefrye 发表于 2021-4-29 21:09
是的,这一个小屏还要10多元。还不如搞个LED阵列,二手的也就10多元。

可以把表面覆一层神色薄膜,遮挡一下点点
回复 支持 反对

使用道具 举报

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

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-5-7 17:15 , Processed in 0.436801 second(s), 13 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

快速回复 返回顶部 返回列表