WiFi 时钟

news2024/11/20 9:34:02

WiFi 时钟有很多开源项目的。但是,成品往往代码一大篇,看起来有些上头。加上有些库和环境的版本变迁,编译报错排查起来很是费劲。于是从头捋一遍,一步一步的过程,容易上手:

准备工作:

a 零件:只需要用到 ESP8266 和 OLED 各一个。

b 开发环境:arduino_1.8.19 + ESP8266_3.0.2 ,这是我当前使用的,其他高一些的应该也行,没测试

制作步骤:

1. 首先需要保证OLED能够亮起来

#include <U8g2lib.h>
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(/*默认R0,R2为旋转180°*/U8G2_R2, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ 4, /* data=*/ 0);  

void setup(){
  pinMode(16,OUTPUT);digitalWrite(16,HIGH); // OLED供电
  pinMode(5,OUTPUT);digitalWrite(5,LOW);    // OLED供电    
  Serial.begin(115200);  
  u8g2.begin();
  u8g2.enableUTF8Print();                   // 启用中文显示,但库不全
  oledClockDisplay();
}

void loop(){    
}

void oledClockDisplay(){
  u8g2.clearBuffer();      
    u8g2.setCursor(0, 47);u8g2.setFont(u8g2_font_logisoso42_tr);u8g2.print("18:56");   
    u8g2.setCursor(54,35);u8g2.setFont(u8g2_font_unifont_t_chinese2);u8g2.print("34");   
    u8g2.setCursor(0, 64);u8g2.setFont(u8g2_font_unifont_t_chinese2);u8g2.print("2023/04/01");  
    u8g2.print("星期六");
  u8g2.sendBuffer();
}

上面的代码可以让OLED显示出一个静止的时钟,但是星期六三个汉字只有“期”能显示出来,这是因为U8G2库的原生中文字库很小,“星”、“六”这两字没有。

这个布局花了点心思,42号时能够显示全的最大号字体,把“秒”放在冒号中间,需要读秒也能看到。

#include <U8g2lib.h>
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(/*默认R0,R2为旋转180°*/U8G2_R2, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ 4, /* data=*/ 0);  

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
};  

void setup(){
  pinMode(16,OUTPUT);digitalWrite(16,HIGH); // OLED供电
  pinMode(5,OUTPUT);digitalWrite(5,LOW);    // OLED供电    
  Serial.begin(115200);  
  u8g2.begin();
  u8g2.enableUTF8Print();                   // 启用中文显示,但库不全
  oledClockDisplay();
}

void loop(){    
}

void oledClockDisplay(){
  u8g2.clearBuffer();      
    u8g2.setCursor(0, 47);u8g2.setFont(u8g2_font_logisoso42_tr);u8g2.print("18:56");   
    u8g2.setCursor(54,35);u8g2.setFont(u8g2_font_unifont_t_chinese2);u8g2.print("34");   
    u8g2.setCursor(0, 64);u8g2.setFont(u8g2_font_unifont_t_chinese2);u8g2.print("2023/04/01");  
    u8g2.drawXBM(80, 49, 16, 16, xing);
    u8g2.setCursor(95, 63);u8g2.print("期");
    u8g2.drawXBM(111, 49, 16, 16, liu);
  u8g2.sendBuffer();
}

 u8g2.drawXBM 以图片方式显示汉字, 这样显示部分调试就算完成了。

2. 让时钟走起来

这时需要用到 TimeLib.h 这个库

#include <U8g2lib.h>
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(/*默认R0,R2为旋转180°*/U8G2_R2, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ 4, /* data=*/ 0);  

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
};  

#include <TimeLib.h>
time_t currentDisplayTime = 0; 

void setup(){
  pinMode(16,OUTPUT);digitalWrite(16,HIGH); // OLED供电
  pinMode(5,OUTPUT);digitalWrite(5,LOW);    // OLED供电    
  Serial.begin(115200);  
  u8g2.begin();
  u8g2.enableUTF8Print();                   // 启用中文显示,但库不全
  oledClockDisplay();
}

void loop(){   
  if (now()!= currentDisplayTime){ 
    currentDisplayTime = now();
    oledClockDisplay();
  } 
}

void oledClockDisplay(){
  int years = year();
  int months = month();
  int days = day();
  int hours = hour();
  int minutes = minute();
  int seconds = second();
  int weekdays = weekday();
  Serial.printf("%d/%d/%d %d:%d:%d Weekday:%d\n", years, months, days, hours, minutes, seconds, weekdays);
  String currentTime = "";
    if (hours < 10)currentTime += 0;currentTime += hours;currentTime += ":";
    if (minutes < 10)currentTime += 0;currentTime += minutes;currentTime += ":";
  String currentDate = "";
    currentDate += years;currentDate += "/";
    if (months < 10)currentDate += 0;currentDate += months;currentDate += "/";
    if (days < 10)currentDate += 0;currentDate += days;
  String s="";  if (seconds < 10)s += 0;s += seconds;             // 单独把秒字符串拿出来以小字体显示在冒号处
  
  u8g2.clearBuffer();      
    u8g2.setCursor(0, 47);u8g2.setFont(u8g2_font_logisoso42_tr);u8g2.print(currentTime);   
    u8g2.setCursor(54,35);u8g2.setFont(u8g2_font_unifont_t_chinese2);u8g2.print(s);   
    u8g2.setCursor(0, 64);u8g2.setFont(u8g2_font_unifont_t_chinese2);u8g2.print(currentDate);  
    u8g2.drawXBM(80, 49, 16, 16, xing);
    u8g2.setCursor(95, 63);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();
}

 因为还没有添加对时代码,这个时钟是从1970/1/1 00:00 开始走的。

下面 利用 __TIME__ 这个常量,把PC的时钟写入到ESP8266,只要不断电,这个时钟还算不错,但要做到断电时间不停摆,需要DS1302之类的带电池的RTC模块, 不过ESP8266有WiFi,能从网络获取NTP时间。

#include <U8g2lib.h>
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(/*默认R0,R2为旋转180°*/U8G2_R2, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ 4, /* data=*/ 0);  

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
};  

#include <TimeLib.h>
time_t currentDisplayTime = 0; 

void setup(){
  pinMode(16,OUTPUT);digitalWrite(16,HIGH); // OLED供电
  pinMode(5,OUTPUT);digitalWrite(5,LOW);    // OLED供电    
  Serial.begin(115200);  
  u8g2.begin();
  u8g2.enableUTF8Print();                   // 启用中文显示,但库不全
  oledClockDisplay();

  int yy = 2023;                            // 年月日可以从常量 __DATE__ 中获得,这里暂不处理,只处理时间,以演示 setTime 用法,后续用网络同步即可
  int mm = 4;  
  int dd = 19;
  int HH = (int(__TIME__[0])-48)*10 + int(__TIME__[1])-48;    // 0 的 ascii 48
  int MM = (int(__TIME__[3])-48)*10 + int(__TIME__[4])-48;
  int SS = (int(__TIME__[6])-48)*10 + int(__TIME__[7])-48;
  setTime(mktime(yy,mm,dd,HH,MM,SS)+30); 
  //setTime(1357041600);                    // 从1970-1-1开始至今的秒数 1357041600 = Jan 1 2013
  //setTime(mktime(2023,4,19,17,42,00));    // 从日期计算秒数
}

void loop(){   
  if (now()!= currentDisplayTime){ 
    currentDisplayTime = now();
    Serial.println(currentDisplayTime);    // 输出为 1681868855 这样的 Epoch 时间 https://www.epochconverter.com/
    oledClockDisplay();
  } 
}

void oledClockDisplay(){
  int years = year();
  int months = month();
  int days = day();
  int hours = hour();
  int minutes = minute();
  int seconds = second();
  int weekdays = weekday();
  Serial.printf("%d/%d/%d %d:%d:%d Weekday:%d\n", years, months, days, hours, minutes, seconds, weekdays);
  String currentTime = "";
    if (hours < 10)currentTime += 0;currentTime += hours;currentTime += ":";
    if (minutes < 10)currentTime += 0;currentTime += minutes;currentTime += ":";
  String currentDate = "";
    currentDate += years;currentDate += "/";
    if (months < 10)currentDate += 0;currentDate += months;currentDate += "/";
    if (days < 10)currentDate += 0;currentDate += days;
  String s="";  if (seconds < 10)s += 0;s += seconds;             // 单独把秒字符串拿出来以小字体显示在冒号处
  
  u8g2.clearBuffer();      
    u8g2.setCursor(0, 47);u8g2.setFont(u8g2_font_logisoso42_tr);u8g2.print(currentTime);   
    u8g2.setCursor(54,35);u8g2.setFont(u8g2_font_unifont_t_chinese2);u8g2.print(s);   
    u8g2.setCursor(0, 64);u8g2.setFont(u8g2_font_unifont_t_chinese2);u8g2.print(currentDate);  
    u8g2.drawXBM(80, 49, 16, 16, xing);
    u8g2.setCursor(95, 63);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();
}

/* ----------------- 当前到1970-1-1 的秒数 https://blog.csdn.net/weixin_46935110/article/details/124325951 ------------*/
long mktime (int year, int mon, int day, int hour, int min, int sec){
    if (0 >= (int) (mon -= 2)){mon += 12;year -= 1;} 
    return ((((unsigned long) (year/4 - year/100 + year/400 + 367*mon/12 + day) + year*365 - 719499)*24 + hour)*60 + min)*60 + sec; 
}

3. 网络对时

先直接上代码,注意需要修改 “WiFi.begin("SSID", "PASSWORD");” 这一行

用到了 NTPClient.h 这个库,在线对时的代码很简洁了。

整个代码里,几十行都是显示相关语句,还有几十行头文件,初始化这些固定操作,真正体现程序逻辑的是 loop 里面的3行,以及函数 getNtpTime 里面的4行, 理解起来应该很清晰了。

#include <U8g2lib.h>
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(/*默认R0,R2为旋转180°*/U8G2_R2, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ 4, /* data=*/ 0);  

#include <TimeLib.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <NTPClient.h>
WiFiUDP Udp;
NTPClient timeClient(Udp, "cn.pool.ntp.org"); //ntp1.aliyun.com
time_t currentDisplayTime = 0;    

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
};   

void setup(){
  pinMode(16,OUTPUT);digitalWrite(16,HIGH); // OLED供电
  pinMode(5,OUTPUT);digitalWrite(5,LOW);    // OLED供电
    
  Serial.begin(115200);
  
  u8g2.begin();
  u8g2.enableUTF8Print();                   // 启用中文显示,但库不全
  
  WiFi.begin("SSID", "PASSWORD");
  Serial.print("\n\n\nConnecting WiFi");    // ESP8266复位有很多乱码,换几行再显示
  while (WiFi.status()!= WL_CONNECTED){delay(1000);Serial.print(".");}
  Udp.begin(8888);                          // UDP 侦听端口,任意指定
  setSyncProvider(getNtpTime);
  setSyncInterval(60);                      // NTP网络同步间隔时间,单位秒
}

void loop(){
  if (now()!= currentDisplayTime){ 
    currentDisplayTime = now();
    oledClockDisplay();
  }
}

/*---------------- 刷新显示 ------------------*/
void oledClockDisplay(){
  int years = year();
  int months = month();
  int days = day();
  int hours = hour();
  int minutes = minute();
  int seconds = second();
  int weekdays = weekday();
  Serial.printf("%d/%d/%d %d:%d:%d Weekday:%d\n", years, months, days, hours, minutes, seconds, weekdays);
  String currentTime = "";
    if (hours < 10)currentTime += 0;currentTime += hours;currentTime += ":";
    if (minutes < 10)currentTime += 0;currentTime += minutes;currentTime += ":";
  String currentDate = "";
    currentDate += years;currentDate += "/";
    if (months < 10)currentDate += 0;currentDate += months;currentDate += "/";
    if (days < 10)currentDate += 0;currentDate += days;
  String s="";  if (seconds < 10)s += 0;s += seconds;             // 单独把秒字符串拿出来以小字体显示在冒号处
  
  u8g2.clearBuffer();      
    u8g2.setCursor(0, 47);u8g2.setFont(u8g2_font_logisoso42_tr);u8g2.print(currentTime);   
    u8g2.setCursor(54,35);u8g2.setFont(u8g2_font_unifont_t_chinese2);u8g2.print(s);   
    u8g2.setCursor(0, 64);u8g2.setFont(u8g2_font_unifont_t_chinese2);u8g2.print(currentDate);  
    u8g2.drawXBM(80, 49, 16, 16, xing);
    u8g2.setCursor(95, 63);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 代码 ------------------*/
time_t getNtpTime(){
  Serial.print("\nSync...");
  if(timeClient.update())Serial.println("Success!");    // 串口打印同步成功与否 0 失败 1 成功
  else Serial.println("Failed!");    
  return(timeClient.getEpochTime()+28800);              // GMT+8, 3600*8
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/450889.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Netty源码解读

Netty源码解读 Netty线程模型 1、定义了两组线程池BossGroup和WorkerGroup&#xff0c;BossGroup专门负责接收客户端的连接, WorkerGroup专门负责网络的读写 2、BossGroup和WorkerGroup类型都是NioEventLoopGroup&#xff0c;Group中维护了多个事件循环线程NioEventLoop&#…

AI新产品层出不穷,学不过来怎么办。

最近各个互联网巨头和创业新贵发布的AI工具&#xff0c;AI模型层出不穷&#xff0c;相关自媒体的热度也都很高&#xff0c;当然&#xff0c;各种大佬的隔空喊话也是非常吸引眼球&#xff0c;那么很多人就会觉得&#xff0c;要看的东西太多了&#xff0c;要学的东西太多了&#…

【数据结构】顺序表详解(附leetcode练习题)

☃️个人主页&#xff1a;fighting小泽 &#x1f338;作者简介&#xff1a;目前正在学习C语言和数据结构 &#x1f33c;博客专栏&#xff1a;数据结构 &#x1f3f5;️欢迎关注&#xff1a;评论&#x1f44a;&#x1f3fb;点赞&#x1f44d;&#x1f3fb;留言&#x1f4aa;&…

Java编译器插件Manifold(流形)

流形 文天祥正气歌中有云&#xff1a;“天地有正气&#xff0c;杂然赋流形”。 流形是一种抽象而又具体的事务&#xff0c;要研究一个事务就要格物&#xff0c;不格物就不能知道事物的具体描绘形式。流形大多数情况下是一种数学计算方式&#xff0c;可以将一个复杂的模型抽象…

Matplotlib Pyplot

Pyplot 是 Matplotlib 的子库&#xff0c;提供了和 MATLAB 类似的绘图 API。 Pyplot 是常用的绘图模块&#xff0c;能很方便让用户绘制 2D 图表。 Pyplot 包含一系列绘图函数的相关函数&#xff0c;每个函数会对当前的图像进行一些修改&#xff0c;例如&#xff1a;给图像加上…

ChatGPT | 申请与使用new bing的实用教程

1. 教程参考&#xff1a; https://juejin.cn/post/7199557716998078522 2.在参考上述教程遇到的问题与解决 2.1 下载dev浏览器的网址打不开 egde dev下载地址&#xff08;上面网站上的&#xff09;我电脑打不开 换用下面的网址即可 https://www.microsoftedgeinsider.com/z…

给定一个正整数字符串,使用Python正则表达式在其千分位上添加逗号

点击上方“Python爬虫与数据挖掘”&#xff0c;进行关注 回复“书籍”即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 楼阁玲珑五云起&#xff0c;其中绰约多仙子。 大家好&#xff0c;我是皮皮。 一、前言 前几天在Python黄金青铜群【沐】问了一个Python正则表达式的问题…

MySQL开发工具评测,包含了Navicat、DBeaver、SQL Studio等12种

面对五花八门的MySQL客户端,开发者该如何选择,今天我整理了12种MySQL开发工具,从产品体验,功能完整度,云适配,计费模式,OS先容性等多个角度进行评估与分析,大家可根据自己的实际情况选择![在这里插入图片描述](https://img-blog.csdnimg.cn/56bdfc89afe743b9b87477d7c0521023.p…

SAP KANBAN 从入门到放弃系列之调拨模式

之前已经有三篇文章写了后台配置相关的介绍&#xff0c;这里不赘述。详见&#xff1a; PP-KANBAN-看板概述 SAP KANBAN 从入门到放弃系列之生产补货模式 SAP KANBAN 从入门到放弃系列之采购补货模式 第一步&#xff1a;补货策略-转库。不同的补充策略的控制类型有不同的作用…

【vue2 pc端】下拉滑动加载更多 vue-data-loading

官网地址 页面项目中使用 <template><!-- 空数据时显示 --><div class"nonono"><img src"/assets/img/404_cloud.png" alt"" v-if"goodslist.length < 0" class"nonnonoimg"></div>&…

燃气管道定位83KHZ地下电子标识器探测仪ED-8000操作指南

1、电子标识器探测工作 燃气管道定位83KHZ地下电子标识器探测仪ED-8000&#xff0c;探测时周边 3 米范围内不能有其他探测仪&#xff0c;保持探测仪垂直向 下&#xff0c;探测仪的末端距离地面 5~10cm 左右&#xff0c;延估计的埋地管线走向水平移动探测仪。当发现持续信号且信…

反射-Class类分析

反射相关的主要类 java.lang.Class&#xff1a;代表一个类&#xff0c;Class对象表示某个类加载后在堆中的对象java.lang.reflect.Method&#xff1a;代表类的方法&#xff0c;Method对象表示某个类的方法java.lang.reflect.Field&#xff1a;代表类的成员变量&#xff0c;Fie…

有手就行——基础XGBoost实战以 iris 数据集为例

基础 XGBoost 实战以 iris 数据集为例 1、导入数据2、数据预处理3、分训练集和测试集4、训练模型构建5、测试集预测准确度6、构建混淆矩阵7、特征重要性 对于很多只是小小使用机器学习&#xff0c;而不是深入了解的人来说&#xff0c;了解各种原理可能是十分痛苦的&#xff0c;…

Gnuplot绘图入门2 快捷方式

Gnuplot绘图入门2——根据多列文本数据绘制图形 Gnuplot绘图入门1以绘制sin(x)的函数图形为例&#xff0c;对Gnuplot进行了简要介绍。这个教程将介绍如何使用Gnuplot对保存在文本文件&#xff08;.txt、.dat文件&#xff09;中的数据进行可视化。 将下面的数据复制下了&#…

Linux安装Nginx,源码安装及创建软连接

前言 Nginx是一个功能强大、高性能、可扩展、易用和安全的Web服务器和反向代理服务器&#xff0c;被广泛应用于企业级和互联网领域 可扩展性&#xff1a;Nginx可以通过添加各种模块和插件来扩展其功能&#xff0c;包括HTTP流控制、SSL加密、压缩和解压缩、访问控制等。 高可靠…

项目设计:迷宫游戏设计day3

一、界面制作 我用的easyx实现图形化界面&#xff0c;在制作第一个界面的时候&#xff0c;第一个界面的功能有开始游戏&#xff0c;退出游戏&#xff0c;排行榜&#xff08;虽然还没实现&#xff09; 那么首先还是得用一个图片贴在上面&#xff0c;这个图片是我自己画的&#…

20230419 生物基础学习- 氨基酸-密码子-突变

文章目录 名称形状密码子-氨基酸对应表简明中文英文和简称突变类型生物化学课程笔记特殊氨基酸的性质缬氨酸和甲硫氨酸 染色体 - RNA - 蛋白质 名称 Phenylalanine,Leucine,Isoleucine,Methionine,Valine,Serine,Proline,Threonine,Alanine,Tyrosine,Histidine,Glutamine,Aspa…

「 计算机网络 」HTTP和RPC的区别与联系

「 计算机网络 」HTTP和RPC的区别与联系 参考&鸣谢 HTTP 和 RPC 的区别 小十七_ Http协议和Rpc协议有什么区别&#xff1f; 俗人杂念 为什么要自研RPC框架&#xff1f;HTTP和RPC的区别 starine 既然有HTTP协议&#xff0c;为什么还要有RPC 小白debug 文章目录 「 计算机网络…

工装识别工装检测系统 yolov7

工装识别工装检测系统通过yolov7python网络模型算法智能分析技术&#xff0c;工装识别工装检测系统对现场人员是否穿戴的进行实时分析&#xff0c;发现现场画面人员未按要求着装&#xff0c;系统会自动抓拍发出警报并讲违规图片视频保存下来&#xff0c;同步回传后台提醒监理人…

uniapp调用七牛云api实现文件上传-node.js向外提供uploadToken的接口-客户端不用下载七牛云的包和SDK-发起网络请求直接上传

uniapp调用七牛云api实现文件上传 实现思路&#xff1a; 1.使用node.js向客户端提供uploadToken&#xff0c;客户端获取uploadToken后使用七牛云的api接口发起网络请求&#xff0c;上传文件&#xff1b; node.js向外提供uploadToken的接口-客户端不用下载七牛云的包和SDK-&…