Developing in C for the ATmega328P: Code vs. Cost

4 minute read

Where I demonstrate the value of coding efficiency to reduce the cost of hardware.

Video

Introduction

In the another entry, I discussed code size, program space and RAM requirements and why they matter. Here are my thoughts from that page:

Why Size Matters

(From Developing in C for the ATmega328P: structures)

With each variation of code, I will also discuss code size in number of lines, program space and RAM (data) requirements. Given how simple this program is, it might seem obsessive. I want to illustrate the importance of the three elements for the following reasons:

  • code size in lines: is a relative and simple measurement as to the complexity of the program and helps us to understand how maintainable the code will be, as well as reducing issues in debugging. Simplistically speaking, the higher the number of lines, the worse everything becomes.
  • program size in bytes: describes how much Flash will be required on the microcontroller. This tends to be the least important issue, as Flash capacity tends to be much larger than RAM.
  • data size in bytes: describes the minimum amount of RAM required for the program. This is the most critical issue for two reasons, first, as a finite limit, the program will fail if it exceeds the RAM on the microcontroller and second, as the amount of RAM consumed becomes near the RAM limit, it introduces run-time bugs as the stack might get corrupted. [Note: The data size doesn’t include RAM requirements for the stack, as stack requirements aren’t readily discernible. For a little bit more information as to RAM and the stack see this.]

Example

I’ll use a simple example to make the point. The example will demonstrate the engineering analysis (hardware costs vs software development) to make the point, however, I wouldn’t use this specific example as a well thought out solution. (Ed. Note: Using a microcontroller for 9 LEDs is overkill.)

In the structs entry) I discussed how to write a program which ultimately drove 6 LEDs to blink. Blinking LEDs by themselves aren’t interesting, however the concept of a Persistence of Vision (POV) is. Moving LEDs or any light source rapidly through space can create a POV. The more LEDs, the more interesting the display can become. In our case, we’re going to assume a device which uses 9 LEDs to create a 9 LED POV.

9 LED POV

I was able to plug-in 8 LEDs and use the built-in LED for a total of 9 for our simple POV display. I added the lines required to drive all 9 LEDs and ended up with the following from a size requirement:

# Code size: 49 lines
avr-size -C --mcu=atmega328p main.elf
AVR Memory Usage
----------------
Device: atmega328p

Program:    1458 bytes (4.4% Full)
(.text + .data + .bootloader)

Data:         73 bytes (3.6% Full)
(.data + .bss + .noinit)

Clearly, the Uno had no issue with these requirements so let’s start a cost analysis using the 328P chip, which is the microcontroller the Uno uses. Our hardware requirements list is the following:

  • 9 Output lines
  • 2K bytes of Flash (1458 bytes rounded up)
  • 128 bytes of RAM (73 bytes rounded up)
  • Dual-Inline-Package (DIP) so we can wire it up ourselves

Lada Ada of Adafruit performs an in-depth search of Digikey for a specific part on a weekly basis. I highly recommend you watch what she does, as it is very helpful in understanding how to search for specific parts.

I’ll perform a similar search starting with the Uno chip:

ATMEGA328P-PU

  • 23 Output lines
  • 32K bytes of Flash
  • 2K bytes of RAM
  • Dual-Inline-Package (DIP)
  • $2.83 each

Note: I’m not going to be concerned with out-of-stock parts (which the 328P-PU is).

I’ve got two thoughts, clearly the 328P would work, however it has far more of everything than what I need, so I believe I can keep looking and lower my costs.

Let’s go to the cheapest AVR microcontroller and see what it offers:

ATTINY13A-PU

  • 6 Output lines
  • 1K bytes of Flash
  • 64 bytes of RAM
  • Dual-Inline-Package (DIP)
  • $1.22 each

I love the price! However, this specific chip won’t work for the other 3 requirements, I/O lines, Flash memory and RAM are all insufficient.

Since I’m able to narrow my search my specific parameters, I’ll narrow the results to chips which have at least 128 bytes of RAM, which is a critical parameter.

ATTINY44A-PU

  • 12 Output lines
  • 4K bytes of Flash
  • 256 bytes of RAM
  • Dual-Inline-Package (DIP)
  • $1.66 each

Perfect! This chip isn’t considerably more than my least expensive and saves my over 40% from the Uno chip.

Parts considered

Chip I/O Lines Flash RAM Price
ATMEGA328P-PU 23 32K 2K $2.83
ATTINY44A-PU 12 4K 256 $1.66
ATTINY13A-PU 6 1K 64 $1.22

Conclusion

So what is the point of this exercise? Practicing engineering. Engineering is the science and art of designing a product which meets multiple criteria such as, development costs, production costs, maintenance costs, marketing requirements etc. Software development is only one aspect of meeting such criteria, and its important to understand the role software development plays in the trade-offs between software and hardware, maintaining the code vs. debugging the code, product feature sets etc. As an engineer, think of learning software development as you would learning how to use a shovel. Learning to program means you know how to dig holes.

One additional point will be marketing requirements. As you have probably seen with any device, there is a always a desire to introduce a new one with increased features. With the microcontroller being a significant percentage of the bill of materials (a list of elements required to make a device), marketing will want to know how many additional LED’s could be powered:

  • based on I/O pins: 3 LEDs
  • based on Flash: not a forseeable issue
  • based on RAM: required RAM is 73 + 24 bytes/stack = 100, 6 bytes/LED out of remaining 156 bytes, at least 20 more LEDs

Comments powered by Talkyard.