Hello everyone.
I'm having trouble identifying an IC.
I developed a project to test and identify encoders of RF433 remote controls commonly used to open garage doors.
I identified two main types of ICs.
The fixed code encoder HT6P20, no longer recommended due to its ease of being hacked,
and the rolling code encoder HCSxxx. Rolling code - Wikipedia
HT6P20 Datasheet https://pdf.datasheetcatalog.com/datasheets/120/170613_DS.pdf
HCS201 Datasheet https://ww1.microchip.com/downloads/aemDocuments/documents/MCU08/ProductDocuments/DataSheets/41098D.pdf
The project worked very well, I can read the serial numbers of both models and also the encrypted code of the rolling code IC.
I tested it with several controllers and they worked very well.
But I found a controller that did not work with my project, but works correctly with the gate module.
Analyzing the PCB of this controller I identified that it uses an IC with a different pinout.
I did extensive research looking for different types of remote control ICs, I searched with the numbers found on the IC of this control and with numbers found on the PCB of this control, but I couldn't find any datasheet.
It has diferent pinout.
Using a logic analyzer, I got the timing chart of the HCS201 IC and this IC.
Comparing the timing charts, I noticed small differences in timing both in the synchronization block and in the data bits.
With a small modification in the reading times of my project, I was able to read the data from this IC.
But I couldn't find the datasheet of the IC used.
Below are photos of the control, the schematic I created of this control, and the schematic of the project project I built, the timing charts of both ICs (HCS201 and the "VR2A1709" IC).
Although it is unnecessary, I will also post the code I used for this project. It was developed from two codes.
The HT6P20 part was extracted from the RCSwitch.h library example and the HSCxxx part was extracted from the link: Decode Rolling Code 433Mhz Signals with Arduino – Manuel Schütze
I would like to thank you in advance for any help in identifying this IC.
VR2A1709
HCS201
// HCS301 decoder // https://www.manuelschutze.com/?p=333
// Modifiquei no tempo da linha 154 para ler controles do Antilhas
#include <LiquidCrystal_I2C.h> // Biblioteca LCD I2C
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Endereco LCD I2C e pinos Da caixinha
//#include "HT6.h"
bool flagHT6 = true;
#define selectCode 6
unsigned long LED_time = 0;
#define HCS_RECIEVER_PIN 3 //connected to 433Mhz receiver
#define LED 8 //Led pin
class HCS201 {
public:
unsigned BatteryLow : 1;
unsigned Repeat : 1;
unsigned Btn1 : 1;
unsigned Btn2 : 1;
unsigned Btn3 : 1;
unsigned Btn4 : 1;
unsigned long SerialNum;
unsigned long Encript;
void print();
};
volatile boolean HCS_Listening = true;
byte HCS_preamble_count = 0;
uint32_t HCS_last_change = 0;
uint32_t HCS_start_preamble = 0;
uint8_t HCS_bit_counter;
uint8_t HCS_bit_array[66];
uint32_t HCS_Te = 400; //Typical Te duration
uint32_t HCS_Te2_3 = 600; //HCS_TE * 3 / 2
boolean relayOn = false;
unsigned long millisStart = 0;
unsigned long relayDuration = 5 * 60 * 1000; //Duration of relay on
HCS201 hcs201;
//-----------------------------------------------------------------
void setup() {
Serial.begin(115200);
pinMode(selectCode, INPUT_PULLUP);
pinMode(HCS_RECIEVER_PIN, INPUT);
pinMode(LED, OUTPUT);
LED_time = millis();
attachInterrupt(1, HCS_interrupt, CHANGE);
//Serial.println("Setup OK");
lcd.begin(16, 2); // Inicialisa o LCD 16 x 2
if (digitalRead(selectCode) == LOW) {
flagHT6 = true;
lcd.print("HT6 "); // print
setup_HT6();
}
else {
flagHT6 = false;
lcd.print("FOB "); // print
//setup_FOB();
}
}
int myCount = 0;
//-----------------------------------------------------------------
void loop() {
if (flagHT6 == true) {
loopHT6();
}
else {
long CurTime = millis();
if (HCS_Listening == false) {
HCS201 msg; //get message
memcpy(&msg, &hcs201, sizeof(HCS201));
msg.print(); //do something
HCS_Listening = true;
}
}
if (millis() - LED_time >= 100) {
digitalWrite(LED, LOW);
}
else {
digitalWrite(LED, HIGH);
}
if (myCount > 1) {
LED_time = millis();
Serial.println(myCount);
myCount = 0;
}
}
//-----------------------------------------------------------------
void HCS201::print() { //print data from hcs201
String btn;
if (Btn1 == 1) btn += "1";
if (Btn2 == 1) btn += "2";
if (Btn3 == 1) btn += "3";
if (Btn4 == 1) btn += "4";
String it2;
it2 += "Encript=";
it2 += Encript;
it2 += " Serial=";
it2 += SerialNum;
it2 += " Button=";
it2 += btn;
it2 += " BatteryLow=";
it2 += BatteryLow;
it2 += " Rep=";
it2 += Repeat;
//Serial.println(it2);
//Serial.println(SerialNum, HEX);
if ( SerialNum != 0xFFFFFFF) {
lcd.setCursor(0, 0); // Posição linha
lcd.print("SN "); // print
lcd.print(SerialNum, HEX);
lcd.print(" bt ");
lcd.print(btn);
lcd.print(" ");
lcd.setCursor(0, 1); // Posição linha
lcd.print("Cd "); // print
lcd.print(Encript, HEX);
lcd.print(" ");
}
}
//-----------------------------------------------------------------
void HCS_interrupt() { //new data
if (HCS_Listening == false) {
return;
}
uint32_t cur_timestamp = micros();
uint8_t cur_status = digitalRead(HCS_RECIEVER_PIN);
uint32_t pulse_duration = cur_timestamp - HCS_last_change;
HCS_last_change = cur_timestamp;
myCount = HCS_preamble_count;
if (HCS_preamble_count < 12) { // gets preamble
if (cur_status == HIGH) {
if ( ((pulse_duration > 150) && (pulse_duration < 500)) || HCS_preamble_count == 0) {
if (HCS_preamble_count == 0) {
HCS_start_preamble = cur_timestamp;
}
}
else {
HCS_preamble_count = 0;
goto exit;
}
}
else {
if ((pulse_duration > 300) && (pulse_duration < 600)) {
HCS_preamble_count ++;
if (HCS_preamble_count == 12) {
HCS_Te = (cur_timestamp - HCS_start_preamble) / 23;
HCS_Te2_3 = HCS_Te * 3 / 2;
HCS_bit_counter = 0;
goto exit;
}
}
else {
HCS_preamble_count = 0;
goto exit;
}
}
}
if (HCS_preamble_count == 12) { // gets data
LED_time = millis();
if (cur_status == HIGH) {
//if (((pulse_duration > 250) && (pulse_duration < 900)) || HCS_bit_counter == 0) {
if (((pulse_duration > 250) && (pulse_duration < 1100)) || HCS_bit_counter == 0) {
// beginning of data pulse
}
else {
HCS_preamble_count = 0; // incorrect pause between pulses
goto exit;
}
}
else {
// end of data pulse
if ((pulse_duration > 250) && (pulse_duration < 900)) {
HCS_bit_array[65 - HCS_bit_counter] = (pulse_duration > HCS_Te2_3) ? 0 : 1;
HCS_bit_counter++;
if (HCS_bit_counter == 66) { // all bits captured
HCS_Listening = false;
HCS_preamble_count = 0;
hcs201.Repeat = HCS_bit_array[0];
hcs201.BatteryLow = HCS_bit_array[1];
hcs201.Btn1 = HCS_bit_array[2];
hcs201.Btn2 = HCS_bit_array[3];
hcs201.Btn3 = HCS_bit_array[4];
hcs201.Btn4 = HCS_bit_array[5];
hcs201.SerialNum = 0;
for (int i = 6; i < 34; i++) {
hcs201.SerialNum = (hcs201.SerialNum << 1) + HCS_bit_array[i];
};
uint32_t Encript = 0;
for (int i = 34; i < 66; i++) {
Encript = (Encript << 1) + HCS_bit_array[i];
};
hcs201.Encript = Encript;
}
}
else {
HCS_preamble_count = 0;
goto exit;
}
}
}
exit:;
}
// HT6
#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();
unsigned long myCode = 0xFFFFFFFF;
unsigned long myTime = 0xFFFFFFFF;
byte D1;
byte D2;
int ultimo = 3;
//--------------------------------------------------------------
void setup_HT6() {
mySwitch.enableReceive(1); // Receiver on interrupt 1 => that is pin #3
mySwitch.setPulseLength(360); // Largur do pulso
mySwitch.setProtocol(6); // Protocolo usado
mySwitch.setRepeatTransmit(5); // repeticao de transmisao
}
//---------------------------------------------------------------------------------
void useDisplay(unsigned long code) {
D1 = bitRead(code, 4);
D2 = bitRead(code, 5);
lcd.setCursor(0, 0); // Posição linha
lcd.print(code, HEX); // print
lcd.print(" "); // print
lcd.setCursor(9, 0); // Posição linha
lcd.print(code >> 6, HEX); // print
lcd.print(" "); // print
lcd.setCursor(0, 1); // Posição linha
lcd.print(D1, BIN); // print
lcd.print(" "); // print
lcd.print(D2, BIN); // print
lcd.print(" "); // print
lcd.print(mySwitch.getReceivedBitlength()); // print
lcd.print(" "); // print
lcd.print( mySwitch.getReceivedProtocol()); // print
lcd.print(" "); // print
lcd.setCursor(13, 1); // Posição linha
lcd.print((ultimo - 3) / 4); // print
}
//--------------------------------------------------------------
void loopHT6() {
if (mySwitch.available()) {
myCode = mySwitch.getReceivedValue();
//Serial.print(myCode); Serial.print(" / ");
myTime = mySwitch.getReceivedDelay();
//Serial.print(myTime); Serial.print(" / ");
LED_time = millis();
if (myTime > 350) {
/* Serial.print("Received PPA Type ");
Serial.print(myCode >> 6, HEX);
Serial.print(" / ");
Serial.print(bitRead(myCode, 4));
Serial.print(" / ");
Serial.print(bitRead(myCode, 5));
Serial.print(" / ");
Serial.print( mySwitch.getReceivedBitlength() );
Serial.print("bit ");
Serial.print("Protocol: ");
Serial.println( mySwitch.getReceivedProtocol() );
*/
useDisplay(myCode);
}
if (myTime < 350 and myTime > 200) {
/*
Serial.print("Received other Type ");
Serial.print(myCode >> 6, HEX);
Serial.print(" / ");
Serial.print(bitRead(myCode, 4));
Serial.print(" / ");
Serial.print(bitRead(myCode, 5));
Serial.print(" / ");
Serial.print( mySwitch.getReceivedBitlength() );
Serial.print("bit ");
Serial.print("Protocol: ");
Serial.println( mySwitch.getReceivedProtocol() );
*/
useDisplay(myCode);
}
mySwitch.resetAvailable();
}
}