Can an Electron (Not in product status) talk to an Electron (In product status)?

Greetings,

I have been developing this Alert Route Lighting System for some time now. I finally got the USAF to pay the data bill so I can turn my signs back on. Anyways…

I have three of my 22 electrons in the product status with the firmware that is subscribed to an event. The remainder of my electrons are not in the product status. Just one of my electrons lives in a mechanical room and is basically hooked up to poll when a switch is closed. When the switch is closed it publishes and event that would normally turn on my signs all over the base.

This begs the question. How can I have 21 electrons with product firmware listen to another product or electron that is not using product firmware?

Cheers,

AFAIK as long as the Electrons are claimed under your account you can publish and subscribe between them.

So I wonder why they didn’t work today.

Product Firmware

PRODUCT_ID(XXXX); // replace by your product ID
PRODUCT_VERSION(1);

int retrys;

int triggerRelay(String command);
void arlshandler(const char* event, const char* data);

void setup() {
    Particle.subscribe("klaxon", arlsHandler, MY_DEVICES);
    Particle.function("controlRelay", triggerRelay);
    configRetry:
    Wire.begin();
    Wire.beginTransmission(0x20);
    Wire.write(0x00);
    Wire.write(0xFC);
    byte status = Wire.endTransmission();
    if(status != 0){
        if(retrys < 3){
            retrys++;
            delay(500);
            Particle.publish("Wires", "Config Error", 60, PRIVATE);
            Wire.reset();
            delay(500);
            goto configRetry;
        }
        else{
            retrys = 0;
            Particle.publish("Wires", "Config Failed", 60, PRIVATE);
            delay(500);
            System.reset();
        }
    }
    else{
        Particle.publish( "Wires", "Config Success", 60, PRIVATE);
    }
}

void loop() {
    //
}

int triggerRelay(String command){
    
    if ( command.equalsIgnoreCase("relayon") ){
        trigOnRetry:
        Wire.beginTransmission(0x20);
        Wire.write(0x0A);
        Wire.write(0x01);
        byte trig = Wire.endTransmission();
        if(trig != 0){
            if(retrys < 3){
                retrys++;
                delay(500);
                Particle.publish("Wires", "Relay Error", 60, PRIVATE);
                Wire.reset();
                delay(500);
                goto trigOnRetry;
            }
            else{
                retrys = 0;
                Particle.publish("Wires", "Relay Failed", 60, PRIVATE);
                delay(500);
                goto hardReset;
            }
        }
        else{
            Particle.publish( "Wires", "Relay Success", 60, PRIVATE);
            return 1;
        }
    }
    
    if( command.equalsIgnoreCase("relayoff") ){
        trigOffRetry:
		Wire.beginTransmission(0x20);
        Wire.write(0x0A);
        Wire.write(0x00);
        byte trig = Wire.endTransmission();
        if(trig != 0){
            if(retrys < 3){
                retrys++;
                delay(500);
                Particle.publish("Wires", "Relay Error", 60, PRIVATE);
                Wire.reset();
                delay(500);
                goto trigOffRetry;
            }
            else{
                retrys = 0;
                Particle.publish("Wires", "Relay Failed", 60, PRIVATE);
                delay(500);
                goto hardReset;
            }
        }
        else{
            Particle.publish( "Wires", "Relay Success", 60, PRIVATE);
            return 1;
        }
	}
	if( command.equalsIgnoreCase("reset") ){
	    delay(500);
	    hardReset:
		System.reset();
		return 1;
	}
	return 0;
}

void arlsHandler(const char* event, const char* data){
    if ( strcmp(event, "XXXXX") == 0 && strcmp(data, "on")==0 ){
        delay(500);
        triggerRelay("relayon");
    }
    if ( strcmp(event, "XXXXXX") == 0 && strcmp(data, "off")==0 ){
        delay(500);
        triggerRelay("relayoff");
    }
}

The firmware on the electron (not in product firmware)

// This #include statement was automatically added by the Particle IDE.
#include <NCD2Relay.h>

SYSTEM_MODE(AUTOMATIC);

NCD2Relay relayController;

int lastInputState = 0;

void setup() {
    Serial.begin(115200);
	relayController.setAddress(0,0,0);
}

void loop() {
    int Status = relayController.readAllInputs();
    if (Status != lastInputState){
        if (Status ==1){
            Particle.publish("CCCC", "on", PRIVATE);
        }
        else{
            Particle.publish("CCCC", "off", PRIVATE);
        }
        delay(500);
    }
    lastInputState = Status;
}

Generally it’s bad practice to use goto, but I don’t know if that’s exactly what’s causing the problem.

I know, with my limited knowledge in programming I have to use this to ensure the signs fire when commanded to do so. Using goto enables me to no kidding make sure they turn on when needed. In the past, not using goto after my signs go unused for months nothing would happen.

So I am implementing this to wake the I2C bus up and get to business.

I really feel like this has to do with the fact that PRIVATE is added to the subscribe/publish functions. Then of course a barrier between the devices as a few of them are in Product status.

Cheers,

Where are subscribing to the “CCCC” events?

Yes I apologize, I put "CCCC" and "XXXX" to mask my event names. "CCCC" and "XXXX" are the same event.

Cheers

@ScruffR I unkowingly let my event name show in the code above anyway. “Klaxon”

OK, but is it klaxon or Klaxon? You subscribe to the former, if you publish the latter it won’t work. The case must match too.

However, I’m not entirely sure that cross-talking between individual product devices is supported and for that cross-talking between different products (a non-product device can be seen as just a special kind of product) too.

@rickkas7, can you clarify please?

1 Like

klaxon in lowerCase form. Sorry I am just adding to confusion. Let say though, that this was working just fine before I added some of my Electrons to the product firmware. It has several months since I worked on this project. So I tested today for the first time in a while and noticed it wasn't working like before.

The problem I think becomes. If I turn this into a "Product" for the USAF, I need to make adoption for each base super easy.

So for example, Base X wants the system. I can't really go to that base to do the install of said system. I need a way to have two products (I think) for each base. One will be the Electron that publishes the "klaxon" and the other will be the Electron (or hopefully someday Mesh devices) that are subscribed to the "klaxon" event and make the signs light up.

I think that by having two products I can have two easy to maintain firmwares that I can manage OTA from wherever I am located. Have I explained that right @ScruffR?

Or is it better to write one firmware so the device can either be a "pub" or "sub" depending on a variable?

Cheers,

Here is a link to the Relay Board I am using for the Electrons:

2 Relay Board

I mounted these in enclosures and have 12V batteries and PV related items hooked up to keep the batteries charged.

Only main difference is that one of them doesn’t have any PV attached and lives in a dark room plugged into the wall for power. It is connected to a RS232 device in a Monaco system. So when it senses that an input is connected to ground it pubs “klaxon” with “on” as the data.

At which time all the devices outside on the street lamp posts will turn on the signs.

So would it be best to just say that both functions should rolled into one version of firmware that I can use a particle variable to assign whether or not that device is the commanding device or the slave devices outside?