Fighting Arduino for Timer0

Hey folks,  Crow here.  This issue has probably been raised and solved many times prior to my experience with it, but I will make a note of it here for anyone similar in coding practices to the way I do things.  I am not really a C programmer.  I am an assembly language programmer, from the olden days of the COSMAC CDP1802 (“Olduino” — it was CMOS and would run on a 9V battery in 1976!)  through the Zilog Z8 and Z80 and finally things like the MC68000.  Then I discovered PICs, and learning that MCU’s strange little instruction set taught me some things are sort of meant to have their code built from a compiler, which brings me to the AVR parts.

My single-board Crowminius instrument has a MIDICV circuit that uses an ATMEGA328P along with a pair of MCP4822 DAC chips to provide the control voltages and gates to operate the analog synthesizer.  Also buried in the code is a direct-digital synthesis PWM sine wave generator programmed to provide a single tone at 440.00Hz as a tuning reference.  Since the Crowminius Euro module set I am designing will not have a built-in  MIDICV circuit, the local 440Hz reference would need its own dedicated microcontroller.  Using an Adafruit Trinket with its ATTINY85 MCU, I chopped the code down to just that needed for the tone generator.  The ATTINY85 has one 8-bit timer, “Timer 0,”  as opposed the the 328P’s Timer 0 and Timer 2.  (Timer 1 in both parts is a 16-bit unit). I had been using Timer 2 in the ATMEGA328P for the DDS phase accumulator interrupt routine, which is unclaimed by the Arduino toolkit.

Except I wanted to use Timer 0 on the ATTINY85, which led to a compile-time issue.  Timer 0 is reserved by the Arduino environment for use in the delay() and millis() functions.  If I try to declare my own timer 0 interrupt header ISR(TIMER0_OVF_VECT)  Everything seems to compile fine until the core module linker later starts complaining:

core.a(wiring.c.o): In function `__vector_5′:
C:\Users\Crow\Arduino\arduino-1.0.5\hardware\arduino\cores\arduino/wiring.c:49: multiple definition of `__vector_5′

Duplicate vector?  “__vector__5” is not exactly descriptive but I only declared the one interrupt vector so some kind of black magic was being invoked during the compile.  This starts getting into why I never warmed up much to C: too many files to keep track of, particularly when one is not used to ‘just knowing’ where stuff tends to be located.  At least the compiler tells me where to look, line 49 of this ‘wiring.c’ file buried several layers into the directory tree in which a Timer0 ISR is declared for the delay stuff and which explains the multiple definition error.  Now if I were writing the compiler, my pre-processor would allow the option to just pick the first declaration and ignore any subsequent ones, not just error out on the fact more than one exists.  I get that sometimes this is needed, but as I said I would at least have the option.

I still wanted to use Timer0, so I decided to make the code as generic as possible with no hooks into non-AVR files.  It turns out if I do not use the setup() or loop() statements and instead just declare main(), avr-gcc compiles the code without linking to things like wiring.c.o.  Of course this means all the handy function calls the Arduino IDE offers are off the table, but I am just wanting to generate a PWM sine wave and do not need much beyond basic K&R C and a couple of AVR’s library functions to use a data table stored in the program flash area.

This may all seem obvious to a veteran embedded C programmer, but for folks like me who live “close to the hardware” it is always a learning experience.  I’ve since googled further about the issue and learned others also ditched setup() & loop() for main(), have modified alternate versions of wiring.c and implemented things like vector list pointers.  That last one is somewhat like interrupt server chaining I did 25 years ago on the Amiga in 68000 assembly, but interrupt service chaining is a bit highbrow for a program that just generates a single 440.00Hz PWM sine tone.  The code snippet below shows the important parts.  I’ll post the code for anyone who cares once I test it on the actual circuit it is meant for.






bGrab is just a #define  bGrab  pgm_read_byte_near as too many variables and functions seem to have_names_as_long_as_my_forearm.


Adafruit publishes a wide range of writing and video content, including interviews and reporting on the maker market and the wider technology world. Our standards page is intended as a guide to best practices that Adafruit uses, as well as an outline of the ethical standards Adafruit aspires to. While Adafruit is not an independent journalistic institution, Adafruit strives to be a fair, informative, and positive voice within the community – check it out here:

Join Adafruit on Mastodon

Adafruit is on Mastodon, join in!

Stop breadboarding and soldering – start making immediately! Adafruit’s Circuit Playground is jam-packed with LEDs, sensors, buttons, alligator clip pads and more. Build projects with Circuit Playground in a few minutes with the drag-and-drop MakeCode programming site, learn computer science using the CS Discoveries class on, jump into CircuitPython to learn Python and hardware together, TinyGO, or even use the Arduino IDE. Circuit Playground Express is the newest and best Circuit Playground board, with support for CircuitPython, MakeCode, and Arduino. It has a powerful processor, 10 NeoPixels, mini speaker, InfraRed receive and transmit, two buttons, a switch, 14 alligator clip pads, and lots of sensors: capacitive touch, IR proximity, temperature, light, motion and sound. A whole wide world of electronics and coding is waiting for you, and it fits in the palm of your hand.

Have an amazing project to share? The Electronics Show and Tell is every Wednesday at 7pm ET! To join, head over to YouTube and check out the show’s live chat – we’ll post the link there.

Join us every Wednesday night at 8pm ET for Ask an Engineer!

Join over 36,000+ makers on Adafruit’s Discord channels and be part of the community!

CircuitPython – The easiest way to program microcontrollers –

Maker Business — “Packaging” chips in the US

Wearables — Enclosures help fight body humidity in costumes

Electronics — Transformers: More than meets the eye!

Python for Microcontrollers — Python on Microcontrollers Newsletter: Silicon Labs introduces CircuitPython support, and more! #CircuitPython #Python #micropython @ThePSF @Raspberry_Pi

Adafruit IoT Monthly — Guardian Robot, Weather-wise Umbrella Stand, and more!

Microsoft MakeCode — MakeCode Thank You!

EYE on NPI — Maxim’s Himalaya uSLIC Step-Down Power Module #EyeOnNPI @maximintegrated @digikey

New Products – Adafruit Industries – Makers, hackers, artists, designers and engineers! — #NewProds 7/19/23 Feat. Adafruit Matrix Portal S3 CircuitPython Powered Internet Display!

Get the only spam-free daily newsletter about wearables, running a "maker business", electronic tips and more! Subscribe at !

No Comments

No comments yet.

Sorry, the comment form is closed at this time.