Home AMX User Forum AMX General Discussion

Russound MCA-66 on RS-232 with RIO

Hi!

Trying to set-up a Russound multi-room audio controller with RS-232.

The issues is that Russound will not react to any commands on Serial connection, while they look correct and will not send any feedback.
However, MCA-66 does send data after reboot which looks like this:
Line     17 (16:44:26):: String From [5001:1:1]-[$F0$00$10u$00$00$7F$00$04$06$05$01$00$08$07$00$06$00$06$05$01$00$00$00$01$00$01$00$00D$F7$F0$00 u$00$00$7F$00$04$06$05$01$00$08$07$00$06$01$06$05$01$00$00$00$01$00$01$00$00U$F7]
Line     18 (16:44:27):: String From [5001:1:1]-[$F0$00$10u$00$00$7F$00$04$06$05$01$00$08$07$00$06$00$06$05$01$00$00$00$01$00$01$00$00D$F7$F0$00 u$00$00$7F$00$04$06$05$01$00$08$07$00$06$01$06$05$01$00$00$00$01$00$01$00$00U$F7]
Line     19 (16:44:29):: String From [5001:1:1]-[$F0$00$10u$00$00$7F$00$04$06$05$01$00$08$07$00$06$00$06$05$01$00$00$00$01$00$01$00$00D$F7$F0$00 u$00$00$7F$00$04$06$05$01$00$08$07$00$06$01$06$05$01$00$00$00$01$00$01$00$00U$F7$F0$00]
Line     20 (16:44:29):: String From [5001:1:1]-[$10u$00$00$7F$00$04$06$05$01$00$08$07$00$06$00$06$05$01$00$00$00$01$00$01$00$00D$F7$F0$00 u$00$00$7F$00$04$06$05$01$00$08$07$00$06$01$06$05$01$00$00$00$01$00$01$00$00U$F7$F0}$00$7F]
Line     21 (16:44:29):: String From [5001:1:1]-[$00$00$7F$05$02$01$00$02$01$00U$01Q$00$02$00$015$F7$F0$7F$00$00$00$00$7F$00$03$06$02$06$00$00$00$01$00$01$00$00$15$F7$F0$7F$00$00$00$00$7F$00$03$04$04$03$02$0B$01$00$00$01$00$01$00$00"]
Line     22 (16:44:29):: String From [5001:1:1]-[$F7]
Line     23 (16:44:29):: String From [5001:1:1]-[$F0}$00$7F$00$00$7F$05$02$01$00$02$01$00f$01$00$00$EB$03$01a$F7]
Line     24 (16:44:39):: String From [5001:1:1]-[$F0}$00$7F$00$00$7F$05$02$01$00$02$01$00f$01$00$00$EC$03$01b$F7]
Line     25 (16:45:39):: String From [5001:1:1]-[$F0}$00$7F$00$00$7F$05$02$01$00$02$01$00f$01$00$00$ED$03$01c$F7]

These strings do look like the former RNET protocol, but I'm pretty sure the length is wrong.
Could that be a fault in Russound itself OR a problem with cabling?

Comments

  • ericmedleyericmedley Posts: 4,177
    I kinda wonder if you might have the baud rate set incorrectly. It kind of looks like garbage data due to bad timing. I'd need to look at some old Russound code to confirm but the lengths do not look right. You might check the baud on both the device and your port. Silly, but it might be worth a try.
  • Nope, the BAUD rates were checked over 900 times to be honest.
    The issue was found - simple as $0D not being sent and Russound going mad...
  • Now I am trying to get an idea of how to get 255 levels of the keypad to match russound 50 levels of volume :D
  • DaniilK wrote: »
    Now I am trying to get an idea of how to get 255 levels of the keypad to match russound 50 levels of volume :D
    Either math, or a value library, or a little bit of both?
  • ericmedleyericmedley Posts: 4,177
    DaniilK wrote: »
    Now I am trying to get an idea of how to get 255 levels of the keypad to match russound 50 levels of volume :D


    AMX Leve​l=(Level*51)/10
  • ericmedley wrote: »


    AMX Leve​l=(Level*51)/10
    uhm, the other way actually.
    I have Massio keypads with their level knobs. The knob returns 0-255, while russound accepts 0-50. It works OK if I use a button_event on that knob, but with known rotation speed limits. I'd rather use a level_event for volume control.
  • Either math, or a value library, or a little bit of both?
    yea, division w/o remainder would be nice. not too precise, but perfect for the situation. But I'm not sure AMX can do that(i'm more of a Python dude and it's pretty simple there)
  • ericmedleyericmedley Posts: 4,177
    DaniilK wrote: »
    uhm, the other way actually.
    I have Massio keypads with their level knobs. The knob returns 0-255, while russound accepts 0-50. It works OK if I use a button_event on that knob, but with known rotation speed limits. I'd rather use a level_event for volume control.


    okay.. I will do the algebra for you. that's

    Device level = (AMX level * 10) / 51

    Using the level is an okay thing to do but you do have to know and understand the behaviors and tolerances of the devices in play.

    For example: the keypad might possibly generate many level_events from just one spin of the knob. The AMX processor is probably well able to handle so many events in such a short span of time. However, you might overrun the rs232 buffer if you try to send a whole series of send_string messages based upon the level_evnts that a single spin could generate.

    In addition, the Russound might not like being banged on that much as well. (I find this to be the case most the time: the device needs a bit of a breather between messages.)

    An easy way to deal with this is to either build a queue for your outgoing messages that will stack all the messages up but send them out at a nice controlled pace, or build a bit of logic that looks for bursts of level_events and just ignores the first ones and only sends out the last of the bunch. The end result for the user will be fairly unseen as it can all happen with millisecond or even 10th of a second delay. Mere humans won't be bothered by that.

    I tend to queue all my rs232 stuff because I've already built the code to do it and don't need to re-write it. It works just fine for simple one-shot commands but saves a lot of heartache when things get chatty. The second method might be easier to write right in the level_event itself but I'm not a fan of one-shot code when avoidable. That's just me...
  • ericmedley wrote: »


    okay.. I will do the algebra for you. that's

    Device level = (AMX level * 10) / 51

    Using the level is an okay thing to do but you do have to know and understand the behaviors and tolerances of the devices in play.

    For example: the keypad might possibly generate many level_events from just one spin of the knob. The AMX processor is probably well able to handle so many events in such a short span of time. However, you might overrun the rs232 buffer if you try to send a whole series of send_string messages based upon the level_evnts that a single spin could generate.

    In addition, the Russound might not like being banged on that much as well. (I find this to be the case most the time: the device needs a bit of a breather between messages.)

    An easy way to deal with this is to either build a queue for your outgoing messages that will stack all the messages up but send them out at a nice controlled pace, or build a bit of logic that looks for bursts of level_events and just ignores the first ones and only sends out the last of the bunch. The end result for the user will be fairly unseen as it can all happen with millisecond or even 10th of a second delay. Mere humans won't be bothered by that.

    I tend to queue all my rs232 stuff because I've already built the code to do it and don't need to re-write it. It works just fine for simple one-shot commands but saves a lot of heartache when things get chatty. The second method might be easier to write right in the level_event itself but I'm not a fan of one-shot code when avoidable. That's just me...
    Hmm, I had a brave new idea of trying something like
    if keypad.level mod 5 = 0 send.string
    
    which will allow me to use only exact numbers which russound is happy with and NOT overflow the buffer. However, this depends on how accurate the keypad is - does it send a level event for exactly EACH knob turn despite the rotation speed/etc?
  • You will laugh, but I ended up with this piece of code for MCA-66 volume levels:
    LEVEL_EVENT [dvKP1, 2]
    {
    IF (level.value % 5 = 0)
        {
        IF (kp1LVL <= level.value)
        {
        SEND_STRING dvMCA66, "'EVENT C[1].Z[3]!KeyPress VolumeUp', $0D"
        SEND_LEVEL dvKP1, 1, level.value
        kp1LVL = level.value
        }
        ELSE
        {
        SEND_STRING dvMCA66, "'EVENT C[1].Z[3]!KeyPress VolumeDown', $0D"
        SEND_LEVEL dvKP1, 1, level.value
        kp1LVL = level.value
        }
        }
    }
    
    just because I can not use a variable on volume level - SEND_STRING command converts any variable to HEX instead of ASCII. Any ideas how to TURN THIS CONVERSION OFF? :D
  • John NagyJohn Nagy Posts: 1,734
    Because audio intensity isn't linear, nor are many device's output, we prefer to make a custom value lookup table in data. So across the 100 percentage steps, we can assign each a specific command level to the device. Lets you jump quickly into the audible range at the low level, make a nice "standard" volume at 50%, and contour the upper end for best "feel". Yes, some adjacent percentage volumes will have the same output number. And to make the volume feel more responsive when there are fewer output steps, consider incrementing volume by perhaps 2 or 3 percent each touch.

    This approach also makes for more universal code, so if you trade out the volume device at some point, you don't rewrite code, just update the table if needed.
  • Not sure if I understand what you say, but SEND_STRING doesn't convert anything to hex. What exactly are you trying to do and where does it go wrong?

    If you want to send an ASCII representatation of some numeric value, you have to convert it. Something like:
    SEND_STRING dvMCA66, "'VolumeLevel:', ITOA(nVolumeLevel), $0D"
    

    of course I made up the command, don't know anything about the MCA66
  • Not sure if I understand what you say, but SEND_STRING doesn't convert anything to hex. What exactly are you trying to do and where does it go wrong?

    If you want to send an ASCII representatation of some numeric value, you have to convert it. Something like:
    SEND_STRING dvMCA66, "'VolumeLevel:', ITOA(nVolumeLevel), $0D"
    

    of course I made up the command, don't know anything about the MCA66
    Hmm,
    SEND_STRING dvMCA66 "'EVENT C[1].Z[3]!KeyPress Volume ', z1Vol, $0D"
    
    is what I am sending where z1Vol is a division of 5 for level.value on keypad.
    But in the output log I see a string of
    EVENT C[1].Z[3]!KeyPress Volume $18$0D
    
    for an occasion of 24 in the variable for example.

    Will check the ITOA function right off.

    EDIT: The ITOA works like a charm - specifically the function that was needed. THANK YOU
    EDIT 2 : For other people who will ran in to the MCA66 - here's the simple code I am using. It controls the volume level pretty darn smooth
    LEVEL_EVENT [dvKeypad, 2]
    {
    IF (level.value % 5 = 0) //we have 255 level on keypad and 50 levels on MCA66, check if they match
        {
        z3Vol = level.value / 5 //make a volume variable for MCA66
        SEND_STRING dvMCA66, "'EVENT C[1].Z[3]!KeyPress Volume ', ITOA(z3Vol), $0D" //command to change volume. 
        SEND_LEVEL dvKeypad, 1, level.value
        keyapd1LVL = level.value //save the level value last used in-case of desync, power outage, etc.
        }
    }
    
  • ericmedleyericmedley Posts: 4,177
    That's because...
    This:
     SEND_STRING dvMCA66 "'EVENT C[1].Z[3]!KeyPress Volume ', z1Vol, $0D"
    
    needs to be this:

    SEND_STRING dvMCA66 "'EVENT C[1].Z[3]!KeyPress Volume ', itoa(z1Vol), $0D"
    if you wanted it to read "18" from your example.
Sign In or Register to comment.