order in Arduino IDE

Functions are to be defined outside void setup and void loop. Ok. Before being defined, they have to be declared. OK again.

But I cant figure out the order in Arduino IDE.

Namely, I guess it is like this (please correct me if I am wrong):

  1. pre-compiler
  2. declare functions
  3. define functions {in brackets}- is that also allowed after void loop? I saw this in some examples, but I cant understand whether they can be wherever in the code sequence (before or after the void loop) or just in one place- very puzzled
  4. void setup
  5. void loop

Now, as far as I understand, functions can be defined (either void or typed) in the separate tab in Arduino IDE, so no bother with the order.

Thank you for any light!

If you create a function prototype, or let the IDE create one for you, the position of the function relative to where it is called, doesn't matter.

If you use multiple tabs, with the ino extension, they will be collected into one file for compilation. The individual files are joined in alphabetical order by tab (and ino file) name. Function prototypes are generated after the ino files are merged.

My suggestion is that you stick with ONE ino file. If more files are needed, use .h and .cpp as the extensions and define your own function prototypes.

PaulS:
My suggestion is that you stick with ONE ino file.

Why do you recommend against multiple .ino files?

pert:
Why do you recommend against multiple .ino files?

Because I do not like to have to resort to naming them in a convoluted fashion to get the IDE to assemble them in the correct order.

If a sketch grows beyond the point where one ino file is sufficient, using classes/libraries makes more sense to me.

If I go by declaring the function along with its statements, in one place- then this can be done wherever I want (before or after pre-compiling, after the void loop, in between void setup and void loop or even in separate tabs (paying attention to multiple ino files, as @Paul wrote)?

Did I correctly understand?

@ Paul

I do not know how to make classes or libraries (yet). I will learn.
Libraries sound to me like a sort of subroutines that are called and stay resident while the main program is executed. It scares me because I saw SD library eating up a lot out of my defenseless Arduino UNO. :-).
Clasess - I do not know anything about them (for the moment).

Libraries sound to me like a sort of subroutines that are called and stay resident while the main program is executed. It scares me because I saw SD library eating up a lot out of my defenseless Arduino UNO. :-).

A library is simply a collection of functions, whether or not a class is involved. Those functions will take up no more, and no less, memory than the function would if it were in the ino file instead.

@ Paul

Then I guess that the reason why SD library is huge is not that it is a library, but because its functions eat up memory anyway.

I have to learn classes and libraries. Hope I will finish soon learning EEPROMs to move on.
I must confess I feel a bit confused by C++ functions anyway. Why do we need void functions anyway? Wouldnt be easier to just get a ghost return?

I found very rapidly that my codes gets scattered and confused in Arduino IDE. I read the "how to" in the programming section of this forum. Its ok, but does not solve the clarity problem. I feel the need for a more structured approach in coding. Perhaps library and classes are the answer. Certainly, from one senzsor + 1 LCD ahead, linear code is to confusing, for me at least.

Then I came to the order question.

So, if in the main program I can go with a main module and call the subroutines (either classes or libraries) from this one, this will be a gain in the structure. But I must understand very well what follows what.

Then I guess that the reason why SD library is huge is not that it is a library, but because its functions eat up memory anyway.

Correct. Actually, it is primarily because the SD class needs a 512 byte buffer for every open file, since file.print() writes to the buffer, not to the file. The file only gets written to/read from when the buffer is full/empty. Other writes/reads get data from the buffer.

Wouldnt be easier to just get a ghost return?

Maybe. That depends on your definition of "a ghost return". Outside of the sequels to Ghostbusters, I've never encountered a ghost return.

A void function does not return anything, right? To me it looks like a command. Print "abc" does not return any value, but does print "abc". Calling a function and do nothing with the return of the function.

+++

Anyway, I had a look on classes in C++.

As far as I could understand in this incipient stage, does not matter where are they physically located in the program - as long as they are outside the main section. In other words, the main program alone dictates the order, sequence (etc.) of the execution of classes. However, they must be in the same file, while libraries have a standalone existence.

I guess this is also valid in Arduino IDE. Although declaring classes can simplify the life, from visual point of view, having 20 classes one after another may turn to a nightmare, taking into account that the editing is very basic in IDE (no colors, no increased sizes etc).

So I came to the conclusion that keeping the order of the classes is a task in itself. How this is to be done, I do not know. ??

+++

In my project - I must know Miow class is executed after Purr class, if I told to the program to do so, no matter where these classes are placed in the program.

The ideal case would be to upload one routine (say class) only if I need it and discard it from memory afterwards. This is not just a matter of memory space, but also a matter of speed and code clarity . I do not know whether this is possible in Arduino world.

Print "abc" does not return any value,

Nor is it a valid function call.

   Serial.print("abc");

DOES return a value. The value is 3. It's just that most times we don't care that the function printed three characters to the serial port.

Calling a function and do nothing with the return of the function.

There are times when people call functions that return a value, and do nothing with the return value, and that is correct. There are times when people call functions that return a value, and do nothing with the return value, and that is wrong. Serial.print() returns a value (the number of characters printed), but we rarely care, since it is what the function does that is important, not what it returns. The analogRead() function, on the other hand, is usefully only when we care about the return value.

I found that I can free-up space by using destructors in classes. May worth in case of big data, but pretty useless to get rude of the class itself when not needed.

The more I look into C++ the more I become concerned about inter-operability of Arduino IDE and C++.

OK, C++ is non-linear. But this means I need a pretty sound engineering method prior to getting to coding. Otherwise chances are to get lost rapidly. First, in terms of keeping track of time. The delay command makes the procedures even more incomprehensible in terms of timing.

So the question turns to where I can find a beginer tutorial in engineering the programs with C++ in mind? Not C++ syntax as such.

I’d recommend getting a solid foundation in Old School ‘C’ before moving on to OOP and the other features of ‘C++’. There are any number of introductory books and online tutorials. Start with Google.

falexandru:
I found that I can free-up space by using destructors in classes. May worth in case of big data, but pretty useless to get rude of the class itself when not needed.

It sounds like you don't have a full grasp of the concepts involved here, like the difference between class and object. I can't tell if you're expecting the destructor to free up RAM or Flash space. Also your comments about "execution of classes". Classes are not executed, functions are.

The more I look into C++ the more I become concerned about inter-operability of Arduino IDE and C++.

I don't know how you can be concerned. Arduino is C++ with a little bit of extra preprocessing for convenience.

OK, C++ is non-linear. But this means I need a pretty sound engineering method prior to getting to coding. Otherwise chances are to get lost rapidly. First, in terms of keeping track of time. The delay command makes the procedures even more incomprehensible in terms of timing.

This is true of every programming language in existence. A language that could only execute a single linear sequence would be very nearly useless.

Do not use delay(). It is the most abused function here and its presence in a sketch (for anything more than a quick proof-of-concept test) is repulsive to me. The sooner you cultivate a healthy disgust for it, the better off you will be.

OK, I said I just started to learn C++. I already learn a lot from your comments here. You will be amazed to know how little attention is paid to crucial knowledge in most internet references, while obvious facts are repeated over and over again.

O spent one day in searching youtube about EEPROM memories, with little result.

Again, all people in this thread are of utmost help and I just cant find my words to thank you. I know how difficult may be to answer to bizarre questions.

++++

Good idea to revert to C for a while. I was afraid not to get caught in obsolete methods. But, why not?

The way I learn (not only Arduino, but everything I need) is to read, do and ask in parallel. I found this method extremely effective.

+++

In the EEPROM delay(5) is said mandatory to allow time for the chip to write. Is there any other way to cope with this?

Since my projects and needs are very much related to timing, the delay command is by its nature "disgusting" me. As the GoTo in the old school.

The point is most examples I found target beginners and are ment to offer rapid, effortless results.

An EEPROM write takes 3.3mS to complete. The library may take that into account already.
Write yourself a simple test to confirm:
capture the time, startTime = micros();
perform the EEPROM write.
capture the time again, endTime = micros();
determine how much time passed, elapsedTime = endTime - startTime;
If it's around 3300, then you know the library is waiting out the write.
If its much faster, then you need to do something to let the EEPROM write finish before starting another one.

falexandru:
OK, I said I just started to learn C++. I already learn a lot from your comments here. You will be amazed to know how little attention is paid to crucial knowledge in most internet references, while obvious facts are repeated over and over again.

Actually no, I would not be surprised.

It's been quite a while since I was in the newbie phase for C++, so I don't exactly remember what was most helpful for me. One thing I do know is that as part of my ongoing learning, no tutorial beats a comprehensive reference. For the C++ language itself, try CPP Reference. For the AVR specific libraries that the Arduino core is built on top of, the avr-libc modules page is indispensable.

In the EEPROM delay(5) is said mandatory to allow time for the chip to write. Is there any other way to cope with this?

I'm not sure which EEPROM you have, but for the one I looked at (datasheet attached) there is an "Acknowledge Polling" section that describes how you can check if the EEPROM is finished with it's write. This EEPROM takes 10-20 ms to perform a write, so you can't just trust a blind 5 ms delay. I imagine most EEPROMs will have a comparable way to check if the write it finished. The method for this EEPROM might even be a de facto standard common to most I2C EEPROMs.

Since my projects and needs are very much related to timing, the delay command is by its nature "disgusting" me. As the GoTo in the old school.

You're off to a good start.

Regaring some other thing you asked in a previous post:

Why do we need void functions anyway? Wouldnt be easier to just get a ghost return?

C++ follows the philosophy of strong typing. Everything must be declared with a specific type, and implicit conversions are only allowed according to strict rules. By having void as a return type, it tells the compiler that the function will not return a value and cannot be used as part of an expression. Nonsense like int var = loop(); will give you a compilation error.

An EEPROM write takes 3.3mS to complete. The library may take that into account already.
Write yourself a simple test to confirm:
capture the time, startTime = micros();
perform the EEPROM write.
capture the time again, endTime = micros();
determine how much time passed, elapsedTime = endTime - startTime;
If it's around 3300, then you know the library is waiting out the write.
If its much faster, then you need to do something to let the EEPROM write finish before starting another one.

falexandru did not specify that it was the internal EEPROM. And since a library was referenced, I assume it's an external one.

AT24C32 - EEPROM, I2C 32k.pdf (210 KB)

AND, if you want to impress the noobs with your C programming knowledge, stop calling functions "voids". :slight_smile:

I played few days with EEPROM AT24C256.

This one: