无法用8266连接uno控制舵机转动
本帖最后由 逆天鲨鱼头 于 2021-10-29 00:42 编辑想要用单片机控制宿舍开门,用到了uno、rc522和8266,还有点灯blinker的库
8266能通过wifi收到手机上的指令,uno从机能收到8266主机的数据,但是执行不了转动舵机的指令。
用8266做主机,uno从机,iic通信,舵机接在uno上。
舵机没坏,rc522识别nfc卡能正常转动舵机。
=========================================
问题代码在这里,完整代码放在后面(代码可能有点奇怪,其实是为了验证串口通信,一直改,越来越怪)这段是iic通信 从机接受到主机数据后执行的程序
void receiveEvent(int howMany){
string = "";
while(Wire.available()>0){
char c =Wire.read();
string += c;
}
Serial.println(string);
delay(100);
myservo.write(30);
delay(2000);
myservo.write(180);
Serial.println("114514"); //这行没意义,只是验证从机能否正常收到数据,最后串口能收到,但是舵机不动
}
-----------
最后串口里能收到
open
114514
open是主机发送来的,也就是string的内容
但是舵机就是没反应
============================================
uno从机代码如下:
#include <SPI.h>
#include <MFRC522.h>//nfc头文件
#include <Servo.h>//舵机头文件
#include <Wire.h>
MFRC522 rfid(10, 9);//创建一个rc522读卡器对象
Servo myservo;//创建一个舵机控制对象
byte nuidPICC;// 初始化数组用于存储读取到的NUID
String string = "";//存储从主机收到的数据
void open(){
for (int pos = 180; pos >= 30; pos --){
myservo.write(pos);
delay(5);
}
delay(2000);
myservo.write(180);
}
void receiveEvent(int howMany){
string = "";
while(Wire.available()>0){
char c =Wire.read();
string += c;
}
Serial.println(string);
delay(100);
myservo.write(30);
delay(2000);
myservo.write(180);
Serial.println("114514"); //这行没意义,只是验证从机能否正常收到数据,最后串口能收到,但是舵机不动
}
void setup(){
SPI.begin(); // 初始化SPI总线
rfid.PCD_Init();
Serial.begin(9600);
myservo.attach(6);//设定舵机的接口为6
myservo.write(180);//设定舵机旋转角度复位为0.(可调0~180)
Wire.begin(8);
Wire.onReceive(receiveEvent);
}
void loop(){
// 找卡
if ( ! rfid.PICC_IsNewCardPresent())
return;
// 验证NUID是否可读
if ( ! rfid.PICC_ReadCardSerial())
return;
MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
// 将NUID保存到nuidPICC数组
for (byte i = 0; i < 4; i++) {
nuidPICC = rfid.uid.uidByte;
Serial.print(nuidPICC);
}
Serial.println();
if (nuidPICC==21&& nuidPICC==17&& nuidPICC==48&& nuidPICC==105) { //改成自己卡的uid10
open();
}
rfid.PICC_HaltA();// 使放置在读卡区的IC卡进入休眠状态,不再重复读卡
rfid.PCD_StopCrypto1();// 停止读卡模块编码
}
=========================================
主机:
#define BLINKER_PRINT Serial
#define BLINKER_WIFI
#include <Wire.h>
#include <Blinker.h>
char auth[] = "5075ce7143f3";
char ssid[] = "616";
char pswd[] = "lsq1439374642";
// 新建组件对象
BlinkerButton Button1("btn-abc");
BlinkerNumber Number1("num-abc");
BlinkerButton Button2("btn-open");
int counter = 0;
// 按下按键即会执行该函数
void button1_callback(const String & state) {
BLINKER_LOG("get button state: ", state);
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}
void button2_callback(const String & state) {
BLINKER_LOG("get button state: ", state);
Wire.beginTransmission(8);
Wire.write("open");
Wire.endTransmission();
digitalWrite(LED_BUILTIN,LOW);
delay(500);
digitalWrite(LED_BUILTIN,HIGH);
}
// 如果未绑定的组件被触发,则会执行其中内容
void dataRead(const String & data)
{
BLINKER_LOG("Blinker readString: ", data);
counter++;
Number1.print(counter);
}
void setup() {
// 初始化串口
Serial.begin(115200);
Wire.begin(D1, D2);
#if defined(BLINKER_PRINT)
BLINKER_DEBUG.stream(BLINKER_PRINT);
#endif
// 初始化有LED的IO
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
// 初始化blinker
Blinker.begin(auth, ssid, pswd);
Blinker.attachData(dataRead);
Button1.attach(button1_callback);
Button2.attach(button2_callback);
}
void loop() {
Blinker.run();
}
中断里delay。。。。。 XlinliY.Zhang 发表于 2021-10-29 11:30
中断里delay。。。。。
什么意思? callback这种回调函数属于中断类函数,里面不能用delay这种函数,可以设置一个标志量,比如flag,然后在loop循环中,根据flag的值,进行相应操作。时间有些远了,不知道对您是否还有帮助 LegendYang 发表于 2021-12-11 22:50
callback这种回调函数属于中断类函数,里面不能用delay这种函数,可以设置一个标志量,比如flag,然后在loo ...
感谢!回调是指从机的receiveEvent吗?最近没空,过两天我试一试 我说的回调函数是void button2_callback(const String & state) ,这个是blinker的回调函数。
不管是主机还是从机,都有这个问题,所有跟中断相关的函数,里面都不要出现delay,也尽量不要出现serial.print()这类函数。我记得ESP8266哪里提到过中断函数的执行时间不能超过1ms。您对照看一下您的函数。
还有一点,就是您的从机函数里面delay时间太长了,这么长的时间,可以用其他方法来做,比如定时器,因为delay函数执行期间,整个机器是什么都做不了的,delay几个ms就差不都了
页:
[1]