Stubborn RF433 Mhz remote control

Guys, I tested a 433 Mhz garage remote again using the RCswitch.h library

My problem is that the control sends signal bursts. And I think that's why I can't toggle the state of the testX variable as I'd like.

What I need is that: When I press the button and keep it pressed (code sent is final 869) testX is equal to 1. When I release the button, testX has to be equal to 2. It can be equal to 2 when I press the button again.

That is, alternation 1 and 2 can only occur when I release the button and press it again.

As it is, just keep the button pressed for testX to vary between 1 and 2 indefinitely.

And I think it's the very nature of the remote that sends out bursts as if we were pressing and releasing quickly.

How to make ?

Thanks

#include <Arduino.h>
#include <SPI.h>
#include <RCSwitch.h>

RCSwitch mySwitch = RCSwitch();
int testX;
boolean state = 1;
  
void setup() {
  Serial.begin(115200);
  mySwitch.enableReceive(0);  // Receiver on interrupt 0 => that is pin #2
}

void loop() {
  
  if (mySwitch.available()) {
    
    int value = mySwitch.getReceivedValue();
    
    if (value == 0) {
      Serial.print("Unknown encoding");
    } else {
   
      Serial.print("Received ");
      Serial.print( mySwitch.getReceivedValue() );
      Serial.print(" / ");
      Serial.print( mySwitch.getReceivedBitlength() );
      Serial.print("bit ");
      Serial.print("Protocol: ");
      Serial.println( mySwitch.getReceivedProtocol() );
    }  
    
    if(mySwitch.getReceivedValue() == 140160869) {
       state = !state; 
       switch(state) {
       case 0: // caso esteja apagado
         testX = 1;
       break;
       case 1: // caso esteja aceso
         testX = 2;
       break;  
    }
    while (!mySwitch.getReceivedValue() == 140160869) {}
    delay(150);
  }
    Serial.println(testX);

    mySwitch.resetAvailable();   
  }
}

The first time you get the valid message, do the thing you want because you got a valid message, and set a timer to the current value of millis().

Every time you get a valid message, see if enough time has gone by since the last one so you know it is a new message meant to do the thing again, and not a liked on message from a burst.

If sufficient time has gone by, treat it like the first press.

If not… reset the timer. So the timer gets set every time you get a valid message, and sorta moves along with the burst to make it so the next message is too early to be valid if it arrives shortly after the preceding. Message.

Eventually, the new message arrives to find that enough time has gone by. Because you got your finger off the button and gave it time.

Sry, typing into the little window and I see my description starting to repeat itself, so please try to make sense of it. I'll see later when I am at a bigger window.

HTH

a7

alto777

I swear I read it three times and slowly and didn't understand a thing. I have no knowledge.

But I did as below and I think it will work.

if(mySwitch.getReceivedValue() == 140160869) {
         testX = 1;
    }
  }
    Serial.println(testX);

    mySwitch.resetAvailable();   
    delay(100);
    testX = 2;
}

Please describe what you want to do using the remote.

I thought the intent was to get it to alternate printing '1' and '2' as you pressed a button on the remote. One press, '1', next press '2' and so forth.

And that your original program would misbehave and just print 1 then 2 then 1 if you kept the button pressed.

Does your new code work any better?

a7

"When I release the button, testX has to be equal to 2"

In this part of my first post I explained this.

Thank you very much for taking care of my problem.

But I would like to see this idea of ​​yours that would meet the second good option which would be to switch between 1 and 2 according to the button press.

Dear friend alto777 no need, it worked here for me.

Very grateful for your attention.

I need the LEDBUILTIN to go HIGH when I press the button i.e. when testX == 1.

To turn off the led I have to release the same button and press it again

A new press (press and release), LED lights up. One more press and release, LED goes off.

But without using else. Using boolean logic.

How do I do it ?

#include <Arduino.h>
#include <SPI.h>
#include <RCSwitch.h>
#include <DMD2.h>

RCSwitch mySwitch = RCSwitch();
int testX;
boolean state = 1;

SPIDMD dmd(1,1);
  
void setup() {
  Serial.begin(115200);
  dmd.begin();
  mySwitch.enableReceive(0);  // Receiver on interrupt 0 => that is pin #2
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  
  if (mySwitch.available()) {
    
    int value = mySwitch.getReceivedValue();
    
    if (value == 0) {
      Serial.print("Unknown encoding");
    } else {
   
      Serial.print("Received ");
      Serial.print( mySwitch.getReceivedValue() );
      Serial.print(" / ");
      Serial.print( mySwitch.getReceivedBitlength() );
      Serial.print("bit ");
      Serial.print("Protocol: ");
      Serial.println( mySwitch.getReceivedProtocol() );
    }  
    
    if(mySwitch.getReceivedValue() == 140160869) {
         testX = 1;
    }
  }
    Serial.println(testX);

    mySwitch.resetAvailable();   
    delay(100);
    testX = 2;

    if(testX == 1) {
    digitalWrite(LED_BUILTIN, HIGH); 
    }

    if(testX == 2) {
      digitalWrite(LED_BUILTIN, LOW); 
    }
    
}

I'm about to pick up a hammer and put an end to everything around here.

I tried everything.

The closest I could get was this (code below). When I press the button on the 433Mhz remote the state of testX changes each time.

But if I keep the testX button pressed, it changes by itself. This is the error.

What I'm looking for is to change the state of testX ONLY when I release the button. If you keep the button pressed nothing should happen to testX.

Anybody know ?

#include <Arduino.h>
#include <SPI.h>
#include <RCSwitch.h>
#include <DMD2.h>

RCSwitch mySwitch = RCSwitch();
int testX,cron;

void setup() {
  Serial.begin(115200);
  mySwitch.enableReceive(0);  // Receiver on interrupt 0 => that is pin #2
}

void loop() {
  
  if (mySwitch.available()) {
    
    int value = mySwitch.getReceivedValue();
    
    if (value == 0) {
      Serial.print("Unknown encoding");
    } else {
   
//      Serial.print("Received ");
//      Serial.print( mySwitch.getReceivedValue() );
//      Serial.print(" / ");
//      Serial.print( mySwitch.getReceivedBitlength() );
//      Serial.print("bit ");
//      Serial.print("Protocol: ");
//      Serial.println( mySwitch.getReceivedProtocol() );
    }  

    if(mySwitch.getReceivedValue() == 140160869) {
         cron++;
         delay(100);
         if(cron > 1) {
          cron=0;
         } 
    } 
    Serial.print(cron);Serial.print("   ");Serial.println(testX);
  
  }
    
    mySwitch.resetAvailable();   
    delay(20);
   
    if(cron==1){
      testX = 2;
    }
    if(cron==0){
      testX = 1;
    }
          
}

Take a look at this

State Change Detection Tutorial

I think the same or similar code is in the IDE examples near the beginning of the listings you get, look for "state change detection".

Basically you need to see and track two conditions your input device can provide

  • a valid and matching massage to act upon

and

  • no valid message (or different message)

So...

Once you get a valid message, do something. Don't do that something again, even if you get a valid message, until you have seen the input device report "no code" or a message you don't want to react to.

The message / no message are analogous to the button being pressed or not pressed in the state change algorithm.

something is in your case changing the value of trstX from 1 to 2 or back from 2 to 1. One action per state change detected. One action when you press the button, and no action until you have been seen to be off the button, and then back on again.

You almost there, this stuff can be hard until it is easy.

a7

Dear Alto777, it's the bursts emitted by 433Mhz that are disturbing... and a lot

It also works if it's like this: I press the button, testX=1
I release the button, nothing happens.
I press the button again, testX=2

What cannot be testX is 1-2 or 2-1 if the button remains pressed

Have you looked at the state change detection tutorial?

What messages do you get from the device if you keep you finger on the button?

Just print all the input you get. Presumably you get "Unknown encoding", 0, or some value that either is or is not 140160869.

Please just run a simple if/else and nothing else, like this below what was in your code. Do nothing else. I haven't your hardware and it isn't clear to me what you are getting as input.

Then tell us, and be sure to note where in the traffic printed you were on or off the button.

  if (mySwitch.available()) {
    
    int value = mySwitch.getReceivedValue();
    
    if (value == 0) {
      Serial.print("Unknown encoding");
    } else {
   
      Serial.print("Received ");
      Serial.println( mySwitch.getReceivedValue() );

//      Serial.print(" / ");
//      Serial.print( mySwitch.getReceivedBitlength() );
//      Serial.print("bit ");
//      Serial.print("Protocol: ");
//      Serial.println( mySwitch.getReceivedProtocol() );
    }  

But srsly, this is state change detection time, with a remote possibility of having to add some kind of timed lockout. Only knowing what your input looks like will help.

a7

When I press the button I get the code 140160869. When I release the button I get nothing.

The bursts work as if we were pressing and releasing a psuh-button several times per second. This you know very well.

And that's all that's holding me back in this sea of ​​failure.

I tried to put a stopwatch, and say that if cron > 5 then testX = 1. But I need to reset the stopwatch by setting cron = 0;

When I reset it, I go back to the problem of looping if I keep the button pressed forever.


mySwitch.resetAvailable();
    delay(200);
    
    Serial.print(cron);Serial.print("   ");Serial.println(testX);
     
    if(cron>2){
      testX = 2;
      cron=0;
    }
    if(cron>1 && testX==2){
      testX = 1;
      cron=0;
    }

When you receive the message 140160869, react to it if enough time has gone by, and set a timer to the current value of mills(), check the elapsed time since the last reception:

  if (milis() - lastMessageTime > 500) {
      // react to a new valid message
      // however
  }

 // and in either case, move the timer up to now
  lastMessageTime = millis();

Since lastMessageTime starts at zero (a global unsigned long variable is initially 0), the very first press will always come long enough later to be seen, so not a psecial case.

Nutshell:

If enough time has elapsed, react to the message. If insufficient time has gone by, reset the timer to the current value of millis(). Always set the timer so we have to see a gap before reacting to a message that may have come too soon.

This is a basic standard pattern involving millis(). If it baffles you yet, please google

  using millis arduino

and poke aroind a bit for something that matches your learning style and level of knowledge.

a7

It's not as easy as it appears to be.

I will include a second button, every garage key fob has at least two buttons. I wanted to use only one but it won't hurt to use two.

Thank you very much for your attention and study material. I will value.

I never argue with success.

If you post a working solution using two codes from the remote control, I will post a version that does the same with one code, using one or both of the ideas I float past you.

I know this is going into a larger context, that is irrelevant. Just post a small example like you have been working on, that you may have right there.

a7