Problem sending serial commands to a video projector

Hi there,

I try to interface with my Optoma HD33 projector in order to control it with an Arduino Uno with serial RS232 commands.
For my Proof of Concept I try to send the command “~0012 5” to my projector to switch to VGA INPUT.

So far I got a MAX3232 TTLtoRS232 adapter and can send RS232 commands from my Arduino Uno with it; however unfortunately I am not able to control my projector and after days of tinkering I could not find a solution, hopefully someone can help :confused:

I confirmed that the command “~0012 5” works by connecting a Serial2USB cable to the Projector and my MacBookPro and send the command with the app “Serial” and also with the terminal “screen /dev/cu.usbserial-A703TM76 9600” to the projector. This works without any issues and the projector returns “P” for PASS and switches to VGA INPUT.

However if I send the command “~0012 5” with my Arduino to the projector it reports back “F” for FAIL. So the Arduino has successfully send (something) to the projector and the projector responded with “F”. I see that response in the Arduino Serial Monitor. So communication in general seems to work as I send something and receive a response from the projector.

I thought maybe the Arduino for whatever reason sends the wrong characters or a prefix and tried to debug it by letting the Arduino talk to my Mac via the same SerialtoUSB cable:
Arduino sends “~0012 5” over MAX3232 adaptor to Serial2USB cable back to MacBookPro → “screen” in terminal shows me “~0012 5”.
So it seems the Arduino outputs the correct serial command.

My test code is below, I tried to send the command as string and with hex codes, both times the projector returns “F”.
As I can receive responses from the projector and also see the requests on my MacBook I am quite confident that the cable connections are ok.
Can anyone help?

This is the MAX3232 adapter I am using:

Optoma HD33 RS232 Documentation:

boolean intrap = false;
SoftwareSerial mySerial(10, 11, false); // RX, TX
 
void setup() {
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  mySerial.begin(9600);
    while (!mySerial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
}
 
void loop() {
 
  if (mySerial.available()) {
    Serial.write(mySerial.read());
  }
 
  if( millis() > 2000 && intrap==false) {
    intrap = true;
 
    //TEST 1 - String Only
    mySerial.write("~0012 5\r");
 
 
    //TEST 2 - Hex and String
    //mySerial.write( 0x0D ); //CR to reset
    //mySerial.write("0012 5");
    //mySerial.write( 0x0D ); //CR
 
    //TEST 3 - Hex Only
    //mySerial.write( 0x0D ); //CR to reset
    //mySerial.write( 0x7e );
    //mySerial.write( 0x30 );
    //mySerial.write( 0x30 );
    //mySerial.write( 0x31 );
    //mySerial.write( 0x32 );
    //mySerial.write( 0x20 );
    //mySerial.write( 0x35 );
    //mySerial.write( 0x0D ); //CR
   
  }
 
}

I don't think this is doing what you think

mySerial.write("~0012 5\r");

try

mySerial.print("~0012 5\r");

...R

I tried it now with

mySerial.print("~0012 5\r");

and interestingly now I get the response “7013” in the Arduino Serial Monitor.
I assume those are now ASCII characters and according to my ASCII table
70 = F
13 =

So the same response “F” = Fail if my assumption is correct, just different formatted?!

TerrAustria: I tried it now with

Post the latest version of your program.

...R

Robin2:
Post the latest version of your program.

#include <SoftwareSerial.h>

boolean intrap = false;
SoftwareSerial mySerial(10, 11, false); // RX, TX

void setup() {
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  mySerial.begin(9600);
    while (!mySerial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
}

void loop() {

  if (mySerial.available()) {
    Serial.print(mySerial.read());
  }

  if( millis() > 2000 && intrap==false) {
    intrap = true;
    mySerial.print("~0012 5\r");
  }

}

However I just got my projector started.
Turn off, un-plug, plug-in again, do mySerial.print("~0000 1\r"); and it turns on. However after that I just get 7013 codes back when I try something else like switching to VGA with “~0012 5\r” as above.

Either the projector protocol is messed up or something is missing here…

The code you posted does not send ~0000 1\r

If you just want to do something once then put all the code in setup() and leave loop() empty.

I wonder if you need "proper" code to recognize that a reply has been received before sending the next command. Have a look at the 2nd example in Serial Input Basics. I reckon you will need to change the end-marker to '\r'

Note how it sets newData = true when it receives a message. That is probably the signal to send another command.

...R PS. I can't read the projector PDF tonight because my internet connection is too slow

Robin2:
I wonder if you need “proper” code to recognize that a reply has been received before sending the next command. Have a look at the 2nd example in Serial Input Basics. I reckon you will need to change the end-marker to ‘\r’

I added the code from Example #2 and put the command sending into the setup(), please note that I changed the reading of the serial port from Serial.available() and Serial.read() to mySerial.available() and mySerial.read() as I am using pins 10 and 11 with SoftwareSerial.

Also I decided to not use the command “~0012 5\r” for testing but “~00150 1\r”, latter one returns the current status of the beamer.

#include <SoftwareSerial.h>

const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data
boolean newData = false;

SoftwareSerial mySerial(10, 11, false); // RX, TX

void setup() {
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  mySerial.begin(9600);
    while (!mySerial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  Serial.println("<Arduino is ready>");

  mySerial.print("~00150 1\r");
  
}

void loop() {
  recvWithEndMarker();
  showNewData();
}

void recvWithEndMarker() {
    static byte ndx = 0;
    char endMarker = '\r';
    char rc;
    
    while (mySerial.available() > 0 && newData == false) {
        rc = mySerial.read();

        if (rc != endMarker) {
            receivedChars[ndx] = rc;
            ndx++;
            if (ndx >= numChars) {
                ndx = numChars - 1;
            }
        }
        else {
            receivedChars[ndx] = '\0'; // terminate the string
            ndx = 0;
            newData = true;
        }
    }
}

void showNewData() {
    if (newData == true) {
        Serial.print("This just in ... ");
        Serial.println(receivedChars);
        newData = false;
    }
}

When I run this when the projector is turned OFF I get different responses each time, so the following responses in the Arduino Serial Monitor happened when I uploaded the sketch 4 times on the Arduino. The response appeared instantly on the serial monitor without delay.

Sketch Upload #1

<Arduino is ready>
This just in ... OK1125800C0040
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... FF
This just in ... 
This just in ... FF
This just in ... 
This just in ... FF
This just in ... 
This just in ... FF
This just in ... F
This just in ... 
This just in ... FF
This just in ... 
This just in ... FF
This just in ... 
This just in ... FF
This just in ... 
This just in ... FF
This just in ... 
This just in ... FF
This just in ... 
This just in ... FF
This just in ... 
This just in ... FF

Sketch Upload #2

<Arduino is ready>
This just in ... ⸮⸮F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... FF
This just in ... 
This just in ... FF
This just in ... 
This just in ... FF
This just in ...

Sketch Upload #3

<Arduino is ready>

Sketch Upload #4

<Arduino is ready>
This just in ... OK1125800C0040
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F
This just in ... F

OK1125800C0040 is a proper response from the projector, according to the manual:

OK = Prefix of information
1 = Power State ON (which is strange because it is turned off, only connected to power)
1258 = Lamp Hours
00 = Input Source Commands None
C004 = Firmware Version
0 = Display Mode None

In case the projector is turned ON (with the IR remote control) and I upload the sketch again I always only get:

Sketch Upload #1, #2, #3 and #4

<Arduino is ready>
This just in ... F
This just in ... F

When I turn the projector with the remote control off again the projector sends the info to the Arduino and I see in the serial monitor:

<Arduino is ready>
This just in ... F
This just in ... F
This just in ... INFO2

Note that the INFO2 line appears when I press the remote button to turn it off, the lines before where already there.
INFO2 is a proper response from the projector, according to the manual:

INFO = Prefix of automatic information
2 = Cooling Down

So from what I see it seems that it does not accept any serial commands when it is turned ON?!

I'm confused about what you mean by "turned on". Clearly it is different from "plugged into the mains and the power switch pressed"

You said you had success sending commands some other way. I suggest you pick 2 or 3 commands and send them using the working mechanism and carefully note exactly what you sent and exactly what the response was.

Then concentrate on replicating that with your Arduino.

You do seem to be making some progress. I don't understand what is making it send more than a single 'F'

...R

Robin2:
I’m confused about what you mean by “turned on”. Clearly it is different from “plugged into the mains and the power switch pressed”

to clarify:
turned on = lamp is on and it is projecting something
turned off = plugged in = lamp is off, power coord is attached, it is in standby

Robin2:
You said you had success sending commands some other way. I suggest you pick 2 or 3 commands and send them using the working mechanism and carefully note exactly what you sent and exactly what the response was.

Then concentrate on replicating that with your Arduino.

You do seem to be making some progress. I don’t understand what is making it send more than a single ‘F’

Indeed, it works with a Serial2USB cable from my Laptop, just not with the Arduino :frowning:
I now also try to figure out why I get so many “F” responses so I build a debug setup:

So I connected the Arduino with the MAX3232 serial port with a Serial2USB cable to my laptop and from the laptop I connect a second Serial2USB cable to the projector, with the application “serialTools” I can internally connect both and see exactly in the Protocol Analyzer what the Arduino is sending and what responses get send back without relying on the Arduino Serial Monitor.

The result is that I have no issues with this setup, it works as expected, no errors, no "F"s in the monitor and also the Arduino Serial Monitor shows no "F"s.


image uploader

I am running out of ideas what and where the problem can be…
Maybe the Serial2USB cables do some extra stuff I am unaware off

#include <SoftwareSerial.h>

const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data
boolean newData = false;

SoftwareSerial mySerial(10, 11, false); // RX, TX

void setup() {
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  mySerial.begin(9600);
    while (!mySerial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  Serial.println("<Arduino is ready>");

  mySerial.print("~00150 1\r");
  
}

void loop() {
  recvWithEndMarker();
  showNewData();
}

void recvWithEndMarker() {
    static byte ndx = 0;
    char endMarker = '\r';
    char rc;
    
    while (mySerial.available() > 0 && newData == false) {
        rc = mySerial.read();

        if (rc != endMarker) {
            receivedChars[ndx] = rc;
            ndx++;
            if (ndx >= numChars) {
                ndx = numChars - 1;
            }
        }
        else {
            receivedChars[ndx] = '\0'; // terminate the string
            ndx = 0;
            newData = true;
        }
    }
}

void showNewData() {
    if (newData == true) {
        Serial.print("This just in ... ");
        Serial.println(receivedChars);
        newData = false;
    }
}

As I don't have your hardware to play with I can't think of anything else.

I think if it was my problem I would put to one side all the programs I had already written and, with the instructions by my side start a completely new program, just in case I missed something silly.

The PDF you posted does not say whether the serial connection on the projector works at TTL or RS232 signal levels. If it works at R232 levels then maybe your USB-RS232 cable is not behaving the same as the MAX232. However I have no experience of the MAX232

...R

Robin2: The PDF you posted does not say whether the serial connection on the projector works at TTL or RS232 signal levels. If it works at R232 levels then maybe your USB-RS232 cable is not behaving the same as the MAX232. However I have no experience of the MAX232

...R

I assume if it works with a USB2Serial cable and (sometimes) with the MAX3232 t should be RS232. Would you have another method recommended for talking with RS232 with an Arduino except a MAX3232?

Thanks for your hints so far

TerrAustria: I assume if it works with a USB2Serial cable and (sometimes) with the MAX3232 t should be RS232.

However the USB-Serial cable may not be working exactly the same as the MAX3232.

Sorry, I'm all out of ideas.

...R

Just to put a line under his thread. I now bought a Raspberry Pi Zero W and attached my USB-to-Serial cable to it to send commands to the printer, works without any flaws.

Would have hoped to solve this with an Arduino although.

TerrAustria:
Just to put a line under his thread. I now bought a Raspberry Pi Zero W and attached my USB-to-Serial cable to it to send commands to the printer, works without any flaws.

Would have hoped to solve this with an Arduino although.

Thanks for the update. It certainly seems strange.

Maybe you could get the RPi to send its commands to the Arduino to see what it is sending - or maybe rig up the Arduino to spy on the data flowing in both directions.

…R