Home AMX User Forum AMX General Discussion

Programing Tascam BluRay over IP

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";
}
}

Comments

  • There's a Duet module on amx.com that supports both rs232 and IP control for the Tascam BD-01
  • Thanks, I have downloaded the Module and will use that to control..
  • If you want to try and roll your own - implement ip_client_open() in a infinitely lopping timeline (~30-second interval usually works well enough).
    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.

    data_event[dvTascamIP]
    {
      online:
      {
        bDvdIsConnected = TRUE;
      }
      offline:
     {
        bDvdIsConnected = FALSE;
      }
    }
    
    timeline_event[TL_DVD_CONNECT]
    {
      if(bDvdIsConnected == TRUE)
      {
        send_string dvTascamIP," '!7?STST' , $0D";  // Query Status
      }
      else
      {
        ip_client_open(dvTascamIP.PORT,'10.3.19.3',60128,ip_tcp);
      }
    }
    
    
  • Thanks for all the help, I will try the module for now, but will definitely want to get around to doing it myself for those devices that dont have modules.
  • a_riot42a_riot42 Posts: 1,624
    icraigie wrote: »
    If you want to try and roll your own - implement ip_client_open() in a infinitely lopping timeline (~30-second interval usually works well enough).
    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.

    data_event[dvTascamIP]
    {
    online:
    {
    bDvdIsConnected = TRUE;
    }
    offline:
    {
    bDvdIsConnected = FALSE;
    }
    }
    
    timeline_event[TL_DVD_CONNECT]
    {
    if(bDvdIsConnected == TRUE)
    {
    send_string dvTascamIP," '!7?STST' , $0D"; // Query Status
    }
    else
    {
    ip_client_open(dvTascamIP.PORT,'10.3.19.3',60128,ip_tcp);
    }
    }
    
    

    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.

    data_event[dvTascamIP]
    {
    online:
    {
      //  Parse incoming feedback.  If there are queued commands to send, send them now, since the port is online.
    }
    offline:
    {
      // port is offline.  If there are queued commands to send, open the port and they'll get sent when it comes online.
      //  If there are no commands to send, just leave it closed.
    }
    }
    
    
    
  • So, I decided to keep trying without the module. using the online/offline data events I can track the connection in debug, I am getting a true for the variable that its connected, but the device is still not responding to any commands. what is the best way to track the string output? I will include the updated code now

    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"
    }
    }


  • JasonSJasonS Posts: 229
    Your dvTascamIP port should be larger than 3. There is a system variable that returns the first available port, dont remember its name but it usually returns 3. I always use something larger. Not sure if this has changed with NX processors.
  • ericmedleyericmedley Posts: 4,177
    JasonS wrote: »
    Your dvTascamIP port should be larger than 3. There is a system variable that returns the first available port, dont remember its name but it usually returns 3. I always use something larger. Not sure if this has changed with NX processors.

    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
  • JasonSJasonS Posts: 229
    I forgot about that part [USER="1623"]ericmedley[/USER] I was excited when I first discovered it, it was going to very handy. But then it wasn't.
  • I've switched it to port 101, since i am using port 100 for my touch panel file. I am getting a true for my online event, so it seems like its making the connection. when I turn on device notifications i can see my button presses but no strings in or out. i made sure they were all enabled and device notifications are on, is there something im missing to help check my string output?
  • MLaletasMLaletas Posts: 226
    You will not get notifications on a IP socket. You will need to put the strings you are transmitting and receiving on the master or on a virtual device in order to see them.
  • ericmedleyericmedley Posts: 4,177
    I've switched it to port 101, since i am using port 100 for my touch panel file. I am getting a true for my online event, so it seems like its making the connection. when I turn on device notifications i can see my button presses but no strings in or out. i made sure they were all enabled and device notifications are on, is there something im missing to help check my string output?

    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.
  • ericmedley wrote: »

    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?

  • ericmedleyericmedley Posts: 4,177
    zack.boyd wrote: »

    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 always start my IP ports at 9; I throw away everything between 3-8, despite the resource usage, just so the port number doesn't conflict with any other 2-way communications ports in a typical 5001 device. That way I can use a reverse-lookup table based on the port ID, to map physical ports to logical device IDs. Of course that doesn't work so well now with so many devices that have their own Netlinx Device number, instead of talking on a port on either 0 or 5001.
  • Thanks for all the help and input so far guys..

    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?


  • a_riot42 wrote: »

    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.

    data_event[dvTascamIP]
    {
    online:
    {
    // Parse incoming feedback. If there are queued commands to send, send them now, since the port is online.
    }
    offline:
    {
    // port is offline. If there are queued commands to send, open the port and they'll get sent when it comes online.
    // If there are no commands to send, just leave it closed.
    }
    }
    
    
    

    True - just as long as the error codes are properly evaluated and reacted to correctly.
  • Thanks for all the help and input so far guys..

    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?


    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.
  • I now have actually loaded the example workspace from the module and UI file to a master and touch panel, i updated the IP and still cant get the socket to open. I will try opening a terminal session with the master now, the only other thing I can think of is that it may need the subnet?
  • I now have actually loaded the example workspace from the module and UI file to a master and touch panel, i updated the IP and still cant get the socket to open. I will try opening a terminal session with the master now, the only other thing I can think of is that it may need the subnet?

    Subnet is required at the IP settings of the DVD and NX Master. It is not a parameter that is passed into the module.

  • I can ping the Tascam from the master in terminal, but when i do show TCP command the connection isnt there.. i pulled up the logs and see all the socket errors. I also see Cip events for a DPS of 32001:1:1
  • Assuming you use the AMX Duet module for the BD player, try setting the module to 'DEBUG-4' (use 'control a device' to send that to your virtual device) and watch 'diagnostics' to see if that helps.
    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.
  • I was able to send the 'DEBUG-4' command through the terminal. I am getting a little more in the logs now but still not seeing exactly why the socket won't open it has the IP and port information right. it just keeps repeating this process.



    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
  • You could use something like Extron's 'dataviewer' to connect to the BD player from your computer directly and see if that works. Just bypass anything AMX as a check.
  • You could use something like Extron's 'dataviewer' to connect to the BD player from your computer directly and see if that works. Just bypass anything AMX as a check.

    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.
  • UPDATE

    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!
  • Not having immediate access to the code or a Tascam not sure on this message:

    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.
  • UPDATE

    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.
Sign In or Register to comment.