【零知ESP8266项目篇】1 OLED天气时钟

2023-10-31

引述:
我们一起学了这么久的零知ESP8266的教程,是不是该检验一下自己了呢?在前面的分享中,有小伙伴留言:太简单!那我就顺水推舟,拔高一下,实践搞个小项目——天气时钟。

到现在为止,作为一个基本的开发者,咱们已经对零知ESP8266有了最基本的了解了,可能你早就按耐不住要做项目了吧!那咱今儿个就做个小项目瞧瞧。继续给我们电子世界的轮廓加一个点。

一、硬件准备
电脑,windows系统
零知ESP8266开发板
OLED SSD1306模块
micro-usb线

二、连线
在这里插入图片描述
在这里插入图片描述

三、软件库
①打开零知开发工具最新版,选中开发板,如图所示:
在这里插入图片描述
②点击库,然后安装以下两个库,如图:
在这里插入图片描述

安装完成后,就可以啦。

四、打开零知开发软件,新建工程,命名weather—station。然后烧写如下代码(已经做好了中文注释,复制粘贴即可):

/*
2019年6月13日13:47:26
by 零知实验室
*/

#include <ESPWiFi.h>
#include <ESPHTTPClient.h>
#include <JsonListener.h>

// time
#include <time.h>                       
#include <sys/time.h>                   
#include <coredecls.h>                  

#include "SSD1306Wire.h"
#include "OLEDDisplayUi.h"
#include "Wire.h"
#include "OpenWeatherMapCurrent.h"
#include "OpenWeatherMapForecast.h"
#include "WeatherStationFonts.h"
#include "WeatherStationImages.h"


/***************************
 * 开始设置
 **************************/

// 这里填写WiFi凭证信息
const char* WIFI_SSID = "WiFi名";
const char* WIFI_PWD = "WiFi密码";

#define TZ              8       // 通用协调时  东八区  北京时间为准
#define DST_MN          60      // 在一些国家依然用夏令时

// Setup
const int UPDATE_INTERVAL_SECS = 20 * 60; // 更新20分钟

// 展示设置
const int I2C_DISPLAY_ADDRESS = 0x3c;

const int SDA_PIN = D3;
const int SDC_PIN = D4;

// OpenWeatherMap设置
// 在此处注册以获取API密钥 
//https://docs.thingpulse.com/how-tos/openweathermap-key/
//也可以在零知实验室官网查看“无线”项目篇中提供账户,获得API密匙
String OPEN_WEATHER_MAP_APP_ID = "3213ac05f30cc2f7d8d8da6d2b03f2e8";  
//得到密匙  下面会有教程
/*
转到https://openweathermap.org/find?q=并搜索位置。 
通过结果设置并选择最接近要显示的实际位置的条目数据 
它将是一个类似于https://openweathermap.org/city/2657896.的链接最后的数字是你分配给下面常量的数字。
 */
String OPEN_WEATHER_MAP_LOCATION_ID = "1795565"; //city:深圳

//从此列表中选择语言代码:
//阿拉伯文-ar,保加利亚语-bg,加泰罗尼亚语-ca,捷克语-cz,德语-de,希腊语-el,
//英语-en,波斯语(波斯语)-fa,芬兰语-fi,法语-fr,加利西亚语-gl,
//克罗地亚语-hr,匈牙利语-hu,意大利语-it,日语-ja,韩语-kr,
//拉脱维亚-la,立陶宛语-lt,马其顿语-mk,荷兰语-nl,波兰语-pl,
//葡萄牙语-pt,罗马尼亚语-ro,俄语-ru,瑞典语-se,斯洛伐克语-sk,
//斯洛文尼亚文-sl,西班牙文-es,土耳其文-tr,乌克兰文-ua,越南文-vi,
//简体中文-zh_cn,繁体中文-zh_tw。
String OPEN_WEATHER_MAP_LANGUAGE = "zh_cn";    //这里选择中文简体。
const uint8_t MAX_FORECASTS = 4;

const boolean IS_METRIC = true;

// 根据你的需要调整语言
const String WDAY_NAMES[] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"}; //每周七天
const String MONTH_NAMES[] = {"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"}; //12个月

/***************************
 * 结束设置
 **************************/
 // 初始化OLED地址
 //  I2C接口:SDA引脚14 SCL引脚12
 SSD1306Wire     display(I2C_DISPLAY_ADDRESS, SDA_PIN, SDC_PIN);  //为OLED创建一个实例display
 OLEDDisplayUi   ui( &display );   //创建一个ui实例 

OpenWeatherMapCurrentData currentWeather;     //创建一个当前天气数据
OpenWeatherMapCurrent currentWeatherClient;   //创建一个当前天气客户端

OpenWeatherMapForecastData forecasts[MAX_FORECASTS];
OpenWeatherMapForecast forecastClient;

#define TZ_MN           ((TZ)*60)
#define TZ_SEC          ((TZ)*3600)
#define DST_SEC         ((DST_MN)*60)
time_t now;

// 标记每10分钟更改一次。
bool readyForWeatherUpdate = false;

String lastUpdate = "--";

long timeSinceLastWUpdate = 0;

//申明原型
void drawProgress(OLEDDisplay *display, int percentage, String label);
void updateData(OLEDDisplay *display);
void drawDateTime(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
void drawCurrentWeather(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
void drawForecast(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
void drawForecastDetails(OLEDDisplay *display, int x, int y, int dayIndex);
void drawHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state);
void setReadyForWeatherUpdate();

//添加框架
//此数组保留指向所有帧的函数指针
//框架是从右向左滑动的单个视图
FrameCallback frames[] = { drawDateTime, drawCurrentWeather, drawForecast };
int numberOfFrames = 3;

OverlayCallback overlays[] = { drawHeaderOverlay };
int numberOfOverlays = 1;

void setup() {
  Serial.begin(115200);
  Serial.println();
  Serial.println();

  // 初始化显示
  display.init();
  display.clear();
  display.display();

  //display.flipScreenVertically();
  display.setFont(ArialMT_Plain_10);
  display.setTextAlignment(TEXT_ALIGN_CENTER);
  display.setContrast(255);

  WiFi.begin(WIFI_SSID, WIFI_PWD);

  int counter = 0;
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    display.clear();
    display.drawString(64, 10, "Connecting to WiFi");
    display.drawXbm(46, 30, 8, 8, counter % 3 == 0 ? activeSymbole : inactiveSymbole);
    display.drawXbm(60, 30, 8, 8, counter % 3 == 1 ? activeSymbole : inactiveSymbole);
    display.drawXbm(74, 30, 8, 8, counter % 3 == 2 ? activeSymbole : inactiveSymbole);
    display.display();

    counter++;
  }
  // 从网络时间服务得到时间
  configTime(TZ_SEC, DST_SEC, "pool.ntp.org");

  ui.setTargetFPS(30);

  ui.setActiveSymbol(activeSymbole);
  ui.setInactiveSymbol(inactiveSymbole);

  // 你可以改变它,
  // 向上(TOP), 向左(LEFT), 向下(BOTTOM), 向右(RIGHT)
  ui.setIndicatorPosition(BOTTOM);

  // 定义第一个帧位于中间的位置
  ui.setIndicatorDirection(LEFT_RIGHT);

  // 你可以更改幻灯片通过
  // 向左滑动(SLIDE_LEFT),向右滑动( SLIDE_RIGHT)向上滑动( SLIDE_TOP), 向下滑动(SLIDE_DOWN)
  ui.setFrameAnimation(SLIDE_LEFT);   //这里填写设置向左滑动,根据上面提供的注释、个人喜好选择

  ui.setFrames(frames, numberOfFrames);

  ui.setOverlays(overlays, numberOfOverlays);

  // Inital UI takes care of initalising the display too.
  ui.init();

  Serial.println("");

  updateData(&display);

}

void loop() {

  if (millis() - timeSinceLastWUpdate > (1000L*UPDATE_INTERVAL_SECS)) {
    setReadyForWeatherUpdate();
    timeSinceLastWUpdate = millis();
  }

  if (readyForWeatherUpdate && ui.getUiState()->frameState == FIXED) {
    updateData(&display);
  }

  int remainingTimeBudget = ui.update();

  if (remainingTimeBudget > 0) {
    //你可以在这里添加一些代码,当然要在下面的remainingTimeBudget(停留时间预算内)
	//否则会出现闪频状态
    delay(remainingTimeBudget);
  }


}

void drawProgress(OLEDDisplay *display, int percentage, String label)   //绘制进度
 {
  display->clear();
  display->setTextAlignment(TEXT_ALIGN_CENTER);
  display->setFont(ArialMT_Plain_10);
  display->drawString(64, 10, label);
  display->drawProgressBar(2, 28, 124, 10, percentage);
  display->display();
}

void updateData(OLEDDisplay *display)   //更新数据
 {
  drawProgress(display, 10, "Updating time...");
  drawProgress(display, 30, "Updating weather...");
  currentWeatherClient.setMetric(IS_METRIC);
  currentWeatherClient.setLanguage(OPEN_WEATHER_MAP_LANGUAGE);
  currentWeatherClient.updateCurrentById(&currentWeather, OPEN_WEATHER_MAP_APP_ID, OPEN_WEATHER_MAP_LOCATION_ID);
  drawProgress(display, 50, "Updating forecasts...");
  forecastClient.setMetric(IS_METRIC);
  forecastClient.setLanguage(OPEN_WEATHER_MAP_LANGUAGE);
  uint8_t allowedHours[] = {12};
  forecastClient.setAllowedHours(allowedHours, sizeof(allowedHours));
  forecastClient.updateForecastsById(forecasts, OPEN_WEATHER_MAP_APP_ID, OPEN_WEATHER_MAP_LOCATION_ID, MAX_FORECASTS);

  readyForWeatherUpdate = false;
  drawProgress(display, 100, "Done...");
  delay(1000);
}



void drawDateTime(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) //绘制数据时间

{
  now = time(nullptr);
  struct tm* timeInfo;
  timeInfo = localtime(&now);
  char buff[16];


  display->setTextAlignment(TEXT_ALIGN_CENTER);
  display->setFont(ArialMT_Plain_10);
  String date = WDAY_NAMES[timeInfo->tm_wday];

  sprintf_P(buff, PSTR("%s, %02d/%02d/%04d"), WDAY_NAMES[timeInfo->tm_wday].c_str(), timeInfo->tm_mday, timeInfo->tm_mon+1, timeInfo->tm_year + 1900);
  display->drawString(64 + x, 5 + y, String(buff));
  display->setFont(ArialMT_Plain_24);

  sprintf_P(buff, PSTR("%02d:%02d:%02d"), timeInfo->tm_hour, timeInfo->tm_min, timeInfo->tm_sec);
  display->drawString(64 + x, 15 + y, String(buff));
  display->setTextAlignment(TEXT_ALIGN_LEFT);
}

void drawCurrentWeather(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y)   //绘制当前天气信息
 {
  display->setFont(ArialMT_Plain_10);
  display->setTextAlignment(TEXT_ALIGN_CENTER);
  display->drawString(64 + x, 38 + y, currentWeather.description);

  display->setFont(ArialMT_Plain_24);
  display->setTextAlignment(TEXT_ALIGN_LEFT);
  String temp = String(currentWeather.temp, 1) + (IS_METRIC ? "°C" : "°F");
  display->drawString(60 + x, 5 + y, temp);

  display->setFont(Meteocons_Plain_36);
  display->setTextAlignment(TEXT_ALIGN_CENTER);
  display->drawString(32 + x, 0 + y, currentWeather.iconMeteoCon);
}


void drawForecast(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y)  //绘制预测信息
{
  drawForecastDetails(display, x, y, 0);
  drawForecastDetails(display, x + 44, y, 1);
  drawForecastDetails(display, x + 88, y, 2);
}

void drawForecastDetails(OLEDDisplay *display, int x, int y, int dayIndex)   //绘制预测明细
 {
  time_t observationTimestamp = forecasts[dayIndex].observationTime;
  struct tm* timeInfo;
  timeInfo = localtime(&observationTimestamp);
  display->setTextAlignment(TEXT_ALIGN_CENTER);
  display->setFont(ArialMT_Plain_10);
  display->drawString(x + 20, y, WDAY_NAMES[timeInfo->tm_wday]);

  display->setFont(Meteocons_Plain_21);
  display->drawString(x + 20, y + 12, forecasts[dayIndex].iconMeteoCon);
  String temp = String(forecasts[dayIndex].temp, 0) + (IS_METRIC ? "°C" : "°F");
  display->setFont(ArialMT_Plain_10);
  display->drawString(x + 20, y + 34, temp);
  display->setTextAlignment(TEXT_ALIGN_LEFT);
}

void drawHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state) //绘制页眉

{
  now = time(nullptr);
  struct tm* timeInfo;
  timeInfo = localtime(&now);
  char buff[14];
  sprintf_P(buff, PSTR("%02d:%02d"), timeInfo->tm_hour, timeInfo->tm_min);
  display->setColor(WHITE);
  display->setFont(ArialMT_Plain_10);
  display->setTextAlignment(TEXT_ALIGN_LEFT);
  display->drawString(0, 54, String(buff));
  display->setTextAlignment(TEXT_ALIGN_RIGHT);
  String temp = String(currentWeather.temp, 1) + (IS_METRIC ? "°C" : "°F");
  display->drawString(128, 54, temp);
  display->drawHorizontalLine(0, 52, 128);
}

void setReadyForWeatherUpdate()     //设置为天气更新准备
{
  Serial.println("Setting readyForUpdate to true");
  readyForWeatherUpdate = true;
}

验证完毕,然后再点击“上传”即可。

代码中获取数据的方法:点击这里

完整工程:weather_station1.7z(若有任何问题,欢迎评论留言)

五、结果
在这里插入图片描述

获取返回结果代码:200表示成功了

如果错误码,可以把地址粘贴到浏览器里看看是什么原因。

在这里插入图片描述
看看视频效果:拂尘~走

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【零知ESP8266项目篇】1 OLED天气时钟 的相关文章

  • JDK8源码阅读(三) java.io.Serializable

    一 类 1 1 类修饰符 A 是一个接口 B 类的可序列化性由实现java io serializable接口的类启用 不实现此接口的类将不具有序列化或反序列化的任何状态 可序列化类的所有子类型本身都是可序列化的 序列化接口没有方法或字段
  • 前端框架——React 学习总结,这篇7000字全解决

    React组件复用 React组件复用 把多个组件中部分功能相似或者相同的状态或者逻辑进行复用 复用 state和操作state的方法 复用的方式 render props模式 高阶组件 HOC render props模式 用childr
  • 网站弹窗公告一天弹窗一次源码简单好看

    介绍 简单好看到爆炸 上传到根目录使用即可 一天只弹一次 使用cookie记录 网盘下载地址 http kekewangLuo net T2ztQxJWt16 图片
  • PACS系统源码 PACS源码 基于VC + MSSQL开发

    基于VC MSSQL开发的一套大型医院医学影像PACS系统源码 有演示 文末获取联系 PACS系统可以覆盖医院现有放射 CT MR 核医学 超声 内镜 病理 心电等绝大部分DICOM和非DICOM检查设备 支持从科室级 全院级 集团医院级乃
  • oschina源码分析之侧滑菜单界面之可以拖动的ScrollView

    先上源码 package net oschina app widget import android annotation SuppressLint import android content Context import android
  • 修改Jar包源码(无需反编译工具)(文章看起来很长,其实方法超级简单!)

    前言 本文结合实际项目案例 介绍修改jar包源码的方式 其中运用了一些小技巧 正文 场景 在项目中用了第三方的jar包 但是jar包某个类的成员变量是private的 想将其改为public属性 以便为其赋值 源码中没有其提供简单的set方
  • 关于PCB走线,铜厚与允许的最大电流之间的关系

    最近在看西安电子科技大学庄奕琪教授的 电子设计可靠性工程 这本书对于电子专业的工程师 学生来说 真的特别实用 其中他并没有提到关于EMC EMI之类的词语 但是关于电磁兼容 电磁屏蔽之类的一些操作都写的非常详细 做笔记做笔记 关于PCB走线
  • 双向可控硅的工作原理

    先看下图的工作原理 如果想简单一点只要记住一句话即可 只要在G端有信号 那么T1 T2这条路就是通的 只有G在零点的时候才不会导通 主要来看一下应用吧 来看我们公司的一个电路图 其实双向可控硅多数用在交流电路中 简单介绍一下 Q5是三极管
  • Arduino IDE将FreeRTOS用于STM32

    介绍 适用于STM32F103C8的FreeRTOS STM32F103C是一种能够使用FreeRTOS的ARM Cortex M3处理器 我们直接在Arduino IDE中开始使用STM32F103C8的FreeRTOS 我们也可以使用K
  • [Hyperf]源码阅读:验证器验证规则

    hyperf validation src Concerns ValidatesAttributes php
  • Vue 源码解读(12)—— patch

    当学习成为了习惯 知识也就变成了常识 感谢各位的 关注 点赞 收藏和评论 新视频和文章会第一时间在微信公众号发送 欢迎关注 李永宁lyn 文章已收录到 github 仓库 liyongning blog 欢迎 Watch 和 Star 前言
  • jdk8源码之Queue-ArrayQueue

    关于队列这个数据结构 大家应该都是比较熟悉 列队是一种先进先出 FIFO 的数据结构 删除操作只能在表的头部 插入操作只能在表的尾部 Queue一般是作为一个缓冲队列使用的 简单举例 生产端的生产速度偶尔会大于消费端的消费速度 但又不想等待
  • #QGIS源码官方编译指南

    QGIS源码官方编译指南 将QGIS官方的编译指南windows部分翻译一下 供大家参考 这个版本是QGIS源代码工程中2017年4月30日最后修改的版本 对应QGIS 2 99 也就是即将发布为QGIS 3 0的版本 翻译 Jacory
  • cmake-3.19.2源码编译与安装

    1 介绍 和 编译环境 1 介绍 cmake是跨平台且开源的编译工具 支持如下7种平台 其他平台不认识没关系 认识linux就行 Microsoft Windows Apple macOS Linux FreeBSD OpenBSD Sol
  • gradle 编译 Spring 源码(亲测有效)

    天知道我今天下午经历了什么 从去年开始断断续续看源码 在 IDEA 中 Spring 源码只读不能写 所以每次都是将方法拷贝到 vscode 中 IDEA 中看代码逻辑 接着在 vscode 对应的方法上写注释 期初这种方式没觉得有什么不便
  • Nacos 1.4.1注册中心源码深度解析-服务下线

    服务下线比较简单 入口在com alibaba nacos naming controllers InstanceController deregister gt serviceManager removeInstance gt remov
  • 什么是医院绩效管理系统?它有哪些功能特点?

    医院绩效 定义 医院工作量绩效方案 是一套以 工作量 RBRVS 相对价值比率 为核算基础 以工作岗位 技术含量 风险程度 服务数量等业绩为主要依据 以工作效率和效益 工作质量 患者满意度等指标为综合考核体系 综合计量和评价的绩效分配体系
  • 医院绩效系统源码:基础数据管理、核算方法和分配规则、KPI评分公式等功能

    医院绩效管理系统源码 医院绩效管理数据采集的自动化和绩效评估数字化 医院绩效管理系统以国家医院绩效管理考核政策法规为依据 结合医院管理实践 以经济管理指标为核心 医疗质量 安全 效率 效益管理为重点 特别强调持续改进 PDCA 管理理念 实
  • 开源Cloudreve云盘系统源码/ 支持本地储存+对接各大对象储存/带云盘系统安装教程/公私兼备网盘系统

    源码介绍 Cloudreve云盘系统源码 它不仅支持本地储存 而且还对接各大对象储存 附带云盘系统安装教程 轻松搭建个人网盘 拥有美观界面 云盘系统安装教程 公私兼备网盘系统 多功能仿百度网盘源码 测试环境 PHP7 1 MYSQL5 6
  • 医院绩效核算系统源码,java语言开发

    医院绩效考核系统全套源码 医院绩效核算系统源码 java语言开发 医院绩效考核系统可根据工作绩效考核管理规定 配置相应的绩效考核模型 从工作量统计 核算维度 核算权重三方面计算工作绩效 利用数据处理和数据分析的支撑作用 实现对工作量统计和绩

随机推荐

  • 遥感影像分类方法

    最初的遥感影像分类是通过目视解译 濮静娟 1984 来完成的 对研究人员的主观意识有较强的依赖性 而且效率较低 适用于数据量较小的情况 通常作为其他方法对比的对象 目前的遥感图像分类主要以计算机分类为主 因此按照人工参与的程度可以将分类方法
  • jenkins系列教程

    jenkins系列教程
  • echarts之横式柱状图

    echarts之横式柱状图 文末有完整代码 可以直接复制使用 效果图 原理 设置x轴为不显示 只显示y轴 设置两个y轴 一个显示柱子 另一个只显示柱子的边框 通过设置两个y轴柱子的层次度 使得看起来像是一个柱子 该实例是在官方例子的基础上修
  • CSS设置滚动条不可见,但可以滚动

    在一个固定窗口内我们做一个可滚动的菜单的时候经常会出现很宽的滚动条 不仅影响美观而且影响布局 解决办法就是在它的外层再套一个div并且设置为overflow heidden 子元素设置overflow y x scroll 并给够足够的宽度
  • 函数指针与指针函数区别

    简述 最近看到安森美芯片的boot的部分代码 如下 写的不易观看 可能C萌新 不易理解 这涉及到指针函数 函数指针的相关概念 typedef enum BOOTROM ERR NONE 0x0 BOOTROM ERR BAD ALIGN 0
  • 频繁FullGc排查思路

    现象 通过监控系统平台告警感知到 某应用某IP在某段时间内出现FullGC FullGC的过程伴随着STW 如果过于频繁 将会导致用户体验极具下降 FullGC的出现经常伴随老年代空间被打满的情况 可以通过监控视图来观测到 当前统一使用CM
  • cs186 学习笔记

    书籍准备利用数据库系统概念 用课程参考资料和题 课程网站 答案 HW0 主要是后面会用到的一些配置 Docker Git Box 课程建议说多备份 Box是本地备份 Git是远程的 都不太会 需要先把这些看完 HW1
  • ubuntu下查看软链接

    工作笔记 以python为例 以root用户进入 usr bin 目录 找到python 可以看到python被链接到python2 7这个执行程序上 建立新的软链接 ln s 源文件 目标文件 删除 rm rf 链接名 转载于 https
  • python求素数

    口求100内的素数 个数能被从2开始到自己的平发根的正整数整数整除 就是合数 import math n 100 for X in range 2 n for i in range 2 math ceil math sqrt x if x
  • 追梦路上—记这一年的自己

    这一年的文字 借这个总结的机会将自己的博客总结 2014年9月 2015年9月 看了一遍 既是在回顾总结 也是在看自己这一年的成长变化 B S系列 牛腩新闻发布系统 只写了一篇关于发布网站和分页的总结 现在回去看 感觉价值不是很大 贴了很详
  • 如何实现小型WEB搜索引擎(C#+SQL Server全文检索+Asp.net)

    1 引言 21世纪 中国互联网搜索引擎领域可谓群雄逐鹿 百度 Yahoo 中搜 搜狗等等都使出浑身解数吸引着网民的眼球 这些大网站可谓是各有所长 总的来说虽然他们搜索功能都很强 但是搜索得到的结果基本上是千篇一律 信息的冗余量很大 网民不得
  • jenkins持续集成源码管理选项为None,构建失败找不到git.exe解决办法

    我的jenkins版本为Jenkins ver 2 19 1 1 源码管理选项只有None的解决办法 在插件管理中心 搜索对应的源码管理插件这里以git为例 搜索git plugin点击右下角的安装方式 在线安装需要连接VPN你懂的 如下图
  • 查询按键控制数码管的显示

    一 仿真电路图 二 c语言代码 include at89x51 h unsigned int j unsigned char i k cz unsigned char code a 0x3f 0x06 0x5b 0x4f 0x66 0x6d
  • 10 个用于 Linux 的开源轻量级 Web 浏览器

    导语 在一些快速对比之后 本文发现了一些适用于 Linux 的轻量级 Web 浏览器 推荐给大家 希望大家有所裨益 不过需要注意的是 文章所提及的浏览器并没有做过任何基准测试 因此适用于 Linux 系统的东西可能不适用于其他系统 作者 M
  • 实际生产环境Apache RocketMQ消息体过大的解决方案

    前言 官方定义消息体默认大小为 4MB 普通顺序消息类型 事务 定时 延时类消息默认大小为64KB 如果超过限制则会抛出异常 但实际工作中 需要使用到MQ进行异步解耦 传输的业务消息偶尔会遇到超过4MB 尤其在业务复杂的系统中 那么我们应该
  • 牛客网笔试输入输出的一堆坑。。(Python)

    牛客网笔试的时候Python的输入输出是真的很坑 有时候线下自测案例是正常的 线上却怎么都调不过去 这里简单记录一下 一 常见输入输出的写法 1 input 直接使用input 读取回来的是字符串 比如输入为 abds n就为 abds n
  • Ubuntu 18.04 的安装及基础操作流程

    目录 一 Ubuntu 的安装及设置网络参数 1 Ubuntu 的安装 2 设置网络参数 二 将apt get源更换为清华源 1 备份原文件 输入sudo cp etc apt sources list etc apt sources li
  • 天天给 App 抓包,还不懂 HTTP 代理吗?

    一 序 今天来和大家一起聊聊 HTTP 代理 在 HTTP 协议中 最基础的就是请求和响应的报文 而报文又由报文头和报文实体组成 大多数 HTTP 协议的使用场景 都是依赖设置不同的 HTTP 请求 响应 的 Header 来实现的 既然要
  • CTO、技术总监和技术经理有啥区别?

    最近朋友圈上被CTO的故事刷的满屏都是 着实又火了一次 大概是某个C轮融资的医疗网站CTO被离职 而CTO是一个知乎大V和微信大号 此事一出 在微信群有支持也有反对之声 支持此CTO被离职的认为其在工作时没有Review程序 自己不写代码
  • 【零知ESP8266项目篇】1 OLED天气时钟

    引述 我们一起学了这么久的零知ESP8266的教程 是不是该检验一下自己了呢 在前面的分享中 有小伙伴留言 太简单 那我就顺水推舟 拔高一下 实践搞个小项目 天气时钟 到现在为止 作为一个基本的开发者 咱们已经对零知ESP8266有了最基本