技术标签: 单片机
文章首发及后续更新:https://mwhls.top/1075.html
新的更新内容请到mwhls.top查看。
无图/格式错误请到上方的文章首发页面查看。
http://pan-yz.chaoxing.com/preview/showpreview_536535694800277504.html?v=1605849878000
舵机转动:收到转动信号后,舵机正转180°,后逆转180°复原。
读卡转动舵机:RC522读卡器读到已知卡时,会向舵机发送转动信号。
联网控制舵机:ESP8266启动wifi后,使用任意带无线网卡的主机连接到ESP8266Web网络后,打开192.168.4.1后,可进入舵机控制页面,点击控制键后,可向舵机发送转动信号。
未知卡ID读取:将nano板连接至电脑,可显示串口信息后,将未知的卡放在读卡器上,可输出卡ID。
新卡添加:将卡ID加入nano代码的userCard数组中,再将USER_NUM加一,即可添加新卡,可添加校园卡并正常刷卡转动。
舵机环形转动,拉动宿舍门栓时会转到一个地方卡主,即因为不能平行拉动,无法正常拉动门栓,于是换了一栋楼尝试。
舵机力量太小,在另一栋楼又无法拉动门栓。
改进方向:改用平移的舵机,或使用拉力更大的舵机。
RC522质量差,在使用时,第一片RC522可正常转动,但一天后损坏,
而后又买了一片RC522,在示例程序中也无法正常使用,只能读三次卡后,转动一次舵机,然后只能重启后才能继续读卡。
但wifi模块始终正常运行。
改进方向:更换读卡芯片,或换一家质量好的店铺。
电源使用小米20000毫安微电流充电宝,价格将近整套材料三倍。
改进方向:使用电池供电。
除自带的充电宝作为电源外,零件理论共44.6元,但实际使用中,RC522坏了一块,于是重新购买,再扣去红包折扣,实际花费44.82元。
当然,如果直接用电脑,也是不用电源的。
名称 | 用途 | 数量 | 价格/元 |
Arduino Nano V3 及配套数据线 | 开发板 | 1 | 16.7 |
MFRC522 | RFID读卡器 | 1 | 4.8 |
NodeMCU(CH340串口) 及配套数据线 | ESP8266模块 | 1 | 14.8 |
SG90 | 舵机 | 1 | 5.1 |
母对母杜邦线 | 导线 | 13 | 1.6 |
公对公杜邦线 | 导线 | 3 | 1.6 |
支持微电流的两万毫安小米充电宝 | 电源 | 1 | - |
Arduino(引脚) | NodeMCU(引脚) | RC522(顺序) | SG90(颜色) |
GND | GND | ||
A4 | D1 | ||
A5 | D2 | ||
D9 | RST (2) | ||
D10 | SDA (8) | ||
D11 | MOSI (6) | ||
D12 | MISO (5) | ||
D13 | SCK (7) | ||
3V3 | 3.3V (1) | ||
GND | GND (3) | ||
5V | 5V(红) | ||
D8 | PWM信号(黄) | ||
GND | GND (棕) |
Arduino 1.8.13
开发板:Arduino Nano
处理器:ATmega328P (Old Bootloader)
代码功能介绍:
基于MFRC522.h提供的实例库,实例库提供了寻卡、卡类型识别、卡验证、防碰撞等基本功能,
加入了卡的存储管理数组userCard,用于存储卡ID的十进制数据。
加入了舵机控制函数,收到信号后,控制舵机转动180°后,回转180°回到原位,舵机使用脉冲控制替换了舵机库控制,因此不限于特定引脚发送信号。
加入了读特定卡后舵机转动功能,读到卡后,与userCard中数据对比,若相同,则向舵机发送转动信号。
加入了读未知卡后串口输出卡ID功能,将卡ID添加至userCard数组后,将USER_NUM加一,即可添加新卡。
加入了I2C通信函数,NodeMCU板通过I2C通信,将信号传输到Nano版,验证信号后,向舵机发送转动信号。
/* 作者:MWHLS,主页MWHLS.TOP
* 链接:http://mwhls.top/?p=1075
* 因为使用的不是SERVO.H库,舵机的PWM控制端口并不局限于9/10两个端口,且也不局限于仅控制两个舵机。
* 通行卡的存储使用二维数组,将卡的UID转为十进制保存。
* 卡的对比使用for函数遍历二维数组,对比UID是否相同。
* 舵机启动由舵机控制变量servoRun控制,若值为1,则启动,其余不运行。
* 接受到NodeMCU传来的信号时,舵机控制变量置1。
* 发现通行卡时,舵机控制变量置1。
* 参考文章:
* 网页控制:https://blog.csdn.net/qq_46292418/article/details/106605366
* I2C通信:https://blog.csdn.net/qq_44506730/article/details/90578507
* RC522读卡:https://blog.csdn.net/leytton/article/details/73480974
* 舵机控制:https://blog.csdn.net/sss_369/article/details/52894347
*/
#include <SPI.h>
#include <MFRC522.h>
#include <Wire.h> //使用Wire.h进行I2C通信
#define SS_PIN 10
#define RST_PIN 9
#define SERVO_PIN 8
#define USER_NUM 3
byte servoRun = 0; // 舵机控制变量。
MFRC522 rfid(SS_PIN, RST_PIN); // 实例化类
byte userCard[USER_NUM][4] = { // 通行卡存储数组。
{28, 184, 119, 33},
{249, 231, 71, 179},
{109, 242, 234, 235}
};
void setup() {
Serial.begin(9600); // 波特率设置
SPI.begin(); // 初始化SPI总线
rfid.PCD_Init(); // 初始化 MFRC522
pinMode(SERVO_PIN, OUTPUT); // 舵机控制端口。
Wire.begin(8); // 设置与NodeMCU的通信I2C端口。
Wire.onReceive(receiveEvent); // 信号接受处理。
}
void loop() {
if(servoRun == 1){ // 舵机运行变量若为1,则运行。
servoControl(); // 舵机控制函数。
}
if ( ! rfid.PICC_IsNewCardPresent()) return; // 找卡
if ( ! rfid.PICC_ReadCardSerial()) return; // 验证NUID是否可读
MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI && // 检查是否MIFARE卡类型
piccType != MFRC522::PICC_TYPE_MIFARE_1K &&
piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
Serial.println("Can identify this card!");
return;
}
byte i;
for (i=0; i<USER_NUM; i++){ // 判断卡是否为通行卡。
byte i2;
for(i2=0; i2<4; i2++){ // 遍历userCard中所有卡。
if(rfid.uid.uidByte[i2] != userCard[i][i2]) break;
} // break时,表示此卡不是通行卡。
if(i2 == 4){ // i2为4,表示此卡的四位值都验证通过。
Serial.println("Find an accessful card."); // 输出成功信息。
servoRun = 1; // 将开门变量置1。
break; // 已找到通行卡,跳出循环。
}
}
if(i==USER_NUM){ // 若i等于通行用户数量,则上层循环未找到通行卡。
Serial.print("Find a unknown card, its uid:");
for(i=0; i<4; i++){ // 输出此卡UID,便于后期新增通行卡。
Serial.print(rfid.uid.uidByte[i], DEC);
Serial.print(" ");
}
Serial.println();
}
rfid.PICC_HaltA(); // 使放置在读卡区的IC卡进入休眠状态,不再重复读卡
rfid.PCD_StopCrypto1(); // 停止读卡模块编码
}
void servoControl(){ // 舵机控制函数。
Serial.println("Servo run!"); // 函数运行输出标识。
servoPulse(0); // 舵机转至0度。
delay(1000); // 等待舵机运转。
servoPulse(180); // 舵机转至180度。
servoRun = 0; // 舵机运行变量置零。
}
void servoPulse(int myangle) // 定义一个脉冲函数,作者:https://blog.csdn.net/sss_369/article/details/52894347
{
int pulseWidth=(myangle*11)+500;// 将角度转化为500-2480 的脉宽值
digitalWrite(SERVO_PIN,HIGH); // 将舵机接口电平至高
delayMicroseconds(pulseWidth); // 延时脉宽值的微秒数weimiao
digitalWrite(SERVO_PIN,LOW); // 将舵机接口电平至低
delay(20-pulseWidth/1000);
}
void receiveEvent(int howMany){ // 定义接受联网信息函数,参考:https://blog.csdn.net/qq_44506730/article/details/90578507
while(0<Wire.available()){
char c = Wire.read();
if (c == '1') servoRun = 1; // 如果传入数据为1,则舵机运行变量置1。
Serial.println("Receive an access sign from ESP8266.");
}
}
Arduino 1.8.13
开发板:NodeMCU 1.0
其余设置默认。
代码功能介绍:
NodeMCU通电后自动运行代码,
将使用AP模式开启一个ESP8266Web的wifi,
并建立一个简单网页,
网页中有一个基于I2C通信的按钮,在按下后,NodeMCU会向Nano板发送信号。
将NodeMCU与主机连接,监听串口信息,在wifi开启后,串口会输出wifi相关信息,包括wifi名称,wifi密码以及控制页面地址。
/* 作者:MWHLS,主页MWHLS.TOP
* 链接:http://mwhls.top/?p=1075
* 通过主机连接上ESP8266热点,进入通信网址,点击CLICK按钮后,
* 一个消息会使用I2C通信传输给Arduino,这个消息会触发舵机转动。
* 参考文章:
* I2C通信:https://blog.csdn.net/qq_44506730/article/details/90578507
* 网页控制:https://blog.csdn.net/qq_46292418/article/details/106605366
*/
#include <ESP8266WiFi.h> // 本程序使用 ESP8266WiFi库
#include <ESP8266WebServer.h> // ESP8266WebServer库
#include <Wire.h> // 使用Wire.h进行I2C通信
ESP8266WebServer esp8266_server(80);// 建立ESP8266WebServer对象,对象名称为esp8266_server
// 括号中的数字是网路服务器响应http请求的端口号
// 网络服务器标准http端口号为80,因此这里使用80为端口号
#define WIFISSID "ESP8266Web" // 设定ESP8266 wifi名称
#define WIFIPSSD "123456789" // 设定wifi密码
void setup(void){
Serial.begin(9600); // 启动串口通讯
Wire.begin(D1,D2); // I2C通信端口
setAP(); // 设定AP模式,并建立热点。
//--------"启动网络服务功能"程序部分开始-------- // 此部分为程序为本示例程序重点1
esp8266_server.begin(); // 详细讲解请参见太极创客网站《零基础入门学用物联网》
esp8266_server.on("/", HTTP_GET, handleRoot); // 第3章-第2节 ESP8266-NodeMCU网络服务器-1
esp8266_server.on("/CLICK", HTTP_POST, handleClick);// 处理用户点击消息。
esp8266_server.onNotFound(handleNotFound); // 404处理。
//--------"启动网络服务功能"程序部分结束--------
Serial.println("HTTP esp8266_server started"); // 告知用户ESP8266网络服务功能已经启动
}
void loop(void){
esp8266_server.handleClient(); // 处理http服务器访问
}
void setAP(){
WiFi.mode(WIFI_AP); // 设定ESP8266的AP模式
WiFi.softAP(WIFISSID,WIFIPSSD); // 设定ESP8266热点
Serial.printf("Success!\nWIFISSID: %s \nWIFIPSSD: %s \nControlWeb: ", WIFISSID, WIFIPSSD);
Serial.println(WiFi.softAPIP()); // 接上行,输出WIFI信息与通信网址。
}
void handleRoot() { // 处理网站根目录“/”的访问请求
esp8266_server.send(200, "text/html", "<form action=\"/CLICK\" method=\"POST\"><input type=\"submit\" value=\"CLICK\"></form>");
}
void handleClick(){ // 点击消息处理函数
Serial.println("Click.");
clickTransmission(); // 传输点击消息到Arduino板。
esp8266_server.sendHeader("Location","/"); // 跳转回页面根目录
esp8266_server.send(303); // 发送Http相应代码303 跳转
}
void clickTransmission(){ // 点击消息传输函数
Wire.beginTransmission(8); // 开始传输
Wire.write('1'); // 传 1 至Arduino版
Wire.endTransmission(); // 结束传输
Serial.println("Click transmiss success."); // 输出成功信息
}
// 设置处理404情况的函数'handleNotFound'
void handleNotFound(){ // 当浏览器请求的网络资源无法在服务器找到时,
esp8266_server.send(404, "text/plain", "404: Not found"); // NodeMCU将调用此函数。
}
文章浏览阅读1.6k次。安装配置gi、安装数据库软件、dbca建库见下:http://blog.csdn.net/kadwf123/article/details/784299611、检查集群节点及状态:[root@rac2 ~]# olsnodes -srac1 Activerac2 Activerac3 Activerac4 Active[root@rac2 ~]_12c查看crs状态
文章浏览阅读1.3w次,点赞45次,收藏99次。我个人用的是anaconda3的一个python集成环境,自带jupyter notebook,但在我打开jupyter notebook界面后,却找不到对应的虚拟环境,原来是jupyter notebook只是通用于下载anaconda时自带的环境,其他环境要想使用必须手动下载一些库:1.首先进入到自己创建的虚拟环境(pytorch是虚拟环境的名字)activate pytorch2.在该环境下下载这个库conda install ipykernelconda install nb__jupyter没有pytorch环境
文章浏览阅读5.2k次,点赞19次,收藏28次。选择scoop纯属意外,也是无奈,因为电脑用户被锁了管理员权限,所有exe安装程序都无法安装,只可以用绿色软件,最后被我发现scoop,省去了到处下载XXX绿色版的烦恼,当然scoop里需要管理员权限的软件也跟我无缘了(譬如everything)。推荐添加dorado这个bucket镜像,里面很多中文软件,但是部分国外的软件下载地址在github,可能无法下载。以上两个是官方bucket的国内镜像,所有软件建议优先从这里下载。上面可以看到很多bucket以及软件数。如果官网登陆不了可以试一下以下方式。_scoop-cn
文章浏览阅读4.5k次,点赞2次,收藏3次。首先要有一个color-picker组件 <el-color-picker v-model="headcolor"></el-color-picker>在data里面data() { return {headcolor: ’ #278add ’ //这里可以选择一个默认的颜色} }然后在你想要改变颜色的地方用v-bind绑定就好了,例如:这里的:sty..._vue el-color-picker
文章浏览阅读640次。基于芯片日益增长的问题,所以内核开发者们引入了新的方法,就是在内核中只保留函数,而数据则不包含,由用户(应用程序员)自己把数据按照规定的格式编写,并放在约定的地方,为了不占用过多的内存,还要求数据以根精简的方式编写。boot启动时,传参给内核,告诉内核设备树文件和kernel的位置,内核启动时根据地址去找到设备树文件,再利用专用的编译器去反编译dtb文件,将dtb还原成数据结构,以供驱动的函数去调用。firmware是三星的一个固件的设备信息,因为找不到固件,所以内核启动不成功。_exynos 4412 刷机
文章浏览阅读2w次,点赞24次,收藏42次。Linux系统配置jdkLinux学习教程,Linux入门教程(超详细)_linux配置jdk
文章浏览阅读3.3k次,点赞5次,收藏19次。xlabel('\delta');ylabel('AUC');具体符号的对照表参照下图:_matlab微米怎么输入
文章浏览阅读119次。顺序读写指的是按照文件中数据的顺序进行读取或写入。对于文本文件,可以使用fgets、fputs、fscanf、fprintf等函数进行顺序读写。在C语言中,对文件的操作通常涉及文件的打开、读写以及关闭。文件的打开使用fopen函数,而关闭则使用fclose函数。在C语言中,可以使用fread和fwrite函数进行二进制读写。 Biaoge 于2024-03-09 23:51发布 阅读量:7 ️文章类型:【 C语言程序设计 】在C语言中,用于打开文件的函数是____,用于关闭文件的函数是____。
文章浏览阅读3.4k次,点赞2次,收藏13次。跟随鼠标移动的粒子以grid(SOP)为partical(SOP)的资源模板,调整后连接【Geo组合+point spirit(MAT)】,在连接【feedback组合】适当调整。影响粒子动态的节点【metaball(SOP)+force(SOP)】添加mouse in(CHOP)鼠标位置到metaball的坐标,实现鼠标影响。..._touchdesigner怎么让一个模型跟着鼠标移动
文章浏览阅读178次。项目运行环境配置:Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:Springboot + mybatis + Maven +mysql5.7或8.0+html+css+js等等组成,B/S模式 + Maven管理等等。环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。_基于java技术的停车场管理系统实现与设计
文章浏览阅读3.5k次。前言对于MediaPlayer播放器的源码分析内容相对来说比较多,会从Java-&amp;gt;Jni-&amp;gt;C/C++慢慢分析,后面会慢慢更新。另外,博客只作为自己学习记录的一种方式,对于其他的不过多的评论。MediaPlayerDemopublic class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal..._android多媒体播放源码分析 时序图
文章浏览阅读2.4k次,点赞41次,收藏13次。java 数据结构与算法 ——快速排序法_快速排序法