一、开发板资源

HELLO WORLD

串口打印

选编译并下载固件(右箭头)

下载成功后按复位按钮运行程序

生成bin文件,下载固件

用 Arduino IDE 生成一个工程的 bin 文件,然后用 ESPFlashDownloadTool 下载固件。

先点导出 bin 文件


打开 ESPFlashDownloadTool ,选择刚导出的bin文件和bootloader , default文件,填写好地址和参数,点击下载。

Arduino ESP32 开发环境的文件结构

Core 文件夹:乐鑫提供的 ESP32 底层内核文件,包括 gpio timer iic spi touch uarts 等外设驱动,还有二次封装好的 TCP UDP Server 等常用 arduino 库文件。
libraries 文件夹:包含各厂家的 arduino 例程,我们的例程文件夹是 ESP-32F
variants 文件夹:各种 esp32 开发板的引脚定义头文件 (如果需要添加的自己开发板,则需 要在该文件夹内加入自己开发板的引脚定义头文件,添加方法可以参考其他开发板的头文 件,依样画葫芦即可)
Tools 文件夹:esp32 sdk 和编译工具链
Boards.txt:定义开发板的各项参数,这些参数将会在 arduino ide 选择开发板型号和参数的 面板中体现出来

实验

实验 1:驱动 RGB

steup 函数相当于 main 函数 ,程序从这里开始
void setup() {
// put your setup code here, to run once:
}
Loop 函数相当予 while(1){} 函数,
void loop() {
// put your main code here, to run repeatedly:
}
delay(x); arduino 系统延时函数 延时 x 毫秒
rand() 随机数函数,rand()%2 代表 0-1 这两个数取随机数

void setup() {// put your setup code here, to run once:pinMode(32,OUTPUT);pinMode(33,OUTPUT); pinMode(27,OUTPUT);//IO27 IO32 IO33 三个引脚设置为输出模式
}void loop() {// put your main code here, to run repeatedly:digitalWrite(32,rand()%2); //三个 LED 随机点亮,组成不同的颜色 digitalWrite(33,rand()%2); digitalWrite(27,rand()%2); delay(1000);//延时 1000ms
}



实验 2:Serial 的使用

Arduino 串口通讯会用到 Stream 这个类,Stream 类是二进制数据或者字符串数据流传输的基础类,不能被直接调用,但可以被继承。

available()获取数据流中接收到的字节数,返回值是 int 类型。
read()获取数据流中第一个字节数据,获取数据后会清除当前字节数据。返回值是 读取数据字符的第一个字节(8bit)
peek()从数据流中读取当前的一个字节,不会清除数据流中当前字节数据
flush()清除数据流所有未向外发送的数据。返回bool 类型。
find() 从数据流中查找目标字符串,找到目标字符串后返回值 = true,超时则返回值 = false。
findUntil() 从数据流中读取目标字符串或者终止目标字符串,找到目标字符串后返回值 = true,超时则返回值 = false。
Serial 类 用于对串口数据流的读写。

String buf;
char temp;
void setup() {// put your setup code here, to run once: Serial.begin(115200); Serial.setTimeout(10);//设置串口接收超时时间 10ms (如果不明白可以改成 1000 ,用串 口助手看效果) Serial.println("Goouuu HelloWorld!"); }void loop() { // put your main code here, to run repeatedly:if(Serial.available()!=0)//如果接收缓冲区非空 { buf=Serial.readString();//将收到的数据以字符串形式存到 buf Serial.print(buf);//串口打印 buf } }}
}

如图,串口正常打印输入信息。

实验3:触摸按键

ESP-32F 开发板上的触摸通道是用了 T0(IO4) 和 T2(IO2)

uint16_t touchRead(uint8_t pin); 获取某个通道采集的数值。

// Just test touch pin - Touch0 is T0 which is on GPIO 2.
int T0_Cul=0;
int T2_Cul=0;
void LED_Init(void)//LED 初始化
{ pinMode(33,OUTPUT);pinMode(27,OUTPUT);
}
void setup()
{ LED_Init(); Serial.begin(115200); Serial.println("ESP32 Touch Test");
}
void Touch_Pad_Check(void)
{ Serial.print("T0_Value:"); Serial.println(touchRead(T0)); // get value using T0 T0_Cul=touchRead(T0); Serial.print("T2_Value:"); // get value using T2 Serial.println(touchRead(T2)); //T2_Cul=touchRead(T2);if(T0_Cul<=15)//通道采集数值低于 15 被认为按键按下 { digitalWrite(33,0);//点亮 LEDA}else if(T0_Cul>20)//通道采集数值高于 20 被认为按键被释放 {digitalWrite(33,1);//熄灭 LEDA }if(T2_Cul<=15){digitalWrite(27,0); }else if(T2_Cul>20){digitalWrite(27,1); }
}
void loop()
{ Touch_Pad_Check();
}


当我按住触摸按键 T1 不放时,T0 通 道输出值都是保持在 15 以下,这时候这个通道触发的阀值就很清楚了。此时LED点亮。

if(T0_Cul<=15)//通道采集数值低于 15 被认为按键按下
{ digitalWrite(33,0);//点亮 LEDA
}


实验 4:定时器

hw_timer_t *timer=NULL;//创建一个定时器结构体
volatile SemaphoreHandle_t timerSemaphore;//创建一个定时器信号量
int time_count=0;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
void IRAM_ATTR Timer_Hander()
{
portENTER_CRITICAL_ISR(&timerMux);//进入临界段
time_count++;
portEXIT_CRITICAL_ISR(&timerMux);//退出临界段
xSemaphoreGiveFromISR(timerSemaphore, NULL);//释放一个二值信号量 timerSemaphore
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
timerSemaphore=xSemaphoreCreateBinary();//定义信号量
timer = timerBegin(0, 80, true);//初始化定时器 0 80 分频 向上计数 // 配置定时器中断函数
timerAttachInterrupt(timer, &Timer_Hander, true);
// Set alarm to call onTimer function every second (value in microseconds).
// Repeat the alarm (third parameter)
timerAlarmWrite(timer, 5000000, true);//每计数 5000000 次触发定时器中断 自动重载开启
// Start an alarm
timerAlarmEnable(timer);//使能定时器函数
}
void loop() {
// put your main code here, to run repeatedly:收到定时器触发后置位的二值信号量后打印 计数值if (xSemaphoreTake(timerSemaphore,0) == pdTRUE){ portENTER_CRITICAL_ISR(&timerMux); Serial.println(millis());//打印系统已经运行了多少时间 Serial.println(time_count);//计数值 portEXIT_CRITICAL_ISR(&timerMux); }
}

串口打印系统程序已经运行的时间和定时器计数的次数。

实验 5:读取 DHT11 温湿度传感器

DHT11 输出两个字节湿度数据,两个字节温度数据 ,一个校验字节,共五个字节。

建立自己封装的 c++类库

1.点击下拉箭头 新建标签,输入文件名 xxx.cpp 后确定。

构造函数:

在类实例化对象时自动执行,对类中的数据进行初始化

构造函数可以从载,可以有多个, 但是只能有一个缺省构造函数。

构造函数必须和类同名 。

析构函数:

撤销对象占用的内存之前,进行一些操作的函数。

析构函数不能被重载,只能有一个。

析构函数如果我们不写的话,C++ 会帮我们自动的合成一个,C++ 会自动的帮我们写一个析构函数。自动生成的析构函数可以很好的工作,但是一些重要的事迹, 就必须我们自己去写析构函数。

析构函数和构造函数是一对。构造函数用于创建对象,而析构函数是用来撤销对象。一个对象出生的时候,使用构造函数,死掉的时候,使用析构函数。
定义
类名::方法名

实验 6:ADC 采集 GP2Y1014AU 粉尘传感器

ESP32 ADC 库函数

void analogSetSamples(uint8_t samples); 设置分频 1-255
bool adcAttachPin(uint8_t pin); 设置 ADC 采集引脚
uint16_t analogRead(uint8_t pin); 读取 ADC 通道值
bool adcStart(uint8_t pin); 开始 ADC 采集

GP2Y1014AU 粉尘传感器

检测原理
传感器中心有个洞可以让空气自由流过,定向发射LED光,通过检测经过空气中灰尘折射过后的光线来判断灰尘的含量。

#include "Arduino.h"
#define dustPin 35 //定义 adc 采集引脚
#define ledPower 21 //定义 led 发射引脚 int value;
float dustVal=0;
int delayTime=280;
int delayTime2=40;
float offTime=9680; void setup() {
// put your setup code here, to run once:
pinMode(ledPower,OUTPUT);
adcAttachPin(dustPin); //设置 ADC 采集引脚
adcStart(dustPin); //开始 ADC 采集
Serial.begin(115200);
}
void loop() {
// put your main code here, to run repeatedly:
digitalWrite(ledPower,LOW);
delayMicroseconds(delayTime);
dustVal=analogRead(dustPin);
// Serial.write(value>>8); Serial.write(value);
delayMicroseconds(delayTime2);
digitalWrite(ledPower,HIGH);
delayMicroseconds(offTime); delay(1000);
if (dustVal>36.455)
Serial.println((float(dustVal/4096)-0.0356)*120000*0.035); }

引脚问题,需要拿个中介板焊到一起。

实验 7:ESP32 I2C 驱动 OLED

0.96 OLED 和开发板的连线
VCC ----3.3V
GND----GND
SCL----- GPIO14
SDA---- GPIO15

#include "SSD1306.h"
#include "images.h"
SSD1306 oled(0x3c,15,14); //实例化 SSD1306 类
void drawCircle(void) {
//画圆形
for (int16_t i=0; i<DISPLAY_HEIGHT; i+=2) { oled.drawCircle(DISPLAY_WIDTH/2, DISPLAY_HEIGHT/2, i); oled.display(); delay(10);
}
delay(1000);
oled.clear(); //清屏
// This will draw the part of the circel in quadrant 1
// Quadrants are numberd like this:
// 0010 | 0001
// ------|----- // 0100 | 1000 //
oled.drawCircleQuads(DISPLAY_WIDTH/2,DISPLAY_HEIGHT/2,DISPLAY_HEIGHT/4,0b00000001); oled.display();
delay(200); oled.drawCircleQuads(DISPLAY_WIDTH/2,DISPLAY_HEIGHT/2,DISPLAY_HEIGHT/4,0b00000011); oled.display();
delay(200); oled.drawCircleQuads(DISPLAY_WIDTH/2,DISPLAY_HEIGHT/2,DISPLAY_HEIGHT/4,0b00000111); oled.display();
delay(200); oled.drawCircleQuads(DISPLAY_WIDTH/2,DISPLAY_HEIGHT/2,DISPLAY_HEIGHT/4,0b00001111); oled.display();
}
void setup() {
// put your setup code here, to run once:
oled.init();//初始化
OLED oled.flipScreenVertically();//
oled.setContrast(255);//设置对比度 255
drawCircle();//画动态圆形的函数
//oled.drawXbm(0,0, Logo_width,Logo_height, Logo_bits);
oled.display();//显示内容
}
void loop() {
// put your main code here, to run repeatedly:
}

错误1

解决:
安装ESP8266 and ESP32 Oled Driver for SSD1306 display
错误2

解决方法:
换一个安装路径。
仍存在此问题,未解决,没有images.h,但是路径中有呀,要再下载一个esp32-expressf-master,我虽然有,但是库中文件不全。
多次下载失败,以上例程未实现,少库,应该是master中文件不全,再下载。
以下例程都是此问题,均未实现。

打印字符串

如果是要打印字符串可以在主函数下添加如下代码

oled.setFont(ArialMT_Plain_16);//设置字体为 16 号

如果想变其他字体可以看下 OLEDDisplayFonts.h 这个文件,选择自己需要的字体。

oled.drawString(1,1,"Goouuu");//打印字符串

打印位图

如果想打印一张位图 那么可以用这个函数

oled.drawXbm(0,0, Logo_width,Logo_height, Logo_bits);

图片取模过程如下:
1.先用美图秀秀,将图片尺寸强制变成 128x64 并保存为 png 格式。
2.用画图软件打开修改后的 png 图片设置为黑白点确定。
3.打开取模软件,调入黑白图像,点 c51 格式,然后把取到的数据复制到 arduino 里图像的数 组即可。
4.打开取模软件,调入黑白图像,点 c51 格式,然后把取到的数据复制到 arduino 里图像的数 组即可。
之前笔记更简单。
参考之前学习笔记

实验 8:ESP32 SPI 驱动 LCD

例程一:画线

#include"lcd.h"
#include"icon.h"
LCD lcd; //实例化这个类
void setup() {
// put your setup code here, to run once:
lcd.LCD_GPIOInit();
lcd.LCD_Init();
lcd.LCD_Clear(BLACK); //清屏幕,并把背景设为黑色
POINT_COLOR=BLUE;//设置画笔颜色蓝色
lcd.LCD_DrawLine(0,127,127,0); // 画两条直线
lcd.LCD_DrawLine(0,0,127,127); //
}
void loop() {
// put your main code here, to run repeatedly:
}

例程二:显示英文和中文字符

#include"lcd.h"
#include"icon.h"
LCD lcd; //实例化这个类
void setup() {
// put your setup code here, to run once:
lcd.LCD_GPIOInit();
lcd.LCD_Init();
lcd.LCD_Clear(BLACK); //清屏幕,并把背景设为黑色
POINT_COLOR=BLUE;//设置画笔颜色蓝色
lcd.Show_Str(40,25,BLUE,BLACK,"Goouuu",16,1);
lcd.Show_Str(32,50,BLUE,BLACK,"果 云 科 技 ",8,1);
}
void loop() {
// put your main code here, to run repeatedly:
}

实验 9:ESP32 DAC 驱动扬声器播放 PCM 音乐

扬声器就是通常我们说的音箱。可以播放各种声音,例如音乐。
蜂鸣器则是单纯只发出一种声音的报警装置。它会通过声音的长短来报告错误。

#include "Speaker.h"
#include "music_8bit.h"
SPEAKER Speaker;
void setup() {
// put your setup code here, to run once:
Speaker.begin(); //初始化
Speaker.setVolume(10); //设置音量为10
Speaker.playMusic(data, 22500); //播放 pcm 格式数据,并设定采样率
}
void loop() {
// put your main code here, to run repeatedly:
Speaker.update();
}

实验 10:ESP32 读写 MicroSD 卡操作

列出指定目录下的文件

#include "FS.h"
#include "SD.h"
#include "SPI.h"
#include "Speaker.h"
SPEAKER Speaker; /*---------------------------------------------------- 列出指定目录下的文件-----------------------------------------------------*/
void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
Serial.printf("Listing directory: %s\n", dirname);
File root = fs.open(dirname);
if(!root){ Serial.println("Failed to open directory"); return;
}
if(!root.isDirectory()){ Serial.println("Not a directory"); return;
}
File file = root.openNextFile();
while(file){ if(file.isDirectory()){ Serial.print(" DIR : "); Serial.println(file.name()); if(levels){ listDir(fs, file.name(), levels -1); } } else {Serial.print(" FILE: "); Serial.print(file.name()); Serial.print(" SIZE: "); Serial.println(file.size()); }file = root.openNextFile(); }
}

创建目录

void createDir(fs::FS &fs, const char * path){ Serial.printf("Creating Dir: %s\n", path); if(fs.mkdir(path)){ Serial.println("Dir created"); } else {Serial.println("mkdir failed"); }
}

移除目录

void removeDir(fs::FS &fs, const char * path){
Serial.printf("Removing Dir: %s\n", path);
if(fs.rmdir(path)){ Serial.println("Dir removed");
} else {Serial.println("rmdir failed"); }
}

读取指定文件的内容

void readFile(fs::FS &fs, const char * path){
uint8_t buf[2];
uint16_t delay_interval = ((uint32_t)1000000/25000);
Serial.printf("Reading file: %s\n", path);
File file = fs.open(path);
if(!file){ Serial.println("Failed to open file for reading"); return;
}
Serial.print("Read from file: ");
while(file.available()){ buf[0]=file.read(); dacWrite(SPEAKER_PIN,buf[0]); delayMicroseconds(delay_interval-20);
}
file.close();
}

写入指定内容到指定文件

void writeFile(fs::FS &fs, const char * path, const char * message){         Serial.printf("Writing file: %s\n", path);
File file = fs.open(path, FILE_WRITE); //打开指定的某个文件
if(!file){ Serial.println("Failed to open file for writing"); return;
}
if(file.print(message)){ Serial.println("File written");
} else {Serial.println("Write failed");
}file.close();
}

写入指定内容到指定文件,如果这个文件不存在,则创建一个新的指定名字的文件,再写入内容。

void appendFile(fs::FS &fs, const char * path, const char * message){    Serial.printf("Appending to file: %s\n", path);
File file = fs.open(path, FILE_APPEND);
if(!file){ Serial.println("Failed to open file for appending"); return;
}
if(file.print(message)){ Serial.println("Message appended");
} else {Serial.println("Append failed");
}file.close();
}

重命名文件

void renameFile(fs::FS &fs, const char * path1, const char * path2){     Serial.printf("Renaming file %s to %s\n", path1, path2);
if (fs.rename(path1, path2)) { Serial.println("File renamed");
} else {Serial.println("Rename failed"); }
}

删除指定文件

void deleteFile(fs::FS &fs, const char * path){ Serial.printf("Deleting file: %s\n", path); if(fs.remove(path)){ Serial.println("File deleted"); } else {Serial.println("Delete failed"); }
}

读写文件测试

void testFileIO(fs::FS &fs, const char * path){
File file = fs.open(path);
static uint8_t buf[512];
size_t len = 0; uint32_t start = millis();
uint32_t end = start;
if(file){len = file.size(); size_t flen = len; start = millis(); while(len){size_t toRead = len; if(toRead > 512){ toRead = 512; }file.read(buf, toRead); len -= toRead; }end = millis() - start; Serial.printf("%u bytes read for %u ms\n", flen, end); file.close();
} else {Serial.println("Failed to open file for reading");
}
file = fs.open(path, FILE_WRITE);
if(!file){ Serial.println("Failed to open file for writing"); return;
}size_t i;
start = millis();
for(i=0; i<2048; i++){ file.write(buf, 512);
}
end = millis() - start;
Serial.printf("%u bytes written for %u ms\n", 2048 * 512, end);
file.close();
}
void setup(){ Serial.begin(115200); if(!SD.begin()){ //初始化 SD 卡 Serial.println("Card Mount Failed"); return; }uint8_t cardType = SD.cardType(); //读取 SD 卡类型//判断 SD 卡类型 if(cardType == CARD_NONE){ Serial.println("No SD card attached"); return; }Serial.print("SD Card Type: "); if(cardType == CARD_MMC){ Serial.println("MMC"); } else if(cardType == CARD_SD){ Serial.println("SDSC"); } else if(cardType == CARD_SDHC){ Serial.println("SDHC"); } else {Serial.println("UNKNOWN"); }//读取 SD 卡尺寸 uint64_t cardSize = SD.cardSize() / (1024 * 1024); Serial.printf("SD Card Size: %lluMB\n", cardSize); listDir(SD, "/", 0);//列出目录 createDir(SD, "/mydir");//创建 1 个 mydir 的文件夹目录 listDir(SD, "/", 0);//列出目录 removeDir(SD, "/mydir");//删除 mydir 的文件夹目录 listDir(SD, "/", 2);//列出目录 writeFile(SD, "/hello.txt", "Hello ");//对 hello.txt 这个文件写内容 Hello appendFile(SD, "/hello.txt", "World!\n");//检测 hello.txt 这个是否存在,不存在则创建并写 //入内容,如果存在则直接写入内容 readFile(SD, "/hello.txt");//读取 hello.txt 文件 deleteFile(SD, "/foo.txt");//删除 foo.txt 文件 renameFile(SD, "/hello.txt", "/foo.txt");//把 hello.txt 这个文件重命名为 foo.txt     readFile(SD, "/jqm.pcm");//读取 jqm.pcm 这个文件,并播放 }void loop(){ }

ESP32 WiFi 的使用

STA 模式下的 TCP 通讯实验:

ESP32 作为 Station 模式,连接路由器,然后连接我们的公网测试服务器端,惊醒 tcp 通讯。

#include<WiFi.h>
#include<WiFiMulti.h>
WiFiMulti WiFiMulti;
WiFiClient client;
#define WIFISSID "yq"
#define Password "goouuu8266"
uint8_t test[6]={0x12,0x34,0x56,0x78,0x0c,0x0b};//6 个字节的测试数据
const uint16_t port = 8266;//主机端口
const char * host = "39.106.163.29"; // ip or dns 远程主机 ip
void Connect_Router(void);//连接到你的路由器
void Connect_Host(void);//连接到远程服务器
void setup() { // put your setup code here, to run once: Serial.begin(115200); Connect_Router();//连接到你的路由器
}void loop() {
// put your main code here, to run repeatedly: Connect_Host();//连接到远程服务器 // This will send the request to the server client.write(test,6);//发送 6 个字节数据 client.print("Hello_Goouuu!\r\n");//发送字符串 //read back one line from serverString line = client.readStringUntil('\r');读取服务器发来的数据     Serial.println(line);//打印服务器发来的数据 client.stop();//关闭端口 Serial.println("closing connection"); Serial.println("wait 5 sec..."); delay(5000); }void Connect_Router(void) { // We start by connecting to a WiFi network WiFiMulti.addAP(WIFISSID,Password); Serial.println(); Serial.println(); Serial.print("Wait for WiFi... "); while(WiFiMulti.run() != WL_CONNECTED) { Serial.print("."); delay(500); }Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); delay(500); }void Connect_Host(void) { if (!client.connect(host, port)) { Serial.println("connection failed"); Serial.println("wait 5 sec..."); delay(5000); return; } }

Sta 模式下扫描周围热点:

 #include "WiFi.h" void setup() { Serial.begin(115200); // Set WiFi to station mode and disconnect from an AP if it was previously connected    WiFi.mode(WIFI_STA);//设置为 STA 模式 WiFi.disconnect();//断开连接 delay(100); Serial.println("Setup done");
}
void loop()
{ Serial.println("scan start"); // WiFi.scanNetworks will return the number of networks found int n = WiFi.scanNetworks();//获取可以正常连接的热点数量 Serial.println("scan done"); if (n == 0) { Serial.println("no networks found"); } else {Serial.print(n); Serial.println(" networks found"); for (int i = 0; i < n; ++i) { // Print SSID and RSSI for each network found Serial.print(i + 1); Serial.print(": "); Serial.print(WiFi.SSID(i));//打印热点 SSID Serial.print(" ("); Serial.print(WiFi.RSSI(i));//打印热点信号强度 Serial.print(")"); Serial.print(" ("); Serial.print(WiFi.channel(i));//打印热点信道 Serial.print(")"); Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN)?" ":"*");   delay(10); } }Serial.println(""); // Wait a bit before scanning again delay(5000); }

Smartconfig 一键连接原理

首先 WiFi 模块进入初始化状态,处于一个待收包状态。
手机点下配置键后,将已知 AP 的 SSID 和密码等信息,通过 UDP 广播发送出去。
WiFi 模块收到 UDP 包后解析得到 AP 的 SSID 和密码等信息后,切换到 STA 状态,对目标 AP 发起连接,连上目标 AP 后,配置就结束了。

#include "WiFi.h"
void setup() { Serial.begin(115200); //Init WiFi as Station, start SmartConfig WiFi.mode(WIFI_AP_STA); WiFi.beginSmartConfig(); //Wait for SmartConfig packet from mobile Serial.println("Waiting for SmartConfig."); while (!WiFi.smartConfigDone()) { delay(500); Serial.print("."); }Serial.println(""); Serial.println("SmartConfig received."); //Wait for WiFi to connect to AP Serial.println("Waiting for WiFi"); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }Serial.println("WiFi Connected."); Serial.print("IP Address: "); Serial.println(WiFi.localIP());
}
void loop() {
// put your main code here, to run repeatedly:
}

esp32入门手册学习相关推荐

  1. 吹爆系列:教科书级别的Android音视频入门进阶学习手册,学完我成功“挤进”了抖音音视频开发岗

    Android开发工作两年,真的是感觉Android应用层开发没什么前景了,于是打算在网络安全,智能硬件,音视频这几个方向发展,考虑了一段时间,最终决定选择音视频.理由就不说了,既然选择了就要好好深耕 ...

  2. JQuery入门手册(学习笔记整理)

    JQuery入门手册 基础 学习重点 技术介绍 jQuery使用 jQuery对象与DOM对象的区别 jQuery对象与DOM对象转换 选择器 选择器语法 基本选择器 层级选择器 input标签选择器 ...

  3. ESP32 入门笔记08:1.54寸(240*240)彩色TFT 显示高清IPS LCD 屏幕 SPI接口

    目录 1.屏幕规格 2.原理图 3.程序实现 3.1引脚定义 3.2Adafruit_GFX / Arduino_ST7789版 3.3TFT_eSPI库版 3.3.1配置TFT_eSPI a.选择屏 ...

  4. AI产品经理入门手册(下)

    近两年来AI产业已然成为新的焦点和风口,各互联网巨头都在布局人工智能,不少互联网产品经理也开始考虑转型AI产品经理,本文作者也同样在转型中.本篇文章是通过一段时间的学习归纳总结整理而成,力图通过这篇文 ...

  5. 心得丨老生常谈:普通程序员到底如何入门深度学习?

    作为一名软件工程师,我们应该活到老学到老,时刻与不断发展的框架.标准和范式保持同步.同时,还要能活学活用,在工作中使用最合适的工具,以提高工作效率.随着机器学习在越来越多的应用程序中寻得了一席之地,越 ...

  6. rocketmq 顺序消费_必须先理解的RocketMQ入门手册,才能再次深入解读

    推荐阅读一下下 2020年后想跳槽?MQ.ZK.Nginx.Kafk等分布式技术你都掌握了? 阿里架构师推荐学习的<RabbitMQ实战指南>,渣渣的你都看过吗? RocketMQ入门手册 ...

  7. 深度学习实战_五天入门深度学习,这里有一份PyTorch实战课程

    这是一门五天入门深度学习的实战课程. 想入门深度学习的小伙伴有福了!dataflowr 最近推出了一门五天初步掌握深度学习的实战教程(实战使用 PyTorch 框架),有知识点有实例有代码,值得一看. ...

  8. (翻译)60分钟入门深度学习工具-PyTorch

    60分钟入门深度学习工具-PyTorch 作者:Soumith Chintala 原文翻译自: https://pytorch.org/tutorials/beginner/deep_learning ...

  9. 推荐算法炼丹笔记:CTR点击率预估系列入门手册

    ​CTR点击率预估系列家谱 炼丹之前,先放一张CTR预估系列的家谱,让脉络更加清晰. (一)FiBiNET:结合特征重要性和双线性特征交互进行CTR预估 1.1 背景 本文发表在RecSys 2019 ...

最新文章

  1. 《强化学习周刊》第2期:多智能体强化学习(MARL)赋能“AI智能时代”
  2. Scala:没有continue,break怎么办?
  3. NVIDIA NeMo User Guide
  4. CheckedComboBoxEdit 重置初始化值的方法
  5. seo全攻略_SaaS 企业推广获客全攻略(2):如何做好企业官网?
  6. c语言二分法_14个经典C语言算法你就不看一眼?(附详细代码)
  7. vivo硬件测试员干什么的_vivo的新年礼物:用APEX 2019告诉你5G旗舰机该长啥样
  8. ARP欺骗原理 [转]
  9. 【9108】模拟数学计算器
  10. Maven工程 报 Diamond types are not supported at language level '5'
  11. 海康威视_摄像头搜索工具
  12. spss和python财务数据分析_用SPSS做数据分析?先弄懂SPSS的基础知识吧
  13. Android Design 与 Holo Theme
  14. cistern java,basin是什么意思_basin怎么读_basin翻译_用法_发音_词组_同反义词_盆-新东方在线英语词典...
  15. Rsync守护进程部署和实践
  16. SVN使用教程(一)
  17. 2022广州大学计算机网络实验--Windows网络测试工具
  18. 旁挂二层组网隧道转发
  19. 利用互信息推断基因调控网络
  20. 基于Quartus II软件的FPGA综合实验——多功能数字钟

热门文章

  1. arp攻击----arpspoof
  2. 语音识别ASR和NLP有什么区别?
  3. java微信支付v3系列——4.创建订单的封装及使用
  4. 求整型矩阵主对角线元素之和
  5. 记一次成功的iPhone维修
  6. 异步请求 ajax的使用详解
  7. java商城源码_java 多商户商城系统源码分享
  8. [UNR#5]诡异操作
  9. 移动设备IP地址的获取
  10. 安卓开发视频处理框架!2021年这些高频面试知识点最后再发一次,全网疯传