For this first tutorial, I’m going to show how to connect the Teletext Experimenter’s Board to an Arduino Uno, control it by I2C, and (in finest programming tradition) print “Hello World”.
I’ve chosen the Arduino Uno because they’re pretty-well understood, easy to work with, and cheap. If you have a different platform of choice then hopefully these notes will still prove useful. But I’ll be covering other platforms (like the Raspberry-Pi) in later tutorials.
Connecting the Experimenter’s Board to the Arduino
On the lower-right corner of the TEB is a 4-way pin header. These need connecting to your Arduino. Find some male-to-female DuPont connecting wires. From left to right, connect as follows:
- +5v – to 5v
- 0v – to GND
- I2C Clock – to A5 on early Arduinos, or “SCL” on later editions
- I2C Data – to A4 on early arduinos, or “SDA” on later editions
Use a USB cable to connect your Arduino to your PC, and connect your TEB to your monitor. And that’s it!
Download this Arduino sketch, and open it in your Arduino IDE. You might find it helpful to have it and this blogpost on-screen together. The sketch includes just enough code to send the relevant I2C data to the board to initialise it, and put some text on screen. To compensate for the little amount of code, I’ve put far too many comments in!
We communicate with the SAA5246 by reading and writing “registers” in it. Think of these as numbered locations in its RAM that you can write-to or read from. When we communicate via I2C to the SAA5246, the first byte we send sets the “current” register. Any subsequent bytes we send will be written to the current register.
After writing to almost any register, the “current” register increments to the next one. So the first transmission of bytes we send to the TEB does this:
Wire.beginTransmission(kDeviceID); Wire.write(4); // we're going to start writing at register 4 Wire.write(7); // writes 7 into register 4 ("Display chapter") Wire.write(0xCC); // writes 0xCC into register 5 ("Display control"). Wire.write(0x00); // writes 0 into register 6 ("Display control") Wire.write(0x00); // writes 0 into register 7 ("Display mode") Wire.endTransmission();
This code selects register 4. Then by sending bytes 7, 0xCC, 0, 0, these are written into registers 4, 5, 6 and 7.
In the example code, there are three such transmission blocks that setup the IC. To be honest, they can seem confusing, because they don’t really mean much right now. At this stage, I’d recommend you just accept the initialisation code for what it is. In later tutorials, we’ll revisit some of these registers and see how we can use them. But for this “Hello World” tutorial, I just want a screen I can put some text on.
Writing text to the screen
The SAA5246 has the concept of the “cursor position”. This is just the row and column where the next character will appear, when we send it. The current cursor position can be set by writing to registers 9 and 10.
Register 11 is the “please put this character on screen” register. When we write a byte in here – it appears on screen!
Unlike all the other registers: when we write to register 11, it does NOT move on to register 12 afterwards. This is by design! To put a line of text on screen, we simply start the transmission with a byte of 11 (to select the register), and then send each character of text, a byte at a time.
If you look at the third “initialisation” transmission in the example, you’ll see that it writes 0 into both the cursor-row and cursor-column registers. As you might expect, this moves the cursor into the top-left corner. So to make some text appear at the current cursor location, we write it to register 11:
Wire.beginTransmission(kDeviceID); Wire.write(11); Wire.write("Hello World!"); // writes each character in the string as a byte. Wire.endTransmission();
Also note that registers 9 and 10 are … before register 11! This is by design, too. It means if we want to move the cursor position and then immediately write text, it can be done with one transmission:
Wire.beginTransmission(kDeviceID); Wire.write(9); // start at register 9 Wire.write(12); // sets the cursor row (register 9) Wire.write(10); // sets the cursor column (register 10) Wire.write("Another line of text."); // write some text Wire.endTransmission();
That’s enough for this first tutorial. In the next, we’ll build on this by messing with some colour and effects.