Crestron Samsung Module - Modification Help
Hi all,
I am not a SIMPL+ wiz by any means. I discovered that the Crestron module for most Samsung TVs has a bug of sorts.
The Ex-Link protocol specifies for direct channel tuning, you take the major channel number and multiply by 4 and convert to hex, and that's byte 5. Minor channel is byte 6. Byte 4 is \x80 for DTV.
The SIMPL+ processor doesn't account for channel numbers higher than 63, where channel 64 * 4 = 256 -> \x100.
The correct way to handle this is to put the "1" in byte 4 so it is \x81. The remainder is byte 5 and minor is still byte 6.
All commands need a checksum.
Below is the SIMPL+ processor. Any ideas how to modify this to handle higher channel numbers?
/*******************************************************************************************
SIMPL+ Module Information
(Fill in comments below)
*******************************************************************************************/
/*
Dealer Name: Crestron Electronics, Inc.
System Name:
System Number:
Programmer: LP
Comments:
*/
/*******************************************************************************************
Compiler Directives
(Uncomment and declare compiler directives as needed)
*******************************************************************************************/
// #ENABLE_DYNAMIC
#SYMBOL_NAME "Samsung UN55ES8000 v1.0 Processor"
// #HINT ""
// #DEFINE_CONSTANT
// #CATEGORY ""
// #DEFAULT_VOLATILE
#PRINT_TO_TRACE
// #DIGITAL_EXPAND
// #ANALOG_SERIAL_EXPAND
// #OUTPUT_SHIFT
// #HELP_PDF_FILE ""
#DEFAULT_NONVOLATILE
#ENABLE_STACK_CHECKING
#ENABLE_TRACE
#HELP_BEGIN
To be used with the Samsung UN55ES8000 v1.0.umc module only.
Not to be used as a stand-alone module.
#HELP_END
/*******************************************************************************************
Include Libraries
(Uncomment and include additional libraries as needed)
*******************************************************************************************/
// #CRESTRON_LIBRARY ""
// #USER_LIBRARY ""
/*******************************************************************************************
DIGITAL, ANALOG and SERIAL INPUTS and OUTPUTS
(Uncomment and declare inputs and outputs as needed)
*******************************************************************************************/
ANALOG_INPUT Volume_Set_Value,
ThreeD_View_Point_Value,
ThreeD_Depth_Value;
DIGITAL_INPUT ATV, DTV, KP[13];
STRING_INPUT String_To_Send[10];
ANALOG_INPUT Current_Channel;
ANALOG_INPUT Current_Channel_Sub;
ANALOG_INPUT Current_Volume;
// BUFFER_INPUT
// DIGITAL_OUTPUT
// ANALOG_OUTPUT
STRING_OUTPUT Channel_Text, Volume_Text, To_Device;
/*******************************************************************************************
SOCKETS
(Uncomment and define socket definitions as needed)
*******************************************************************************************/
// TCP_CLIENT
// TCP_SERVER
// UDP_SOCKET
/*******************************************************************************************
Parameters
(Uncomment and declare parameters as needed)
*******************************************************************************************/
// INTEGER_PARAMETER
// SIGNED_INTEGER_PARAMETER
// LONG_INTEGER_PARAMETER
// SIGNED_LONG_INTEGER_PARAMETER
// STRING_PARAMETER
/*******************************************************************************************
Parameter Properties
(Uncomment and declare parameter properties as needed)
*******************************************************************************************/
/*
#BEGIN_PARAMETER_PROPERTIES parameter_variable, parameter_variable, ...
// propValidUnits = // unitString or unitDecimal|unitHex|unitPercent|unitCharacter|unitTime|unitTicks;
// propDefaultUnit = // unitString, unitDecimal, unitHex, unitPercent, unitCharacter, unitTime or unitTicks;
// propBounds = lower_bound , upper_bound;
// propDefaultValue = ; // or, propDefaultValue = "";
// propList = // { "value" , "label" } , { "value" , "label" } , ... ;
// propShortDescription = "status_bar_hint_text";
// #BEGIN_PROP_FULL_DESCRIPTION line_1... line_2... line_n #END_PROP_FULL_DESCRIPTION
// #BEGIN_PROP_NOTES line_1... line_2... line_n #END_PROP_NOTES
#END_PARAMETER_PROPERTIES
*/
/*******************************************************************************************
Structure Definitions
(Uncomment and define structure definitions as needed)
Note: Be sure to initialize all declared STRING variables as needed
For example, in Function Main: struct.myString = "";
*******************************************************************************************/
/*
STRUCTURE MyStruct1
{
};
MyStruct1 struct;
*/
/*******************************************************************************************
Global Variables
(Uncomment and declare global variables as needed)
Note: Be sure to initialize all declared STRING variables as needed
For example, in Function Main: myString = "";
*******************************************************************************************/
INTEGER iSemaphore, a, iCS, iEnableChange, iLoc;
INTEGER iMainChannel, iSubChannel;
// LONG_INTEGER
// SIGNED_INTEGER
// SIGNED_LONG_INTEGER
STRING sTemp[10], sVolumeTemp[50], sThreeDViewPointTemp[50], sThreeDDepthTemp[50], sChannelTemp[50];
STRING sNumber[11], sChannelCommand[13];
/*******************************************************************************************
Functions
(Add any additional functions here)
Note: Functions must be physically placed before the location in
the code that calls them.
*******************************************************************************************/
String_Function SendString(STRING StringSend)
{
INTEGER a, iCS;
STRING sStringFinal[50];
iCS = 0;
for(a = 1 to len(StringSend))
{
iCS = iCS + byte(StringSend, a);
}
iCS = (0x0100 - iCS);
sStringFinal = StringSend + chr(iCS);
Return (sStringFinal);
}
/*******************************************************************************************
Event Handlers
(Uncomment and declare additional event handlers as needed)
*******************************************************************************************/
CHANGE String_To_Send
{
iCS = 0;
if(iSemaphore = 0)
{
iSemaphore = 1;
sTemp = String_To_Send;
To_Device = SendString(sTemp);
iSemaphore = 0;
}
}
CHANGE Volume_Set_Value
{
if(iEnableChange = 1)
{
makestring(sVolumeTemp, "\x08\x22\x01\x00\x00%s", chr(Volume_Set_Value));
To_Device = SendString(sVolumeTemp);
makestring(Volume_Text, "%s", itoa(Volume_Set_Value));
}
}
CHANGE ThreeD_View_Point_Value
{
if(iEnableChange = 1)
{
makestring(sThreeDViewPointTemp, "\x08\x22\x0B\x0C\x02%s", chr(ThreeD_View_Point_Value));
To_Device = SendString(sThreeDViewPointTemp);
}
}
CHANGE ThreeD_Depth_Value
{
if(iEnableChange = 1)
{
makestring(sThreeDDepthTemp, "\x08\x22\x0B\x0C\x03%s", chr(ThreeD_Depth_Value));
To_Device = SendString(sThreeDDepthTemp);
}
}
PUSH KP // used to send channel number command
{
switch(getlastmodifiedarrayindex())
{
case(1):
makestring(sNumber, "%s0", sNumber);
case(2):
makestring(sNumber, "%s1", sNumber);
case(3):
makestring(sNumber, "%s2", sNumber);
case(4):
makestring(sNumber, "%s3", sNumber);
case(5):
makestring(sNumber, "%s4", sNumber);
case(6):
makestring(sNumber, "%s5", sNumber);
case(7):
makestring(sNumber, "%s6", sNumber);
case(8):
makestring(sNumber, "%s7", sNumber);
case(9):
makestring(sNumber, "%s8", sNumber);
case(10):
makestring(sNumber, "%s9", sNumber);
case(11): // dash
{
iLoc = find("-", sNumber);
if(iLoc = 0 && len(sNumber) > 0) // if a dash doesn't already exist and the number field has at least one number in it
{
makestring(sNumber, "%s-", sNumber); // append dash
}
}
case(12): // clear
{
clearbuffer(sNumber);
}
case(13): //
{
if(len(sNumber) > 0) // if number string exists
{
if(find("-", sNumber))
{
iMainChannel = atoi(left(sNumber, find("-", sNumber) - 1));
iSubChannel = atoi(right(sNumber, len(sNumber) - find("-", sNumber)));
if(ATV)
makestring(sChannelCommand, "\x08\x22\x04\x00\x00%s", chr(iMainChannel));
if(DTV)
makestring(sChannelCommand, "\x08\x22\x04\x80%s%s", chr(iMainChannel * 4), chr(iSubChannel));
}
else
{
iMainChannel = atoi(sNumber);
if(ATV)
makestring(sChannelCommand, "\x08\x22\x04\x00\x00%s", chr(iMainChannel));
if(DTV)
makestring(sChannelCommand, "\x08\x22\x04\x80%s\x00", chr(iMainChannel * 4));
}
To_Device = SendString(sChannelCommand);
clearbuffer(sNumber);
}
}
}
if(len(sNumber) > 0) // if number string exists
makestring(Channel_Text, "%s", sNumber); // send to text field
else // if not
makestring(Channel_Text, "\x20"); // clear text field
}
CHANGE Current_Channel
{
if(Current_Channel_Sub = 0)
makestring(Channel_Text, "%d", Current_Channel);
else
makestring(Channel_Text, "%d-%d", Current_Channel, Current_Channel_Sub);
}
CHANGE Current_Channel_Sub
{
if(Current_Channel_Sub = 0)
makestring(Channel_Text, "%d", Current_Channel);
else
makestring(Channel_Text, "%d-%d", Current_Channel, Current_Channel_Sub);
}
CHANGE Current_Volume
{
makestring(Volume_Text, "%d", Current_Volume);
}
/******************************************************************************************
Main()
Uncomment and place one-time startup code here
(This code will get called when the system starts up)
*******************************************************************************************/
Function Main()
{
iEnableChange = 0;
iSemaphore = 0;
wait(100)
{
iEnableChange = 1;
}
}
Posted Mar 12, 2018, 9:15 PM UTC · edited
21