简体   繁体   English

Arduino Servo 在 setup function 中工作但不使用蓝牙命令

[英]Arduino Servo working in setup function but not with bluetooth command

i am experiencing a very strange issue, i wrote code for arduino UNO 3 which is designed to unlock door using servo motor, components attached are following我遇到了一个非常奇怪的问题,我为 arduino UNO 3 编写了代码,该代码旨在使用伺服电机解锁门,附带的组件如下

  1. Servo Motor伺服马达
  2. 1 Red Led (for failure alert) 1 个红色 LED(用于故障警报)
  3. 1 Green Led (for success alert) 1 个绿色 LED(用于成功提醒)
  4. 1 Buzzer (for audible alert on unlock) 1 个蜂鸣器(解锁时发出声音警报)

The code is following代码如下

#include <Arduino_JSON.h>
#include <SoftwareSerial.h>
#include <EEPROM.h>
#include <Servo.h>

String com = "";

const int buzzer    = 6;
const int ledfalse  = 8;
const int ledtrue   = 13;
const int servo     = 11;

Servo myservo;
SoftwareSerial mySerial(2, 3);

void ResetAdmin()
{
    for (int i = 0 ; i < EEPROM.length() ; i++)
            EEPROM.write(i, 0);

    Blink(ledtrue, 2);
}

void WriteAdmin(String admin)
{
    byte len = admin.length();
    EEPROM.write(0, len);
    for (int i = 0; i < len; i++)
    {
        EEPROM.write(i + 1, admin[i]);
    }
    
    Blink(ledtrue, 2);
}

String ReadAdmin()
{
    int newStrLen = EEPROM.read(0);
    char data[newStrLen + 1];
    for (int i = 0; i < newStrLen; i++)
    {
        data[i] = EEPROM.read(i + 1);
    }
    
    data[newStrLen] = '\0';
    return String(data);
}

void Unlock()
{
    Alert();
    myservo.write(0);
    delay(500);
    myservo.write(90);
    delay(6500);
    myservo.write(360);
    delay(500);
    myservo.write(90);
}

void Blink(int type, int times)
{
      for(int i = 1; i <= times; i++)
      {
            digitalWrite(type, HIGH);
            delay(80);
            digitalWrite(type, LOW);
            delay(80);
      }
}

void Alert()
{
      for(int i = 1; i <= 4; i++)
      {
            tone(buzzer, 1000);
            delay(80);
            noTone(buzzer);
            delay(80);
      }
}

void ProcessCommand(String command)
{
      if(command == "unlock")
            Unlock(); //not works here
      else if(command == "reset")
            ResetAdmin();
      else
      {
            Blink(ledfalse, 2);
      }
}

void setup() 
{ 
    myservo.attach(servo);
    mySerial.begin(9600);

    pinMode(buzzer, OUTPUT);
      pinMode(ledfalse, OUTPUT);
      pinMode(ledtrue, OUTPUT);
     //Unlock() or Blink(ledtrue, 4) or Alert() works here    

    digitalWrite(ledtrue, HIGH);
    digitalWrite(ledfalse, HIGH);
    delay(3000);
    digitalWrite(ledtrue, LOW);
    digitalWrite(ledfalse, LOW);
}

void loop()
{
    while(mySerial.available() > 0)
      {
            delay(10);
            com += (char)Serial.read();
      }
    
      if(com.length() > 0)
      {
            JSONVar doc = JSON.parse(com);

            if (JSON.typeof(doc) != "undefined") 
            {
                  String admin = ReadAdmin();
                  if(admin == "")
                  {
                        admin = doc["admin"];
                        WriteAdmin(admin);
                  }
            
                  if(admin == doc["admin"])
                  {
                        ProcessCommand((const char*) doc["command"]);
                  }
                  else
                  {
                        Blink(ledfalse, 2);
                  }
            }
            else
            {
                  Blink(ledfalse, 2);
            }
        
            com = "";
      }
    
      delay(10);
}

The java snippet for sending command is following发送命令的 java 片段如下

private void Unlock() {
        if (btSocket != null) {
            try {
                String payload = "{\"admin\": \"" + getUUID() + "\", \"command\": \"unlock\"}";
                btSocket.getOutputStream().write(payload.getBytes());
            } catch (Exception e) {
                e.printStackTrace();
                biometricLoginButton.setImageResource(R.drawable.warning);
                failed = true;
                Toast.makeText(getBaseContext(), "Error occurred while unlocking", Toast.LENGTH_SHORT).show();
            }
        } else {
            Toast.makeText(getBaseContext(), "Door Lock not connected", Toast.LENGTH_SHORT).show();
            biometricLoginButton.setImageResource(R.drawable.warning);
            failed = true;
        }
    }

The issue is when i put the Alert() , Unlock() & Blink() function in the Arduino setup function then alert is working fine and so do the other two, but when the same functions called using Bluetooth signal none of them works.问题是当我将Alert()Unlock()Blink() function 放入 Arduino 设置 function 时,警报工作正常,其他两个也是如此,但是当使用蓝牙信号调用相同的函数时,它们都不起作用。 Note that the function is called as servo try to move but not correctly, this shows that Bluetooth is receiving data correctly from android and conditions are being evaluated correctly.请注意,function 被称为伺服尝试移动但不正确,这表明蓝牙正在从 android 正确接收数据并且正在正确评估条件。

Finally i myself figured out the issue, basically the problem was with the EEPROM of the Arduino the problematic section of the code is following最后我自己弄清楚了问题,基本上问题出在 Arduino 的 EEPROM 代码的问题部分如下

String admin = ReadAdmin();
if(admin == "")
{
     //on first run it never returned empty string, may be my reading function bug
     admin = doc["admin"];
     WriteAdmin(admin);
}
            
if(admin == doc["admin"])
{
     //due to garbage value compared with actual one this block never executed
     rocessCommand((const char*) doc["command"]);
}
else
{
     Blink(ledfalse, 2);
}

First condition is for the first run so that when there is no admin stored in the EEPROM, then store the one coming in the JSON, but i don't know why but it was always some garbage value instead of empty or null string that's why the admin was not being matched eg the garbage value and the one received in JSON and thus not running the Unlock sequence第一个条件是第一次运行,这样当 EEPROM 中没有存储管理员时,然后存储 JSON 中的管理员,但我不知道为什么,但它总是一些垃圾值而不是空或 null 字符串,这就是为什么管理员不匹配,例如垃圾值和 JSON 中收到的值,因此不运行解锁序列

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM