Arduino Servo 在设置功能中工作但不使用蓝牙命令

Arduino Servo working in setup function but not with bluetooth command

我遇到了一个非常奇怪的问题,我为 arduino UNO 3 编写了代码,该代码旨在使用伺服电机解锁门,附带的组件如下

  1. 伺服电机
  2. 1 个红色 LED(用于故障警报)
  3. 1 个绿色 LED(用于成功提醒)
  4. 1 个蜂鸣器(解锁时发出声音警报)

代码如下

#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] = '[=10=]';
    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);
}

发送命令的 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;
        }
    }

问题是,当我将 Alert()Unlock()Blink() 函数放入 Arduino 设置函数中时,警报工作正常,其他两个也是如此,但是当使用蓝牙信号 none 调用的相同函数有效。请注意,该函数被称为伺服尝试移动但不正确,这表明蓝牙正在从 android 正确接收数据并且正在正确评估条件。

最后我自己弄清楚了问题,基本上问题出在 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);
}

第一个条件是第一个运行,这样当EEPROM中没有存储admin时,然后存储进入JSON的admin,但我不知道为什么但是它总是一些垃圾值而不是空字符串或空字符串,这就是管理员未被匹配的原因,例如垃圾值和在 JSON 中收到的值,因此没有 运行 解锁序列