# Sony Control-S help me do it better

I am working on controlling a Sony receiver via the Control-S bus http://www.armory.com/~spcecdt/remote/control-S.html I have written a proof of concept sketch and am able to turn the receiver on and off. However I think there should be an easier/more logical way to write the program. Below is the code that I have written that works. However it will be complicated to expand as I add more control functions. The control packet has to be 45ms and each packet has to be sent 3 times. long A logical 1 = 1.8ms and a logical 0 =1.2 ms each packet is 12 bits and will take a different amount of time to transmit so I have to do math on each packet to determine how long to wait before I send the next packet (in the case of the power command its 29ms).

I lack the vocabulary I need to properly ask the questions below so please bear with me.

What do I need to do to get a binary number represented in hex to correspond with the string of logical 1's and 0's that i need to send? So I can do something like sendCmd(0xA81).

How do I calculate how long 0xA81 takes to transmit so I can subtract it from 45 to get the amount of time to delay?

Any help is appreciated Thanks, Josh

``````//////////////////////////////////
//Working Sony Control-S Sketch //
//////////////////////////////////

int cpin = 12; //control s-pin

void setup() {
pinMode(cpin, OUTPUT);
digitalWrite(cpin, LOW); // Make sure CPIN is LOW on startup
delay(2000); //just seems like a good idea
}

void loop() {

/// Example code eventualy will have the code run based on a button press or some other input

////Packet must be sent three times total packet length must be 45ms I know I can simplify sending this 3 times with a loop

SB();  //send start string  #1
powercode(); //send power on
delay (29) //holds  pin 12 low for 29ms to make entire packet length 45ms

SB();  //send start string #2
powercode(); //send power on
delay (29)

SB();  //send start string #3
powercode(); //send power on
delay (29)

//some visual feedback to let me know the packets were sent.
digitalWrite(13, HIGH);
delay(1000);
digitalWrite(13, LOW);
delay(1000);
}

/////////Functions////////
/// L1 and L0 functions Define what logic "1" and logic "0" are
/// SB Defines the start bit
//////////

int L1(){   //Logic 1
//digitalWrite(cpin,LOW);
delayMicroseconds(600);//space
digitalWrite(cpin, HIGH);
delayMicroseconds(1200);
digitalWrite(cpin,LOW);
}

void L0 () { //Logic 0
//digitalWrite(cpin,LOW);
delayMicroseconds(600);//space
digitalWrite(cpin, HIGH);
delayMicroseconds(600);
digitalWrite(cpin, LOW);
}

void SB (){  //start bit transmit
digitalWrite(cpin,LOW);
delayMicroseconds(600);
digitalWrite(cpin, HIGH);
delayMicroseconds(2400);
digitalWrite(cpin, LOW);
}

////Control Function

void powercode() // the code that turns the power on and off
{
L1();
L0();
L1();
L0();
L1();
L0();
L0();
L0();
L0();
L0();
L0();
L1();
}
``````

A good place to start would be to look at "bitRead" over at the reference page.

Rather than calculate a delay you can use the time to determine if it's time to send again:

``````currentTime = millis();
if (timesToSend && currentTime - lastSendTime > 45)
{
send the command (again?)
timesToSend--;
lastSendTime = currentTime;
}

if (timesToSend == 0)  //  No output left to do
{
if we want to send another command:
command = whatever value
timesToSend = 3;
}
``````

That will send the command 3 times at 45 millisecond intervals.

John, That makes much more sense than what I was trying to do.

AWOL, I think I see where you are going... Not sure if i can get there though.

Thanks, Josh

AWOL, I think I see where you are going... Not sure if i can get there though

This:

``````void powercode() // the code that turns the power on and off
{
L1();
L0();
L1();
L0();
L1();
L0();
L0();
L0();
L0();
L0();
L0();
L1();
}
``````

looks to me a lot like "transmit (0b101010000001);" or "transmit (0xA81);"

Well, here is my final code for the Sony Control-S I couldn’t wrap my head around a better way to do it so I literally used excel to automate the writing of the functions for the receiver control. I used Excel to turn the Binary string for each control code into the function that calls the series of functions that represent the logical 1’s and 0’s. If I need to add a new function I can now just type the binary string into excel and it spits out a complete function for the command. its not pretty but it works.

Ignore the light switch stuff this project is just the beginning of a bigger home automation project.

``````#include <X10Firecracker.h>
int cpin = A0; //control s-pin
int ls1 = A1; //Light Switch Pins
int ls2 = A2;
int ls3 = A3;
int ls1state = 0;
int ls1last = 0;
int ls2state = 0;
int ls2last = 0;
int ls3state = 0;
int ls3last = 0;
int ls1count = 0;
long lastDebounceTime = 0;
long debounceDelay = 50;
int lastls1state = LOW;

void setup() {
pinMode(cpin,OUTPUT);
digitalWrite(ls1,HIGH);
digitalWrite(ls2,HIGH);
digitalWrite(ls3,HIGH);
X10.init( 2, 3, 1 );  //Initalize X10 Cm17a
Serial.begin(9600);    //Initalize serial Port
pinMode(cpin, OUTPUT);
digitalWrite(cpin, LOW); // Make sure CPIN is LOW on startup
delay(1000);
}

void loop()
{

if (Serial.available() > 0) {
//int lastOn = 0;
switch (inByte) {
case 'A':  //ON = Uppercase
X10.sendCmd( hcA, 1, cmdOn );
Serial.println("A1 ON");
break;
case 'B':
X10.sendCmd( hcA, 2, cmdOn );
Serial.println("A2 ON");
break;
case 'C':
X10.sendCmd( hcA, 3, cmdOn );
Serial.println("A3 ON");
break;
case 'D':
X10.sendCmd( hcA, 4, cmdOn );
Serial.println("A4 ON");
break;
case 'E':
X10.sendCmd( hcA, 5, cmdOn );
Serial.println("A5 ON");
break;
case 'F':
X10.sendCmd( hcA, 5, cmdOn );
Serial.println("A6 ON");
break;
case 'G':
X10.sendCmd( hcA, 7, cmdOn );
Serial.println("A7 ON");
break;
case 'H':
X10.sendCmd( hcA, 8, cmdOn );
Serial.println("A8 ON");
break;
case 'I':
X10.sendCmd( hcA, 9, cmdOn );
Serial.println("A9 ON");
break;
case 'J':
X10.sendCmd( hcA, 10, cmdOn );
Serial.println("A10 ON");
break;
case 'K':
X10.sendCmd( hcA, 11, cmdOn );
Serial.println("A11 ON");
break;
case 'L':
X10.sendCmd( hcA, 12, cmdOn );
Serial.println("A12 ON");
break;
case 'M':
X10.sendCmd( hcA, 13, cmdOn );
Serial.println("A13 ON");
break;
case 'N':
X10.sendCmd( hcA, 14, cmdOn );
Serial.println("A14 ON");
break;
case 'O':
X10.sendCmd( hcA, 15, cmdOn );
Serial.println("A15 ON");
break;
case 'P':
X10.sendCmd( hcA, 16, cmdOn );
Serial.println("A16 ON");
break;
case 'a':    //OFF = Lowercase
X10.sendCmd( hcA, 1, cmdOff );
Serial.println("A1  OFF");
break;
case 'b':
X10.sendCmd( hcA, 2, cmdOff );
Serial.println("A2 OFF");
break;
case 'c':
X10.sendCmd( hcA, 3, cmdOff );
Serial.println("A3 OFF");
break;
case 'd':
X10.sendCmd( hcA, 4, cmdOff );
Serial.println("A4 OFF");
break;
case 'e':
X10.sendCmd( hcA, 5, cmdOff );
Serial.println("A5 OFF");
break;
case 'f':
X10.sendCmd( hcA, 6, cmdOff );
Serial.println("A6 OFF");
break;
case 'g':
X10.sendCmd( hcA, 7, cmdOff );
Serial.println("A7 OFF");
break;
case 'h':
X10.sendCmd( hcA, 8, cmdOff );
Serial.println("A8 OFF");
break;
case 'i':
X10.sendCmd( hcA, 9, cmdOff );
Serial.println("A9 OFF");
break;
case 'j':
X10.sendCmd( hcA, 10, cmdOff );
Serial.println("A10 OFF");
break;
case 'k':
X10.sendCmd( hcA, 11, cmdOff );
Serial.println("A11 OFF");
break;
case 'l':
X10.sendCmd( hcA, 12, cmdOff );
Serial.println("A12 OFF");
break;
case 'm':
X10.sendCmd( hcA, 13, cmdOff );
Serial.println("A13 OFF");
break;
case 'n':
X10.sendCmd( hcA, 14, cmdOff );
Serial.println("A14 OFF");
break;
case 'o':
X10.sendCmd( hcA, 15, cmdOff );
Serial.println("A15 OFF");
break;
case 'p':
X10.sendCmd( hcA, 16, cmdOff );
Serial.println("A16 OFF");
break;
case '+':   //bright
X10.sendCmd( hcA, 1, cmdBright );
Serial.println("A BRIGHT OFF");
break;
case '-':    //dim
X10.sendCmd( hcA, 1, cmdDim );
Serial.println("A DIM OFF");
break;
case '0':
poweroff();
Serial.println("Sony Power Off");
break;
case '1':
poweron();
Serial.println("Sony Power On");
break;
case '2':
mute();
break;
case '3':
vid2();
break;
case '4':
tuner();
break;
case '5':
tunescandown();
break;
case '6':
tunescanup();
break;
case '7':
{
int z=0;
while (z < 6){
volup();
delay (50);
z++;
}
}
break;

case '8':
{
int y=0;
while (y < 6){
voldn();
delay (50);
y++;
}
}
break;

case '9':
CD();
break;

///for testing
case 'Q':
X10.sendCmd( hcB, 1, cmdOn);
digitalWrite(13, HIGH);
delay(500);
digitalWrite(13, LOW);
break;
case 'q':
X10.sendCmd( hcB, 1, cmdOff );
digitalWrite(13, HIGH);
delay(200);
digitalWrite(13, LOW);
delay(200);
digitalWrite(13, HIGH);
delay(200);
digitalWrite(13, LOW);
break;
}
}
}

/////////Functions For Sony Control S////////
/// Defining what logic "1" and logic "0" are
//////////////////////////
int L1(){   //Logic 1
//digitalWrite(cpin,LOW);
delayMicroseconds(600);//space
digitalWrite(cpin, HIGH);
delayMicroseconds(1200);
digitalWrite(cpin,LOW);
}

void L0 () { //Logic 0
//digitalWrite(cpin,LOW);
delayMicroseconds(600);//space
digitalWrite(cpin, HIGH);
delayMicroseconds(600);
digitalWrite(cpin, LOW);
}

void SB (){  //start bit transmit
digitalWrite(cpin,LOW);
delayMicroseconds(600);
digitalWrite(cpin, HIGH);
delayMicroseconds(2400);
digitalWrite(cpin, LOW);
}

////Control Functions
////  Send string

void tuneup  () { int x=0; while (x < 4){SB();L0();L0();L0();L0();L1();L0();L0();L0();L0();L0();L0();L1();delay (25);x++;}}
void tunedown () { int x=0; while (x < 4){SB();L1();L0();L0();L0();L1();L0();L0();L0();L0();L0();L0();L1();delay (25);x++;}}
void volup () { int x=0; while (x < 4){SB();L0();L1();L0();L0();L1();L0();L0();L0();L0();L0();L0();L1();delay (25);x++;}}
void voldn () { int x=0; while (x < 4){SB();L1();L1();L0();L0();L1();L0();L0();L0();L0();L0();L0();L1();delay (25);x++;}}
void power () { int x=0; while (x < 4){SB();L1();L0();L1();L0();L1();L0();L0();L0();L0();L0();L0();L1();delay (25);x++;}}
void poweron () { int x=0; while (x < 4){SB();L0();L1();L1();L1();L0();L1();L0();L0();L0();L0();L0();L1();delay (25);x++;}}
void poweroff () { int x=0; while (x < 4){SB();L1();L1();L1();L1();L0();L1();L0();L0();L0();L0();L0();L1();delay (25);x++;}}
void tv () { int x=0; while (x < 4){SB();L1();L0();L1();L1();L1();L0();L0();L0();L0();L0();L0();L1();delay (25);x++;}}
void vid2 () { int x=0; while (x < 4){SB();L0();L1();L1();L1();L1();L0();L0();L0();L0();L0();L0();L1();delay (25);x++;}}
void tuner () { int x=0; while (x < 4){SB();L1();L0();L0();L0();L0();L1();L0();L0();L0();L0();L0();L1();delay (25);x++;}}
void CD () { int x=0; while (x < 4){SB();L1();L0();L1();L0();L0();L1();L0();L0();L0();L0();L0();L1();delay (25);x++;}}
void mute () { int x=0; while (x < 4){SB();L0();L0();L1();L0();L1();L0();L0();L0();L0();L0();L0();L1();delay (25);x++;}}
void tunerpreset () { int x=0; while (x < 4){SB();L0();L1();L1();L0();L1();L0();L0();L0();L0();L0();L0();L1();delay (25);x++;}}
void tunescanup  () { int x=0; while (x < 4){SB();L0();L1();L0();L0();L1();L0();L0();L1();L0();L1();L1();L0();delay (25);x++;}}
void tunescandown  () { int x=0; while (x < 4){SB();L1();L1();L0();L0();L1();L0();L0();L1();L0();L1();L1();L0();delay (25);x++;}}

///FEEDBACk Function
void flash (){
int x;
while (x < 6){
digitalWrite(13,HIGH);
delay (100);
digitalWrite (13,LOW);
x++;
}
}
``````