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

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1355|回复: 6

无法用8266连接uno控制舵机转动

[复制链接]
发表于 2021-10-29 00:37 | 显示全部楼层 |阅读模式
本帖最后由 逆天鲨鱼头 于 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[4];// 初始化数组用于存储读取到的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:ICC_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[0]==21&& nuidPICC[1]==17&& nuidPICC[2]==48&& nuidPICC[3]==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();
}





发表于 2021-10-29 11:30 | 显示全部楼层
中断里delay。。。。。
 楼主| 发表于 2021-10-29 12:27 | 显示全部楼层
XlinliY.Zhang 发表于 2021-10-29 11:30
中断里delay。。。。。

什么意思?
发表于 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吗?最近没空,过两天我试一试
发表于 2021-12-11 23:01 | 显示全部楼层
我说的回调函数是void button2_callback(const String & state) ,这个是blinker的回调函数。
不管是主机还是从机,都有这个问题,所有跟中断相关的函数,里面都不要出现delay,也尽量不要出现serial.print()这类函数。我记得ESP8266哪里提到过中断函数的执行时间不能超过1ms。您对照看一下您的函数。
还有一点,就是您的从机函数里面delay时间太长了,这么长的时间,可以用其他方法来做,比如定时器,因为delay函数执行期间,整个机器是什么都做不了的,delay几个ms就差不都了
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 08:50 , Processed in 0.150542 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表