cpp or ino

I'm restarting this discussion and it could readily be part of a couple of others, including:

and programming - Classes and objects: how many and which file types do I actually need to use them? - Arduino Stack Exchange
because it seems to come up in a lot of different posts
https://forum.arduino.cc/index.php?topic=534474.0

I've also looked at a bunch of examples in github, etc. and then looking at the practicalities of developing a small but not trivial application that includes wifi, ntp time, a web server for the UI, config variables, hardware and communication access, logging, timers, and then the operational state machine.
It would be nice if there were in the tutorials, rather than scattered across this forum, stackoverflow, github, and very thick C++ tomes, about the best ways and the trade-offs for doing a somewhat sophisticated "sketch" on the arduino supported platforms. There are at least two issues here:

  1. What are the trade-offs of various approaches in general
    2 Whether the arduino IDE is the best tool for doing the job.

The comments by Robbin and gfvalvo in the 588837.0 post set the tone. Hybrids are possible, and maybe preferred in some cases. Following gfvalvo, for example, takes one down the path more oriented toward classes and objects. (note: I'm no expert programmer here, so I may make incorrect assumptions, hence my request for a primer or tutorial on the matter). And that seems to be more work. For example, I have a web server in may main .ino file, and started out with all the route handling code in a routine in another file/tab. It worked. But it's not very clean. But when I convert to .cpp and .h. the .cpp file doesn't have the scope to know what is the server, and since it's not a class, I could try passing it to the function, but it would be cleaner to make the web module more or less stand alone. Then this creeps into how much encapsulation to do , variable passing, interfaces to hardware, minimizing global variables, etc. How does a class communicate with other classes, pass by reference, etc are all important topics. And then there are things like lambda functions that I really don't know what is involved. So a tutorial organized around these topics could probably help a lot of people And I'm certainly not the only one who is not exactly an experienced coder who is trying to do something more complicated than an example sketch.

I would say never use more than one .ino file.

Important in a large project is to break it down into separate, more or less autonomous, units with the smallest possible interfaces between them. Each unit would be represented by a .cpp and a .h file. Knowing how to take a real world problem and break it down into such logical units that is something which cannot come from text books and tutorials alone.

It will help to study how other large projects, similar to what you are trying to achieve, have been put together but there is no substitute for experience. So start trying something. If you find that every unit needs an interface to every other unit, that is a sign that you’ve done something wrong.

As for the IDE, just use the Arduino IDE to start with. You’ll grow out of if at least when you have so many .cpp and .h files that the IDE cannot display all the tabs properly that these create.

dduehren:
It would be nice if there were in the tutorials, rather than scattered across this forum, stackoverflow, github, and very thick C++ tomes, about the best ways and the trade-offs for doing a somewhat sophisticated "sketch" on the arduino supported platforms.

Regarding program structure...
Take ten programmers and you will have ten different structure methodologies. All equally valid.

You use the process and structure that works for you. Personally, I like tabs. This way I don't have to recreate the wheel with every project. For example, if I need MQTT and WiFi in my sketch, I just copy my "stock" mqtt.ino and wifi.ino into the project folder. Add some globals in the main file and call the functions when appropriate- usually in setup().

I think the record I've ever compiled on Arduino was Tasmota for the 8266. It had 253 tabs. I know the writer didn't use Arduino IDE, but it does compile.

Other programmers organize their functions in .cpp/.h files. I may yet, but tabs work for me.

SteveMann:
Other programmers organize their functions in .cpp/.h files. I may yet, but tabs work for me.

That’s irrelevant distinction. The Arduino IDE displays all applicable file types (.ino, .cpp, .c, .h) in “Tabs”. Using all .ino files in your “Tabs” is no different than one giant .ino file as the IDE smashes all .ino files into one file before handing it off to the compiler. Separating your code into individual translation units helps you modularize your project — making it easier to debug, maintain, and scale.

dduehren:
Following gfvalvo, for example, takes one down the path more oriented toward classes and objects.

Not necessarily. I assume you're talking about my Reply #3 in that thread.
The techniques described there are equally applicable to organizing and modularizing your code as traditional C-type functions as they are for using classes. BTW, your statement that using classes "seems to be more work" is purely subjective.

That post is a concise and relatively complete description of how code can be modularized using .h / .cpp files and what the contents of each file type should be. What do you have a question about?

2 Whether the arduino IDE is the best tool for doing the job.

It is certainly possible to partition your code into a single .ino files with multiple .h / .cpp files using the Arduino IDE. The question of it being the "best tool" is, again, subjective.

Are any you familiar with the SPIFFS file system? I'm trying to figure out how to mount it once and then make it available to other cpp functions and classes. Does FS.h serve as the .h for a global object like SPIFFS, or do I have to somehow pass it to the files and classes, and if I do that, what it's type would be.

This is an example of of the things I struggle with in trying to modularize the code where the web server needs file access as does the logger and, at startup, the configuration system.

Take a look at this example project: https://forum.arduino.cc/index.php?topic=559652.0
It uses SPIFFS (which is anyway deprecated in favour of littleFS ) and most of the other things you mentioned in your OP: wifi, ntp time, a web server for the UI, config variables, hardware and communication access etc.
You can see from the documentation how it is built up, and you can easily strip out what you don’t need because it is quite modular.

6v6gt:
It uses SPIFFS (which is anyway deprecated in favour of littleFS )

Surprisingly, not on ESP32. In fact, there isn't even support for littleFS in the standard ESP32 core.

Hi,
I looked into the source code of FS.h and it appears the SPIFFS supports more than one mounting.

Now I have a question about why the compiler isn’t recognizing variables in my .h file. The compiler complains that most of the variables I declared as private “are not declared in this scope”. I’m wondering what I’m missing since I have another library that is very similar that works fine. I’ve attached the .h and .cpp files and could use some help on this.

Thanks,

David

relay.cpp (2.49 KB)

relay.h (733 Bytes)

I should add that I've ordered a book on C++ since it's clear to me that I don't know enough to do this.

Laying out your project should be simple. Think of it like running a battleship. You are the .ino file your crew are the .cpp/.h files. (classes in my case) The battleship is the hardware you control to accomplish your mission.

As for SPIFFS, why would you want something like that? Seems mighty limiting.

-jim lee

I fixed the obvious errors. All of the problems are in the internal routine for sending a command. And this gets to the part that I don’t understand. Why aren’t the class variables like global variables to this subroutine which is called from one of the regular commands. Is there a simple way to tell it to use the context its called in? Should I just make it a relayCmd::sendCmd() function, even though it’s internal?

I’ve attached the cpp file with the corrections to the other errors.

As I said, I’m still learning the C++ stuff.

relay.cpp (2.59 KB)

It works by making that routine relayCmd::sendCmd() , even though it's a private function I see that it's not part of the class unless it starts with the class:: priors.

Sorry to be a bother.

  • David

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.