Hacker News new | past | comments | ask | show | jobs | submit login
I Don’t ‘Do’ Arduino (mattmillman.com)
31 points by todsacerdoti on March 13, 2021 | hide | past | favorite | 27 comments



I used to program Intel 8031 (the ROMless version of the original MCS-51) in assembly language. Really low level, like the exact right number of NOP instructions to get a loop to run at 38KHz to generate a (modulated!) infrared carrier in software. And I got more functionality out of that primitive part than most modern Arduino programs get out of a microcontroller that's about 10x better.

And I don't care! A few years ago I got an Arduino starter kit at a garage sale. I have kids now and not much geek time. I finally plugged the thing in, and literally 5 minutes later I was running code on it. Who cares that it's inefficient. It makes the difference between a project built and one not built. I already posted my most recent one the other day, but why not again...

https://github.com/MarkusWandel/battery-tester

The code is right there. It's simple, it's readable, anyone could understand it in half an hour and change it. Not as heroic as my biggest MCS-51 assembly language project, whose source code is here:

http://wandel.ca/homepage/rom.asm.html

But tell me which of these is going to get someone over the "I can do this!" threshold?


> it’s my opinion that the Arduino ecosystem is a hinderance

I'd say this blog post is the real hindrance.

It's ridiculous to suggest that people should always start at the very lowest level; that newcomers to a space are somehow "hindered" by not doing everything the hardest way possible from the get-go. It's like saying Basic was a hindrance to game programming because the people who cut their teeth on it were shielded from the concerns that "real game developers" have to deal with in C and C++. Quite the opposite! Anything that opens things up and helps more people discover an interest is good for that field in the long run, even if they have to learn more as they progress (who doesn't?).

This just reads as a big, tasteless, "look how much smarter and more experienced I am than you"


I agree. I've been programming embedded systems of all sizes from 8-bit CPUs with 500 bytes of ROM to systems powered by 64-bit desktop processors for the better part of 30 years and I disagree with most of his post.

When I start a project with an STM32 microprocessor, I don't start by digging into the hundreds of pages of data sheet and bit twiddling each register. I start up the STMCube tool and specify what peripherals I need on which pins and let the tool configure the registers correctly. If I need better performance than it provides, then I start tweaking bits.

There is rarely any benefit to making things harder on yourself. I use C++ in embedded systems because it makes things easier to abstract than C does. Hell, I've seen people basically recreate concepts like polymorphism in C because they were on a CPU that didn't have a good C++ compiler.

I feel like all the lessons learned in desktop programming over the decades are struggling to find a foothold in the embedded world.


Yeah, this blog post is a real drag. Ok, so you've been at this for a long time and are super smart and experienced. Great. That's not who Arduinos are for. They're for folks who want to use a microcontroller and don't want to have to worry about toolchains, bootloaders, and programmers.


I'm getting strong notes of "crusty old curmudgeon", and just a hint of "Get off my lawn with your new-fangled ideas!"

The unfortunate part is, I think he has a some good underlying points, especially about hidden details; and I agree that for many serious use cases, Arduino libraries are just too fickle and unreliable.

If only he had not written that whole piece from a place of professional insecurity...


One place they do have a point (for AVR-based Arduinos at least) is how damned inefficient the basic IO stuff is.

Look at this, for crying out loud![0] All of that assembly for no good reason. The pin mode only requires one or two instructions. If there's no timer config needed, a digital write is a single instruction, as is a digital read.

Even my amateurish attempts[1] (granted, with a C++17 feature) resulted in a better performing, less error-prone result, which is also easier to read.

[0] https://godbolt.org/z/1x57Ta

[1] https://godbolt.org/z/xMex4o


You should contribute these improvements upstream then.

The Arudino developers are not trying to write slow code on purpose. Mocking them on hackernews doesn't solve anything. I'm sure they would greatly appreciate you pointing out how slow this code is and offering your improved implementation.


> You should contribute these improvements upstream then.

You honestly think they'd accept changes that would break literally every single library using these functions? Somehow I find that hard to believe.

> The Arudino developers are not trying to write slow code on purpose.

Of course they didn't. No reasonable person goes out of their way to make a terrible API. That's why I'm confused and irritated about how they managed to do such a bad job.

All the inputs are bare integers, pins and mode/state, so you get no warning whatsoever when you get it wrong. I've seen posts from people confused because they tried to digitalWrite pins A6 or A7 on a Nano which is accepted by the compiler and runs, but doesn't work correctly because those pins aren't on a digital port. The other analog pins are on a digital port, so work fine.

It gets better. Let's say I digitalWrite with a pin number higher than 19 on a Nano, what happens? Well, it will start off by doing lookups in its pin tables [0]. How does it do the lookup? It just adds the user's value to the lookup tables' addresses [1], and reads that address. On the Nano, these tables are 20 items long [3]. It's going to read god knows what from your flash, and use whatever gibberish it received to decide what to do!

And, because of the need to use inline assembly for the lookups, the compiler can't reason about the data in the tables, and so can't optimize out the lookups, nor can it properly optimize code that relies on those lookups. So the result is it ends up needlessly consuming your limited flash space.

And this is an API that's supposed to be used by beginners! Beginners are the ones most likely to get it wrong because they don't know better.

They're using a C++ compiler in C++11 mode, they're not stuck in the dark ages! Why use a bare integer to represent the pin, a pin's IO mode, or the pin state, or the analog reference voltage source (which, by the way, also makes no attempt to ensure it's a valid value [4])? At the very least they could have used enum classes instead of bare integers so users get a compiler error when they fuck up.

[0] https://github.com/arduino/ArduinoCore-avr/blob/master/cores...

[1] https://github.com/arduino/ArduinoCore-avr/blob/master/cores... [2]

[2] Because of the separate memory spaces, it has to use inline assembly to do this. The pgm_read_byte macro from the AVR header is what does that here.

[3] https://github.com/arduino/ArduinoCore-avr/blob/master/varia...

[4] https://github.com/arduino/ArduinoCore-avr/blob/master/cores...


I started embedded programming with 8 bit PICs and it had to be done in assembly or and limited c compiler. I hated working on microcontroller projects become Arduino came around (got my first one in 2011). With Arduino I could make some really cool stuff and not worry about setting up the the build environment on my machine. Arduino also just works on windows, Linux, and Mac which makes it very appealing to newbies. I love my original Arduino I made some many fun projects.


Yeah! If you go back far enough real programmers didn’t see the point of this new fangled assembly language making things too easy.

https://forum.osdev.org/viewtopic.php?t=28852


The authors comments are interesting, but perhaps underplay the fantastic effect that Arduino has had on the microcontroller and maker world.

He is correct about the code size, and certainly about the abstraction hiding details, but those things don't matter for 99% of the cases. Many 'makers' are using something Arduino based to do a few simple tasks that in years past could have been done with a $1 PIC but required significantly more skill to build.

Even more so, with the advent of the ESP32 you have an incredible, fast, cheap platform with wifi that you can use to solve real world problems that those old PICs could never do - and Arduino makes that in reach for more people.

Sure, those of us that are more serious tend to do things more efficiently and directly. We also dig more into those hardware details and the underlying architecture, but the reason those boards are $5 is because of everyone else that buys them to use with the Arduino environment.

Note: I have used the Arduino environment for many years, as well as almost all of the direct platform tools. One could write a book about the compromises in the Arduino platform.. a book that few would read. For anything serious I tend towards to OEM tools and compilers, and like the author I have my own collection of libraries that I have developed, some that are pretty cool, and some that a really terrible. Sounds pretty standard for software development.


Arduinos are still cheap as hell to use - just remove the ATmega328P and use it directly after programming (you could also set things up to program controllers that aren't on the board in the first place).


The last point is the most telling; when you've got more effort invested in a lower level toolchain already; the candy version has little to offer.

Many Arduino users don't care about these points, they'll never need to know the difference between the 16kb part and the 64kb; they'll never care about the higher performance available with tighter code either. When some of them do hit a situation where it becomes relevant, articles like this will help them figure out where they need to go.


True.. and hopefully more people make that transition if only because they can help mature those other toolchains. Anyone that works with OEM toolchains knows the pains that go with it sometimes!


This is such an ivory tower kind of viewpoint. Thinking like this we'd never have high level languages and tools that make life easier for everyone.

I recently got into hardware during the past year. The learning curve (especially on the software side of hardware) is quite steep. Also the toolchains suck. Coming from a webdev world it is night and day as to the amount of open source code out there that helps you get started. Arduino helps chip away at that steep learning curve and I wish there were more projects like it.


He also really shouldn't be doing C89, but he does. I'm afraid he wrote this post because he feels he'll be behind soon.

While he fears Arduino, he does not see the bigger picture. He should be celebrating the demise of C that is coming for his livelihood.


What is replacing C?


C++, Rust, Python. Anything But C!


It's not like you're supposed to do any memory allocation on a 8-bit embedded system. C is really the right choice for AVR microcontroller.


Memory allocation is fine; dynamic memory allocation is where problems occur.


Zig


Interesting article, particularly in some ways, -

> It’s never too early to start thinking about the long term prospects of the product you’re building.

- it's practically the opposite of what on higher level of software development is called YAGNI - "you ain't gonna need it". In other words, it's actually detrimental to "optimize too early", in more than one way.

At the same time it would be nice to have an alternative way to develop software for microcontrollers, without Arduino's unwanted features, like those described.


This sounds like someone who has been in their field so long they've forgotten what it's like to be a beginner. They've utterly missed the point of Arduino. It's not for them, it's for beginners, and hobbyists, optimized for fast feedback and making it hard to screw up too much.

I mention fast feedback, because it's so important to new entrants to a field. I tried to build some MCU project way back in the early 2000s, which involved soldering together a parallel port based programmer, and attempting to drive a blinking light as the first project.

It didn't work. I have no idea why. Maybe I had blew some components up or put one in backwards. I don't know what I did wrong, and I didn't know enough to debug it. I didn't know enough to know what questions to ask.

When I came back to MCU programming many years later, I picked up an Arduino kit. A small part of me felt like it was cheating, but it let me get started. It let me iteratively play around with and learn concepts piece by piece. Ironically, I feel like now I'd actually now have a chance of debugging and fixing that parallel port programmer.


This! I have a nice hackable ESP32 clock (Lilygo TTGO T-Watch-2020) that apparently is wired so that it can go to deep sleep and wake up on button press. Except all code samples use intimidating big library supplied by manufacturer which seems not to support it. The reason I discerned is that all intended use cases include wifi connection maintenance.

So, the battery needlessly dies in a day.


While it is probably true that the provided library is incompatible with sleep modes, it is also true that ESP sleep modes are said not to work right. Just from the data sheet, the regular sleep mode draws quite a lot more current than it should. Apparently, getting it to wake up reliably from a deep sleep mode, instead, where power draw would be reasonable, is more tricky or unreliable than is documented.

If you want a true low-power system, you probably need to use STM or something else.


It has a second chip (AXP202) that is responsible for battery /power and has the button directly wired to it. That's why I believe deep sleep should be possible. If it needs to reboot instead, fine I can accept a ~second delay. But again, the supplied firmware boots 5 seconds and I've no idea why and how to rectify it.


This post reminds me of the "REAL programmers use butterflies" XKCD comic: https://xkcd.com/378/




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: