BE SMARTER! Make, play and learn with the Tinusaur microcontroller boards.

library

The MAX7219 controller is manufactured by Maxim Integrated is compact, serial input/output common-cathode display driver that could interface microcontrollers to 64 individual LEDs, 7-segment numeric LED displays of up to 8 digits, bar-graph displays, etc. Included on-chip are a BCD code-B decoder, multiplex scan circuitry, segment and digit drivers and an 8×8 static RAM that stores each digit.

The MAX7219 modules are very convenient to use with microcontrollers such as ATtiny85, or, in our case the Tinusaur Board.

The Hardware

The MAX7219 modules usually look like this:

MAX7219 Module and LED Matrix 8×8

They have an input bus on one side and output bus on the other. This allows you to daisy chain 2 or more modules, i.e. one after another, to create more complicated setups.

The modules that we are using are capable of connecting in a chain using 5 small jumpers. See the picture below.

2x MAX7219 Modules Connected

Pinout and Signals

MAX7219 module has 5 pins:

VCC – power (+)

GND – ground (-)

DIN – Data input

CS – Chip select

CLK – Clock

That means that we need 3 pins on the ATtiny85 microcontroller side to control the module. Those will be:

PB0 – connected to the CLK

PB1 – connected to the CS

PB2 – connected to the DIN

This is sufficient to connect to the MAX7219 module and program it.

The Protocol

Communicating with the MAX7219 is relatively easy – it uses a synchronous protocol which means that for every data bit we send there is a clock cycle that signifies the presence of that data bit.

MAX7219 Timing Diagram

In other words, we send 2 parallel sequences to bits – one for the clock and another for the data. This is what the software does.

The Software

The way this MAX7219 module works is this:

We write bytes to its internal register.

MAX7219 interprets the data.

MAX7219 controls the LEDs in the matrix.

That also means that we don’t have to circle through the array of LEDs all the time in order to light them up – the MAX7219 controller takes care of that. It could also manage the intensity of the LEDs.

So, to use the MAX7219 modules in a convenient way we need a library of functions to serve that purpose.

First, we need some basic functions in order to write to the MAX7219 registers.

It is important to note here the line where we bring the CS signal back to HIGH – this marks the end of the sequence – in this case, the end of the command. A similar technique is used when controlling more that one matrix connected in a chain.

Next step, before we start turning on and off the LEDs, is to initialize the MAX7219 controller. This is done by writing certain values to certain registers. For convenience, while coding it we could put the initialization sequence in an array.

It is important to note that this will work for 1 matrix only. If we connect more matrices in a chain they will all show the same data. The reason for this is that after sending the command we bring the CS signal back to HIGH which causes all the MAX7219 controllers in the chain to latch and show whatever the last command was.

Testing

This is a simple testing program that lights up a LED on the first row (r=1) on the right-most position, then moves that on the left until it reaches the left-most position, then does the same on one row up (r=2) )until it reaches the top (r=8).

The BMP180tiny Library

So, we wrote a simple library (called it BMP180tiny) that uses USITWIX to read and write from/to BMP180 registers, retrieve the measurements, do some additional calculations and produce result suitable for use in an application.

Setup

Here’s the setup:

NOTE: We need the USB-to-Serial just for debugging – it isn’t essential part of the setup.

As we know, there’s no I²C on ATtiny85, not even the TWI (Two Wire Interface, which is basically I2C with a different name) that some other Atmel chips have, so I had to write my own that takes advantage on the built-in USI unit. This library is called USITWIX and will be presented in this blog post.

Of course, I used other people’s work write mine and they’re references in the source code.

Using the USITWIX library

There is also a Variometer project that uses those libraries to produce audible measurements of the changes in the altitude by measuring the atmospheric pressure and taking into account the temperature. Such tools, or instruments, are often used by paragliders.

References

Here are some references to sources that I used while working on this project.

AVR312: Using the USI module as a I2C slavehttp://www.atmel.com/Images/doc2560.pdfC-code driver for TWI slave, with transmit and receive buffers; Compatible with I2C protocol; Interrupt driven, detection and transmission/reception; Wake up from all sleep mode, including Power Down.

ATTiny USI I2C Introduction – A powerful, fast, and convenient communication interface for your ATTiny projects!http://www.instructables.com/id/ATTiny-USI-I2C-The-detailed-in-depth-and-infor/I2C, it’s a standard that’s been around for around 20 years and has found uses in nearly every corner of the electronics universe. It’s an incredibly useful technology for us microcontroller hobbyists but can seem daunting for new users. This tutorial will solve that problem, first by reviewing what I2C is and how it works, then by going in-depth on how to implement I2C in Atmel’s ATTiny USI (Universal Serial Interface) hardware.

I2C Bus for ATtiny and ATmegahttp://www.instructables.com/id/I2C_Bus_for_ATtiny_and_ATmega/This two wire interface is formally known as the Inter-Integrated Circuit bus, or just the I2C bus and was invented by NXP when it was still Philips Semiconductors. If you’re reading this Instructable then you’ve probably heard of the I2C bus and may even have used it on a PIC or other microcontroller. While conceptually very simple, and supported by hardware resources on the AVRs, software drivers are still necessary to use the I2C bus. Atmel provides Application Notes (see the Resources later in this Instructable), but these are incomplete and don’t show any examples beyond communicating with another AVR device.

OWOWOD is One Wire / One Way Output for Debugging library. It allows you to output text from the Tinusaur (ATtiny85 microcontroller or other similar), though USB-to-Serial or TTL converter (based on PL2303, CH340G or similar) and to the computer screen using COM port monitoring tool.

Why one would need something like that?

I would’ve been nice if it was possible to write something li this …

debugging_print("working, x=%i", x);

… and see the output on a computer. Great for debugging and other things.

Unfortunately there is no easy way of doing that – in fact not possible with the standard tools used to work with the ATtiny85. The problem is this: (1) those micro-controllers have too few I/O ports; and (2) most of the programmers (ex.: USBasp) do not offer that kind of communication between the micro-controller and the computer, i.e. there is no 2-way communication.

There are some solution and the OWOWOD library is just one of them. It uses an additional hardware component – USB-to-Serial converter also known as USB TTL Converter. They are very inexpensive, easy to find and work with.

The OWOWOD Library could do that.

For this to work we need …

Micro-controller

USB-to-Serial converter

Computer

The Library works like this …

When you use a library function like owowod_print_char(‘U’) it will start sending sending the bits of the ‘U’ byte (hex: 0x55, bin: 01010101) in series, i.e. one bit after another, through one of the microcontroller pins – for instance PB3.

At the other end of the wire there is USB-to-Serial converter that will take the individual 01010101 bits and re-compose them back into one byte as 0x55.

Then the USB-to-Serial converter will send that ‘U’ byte (0x55) to the computer USB port.

The computer sees the USB-to-Serial as a Serial COM Port port, so it reads that ‘U’ byte.

Using another program on the computer we get that ‘U’ byte and show it on the screen.

DEBUGGING_VAR and DEBUGGING_VARU print variable name and then the value.

DEBUGGING_ERROR prints the error code then the message.

To see the results we need a program that will run on a computer and show on the screen the information that comes through the serial port. There are many programs that could do that. One particularly simple to use is the Hercules Setup utility by HW group – it is just one EXE file that you run – that’s it.

After playing for awhile with that SSD1306OLED display I decided to add few more things to the SSD1306xLED library and the ability to print numbers seamed to be an important one.

There is already a function in the library that outputs strings so I needed only the conversion from int to decimal string. So I used another function usint2decascii that I previously wrote for another project OWOWOD which code in turn I borrowed from a third project LCDDDD – a LCDDirect Drawing Driver for PCD8544 based displays such as Nokia 3310 LCD. The weird LCDDDD name comes from the fact that it outputs the data directly to the LCD instead of storing it into a buffer first and then periodically outputting it to the LCD – this is unlike most of the popular LCD drivers.

Here is the main function definition …

uint8_t usint2decascii(uint16_t num, char* buffer)

The function requires a small buffer to store the result. Since the largest number is 65535 – that is 0xFFFF in hex, 5+1 bytes are needed for that buffer.

For convenience there are 2 functions for direct printing of numbers. Below is their implementation – it’s very simple:

The MAX7219LED8x8 library uses now simple scheduler to automate the task of outputting the buffer to the LED 8×8 matrix. This is not like a real task scheduler (in a real operating system) but it uses the ATtiny85microcontroller‘s timer and its interrupt to do certain things on regular intervals.

So this is how I’ve got the idea …

While I was working on some code that uses the MAX7219LED8x8 library I figured out that the task of writing the content of the memory buffer to the MAX7219 could be automated by hooking some code to the ATtiny85 timer.

The modification and additions could be broken down into 2 parts:

First, the scheduling part that initializes the ATtiny85 timer, starts it and handles the hardware interrupt.

Second, the MAX7219LED8x8 library functions for setting/clearing pixels and outputting the buffer that now should work with the scheduler.