Some basic questions

Hello guys,

I'm kind of noob to C/C++ as well as embedded programming. So please excuse me if my questions are stupid or not relevant to this forum:

So one of the problems I have is that I'm struggling to draw line of what I can do with C++ for Arduino compiler, meaning for example I have certain problem at the moment and I know I can find answer by including C++ std libraries. But from what i understand, you can’t really do that, because then you will really quickly ran out of microcontroller memory or space. So first question would be is where should i ask questions about on how to write certain stuff specifically for Arduino compiler in C++, without annoying people?

I can't really ask them in C++ forum, because then they always advice to use functionality from standard libraries... And I'm not sure, if I can ask them here, because usually related to knowledge of C++ itself rather than to microcontroller...

Here are some examples of the questions I have:

  1. I would like to have dynamic array/list... to which I can add/remove instances of the object, and which will only use memory depending on amount added items... I know here is "list" in std libraries of C++, but is it possible to achieve something similar in C/C++ for Arduino?

  2. I have written class for scheduling some tasks depending on time parameters (similar to Timer/SimpleTimer), now the problem I found is that in C++ seems function is different thing to method, therefor my callback for function typedef void(*SchedulerTaskCallback)(void) is not same as callback for methods and I can not call it from another class, so i had to change it to typedef void(T::*SchedulerTaskCallback)(void), but then I cannot call it from main loop and call it as function, plus then I had to add "template " to my Scheduler class and that opens whole new can of worms. My question is there way to add callback to my Schuduler class, which can be used from both another class method and function from man loop? and not make my Schuduler class have template to type of another class?

I'm sorry, if my questions do not make sense, like I said I'm new to this.

where should i ask questions about on how to write certain stuff specifically for Arduino compiler in C++, without annoying people?

The Project Guidance section of the forum would be a good place

UKHeliBob:
The Project Guidance section of the forum would be a good place

Thanks. Sorry, I thought my question was more relivent to Programming rather then to Project.

wize1:
Thanks. Sorry, I thought my question was more relivent to Programming rather then to Project.

This section is usually for code that has been written but is not working as expected/required or for help with error messages. but there are no hard and fast rules.

wize1:
Hello guys,

I'm kind of noob to C/C++ as well as embedded programming. So please excuse me if my questions are stupid or not relevant to this forum:

So one of the problems I have is that I'm struggling to draw line of what I can do with C++ for Arduino compiler, meaning for example I have certain problem at the moment and I know I can find answer by including C++ std libraries. But from what i understand, you can’t really do that, because then you will really quickly ran out of microcontroller memory or space. So first question would be is where should i ask questions about on how to write certain stuff specifically for Arduino compiler in C++, without annoying people?

I can't really ask them in C++ forum, because then they always advice to use functionality from standard libraries... And I'm not sure, if I can ask them here, because usually related to knowledge of C++ itself rather than to microcontroller...

Here are some examples of the questions I have:

  1. I would like to have dynamic array/list... to which I can add/remove instances of the object, and which will only use memory depending on amount added items... I know here is "list" in std libraries of C++, but is it possible to achieve something similar in C/C++ for Arduino?

  2. I have written class for scheduling some tasks depending on time parameters (similar to Timer/SimpleTimer), now the problem I found is that in C++ seems function is different thing to method, therefor my callback for function typedef void(*SchedulerTaskCallback)(void) is not same as callback for methods and I can not call it from another class, so i had to change it to typedef void(T::*SchedulerTaskCallback)(void), but then I cannot call it from main loop and call it as function, plus then I had to add "template " to my Scheduler class and that opens whole new can of worms. My question is there way to add callback to my Schuduler class, which can be used from both another class method and function from man loop? and not make my Schuduler class have template to type of another class?

I'm sorry, if my questions do not make sense, like I said I'm new to this.

Dynamic allocation needs a good bit of RAM. You're lots better off using a fixed buffer that your sketch manages.
You can do it at all, sure, but it will limit what you can do. C char array strings are preferable to C++ String Objects.

A bathtub fits well in a house. The same bathtub fits poorly on a bicycle.

Much of C++ is very good on Arduino but not dynamic allocation.

Learn the "do many things at once" lesson hawked here and elsewhere on the web and you won't need any overhead-heavy tasking system, you will write cooperative tasks instead. How does void loop() running a few 10's of times per millisecond on average sound? It's not rocket science, an Uno runs 16000 cycles per millisecond and a well written void loop() will average a few 100 to do most jobs while a poorly written void loop() will average > 1000 to more than 16000.

Do you why 3 GHz PC's with Winblows or Linux still can't keep up with running motors or sensing events closely worth a damn?
Who cares! Look at all they do! Use Arduino the same so I don't have to learn the old ways!

Here's other fun: don't treat SD cards like magnetic drives (floppy and hard drives) by sorting records in file. Write a new data file or write a file of sorted links to the original. Oh wait.... learning curve!

If the last two are not you, learn C (C for Close to the metal) and add static C++ objects for best results with Arduino.

Thank you for your input GoForSmoke.

GoForSmoke:
Learn the "do many things at once" lesson hawked here and elsewhere on the web and you won't need any overhead-heavy tasking system, you will write cooperative tasks instead. How does void loop() running a few 10's of times per millisecond on average sound? It's not rocket science, an Uno runs 16000 cycles per millisecond and a well written void loop() will average a few 100 to do most jobs while a poorly written void loop() will average > 1000 to more than 16000.

I do know how to do this is main loop... but the logic of program is getting rather complex, and i wanted to break it all down into clear classes, rather then have it all dumped in one loop and loaded all at once even if it will be never used...

As for rest of your comments... thank you I will keep it in mind.

wize1:
I do know how to do this is main loop... but the logic of program is getting rather complex, and i wanted to break it all down into clear classes, rather then have it all dumped in one loop and loaded all at once even if it will be never used...

Everything in an Arduino program is loaded when you upload your code - there is not separate place to store code that is only used occasionally. I reckon you are still thinking about an Arduino wearing your PC-programming-hat.

Rather than having all the code in loop() it will be much easier to manage if you put it in separate short single-purpose functions that can each be tested on its own. Have a look at Planning and Implementing a Program

By all means use classes if you are familiar with their construction and use, but they are not essential.

...R

Writing classes is great, put them in libraries and #include those.

Storage on AVRs is divided.

On an Uno (ATmega328P) you have 2K RAM for stack and heap and 32K flash for program and constant data (tables, prompts and labels, etc) which really isn't bad. Use PROGMEM to store data directly. Use the F() macro to make print literals stay in flash and print from there.

If you need more, the ATmega1284P has 16K RAM and 128K flash while a Mega2560 board has 8K RAM with connections for external RAM (Rugged Circuits makes a 512K board that gives 8 banks of 56K heap while the internal 8K becomes dedicated stack) and 4 UARTs (1284P has 2) that makes it a bit of a monster.

Arduino setup() and loop() fit into a main() that you have to dig to see. The setup() and loop() fit automation very well, there is no OS to exit to.

wize1:
Thank you for your input GoForSmoke.

I do know how to do this is main loop... but the logic of program is getting rather complex, and i wanted to break it all down into clear classes, rather then have it all dumped in one loop and loaded all at once even if it will be never used...

Do you know how to use millis() and/or micros() to time events?

Break your tasks down and use finite state machine(s) to walk through steps. You want every task to spend limited time during any one pass through void loop(). This is key to fast response, smooth running tasks. Do not use delays anywhere, do not process large arrays in a single pass through void loop() where you don't have to. Try to keep task execution to less than 50 micros (8000 cycles on a RISC chip with 32 GP CPU registers, pretty fat) or less.

In my signature space are addresses of 3 of Nick Gammon's blog tutorials. The 1st is most basic and important to know, does give Arduino specifics. The 2nd has more technique and covers state machines and the 3rd.. if you need interrupts it's an Arduino howto but note that interrupts have > 5us overhead -- need is operative there, it's better to engineer around needing a lot of interrupts.

I put a loop counter in many of my examples. It counts runs through void loop(), prints that out and zeros the count every second. That's my "sketch health meter" to tell me if the task I added needs work or not.

Another name for cooperative tasking could be event-driven code.

Thank you Robin... you probably right about my "hat" :slight_smile: But I'm still trying to make sense of it all and getting used it, need more experience, which will come.

My idea was that for example, if I dont instantiate for example Display class... because user of devices has disabled it, then it will not loaded it into memory and then its much easier to manage all related state memory usage related to that device.

GoForSmoke... Thank you for your input.

No, I don't use any delays in my app, as it very time critical and I can not afford to miss any of the events or anything to stole. I use only one interrupt for very crical portion of the app which needs to switch of one of the relays as fast as possible, rest of the the events handle by main loop with micros() and millis() depending on interval of task.

wize1:
My idea was that for example, if I dont instantiate for example Display class... because user of devices has disabled it,

Unless the user has control of the compiling process s/he cannot influence the content of the code uploaded to the Arduino.

The human-readable C++ code that you write never gets to the Arduino.

...R

Robin: Yes, you right. He can not control content of the code. But i was talking about memory usage, which you can control by creating/not creating instance of the class of certain functionality.

What is the project that you're trying to do with lists and a scheduler? It sounds like you're using sound software design principles and possibly trying to build a general purpose framework.

However, generally, something like an Uno is too small for that kind of approach and if you're building something simple to read and act on a few sensors that'll run forever on a single device, there's not much benefit either.

Of course, if you're making some kind of general purpose IoT device to deploy by the hundreds, maybe a more rigorous approach will serve you well.

wize1:
Robin: Yes, you right. He can not control content of the code. But i was talking about memory usage, which you can control by creating/not creating instance of the class of certain functionality.

Let's suppose that you can avoid using some memory by not creating an instance of a class. What do you propose to do with the unused memory?

Unlike on a PC there is no other program that could make use of the empty space.

...R

wize1:
Robin: Yes, you right. He can not control content of the code. But i was talking about memory usage, which you can control by creating/not creating instance of the class of certain functionality.

The control you mention there involves making deallocation holes in your heap and later expecting them to be filled efficiently?

Why not to use String. Make a String and add a character and the new copy of the String gets added to the heap in the 1st place it fits then the old one gets deleted. Add another char, same thing only the new longer String doesn't fill the last hole and the heap grows. If you are reading a serial string of 12 chars you get 12 Strings made and 11 deleted along the way.
You can make a fixed length String with room from the start which is a FIX for String but by then you might as well have use a char array and treat it as a C string to save a byte or two of String overhead. It does not save you from making holes when you delete it.

String is not just extra bytes, it eats CPU cycles making the copies and finding holes to drop the newest allocation. You pay for the convenience. And in all that, what stack use does the String code do and will there be a collision between heap and stack and a thread about mystery resets?

Dynamic allocation shares with that as far as holes and filling especially if your pop-in-and-out data objects are of different > 1 byte sizes. The heap will be shotgunned up bigger than necessary.

You can manage a buffer space more efficiently using pointers though it may take a good deal of planning. You would likely not use it completely much of the time but you can keep from crashing the stack with good planning.

2048 bytes for heap and stack, if you nest a lot of function calls then you better plan for that too. You can write recursive functions but make sure the recursion is limited or better yet find a different process.

You might look into the 1284P or a Mega2560 and external RAM if you need more RAM, and then look into a Teensy 3.6 with IIRC 256K RAM and built-n SD slot.