无法用8266连接uno控制舵机转动-Arduino中文社区 - Powered by Discuz! Archiver

逆天鲨鱼头 发表于 2021-10-29 00:37

无法用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();
}





XlinliY.Zhang 发表于 2021-10-29 11:30

中断里delay。。。。。

逆天鲨鱼头 发表于 2021-10-29 12:27

XlinliY.Zhang 发表于 2021-10-29 11:30
中断里delay。。。。。

什么意思?

LegendYang 发表于 2021-12-11 22:50

callback这种回调函数属于中断类函数,里面不能用delay这种函数,可以设置一个标志量,比如flag,然后在loop循环中,根据flag的值,进行相应操作。时间有些远了,不知道对您是否还有帮助

逆天鲨鱼头 发表于 2021-12-11 22:52

LegendYang 发表于 2021-12-11 22:50
callback这种回调函数属于中断类函数,里面不能用delay这种函数,可以设置一个标志量,比如flag,然后在loo ...

感谢!回调是指从机的receiveEvent吗?最近没空,过两天我试一试

LegendYang 发表于 2021-12-11 23:01

我说的回调函数是void button2_callback(const String & state) ,这个是blinker的回调函数。
不管是主机还是从机,都有这个问题,所有跟中断相关的函数,里面都不要出现delay,也尽量不要出现serial.print()这类函数。我记得ESP8266哪里提到过中断函数的执行时间不能超过1ms。您对照看一下您的函数。
还有一点,就是您的从机函数里面delay时间太长了,这么长的时间,可以用其他方法来做,比如定时器,因为delay函数执行期间,整个机器是什么都做不了的,delay几个ms就差不都了
页: [1]
查看完整版本: 无法用8266连接uno控制舵机转动