Vivitek Projector Serial Commands over IP through Raspberry Pi - Help Needed


(The Viking AKA "Holy Crap You're a Giant!") #1

I’m at a complete loss for this one and was hoping someone out there would be able to help.

I have a Vivitek projector with an RS232 port on it.
This is connected to a Raspberry Pi via a USB to Serial adapter, and the Pi is able to communicate without issue with the projector for powering on/off, managing inputs, etc.

Sending the commands is simple. ~PO (enter) sends a Power On command. ~PF (enter) sends a Power Off command.
I am able to send the commands via Telnet from any system in the house to the Pi by connecting to the Pi’s Static IP and then typing the command. I have also successfully “BATCHED” this out for Windows in several .bat files, so I can double click and things happen.

I can also query the projector for power/input/lamp hours and more, as well as set all manner of features with it.
Details on the projector serial commands are here: http://www.vivitek.com.tw/upfile/down/2011-08-22/b20110822040023432.pdf

I’d like to find a way to have a device type in SmartThings for the projector and have it just send/query from the Pi over Telnet from the hub, or worst case, have a page on the Pi that shows the status of the projector at all times (with a five or ten second refresh) that will also accept commands…

I’m not a developer. I can’t code to save my life. I know quite a few people with televisions/projectors that all support serial interfaces of one kind or another for turning on/off and controlling basic functions. This should be adaptable across multiple brands.

Help?


(ActionTiles.com co-founder Terry @ActionTiles; GitHub: @cosmicpuppy) #2

I’ve done this for my projector (also RS-232) using Arduino with SmartThings Shield… Pretty cheap and makes the SmartThings DTH programing super easy (just text strings to/from the Arduino).

I’ll try to dig up and share the code in case it helps…


(The Viking AKA "Holy Crap You're a Giant!") #3

@tgauchat

That would be awesome of you!

I have the existing Pi stuff, and I’m running it over PoE using a PoE splitter from my Cisco PoE switch. It works great to always be online and operational.

I’m planning on tucking the projector in a drop down panel in the ceiling, and already have the linear actuator, etc.
This is why I’m devoting a Pi to this project, so that it can operate as both the Serial over IP and the motor controller for the projection system.


(ActionTiles.com co-founder Terry @ActionTiles; GitHub: @cosmicpuppy) #4

My SmartThings + Arduino sketch does 433mhz transmission to raise and lower the screen, 12v trigger signal detect to activate the screen if ST is down, and on/off/mode via RS232 for the projector!

Here’s the DTH:

And the Arduino Sketch…

*Dang… Not in the same Repo. Post it later.


Need Z-Wave/zigbee solution for projection screen w/ wall switch and 12V trigger
(ActionTiles.com co-founder Terry @ActionTiles; GitHub: @cosmicpuppy) #5

Here’s the Arduino portion… Not sure why I didn’t have it in Repo. Nothing too fancy; but combined with the DTH above, it shows the “ease of use” benefit with the ThingShield (ZigBee based).

For rPi, you can run a node or other simple http server to take REST-API calls from the LAN with similar messages.

#include <SoftwareSerial.h>   //TODO need to set due to some weird wire language linker, should we absorb this whole library into smartthings
#include <SmartThings.h>

#define PIN_THING_RX    3
#define PIN_THING_TX    2

SmartThingsCallout_t messageCallout;    // call out function forward decalaration
SmartThings smartthing(PIN_THING_RX, PIN_THING_TX, messageCallout, "", false);  // constructor


int ledPin = 13;
bool isDebugEnabled = true;    // enable or disable debug in this example

int downRelayPin = 12;
int upRelayPin = 11;
int holdDuration = 300; // duration of the relay on "press"
int waitDuration = 100; // duration of the relay between "presses".

int inputPin = 7; // 12vDC mono trigger signal input from Projector
bool projectorOn = false;
bool projectorUpdate = false; /* Let status of Projector be unsent until we see it change? */
int inputPinSum = 0; // We will sum the value of input pin over several samples to make sure it is really ON or really OFF.
int loopCount = 0;

/* TODO: These could be made on/off configuration options from the SmartThings Device Tiles! */
/*       or change them to #define */
bool screenAutoOn = true;   // Localized automatic screen down/on when Projector ON  if true.
bool screenAutoOff = false; // Localized automatic screen up/off  when Projector OFF if true.


/**
 * setup
 */
void setup()
{
  /* Input trigger from Projector */
  analogReference(DEFAULT);
  pinMode(inputPin, INPUT);
  digitalWrite(inputPin, LOW); // Must be LOW else always get 1. Is this Pulldown enabled?
  
  /* Set mode for Hardware Pins */
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, HIGH);

  pinMode(downRelayPin, OUTPUT);
  digitalWrite(downRelayPin, LOW);

  pinMode(upRelayPin, OUTPUT);
  digitalWrite(upRelayPin, LOW);

  if (isDebugEnabled)
  { // setup debug serial port
    Serial.begin(9600);         // setup serial with a baud rate of 9600
    Serial.println("setup..");  // print out 'setup..' on start
  }
} /* setup() */


/**
 * loop
 */
void loop()
{
  
  /* We will allow a few "missed" signal values 5 out of 50 and still count as ON. */
  inputPinSum += digitalRead(inputPin);
  if ( loopCount <= 50 && inputPinSum > 45 ) {
    if ( !projectorOn ) {
      projectorOn = true;
      projectorUpdate = true; /* Let status of Projector be unsent until we see it change? */
      messageCallout( "" );
      if ( screenAutoOn ) on();
    }
    loopCount = 0;
    inputPinSum = 0;
  } else if ( loopCount >= 50 && inputPinSum < 5 ) {
    if ( projectorOn ) {
      projectorOn = false;
      projectorUpdate = true; /* Let status of Projector be unsent until we see it change? */
      messageCallout( "" );
      if ( screenAutoOff ) off();
    }
    loopCount = 0;
    inputPinSum = 0;
  }
  if ( loopCount > 50 ) { loopCount = 0; inputPinSum = 0; }
  loopCount ++;

/*
  Serial.print("loopCount: ");
  Serial.print(loopCount);
  Serial.print(" inputPinSum: ");
  Serial.print(inputPinSum);
  Serial.print(" ProjectorOn Value: ");
  Serial.print(projectorOn);
  Serial.println(".");
*/

  smartthing.run();
  
} /* loop() */


/**
 * doublePress
 */
void doublePress( int whichPin )
{
  singlePress( whichPin );
  singlePress( whichPin );
}


/**
 * singlePress
 */
void singlePress( int whichPin )
{
  digitalWrite(whichPin, HIGH);
  delay(holdDuration);
  digitalWrite(whichPin, LOW);
  delay(waitDuration);
}


/**
 * on() - Screen Down
 */
void on()
{
  smartthing.shieldSetLED(0, 1, 0); // green

  digitalWrite( upRelayPin, LOW);  // Be certain to lift the other button.
  doublePress( downRelayPin );

  smartthing.send("on");        // send message to cloud
  Serial.println("Sent: on");
  // Serial.println( smartthing.shieldGetLastNetworkState() );
}


/**
 * off() - Screen Up
 */
void off()
{
  smartthing.shieldSetLED(0, 0, 1); // blue

  digitalWrite( downRelayPin, LOW);  // Be certain to lift the other button.  
  doublePress( upRelayPin );

  smartthing.send("off");       // send message to cloud
  Serial.println("Sent: off");
  // Serial.println( smartthing.shieldGetLastNetworkState() );
}


/**
 * disable() - Stop Screen (TODO: could also disable SmartThings control).
 */
void disable()
{
  smartthing.shieldSetLED(1, 0, 0); // red

  digitalWrite( upRelayPin, LOW);  // Be certain to lift the other button.  
  singlePress( downRelayPin );
  singlePress( upRelayPin );

  smartthing.send("disable");       // send message to cloud
  Serial.println("Sent: disable");
  // Serial.println( smartthing.shieldGetLastNetworkState() );
}


/**
 * enable() - Enable SmartThings (TODO: Just resets from disable for now.).
 */
void enable()
{
  smartthing.shieldSetLED(1, 2, 1); // 

  digitalWrite( upRelayPin, LOW);  // Be certain to lift the other button.  
  singlePress( downRelayPin );
  singlePress( upRelayPin );

  smartthing.send("enable");       // send message to cloud
  Serial.println("Sent: enable");
  // Serial.println( smartthing.shieldGetLastNetworkState() );
}


/**
 * messageCallout
 * TODO: Move projectorUpdate outside this function as well as callers in loop().
 */
void messageCallout(String message)
{
  // if debug is enabled print out the received message
  if (isDebugEnabled)
  {
    Serial.print("Received message: '");
    Serial.print(message);
    Serial.println("' ");
  }

  if (message.equals("on"))
  {
    on();
  }
  
  if (message.equals("off"))
  {
    off();
  }
  
  if (message.equals("disable"))
  {
    disable();
  }
  
  if (message.equals("enable"))
  {
    enable();
  }

  /* TODO: This should be own function, not here in messageCallout(). */
  /*       But ... if we add remote projON / projOFF (RS232), then we move things around anyway. */
  if (projectorUpdate)
  {
    projectorUpdate = false;
    if (projectorOn) {
      Serial.println( "Sending: projON" );
      smartthing.send("projON");
    } else {
      Serial.println( "Sending: projOFF" );
      smartthing.send("projOFF");
    }
  }
  
} /* messageCallout() */


/* =========== */
/* End of File */
/* =========== */

(Michael Hess) #6

I used to use my Pi for my projector like this, used EventGhost to interface stuff, then just got fed up with all the bits and pieces and let my Harmony handle it all. I didn’t have a lift to deal with though, but with virtual switches/EG in ST I bet you could fashion something that easily triggers the Pi.