Trying out Arduino
01 December 2023Back in late-2013 shortly after returning from New Zealand I bought an Arduino Franzis from Maplin with the intention of driving an
HD44780
compatible LCD display from it, but for reasons long forgotten never got very far and since then got into firmware development via Microchip PIC microcontrollers instead.
Recently I obtained an Arduino Nano in order to see what the hardware and its eco-system were like, particularly for experimental work on solderless breadboard as these days I do relatively little firmware development.
On the whole I am impressed although I have my doubts about it displacing my current choice of microcontrollers.
Arduino IDE
I was on the road when I got hold of my Arduino Nanos so my first experience of the modern Arduino IDE was on MacOS rather than my usual Linux, but on the whole I took to it quite quickly once I worked out how to allow running of internet-downloaded packages. Like most IDEs there is plenty I dislike about the Arduino IDE and this may have played a part of me quickly giving up on the Franzis back in 2013, but it had the redeeming feature of detecting when eternal programs have changed source files so at least my much preferred GVim can be used for the actual writing of firmware code. There is a SlackBuild for the Arduino IDE but it is the legacy v1.8.x series which looks like it was discontinued last year, and the precompiled v2.2.1 pretty much just works wherever it happens to be unzipped. Underneath it looks like a real Italian plumbing job so did not put much effort into working out how to compile and upload usingarduino-cli
from the command-line, but this is something for another time if and when I make use of Arduino for an actual project.
The Nano hardware
I originally obtained an Arduino Nano ESP32 but then found out it used 3.3-volt I/O rather than the 5 volts my circuits typically use, and in order to avoid messing around with logic-level converters soon ordered in an older ATmega328P-based unit. Since there were lots of cheap Arduino clones also listed one of them was also ordered in, partly to quality for free delivery and partly to see whether they were any good being a quarter or less than the price of the “genuine” Nanos. In order to give the Arduino a proper test I did what got me intro electronics in the first place and partly recreated my RS232-driven display which made use of the relatively robust text-based LCD display — by default all non-power pins are input so over-volting aside any miswiring won't damage anything.
A really nice feature is having both built-in regulated power supply and built-in firmware programming which negates the need for any sort of support infrastructure, while also leaving open the option of using external power which can be either regulated or unregulated. The same thing goes for the RS232 support as well since in more recent years I have used RS232 via a USB adapter as either an interface and/or a debugging side-channel. It would have been the perfect thing for trying out chips like the Atmel parallel EEPROM as at the time I was needing to minimise how many components I kept close at hand.
Writing firmware
There is a library specifically for the control ofHD44780
compatible LCD displays but for the purposes of this exercise it is not used, and instead the firmware is written using only the most generic functionality of the system.
Arduino's programming language is somewhere between C and classic C++ although to a modern audience I would buck the trend and simply classify it as C since it is nothing like the incarnations of C++ of the last 10-20 years, although indications are the underlying compiler is GCC so I suspect people could use the more exotic C++ features if they really want to but to me this is the wrong mind-set for low-level firmware development.
Arduino exposes a lot of chipset functionality through built-in functions so all that is needed to reimplement the serially-controlled text display could be done through language-level APIs rather than needing to use special registers, although for sake of efficiency some drilling down to use the latter is done which results in clean and concise code:
void bangEnable() { digitalWrite(4, HIGH); delay(1); digitalWrite(4, LOW); delay(1); } void bangNibble(unsigned int bits) { PORTB &= !0b11110; PORTB |= bits <i;< 1; bangEnable(); } void bangLetter(unsigned int letter) { unsigned char lo = letter & 0x0f; unsigned char hi = (letter & 0xf0) >> 4; digitalWrite(2, HIGH); bangNibble(hi); bangNibble(lo); } void setup() { pinMode(2, OUTPUT); pinMode(4, OUTPUT); DDRB |= 0b00011110; // Pins 9..12 digitalWrite(2, LOW); bangNibble(0x03); bangNibble(0x03); bangNibble(0x03); bangNibble(0x02); bangNibble(0x00); bangNibble(0x0c); bangNibble(0x00); bangNibble(0x01); bangNibble(0x00); bangNibble(0x06); Serial.begin(57600); } void loop() { while( Serial.available() > 0 ) { int letter = Serial.read(); bangLetter( letter ); } }
While digitalWrite(pin, bit);
is verbose it does provide a way to address individual pins which is an important thing with typical bit-banging like this that a lot of microcontrollers end up doing, but the clarity is as good as it gets so someone with knowledge of C but not Arduino itself would have no problems understanding this.
My frame of reference is writing PIC microcontrollers using SDCC which is something I eventually abandoned in favour of writing directly in assembly because of the poor job SDDC did of targeting the PIC instruction set architecture, which is why the last PIC firmware I wrote using C which did various tricks including inline assembly to get round the poor integration between SDCC and the target assembly language, and Arduino is clearly so much more polished.