Hi!
I just got my TV controller working and would like to share this to you.
Behind my LG TV there is a RS232 port. I have always been curious what that port does. Then I read the manual (after 5 years of curiosity) and apparently you can control almost everything in the TV with simple serial commands and it´s well documented in the manual.
The commands are built in three segments: “[COMMAND] [TV ID] [VALUE]”. For example, if I would like to turn on my TV, the command is Serial.println(“ka 01 01”), where “ka” is the command for power. To turn it off again I use Serial.println(“ka 01 00”). You can also check if the TV is on or off via the command Serial.println(“ka 01 FF”) and it will return “a 01 OK01” (on) or “a 01 OK00” (off).
After testing the commands from my computer via null modem cable I ordered a RS232 to TTL converter module. A simple way to use software serial to control RS232. The hardware is simple to set up. I use a 5v Arduino Mini Pro, the RS232 to TTL, mini usb BOB (only for power source) and of course the NRF24L01 radio with a socket adapter.
I bought this one: RS232 To TTL Converter Module
• Connect the radio like always.
• Connect the VCC on RS232 to 5v, ground to ground, RX to D6 and TX to D7
With this code I can controll the power and volume on the TV. I can also see if the TV is on or off.
#include <MySensor.h>
#include <SPI.h>
#include <SoftwareSerial.h>
MySensor gw;
MyMessage msg(1, V_LIGHT);
MyMessage msg2(2, V_PERCENTAGE);
//Software Serial for RS232 to TTL board, define output pins
SoftwareSerial mySerial(6, 7); // RX, TX
String tvPower = "00"; //Power 00=off 01=on
int tvVolume = 0; //Volume
const String tvid = "01"; //The ID you set in your TV
unsigned long previousMillis = 0; // last time update
int messageToSend = 0;
void setup()
{
// Initialize library and add callback for incoming messages
gw.begin(incomingMessage, AUTO, true);
// Send the sketch version information to the gateway and Controller
gw.sendSketchInfo("LG TV RS232", "1.1");
gw.present(1, S_LIGHT);
gw.present(2, S_DIMMER);
//Software Serial for RS232 to TTL board, begin
mySerial.begin(9600);
}
void loop()
{
// Alway process incoming messages whenever possible
gw.process();
if (mySerial.available() > 0) {
String incommingString;
// read the incoming byte:
//incomingByte = mySerial.read();
// say what you got:
incommingString = mySerial.readStringUntil('\n');
Serial.print("I received: ");
Serial.println(incommingString);
parseSerialString(incommingString);
}
//Check if TV is on
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > 30000) {
previousMillis = currentMillis;
if(messageToSend>0) messageToSend=0;
if(messageToSend==0){
sendMessage("ka", "FF"); //Set status to FF if you want to see the current power status.
messageToSend++;
}else if(messageToSend==1){
sendMessage("kf", "FF"); //Set status to FF if you want to see the current volume.
messageToSend++;
}
}
}
void incomingMessage(const MyMessage &message) {
if (message.sensor==1) {
if(message.getBool()){
setPower("01");
}else{
setPower("00");
}
// Store state in eeprom
gw.saveState(message.sensor, message.getBool());
// Write some debug info
Serial.print("Incoming change for sensor:");
Serial.print(message.sensor);
Serial.print(", New status: ");
Serial.println(message.getBool());
}
else if (message.sensor == 2) {
Serial.println( "V_PERCENTAGE command received..." );
int dimvalue= atoi( message.data );
if ((dimvalue<0)||(dimvalue>100)) {
Serial.println( "V_DIMMER data invalid (should be 0..100)" );
return;
}else{
Serial.print("V_PERCENTAGE value: ");
Serial.println(dimvalue);
}
gw.saveState(message.sensor, dimvalue);
dimvalue = round(dimvalue*2/10);
Serial.print("New value: ");
Serial.println(dimvalue);
setVolume(dimvalue);
}
}
//Send message to tv
void sendMessage(String tvcommand, String tvstatus){
mySerial.println(tvcommand + " " + tvid + " " + tvstatus);
}
//Turn TV on or off
void setPower(String tvstatus){
sendMessage("ka", tvstatus);
}
//Set TV volume
void setVolume(int volume){
String strVolume;
if(volume<0) volume=0;
if(volume>64) volume=64;
strVolume = String(volume, HEX);
if(strVolume.length()==1){
strVolume = "0" + strVolume;
}
sendMessage("kf", strVolume);
}
//Parse incomming serial string
void parseSerialString(String serialString){
String tvcommand;
String tvstatus;
tvcommand = serialString.substring(0,1);
tvstatus = serialString.substring(7,9);
if(tvcommand=="a"){
tvPower = tvstatus;
gw.send(msg.set(tvPower.toInt()));
Serial.println("Power is: " + tvPower);
}
if(tvcommand=="f"){
tvVolume = tvstatus.toInt();
gw.send(msg.set(tvVolume));
Serial.println("Volume is: " + tvstatus);
}
}
Any feedback on the code is welcome! This is my first project for MySensors and I have a lot to learn!