Serial Communication: A “Don Quichotte” story !

Serial communication with Arduino :

The ATmega328p shipped with Arduino can do a lot of interesting things, including communication over several different protocols: SPI, I2E, and “classical” serial communication.

The serial communication is very useful as it allow us to send data to the host computer “easily” mainly for debugging purposes. Has i don’t know for the moment if a “real” debugger like GDB will operate withArduino, i will rely on simple “printf like” function to debug my code. That’s why Serial communication is pretty important.

Serial communication is provided by the ATmega328p used on Arduino Uno board. Arduino provide us facilities to use it, and among those facilities, there is the:

Serial over USB !!

This was the first point in this project where i get stuck for several hours trying to understand why things where not working as i except, i finally solve the problem, which one, like most of the time in programming, much more simpler then i thought !

In order for me to remember and for you to laugh at me here is the story :

Fighting against Windmill:

Because my development computer, a Raspberry pi, does not have any serial port, i need to use the usb port connected to the Arduino to communicate with it.

On the Arduino uno revision 3 this feature is provided by a small chip soldered on the board and connected to the ATmega328p. This chip, an ATmega8u2 (an other avr chip by atmel) is responsible of routing all the serial data going out of the main ATmega328p to the usb port of the arduino in the appropriate format.

When the arduino is connected to the Raspberry pi, a new tty is detected by the linux kernel:
/dev/ttyACM0
It’s through this tty that you can read what the arduino send.

This sound pretty straight forward, but after uploading my first program to the Arduino, i did not receive any serial data on this tty…

At first i tough it was coming from a problem in my build options, or maybe from a wrong version of the Avr-Libc… so i spend several hours reading stuff about how the USB over serial was working until i realize something by looking at a typical sketch created using the Arduino IDE.

Roughly, when you write a sketch in Arduino IDE, you need to write only two function: Init() and Loop(). Those functions are then called by the code provided in the main.cpp file:

#include <Arduino.h>

int main(void)
{
        init();
 
#if defined(USBCON)
        USBDevice.attach();
#endif
        
        setup();
    
        for (;;) {
                loop();
                if (serialEventRun) serialEventRun();
        }
        
        return 0;
}

What is miss in my own program was the call to init(), which in defined in wiring.c. This function initialize some serial communication related stuff, and, as the comment in the code specifies:

“// this needs to be called before setup() or some functions won’t
// work there”

So after adding a call to init() in my own code, i was able to send and receive data over USB and start debugging my application ! Great !

Advertisements

Building Arduino Libraries

Among all the good things in the Arduino platform, is the huge amount of libraries. They either come from the standard Arduino distribution or from third party developer. And what’s even better is that they are all written in C++ ! Here is a list of some of the library i’m planning to use for this project:

  • Arduino distrib’s library :
    • Core Library:
      • Hardware serial communication library
    • Additional Library:
      • SPI library (SPI is a communication protocol used to connect chips or other devices to the Arduino)
  • Third party distrib:
    • SPI Ram library (i will probably need it to use the 23k256 chips from microchip that provide 256k bit of additional SRAM)
    • MIDI library used to receive and send MIDI data thru the MIDI shield

I will probably use other one, but for now these are the only one which sound really useful …

Compiling Arduino Core library:

So as Arduino is an OpenSource project, all the source code are freely available. You can get them here:  https://github.com/arduino/Arduino/tree/master/hardware/arduino/cores/arduino In order to understand how to compile them, i have used mainly two sources of informations:

  • The Arduino web page explaining how to setup eclipse IDE to compile Arduino code (This article include a paragraph about how to compile Arduino Core Library)
  • The output of the Arduino IDE ( Check File->Preferences->Show verbose output during: compilation / upload )

After several tests, here are the GCC options i’m using for compiling the Core Library (and all the other one in fact !):

  • Compiling C Code:
    • -c : Do not invoke linker after compilation
    • -g : Generate debug informations
    • -Os: Optimize code to reduce it’s size
    • -Wall:  Enable all warning
    • -ffunction-sections : Place  functions item into its own section in the output file
    • -fdata-sections : Place  data items into its own section in the output file
    • -mmcu=atmega328p: Select the right type of AVR to use
    • -DF_CPU=16000000L: Specify the clock frequency of the AVH in hertz
    • -MMD: ???
    • -DUSB_VID=null: ???
    • -DUSB_PID=null: ???
    • -DARDUINO=105: Version of the Arduino libs
  • Compiling C++ Code:
    • All the previous one plus:
    • -fno-exceptions: Disable C++ exception support which are not supported by Arduino (And probably the underlying AVR hardware…)

Hate MakeFile, love CMake :

As i’m working under a Linux environment (Raspian on Raspberry Pi), i need some kind of MakeFile to drive the build process. I’m not a fan of this kind of file so i decided to go and use CMake to generate them for me! CMake is a great tool that allow you to write all your program/library specification using a simple language and which convert this specifications into a very complete Makefile or even a Project for the Microsoft Compiler !

Here is the Specification file i use to build the ArduinoCore Library:

Compiling others library:

Others libraries, including Arduino additional libraries and third party libraries are build the exact same way. So actually i’m building 4 library:

  • Arduino Core
  • Arduino SPI
  • Arduino SPI RAM
  • Arduino MIDI

Here is a link to the git hub project that host all of those library with the appropriate CMakeLists.txt (CMake specification file).

https://github.com/ClementVidal/ArduinoLib

As always: Feel free to use it !

The programming Toolchain

Re-invent the wheel !

Most of the time, when i develop something for a personal project, i really like to start from scratch…It’s not about being a Linux or a command line extremist, it’s just that it allow me to really understand clearly what i’m doing.

This is one of the reason that drive my choice of not using the Arduino Integrated development environment. The other reason is that i want to program the entire project in C/C++ (which is my favorite language ) and that the Arduino IDE allow me to program in a “simplified” language which is not true C/C++.

Obviously, i made this choice after investigating what was feasible according to the basic tools available… Those research lead me to the following observation:

  • The Arduino IDE translate it’s “simplified” source code into true C/C++ during the compilation phase.
  • The Arduino IDE compilation process is based upon GNU avr-gcc which is an open source implementation of the GNU compiler collection for the AVR platform.
  • All the facility library used by Arduino are written in pure C/C++

So everything is already here to build a standard toolchain that can compile C/C++ code, use existing library (to do serial communication or MIDI processing…), and upload the program to the Arduino without a lot of pain..

Tools used:

So to summarize everything, here is what i will use to develop the software side of the MIDILooper:

  • Host computer: Raspberry PI.
  • Host OS: Raspian, a derived version of Debian compiled for the ARM architecture of the Raspberry.
  • Source Control: Git (using remote repository hosted on GitHub).
  • CMake for creating makefile allowing me to build the ArduinoCore library plus the MIDILooper program itself.
  • The GNU avr-gcc toolchain for compiling, assembling and linking my code.

So now, next step is to setup those tools and compile the Arduino Core Library !