Search code examples
arduinostatestate-machinearduino-c++

How to perform an action only when a state is changed?


Basically I want to make my IR led send one code when the Bluetooth connection state is CONNECTED. When the connection state becomes DISCONNECTED, the IR led should send a different code once. However, my code keeps sending one IR code continuously. When the Bluetooth state has changed, it keeps sending the other IR code continuously.

How can I change my code to only send one IR code every time the Bluetooth connection state changes?

#include "BluetoothA2DPSink32.h"
#include <Arduino.h>
#include <IRremoteESP8266.h>
#include <IRsend.h>

const uint16_t kIrLed = 2; 
IRsend irsend(kIrLed);
const uint16_t rawData[71] = {9004, 4556,  534, 602,  506, 654,  490, 624,  514, 1762,  490, 1764,  486, 1768,  516, 1762,  490, 626,  516, 622,  486, 1770,  514, 1762,  492, 1762,  486, 654,  490, 624,  514, 622,  486, 652,  490, 626,  514, 622,  488, 632,  512, 626,  512, 602,  532, 628,  490, 626,  514, 622,  486, 1770,  514, 1744,  510, 1742,  508, 1768,  516, 1762,  490, 1764,  512, 1744,  514, 1762,  492, 41344,  9022, 2298,  508};
const uint16_t rawData2[71] = {9022, 4574,  518, 622,  486, 654,  490, 628,  512, 1762,  490, 1764,  486, 1770,  514, 1762,  490, 626,  514, 622,  488, 1768,  514, 1762,  490, 1744,  506, 654,  490, 624,  516, 622,  486, 652,  492, 1764,  486, 1768,  516, 622,  488, 652,  490, 624,  516, 622,  488, 652,  490, 626,  514, 622,  488, 654,  490, 1764,  486, 1770,  514, 1762,  490, 1764,  486, 1770,  514, 1764,  490, 41360,  9006, 2318,  488};

BluetoothA2DPSink32 a2dp_sink;

void setup() {
  irsend.begin();
  a2dp_sink.set_bits_per_sample(32);  
  a2dp_sink.start("Hifi32bit");   
}

void loop() {
  if (a2dp_sink.get_connection_state()==ESP_A2D_CONNECTION_STATE_CONNECTED) {
    irsend.sendRaw(rawData, 71, 38);
  }

  if (a2dp_sink.get_connection_state()==ESP_A2D_CONNECTION_STATE_DISCONNECTED) {
    irsend.sendRaw(rawData2, 71, 38);
  }
}

Solution

  • The problem is that you're performing the check continuously, and for every check you execute the if-statement in which you send the IR code. Consequently, your application will keep sending IR codes as fast as it can.

    If you only want to send do something (send an IR code) on a state change, you should remember the state, and perform an action on a state change instead.

    This is very easy to implement by adding a variable previous_connection_state. Example code below (this would replace the loop() from your current code).

    esp_a2d_connection_state_t previous_connection_state;
    
    void loop() {
        esp_a2d_connection_state_t connection_state = a2dp_sink.get_connection_state();
    
        if (connection_state != previous_connection_state) {
    
            if (connection_state == ESP_A2D_CONNECTION_STATE_CONNECTED) {
                irsend.sendRaw(rawData, 71, 38);
            }
    
            if (connection_state == ESP_A2D_CONNECTION_STATE_DISCONNECTED) {
                irsend.sendRaw(rawData2, 71, 38);
            }
    
            previous_connection_state = connection_state;
        }
    }