“The Pigenator” – so what’s in a name? And more importantly, “Can a name define you?”



Short version: What would be the downside of using “flags” in the device name to alter the function of a device? E.g. Use a single codebase for different device-types - if my device name ends in _X then expose function1, funtion2, variableX – if my name ends in _Y then expose function3, funtion2, variableZ

Long version: - read on…

As per: https://community.particle.io/t/electron-vs-boron-living-on-the-edge-what-has-changed-with-the-cellular-connection/47872 I’m building a smart pig/hog trapping system.

Up till now, I’ve just been running the one bit of code on a single device but now I’m going to throw Xenons in the mix and embrace the mesh.

Up till now, I’ve just had a trigger:


The trigger has a relay driving an actuator to close the trap and a magnetic reed switch to read the door opened/closed status (because cameras fail).

So now I’m about to automate the feeder.


Currently I load corn in the feeder, set the timer schedule which spins-up a motor to throw corn on the ground at set intervals. The feeder’s little timer/computer can give an estimate of how many days the current level of corn will last based on how much corn if told it is in the tank and the rate of use (as calculated from the timer schedule) - but it’s not accurate (an unlevel feeder drops more corn – different batches of corn have varying kernel sizes – etc.)

I also want to change the rate of feeds (because there’s no point wasting corn every day if there are no pigs around) and I want to know the “actual” level of feed in the tank. AND I want to know if there’s a pig standing under/near the feeder so I can “fire the trigger” automatically (say a single pig has been recorded via camera entering the tap and feeding for a couple of days – so I’m happy for the system so shut the trap itself. As opposed to 5 pigs turning up but 2 of them are “trap shy” – in which case I need to wait and probably fire the trigger myself remotely).

I’ve got the corn level sorted with one of these:


I’ve been playing with PIR for basic motion detection but will probably also use ultrasonic sensor to detect the pigs – because corn attracts birds, bandicoots and snakes – and pigs are the “tallest” of these creatures.

….so both the trigger and the feeder have common components and therefore common code. Solar power/charger, current sensor for batter management. Etc.

…and I could well use the came code/components to create a hybrid “Trigger/Feeder”. I have several small traps – so I could use a single Boron to drive the feeder and provide the trigger mechanism.

…and I could use the same codebase to build my own camera – or extend the motion sensor network outside the trap.

I know I could use any form of database to define the device functions – or use the devices EPROM - but as I stated in my first post, I’ve got a lovely management/reporting system based on IFTTT and Google Sheets that works great. So, until my system takes over the world, I’m just looking to keep it simple.

Your thoughts?


Using the same codebase is a good idea for different devices where you have a number of common functions - examples might be DST adjustment, cloud comms/ message log. You could conditionally run different functions according to device type at run time by having a switch () based selectorlr at the root of the loop(). The slight issue with this is that using device name you need to subscribe to the cloud to get and thus at start up there maybe a period where the device does not have its name. You could get over this by storing the name in eeprom and overwriting it when received from the cloud. Alternatively, you could conditionally compile using #if DEVICE-A code #elif DEVICE-B code #endif.


…just for the record - using flags in the Device name can be problematic.

There seems to be an amount of caching in the Particle web servers (specifically the device console). Also, you need to restart he device to get then new name (obviosly).

I’ve just switched to using EEPROM.get().

In conjunction with STARTUP() - I can selectively expose functions on boot.


STARTUP(startupConfig()); // get my damn config!

// vars for device type/functions
int Configaddr = 0;

struct deviceConfig
bool isTrigger = FALSE;
bool isFeeder = FALSE;

// get the device config flags from EPROM on STARTUP (no paramters used/allowed)
void startupConfig()
// just get it - i don’t care
EEPROM.get(Configaddr, thisDeviceConfig);

void setup()
// +10

// Telstra may be up to 120 seconds?

//grab me the device name
Particle.subscribe("spark/", deviceNameHandler);
Particle.publish("spark/device/name", PRIVATE);

// set pin modes
pinMode(relay1pin, OUTPUT);
pinMode(switch1pin, INPUT_PULLUP);

// functions
if (thisDeviceConfig.isTrigger)
    Particle.function("trigger", triggerRelay);
    Particle.function("switchStatus", switchStatus);