Design pattern State with Arduino?

Hi, I'm currently programming on an ATmega328P (arduino uno) and I don't understand why I can't use the design pattern state on my microcontroler.

I'm currently working on a project that asked me to use a state machine to make the robot accomplish multiples steps. This is what I started to do, but quickly I figure out that it could be a lot more simple to use the design pattern State.

Normally, you wouldn't be able to create an objet with a pointer. I think that the keyword 'new' is not supported. Therefore, for being able to make an object with a pointer, I instantiate my objects by allocating memory manually with malloc and free. Exemple: AbstractObj absObj = (AbstractObj)mallloc(sizeof(AbsObj)); Once I want to delete my object, I use: free(absObj);s

I made a new very simple project just to see if the architecture would work and I saw that it's just not working correctly. It tells me that it cannot recognize the functions that I'm calling in the main (the funcitions called by client). I feel like it's not capable of doing polymorphism.

The Arduino is programmed in C/C++.

Anything you can express in C/C++ that fits within the resources of the Arduino you are using will function as you would expect it to.

There are no missing or removed features.

Post code you think should do something but doesn't, or is doing something you don't think it should.

a7

What makes you think that ?

That used to be true, a long time ago.

Easy enough to find out...

Well, it might be because I've used linux with avr-gcc for a long time. I was normally using makefile that would directly use avr-gcc to compile my programs. I've only recently switched from using linux to using Visual Studio Code via arduino's extension. However, by looking online, I saw that arduino's compiler is still avr-gcc. I thought that the issues that I had with avr-gcc would still be present.

I saw that arduino's compiler is still avr-gcc. I thought that the issues that I had with avr-gcc would still be present.

I thought that it could work in the .ino file and not show errors in the rest of the files. The .ino file confuses me. It allows me to use _delay_ms() which comes form <util/delay.h> without including the library. However, I can't do that with the other cpp and h files.

When you do that, nobody calls the object constructor. That's why you use 'new'.

It looks like the supported way to create an object with malloc() is to use a 'placement new':

AbstractObj *absObj = (AbstractObj*)mallloc(sizeof(AbsObj));
new (absObj) AbstractObj();

Later you must explicitly call the destructor before freeing the memory:

absObj->~AbstractObj();
free(absObj);

Yes, me too. Still. :expressionless:

google

 arduino preprocessor

and look around, I see this

which might shed some information.

It is an odd arrangement for ppl accustomed to handling everything manually, or with make or whatever, but it was an honest attempt, I assume, to make things easier for noobs,

a7

Oh, it makes sense now that it's using a preprocessor. Of course, personally I hate use it. I delete the setup and the loop function and place a int main() function inside of it instead.

This answer is amazing, thank you so much! Going to test it right away!

Actually, I've looked at c++ version and it says that it's version c++14. However, I have compiling errors while using the keyword 'new'. By looking at the mangling, it seemed like the error was due to the constructor. We were able to solve the problem by making a file.h whose job is only to let me use the keywords new and delete

Do you mean you tried to create an object with 'new' and got an error because you didn't pass the required constructor arguments?

No, the objects that I wanted to create doesn't need any parameters. Actually, using arduino as my programmer, it's now able to run perfectly. I don't have any issues. However, when I was using only avr-gcc on linux, I encountered mulitple problems with the exact same code. I think that the problem is more about the use of avr-gcc than about arduinos. I don't think that avr-gcc can support polymorphism. Arduino preprocessor seems to make this possible.

That would be a total failure for what is probably the world's most commonly used C++ compiler. The Arduino IDE uses the avr-gcc compiler (for AVR platforms like the UNO, NANO, Mini, MEGA, Leonardo, Micro...). Can you show an example of a C++ program that compiles on the Ardiuno IDE but not on the avr-gcc?

This is an exemple of a code that works on Arduino that doesn't using avr-gcc. For compiling the program, I first compile the library with the command 'make clean && make' and then, I can compile the main program compiling the second makefile using, once again, 'make clean && make'. The library is independant of the main.

Projet_not_working.zip (13.2 KB)

When I compile that with the Arduino IDE there are some ominous warnings for Line 11 and Line 17 of Robot.cpp

Robot.cpp:11:12: warning: deleting object of abstract class type 'AbstractState' which has non-virtual destructor will cause undefined behavior [-Wdelete-non-virtual-dtor]
     delete state_;
            ^~~~~~

Robot.cpp:17:12: warning: deleting object of abstract class type 'AbstractState' which has non-virtual destructor will cause undefined behavior [-Wdelete-non-virtual-dtor]
     delete state_;
            ^~~~~~

Adding "virtual ~AbstractState() {};" to AbstractState gets rid of the ominous warnings.

Has the OP taken the time to read ANY Arduino tutorials??? He seems to have some pretty massive misunderstandings about the most fundamental aspects of Arduino programming that could easily have been corrected by spending even a single hour with some beginner Arduino tutorials.