用ESP8266制作一个可以查看天气是闹钟

用ESP8266制作一个小时钟,外加天气情况

首先要准备一个ESP8266 模块,和一个OLED,我这里为了好看给他重新设计了一个板子,至少个头会MINI很多,很可爱。代码已经放上来了直接烧录进去,接线就可以使用。

成品图片在这里插入图片描述

侧颜在这里插入图片描述

部分代码

#include <Wire.h>
#include "SSD1306Wire.h"
//2020.2.19
#include "images.h"
#include <ESP8266WiFi.h>
#include <ArduinoJson.h>                
#include <Time.h>
#include <Timezone.h>
#include "NTP.h"


int json_state;//天气返回编码
int json_state2;//温度返回值
String json_temp;

const char* AP_SSID ="TP-LINK_06";         // 你的WiFi账号
const char* AP_PSK = "123456789";        // 你的WiFi密码
const char *host = "ip-api.com"; //欲访问的域名

// 北京时间时区
#define STD_TIMEZONE_OFFSET +8    // Standard Time offset (-7 is mountain time)

TimeChangeRule mySTD = {"", First,  Sun, Jan, 0, STD_TIMEZONE_OFFSET * 60};
Timezone myTZ(mySTD, mySTD);

WiFiClient client;                       //创建一个网络对象

String key = "SFYwl_WGlDEUncVhp";   //心知天气的秘钥,可以自己去注册也可以用我的
String weizhi = "zhuhai";        //这里写你的地址

//液晶部分
SSD1306Wire display(0x3c, 5, 4);   //SDA SCL
typedef void (*Demo)(void);


/*====================================画天气图标函数===============================*/
void drawzhongyu() {

  display.drawXbm(drawposition, 0, WiFi_Logo_width, WiFi_Logo_height, zhongyu);

}
void drawdayu() {

  display.drawXbm(drawposition, 0, WiFi_Logo_width, WiFi_Logo_height, dayu);

}
void drawxiaoyu() {

  display.drawXbm(drawposition, 0, WiFi_Logo_width, WiFi_Logo_height, xiaoyu);

}
void drawqingtian() {

  display.drawXbm(drawposition, 0, WiFi_Logo_width, WiFi_Logo_height, qingtian);

}
void drawduoyun() {

  display.drawXbm(drawposition, 0, WiFi_Logo_width, WiFi_Logo_height, duoyun);

}

void drawzhu() {

  display.drawXbm(32, 0, 64, 64, WiFi_Logo_bits);

}
void drawseconds_iconclear() {

  display.drawXbm(0, 40, 24, 24, icon_clear);

}
Demo demos[] = {drawqingtian, drawduoyun, drawxiaoyu, drawzhongyu, drawdayu, drawzhu, drawseconds_iconclear}; //6


/*========================画图部分结束,接下来是数据处理部分=====================*/



void wifi_start_connect()              //连接WIFI
{
  WiFi.mode(WIFI_STA);                 //设置esp8266 工作模式
  Serial.println("Connecting to ");    //写几句提示
  Serial.println(AP_SSID);
  WiFi.begin(AP_SSID, AP_PSK);         //连接wifi
  WiFi.setAutoConnect(true);
  while (WiFi.status() != WL_CONNECTED) //这个函数是wifi连接状态,返回wifi链接状态
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("WiFi connected IP is");
  Serial.println(WiFi.localIP());
}



void parseUserData(String content)
{
  const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + 2 * JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(6) + 210;
  DynamicJsonBuffer jsonBuffer(capacity);

  JsonObject& root = jsonBuffer.parseObject(content);

  JsonObject& results_0 = root["results"][0];


  JsonObject& results_0_now = results_0["now"];
  //const char* results_0_now_text = results_0_now["text"];  // 天气情况
  int results_0_now_code = results_0_now["code"];  //天气情况识别码
  const char* results_0_now_temperature = results_0_now["temperature"];//气温
  

  

  display.setTextAlignment(TEXT_ALIGN_LEFT);
  display.setFont(ArialMT_Plain_24);

  json_temp = results_0_now_temperature;   
   
  json_state = results_0_now_code;
  
}

//调用api函数
void apicmd()
{
 
  if (client.connect("api.seniverse.com", 80) == 1)    //服务连接
  {
    client.print("GET /v3/weather/now.json?key=");
    client.print(key);
    client.print("&location=");
    client.print(weizhi);
    client.print("&language=zh-Hans&unit=c HTTP/1.1\r\n");

    client.print("Host:api.seniverse.com\r\n");
    client.print("Accept-Language:zh-cn\r\n");
    client.print("Connection:close\r\n\r\n");                 //向心知天气的服务器发送请求。


    
    if (client.find("\r\n\r\n") == 1)                         //跳过返回的json数据头,
    {
      String json_from_server = client.readStringUntil('\n'); //读取返回的JSON数据
      Serial.println(json_from_server);                      //打印json数据
      parseUserData(json_from_server);                       //调用josn解析函数,并传参

    }
  }
  else
  {
    Serial.println("服务器连接失败");
    delay(5000);
  }

  client.stop();                                            //关闭HTTP

}

String Middle_minutes;
String Middle_hours;
//时间获取函数
void updateDisplay(void) {

  TimeChangeRule *tcr;        // Pointer to the time change rule

  // Read the current UTC time from the NTP provider
  time_t utc = now();

  // Convert to local time taking DST into consideration
  time_t localTime = myTZ.toLocal(utc, &tcr);

  // Map time to pixel positions
  //int weekdays =   weekday(localTime);
  String days    =  (String) day(localTime);
  String months  = (String) month(localTime);
 // String years   = (String) year(localTime);
 // String seconds = (String) second(localTime);
  String minutes = (String) minute(localTime);
  String hours   = (String) hour(localTime); 

/*串口输出时间
  Serial.println("");
  Serial.print("Current local time:");
  Serial.print(days);
  Serial.print("/");
  Serial.print(months);
  Serial.print("/");
  Serial.print(years);
  Serial.print(" - ");
  Serial.print(hours);
  Serial.print(":");
  Serial.print(minutes);
  Serial.print(":");
  Serial.print(seconds);
  Serial.print(" - ");
  Serial.print(dayStr(weekdays));
  Serial.println("");
*/


  if (Middle_minutes != minutes)
  {
    display.clear();
    display.setTextAlignment(TEXT_ALIGN_LEFT);
    display.setFont(ArialMT_Plain_24);
    Serial.println("调用天气");
    apicmd();
    
    display.drawString(75, 40, json_temp);
    display.drawString(100, 40, "°C");

    display.drawString(10, 5, hours);
    display.drawString(38, 3, ":");
    display.drawString(45, 5, minutes);
    
    判断返回输出图标
    if (json_state == 0)
    {
      demos[0]();
      
    }
    else if (json_state > 0  && json_state < 4)
    {
      demos[0]();
      
    }
    else if (json_state > 3  && json_state < 10)
    {
      demos[1]();
      
    }
    else if (json_state > 9  && json_state < 14)
    {
      demos[2]();
      
    }
    else if (json_state == 14)
    {
      demos[3]();
      
    }
    else if (json_state > 14  && json_state < 19)
    {
      demos[4]();

    }

    display.drawString(0, 40, months);
    display.drawString(27, 40, "/");
    display.drawString(33, 40, days);
    
    
    
    Middle_minutes = minutes;
  }

    display.display();
}


void setup() {
  
  Serial.begin(115200);  
  display.init();
  display.flipScreenVertically();//反向显示
  display.clear();
  demos[5]();
  display.display();
   
  initNTP(AP_SSID, AP_PSK);
 
  
  client.setTimeout(5000);//设置服务器连接超时时间
  

}
time_t previousSecond = 0;
void loop() {


  if (timeStatus() != timeNotSet) {
    if (second() != previousSecond) {
      previousSecond = second();
      updateDisplay();

    }
  }
  delay(1000);


}

https://download.csdn.net/download/cheng592/12253373
怎么上传压缩文件找了半天找不到,在线等挺急的,实在没办法只能用这种土方法了,希望大家多多支持

  • 5
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
使用ESP8266制作一个带有OLED屏幕的温湿度传感器并接入ESPHome是一个非常常见且简单的项目。下面我将提供一种基本的解决方案。 首先,你需要准备以下的物料和工具: - 一个ESP8266开发板(如NodeMCU) - 一个OLED屏幕 - 一个温湿度传感器(如DHT11或DHT22) - 杜邦线(用于连接电路) - 一个电脑(用于编程和调试) 接下来,按照以下步骤进行操作: 步骤1:连接硬件部分 - 将ESP8266板连接到电脑上,并确保其能够正常运行。 - 将OLED屏幕和温湿度传感器与ESP8266板连接。一般来说,你需要将OLED屏幕的SDA引脚连接到ESP8266的D2引脚,SCL引脚连接到D1引脚;将温湿度传感器的数据引脚连接到D3引脚。 步骤2:安装ESPHome软件 - 打开电脑上的命令提示符窗口(或者使用其他的终端软件)。 - 输入以下命令安装ESPHome软件:pip install esphome 步骤3:创建ESPHome配置文件 - 使用任何文本编辑器创建一个新的ESPHome配置文件,并命名为例如"temperature_sensor.yaml"。 - 在配置文件中,你需要指定你的ESP8266板的基本信息(如板名称、WiFi网络和密码)以及传感器的相关信息。 - 根据你使用的OLED屏幕和温湿度传感器型号,你可能需要额外的配置信息,例如OLED屏幕的地址和温湿度传感器的类型。 - 在配置文件中添加一个温度传感器和湿度传感器,以便读取从传感器接收到的数据。 步骤4:编译和上传固件 - 在命令提示符窗口中,导航到你的ESPHome配置文件所在的目录。 - 输入以下命令编译ESPHome固件:esphome temperature_sensor.yaml compile - 编译完成后,输入以下命令将固件上传到ESP8266板上:esphome temperature_sensor.yaml upload 步骤5:监视和调试 - 使用ESPHome监视软件来查看ESP8266板上的日志输出,以确保一切工作正常。 - 当通过串口监视器或ESPHome Dashboard(如果有)收到温湿度数据时,表示你的温湿度传感器和OLED屏幕已经成功接入ESPHome了。 以上就是使用ESP8266制作带有OLED屏幕的温湿度传感器并接入ESPHome的基本步骤。当然,具体的配置和设置取决于你使用的具体硬件和软件版本,你可以根据需要进行调整。希望这些信息对你有所帮助!
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值