Programing Tascam BluRay over IP
BenDerzGreat
Posts: 19
Hey,
I took the programming 1 course but never covered IP programming, But i am getting requests from my job to program a Blu-Ray player over IP. I have tried using the help files and programming guidelines but I can't get the socket to open properly. I will post a copy of the code and attach a pdf of the control specs for the Blu-Ray player, any help would be appreciated.
DEFINE_DEVICE
dvBluRayTP = 10012:100:0; //port 100 on TP, BR controls
dvTascamIP = 0:2:0; // IP communication for Blu-ray player
(***********************************************************)
(* CONSTANT DEFINITIONS GO BELOW *)
(***********************************************************)
DEFINE_CONSTANT
volatile char TascamCMDS[][12]={
'!7PLYUP',
'!7STP',
'!7PAS',
'!7SKPUP',
'!7SKPDN',
'!7SCNUP',
'!7SCNDN',
'!7OSDLF'
};
(***********************************************************)
(* DATA TYPE DEFINITIONS GO BELOW *)
(***********************************************************)
DEFINE_TYPE
(***********************************************************)
(* VARIABLE DEFINITIONS GO BELOW *)
(***********************************************************)
DEFINE_VARIABLE
volatile integer nBluRayBtns[]={1,2,3,4,5,6,7};
volatile integer nBluRayFB;
(***********************************************************)
(* LATCHING DEFINITIONS GO BELOW *)
(***********************************************************)
DEFINE_LATCHING
(***********************************************************)
(* MUTUALLY EXCLUSIVE DEFINITIONS GO BELOW *)
(***********************************************************)
DEFINE_MUTUALLY_EXCLUSIVE
(***********************************************************)
(* SUBROUTINE/FUNCTION DEFINITIONS GO BELOW *)
(***********************************************************)
define_function fnBluRayFB()
{
stack_var integer nLoop;
for(nloop=1;nLoop<=3;nLoop++)
{
[dvBluRayTP,nLoop] = (nBluRayFB == nLoop);
}
}
(***********************************************************)
(* STARTUP CODE GOES BELOW *)
(***********************************************************)
DEFINE_START
ip_client_open(2,'10.3.19.3',60128,ip_tcp);
(***********************************************************)
(* THE EVENTS GO BELOW *)
(***********************************************************)
DEFINE_EVENT
data_event[dvTascamIP]
{
string:
{
local_var char sFromBluRay[12];
local_var char sStatus[5];
sFromBluRay = data.text;
sStatus = mid_string(sFromBluRay,3,5);
select
{
active(sStatus == 'SST01'):
{
nBluRayFB = 1;
}
active(sStatus == 'SST02'):
{
nBluRayFB = 3;
}
active(sStatus == 'SST03'):
{
nBluRayFB = 2;
}
}
fnBluRayFB();
}
}
button_event[dvBluRayTP,nBluRayBtns]
{
push:
{
send_string dvTascamIP,"TascamCMDS[get_last(nBluRayBtns)],$0D";
}
}
I took the programming 1 course but never covered IP programming, But i am getting requests from my job to program a Blu-Ray player over IP. I have tried using the help files and programming guidelines but I can't get the socket to open properly. I will post a copy of the code and attach a pdf of the control specs for the Blu-Ray player, any help would be appreciated.
DEFINE_DEVICE
dvBluRayTP = 10012:100:0; //port 100 on TP, BR controls
dvTascamIP = 0:2:0; // IP communication for Blu-ray player
(***********************************************************)
(* CONSTANT DEFINITIONS GO BELOW *)
(***********************************************************)
DEFINE_CONSTANT
volatile char TascamCMDS[][12]={
'!7PLYUP',
'!7STP',
'!7PAS',
'!7SKPUP',
'!7SKPDN',
'!7SCNUP',
'!7SCNDN',
'!7OSDLF'
};
(***********************************************************)
(* DATA TYPE DEFINITIONS GO BELOW *)
(***********************************************************)
DEFINE_TYPE
(***********************************************************)
(* VARIABLE DEFINITIONS GO BELOW *)
(***********************************************************)
DEFINE_VARIABLE
volatile integer nBluRayBtns[]={1,2,3,4,5,6,7};
volatile integer nBluRayFB;
(***********************************************************)
(* LATCHING DEFINITIONS GO BELOW *)
(***********************************************************)
DEFINE_LATCHING
(***********************************************************)
(* MUTUALLY EXCLUSIVE DEFINITIONS GO BELOW *)
(***********************************************************)
DEFINE_MUTUALLY_EXCLUSIVE
(***********************************************************)
(* SUBROUTINE/FUNCTION DEFINITIONS GO BELOW *)
(***********************************************************)
define_function fnBluRayFB()
{
stack_var integer nLoop;
for(nloop=1;nLoop<=3;nLoop++)
{
[dvBluRayTP,nLoop] = (nBluRayFB == nLoop);
}
}
(***********************************************************)
(* STARTUP CODE GOES BELOW *)
(***********************************************************)
DEFINE_START
ip_client_open(2,'10.3.19.3',60128,ip_tcp);
(***********************************************************)
(* THE EVENTS GO BELOW *)
(***********************************************************)
DEFINE_EVENT
data_event[dvTascamIP]
{
string:
{
local_var char sFromBluRay[12];
local_var char sStatus[5];
sFromBluRay = data.text;
sStatus = mid_string(sFromBluRay,3,5);
select
{
active(sStatus == 'SST01'):
{
nBluRayFB = 1;
}
active(sStatus == 'SST02'):
{
nBluRayFB = 3;
}
active(sStatus == 'SST03'):
{
nBluRayFB = 2;
}
}
fnBluRayFB();
}
}
button_event[dvBluRayTP,nBluRayBtns]
{
push:
{
send_string dvTascamIP,"TascamCMDS[get_last(nBluRayBtns)],$0D";
}
}
0
Comments
Track the online state of the connection and only call ip_client_open() if the connection has not been established.
Easy enough to add in a query for device status if there is a connection.
Why loop? If the connection is broken you will know since the offline event will run, or onerror. The only time you need the port open is when communicating, so if the zone is off, its just wasted events running for no reason. To my mind, you're better off moving your timeline code into the data_event code.
Code:
DEFINE_DEVICE
dvBluRayTP = 10012:100:0; // port 100 on TP, BR controls
dvTascamIP = 0:2:0; // IP communication for Blu-ray player
dvText = 10012:25:0; // text from tascam
(***********************************************************)
(* CONSTANT DEFINITIONS GO BELOW *)
(***********************************************************)
DEFINE_CONSTANT
volatile char TascamCMDS[][12]={
'!7PLYUP',
'!7STP',
'!7PAS',
'!7SKPUP',
'!7SKPDN',
'!7SCNUP',
'!7SCNDN'
};
long TL_BR_Connect = 30000
long TL_BR_Times[]={30000,30000,30000};
(***********************************************************)
(* DATA TYPE DEFINITIONS GO BELOW *)
(***********************************************************)
DEFINE_TYPE
(***********************************************************)
(* VARIABLE DEFINITIONS GO BELOW *)
(***********************************************************)
DEFINE_VARIABLE
volatile integer nBluRayBtns[]={1,2,3,4,5,6,7};
volatile integer nBluRayFB;
volatile integer nIsConnected;
(***********************************************************)
(* LATCHING DEFINITIONS GO BELOW *)
(***********************************************************)
DEFINE_LATCHING
(***********************************************************)
(* MUTUALLY EXCLUSIVE DEFINITIONS GO BELOW *)
(***********************************************************)
DEFINE_MUTUALLY_EXCLUSIVE
(***********************************************************)
(* SUBROUTINE/FUNCTION DEFINITIONS GO BELOW *)
(***********************************************************)
define_function fnBluRayFB()
{
stack_var integer nLoop;
for(nloop=1;nLoop<=3;nLoop++)
{
[dvBluRayTP,nLoop] = (nBluRayFB == nLoop);
}
}
(***********************************************************)
(* STARTUP CODE GOES BELOW *)
(***********************************************************)
DEFINE_START
timeline_create(TL_BR_Connect,TL_BR_Times,length_array(TL_BR_Times),timeline_relative,timeline_repeat)
ip_client_open(dvTascamIP.PORT,'10.3.19.3',60128,ip_tcp);
(***********************************************************)
(* THE EVENTS GO BELOW *)
(***********************************************************)
DEFINE_EVENT
data_event[dvTascamIP]
{
string:
{
local_var char sFromBluRay[12];
local_var char sStatus[5];
sFromBluRay = data.text;
sStatus = mid_string(sFromBluRay,3,5);
select
{
active(sStatus == 'SST01'):
{
nBluRayFB = 1;
}
active(sStatus == 'SST02'):
{
nBluRayFB = 3;
}
active(sStatus == 'SST03'):
{
nBluRayFB = 2;
}
}
fnBluRayFB();
}
}
button_event[dvBluRayTP,nBluRayBtns]
{
push:
{
send_string dvTascamIP,"TascamCMDS[get_last(nBluRayBtns)],$0D";
}
}
data_event[dvTascamIP]
{
online:
{
nIsConnected = TRUE;
}
offline:
{
nIsConnected = FALSE;
}
}
timeline_event[TL_BR_Connect]
{
if(nIsConnected == TRUE)
{
send_string dvTascamIP,"'!7?STST',$0D";
}
else
{
ip_client_open(dvTascamIP.PORT,'10.3.19.3',60128,ip_tcp);
}
}
data_event[dvTascamIP]
{
string:
{
local_var char sFromTascam[12];
sFromTascam = data.text;
send_command dvText,"sFromTascam"
}
}
This is a common misconception. That call does not return the next available. It returns a 3 which doesn?t increment up. But boy if it did work like that it would be cool. But your point is correct. I avoid ports 1 and 2
Are you saying you made a device like dv_My_IP_Port = 0:101:0???
I would not do that. even though you may or may not use that many IP ports the device will try and create them between ports 3~101. It's best practice to go sequentially starting at 3 and working your way up to keep processor resources sane. While the theoretical number of IP ports is something like 200-ish, I've found you kind of max out at around 20-25 active ports.
Since you're the one creating the ports in the first place it should not be a stretch to keep them sequential.
More than best practice, If I'm remembering class correctly, when you create ports above that, resources are allocated to all the ports beneath it. Can someone tell me if I'm right on this?
Exactly right.
I have gone to using the module since I couldnt get the straight ip communication to work.
I believe I have included the module properly and set up the online events to start the IP communications, but I am getting
"TascamDiscDevice: CommManager: handleSocketStatus: socket failed to connect"
i have an online data event to send the command of the IP and to reinit like the module interface document says.. is there something I am doing wrong?
True - just as long as the error codes are properly evaluated and reacted to correctly.
Paste the online code. Check out the device notes at the end of module API document as well as the example code provided in the module package for the correct implementation. Try pinging the DVD IP from the master - there is a ping command available from a terminal session into the master.
Subnet is required at the IP settings of the DVD and NX Master. It is not a parameter that is passed into the module.
Also, just as a heads-up, you are not completely free to choose the virtual device number for a Duet module: it has to be in the range 41000...42000. If you accidentally gave it a device number of, say, 33001, it won't work correctly.
Line 757 2018-02-27 (15:15:55):: TascamDiscDevice: CommManager: reconnect() called
Line 758 2018-02-27 (15:15:55):: TascamDiscDevice: CommManager: ipConnect called
Line 759 2018-02-27 (15:15:55):: TascamDiscDevice: CommManager: getProperty(final String key) called
Line 760 2018-02-27 (15:15:55):: TascamDiscDevice: CommManager: getProperty(IP_Address) = 10.3.18.28
Line 761 2018-02-27 (15:15:55):: TascamDiscDevice: CommManager: getProperty(final String key) called
Line 762 2018-02-27 (15:15:55):: TascamDiscDevice: CommManager: getProperty(Port) = 60128
Line 763 2018-02-27 (15:15:55):: TascamDiscDevice: CommManager: getProperty(final String key) called
Line 764 2018-02-27 (15:15:55):: TascamDiscDevice: CommManager: getProperty(IP_Buffer_Size) =
Line 765 2018-02-27 (15:15:55):: TascamDiscDevice: CommManager: connecting to 10.3.18.28:60128
Line 766 2018-02-27 (15:15:55):: TascamDiscDevice: CommManager: Socket connection to 10.3.18.28:60128
Line 767 2018-02-27 (15:15:57):: TascamDiscDevice: CommManager: handleSocketStatus(-2) called
Line 768 2018-02-27 (15:15:57):: TascamDiscDevice: TascamDiscDevice: handleOfflineEvent()
Line 769 2018-02-27 (15:15:57):: TascamDiscDevice: CommManager: handleOfflineEvent() called
Line 770 2018-02-27 (15:15:57):: TascamDiscDevice: CommManager: handleSocketStatus(-4) called
Line 771 2018-02-27 (15:15:57):: TascamDiscDevice: CommManager: handleSocketStatus: socket failed to connect
Line 772 2018-02-27 (15:15:57):: TascamDiscDevice: TascamDiscDevice: handleErrorEvent(-4)
Line 773 2018-02-27 (15:15:57):: TascamDiscDevice: CommManager: handleErrorEvent: socket failed to connect
Line 774 2018-02-27 (15:15:57):: TascamDiscDevice: CommManager: closing socket...
Line 775 2018-02-27 (15:15:57):: TascamDiscDevice: CommManager: handleOfflineEvent() called
https://packetsender.com/ works pretty well for this sort of thing too. The debug trace looks all good in terms of the module configuration if the IP address of the DVD is '10.3.18.28'. I'd be double checking all the networking settings at both ends as well.
So with no luck on opening the socket I have decided to use serial control. And got everything running right away with a serial connection. I will likely continue using serial, but I would still like to find out why the TCP control was not working. I have reached out to both AMX and Tascam to try and find a solution. Thinking it could relate to firmware or a problem with the module file. I haven't tried the dataviewer or packet sender yet but will probably try just to find the issue.
The only thing that I can see based on the log files is
Line 764 2018-02-27 (15:15:55):: TascamDiscDevice: CommManager: getProperty(IP_Buffer_Size) =
this line contains no information for the buffer size, not sure if thats enough to stop the socket from connecting but its all I have at this point. When I look at the java code for the module the default buffer size is set at 1024, which should be fine, but for some reason its not making it to the netlinx diagnostics alerts, and likely the device. If someone with more experience can advise I would appreciate it.
Thanks to everyone of all of there help and insight, great community!
Line 764 2018-02-27 (15:15:55):: TascamDiscDevice: CommManager: getProperty(IP_Buffer_Size) =
The size of the buffer may be being tracked in the Property object. It may also be a static value that has failed to been set correctly.
As it is in the Property object you have access to set or overwrite the value through the PROPERTY-IP_Buffer_Size,<someNumber> command to the virtual device - 1024 sounds about good as any other number.
The IP_Buffer_Size property is set through the Java code in the module itself, and cannot be set by the property command. I worked with AMX tech support and was unable to find a solution. I talked to Tascam support which was difficult because they say the don't support third party control only the hardware and the control document. I convinced them to have one of their engineers take a look at the issue, and the response I got back was that the device does not support TCP/IP control, despite having a labeled port and instructions in the control document, I have replied back to them to confirm that TCP/IP control is not supported and when I get a response I will post the results here.