Go Down

Topic: Arduino the Object Oriented way (Read 6837 times) previous topic - next topic

PaulMurrayCbr

I response to many and various threads on this programming boards, I have done a bit of a write-up on how to go about doing Arduino projects by treating the components of your sketch as objects.

The write-up is here on github.

ArduinoTheOOWay.html

Don't know if it's any use to anyone, but I'd like to hope so.
http://paulmurraycbr.github.io/ArduinoTheOOWay.html

TomGeorge

Hi,

Thanks mate, have just copied it , will do some holiday reading  and experimenting.
Looks good on just a quick scan.

Tom.... :)
Everything runs on smoke, let the smoke out, it stops running....

CrossRoads

Couple of nit comments:

Why int here and not byte?

const int BUTTON_PIN = 7;

Same with state, prevState, pin. variables that are only 0/1 don't need to be ints, and there are no pins above 255, so they also don't need to be int. You have int's all thru the example that could be byte instead.

I like the explanation you provide.  This looks like stuff I just code inline in my sketches. MrsCrsossRoads ridicules me for it, but I figure I'm saving processing time by  not jumping back & forth in &  out of functions, just performing the simple digitalWrite of whatever is starting the class. Also I don't want to take the time to create all that stuff every time, nor can I remember how every class created over the years is used. Basically sounds like I'm a lazy, not too bright coder! I think having to figure that stuff out every so often helps me to keep thinking about what's really going on tho.
My fencing scoring machine is 25 pages long of code - no functions except setup() and loop(). No classes, etc. The code acts like it tho with a couple of flags to indicate between sections that something needs performing - when a score is updated for example, the score variable is updated, a displayUpdate flag is set - the updateScore test gets its shot and checks the flag and updates the display as needed, clearing the flag.
All the code is inline, and if you read it it's basically what someone might write as 3 functions:
void loop(){
checkRFinput();
checkTouchInput();
updateTimeScoreDisplay();
}
However, I also don't like jumping back and forth in a sketch trying to find a section that is referenced, which also leads to my preference for inline code.
Chalk it up to poor programming preferences by a hardware designer looking for speed over code niceness.

Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

PaulMurrayCbr

Couple of nit comments:

Why int here and not byte?

const int BUTTON_PIN = 7;

Same with state, prevState, pin. variables that are only 0/1 don't need to be ints, and there are no pins above 255, so they also don't need to be int. You have int's all thru the example that could be byte instead.
I use an int because the pinMode and digitalWrite functions take ints.

In justification: the arduino is a 16-bit processor, so it's all just one bus read anyway. Using ints means that things wind up on even byte boundaries, which might be a good thing (It was a thing back in the day on x86 processors). If your sketch is just one byte short of being able to fit into ram, you probably need a mega.

If you have big arrays then that's a different story, agreed.

I like the explanation you provide.  This looks like stuff I just code inline in my sketches.
Absolutely. Classes just provide a way of organising your code. The difference between using classes and not using them is like the diference between using block-structured code and using gotos. Block-structured languages happened because people started noticing that coders followed consistent idioms when writing loops, ifs, and all the rest. Classes are the same - they are formal support in the language for things that people are doing anyway.

MrsCrsossRoads ridicules me for it, but I figure I'm saving processing time by  not jumping back & forth in &  out of functions,
Yeah, there are inefficiencies doing it this way because class methods can't assume an absolute location for your variables. In fact, the memory address of the instance is passed invisibly to every method. If you need hand-tuned speed, working this way won't do the job. But, it's not that bad. At a guess, the instance address goes into a register, and the generated code uses register-relative addresses.

If microseconds matter then this pattern is not suitable, and for some microcontroller projects, microseconds do matter. The really high-speed arduino stuff with be working with interrupts and ports. Even then, however, it can make sense to use classes to do things that operate at human speed - manual switches, blinky lights.

The main benefit is that you can code up complex things that mostly work first time, without burning out your brain keeping track of all the possible permutations of state in your system.
http://paulmurraycbr.github.io/ArduinoTheOOWay.html

CrossRoads

"I use an int because the pinMode and digitalWrite functions take ints."
" Using ints means that things wind up on even byte boundaries, which might be a good thing "

In the datasheet 8.3 SRAM Data Memory shows the SRAM Memory as 2048 x 8 in Figure 8-3. Data Memory Map, which would seem to be in disagreement with the latter statement.

And this also says to me that ints are not required to use SRAM bytes directly:
 "The direct addressing reaches the entire data space.
The Indirect with Displacement mode reaches 63 address locations from the base address given by the Y- or Zregister.
When using register indirect addressing modes with automatic pre-decrement and post-increment, the address
registers X, Y, and Z are decremented or incremented."








Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

PaulMurrayCbr

In the datasheet 8.3 SRAM Data Memory shows the SRAM Memory as 2048 x 8 in Figure 8-3. Data Memory Map, which would seem to be in disagreement with the latter statement.
Ok. Use bytes, then.
http://paulmurraycbr.github.io/ArduinoTheOOWay.html

RayLivingston

I use an int because the pinMode and digitalWrite functions take ints.

In justification: the arduino is a 16-bit processor, so it's all just one bus read anyway. Using ints means that things wind up on even byte boundaries, which might be a good thing (It was a thing back in the day on x86 processors). If your sketch is just one byte short of being able to fit into ram, you probably need a mega.
All of which is neither here nor there.  If the value will fit into a byte, there is no benefit whatsoever to putting it into an int.  The compiler will cast it to an int when passed to a function that takes an int.  And worrying about byte alignment is equally pointless.  The compiler will automatically enforce any memory alignment requirements imposed by the processor architecture.  You don't need to "help" it.  

Bottom line, you're wasting RAM, without getting anything whatsoever in return.

Regards,
Ray L.

PaulMurrayCbr

I cant help feeling that people responding on this thread are missing the point a little.
http://paulmurraycbr.github.io/ArduinoTheOOWay.html

Camel

I cant help feeling that people responding on this thread are missing the point a little.
I feel ya buddy  :) It's a good write up.

Robin2

I have bookmarked your link - thank you for taking the time to write a clear and simple tutotial.

That said, I always have the feeling that OOP is bolted onto C as an afterthought. It is constantly in my mind "I don't actually need all this s**t"

Whereas, in Ruby EVERYTHING is an object and you can't NOT use objects. However that does not require you to create classes just to do simple things with Ruby. If you create variables that "appear" to be outside any class they are actually part of a class (forget what it is called). This makes it very easy (in the Arduino sense of easy) to get started with Ruby.

I gave up Ruby in favour of Python because Python is more widespread (at least in the Arduino community) and because Python is better integrated with its environment (e.g. there is only one pySerial that works on all platforms). But OOP in Python has the same "bolted-on afterwards" feel as it has in C/C++.

The best example I know of how OOP can kill the will to live is Java - even though I think the JVM is excellent. I wonder how many people have given up programming completely because their first exposure was to Java.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

pYro_65

#10
Dec 28, 2015, 10:49 am Last Edit: Dec 28, 2015, 10:52 am by pYro_65
Yes Robin, we have all heard many times how you prefer doing things with out classes etc... (sometimes the hard way, just because code is inside a class and may not expose a newbie to every concept used inside it).

Your very biased attitude towards interfaces and objects is most probably what is holding you back. It seems you gave up on them before learning enough to see the real benefit in using them for what they are.

Being able to encapsulate a few features like shown in these examples is only scraping the surface. The C++ type system is built around having the ability to extend it.

If you need a feature/type that is not provided in the standard, you can make it. By using operators correctly you can create new types which leave your top level code (sketch) looking like nothing more than a C program. None of which has anything to do with the object orientated paradigm (that's all it is, an idea, a method of using classes a certain way, not a requirement).

The more you learn, the more you'll see their benefit (the learning curve isn't really a reason to hide it from newbies either).
Forum Mod anyone?
https://arduino.land/Moduino/

combie

Quote
I use an int because the pinMode and digitalWrite functions take ints.
No.

Code: [Select]
void digitalWrite(uint8_t pin, uint8_t val)
.....

void pinMode(uint8_t pin, uint8_t mode)
....

See: wiring_digital.c
"Freiheit, Gleichheit, Brüderlichkeit!"
Aber wie gelangen wir zu den Tätigkeitswörtern?
Quelle: Stanislaw Jerzy Lec

Robin2

#12
Dec 28, 2015, 11:26 am Last Edit: Dec 28, 2015, 11:27 am by Robin2
Yes Robin, we have all heard many times how you prefer doing things with out classes etc.
I think my comments are as reasonable as yours are, but I have not made any personal criticisms.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

pYro_65

I think my comments are as reasonable as yours are, but I have not made any personal criticisms.

...R
You're opinions are just as valid as the next persons.

I'm not criticising you personally, I'm criticising your opinions you openly voice regularly on the forum regarding classes/objects. Refuting an opinion is not an attack on the person voicing the opinion.

I'm sorry if you feel like I'm attacking you, It just seems like you constantly argue your opinion against a topic which is well and truly proven beneficial by millions of programmers. So I feel it appropriate to argue against it... Fair?

And many times I've seen posts with people offering new ideas or concepts using classes only to have their work criticised because what it offers can be done without a class. And sometimes it has ended up with you mentioning that you do not fully understand the concepts being used. Which is fine, but still a biased influence.
Forum Mod anyone?
https://arduino.land/Moduino/

PaulMurrayCbr

No.

Code: [Select]
void digitalWrite(uint8_t pin, uint8_t val)
.....

void pinMode(uint8_t pin, uint8_t mode)
....

See: wiring_digital.c
Well, that's different then. I have modified the page.
http://paulmurraycbr.github.io/ArduinoTheOOWay.html

Go Up