Notifications
Clear all

Callbacks, Function Pointers and other nasty things

11 Posts
3 Users
0 Likes
1,691 Views
WolfgangW
(@wolfgangw)
Member
Joined: 4 years ago
Posts: 70
Topic starter  

Hi Guys,

Here and now I am addressing those who have a lot of experience with C / C ++. I try to make my problem understandable, which is not that easy. So, I probably have to write more than is really necessary. I beg your pardon if I express myself inappropriately.

First of all: I'm looking for a way in C ++ to send messages from a class / library to the main program in case an error occurs in the library. Something like that only works with a certain workaround.

Use case:

Let's say I want to integrate a certain sensor into a project, regardless of which one. I know the basics so far. The code is running, so no problem so far. And yet I am not satisfied from a programmer's point of view. I would like the integrated library to report to me if there is an error / failure of the sensor.

The reason is simply that I want to keep my main program as lightweight as possible, see the business logic where it belongs, in this case in the library.

Let's just take the DHT22. Everything easy to use. However, it can happen that one fine day the sensor only returns values ​​that cannot be correct under any circumstances. For me (C # programmer) it is very easy to integrate an event in C # that tells my program that something is wrong here. The program reports to me and I know and can react. For example in a Twitter message.

I already dealt a bit with the events in C ++ beforehand, but this is not solved as elegantly as in C # (my opinion). I also dealt with function pointers. Looks promising. Unless you have better suggestions here, I'll probably turn to the function pointers. Callbacks would also be a solution. Because I'm still too inexperienced with C / C ++, I find it a little difficult at this point.

Hence the question to the experienced:

Have you tried something like this before and what solution did you use?

 

friendly greetings to everyone and thank you in advance for your effort 

Wolfgang

 

If I am not here, then I am most probably somewhere else


   
Quote
byron
(@byron)
No Title
Joined: 5 years ago
Posts: 1121
 

@wolfgangw

I think some of the essence of you question may be unclear because of the English so I'm probably not going to be too much help, and I would certainly not get involved in callbacks and pointers, yes they can be horrible things.

I take it that the function you create to read the temperature will have suitable logic to return either the temperature or error codes to the calling program.

I am doing something similar in my current project where Im making my own central heating control system. What to do if something untoward happens? Namely what happens if the temperature reading shoots up because my dear wife puts a hot kettle near the temperature sensor, or the sensor stops working, or the whole node (which is based on an Rpi with a touch screen) stops reporting data to my heating control program running on the Control Rpi. What to do and how am I to be alerted.

In my case the function for reading the temperature is responsible for reading the temperature sensor, but also for reporting errors, which includes sudden temperature spikes. The function normally returns the temperature (in centigrade in whole degrees) but will return number >100 to indicate various error conditions. (maybe with global warming I will have to up this to >1000. 😏 )

This function holds the last reading so unexpected spikes can be reported on the next temperature read. I haven't yet decided on the frequency of the reading but I have every 5 minutes in mind. The heating control program will plod on receiving temperature readings and deciding whether to switch the heating boiler on taking into account an on-off schedule. But if an error is reported instead of a temperature reading then I can take whatever action I wish. So far no need for anything too complicated, just normal error condition handling.

But what happens if the whole the rpi to which the temp sensor is attached goes down and fails to report to the heating control? For this I record the time when a temperature reading is received so I can easily periodically check if it has not been updated within a specified timespan. Again no need to have any complicated callbacks of other horrible things as you call them.

If my main heating rpi stops functioning I will freeze. Though I hope the dropping temperature will trigger me to flip the switch to revert to the old wall thermostat control.

But, as I said, I probably lost the essence of your quest for C++ assistance, but I fear you may be overcomplicating things.  After a nice cup of tea maybe you see an easy solution with plain and simple logic. No? 🤔   

Good luck in any case 😀 


   
ReplyQuote
WolfgangW
(@wolfgangw)
Member
Joined: 4 years ago
Posts: 70
Topic starter  

@byron

 

Event

At the moment, as I still see myself as a beginner, I am thinking of a weather station, firstly because the one I bought only provides temperature and humidity and therefore does not actually deserve the name weather station, secondly because many different sensors are connected there and so I can gain experience.
Ok, now to my problem:
Windows, as you probably know, is an event-based system. This means that if you move the mouse or press a button, an event will be fired that you can intercept in your programs. In C #, I now have the option, and even relatively easy, to trigger an event and intercept it at the appropriate point.
Professionally, I use this in C # very often because it involves important information. In Windows there is the so-called scheduler. The calls certain programs according to a defined time scheme and lets them run through. These are mostly simple tasks that have to be carried out very reliably, because otherwise I get a lot of nasty emails threatening me with butt-hacking.
I can't avoid mistakes anywhere and that doesn't even mean the error in my software. Mistakes happen everywhere. Murphy's Law is very reliable here. Sometimes it's a network failure, sometimes it's simply a file that was not written correctly.
I can catch such errors in my tools and pass them on to my main program. Those tools I talked about before are all DLLs. A DLL cannot simply send messages to the outside world of its own free will. For this you can use events to which you then send information. And that works extremely reliably. I can display these messages in a console, save them in a log file and even send them to me by email in the event of very serious errors.
And that's exactly what I would like to incorporate into the classes / libraries of my sensors. I was researching events for C ++ and nearly got eye cancer. Or maybe I have visited the wrong pages. A colleague also confirmed my fears about the events in C ++ and then finally brought me to the function pointers, which are much easier to use.
Thanks to you I now know that I totally forgot about the Raspberry. Of course, it has to be somehow integrated into the complex.
And no, I don't think I'm bringing too much complexity into this. I think this, on the contrary, will bring me much more security. Even a sensor is just a bit of technology that can fail at any time. No electricity, line damage, water and God knows what else. Of course, this makes the code a lot more complex at first. But I get a fire-and-forget solution, which then even reports to me that it is in pain and also exactly where it hurts. I hope I have been able to express myself so far so far.
I am not a great artist, but I made a little sketch that should explain that a little better. 

I'll show this as simply as possible.
a. declare the event!
b. consume the event from the class you've instanciated.
c. on runtime some bad thing happens inside a try-catch-block
d. the event is triggered.
e. in the main program the logic knows what to do as soon as it intercepts an event.
f. The information that is delivered in the piggyback event is processed in the method.

If I am not here, then I am most probably somewhere else


   
ReplyQuote
WolfgangW
(@wolfgangw)
Member
Joined: 4 years ago
Posts: 70
Topic starter  

@byron

here is what I got from my colleague. It's pretty simple and I guess you sure can make use of it.
At least, I think this is what I was looking for, even I do not really understand what is going on at some code lines, I mean why they've been semantically used in that way.

Wolfgang

If I am not here, then I am most probably somewhere else


   
ReplyQuote
byron
(@byron)
No Title
Joined: 5 years ago
Posts: 1121
 
Posted by: @wolfgangw

I was researching events for C ++ and nearly got eye cancer.

😀.  

I see your logic and that you have a nice set up on your windows computer that works well.  I'm presuming your project entails attaching sensors to something like an esp8266 or esp32.  Whatever it doesn't matter much if you are still intending to go with mqtt for the inter- computer/microprocessor communications.  I'm also presuming that your Rpi will be running you main program, hence your wish to program the main program in C++.  So I give you the following steps:

1.  your main Rpi program publishes a request to the esp8266 for a temperature reading.

2. The program on the esp8266 either publishes the temperature or an error code, or simply fails to respond.

3  your main C++ program (that has subscribed to the message) takes has the logic to take whatever action is necessary on reported errors or simply receives no response.

So the 'events' have been replace with the mechanism of mqtt and quite simple programming.  (well you are doing this in C++ so maybe not so simple, but not a function pointer in sight. 😎 )

Of course your windows computer could also receive the mqtt message (plenty of C# mqtt client libraries or even mqtt broker libraries) and your c# authored mqtt message passed to you windows dll, and you are back in familiar territory.

But hey, I'm not really meaning to persuade you from your path, just playing devils advocate, and I do look forward to seeing your programs when you have it altogether.  

This post was modified 4 years ago 2 times by byron

   
ReplyQuote
WolfgangW
(@wolfgangw)
Member
Joined: 4 years ago
Posts: 70
Topic starter  
Posted by: @byron

Of course your windows computer could also receive the mqtt message (plenty of C# mqtt client libraries or even mqtt broker libraries) and your c# authored mqtt message passed to you windows dll, and you are back in familiar territory.

That is what I am counting on. I hope I can use the best of all worlds.

Posted by: @byron

I do look forward to seeing your programs when you have it altogether.

this may take some while, I think I already mentioned. But well, I don't do big science. So I think there are no secrets inside.

 

If I am not here, then I am most probably somewhere else


   
ReplyQuote
frogandtoad
(@frogandtoad)
Member
Joined: 5 years ago
Posts: 1458
 

@wolfgangw

I think I have to agree with @byron... as it does sound like it's a little over complicated, but I'll talk about a couple of things.

Firstly, in C++ there is exception handling, just like you've shown in the function pointers code (which I'll come back to), but it is not supported for AVR processors, however, I believe that it is supported for some others such as ESP32 architecture, but you'll need to turn it on via a menu option or set the compiler flags.

I have never used "mqtt" before, but I have previously read about it.  When I read about it, it made me realise that it is very similar (if not the same) as the Java JMS queuing system, used in J2E platforms.  Nevertheless, it seems like a good way to go for your application.

Many people are happy enough to just use return codes in their methods, functions or procedures too, but again, this depends on how mission critical the system you're building is, which will determine your design.  Return codes may be good enough, coupled with some redundancy implemented into your design?  I'm not sure, it's something you'll need to decide on.

If you're going to use C#, then using exceptions is I think the way to go, but I don't really see the need for function pointers, because either way you are going to have to poll the sensor to find out what it's doing, unless the sensor library has built in exception handling (which I doubt) anyway.

The reason you might want to use a function pointer is generally to perform additional operations over an element of an array, or store an array of function pointers that can be called dynamically, etc... Modern C++ implements these as functors (spelling is correct), and are passed to algorithmic functions like 'transform' to apply some logic to each element the iterator returns.

Anyway, I had a quick look at the example function pointers you posted, but it's not used correctly, and really just throws away the value by the looks of it.  Also, if you decide to use function pointers, you could also consider using the 'typedef' mechanism to make the code a little easier to read - Here is an example, in standard C++:

 typedef int (*FuncPtr)(int);

 int processValue(int n, FuncPtr f) {
   return f(n);
  }

 int add5(int n) {
   return n + 5;
  }

int main() {
  std::cout << processValue(10, &add5); // prints 15

  return 0;
 }

In your function pointer example, even if you had a different case than '101', you would still override it and return '-1', which makes no sense.  You also should not be catching int anyway, but rather a specific exception class, which C# has many different ones for different scenario's, as well as a catch all capability.

I hope this gave you some more information to base your decision on.

Cheers.


   
ReplyQuote
WolfgangW
(@wolfgangw)
Member
Joined: 4 years ago
Posts: 70
Topic starter  
Posted by: @frogandtoad

I think I have to agree with @byron... as it does sound like it's a little over complicated, but I'll talk about a couple of things.

Ok guys, 

I think I really thinking too much, maybe and most probably just because I have had very good experiences with this matter, by using Events. I also agree, that an Arduinos software is not as complex as a Windows software, using lot of Libraries, which is in my case a use-case-triggered extension to the original Framework of Microsoft. 
In my job, where I make a lot of use of Events, it is really perfectly working and that is why I thought about to use them in C++ too. Anyway, with all your suggestions I think I slowly worked out a pretty good working template which may help me a lot, so thanks to you both.

Either way, I'm somehow "mentally" still at odds, if not at war with the MQTT and the Arduino. I think it makes no difference there whether I use a PC, a Raspberry Pi or even another Arduino as a receiver, at least as far as I understand.
After I have decided - really only for reasons of time - to solve my final solutions with C #, at least as long as there are no valid reasons for me to do this with Python, I will prefer this C # solution.
Since you have more experience @byron here MQTT, I turn to you again specifically.
Do you have a small project for me that you have already built and tested that will give me a code example to understand how it works? If I know that this will work, then I will certainly find a way to work it out for the other devices.

After long time thinking, I think I might solve my "Event" problem easier by sending any problem with MQTT.

so @byron, if you have anything just like the temp-sensor you (and I) mentioned before, just an easy piece of code, I am happy to have.

Thanks from Germany 

Wolfgang

If I am not here, then I am most probably somewhere else


   
ReplyQuote
byron
(@byron)
No Title
Joined: 5 years ago
Posts: 1121
 

@wolfgangw

Firstly I would say you are correct in that it does not matter which platform acts as the receiver for an mqtt message, nor on which platform you run your mqtt broker.

I can certainly give examples as you ask.  My current project that I alluded to has evolved and it did start out with an esp8266 programmed with the Arduino framework with Adafruit libraries.  As things progressed I put micropython onto the esp8266 and then scrapped that to having my room-temperature control running on an rpi with the rpi touch screen.  Right now I'm programming the gui for this.

I presume you would like to see the example of the esp8266 reading a temperature and publishing the results written in the Arduino environment.  Also I currently use an mp9808 temperature sensor, but I have played with DHT22,s in the past and I could change the code to use those libraries instead.

I can also show python code that runs on an rpi that receives the temperature message and places it into a mariadb database.

My current project I alluded to is work in progress and actually writing to you about it has given me some more thought about my processes.  I've decided that I like better the process that I suggested to you in the last response, which was the 'main program' initiates a request for a temperature reading and takes appropriate action on receipt or non receipt of the message.  My 'main program' currently polls the timestamp of the last reading of various sensors to alert of a non-responsive temp reading.  So I have to thank you for nudging me to think again. 😀 .  All my projects are done in little chunks here and there when I get the time and they usually require much re-jigging along the way.

So for the python recipient program to start with I will just give a simple example of receiving the temperature reading that the esp8266 sends on a periodic basis and placing the reading into a mariadb database that also run of the rpi.   This can be built on to provide the error checking and non receipt of expected messages later if desired.   But I think it will be best to start simple to concentrate on the use of mqtt on the arduio and rpi platforms.  I will place the code in a new topic of MQTT in case its also of interest to others.

I'll look out a DHT22 sensor (I think that was you said you had) and check any chopped out code does work before I publish it.  It should not take long and I will have a go this evening.  Right now I have to put up some shelving in the potting shed for the boss. 🤨 


   
ReplyQuote
WolfgangW
(@wolfgangw)
Member
Joined: 4 years ago
Posts: 70
Topic starter  
Posted by: @byron

It should not take long and I will have a go this evening.

Hi Byron (so far this is your name),

that is a huge WOW. Thank you very much and please, you don't have to hurry, I am already happy for all I can have. I think you even don't need to change the sensor just for me, I guess I am going to understand another sensor or data in same way. The main thing for me is to see how you use the MQTT and even I don't understand the Phyton yet, I can transer this example into my C# knowledge.

Thanks again and happy shelfing 😀 

Take care 

Wolfgang

 

If I am not here, then I am most probably somewhere else


   
ReplyQuote
byron
(@byron)
No Title
Joined: 5 years ago
Posts: 1121
 
Posted by: @wolfgangw

even I don't understand the Phyton yet

When you are about to sit in front of the TV to watch the politicians spat, turn if off and look at the enclosed videos presented by a knowledgeable C++ programer who produced the TinyPico ESP32 board.  He gives some short examples of using micropython on his ESP32 board, but it works just a well on an esp8266 and some other boards.  You might get tempted ...... and better than the politicians as a bonus 😀 

happy viewing.


   
ReplyQuote