First steps towards using avr-gcc without the IDE

Being someone who knows C, and didn’t have too much interest in writing non-C code, I set out to use my Arduino sans the IDE, with just avr-gcc and avrdude.

Turns out this had a bit of screwing around to it, but I’ve got it working on Debian Lenny with a Duemilanova.

I included instructions that are hopefully complete for any Debian user and will hopefully save someone else the screw around of putting together all the puzzle pieces just to make a light blink! browse download

It looks like you are not only bypassing the IDE, but all the Arduino software. Are you using the core runtime code or are you not interested in using any of the libraries and application code?

Just looked at your blink.c code. Are you sure that this:

while (1) {
_delay_ms(500); // actually ends up with a ~1sec delay, not important.
PINB = 0b00100000; // toggles state, so to high if low, or to low if high

actually toggles the pin? I thought PINB was what you read when you want to use PORTB as an input?


mem: At the moment not interested, but I'll probably pull in libraries when I need them.

Andrew: You are right you can use PINB to read. But you can also use it to toggle the values of PORTB.

The libraries tend to use the core functions so you will also need to pull them in as well. Other than not having a main, what would you lose if you just replaced the IDE with your editor of choice and keep the arduino core.

Perhaps I am missing something but it looks like you are throwing the baby out with the bathwater.

I think he is facing the issue that it is not that trivial if you are not used to C to actually get the libraries properly included. And then maybe he just does not like the libraries. I have somewhat mixed feelings with them.

Pro: Great for prototyping and get something going

Con: Like any library, once you have specific needs and want more you have to decide to roll your own or to patch the existing stuff.

Pro: If you deal with the libraries you can contribute.

Con: If you even have the faintest plan on commercializing your code you have to deal with the licences.

Having said that, here are my small contribution to working without the IDE:

You may want a convenient commandline substitute for the monitoring functionality. I messed a little bit with putty but now I find the following short script more convenient for my purposes. Of course it can only read, but that's what I need currently. It's main advantage is that it is ultra simple and can be adapted easily to anything I need.

# -*- coding: utf-8 -*-

import serial
import sys

if len(sys.argv) != 3:
    print "Please specify a port and a baudrate, e.g. %s /dev/ttyUSB0 19200" % sys.argv[0]

ser = serial.Serial(sys.argv[1], sys.argv[2])

while 1:

To make my comment on the library functions more specific. The digitalWrite function is great because it abstracts a lot from the hardware. From an architectural point of view it is perfect. However if you are low on memory they are one of the first things to go down the drain (right after the buffer for serial communication and the boot loader). Today I removed all digital writes from my code and substituted them for low level statements --> ~1 kBytes of memory reclaimed.

Cheers, Udo

P.S. I already have some 328 around. But I just want to pack my code into the 168.

Today I removed all digital writes from my code and substituted them for low level statements --> ~1 kBytes of memory reclaimed

The blink sketch that is the example for DigitalWrite uses 896 bytes of flash, Removing the digitalWrites saves 174 bytes. Tested with version 0017, what version are you using?

Hi Mem,

I am using 0017. However it was not this example I was talking about. I was talking about a larger project. With the example I would stick to the standard library. My project is running short of flash memory, hence I decided to switch to tighter code. The digitalWrite stuff uses more than its faire share. I thought this was obvious after my statement that I have send the serial buffer down the drain as well. And once I get the ISP properly running the bootloader will follow. Unfortunately the ISP is still black magic for me.

Cheers, Udo

Hi Udo,

I am not sure I understand. It sounds like that you are abandoning all the runtime code in order to save something under 1k bytes.
If that is the case then the downside is that you would need significantly greater effort to add the functionality to do things like read analog inputs or send data to an LCD or serial port (or access any Arduino library that uses the runtime).
Using your approach, how much effort would you need to duplicate these few lines of code:

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  lcd.begin(16, 2);

void loop() {
int val;
  val = analogRead(0);
  lcd.print(millis()/1000);   // display  the number of seconds since reset:
  lcd.print(val);   // display a value
    Serial.print(val); // send the value to the serial port 

An ATmega168 has almost 12k of code free after loading that sketch.