A max7456 library for Arduino

It's been a while since we published the last article.. Well we've been pretty busy those days but as a gift in this article I'll present you some of our lattest work : A library for the well known max7456 chip by Maxim.

As famous as it is, a little reminder won't be too much. max7456 is basically used to insert customized information in a given analogic video stream. This manip is called "OSD" (for On-Screen Display). A little picture to explain it :

explainationOSD

We recently bought a wireless video system in order to do FPV (First Person Flying, you only look on a video send by a camera installed on the drone/plane). And the problem is that it's quite hard to pilot this way without additional informations about the flight. So we decided to make our own OSD system.

We decided to make a library for the max7456 because we didn't found one that fitted our needs. This library is pretty simple to use and comes with a complete documentation and example programs. This has been used with a PAL system, but the differences with NTSC are not really big (you have to init it an other way, refer to the datasheed of max7456 if you need to).

Here is the Hello World ! code :

#include "SPI.h"
#include "max7456.h"

Max7456 osd;

void setup()
{
  SPI.begin(); //to be called before osd.init
  osd.init(10); //CS on port 10
  osd.setDisplayOffsets(60,18);
  osd.setBlinkParams(_8fields, _BT_BT);

  osd.activateOSD();
  osd.print("Hello world : )",1,3);
}

void loop()
{
}

In order to make easier the process of entering new characters in the NVM (non-volatile memory) of the OSD, I made an program used to transform a bmp picture representing the OSD characters table into a single array you can use with the library (there is an example that shows the use of this array). Just lauch the executable with the options :

convertOSD.exe -i ".bmp picture" -head ".h containing array"

The bmp picture looks like this :

tableOSD

This represents the 256 characters to be insered into the NVM. So here's the deal : when you want to put your customized characters table into the NVM, you must write on a register in the max7456. The values to write on this special register are directly related to the character. To be quick, each pixel of a character is 2-bits coded, and the character is 12x18 pixels you'll need 54 bytes of data. There are 256 characters in the table so the array returned by the program is 13824 bytes long (approx. 13.5k) . This is much more than the Arduino's flash memory can handle (2k). But the program memory is sufficient to store such an array. Then we used a little trick to program the max7456 in one single operation : we simple store the array in the program memory with the instruction :

const prog_uchar tableOfAllCharacters[13824] PROGMEM = {0x55,0x55,0x55,0 // ....

Nothing really hard here : character at address 0x00  is represented by the 54 first bytes, character at address i is represented by the (54*i) next 54 characters. Note that all the 0xFF value has been replaced by "0x55". This is because af a tricky bug in the Arduino bootloader that causes the Arduino to be corrupted if too many 0xFF are sent on a row to the program memory. Therefore, this is the method to get the character i in the table "table" (we fill a special type "charact" which is in fact a 54 bytes array.


//-----------------------------------------------------------------------------
// Implements Max7456::getCARACFromProgMem
//-----------------------------------------------------------------------------
void Max7456::getCARACFromProgMem(const prog_uchar *table, byte i, charact car)
{
	unsigned long index;
	byte read;
	index = i*54;
	for(unsigned long j = 0 ; j < 54 ; j++)
	{
		read = pgm_read_byte_near(table +index+j );
		car[j] = read;
		if (car[j] == 0x55)
			car[j] = 0xff;
	}
}

Note that we experienced problems with the sparkfun max7456 package. This was caused by a chip overheat dued to insuficient copper pad under it. We solved the problem by adding a tiny RAM heat dissipator on it.

Ok, most important part now : the sources !

Character array generator

Max7456 Library

Share to Google Plus

38 thoughts on “A max7456 library for Arduino”

  1. hi

    sorry for this email, but i really need your help

    i have read your article about max7456 here: http://theboredengineers.com/2012/12/a-max7456-library-for-arduino/

    i have a lot of problem, i have spent 2 days around it but it still not works.

    i really dont know why it doesnt works, this is the wiring that i have used: http://localhostr.com/files/xFMs77Z/Uno and Max7456 C.jpg
    this is a sketch that i have flashed: http://pastebin.com/aXieBpbM

    but i dont see nothing on my display (pal tv color "mivar 16 p2").
    i see only the image from a little cam that i have attached but no osd.

    how can you help me?

    regards

    1. Hi trisonic,

      I checked your sketch and it seems OK.
      Your wiring seems good too, but you should try to tie LOS, HSYNC and VSYNC output to 5V with a 5K ou 10k resistor (same as RST). We had numerous problems caused by floating outputs.

      Is the display easily disturbed (when you move it a little with your finger for instance) ?

      Your max7456 seems OK too since the background is displayed.
      Is it warm ? We had to add a heat sinker because after a few seconds the display disappeared.

      1. thanks for your reply!

        i have wired it as you have wrote, i have used some trimpots adjusted at 7k... but nothing.
        i see only the background image but no osd, no disturb, no strange effect, its not warm.

        maybe the problem is on the offset?
        osd.setDisplayOffsets(60,18);
        osd.setBlinkParams(_8fields, _BT_BT);

  2. Hi again,

    Did you upload into the OSD a new character table? if you did it using the sample program Max7456WriteTable.cpp your OSD memory has been overriden with 0xFFs (so all your characters are white). Can you try to invert colors on your osd.print("Hello world :)",1,3); (just replace it with osd.print("Hello world :)",1,3,0,1);. If so, you'll have to upload a non-empty table again.

    1. uhm.... i didn't upload no character table! ;(
      my osd is brand new and i didnt uploaded nothing, my mistake!!
      ...tomorrow i will fix it.

      thanks so much ben

      1. Well actually it should work anyway : don't try it yet. There is a default chars table in the max, and some random characters should appear replacing the "Hello world" string. I'll try tomorow to upload the exact code you posted to see if it's a software problem. one thing you can do is to reset first the OSD (by connecting RST to ground and then put it back to 5V with resistor), and then reset the arduino after this (don't disconnect it, just push the reset button). What is the Arduino board you're working on?

  3. Arduino UNO, and a regular duemilanove (with optiboot bootloader).

    Do you think that my osd has a default table?
    Could you populate Max7456WriteTable.h with a default table?
    Maybe i can try to upload a new table.

    What kind of benefit shoul i will have with resetting the osd?

    regards

    1. resetting the chip will only restore its internal registers to a default value ; basically if the internal state of the max may have been somehow corrupted by something (lets say : rise up on the 5V ; states of the Arduino pins on startup,...). By the way can you tell me what version of the IDE you are using ? You could have to manually set the SPI pins to input and output states. But it's already done on the latest ones. one other problem you're pointing out is the bootloader that can somehow disturb the functionning of the max. those chips are quite sensitive so if you can for your tests I recommand you to get back to the original bootloader and therefore see if this is the source of the problem. If it still don't work, maybe you should try to upload a sample code for the max7456 (you can found it on the internet (http://f5mna.free.fr/Arduino.htm for exemple, it's in french but you can download a sample sketch at http://f5mna.free.fr/arduino/f5mna_8_phrases.zip ). Let us know if you find a solution to your problems.
      Regards

      1. thanks for your suppor dude

        i have tried to reset the osd but nothing on tv, im using ide 1.0.1.
        i want to try to upload a new char table (im desperate!), is your code for arduino? i see a .cpp extension.
        can you try modify it for a regular arduino + ide 1.0.1?

        regards

        1. Hi Andrea,

          I know this little device can be a pain in the ass :(

          This is actually a code designed to be used in eclipse but chances are that you'll be able to open it in your arduino IDE by changing the extension to .ino. (If you often use arduino you should give a try to eclipse we wrote an article about it).

          Also, the .h file that contains the characters table is filled with 0x55 (blanck characters).
          You can try the program that we gave with the library (you have to open it with command lines -hope you know how to do this). It takes a bmp file as input and generate a .h which contains a table of 13.5k of data representing this bmp table into the max memory. You'll just have to copy it and replace the old 0x55 values in the initial.h. I tried your example and it works fine on me.

          If it's an option to you, try to upgrade your IDE to 1.0.2, too..

          1. No problem :) I hope you'll eventually figure out what's the problem. Don't hesitate to comment again to share your experience.

            Ben

  4. Im converting your loader for working with arduino ide but i have some error messages such:

    Max7456 *osd = NULL; //Pointer representing a max7456 .

    In file included from Max7456WriteTable.ino:2:
    Max7456WriteTable.h:25: error: expected constructor, destructor, or type conversion before '*' token

  5. little update for your loader: https://gist.github.com/4622611

    sketch_jan24b.ino: In function 'void setup()':
    sketch_jan24b:303: error: no matching function for call to 'Max7456::getCARACFromProgMem(int&, byte [54])'
    D:\arduino-1.0.3\libraries\max7456/max7456.h:228: note: candidates are: static void Max7456::getCARACFromProgMem(const prog_uchar*, byte, byte*)
    sketch_jan24b:304: error: no matching function for call to 'Max7456::sendCharacter(byte [54], int&)'
    D:\arduino-1.0.3\libraries\max7456/max7456.h:116: note: candidates are: void Max7456::sendCharacter(const byte*, byte, byte)

    how can i solve it?

  6. Ok for your first error you just have to add the name of the variable in progmem : tableOfAllCharacters as first argument. leave the other arguments as they are.

    For the second, do this trick:
    osd->sendCharacter(currentChar,i&0xF0, i&0xF0);

    this is because we use it as low and high addresses and I forget to update the code sample, appologies :(

  7. Thanks for your support

    I have modified the sketch, the *final* version is this: https://gist.github.com/4625393.git

    BUT... the two functions (osd.getCARACFromProgMem - osd.sendCharacter) will overflow the ram of my arduino uno....
    I dont see nothing on the serial monitor but, If i will comment only this two functions it works!

    What do you think?

  8. the problem is only in this function: osd.getCARACFromProgMem(tableOfAllCharacters,i,currentChar);
    if i will comment only this, it will run (but it will write nothing).... maybe it take too much ram in run time.

    what kind of trick can i use for upload a new table on the eeprom?

    some people on internet, with my same issues, have solved it by uploading a new table.... maybe its blank.

    1. Hi again,

      One thing you can try is enable verbose mode for your compilation (file/preferences/check verbose). This can give you a better hint on what's happening. We had this problem but it was solved using the "prog_uchar... PROGMEM" pattern which write the big array into program memory of the chip. btw, what is your atmega version ? we did all our tests with a 328 but if you have a 168 it can be too short in memory (16kb of data from wich you must take the 13.5 from the array and 2k from the bootloader, which left almost nothing). If so, you should try to upload the 128 first characters only (divide the size of the array by 2 which free ~7k of memory) and then if it's ok go ahead with the 128 last characters.

      1. sorry again :)

        "myloader.ino: In function 'void setup()':
        myloaderi.ino:17: warning: '__progmem__' attribute ignored"

        line 17 is for: const prog_uchar tableOfAllCharacters[13824] PROGMEM = {

        is it a big problem?

      2. OK this must be the problem : try to add the static keyword just after the const one.
        If this does not do the trick, try to install a new version of Arduino. Some other dudes had the same problem solved by re-installing the entire chaintool.

        1. There is a function in the library that allow reading characters from the max7456. Try to use it with one or two characters to see if the upload went well

          1. Hi Andrea,

            This is the right function. This code works with me. This seems to be a hardware problem : you can try to see if the SPI pins are correctly initialized (MISO as input for example). Maybe your max7456 is broken, too, but I can't really tell. If you can try with an other go for it. Did you try other examples around the internet ?

          2. (Sorry I just made a typo : it's osd.getCharacter(currentChar,i&0x0F, i&0xF0), not i&0xF0, i&0xF0, but it should not affect the overall function.

  9. Hi Andrea that's great news (altought i'm sorry for your money :-( )

    They are some things you can try out now you have a "running" max7456 :
    - try to reset the OSD before to reset the arduino (do it manually)
    - try to upload the whole new character table : the chinese chars you see come from the default table.

    anyway you should get it to work soon ;)

  10. Hi Ben,

    Very interested in what you have done here - It appears I have everything working except I'm having trouble bringing in your character set.
    I'm not a programmer but hope you could walk me through using your little program ,"I made an program used to transform a bmp picture"

    Thanks
    Rick

    1. Hi, this program basically translate a .bmp picture into a arduino-readable .h file that you can copy/past to the code that upload characters to the max7456. Where are you stuck with that ?

  11. Hijacking Rick's thread a bit, Yes. I understand that your little program reads a BMP of characters and converts them into a file (tableOSD.h) but what the line that then stuffs that in to the MAX7456.

    I see the line
    const prog_uchar tableOfAllCharacters[13824] PROGMEM = {0x55,0x55,0x55,0 //
    and the
    //-----------------------------------------------------------------------------
    // Implements Max7456::getCARACFromProgMem
    //-----------------------------------------------------------------------------
    void Max7456::getCARACFromProgMem(const prog_uchar *table, byte i, charact car)
    {
    unsigned long index;
    byte read;
    index = i*54;
    for(unsigned long j = 0 ; j < 54 ; j++)
    {
    read = pgm_read_byte_near(table +index+j );
    car[j] = read;
    if (car[j] == 0x55)
    car[j] = 0xff;
    }
    }

    Do I put
    #include
    at the start of my listing and then use the function Max7456?

    Yours Simon M

    1. Hey !

      Basically all you need to do is replace all the characters (hexa values) in const prog_uchar tableOfAllCharacters[13824] PROGMEM = {0x55,0x55,0x55,0 //

      by the freshly generated characters from the .h ; then upload the sketch to the arduino and use a terminal to update the characteres memory of the Max and it's done :)

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>