I’m trying to send data over the cloud and have it activate a relay shield on another photon, all of my code looks fine, but something is keeping it from activating. I’ve checked the logs and photon “A” is publishing the event and data, but photon “B” isn’t picking it up, or something is keeping it from activating. Anyone have any insight for this?
Here is the code for the relay shield “photon B”:
#include "Particle.h"
#include "application.h"
const int WIEGAND_D0_PIN = D2; // Green
const int WIEGAND_D1_PIN = D3; // White
int relay = D6;
void wiegandInterrupt(); // forward declaration
bool decodeWiegand(unsigned long value); // forward declaration
void myHandler();
volatile int cardBitCount = 0;
volatile unsigned long cardValue = 0;
volatile unsigned long cardReadStart = 0;
void setup() {
Particle.subscribe("RGS2", myHandler, MY_DEVICES);
pinMode(relay, INPUT_PULLDOWN);
Serial.begin(9600);
// Wiegand pulse are narrow, typically 100 microseconds, so interrupts are desirable to accurately
// detect them
attachInterrupt(WIEGAND_D0_PIN, wiegandInterrupt, FALLING);
attachInterrupt(WIEGAND_D1_PIN, wiegandInterrupt, FALLING);
}
void loop() {
if (cardReadStart != 0) {
if (cardBitCount == 26) {
// Got a valid 26-bit card
if (decodeWiegand(cardValue)) {
// Is valid
Particle.publish("RGS1", String(cardValue), PRIVATE);
}
cardReadStart = 0;
cardBitCount = 0;
}
else
if (millis() - cardReadStart > 500) {
Serial.println("failed to read enough bits");
cardReadStart = 0;
cardBitCount = 0;
}
}
}
void wiegandInterrupt() {
if (cardBitCount == 0) {
cardReadStart = millis();
cardValue = 0;
}
else {
cardValue <<= 1;
}
if (pinReadFast(WIEGAND_D1_PIN) == LOW) {
cardValue |= 1;
}
cardBitCount++;
}
void myHandler(const char *event, const char *data)
{
if (strcmp(data,"open")==0) {
digitalWrite(relay,HIGH);
delay(5000);
digitalWrite(relay,LOW);
}
}
// Note: in the following table the bit numbers are 0-based, 0 - 25 for a 26-bit Wiegand code!
// Bit 25: Even parity, first half of bits
// Bits 24 - 17: Facility code, MSB first 0 - 255
// Bits 16 - 1: Card code, MSB first, 0 - 65536
// Bit 0: Odd parity, second half of bits
bool decodeWiegand(unsigned long value) {
bool valid = false;
int facility = (value >> 17) & 0xff;
int card = (value >> 1) & 0xffff;
unsigned long tempValue = value;
int parity = 0;
for(int ii = 0; ii < 13; ii++) {
if (tempValue & 1) {
parity++;
}
tempValue >>= 1;
}
if ((parity & 0x1) == 1) {
// First parity passed
parity = 0;
for(int ii = 0; ii < 13; ii++) {
if (tempValue & 1) {
parity++;
}
tempValue >>= 1;
}
if ((parity & 0x1) == 0) {
// Second parity passed; looks valid
Serial.printlnf("value=0x%x facility=%d card=%d", value, facility, card);
valid = true;
}
else {
Serial.printlnf("even parity error value=0x%x", value);
}
}
else {
Serial.printlnf("odd parity error value=0x%x", value);
}
return valid;
}
and the code for “Photon A”:
// This #include statement was automatically added by the Particle IDE.
#include "Particle.h"
#include "SparkIntervalTimer.h"
void subscriptionHandler(const char *event, const char *data); // forward declaration
void senderInterrupt(); // forward declaration
const int WIEGAND_D0_PIN = D2; // Green
const int WIEGAND_D1_PIN = D3; // White
int relay = D7;
const int TIMER_PERIOD_US = 100;
const int LOW_PERIOD = 1;
const int HIGH_PERIOD = 10;
IntervalTimer timer;
int sendBitsLeft = 0;
int sendPeriod = 0;
unsigned long sendValue;
void setup()
{
pinMode(relay, INPUT_PULLDOWN);
Serial.begin(9600);
pinMode(WIEGAND_D0_PIN, OUTPUT);
digitalWrite(WIEGAND_D0_PIN, HIGH);
pinMode(WIEGAND_D1_PIN, OUTPUT);
digitalWrite(WIEGAND_D1_PIN, HIGH);
timer.begin(senderInterrupt, TIMER_PERIOD_US, uSec);
Particle.subscribe("RGS1", subscriptionHandler, MY_DEVICES);
}
void loop() {
if (digitalRead(relay)==HIGH) {
Particle.publish("RGS2","open", MY_DEVICES);
delay(10);
digitalWrite(relay, LOW);
delay(5000);
}
}
void subscriptionHandler(const char *event, const char *data) {
unsigned long value = strtoul(data, NULL, 0);
Serial.printlnf("received value=0x%x", value);
sendPeriod = 0;
sendValue = value;
sendBitsLeft = 26;
}
void senderInterrupt() {
if (sendBitsLeft > 0) {
if (sendPeriod == HIGH_PERIOD) {
sendPeriod = 0;
}
if (sendPeriod == 0) {
// Write out the data bit
if ((sendValue >> (sendBitsLeft - 1)) & 1) {
// 1 bit
digitalWrite(WIEGAND_D1_PIN, LOW);
}
else {
// 0 bit
digitalWrite(WIEGAND_D0_PIN, LOW);
}
}
else
if (sendPeriod == LOW_PERIOD) {
// Restore high
digitalWrite(WIEGAND_D0_PIN, HIGH);
digitalWrite(WIEGAND_D1_PIN, HIGH);
sendBitsLeft--;
}
sendPeriod++;
}
}
Also, the way “Photon B” is wired, D3 is pulled high all the time, I don’t know if this makes a difference. I can change the wires and the code to get away from D3 if I need to.