Trying to figure out how to make this message be read twice before turning on relay.
Message is coming from a Keyless Entry Module and a Class 2 Data transciever.
So basically you have to hit the button on the remote twice to activate relay.
This works as is, just wont to have to push button twice.
#include "J1850VPWCore.h"
#define J1850VPW_RX 2 // INT0 on Uno, INT4 on Mega
#define J1850VPW_TX 9
#define SLEEP 5
#define _4XLOOP 7
uint8_t RKE = (0xA8, 0xC7, 0xB0, 0xA0, 0x13);
void setup()
{
Serial.begin(115200);
pinMode(12, OUTPUT);
// MC33390 settings.
pinMode(SLEEP, OUTPUT);
digitalWrite(SLEEP, HIGH); // enable PCI-bus transmitter (receiver is always enabled), HIGH: enable, LOW: disable
// pinMode(_4XLOOP, INPUT); // PCI-bus loopback mode: transmitted message is immediately received (for testing only)
pinMode(_4XLOOP, OUTPUT);
digitalWrite(_4XLOOP, LOW); // PCI-bus waveshaping - LOW: enabled, HIGH: disabled
VPW.onMessageReceived(VPWMessageReceived); // subscribe to the message received event and call this function when a PCI-bus message is received
VPW.begin(J1850VPW_RX, J1850VPW_TX, ACTIVE_HIGH);
}
void VPWMessageReceived(uint8_t *RKEmessage, uint8_t messageLength)
{
for (uint8_t i = 0; i < 5; i++)
{
if ((RKEmessage[0] == 0xA8) && (RKEmessage[1] == 0xC7) && (RKEmessage[2] == 0xB0) && (RKEmessage[3] == 0xA0) && (RKEmessage[4] == 0x13))
{
if (RKEmessage[i] = RKE)
digitalWrite(12, HIGH); // turn relay on
Serial.print("ON"); // testing
delay(1000); //long delay for testing
digitalWrite(12, LOW); // turn relay off
Serial.print("OFF"); // testing
}
}
}
void loop()
{
}
Please follow the forum rules and post code that will compile and demonstrate the problem.
The snippet doesn't make much sense to me, and there appears to be nothing in the snippet that reads a message. Or a button.
I see you updated your original post, which makes the thread hard to follow.
What is the following line suppose to do? The compiler probably emits some warnings, if not fatal errors.
if (RKEmessage[i] = RKE)
"=" is the assignment operator. If you meant to do a comparison, use "==". However, RKE is a pointer to a C-string (a zero terminated character array), and cannot be compared to a byte value.
Please take a few moments to describe what this code should do, and perhaps you will get useful help.
I got this to work. Now to figure out how to make it timeout if second message isnt sent
void VPWMessageReceived(uint8_t *RKEmessage, uint8_t messageLength)
{
uint8_t RKE = 0xA8C7B0A013;
for (uint8_t i = 0; i < 5; i++)
{
if (RKEmessage[i] == RKE)
{
buttonPress++;
}
if (RKEmessage[i] == RKE && buttonPress == 2)
{
digitalWrite(12, HIGH);
Serial.println("ON");
delay(100000);
digitalWrite(12, LOW);
Serial.println("OFF");
buttonPress = 0;
}
}
}
Use a variable and remember the first time that a correct message was received. Wait for the second message; while waiting, check remembered time and if it's longer than the timeout time, start from the beginning. Use a millis() based approach.
I was trying the millis() approach, but not sure where to start. I just keep copying and pasting until something works.
This does not work.
#include "J1850VPWCore.h"
#define J1850VPW_RX 2 // INT0 on Uno, INT4 on Mega
#define J1850VPW_TX 9
#define SLEEP 5
#define _4XLOOP 7
int buttonPress = 0;
unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
const unsigned long timeout = 5000;
void setup()
{
Serial.begin(115200);
pinMode(12, OUTPUT);
// MC33390 settings.
pinMode(SLEEP, OUTPUT);
digitalWrite(SLEEP, HIGH); // enable PCI-bus transmitter (receiver is always enabled), HIGH: enable, LOW: disable
// pinMode(_4XLOOP, INPUT); // PCI-bus loopback mode: transmitted message is immediately received (for testing only)
pinMode(_4XLOOP, OUTPUT);
digitalWrite(_4XLOOP, LOW); // PCI-bus waveshaping - LOW: enabled, HIGH: disabled
VPW.onMessageReceived(VPWMessageReceived); // subscribe to the message received event and call this function when a PCI-bus message is received
VPW.begin(J1850VPW_RX, J1850VPW_TX, ACTIVE_HIGH);
}
void VPWMessageReceived(uint8_t *RKEmessage, uint8_t messageLength)
{
currentMillis = millis();
uint8_t RKE = 0xA8C7B0A013;
for (uint8_t i = 0; i < 5; i++)
{
if (RKEmessage[i] == RKE)
{
buttonPress++;
}
if (currentMillis - previousMillis <= timeout)
{
previousMillis = currentMillis;
if (RKEmessage[i] == RKE && buttonPress == 2)
{
digitalWrite(12, HIGH);
Serial.println("ON");
delay(100000);
digitalWrite(12, LOW);
Serial.println("OFF");
buttonPress = 0;
}
}
}
}
void loop()
{
}
You will first have to fix that. An uint8_t can not hold a 5 byte integer. I suggest that you go back to the approach used in your opening post.
I see that you have a similar problem in the code in your opening post. The below code demonstrates that you do not get what your expect
uint8_t RKE = (0xA8, 0xC7, 0xB0, 0xA0, 0x13);
void setup()
{
Serial.begin(115200);
Serial.println(RKE);
}
void loop()
{
}
This print '19' which is the last byte of your RKE variable.
Please try to explain what the intention of below is
if ((RKEmessage[0] == 0xA8) && (RKEmessage[1] == 0xC7) && (RKEmessage[2] == 0xB0) && (RKEmessage[3] == 0xA0) && (RKEmessage[4] == 0x13))
{
if (RKEmessage[i] = RKE)
Once the first if condition is true the second one will also be true (if i == 4).
SparepartsBlazer:
This does not work.
Not tested but compiles; comments should explain the code, else ask.
#include "J1850VPWCore.h"
#define J1850VPW_RX 2 // INT0 on Uno, INT4 on Mega
#define J1850VPW_TX 9
#define SLEEP 5
#define _4XLOOP 7
// not used; demonstrate correct initialisation of RKE
//const uint8_t RKE[] = {0xA8, 0xC7, 0xB0, 0xA0, 0x13};
// relay pin
const uint8_t pinRelay = 12;
// timeout between button presses
const uint32_t btnTimeout = 1000;
void setup()
{
Serial.begin(115200);
pinMode(pinRelay, OUTPUT);
// MC33390 settings.
pinMode(SLEEP, OUTPUT);
digitalWrite(SLEEP, HIGH); // enable PCI-bus transmitter (receiver is always enabled), HIGH: enable, LOW: disable
// pinMode(_4XLOOP, INPUT); // PCI-bus loopback mode: transmitted message is immediately received (for testing only)
pinMode(_4XLOOP, OUTPUT);
digitalWrite(_4XLOOP, LOW); // PCI-bus waveshaping - LOW: enabled, HIGH: disabled
VPW.onMessageReceived(VPWMessageReceived); // subscribe to the message received event and call this function when a PCI-bus message is received
VPW.begin(J1850VPW_RX, J1850VPW_TX, ACTIVE_HIGH);
}
void VPWMessageReceived(uint8_t *RKEmessage, uint8_t messageLength)
{
// if a message is a match
bool isMatch = false;
// remember button count
static uint8_t buttonCount;
// remember time of first button
static uint32_t firstBtnTime;
// check for match
if ((RKEmessage[0] == 0xA8) && (RKEmessage[1] == 0xC7) && (RKEmessage[2] == 0xB0) && (RKEmessage[3] == 0xA0) && (RKEmessage[4] == 0x13))
{
isMatch = true;
// if it's first button press
if (buttonCount == 0)
{
// remember the time
firstBtnTime = millis();
}
// increment button counter
buttonCount++;
}
// no match
if (isMatch == false)
{
// nothing to do
return;
}
// check for timeout between first and second button press
if (buttonCount == 1 && millis() - firstBtnTime >= btnTimeout)
{
// reset button counter
buttonCount = 0;
Serial.println(F("Timeout"));
// nothing else to do
return;
}
// got two button presses
if (buttonCount == 2)
{
// reset button counter
buttonCount = 0;
// turn relay on
digitalWrite(pinRelay, HIGH);
Serial.print("ON"); // testing
//long delay for testing
delay(1000);
// turn relay off
digitalWrite(pinRelay, LOW);
Serial.print("OFF"); // testing
}
}
void loop()
{
}
This code works the way I want. I have to push the button twice. Only problem is, it need to detect the second button push within say 5 seconds. If not it needs to start over.
#include "J1850VPWCore.h"
#define J1850VPW_RX 2 // INT0 on Uno, INT4 on Mega
#define J1850VPW_TX 9
#define SLEEP 5
#define _4XLOOP 7
int buttonPress = 0;
void setup()
{
Serial.begin(115200);
pinMode(12, OUTPUT);
// MC33390 settings.
pinMode(SLEEP, OUTPUT);
digitalWrite(SLEEP, HIGH); // enable PCI-bus transmitter (receiver is always enabled), HIGH: enable, LOW: disable
// pinMode(_4XLOOP, INPUT); // PCI-bus loopback mode: transmitted message is immediately received (for testing only)
pinMode(_4XLOOP, OUTPUT);
digitalWrite(_4XLOOP, LOW); // PCI-bus waveshaping - LOW: enabled, HIGH: disabled
VPW.onMessageReceived(VPWMessageReceived); // subscribe to the message received event and call this function when a PCI-bus message is received
VPW.begin(J1850VPW_RX, J1850VPW_TX, ACTIVE_HIGH);
}
void VPWMessageReceived(uint8_t *RKEmessage, uint8_t messageLength)
{
uint8_t RKE = 0xA8C7B0A013; //message to look for
for (uint8_t i = 0; i < 5; i++)
{
if (RKEmessage[i] == RKE)
{
buttonPress++;
}
if (RKEmessage[i] == RKE && buttonPress == 2)
{
digitalWrite(12, HIGH);
Serial.println("ON");
delay(100000); //long delay for testing
digitalWrite(12, LOW);
Serial.println("OFF");
buttonPress = 0;
}
}
}
void loop()
{
}
I got this to work like I want. Prob not the best way.
#include "J1850VPWCore.h"
#define J1850VPW_RX 2 // INT0 on Uno, INT4 on Mega
#define J1850VPW_TX 9
#define SLEEP 5
#define _4XLOOP 7
const uint32_t btnTimeout = 2000;
static uint8_t buttonCount;
static uint32_t firstBtnTime;
void setup()
{
Serial.begin(115200);
pinMode(12, OUTPUT); // relay pin
// MC33390 settings.
pinMode(SLEEP, OUTPUT);
digitalWrite(SLEEP, HIGH); // enable PCI-bus transmitter (receiver is always enabled), HIGH: enable, LOW: disable
// pinMode(_4XLOOP, INPUT); // PCI-bus loopback mode: transmitted message is immediately received (for testing only)
pinMode(_4XLOOP, OUTPUT);
digitalWrite(_4XLOOP, LOW); // PCI-bus waveshaping - LOW: enabled, HIGH: disabled
VPW.onMessageReceived(VPWMessageReceived); // subscribe to the message received event and call this function when a PCI-bus message is received
VPW.begin(J1850VPW_RX, J1850VPW_TX, ACTIVE_HIGH);
}
void VPWMessageReceived(uint8_t *RKEmessage, uint8_t messageLength)
{
uint8_t RKE = 0xA8C7B0A013; // message to look for
for (uint8_t i = 0; i < 5; i++)
{
if (RKEmessage[i] == RKE)
{
firstBtnTime = millis();
buttonCount++; // increment button counter
Serial.println(buttonCount);
}
if (RKEmessage[i] == RKE && buttonCount == 2)
{
digitalWrite(12, HIGH);
Serial.println("ON");
delay(100000); // long delay for testing
digitalWrite(12, LOW);
Serial.println("OFF");
buttonCount = 0; // reset button counter
Serial.println(buttonCount);
}
}
}
void loop()
{
if (buttonCount == 1 && millis() - firstBtnTime >= btnTimeout)
{
buttonCount = 0;
Serial.println(millis());
Serial.println(firstBtnTime);
Serial.println(buttonCount);
}
}