javac++arduinoarduino-unohc-05

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

  1. Servo Motor
  2. 1 Red Led (for failure alert)
  3. 1 Green Led (for success alert)
  4. 1 Buzzer (for audible alert on unlock)

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

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. 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.


Solution

  • 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

    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 e.g. the garbage value and the one received in JSON and thus not running the Unlock sequence