Serial Monkey

From EmbeddedSand

Jump to: navigation, search
George watches for the pattern "ka 01 01", the command to turn on an LG television. When George sends the correct acknowledgement, the Arduino program can continue as if it is connected to an actual TV.

The Serial Protocol Simulator is one of the tools in MegunoLink, our free utility for communicating with Arduino's. MegunoLink can also monitor serial data, plot data received from the Arduino, upload compiled programs and more.

MegunoLink's Serial Protocol Simulator is implemented by a clever little monkey named George. The simulator simplifies testing control of serial devices. If the serial device isn't available, or a rogue command sent by the Arduino would create a catastrophe, just connect to the serial port with MegunoLink. Configure the communication protocol on the Serial Monkey tab and George will send out programmed responses every time he detects the appropriate pattern in the serial stream. The protocol is saved with your project, so it is easy to reuse. And you can have several copies of MegunoLink running, each providing responses on a different serial port: connect it to every port on the Arduino Mega if you need to. You can easily see what George is up to: each response sent is added to the list on the Serial Monkey tab.

Contents

Pattern Configuration

Use the controls on the Serial Monkey page to create the patterns George will detect in the serial stream and the responses he will send in reply. Each pattern also has a description. The description can be any text to help you remember what the pattern is for. This description is added to the list box each time George replies to a pattern he has detected.

Use the Add, Edit Delete and Duplicate buttons to create, alter and remove patterns. Each pattern can be enabled or displayed using the adjacent check box. If the box is ticked, George will look for and respond to the pattern; when unchecked the pattern will be ignored.

Using buttons on the Serial Monkey page you can add, edit, duplicate and delete patterns. George will only match patterns with their enable box checked.


Pattern Format

For the most part patterns are matched and sent exactly as is. Special characters, such as new-lines, can be matched using the following escape sequences:

Characters Matches Character code
\n Newline 0x0a
\r Carriage Return 0x0d
\t Tab 0x09
\\ Forward slash 0x5c
\xNN Hex code 0xNN

Starting and Stopping Pattern Matching

George will only look for patterns and send responses when the check box labelled Enabled on the Serial Monkey page is checked. Of course the serial port must be connected and open too!

Example: Simulating an Onkyo Receiver

This simplified example uses an Arduino Mega to turn an Onkyo receiver on and off. The Arduino is connected to the receiver via serial port 1 and will send a power command to the receiver when the user pushes a button on an infrared remote control. Pushing 1 will make the Arduino turn the receiver on; pushing 0 will have it turn the receiver off.

Talking to the Receiver

The command to turn the receiver on is: !1PWR01\r; and off: !1PWR00\r. It will reply in kind sending !PWR01\r when the receiver turns on and !PWR00\r when it turns off. Interestingly the receiver also sends its power message when it is turned on by its own remote so the Arduino could detect this and, for example, turn on a TV as well. But let's not get ahead of ourselves!

Unfortunately the receiver is a long way from the development computer. So we're going to test the Arduino program by attaching the development computer to the serial port that would go to the receiver. Then MegunoLink will detect the power messages sent by the Arduino and reply in place of the receiver.

To make things more interesting, I've connected a uLCD-28PT(GFX) display from 4D Systems to serial port 3. The display is running a simple terminal program, displaying any text it receives. When the Arduino detects a reply to the power command it will send a message to the display so we can see if the receiver turned on or off.

Here's the hardware mock-up:

Arduino set up to test Onkyo receiver serial protocol

Arduino Code

You can download the complete Arduino code that sends serial commands to the receiver in a zip file or view it. As always, the most interesting part is the main loop:

  1. void loop()
  2. {
  3.   /* Detect buttons on the IR Receiver. Turn the receiver on and off when
  4.      the '1' or '0' buttons are detected respectively. */
  5.   if (g_IRReceiver.decode(&g_DecodedIRResult))
  6.   {
  7.     switch (g_DecodedIRResult.value)
  8.     {
  9.       case 0xFD30CF:  // '0' turns off
  10.         Serial1.write("!1PWR00\r\n"); // Serial command to turn receiver OFF.
  11.         break;
  12.        
  13.       case 0xFD08F7:  // '1' turns off
  14.         Serial1.write("!1PWR01\r\n"); // Serial command to turn receiver OFF.
  15.         break;
  16.     }
  17.     g_IRReceiver.resume(); // Receive the next value
  18.   }
  19.  
  20.   /* Gather serial replies from the Receiver. */
  21.   if (Serial1.available() > 0)
  22.   {
  23.     char chReceived;
  24.    
  25.     // Responses from the receiver begin with a '!' character, finish with a '\r'
  26.     while ( (chReceived = Serial1.read()) > 0)
  27.     {
  28.       // Detect start of message & init writing to the buffer.
  29.       if (chReceived == '!')
  30.       {
  31.         g_bStartOfMessageFound = true;
  32.         g_nNextCharacter = 0;
  33.       }
  34.      
  35.       // place characters into the buffer.
  36.       if (g_bStartOfMessageFound && g_nNextCharacter < SERIAL_BUFFER_SIZE)
  37.         g_achSerialBuffer[g_nNextCharacter++] = chReceived;
  38.        
  39.       // Process messages when the \r character is received.
  40.       if (chReceived == '\r' && g_bStartOfMessageFound && g_nNextCharacter < SERIAL_BUFFER_SIZE)
  41.       {
  42.         g_achSerialBuffer[g_nNextCharacter] = '\0'; // Make sure message is terminated
  43.         g_bStartOfMessageFound = false;
  44.  
  45.         if (MessageIs("!1PWR01\r"))
  46.           Serial3.write("Receiver ON\n");
  47.        
  48.         if (MessageIs("!1PWR00\r"))
  49.           Serial3.write("Receiver OFF\n");
  50.       }
  51.     }
  52.   }
  53. }

This code does two things: waits for an infrared signal then sends a serial command to port 1 to turn the receiver on or off (lines 35–52) and waits for a reply from the receiver and reports the response to the display attached to serial port 3 (lines 60–85).

Using Serial Monkey to Fake the Receiver Response

We can test this code without the receiver by attaching a computer running MegunoLink to serial port 1. Use the Add button on the Serial Monkey page to add the two patterns:

DescriptionPatternResponse
Power ON!1PWR01\r!1PWR01\r
Power OFF!1PWR00\r!1PWR00\r

You'll find these patterns already set up in the MegunoLink Project.xal file included in the download.

Enable the Serial Monkey by checking the box labelled Enable near the bottom of the window, select the appropriate COM port and press the Connect button to start a live connection. Each time you press the '1' or '0' button on the remote control, the Arduino will send a power command to MegunoLink, MegunoLink will reply and the Ardunio will report the change in power state to the display.

Screenshot of MegunoLink while testing receiver with Serial Simulator
Photo of display attached to Arduino reporting changes in power state

You can see the serial commands as the come in from the Ardunio on the Monitor page:

Screenshot of MegunoLink serial monitor while testing receiver with Serial Simultor

Now the program is ready for testing on the receiver itself, but that's a story for another day.

Personal tools