ChipChop Support Forum
Log in
Log out
Join the forum
My Details
REPLIES: 12
VIEWS: 341
BACK
REPLY TO THIS POST
Gizmo
18 Feb 2024
ChipChop Library vs. 1.40
The new library version 1.40 is now published and available for download from the usual place https://chipchop.io/downloads/ChipChop_Arduino_Library.zip

This was not just a minor update to the library but also an update to the main engine that has been propagated last night across all servers (I was almost considering releasing it as vs 2.0)

You can still use it with your existing code, everything is cross compatible but I will give you examples where you can modify your code to benefit from the new engine.

Major changes:

Quick Intro

The main focus was to improve the chances of delivery when using fast events like triggerEvent(). With the introduction of Notifications some users have started firing triggerEvents more often and it has become noticeable that in some cases network conditions (your ISP and various other networks & servers that the data packets have to travel) were causing important events to be refused by the ChipChop engine if their timing was wrong.

So the new engine will be a lot more forgiving and instead of issuing penalties and closing connections it will try to work with you and to help you. A new routine called "Connection Watch" is now constantly monitoring every device connection and will inform you if it detects irregularities and even send instructions to the library to attempt reconnections and other things.

This doesn't mean that you can be reckless and not care how you handle your events. It is understandable that we all make mistakes and a small error in the code logic can produce big problems so I don't want anyone to be penalised for that, but also the Connection Watch is not there for only you ! ;-)

- ChipChop.requestRate(int milliseconds) (default 510)
The biggest change is how the library handles events, it runs a constant "pulse" that keeps the space between events as accurate as possible. This completely removes the need for using any timers trying to keep triggerEvents going too fast.
You can simply call a triggerEvent() from anywhere in your code even multiple times one after another and the library will still send them in a correct time.
The only thing you need to watch is that you don't runout of available event in the allocated 60sec slot.
Technically you don't have to use this functionality but there are tricks where it can be extremely useful and I will be happy to give you examples, just ask if you are interested.

- ChipChop.keepAlive(int mode, int timeout)
This simple looking function does a lot of things in the background for you. Its job is to fight to death to keep your connection with ChipChop going. Again, it's completely optional but has already proven in some of my tests that could get you out of a sticky situation .

It takes two parameters "mode" and "timeout":

    - Mode (0,1,2)
    0 - simply disables the keepAlive if it's being activated
    1 - if a loss of connection is detected and can not be re-established (the re-connect routine runs every 15 seconds) the keepAlive will attempt at ditching the entire WebSockets from the chip's memory, reloading them and trying to reconnect
    2 - this is only available on ESP chips - if a loss of connection is detected and can not be re-established, keepAlive will restart the ESP. It is an aggressive mode but can help in poor or unstable WiFi signal areas where on the restart the ESPs modem gets a bit of power boost and may catch a better channel.

    - Timeout in milliseconds, default 120000 (2 minutes)
    This is the timeout after which you think that the re-connects have become pointless and will kickstart the keepAlive routine. I don't know if 2 minutes is a bit too low, let me know and I can increase the default in the next library update.

- heartBeatInterval() - after a very observant user has spotted a typo, this is now correctly named as it used to be hearBeatInterval() (missing a "t" in the "heart" ;-) . You really only need to use it if you want to maybe save a little bit of power by sending heartbeats less frequently. For example an ESP will use around 200ma when sending but around half of that if just receiving.

- ChipChop.restart() - manual way of triggering the keepAlive() routine, the keepAlive has to be active.

Here is an example how you can structure your code to take advantage of the new library:

1. Always start by telling the library the starting state of all your components


void setup(){
    ChipChop.updateStatus("led",led_status);
}



2. if you've done the above in the setup(), then instead of doing this:


//don't need to do it this way

void loop(){
    ChipChop.run();

    if ((millis() - loopCycle) > 10000){
        if(WiFi.status() == WL_CONNECTED){
             ChipChop.updateStatus("led",led_status);
        }
        loopCycle = millis();
    }

}



just do this:


// do it like this

void setup(){
    ChipChop.updateStatus("led",led_status);
}

void loop(){
    ChipChop.run();
}



Notifications This is how you can handle triggerEvents to control notifications



void loop(){
    ChipChop.run();

    if(something_happened == true){
        ChipChop.triggerEvent("notification","trigger word");
        ChipChop.updateStatus("notification","non-trigger word");
    }
}



Multiple Trigger Events You can now safely do stuff like this



void loop(){
    ChipChop.run();

    if(motion_detected == true){
        ChipChop.triggerEvent("motion_sensor","DETECTED");
        ChipChop.triggerEvent("motion_sensor","DETECTED");
        ChipChop.triggerEvent("motion_sensor","DETECTED");
        ChipChop.triggerEvent("motion_sensor","DETECTED");
        ...
        
    }
}



I will post more examples or if you have something specific just ask


Enjoy 😃🤟




jnogues
18 Feb 2024

First tests. Work like a rocket.
Down Under
18 Feb 2024

definitely works, haven't been banned from the platform yet :)

Question though, my sub-brain is telling me that there is a reason for the keepAlive restart but may main-brain just can't see a real life application!
Care to give an example where a restart would be more beneficial than potentially missing something important during the restart?

Honestly, super happy with everything, just trying to figure out where I could use it to the full potential.

Cheers

Hossrod
18 Feb 2024

Thanks Gizmo! I'm really liking this flow/design better. Offloads a lot of logic from my code (and I don't have to repeat on each device).
Gizmo
19 Feb 2024

My dear @DownBelow kangaroo lover, say hi to your sub-brain from me 👋

Ok, so the reason why a full restart can be a good thing apart from boosting the initial modem slightly is the fragmentation of the heap.

I have noticed over time that some devices that do a lot of things simultaneously (may sensors) and receive inconsistent command data (large JSON in varied size) eventually can get their heap fragmented to the point that it starts to affect the performance and as a side effect cause the loss of connection. Won't go too deep into detail but I've been setting on pretty much everything that I build nowadays a full restart once a day.

It's the good old " turn it off and on again", I just make sure to save in the flash the current state before restart and re-load the variables on wake up. For some things that I have and that must run no matter what, I find that 15-20 sec loss of connection is less harmful than a slowdown and potentially getting wrong readings and eventually a crash anyway.

The keepAlive(2) is simply doing that but only addressing a continuous connection loss on the assumption again that it could be a possible heap fragmentation issue and heaving a device heartbeat is more important than it running badly.

So, yeah, that's the reasoning behind the full restart. It's aggressive but tries it's best to get the device back on the IoT road.
Probably not good if you have something that has to do a critical job regardless of the connection, hence the mild version keepAlive(1)

One thing though, I could add a hook into the entire process so your main code could get informed that a restart will happen so you can dump variables in the local flash or potentially even cancel the restart.

Oh, billybollox, I forgot to mention in the post above that you also have the ChipChop.restart() available so you can trigger the restart manually if you want, damn, I'll edit the post.

Let me know what you think
Down Under
20 Feb 2024

man, I never thought about the heap frag! I like the 24hr restart, is it just a timer and when it hits it you call ESP.restart()?
And you are right, if the priority is IoT then few seconds to reconnect are better than a crash.

I'll give it a go tonight, I don't think I'll wait for 24hrs, I'll set it up for 2 and see if I will notice it restarting at all. Who knows, I have one candidate to test, it's a proper little workhorse and it may be already crashing all the time and I just didn't catch it
Gizmo
20 Feb 2024

Ah, thought to catch you before you bugger of to bed, yes that's exactly how to do it and I'll add a hook in the keepAlive so you can intercept if it needs to restart.

News flash though, after a lot of experiments yesterday it seems that the actual WiFi signal may be a culprit in many cases and may not be obvious at all. So I am going to add keepAlive(3) that drops/restarts the WiFi. Or maybe even some sort of "auto"mode that tries dropping sockets first, then wifi and then as last resort a full restart....what do you think?
Aubrey44
20 Feb 2024

I personally really like the sound of the “auto” feature. Always a fan when something or someone else makes decisions for me, im lazy like that. Set it and forget it.

On a side note about notifications…pretty sure i read somewhere there is an hourly/daily/monthly limit of course. We do not want to flood our phone or the servers with notifications. Is it up to us in our code to make sure notifications are sent at respectable intervals? Say…every 2hours/4hours if a condition remains true and never changes for days 😬




void loop(){
ChipChop.run();

if(something_happened == true){

If(millis() - lastNotification >= respectableInterval) {
ChipChop.triggerEvent("notification","trigger word");
ChipChop.updateStatus("notification","non-trigger word");
}
}
}



Thanks 👍🏼. Ill give 1.4 a go when I get out of the bush and back home
Gizmo
20 Feb 2024

ah, ma man, I defo like fire & forget...60% of my code runs on my personal pub/sub engine that is so async it would give programmers recurring nightmares and pop few aneurysms :-)

This is an abstract how my code works, I have shit like this all over the place:

" tell a function that doesn't exists that a user has pressed a button so it can pop itself into existence when convenient and when it gets born to check this event in the past before it was conceived" ... hmmm... wonder how would ChatGPT spit out the code for that?

Don't you worry a thing buddy, I'm gonna "auto" mode the crap out of it. I have full bucket of orders just need to finish some work on a "project for money" and then I'm jumping back in.

What'ya doing in the bush anyway? oh please say you are a bear hunter!!! if you are moose farmer, damn, that would really cramp my style 🤣
Gizmo
20 Feb 2024

@Aubrey44

Forgot to answer the question about notifications limit. It's currently set at 600 per month and max sending rate is 3 per minute (there's no per-day limit, the server doesn't care). It's not set in stone so feel free to experiment and if you run out of bullets just let me know and I'll top it up.

I guess yes, you should set your internal conditions so you don't get flooded but you can also set the time of day in the action so that could take care of notifications through the night or maybe between some hours?

Honestly I haven't had the time to play with it properly, you guys are keeping me busy :-)

Aubrey44
21 Feb 2024

@Gizmo

LOL!! I am definitely not a moose farmer! However, i am a moose hunter but come to think of it, farming would be a hell of a lot easier!! Tthere was a time when I was a bear hunter but i have to say, black bears are one of the fastest, smartest, strongest animals i have ever had the pleasure of hunting and boy they are hard to get…

There are 2 ways of hunting bear in Canada where I am from. the real way (actually hunting and tracking. Human with bow vs Bear aAND the sure way, baiting them with scrap spoiled meat in the spring when they are starving after a long winter hibernation. I personally do not find the latter, baiting and waiting in a tree stand for the poor starving things very fair and the real way of hunting them, It was very hard and I was rarely succesful! Smart buggers! So i gave up! LOL!!

Anyways, way off topic as far as IoT goes eh!! Thanks for answering 👍🏼✌🏻
Hossrod
21 Feb 2024

@Gizmo

I vote for auto recovery mode as well! I like the staged approach, trying least impactful first and working your way up to restart.

If you implement a restart event with it, how would it work? Maybe if I register a callback, you fire the event and let me call reset in my event handler code after I'm done with any cleanup, logging and/or, storage of variables to persit. But if I dont register callback, you auto reset.
Gizmo
21 Feb 2024

@Aubrey

Hunting bears with a bow and arrow...that's... how to put it nicely....batshit crazy! That's the type of people the IoT world needs...awesome! (remind me not to get on your bad side)

So, when are we doing a little viral promo for ChipChop...a quick vid of making an IoT device whilst bare back riding a big daddy moose at full gallop. Don't need more than 2-3 mins of footage for TikTok, easy peasy.

💪🧸🪓