Hi people!
I'm using a CY64 RF RC receiver tied up to an Arduino Pro Micro to read an OOK RF 432.92 MHz remote control transmitter.
The goal is to implement a "remote toggle switch" for test equipment.
Using the RCSwitch library, downloaded from GitHub - sui77/rc-switch: Arduino lib to operate 433/315Mhz devices like power outlet sockets. , my goal is to ignore further received codes from the same burst as the first was read.
For that, I implemented the code below, whose strategy is to measure the time from the last code read to the present one.
New code is accepted only if this time is large enough to guarantee it's from another burst, i.e., if the operator has released and pushed the transmitter button again.
The CY64 is similar to this: https://www.rficy.com/upload/file/20231031/6383434201183461692781707.pdf
The interval between codes of the same burst is ~11 ms and the code is ~40 ms.
But the program cannot do the job. Every time I press and hold the transmitter button, there are multiple code readings( see below the Serial Monitor output ).
Have someone any idea why that is happening?
Thanks a lot.
/*
Electric Diagram:
+------------------+ +----------------------+
| CY64 | | Arduino Pro Micro |
| |3 | |
| +5V +---------------+ +5V |
| | | |
| |5 | |
| DATA +------->>>-----+ D7 |
| | | |
| |6 | |
| GND +---------------+ GND |
| | | |
+------------------+ +----------------------+
Arduino Pro Micro is powered by USB
RC is powered by +5V from Arduino Pro Micro
*/
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
//--------------------------- External Files includes ---------------------------
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
/* ----------------------- System includes ----------------------------------*/
#include <stdbool.h> // bool, ...
#include <stddef.h> // NULL, __null, ...
#include <string.h> // memchr(), memcmp(), memcpy(), memset(), strcmp() ...
#include <stdint.h> // uint32_t, uint8_t, ...
#include <stdlib.h> // abs(), atof(), atoi(), ...
#include <stdio.h> // puts(), printf(), putchar(), EOF, ...
#include <limits.h> // SHRT_MAX, SHRT_MIN, USHRT_MAX, etc.
#include <ctype.h> // isalnum, isalpha, iscntrl, isdigit, isgraph, islower, isprint, ispunct, isspace, isupper, isxdigit etc.
#include <math.h> // sin(), cos(), tan(), fabs(), exp(), pow(), sqrt(), log(), log10() etc.
#include <assert.h> // assert()
/* ----------------------- Platform includes ---------------------------------*/
/* ----------------------- Library includes ----------------------------------*/
#include <RCSwitch.h>
/* ------------------------- App includes ------------------------------------*/
/* ----------------------- This file include ---------------------------------*/
//------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------
//
// ***************************************
// * *
// * *** General Definitions *** *
// * *
// ***************************************
//
// *
// * *** Hardware Pins *** *
// *
// RC read input pin
#define RCSWITCH_RCVR_PIN 7
// Inputs
// Outputs
// ****************************************
// * *
// * *** Arduino Serial Ports *** *
// * *
// ****************************************
// With USE_SERIAL_MONITOR defined, program information is sent to Serial Monitor
// Commenting below line prevents information sending to Serial Monitor
#define USE_SERIAL_MONITOR
#if defined( USE_SERIAL_MONITOR )
#define SerialBegin( x ) Serial.begin( x )
#define SerialPrint( x ) Serial.print( x )
#define SerialPrintln( x ) Serial.println( x )
#define SerialPrintType( x, y ) Serial.print( x, y )
#define SerialPrintlnType( x, y ) Serial.println( x, y )
// #define SERIAL_MONITOR_BAUD_RATE 19200 // This baud rate is suitable for use with slow USB HUBs / USB to RS232 converters
#define SERIAL_MONITOR_BAUD_RATE 115200
#else
#define SerialBegin( x )
#define SerialPrint( x )
#define SerialPrintln( x )
#define SerialPrintType( x, y )
#define SerialPrintlnType( x, y )
#endif
// *
// * *** RCSwitch library configurations *** *
// *
#define HT6P20_PROTOCOL 6
#define TE 470 // µs. Elementary time of the RC
#define SYNC_PULSES 1 // HT6P20 Protocol
#define INTER_FRAME_PAUSE_TEs 23 // HT6P20 Protocol
#define CODE_PULSES 28 // HT6P20 Protocol. 24 code bits + 4 Anti-code bits
#define CODE_SPACING_ms ( ( ( SYNC_PULSES + INTER_FRAME_PAUSE_TEs ) * TE ) / 1000 ) // ms. Interval between 2 consecutive codes of the same burst.
#define CODE_FRAME_TIME_ms ( ( CODE_PULSES * TE ) / 1000 ) // ms. Approximate time length of a code frame.
#define INTER_BURST_TIME_ms ( ( CODE_SPACING_ms + CODE_FRAME_TIME_ms ) * 5 ) // '* 5' is a contingency factor
//------------------------------------------------------------------------------------------------------------------------------------------
//
// *****************************
// * *
// * *** Variables *** *
// * *
// *****************************
//
// *
// * *** Remote Control Radio receptor *** *
// *
RCSwitch CY64_rcvr = RCSwitch() ;
//------------------------------------------------------------------------------------------------------------------------------------------
/***
* _____ ______ ______ __ __ ____
* / ___/ / ____//_ __// / / // __ \
* \__ \ / __/ / / / / / // /_/ /
* ___/ // /___ / / / /_/ ///____/
* /____//_____/ /_/ \____//_/
*
*/
void setup() {
// put your setup code here, to run once:
// ------------------------------------------------------------------------------------------------
// *
// * *** Arduino Pins ***
// *
// Inputs:
// Outputs:
// ------------------------------------------------------------------------------------------------
// *
// * *** Enable and initialize rcSwitch Library ***
// *
CY64_rcvr.enableReceive( digitalPinToInterrupt( RCSWITCH_RCVR_PIN ) );
CY64_rcvr.setProtocol( HT6P20_PROTOCOL ) ; // Emulate HT6P20 Protocol
CY64_rcvr.setPulseLength( 470 ) ; // Te = 470 µs( width of the narrowest pulse )
// ------------------------------------------------------------------------------------------------
// *
// * *** Enable and initialize Arduino Serial Port ***
// *
#ifdef USE_SERIAL_MONITOR
// Wait serial available.
// Needed only for chips that use the embeded USB VCP, like Pro-micro, for instance
while (!Serial) ;
#endif
// Initialize the virtual USB serial port
SerialBegin( SERIAL_MONITOR_BAUD_RATE ) ;
SerialPrintln( F("Program Started!") ) ;
}
/***
* __ ____ ____ ____
* / / / __ \ / __ \ / __ \
* / / / / / // / / // /_/ /
* / /___ / /_/ // /_/ // ____/
* /_____/ \____/ \____//_/
*
*/
void loop() {
// put your main code here, to run repeatedly:
int32_t i32_code = i32_rcReceiveCheck() ;
if ( i32_code > 0 )
{
// new code arrived
// Print what was received
// Decimal
SerialPrint( F("Received string( DEC ): ") ) ;
SerialPrintln( i32_code ) ;
// Hex
SerialPrint( F("Received string( HEX ): 0x") ) ;
SerialPrintlnType( i32_code, HEX ) ;
}
else
{
// Awaiting new code
}
}
// ----------------------------------------------------------------------------------------------------------------------------------------------------------
/***
* ___ _ __ ____ __ _
* / | __ __ _ __ (_)/ /(_)___ _____ __ __ / __ \ ____ __ __ / /_ (_) ___ ___ _____
* / /| | / / / // |/_// // // // __ ` / ___// / / / / /_/ // __ \ / / / // __// // __ \ / _ \ / ___/
* / ___ |/ /_/ //> <// // // // /_/ // / / /_/ / / _, _// /_/ // /_/ // /_ / // / / // __ (__ )
* /_/ |_|\__,_//_/|_//_//_//_/ \__,_//_/ \__, / /_/ |_| \____/ \__,_/ \__//_//_/ /_/ \___/ ____/
* /____/
*/
// ----------------------------------------------------------------------------------------------------------------------------------------------------------
/**
* @name int32_t i32_rcReceiveCheck( void )
* @brief Verify if a RC code is available and reads it
* @param None
* @retval [ i32_receivedCode ]: -1 if no code available or the code itself if available.
*/
int32_t i32_rcReceiveCheck( void )
{
static volatile uint32_t u32_lastReceivedCodeTime ; // Time stamp of the last code received event
static uint32_t u32_lastReceivedCode ; // Last Valid code received
uint32_t u32_timeFromLastCode ; // Elapsed time from the last code received to the present code received
int32_t i32_receivedCode = -1 ; // Function return values. -1 == No valid code received; > 0 = valid code received
noInterrupts() ;
uint32_t u32_presentTime = millis() ;
interrupts() ;
// Wait for code and read it
if ( CY64_rcvr.available() )
{
// Code was received
u32_timeFromLastCode = u32_presentTime - u32_lastReceivedCodeTime ;
u32_lastReceivedCodeTime = u32_presentTime ; // Update for next round
i32_receivedCode = CY64_rcvr.getReceivedValue() ;
CY64_rcvr.resetAvailable() ;
if (
( u32_timeFromLastCode > INTER_BURST_TIME_ms )
// ||
// ( (uint32_t)i32_receivedCode != u32_lastReceivedCode )
)
{
// It's a new code
if ( ( u32_timeFromLastCode >= INTER_BURST_TIME_ms ) )
{
SerialPrint( F("TIMEOUT ==> ") ) ;
SerialPrint( u32_timeFromLastCode ) ;
SerialPrintln( F("ms") ) ;
}
if ( (uint32_t)i32_receivedCode != u32_lastReceivedCode ) SerialPrintln( F("DIFFERENT CODES") ) ;
u32_lastReceivedCode = (uint32_t)i32_receivedCode ;
}
else
{
// NO Timeout or Code of the same burst
// Ignore it
i32_receivedCode = -1 ;
}
}
else
{
// No code available
i32_receivedCode = -1 ;
}
return( i32_receivedCode ) ;
}
// ----------------------------------------------------------------------------------------------------------------------------------------------------------
Serial Monitor output:
14:56:56.064 -> TIMEOUT ==> 5292ms
14:56:56.064 -> Received string( DEC ): 15154197
14:56:56.064 -> Received string( HEX ): 0xE73C15
14:56:56.410 -> TIMEOUT ==> 155ms
14:56:56.410 -> Received string( DEC ): 15154197
14:56:56.410 -> Received string( HEX ): 0xE73C15
14:56:56.799 -> TIMEOUT ==> 156ms
14:56:56.799 -> Received string( DEC ): 15154197
14:56:56.799 -> Received string( HEX ): 0xE73C15
14:56:57.168 -> TIMEOUT ==> 155ms
14:56:57.168 -> Received string( DEC ): 15154197
14:56:57.168 -> Received string( HEX ): 0xE73C15
// ----------------------------------------------------------------------------------------------------------------------------------------------------------
Serial Monitor output:
14:56:56.064 -> TIMEOUT ==> 5292ms
14:56:56.064 -> Received string( DEC ): 15154197
14:56:56.064 -> Received string( HEX ): 0xE73C15
14:56:56.410 -> TIMEOUT ==> 155ms
14:56:56.410 -> Received string( DEC ): 15154197
14:56:56.410 -> Received string( HEX ): 0xE73C15
14:56:56.799 -> TIMEOUT ==> 156ms
14:56:56.799 -> Received string( DEC ): 15154197
14:56:56.799 -> Received string( HEX ): 0xE73C15
14:56:57.168 -> TIMEOUT ==> 155ms
14:56:57.168 -> Received string( DEC ): 15154197
14:56:57.168 -> Received string( HEX ): 0xE73C15