loading

MRETV - Video, Stereo Sound and much more from a standard Arduino !

Now Updated for Arduino 1.6.6 November 2015 !

Use only two resistors and two diodes to generate full screen video. Text 47 x 29 of 8x8 characters, double the vertical resolution (47x57) in experimental interlace modes. Use pixel level graphics with a virtual graphics coprocessor controlling font, screen resolution, vertical and horizontal centering, raster index and pixel size with single scan line resolution. ASCII read and write access of screen characters, screen print strings, decimal, hex or binary. Built in simple scrolling terminal service. Video generation has been done before, but not like this. FULL DUPLEX serial still available while generating video.
Two more resistors and two capacitors will add Stereo playback of Audio samples. One shot or continuous operation. Sound samples are used in real time from progmem and a sound sequencing example is provided. Both Audio and Video are generated automatically in the background with no intervention once started.
Two more resistors and you can now connect a PS/2 keyboard or mouse (the kind before USB). Read raw key input or ASCII chars, let keys merge into the serial stream automatically. Set the keyboard LEDs and send commands to control mouse reporting.
Code examples include Ponguino, a simple terminal, a player piano, a ShootEmUp, use your Arduino as an external video card and some technical examples. Too good to be true? Watch the video then grab your soldering iron!

Step 1: Introduction

Now Updated for Arduino 1.6.6 November 2015 !

What is MRETV ?

MRETV is a few very simple circuits and a simple to use software interface that allows an Arduino to generate Video and Stereo Sound in the background while your sketch executes as normal. Your Arduino plugs directly into the A/V inputs of your TV, VCR, or projector. MRETV also has built in support for other peripherals like keyboards and mice.

Which Arduino's does MRETV work with?

MRETV has been tested and works with Arduino boards using 168, 328, and 2560 CPU's. With the Mega 2560 software serial Tx has a small hardware limitation.

Who can build MRETV?

Any Arduino user. Even if you have never built hardware before, the audio and video circuits are so simple they make a perfect first project. People with moderate experience can build them in about 5 minutes, and probably already have the parts.

How easy is it to program with MRETV?

You can set a string, make 1 function call, and the string shows on your TV. Changing the contents of the string changes the text showing on your TV (in real time without calling any function.)

Why use MRETV ?

An Arduino user interface often involves a few buttons or switches. Indicators commonly range from LEDs to 80 character displays. These can be a large part of the time and cost in a build. MRETV replaces these with a screen of 1 to over 1000 characters, stereo sound and a full PC keyboard. It can be built quickly and cheaply using only 6 resistors 2 diodes and 2 capacitors in total for all 3 circuits (video / stereo audio / keyboard).

What resources does MRETV use ?

The smallest footprint is about a 1.5k sketch using about 35 bytes of RAM, including interrupt stack use, plus 1 byte of RAM for each character location on screen (1 or more locations). The screen character space can be dual purposed. Video uses an 8 bit timer and two IO pins. Audio uses an 8 bit timer and two IO pins. The software serial Tx stream is provided on another IO pin if needed (Rx works on the standard pin). CPU usage varies with visible screen area but is self limiting about at about 80%. A small active screen uses under 10% of the CPU cycles, with a large screen plus audio around 50% is common. Key library structures and routines are redefined each compile for efficiencies. MRETV can be turned on and off ( 0% CPU).

Message:

I have truly enjoyed reading about, constructing, and learning with Instructables. I want to take this opportunity to thank all those who have shared with me, and those who made the sharing possible. You have solved my problems, fed me, inspired me, and shown me how to do what I thought was impossible. As part of that thanks I offer the MRETV debut to the Instructable community.

This Instructable is a Build and Introduction rather than an exhaustive explanation of MRETV. You will quickly have both sound and video from your Arduino. You will have some games to play, and some useful utilities. More importantly you will have a full featured library to use sound, video and more in your own sketches. If there is interest future tutorials on the software interface are possible, it has more depth than can be explored here. Since even this build and introduction covers a lot of material, I suggest you first make the video and sound circuits then take a break and spend some time with the software examples. You can use a terminal program like 'Putty' to explore until you build the keyboard (PS/2) circuit. After making the keyboard circuit you will have all the major parts of MRETV (to use examples like Ponguino and Diode Calibration you need to build some sensors.) Please do not redistribute this Premiere Release of MRETV yet, wait till the bugs become documented features.

I have tested many versions of this project connecting to many different devices and never caused any harm to the Arduino or the other device. Most TV's hold the MRETV signal much better than the capture card I used to make the videos. Due to its simplicity, most of the time, newly built MRETV hardware works the very first try. However ...

Build and use at your own risk. I assume absolutely no liability of any kind for anything you ever do related to MRETV.

Go ahead and watch the second video then let's get building.

Step 2: Video

Supplies for all steps:

soldering iron
solder
shrink wrap or electrical tape
pliers
sharp knife
male and female headers (that plug into the Arduino)
wire

Safety for all steps:

This list may seem trivial but making it was a sobering experience for me. It might be a gentle reminder for others as well.

Don't wear loose clothing, and tie back long hair
Wear eye protection for the whole build, solder 'spits' and snipped wires fly around
Work in an uncluttered, well lit, and well ventilated space
Be careful while using and storing sharp knives and tools
Don't touch the tip of the soldering iron or the element (never below the handle)
Keep a wet sponge or rag to clean your soldering iron frequently, and never hold it in your hand
Use vice grips, pliers and a rubber band, or similar, NOT YOUR FINGERS, to hold parts while you solder
Do not lean into the fumes from the soldering, a small desk fan can direct air flow
'It should be cool enough ' means to wait longer before you touch
Keep track of the sniped ends of wires, they are very bad for people and electronics
Don't leave wires exposed in your circuits, be generous with shrink wrap or tape
Don't leave even cold irons within reach of young children, be careful about the cords
Wash your hands and clean the area after soldering
Don't leave the spoon in your coffee

A short time spent setting up comfortably at the start, and for each solder joint, may be the best safety measure. It also is often quicker in the long run.

Parts:

resistor 1k ohm
resistor 300 ohm
diode 1n4148 (x2) or similar silicon switching diode
RCA plug female (or male with long lead)
male header 2 pin
male header 1 pin

Construction:

You may wish to construct the sound (next step) and video circuits at the same time.
Look at the pictures and make it your own way or
Solder the end of a diode with the stripe to one of the resistors. Repeat with the other diode and resistor.
Solder the free ends of the two resistors and the center lead of your RCA plug together.
Solder a lead to the free end of each diode to attach to Arduino pins 1 and 2. Using shielded cable is good practice but I do not notice a difference when I don't.
Solder a lead to the ground of the RCA plug to attach to the Arduino ground.
You can now connect your Arduino to almost anything with a (usually yellow RCA) composite VIDEO IN such as TV's, VCR's, projectors and video capture cards. I sometimes use the second screen of a two screen car DVD player.

Mega 2560:

Use Arduino pins 1 and 19, use male header 1 pin (x3)

Software:

Download the MRETV.zip
Please do a manual Install (rather than from the Arduino menu)
Close ALL Arduino windows
Copy the MRETV folder to Arduino\libraries
Copy the MRETV-examples folder to Arduino\Examples

Please read the opening of the Arduino\libraries\MRETV\ReadMe.txt before trying the examples to ensure the install goes well.

Tradition dictates you enter and run the following sketch (found in the examples folder.)

#include "MRETV.h"
#include "textfont.h"

char
mystring[]="Hello world";
void setup(){
Screen.begin(textfont,mystring,2*fontheight,6,30,30,1);
}
void loop() {}


Adjusting the TV:

Turn the color setting as low as possible then adjust the brightness and contrast to your liking.

S-Video:

Instead of turning down the color, it is possible to connect MRETV to luminance on a S-Video connection. This avoids color adjustments and achieves a very clear signal. My new friend Ugifer, that I just met here on Instructables, pointed this out. It was too good an idea not to add right away. I made a small cable to adapt from RCA to S-Video and added the pictures to this step. This allows flexibility as some brands of TV do not have S-Video connections. Thanks again Ugifer!

Examples:

Some of the MRETV examples are a simple demonstration of basic use, others will be more complicated showing special abilities. Later in this Instructable you will learn to program with MRETV so don't worry about understanding every example right now.

SimpleDisplay.ino - bare bones I/O, add to your existing projects
TVText.ino - the Arduino as an external video card
TestPattern.ino - a zigzag test pattern, full screen video about 1.5k (set special extensions)
Bounce.ino - a moving test pattern and bitmap graphics example (set special extensions)

Step 3: Sound

Parts:

resistor 1k ohm (x2)
capacitor 1uf (x2)
RCA female (or male with long lead) (x2)
male header 2 pin
male header 1 pin

Construction:

You may wish to construct the sound and video (previous step) circuits at the same time. A good time is now.
Again, the pictures may say it best.
Solder a resistor and capacitor to the center lead of an RCA plug. Repeat with the other RCA plug, resistor and capacitor.
Solder a lead to the free end of each resistor to attach to the Arduino pins 5 and 6.
Solder the free ends of the two capacitors and the two grounds for the RCA plugs together. Solder a lead to attach to the Arduino ground to this same point. This point can be attached to the of the video hardware ground to share a single ground connection.

Mega 2560:

Use Arduino pins 4 and 13, use male header 1 pin (x3)

Software Examples:

Arudion.ino - player piano, sound generation and sequencing 'Dammit Jim, I'm an Example not an EPod!' (set special extensions)
ScreenTool.ino - a full function utility for MRETV, use the MRETV keyboard or a terminal program like 'Putty' to connect (set special extensions)
Ponguino.ino - it has sound, let's build more hardware so we can play (set special extensions)

Step 4: PS/2 Keyboard - Mouse Port

Parts:

resistor 1k ohm (x2)
PS/2 keyboard with round 4-6 pin connector
male header 6 pin
male header 1 pin
Optional Parts:
female and male header 4 pin
PS/2 female socket
small unclad circuit board or similar prototype material
PS/2 mouse with round 4-6 pin connector

Construction:

You are probably using an older keyboard or mouse so make sure they work properly BEFORE you rework them. Cutting the keyboard cord is fast and works. Leave a few inches on the plug end so it can be reconnected for testing if needed. A PS/2 socket is hard to find, I cut an old keyboard extension to get mine. I like to make a small board to translate the Arduino pins to the 4 PS/2 lines allowing me to swap between different mice and keyboards easily. The keyboard port builds are all similar and easily done using male header pins (or female if using the ICSP) .

connect pin 10 through a 1k resistor to ground
connect pin 9 to pin 13
connect pin 9 through a 1k resistor to Vcc
connect the keyboard/mouse Vcc to 5 volts
connect the keyboard/mouse clock line to pin 9
connect the keyboard/mouse data line to pin 11
connect the keyboard/mouse ground line to ground
pin 12 is unused

4 of these 6 connections are available on the ICSP header of the Arduino. It may be useful to use it rather than the standard pins.

Mega 2560:

For the 2560 pin 53 replaces 10, 11 replaces 51, 52 replaces 13, 10 replaces 9 . Use male header 1 pin (x4) , male header 2 pin (x1). An alternate schematic is provided.


Software Examples:

TVText.ino - the Arduino as a terminal
ShootEmUp.ino - classic style game, character cell animation example, arrow keys act as a virtual joystick (set special extensions)(328 /2560 only)
Ponguino.ino - use 'j' to turn on joysticks, wasd keys act as virtual joystick2, paddles would be better (see sensors) (set special extensions)
KeyboardTool.ino - ScreenTool was preschool, way under the hood (set special extensions)
Bounce.ino - more patterns and features accessible from keyboard. (set special extensions)
Arudion.ino - keyboard organ and new features accessible from keyboard. (set special extensions)

Step 5: Software Interface

MRETV is as easy to program as it is to build, so this will be kept short. The following three examples will help you start using MRETV in your own work. They are included in MRETV.zip as SoftwareInterfaceExample.ino . It is best to use a terminal program to connect to MRETV for testing input (rather than the built in serial monitor in the Arduino environment.)

There are 3 steps to using MRETV in your sketches.

1. include the parts
2. begin() output [and input]
3. update information

Using Video in a sketch:

//1. parts
#include
// MRETV itself
#include
// a font, default fontheight is 8
uchar Screenbuf [20 * 20]={
" Use a string here to set your initial display"}; // some place to put display data, 20 rows of 20 characters

// 2. begin
void setup(){
Screen.begin(textfont,Screenbuf, 20*fontheight,20,20,20,1); // start video output
// (font, buffer, ScreenHeight (pix), ScreenWidth (chars), top (pix), left (pix), mode) top and left are centering, mode=1 for normal text
}

//3. update screen
volatile uint a,depth=0;
void loop(){
for(a=5000;a;a--);// slow us down
Screen_progstr(8,0,"Speed "); // update information as needed
Screen.dec(56-((int)depth/300));
Screen_progstr(11,0,"Depth ");
Screen.hexint(depth++);
}



Using Sound in a sketch:

Remember the 3 steps.
1. include the parts
2. begin() output
3. update information

//1. parts
// MRETV uses a special file Arduino\libraries\MRETV\MRETV.extensions to hold information about extended functions
// like sound generation. (To know why see the expert section.) To use sound you need to define an Audio type , we will
// '#define monoaudio' in this file. (see the 'default_extensions' in MRETV.extensions now.)

#include
// MRETV itself
#include
// a font, default fontheight is 8
#include "saw.h" // some sound samples
PROGMEM const char * sounds [] = { // optional array of sound samples, must be called 'sounds[]' and in progmem.
sawCo4,sawDbo4,sawDo4,sawEbo4,sawEo4,sawFo4,sawGbo4,sawGo4,sawAbo4,sawAo4,sawBbo4,sawBo4};
uchar Screenbuf [20 * 20]={
" Use a string here to set your initial display"}; // some place to put display data, 20 rows of 20 characters

// 2. begin
void setup(){
Screen.begin(textfont,Screenbuf, 20*fontheight,20,20,20,1); // start video output, sound is enabled at the same time
// (font, buffer, ScreenHeight (pix), ScreenWidth (chars), top (pix), left (pix), mode) top and left are centering, mode=1 for normal text
}

//3. update screen
volatile uint a,depth=0;
void loop(){
for(a=4000;a;a--);// slow us down
Screen_progstr(8,0,"Speed "); // update information as needed
Screen.dec(56-((int)depth/300));
Screen_progstr(11,0,"Depth ");
Screen.hexint(depth++);

//3. update sound
if (!(depth&0x07f)) switch(depth/0x80){ // beep now and then
case 1:
ssample(sawBo4,50); // play a sample directly (sample, duration (1/60sec) )
break;
case 17:
depth=0;
break;
default:
if( (depth/0x80)>5) setaudio((depth/0x80)-6,15); // play a sample from the array (sample, duration (1/60sec) )
break;
}
}


Using Input (Keyboard and/or Serial Rx) in a sketch:

//1. parts
// in 'Arduino\libraries\MRETV\MRETV.extensions' we will
// '#define monoaudio'
//'#define firmwaremultiport // keyboard and serial
// #define translatekeys // no rawkey up/down stuff
// #define mergstreams // handle both together

#include
// MRETV itself
#include
// a font, default fontheight is 8
#include "saw.h" // some sound samples
PROGMEM const char * sounds [] = { // optional array of sound samples, must be called 'sounds[]' and in progmem.
sawCo4,sawDbo4,sawDo4,sawEbo4,sawEo4,sawFo4,sawGbo4,sawGo4,sawAbo4,sawAo4,sawBbo4,sawBo4};
uchar Screenbuf [20 * 20]={
" Use a string here to set your initial display"}; // some place to put display data, 20 rows of 20 characters

// 2. begin
void setup(){
Screen.begin(textfont,Screenbuf, 20*fontheight,20,20,20,1); // start video output, sound, keyboard and serial extensions
// (font, buffer, ScreenHeight (pix), ScreenWidth (chars), top (pix), left (pix), mode) top and left are centering, mode=1 for normal text
}

volatile uint a,depth=0,Speed=56;
void loop(){
uchar chin; //character in from serial/keyboard stream
for(a=4000;a;a--);// slow us down

//3. update incomming information
switch(chin=Video.readS()){ // a character from serial (with keyboard merged)
case 0: // no character received from input
break;
case 's': // s from input
setaudio(0,35);
break;
case 0x0d: //
from input
depth=0xfff8&(depth+0x8);
depth-=1;
break;
}

//3. update screen
if(chin){
Screen_progstr(8,0,"Speed "); // update information as needed
Screen.dec(Speed-((int)depth/3));
Screen_progstr(11,0,"Depth ");
Screen.hexint(depth++);

//3. update sound
if (!(depth&0x07)) switch(depth/0x8){ // beep now and then
case 1:
ssample(sawBo4,50); // play a sample directly (sample, duration (1/60sec) )
break;
case 17:
depth=0;
break;
default:
if( (depth/0x8)>5)setaudio((depth/0x8)-6,15); // play a sample from the array (sample, duration (1/60sec) )
break;
}
}
}

Step 6: Sensors

Parts:

  diode (x4) almost any, 1n4148 is fine
  resistor  10k ohm (x4)
  male header  2 pin (x4)
Optional Parts:
  resistors  10k 20k  ohm
  thermistor
  digital thermometer 0-100 c
  stiff wire
  toilet paper ( a few sheets )
  salt or sugar ( a few grams )
  variable resistor about 5k ohm linear (x2)
  CDS photo sensor
  male header 2 pin (for each sensor)

Construction:

 You should read the next step (sensor management expansion) before building any sensors.

I WANT TO PLAY PONGUINO NOW !

 Connect a 20k resistor to the center of a 5k variable resistor. Connect a lead from the other end of the (20k) resistor to 5 volts. Connect a lead from one end of the variable resistor to ground. Connect the center of the variable resistor with a lead to analog 1. Do it all again with new resistors but connect to analog 2. The 'j' key turns the analog input off and on in Ponguino. NOTE: analog input 1 and 2 ( not 0 and 1) Have fun!

 Which sensors you build depends on where your interests are, but I suggest you make at least one diode and try the calibration sketch.
  For most sensors simply connect a pair of leads and a two pin connector.
  The temperature sensors (thermister and diode) can be coated with clear nail polish and lots of shrink wrap as they may get wet.
  The two long wires have several inches of insulation removed. One is wrapped in half of the toilet paper. The other wire is placed beside it and the pair are wrapped in the rest of the toilet paper. Hold in place with a small amount of tape. Wet completely with a strong water solution of sugar or salt and let dry. After drying you may need to replace the tape. It is now a moisture sensor whose resistance changes several orders of magnitude with a single drop of water.
  A CDS photo cell can be found in a dollar store automatic night light. 
For the variable resistor only use two leads, the center and one end.
For the voltage divider (the two resistors) connect 3 single pin connectors. Simple as it is, monitoring the supply voltage allows the greatest accuracy from your other sensors.

Using Sensors:

  Each sensor is connected between ground and an analog input pin. It tries to make the analog input 0 volts. A matched resistor connects the same analog pin to 5 volts. It tries to make the analog input 5 volts. In the inevitable battle between good and evil the input ends up somewhere in the middle. A matched resistor is one 4-5 times the maximum resistance of the sensor. This puts the analog input between 0 and 1 volt, a range the Arduino measures very accurately. Using several sensors requires more connections than can be made directly to the Arduino board so see the Sensorbatorium (sensor management expansion) in the next step.
  A CDS photo cell not only tells you how bright it is outside but if you left the light on in the basement or if the fridge door is open. A diode temperature sensor can tell you the freezer or fridge is broken and is accurate enough to raise dough, make beer and wine or bottom heat your seed beds. Water leaks under sinks, in attics and basements and burst hot water tanks all cost more if not found early. See the status of your home / wine / greenhouse / kitchen / garage just by selecting one of those (previously unused) A/V inputs on your new 308 inch flat screen TV. You can power your Arduino by plugging its USB cord into the USB port on the TV. This is a good way to play Ponguino or power projects that do not need to run all the time as the USB port on the TV usually looses power when the TV is off.

Software Examples:

  Ponguino.ino - childhood revisited (set special extensions)
  KeyboardTool.ino - the analog pins readings are on the far right (set special extensions)
  Time to start planning your home monitoring system.

Step 7: Sensorbatorium

Parts:

  Sensorbatorium - the term comes from the Latin 'the end of my old hard drive cable'. You want the one with 40 holes and 40 wires, count them both. It also is a good source of wire for use in your projects.
  male header  6 pin
  male header  1 pin (x5)

Construction:

  Cut a connector off leaving a tail of about 6 inches connected.
  Separate the first 3 inches of each of the 40 wires. Try a sharp knife, or needle nose pliers, or your finger nails if they are long enough. If you have never worked with ribbon cable before practice on your scrap end first. It gets easier with practice.
  Remove the insulation from about 1/4 inch of each wire.
  Refer to the pictures. Gather all the wires connected to holes marked 0 together and connect them to the end of the 6 pin connector. Using an extra small wire may make this easier. Then do the 1's, 2's ... 5's. Use your multimeter to check you have the right wires BEFORE soldering.
  Next do the lettered groups. All the A's to one pin, the B's to another until all groups are done.

Mega 2560:

No changes.

Connecting the Sensorbatorium:

  Plug the 6 pin header into the analog pins 0 - 5. Plug the V lead into 5 volts. Plug the G lead into ground. Plug the C lead into a V hole. Plug the A lead into a G hole. This much is always the same and does not change for different sensors.

Connecting Sensors:

  A sensor plugged into the 0A holes is matched with a resistor is plugged across the 0C holes and is read on analog input 0. 1A matches 1C and read on input 1, so on up to input 5. It is this simplicity and flexibility that makes the build of the Sensorbatorium worthwhile.


Software Examples:

  KeyboardTool.ino - the analog pins readings are on the far right (set special extensions)
  DiodeCalibration.ino- automatic calibration of diodes as accurate temperature sensors (set special extensions)
If you have a thermister, connect it to A0 and match a 10k resistor at C0. Put a 2k (two 1k in series?) resistor at A1 and match 10k at C1 to make a voltage divider. Plug in 1 to 4 diode sensors at A2-A5 and match each with 10K. Now you can calibrate the diodes.

Step 8: For the Expert

YOU DO NOT NEED THIS INFORMATION TO USE MRETV. This section is intended for people with Arduino experience.

  If you read AVR assembler look at the funky start of the actual MRETV interrupt (bottom right panel of this Instructables title picture).

Software Serial Tx:

  On a 168 or 328 based Arduino Serial Tx moves from pin 1 to pin 3 . It moves to pin 18 on the 2560. MRETV software serial is always 2400 8n1.

168/328 CPU 28 pin DIP Safe Hardware Hack:

  MRETV uses the Arduino serial Tx pin in generating video. You may have noticed a side effect. If you turn on the serial monitor you see the video data as random characters coming from the serial port. I built two trivial circuits during development. One allows connecting and disconnecting the serial Tx pin without modifying your Arduino. The other connects to the first and adds the ability to switch between normal Arduino Tx and pin 3 (the software Tx) to maintain full duplex during video generation.

  Most projects can simply use pin 3 instead of pin 1 and do not need a hardware add on. The socket circuit and a removable jumper between pins 1 and 3 works fine instead a switch. So does connecting pins 0 and 3 to a serial port on your computer instead of any of this.

Parts:

  SPDT switch
  28 pin socket
  some headers

Construction:

  Bend out pin 3 of the socket and put a lead on it. This has to be done in such a way that the socket can be plugged in the CPU socket of your Arduino. You can take it from there, this is the expert section.
  I use a female to female and male to female jumper in combination with these circuits. It gives me enough lead length to keep things organized on my bench.

Mega 2560:

  Software serial Tx is available on communication pin 18 and Rx is pin 0 as normal. With a permanently mounted CPU you cannot simply exchange Tx signals with pin 1. The best solution is to use pins 18 and 0 to connect to a serial port on your computer. Currently MRETV always uses UART0 for video (all CPU's) but work on 2560 optimization is underway. Can you guess what might be done with 3 synchronized UARTS in MSPIM?

Why the Extensions file?

  The interrupt in MRETV.S is written in assembler so will only compile in the library folder. The MRETV.extensions is used to decide what extension routines to include at compile time and must be consistent between your sketch and the MRETV code. A speed and size improvement is achieved by hard coding certain values and decisions in the interrupt.

Diode sensors:

  The diode sensors do not rely on the battle between good and evil like the other sensors but the linearity of the band‐gap energy Eg of silicon with respect to temperature.

What's in a name?

  MRETV stands for Master Raster (Extended) Transmission Vision.

  A single visible screen of 47 x 29 of 8 x 8 pixel = 87232 pixel   / 8 bits  = 10904 bytes of changeable data (the transient raster) that  is larger than RAM so it must be generated in real time. An interrupt reads a sequence of characters from a RAM array (master source of the raster), looks up the character in the font, with the offset into the character from the scan line count, reads the character data from program memory, and continuously feeds the serial transmission stream while keeping count to stop and start each scan line. It does this using 2 clocks per pixel. At the start of the raster line and some other timing points the interrupt keeps busy with extended functions like audio.

Step 9: Bugs and Bouquets

  Although a great deal of effort has been put into testing it is inevitable that in a project this size some bugs are left. Letting me know of problems is great, sending me a code example and enough information to reproduce the problem even better. I would also be nice to hear what uses MRETV is put to.

  Thank you for making it to the end of this Instructable ! I hope you find your time has been well spent.

            Mr. E



Using MRETV to play a simple game demonstrating Video, Sound, and Keyboard.
MRETV turns an Arduino into an external video card creating a portable second screen for a laptop.
(bonus - Owner Liability Digital Falling Asset Recovery Test)

Step 10: Appendix - Programming Reference

For a more complete list of functions and other programming information see 'Arduino\libraries\MRETV\ReadMe.txt' .

// Create a screen and start video output
void Screen.begin(const prog_char* CharBase,volatile uchar * textbuf,uchar lines, uchar cols,uchar top,uchar left,uchar mode)

parameters:
CharBase - a pointer to the character shape data in program memory
textbuf - a pointer to a RAM array of characters to display. Textbuf must be
cols x ( lines /( fontheight x pixelheight) ) bytes in size. Almost always
pixelheight is 1 and font height is 8 so the textbuf size = cols x lines / 8.
lines - total scan lines to display
cols - total columns to display (each column = 8 pixels)
top - scan line to start display
left - pixel count to start display
mode - pixel size ( bits 0-4 height 5-7 width ) 0 height is experimental interlace.

// display functions
Screen_progstr(line,col,string)  // put preset string on screen at a location
Screenprogstr(string)  // put preset string on screen at current location
void Screen.write(uchar a)   // place a character in the current location and  advance location
void Screen.write(uchar line, uint col, uchar c)    // set location then write() character
void Screen.render(uchar a) //place character even non printable. (big function I need help with)
void Screen.str(char* c) 
void Screen.str(uchar line, uint col, char* c) 
void Screen.hex(uchar c)
void Screen.hex(uchar line, uint col,uchar c)
void Screen.hexint(uint i)
void Screen.hexint(uchar line, uint col,uint i)
char * Screen.udec(uchar line, uint col,uint d) // return pointer to str
char * Screen.udec(uint d) // return pointer to str since we have it.
char * Screen.dec(uchar line, uint col,int d) // return pointer to str
char * Screen.dec(int d) // return pointer to str since we have it.
char * Screen.bin(uchar b) // return pointer to str since we have it.
char * Screen.bin(uchar line, uint col,uchar d) // return pointer to str

//clear a feild before over printing
void Screen.fill(uchar b,int count)  // set characters, do not change current location if count is negative
void Screen.fill(uchar line, uint col,uchar b,int count)  // set location ,set characters, do not change cur loc again if count is negative

//shape functions
void Screen.fill(uchar c) // fill the screen
void Screen.fillrow(uchar line,uchar c) // fill a row
void Screen.fillcol(uint col,uchar c)   // fill a column
void Screen.rect(uchar row,uint col, uchar wi, uchar hi,char c)
void Screen.frame(uchar row,uint col, uchar wi, uchar hi,char c)

// pixel level functions
not formalized in MRETV 1 , prototypes included in Ponguino  (see source notes)

// screen utility functions
// screen utility functions
void Screen.setcurloc(uint loc)   //  set absolute location
uint Screen.setcurloc(uchar line, uint col)   //  line col to location
uint Screen.skip(char sk)   //  advance and return position.
void Screen.bound()  // put curloc on screen
void Screen.scroll() // move screen up 1 text line
uchar Screen.get()   // get character at current location  and advance current location.
uchar Screen.get(uchar line, uint col) // set current location and return the character there, no advance
char * Screen.time()  // must be zeroed ever 24 hrs not done here....

**** Screen properties ****

uchar * Screen.poke; // pointer to curloc
uint Screen.curloc;  // current location cast as an integer
uint Screen.end; // limit of screen cast as an integer
char Screen.width; // calculated width from begin(), the real width may be dynamic

Note the two forms used in order to overload the function. Both save Ram by putting strings
only in program memory. It you do not use them text will use a lot of RAM.

Screen_progstr(line,col,string)
Screenprogstr(string)

usage:  screen_progstr(0,0,"Hello World ");
        screenprogstr("I eat therefore I am");

**** Video functions ****

void off(); // stop all MRETV activity and CPU use
void on();  // restart MRETV , only after an off()

// software serial port functions 2400 8 N 1
char Video.readS()   // read from serial buffer
void Video.writeS(char a)  // write out serial
void Video.stringS(const char * b) // write out serial

//keyboard functions
char Video.readK()   // read from key buffer
uchar Video.read()  //filtered  read (shaken but not stirred) from keyboard stream
char Video.write2key(uchar datum)  // write out on the PS/2 port
char Video.leds(char l)   // bits 0 1 2
char Video.keyrate(char l)   // as per ps/2 keyboard specs

// mouse functions
char Video.EnableDataReporting()// Let mouse talk
char Video.SetRemoteMode()// report only when asked
char Video.SetStreamMode() // report as needed
char Video.ReadData()  // ask for report

**** Video properties ****

uint Video.LineCount;  // raster line on screen currently being drawn
uchar Video.ScreenWidth,.ScreenTop,.ScreenBottom, .ScreenCenter; // active screen area
uchar Video.ScreenMode; // pixel size ( bits 0-4 height 5-7 width ) 0 height is experimental interlace.
uint Video.FrameCount, Video.FrameHigh;  // if extension selected frame=262 rasterlines = painting one screen
const prog_char *Video.audiodatar,*Video.audiodata;
uchar Video.speckey,Video.fjin;
uchar Video.f2jin;
uchar Video.arcount, Video.alcount


//  Sound, For optimum auditory excitation use SLUG SOUND EENHANCERS
// duration count 1/60 sec, 0= off, 255 continuous
// play from array of samples        sounds[];
 setaudior(sound index,duration)
 setaudiol(sound index,duration)
 setaudio(sound index,duration)
//plays the specified sound sample.
 ssampler(sample,duration)
 ssamplel(sample,duration)
 ssample(sample,duration)
I am not sure if I cmpletely follow you. Are you saying you can connect to the Video in RCA plug OR to S-video?
Yes, you can do both (but only one at a time.) First build the RCA plug video circuit, and then build the RCA to S-Video adapter for use with TV's and other equipment that allow an S-Video connection.
thank you
This is amazing. I really can't believe you can make Arduino do all that at the same time. You've managed to cram almost all the features of Raspberry Pi into arduino(maybe only ethernet left?)! <br>Your intro page text could be made a bit more easy to understand, because it's hard to imagine that all this can be done and the intro page text is a bit vague about where we get the video and audio out. At first I thought this is an instructable for making arduino compatible hardware called MRETV using LCD screens, speakers etc. You can make it clearer that it works for standard TV sets. And a picture of the circuit with live display on TV will be awesome! I'll try it out soon. Thanks for sharing this :-)
Thanks for your patience, I have finally added the video of the hardware being connected and used as you suggested. It's at the end of the 'Bugs and Bouquets' section, the MKV version is best.
Thank you for your enthusiasm ! Build it and you will believe. I almost called the Instructable 'Rusty Nail Pi' , you know the folk tale about soup? <br> <br>Excellent advice on the intro. I'll try to address it.
This seems amazing. I hope to have time to play a bit with. <br>I'd like to know if it's dedicated to some TV standard like NTSC or PAL?
Thanks! if you build it you won't be disappointed. The polarity of the sync makes it NTSC like, but its a stretch to say its 'dedicated to a standard'. I worried at first but it turns out TV's are very forgiving about what they will display.
hi! nice work man! I've sent you a personal message, please answer it when you have the time. thanks in advance!
Thanks, I enjoy doing it. Your reply is done, sorry for the delay (a few bad memory locations in the wetware these days).
Outstanding job!
Thank you! That's high praise coming from the Spork man.
Wow! <br> <br>I think I've just found my next kid's project! A pretty basic PCB &amp; we have a pongduino console for about a fiver! <br> <br>Would love to hear some of the theory on how you generate the video signal. It wouldn't even occur to me to try! <br> <br>Fabulous project!
Do you ever feel like the Ponguino paddles keep getting smaller ? I've played my son, some day I'm going to make a game I can win...
One extra thought - would it be better (for a TV that has it) to drive the luminance line of an S-video input rather than using a composite input? That would avoid any of the signal being interpreted as unintended colour information. <br> <br>Once again though: great project.
Ugifer... look what you made me do to my S-Video cable. I mean it, the new picture and note in the video section of this Instructable. Talk about crowd sourcing, what a great idea! You can just call me E
Great! Glad to be of service (however minor). <br> <br>That's the great thing about Instructables - there are so many people with good ideas and sometimes they see something that can be done in a different way. Sometimes they will even take a project you though was exhausted and put a completely new slant on it &amp; come up with something great. <br> <br>I meant it when I said I might base my next project on making a simple games console around this project - obviously I'll let you know &amp; post an 'ible if I do. <br> <br>Cheers - and thanks for the mention! <br> <br>Ugi
The best thing about Instructables, for me, is learning. If I had understood how much I would learn while making this Instructable I would have done it much sooner. <br> <br>E
Wow, excellent work, really inspiring!
Thank you ! Inspiration, its an honor to pay it forward here where its most deserved.
This is so spectacularly simple I'm amazed. I've been building with Arduinos for years now and nothing like this ever dawned on me as possible. Great job on an excellent Instructable --one of the very best I've ever seen. Thanks so much!
Thank you, your words are too kind.
PS/2 sockets are had by taking a heat gun to an old motherboard.
Indeed they are there, and sometimes difficult to get off. Thanks for the tip about the heat gun.
This is awesome. My mind is buzzing with ideas on how to incorporate this into simple test fixtures that offer much more than LEDs as a user interface. Thanks for such a great job in presenting this! <br>
Thanks, it will be what others do with MRETV that will make my effort worth while. The presentation keeps getting better, thanks again to all my editors out there !
This is a game changer, like a 4th SID channel, like fragment shaders, like dHTML. This is the dawn of a new age.
Thanks ! I was trying to think outside the bag. It became a game changer for me in a trivial way. Even when my project does not use MRETV, being able to temporarily debug/test with a dedicated screen full of data and keyboard helps a lot. I seem to do a lot of 'testing' some days.
Amazing project! It is by far the coolest project I have found on the Arduino scene! I'm willing to give it a try! Great job Mr. E! ;-)
Thank you, for your very kind words, it does represent a lot of work. Its been my development skeleton for a couple of years so is even fairly stable.
<p>How to display decimals (floats)?</p><p>I do not find</p><p>Thank you</p>
I believe it is a change in the syntax needed for the new version of the Arduino IDE. (after 1.58?) &quot;prog_char&quot; is now just &quot;char&quot; and I believe the same for all the prog_ types, the &quot;prog_&quot; is no longer used. The proper thing is to edit all the source files but adding this line at the start of the files with the error should work as well.<br><br>#define prog_char char<br><br>TVout is nice work but you will find that MRETV has advantages .<br>
<p>I need some help. I understanfd the principle, but the coding is beyond me. I am trying to write the code so that when there is a keypress, it does something. so basically :&quot;if a is pressed, do this&quot; If anyone would be willing to give me an easy tu understrand example of this, that would be great. thanks!</p>
<p>Hi Mr. E, i am trying to use your code to send the keyboard characters over Serial and i only sometimes receive the character, it is the right one but i need to hit like 10 characters before it works and then another 10 hit, and only 1 or 2 characters appear on the serial terminal. I don't want it to send the serial information that it received i.e. the command: Video.writeS(Video.read()); instead of Video.writeS(chin);</p><p>This is my code:</p><p>#include &lt;MrETV.h&gt;</p><p>#ifndef default_extensions </p><p>#error Please define 'default_extensions' in arduino\libraries\MRETV\MRETV.extensions , See comments at start of sketch</p><p>#endif</p><p>#include &quot;textfont.h&quot; // readable font</p><p>#ifdef __AVR_ATmega168__</p><p>#define asciibufsize 22*40</p><p>#else </p><p>#define asciibufsize 25*46</p><p>#endif</p><p>#define mergstreams on</p><p>uchar asciibuf[asciibufsize];</p><p>void setup(){</p><p>#ifdef __AVR_ATmega168__</p><p> Screen.begin(textfont,asciibuf, 22*8,40,34,52,1);</p><p>#else </p><p> Screen.begin(textfont,asciibuf, 25*8,46,22,20,1);</p><p>#endif</p><p> Video.readS();</p><p>}</p><p>void loop() {</p><p> uchar chin;</p><p> if((chin=Video.readS())){</p><p> Screen.render(chin);</p><p> Video.writeS(Video.read());</p><p> }</p><p>}</p><p>I am very impressed on your work to, great work. Nice and compact to.</p><p>I have gone into the code and changed a small amount just to add a cursor.</p>
<p>I use Arduino Uno, is it still possible for me to make this. (I am still a little new to Arduino.)</p>
<p>Yes, the Uno works well with MRETV. Enjoy.</p>
Hello Mr E <br> <br>I have just stumbled upon these guys: http://nootropicdesign.com/hackvision/ <br>Seems like they do a similar thing but without using the UART, which I suspect means that your version will be much less processor-hungry. <br> <br>Have you encountered their projects? I was just wondering whether they could be run on the MrETV &quot;platform&quot;. <br> <br>Ugi
The site says resolution of 136x96 pixels and Mono audio, it uses TVOUT. MRETV resolution goes beyond 376 X 324 and the audio is stereo or mono, so you should be able to port the games but it will not be real easy, the interfaces are different. Yes MRETV is less processor-hungry, but their system is game only so it makes sense if they use 100% processor time. MRETV gives you different abilities and expendability for pennies using your standard Arduino, (although my PAL version in not released publicly yet).<br><br>E
Hi! Can I use it to the serial output of my arduino in it? like on a computer with the IDE, this would be useful for on-the-field testing
Yes, MRETV can be used as a terminal (with sound) on a serial port. Note that serial TX moves to a different pin while RX stays the same as normal.
I require the highest of fives.
Thanks !, I think ? 5^5 of spades ...?
You know like high five-ing someone, like give me five.
I thought that might be it, but with no hands its hard to high 5 back. (and yes, I know there is an Instructable to solve that). All your comments here at Instructables have always made sense, and many good points. Thanks again for the high complement.
Brilliant Instructable. Excellently done! Well I was aware of many of the functions you described it is quite something to see it all written up in your article. It is a comprehensive write up; thought provoking and nicely put together. You deserve recognition
Thank you, you are too kind as well, and I certainly don't claim many original ideas. On the other hand ALL the code is new and original, this is its premiere release. ( I also believe real time generation of the raster on an Arduino and talking PS/2 protocol with 8 bit SPI hardware is unique to this work.)
This is very cool. For the time-strapped people like me it would be great if you offered a ready-to-go kit for sale. Maybe do a Kickstarter project? Any chance you will do an HDMI version at some point?
I didn't include any board layouts since its easy to build the circuits right onto the back of the plugs, if there is interest a kit is possible. As far as HDMI, let me finish my Color, 3D, 5.1 surround sound version first. (sort of joking...)
Wow, excellent work, really inspiring!
Wow, excellent work, really inspiring!

About This Instructable

51,813views

398favorites

License:

Bio: I learned to program in Sanskrit at the School of Hard Knocks.Later I home schooled myself in the new 'Morse' coding language. My teacher ... More »
More by Mr. E:Arduino as a Proximity Detector MRETV - Video, Stereo Sound and much more from a standard Arduino ! 
Add instructable to: