Arduino Leonardo and SD or MicroSD Cards

As a follow up to my Ethernet post, here are some notes for using the SD library for card access with Leonardo and other ATMEGA32U4 boards using Arduino 1.0.1 (Leonardo Bootloader and 1.0.1 IDE).

Unlike the Ethernet library, the SD library (which builds from the sdfatlib) handles the AVR SPI all on it’s own. The Ethernet library uses SPI library under the hood which sets up the micro controller pins for the SPI bus to work. When SD starts up it attempts to set up the pins as needed. The pins SPI are defined as 0 (SS), 1 (SCK), 2 (MOSI), 3 (MISO), I suspect this is in support of Teensyduino. However, these pins don’t translate to the correct pins when using the Arduino 1.0.1 IDE.

The pin definitions are used for initial pin direction (input/output) and software SPI. Software SPI is barely worth mentioning here. Using software SPI requires modification of the library files and intended for Arduino MEGA boards. Since the pin direction is set using pinMode the SPI interface doesn’t work because the pin directions aren’t set on the SPI pins, but if the pins are setup first the SD library works just fine.

If you’re using SPI for something besides SD (like Ethernet) you can start those devices first and the SD library will just work.

If you want to start the SD library before other SPI devices or only want to use the SD library you need to put two lines of code (highlighted in a sample below) before SD.begin. These lines setup the SCK and MOSI pins for output. Normally you would need to set the hardware SS pin to output as well, but this is taken care of by the Arduino code handling the USB serial port because this pins is used for a LED on Leonardo boards. The MISO pin needs to be set as an input pin, but the input direction is the power on default for pins.

pinMode(SCK, OUTPUT);
pinMode(MOSI, OUTPUT);

Serial.print("Initializing SD card...");
if (!SD.begin(4)) {
  Serial.println("failed.");
  while(1);                // stay here forever
}
Serial.println("succeeded.");

Arduino Leonardo and Ethernet with 1.0.1

Want to use Ethernet on a Leonardo board? Me too, and I started playing with it in Arduino 1.0. I was succeeding too. Then Arduino 1.0.1 was released and I noticed a few things.

Remember how the recent Ethernet Shield started using the ICSP header for access to the SPI interface? On the product page it seems like they did it for the MEGA board which uses pin 50, 51, 52 instead of 11, 12, and 13 for the SPI bus. Turns out it’s handy for the Leonardo board which doesn’t expose the hardware SPI pins through the regular pins on board. In fact, the hardware SS pin is used for the RX LED on a Leonardo.

I wired up a Wiznet module to the SPI bus on an ATMEGA32U4 breakout board and since I used the hardware SS pin just like a normal ATMEGA328 Arduino it worked great with 1.0 and then 1.0.1 released and nothing. I thought the library was broken and I started telling everyone I could. I tore into the library and saw the SS pin handling changed to use PORTB6. I thought that was dumb and was about to change it. I started looking at the schematic for the Ethernet Shield and the pin mapping of the Leonardo board instead. I realized the shield would connect SS to pin 10, and pin 10 on a Leonardo is PORTB6 which is not the hardware SS pin. (PORTB4 is used on MEGAs and PORTB2/SS on UNO and older ATMEGAx28 boards.)

I quickly rewired my module and found success.

If you’re lucky enough to have a new Arduino Leonardo already and want to add Ethernet be sure your shield or module grabs the SPI bus from ICSP header. This is also an issue for SD/MicroSD card access…but that’ll be another post.

Printing Ethernet Interface Settings…the easy way

Just a quick little library for printing the current settings of the Ethernet interface on Arduino.

Be sure to check the examples. You can print to Serial or any stream you choose. If you’re printing to your own stream you might not want labels, and there’s an option for that too.

The library can be found on GitHub here: https://github.com/blackcatm/PrintIF

Sample Output:

Attempting to start Ethernet.
Ethernet address: 00:aa:bb:cc:de:02
      IP address: 192.168.0.101
     Subnet mask: 255.255.255.0
 Gateway address: 192.168.0.1
      DNS server: 192.168.0.1

Because You Can, Maybe You Shouldn’t

74595 Matrix Display


Adafruit added some neat little multi-digit 7-segment displays and I wanted to play. I picked up a yellow and red .39″ displays and a green .56″ display. I noticed the small ones even have the mitered ends on the segment, something that looked missing on the ebay displays getting down towards this size.

I’ve built a couple displays for clocks using individual 7-segment displays and for each digit I used a 74595 shift register. This is a lot of resistors and shift registers, but a simple design. I was wondering if I could use a series of shift registers to drive the multi-digit matrix. Since the 74595 has a high-Z output when not displaying (pull the OE high) I figured I’d give it a try.

Normally a micro controller is used to do the scanning on a timer interrupt or some similar mechanism. If you only used the micro controller and no shift register you would eat up 12 pins and not even control the colon or upper mark between digits 3 and 4 on his display. Commonly you see people using the 74595 to drive the segments and then the common cathode or anode through some transistors off the micro controller pins. I figured if I could provide my own timing the 74595s would make using this display just like my other displays.

Now I didn’t use transistors for my digit commons so I might have left some brightness on the table but that’s okay. I wasn’t going for bright. I wanted to make this display work like it wasn’t a matrix. I used 4 74575 shift registers in a chain with all the outputs paralleled and driving the segments through 1k resistors. The output enable (OE) line of each 74595 is tied to the common cathodes (CC) for each display and the CC and OE lines are connected through inverters provided by a 7414 (hex inverter) to a 4017 decade counter/divider which I’ve configured to sequence through 4 outputs only. As a clock source I’d use two of the schmidt-trigger inverters of the 7414 with either a crystal or RC, timing isn’t important, just fast so it doesn’t flicker.

I couldn’t locate a suitable resistor and capacitor on my desk and instead just grabbed a DS32KHZ 32.768k oscillator. This gives me an ~8khz update speed which is not at all noticeable. This entire circuit ends up quite large and uses 7 chips and still can’t control the extra LEDs. The upshot is the micro controller can talk with 4 signals (serial data, data clock, latch clock, and reset). I tie the reset low so the display comes up blank then let the micro controller pull it high when it starts displaying.

It was a fun exercise, but it’s hard to recommend unless you’re just experimenting. I could dedicate a micro controller just for the display with a lower component count and similar BOM cost. Even with surface mount components the components would take twice the space of the display.

Extended EEPROM Library for Arduino

The first post here on was an article including some code to print the EEPROM contents in a hex dump on an Arduino to the serial port.

I’ve now built that functionality into a library to replace the EEPROM library. You can now sent the hex dump to any stream (software serial, second hardware serial, etc).

Another handy feature is a set method which works similar to memset. If you need to clear a number of bytes, or set them to a single value this function keeps you from having to implement yourself, and it has some simple bounds checking in case you forget.

The library can be found on GitHub here: E2PROM

Be sure to check out the examples for some usage details.

Arduino Ethernet MAC Address Storage Library

Ethernet interfaces must have a unique hardware address to communicate on the local network. When using a Wiznet based Ethernet connection (either bare module, shield or integrated board) as part of the hardware initialization you must provide the hardware address, or MAC (Media Access Control) address.

MAC addresses are 48-bits, most commonly represented as 6 bytes displayed in hexadecimal. Newer Arduino Ethernet Shields and Arduino Ethernet boards ship with a MAC address on a sticker. Easy for you to read, hard for your program to read. If you have multiple boards you wish to deploy the same software on you’ll want a way to keep the code portable between your boards.

While you could just change the address in code, that requires individual configuration and recompiling for each board. Instead, much like other configuration or user preferences you ought to consider storing the MAC address in nonvolatile memory.

The AVR chips the Arduino is based on has a limited amount of EEPROM memory (512 bytes on atmega168, 1k on atmega328 and even more on the atmega1280 and atmega2560 chips). By storing the address in EEPROM and reading the address before initializing the Ethernet interface you can minimize errors later if you need to change software. Best of all, during normal flash programming the EEPROM is left intact so you can change your program but retain the MAC address (and any other configuration you might store).

I have written a library for Arduino which lets you store and retrieve a MAC address in EEPROM. I choose to store the address in the last 8 bytes of EEPROM memory. For data integrity the value is stored with two checksum bytes. During retrieval the checksum is calculated on read and compared with the stored values and an error case returned if there are any mismatches. During storage the MAC address is written with checksums calculated and before signaling success the MAC address is reread and checked against the checksums.

The library can be found on GitHub here: EtherMac

Please see the included examples for usage.

You can read more about MAC addresses on Wikipedia.
Learn more about Arduino Ethernet.

Dumping EEPROM in Arduino

If you’re debugging your EEPROM enabled Arduino project you might wish you could see into the EEPROM to understand what’s going on.

If you have an in-circuit programmer such as the Adafruit USBtinyISP you can always use avrdude to dump the EEPROM to a file. For example the following code creates a file named e2data.ee with contents of the EEPROM.

$ avrdude -p m328p -c usbtiny -P usb -U eeprom:r:e2data.ee:r

Check the avrdude man page for details.

However, if you don’t have a programer or don’t want to get it out it’s simple enough to read the data from within your Arduino sketch. Use this function modeled after classic hex editors from the days of DOS to dump the contents of EEPROM to your already opened serial port. The entire contents are dumped no matter the AVR chip on board.

#include <EEPROM.h>

void setup(){
  Serial.begin(57600);

  e2reader();
}

void loop(){
}

void e2reader(){
  char buffer[16];
  char valuePrint[4];
  byte value;
  unsigned int address;
  uint8_t trailingSpace = 2;

  Serial.print("Dumping "); Serial.print(E2END + 1);
  Serial.println(" bytes from EEPROM.");
  Serial.print("baseAddr ");
  for(int x = 0; x < 2; x++){
    Serial.print(" ");
    for(int y = 0; y < 25; y++)
      Serial.print("=");
  }

  // E2END is a macro defined as the last EEPROM address
  // (1023 for ATMEGA328P)
  for(address = 0; address <= E2END; address++){
    // read a byte from the current address of the EEPROM
    value = EEPROM.read(address);

    // add space between two sets of 8 bytes
    if(address % 8 == 0)
      Serial.print("  ");

    // newline and address for every 16 bytes
    if(address % 16 == 0){
      //print the buffer
      if(address > 0 && address % 16 == 0)
        printASCII(buffer);

      sprintf(buffer, "\n 0x%05X: ", address);
      Serial.print(buffer);

      //clear the buffer for the next data block
      memset (buffer, 32, 16);
    }

    // save the value in temporary storage
    buffer[address%16] = value;

    // print the formatted value
    sprintf(valuePrint, " %02X", value);
    Serial.print(valuePrint);
  }

  if(address % 16 > 0){
    if(address % 16 < 9)
      trailingSpace += 2;

    trailingSpace += (16 - address % 16) * 3;
  }

  for(int i = trailingSpace; i > 0; i--)
    Serial.print(" ");

  //last line of data and a new line
  printASCII(buffer);
  Serial.println();
}

void printASCII(char * buffer){
  for(int i = 0; i < 16; i++){
    if(i == 8)
      Serial.print(" ");

    if(buffer[i] > 31 and buffer[i] < 127){
      Serial.print(buffer[i]);
    }else{
      Serial.print(".");
    }
  }
}

Here’s a snippet of the output:

Dumping 1024 bytes from EEPROM.
baseAddr  ========================= =========================
 0x00000:  FF FF FF FF FF FF FF FF   FF FF FF FF FF FF FF FF  ........ ........
 0x00010:  FF FF FF FF FF FF FF FF   FF FF FF FF FF FF FF FF  ........ ........
 0x00020:  FF FF FF FF FF FF FF FF   FF FF FF FF FF FF FF FF  ........ ........
.
.
.
 0x003E0:  FF FF FF FF FF FF FF FF   FF FF FF FF FF FF FF FF  ........ ........
 0x003F0:  FF FF FF FF FF FF FF FF   FF FF FF FF FF FF FF FF  ........ ........