How can I create a condition for triggering void loop when proximity sensor state changes

I am working with inductive proximity sensor and bolt locks.
In the void loop, I have setup the code in a way that when the proximity sensor detects the metal, bolt lock is on(locked) and when no metal its off(unlocked).

Also, I want to control my bolt locks from mqtt. I have setup a json for that and when i send commands from my laptop it changes the state for boltlock for a second and goes back to loop where proximity sensor conditions are written.

Is there a way to hold the bolt lock state until proximity sensor status is changed?

Here is my code.


#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>
#include <string.h>
#include <ArduinoJson.h>

// proxy sensor code

int proxy0 = 21;
int state0 = LOW;
// proxy sensor code end

//Bolt lock code

int lock1=7; 
int lock2=27;

//Bolt lock code end

// Update these with values suitable for your network.
byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 61);
const char* server = "192.168.1.3";

EthernetClient ethClient;
PubSubClient mqttClient(ethClient);

StaticJsonDocument<258>  pub_json;
StaticJsonDocument<500>  sub_json;

void callback(char* topic, byte* payload, unsigned int length) {
  //strlcpy(name, doc["name"] | "default", sizeof(name));
  Serial.println("Enter callback");
   Serial.println(length);

  deserializeJson(sub_json, payload, length);
int sub_array = sub_json["status"].size();
String extinsion_id = sub_json["extinsion"];
String door_state=String(sub_json["status"][0]["door"]);
String lock_state=String(sub_json["status"][0]["lock"]);

// for controlling bolt locks from mqtt

  int p =(char)payload[0]-'0';

  if(p==0)

  {

        digitalWrite(lock1,LOW); 
        digitalWrite(lock2,LOW);

    Serial.println("Lock is closed ");
     delay(5000);
   }

if(p==1)

  {

        digitalWrite(lock1,HIGH); 
        digitalWrite(lock2,HIGH);

    Serial.println("Lock is open");
      delay(5000);

  
  }
  

Serial.println();

Serial.print("extinsion number");Serial.println(extinsion_id);
Serial.print("door_state");Serial.println(door_state);
Serial.print("lock_state");Serial.println(lock_state);
}

void setup() {
  // Open serial communications and wait for port to open:
  Ethernet.init(17);
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  Ethernet.begin(mac, ip);
  // Allow the hardware to sort itself out
  delay(1500);

  mqttClient.setServer("192.168.1.3", 1883);
  mqttClient.setCallback(callback);


  if (mqttClient.connect("arduino-1")) {
    // connection succeeded
    Serial.println("Connected ");
    boolean r = mqttClient.subscribe("/bob/status");
    Serial.println("subscribe ");
    Serial.println(r);
  }
  else {
    Serial.println("Connection failed ");
  }

// for bolt locks
    pinMode(lock1,OUTPUT);   
    pinMode(lock2, OUTPUT);

}


void loop() {
  
 
  int val = digitalRead(proxy0);
      if (val != state0) {
          state0 = val;
          
      }
    
    if ( state0 == LOW ) {
        char bufferout[128];
        int b =serializeJson(pub_json, bufferout);
        JsonArray array = pub_json.to<JsonArray>();
        pub_json.add("Not detected");
        digitalWrite(lock1,HIGH); 
        digitalWrite(lock2,HIGH);
        pub_json.add("Lock");
        boolean rc = mqttClient.publish("BOB", bufferout);
        Serial.println(bufferout);
      }

    else {
        char bufferout[128];
        int b =serializeJson(pub_json, bufferout);
        JsonArray array = pub_json.to<JsonArray>();
        pub_json.add("Detected");
        digitalWrite(lock1,LOW); 
        digitalWrite(lock2,LOW);
        pub_json.add("Lock");
        boolean rc = mqttClient.publish("BOB" , bufferout);
        Serial.println(bufferout);
    }
      
    delay(1000);
    mqttClient.loop();
   

  
  delay(1000);
}

what do you mean by "hold the bolt lock state"?
do you want to change the bolt lock state to match the sensor state?

No, I want to change it according to my requirment from the mqtt and the program in void loop shoud not run until the proxy sensor state (metal or no matal) changes.

so you want to ignore the mqtt request until the proxy sensor state changes?

despite the test for a change in proxy sensor state, the following conditional code is always invoked regardless is there is a change

consider this fragment which only processes the conditional code when there is a change in sensor state

void loop() {
    int val = digitalRead(proxy0);
    if (val == state0)
        return;

    state0 = val;

    if ( state0 == LOW ) {
        char bufferout[128];
    ...

No, I think i am not good at explaining :sweat_smile:

Let me try one more time. i want my command from mqtt to work as a switch. which is below

 if(p==0)

  {

        digitalWrite(lock1,LOW); 
        digitalWrite(lock2,LOW);

    Serial.println("Lock is closed ");
     delay(5000);
   }

if(p==1)

  {

        digitalWrite(lock1,HIGH); 
        digitalWrite(lock2,HIGH);

    Serial.println("Lock is open");
      delay(5000);

  
  }

when i press the switch it shoud trigger an inturrupt and stop the conditions for locks i have writtin for locks with proxy sensor in void loop which is below.

int val = digitalRead(proxy0);
      if (val != state0) {
          state0 = val;
    }
    
    else if ( state0 == HIGH ) {
        digitalWrite(lock1,LOW); 
        digitalWrite(lock2,LOW);
       
    }

    else if ( state0 == LOW ) {
      
        digitalWrite(lock1,HIGH); 
        digitalWrite(lock2,HIGH);
    }
    

this second part of the code is in void loop and i want to setup a condition in a way that when i send a comman. the program should not run the void loop intil the proxy sensor's last state changes.

here's an opportunity to practice. sometimes it's more important that learning to code


do you want an mqtt cmd to en/disable the locking mechanism that reacts to the proximity switch?

i'm not familiar with mqtt nor json. it looks like your generating a msg, not receiving one

Yes i will work on that.

for the program part.
I have created 2 Json, pub_json is for sending message from microcontroller to mqtt.
and sub_json is for sending message to microcontroller.

I am sending 1 and 0 to microcontroller.

If i send "1" locks will open but

else if ( state0 == HIGH ) {
        digitalWrite(lock1,LOW); 
        digitalWrite(lock2,LOW);

becase of this part in the void loop it gets locked again!

i want to disable locking mechanism that reacts to the proximity switch until proxymity state changes.

very confusing what you mean by "enable" and what may cause the locks to "unlock"

and "change" from what to what or any change.

can you describe a scenario for how it would be used?

one possibility and "enable" mqtt msg is received that allows the proximity sensor to unlock the locks multiple times

another is similar to above, but only allows the proximity sensor to unlock once, disabling the mechanism until another enable msg

or the "enable" msg unlocks the mechanism after the proximity sensor becomes "active"

or does the proximity sensor send a mqtt msg and a received msg unlocks the mechanism