Home AMX User Forum AMX Technical Discussion
Options

Output decimal number as Binary on a relay card.

Just leaving this here. Got most of it from another thread, so thanks.
DEFINE_CALL'DECIMAL_TO_RELAY_CARD'(DEV rly, INTEGER iDecimalNumber){
//convert a decimal number into it's binary representation on a relay card
    LOCAL_VAR INTEGER itmp64

    FOR(itmp64 = 1; itmp64 <=8; itmp64++){
	[rly,itmp64] = iDecimalNumber & REL_MASKS[itmp64]
    }
}
DEFINE_CONSTANT
INTEGER REL_MASKS[8] = {1,2,4,8,16,32,64,128}

I don't like the variable/param/function names, but naming stuff is like the hardest part of programming.

Comments

  • Options
    DarksideDarkside Posts: 345
    Here's quite a simple way of performing binary representation on a rel card.
    define_function fnDec2bin(integer decimalnum)
      {
      if (decimalnum & 1) on[dvRelay,1]
      if (decimalnum & 2) on[dvRelay,2]
      if (decimalnum & 4) on[dvRelay,3]
      if (decimalnum & 8) on[dvRelay,4]
      if (decimalnum & 16) on[dvRelay,5]
      if (decimalnum & 32) on[dvRelay,6]
      if (decimalnum & 64) on[dvRelay,7]
      if (decimalnum & 128) on[dvRelay,8]
      }
    

    Easily modified to make a binary clock in your card cage to impress even the most 1/0 savvy client :)
  • Options
    BigsquatchBigsquatch Posts: 216
    And bit masking can be used when the number of parameters passed to a function will vary.
    DEFINE_CONSTANT
    
    INTEGER RELAY_NONE = 0
    INTEGER RELAY_1 = 1
    INTEGER RELAY_2 = 2
    INTEGER RELAY_3 = 4
    INTEGER RELAY_4 = 8
    INTEGER RELAY_5 = 16
    INTEGER RELAY_6 = 32
    INTEGER RELAY_7 = 64
    INTEGER RELAY_8 = 128
    
    DEFINE_FUNCTION fnRelayOn(INTEGER decimalNum)
    {
      [dvRelay,1] = (decimalnum & 1)
      [dvRelay,2] = (decimalnum & 2)
      [dvRelay,3] = (decimalnum & 4)
      [dvRelay,4] = (decimalnum & 8)
      [dvRelay,5] = (decimalnum & 16)
      [dvRelay,6] = (decimalnum & 32)
      [dvRelay,7] = (decimalnum & 64) 
      [dvRelay,8] = (decimalnum & 128)
    } 
    
    DEFINE_START
    
    // Turn on relays 1, 3, 5 & 7 
    fnRelayOn(RELAY_1 | RELAY_3 | RELAY_5 | RELAY_7)
    
    // Turn off all relays
    WAIT 50 { fnRelayOn(RELAY_NONE) }
    
    // Turn on relays 2 & 4
    WAIT 60 { fnRelayOn(RELAY_2 | RELAY_4) }
    
    

    This technique gets a lot of use in the Windows API for passing window flags into API functions, allowing users to pass in any combination of the pre-defined flags.
  • Options
    travistravis Posts: 180
    Bigsquatch wrote: »
    fnRelayOn(RELAY_1 | RELAY_3 | RELAY_5 | RELAY_7)
    

    Oh nice. Maybe I can use this elsewhere...
  • Options
    PhreaKPhreaK Posts: 966
    When I read the title of this post my first though was 'why the hell would anyone want to pulse out a value on a relay'. Using the eight to represent the byte didn't even cross my mind - I am so building a clock with one of the spare NI's in the office.

    Personally I prefer your initial version using the lookup table, its simple and neat. Also, as you only have 8 relays to play with (assuming you're talking about the internal ones) this limits you to a single byte rather than an integer.
    define_variable
    
    constant char RELAY[] = { $1, $2, $4, $8, $10, $20, $40, $80 }
    
    define_function setRelayState(char mask) {
    	stack_var char num
    	for (num = 8; num; num--) {
    		[dvRelay, num] = mask & RELAY[num]
    	}
    }
    

    If you're just wanting to represent values and don't care about the convenience of the flag pattern shown by Bigsquatch you can do away with the table altogether:
    define_function representValue(char x) {
    	stack_var char num
    	for (num = 8; num; num--) {
    		[dvRelay, num] = x & (1 << (num - 1))
    	}
    }
    

    Alternatively, if you needed to represent an integer you could do so using both the relays and io's:
    define_function showValue(integer x) {
    	stack_var char num
    	stack_var char mask
    	for (num = 8; num; num--) {
    		mask = 1 << (num - 1)
    		[dvRelay, num] = (x >> 8) & mask
    		[dvIO, num] = (x & $FF) & mask
    	}
    }
    

    </procrastination>
  • Options
    ericmedleyericmedley Posts: 4,177
    Using an NI could gve you two bytes using the relays and the IOs. Also, with the right IR file an on would give you a solid LED on or off too for a fraud total of 3 bytes. Add to this using the serial ports for AM/PM and alarm enable/disable, you could build a nice alarm clock. You cold buzz some relays for a wake up buzzer. The only lingering issue is how to turn the darn thing off. (I guess pull the plug or wire a switch to an IO)
  • Options
    travistravis Posts: 180
    PhreaK wrote: »

    If you're just wanting to represent values and do care about the convenience of the flag pattern shown by Bigsquatch you can do away with the table altogether:
    define_function representValue(char x) {
    	stack_var char num
    	for (num = 8; num; num--) {
    		[dvRelay, num] = x & (1 << (num - 1))
    	}
    }
    

    </procrastination>
    Job-security version.
    I have a pair of these new-fangled EXB-REL8's at the moment to procrastinate with. Actually, this is for a project. I don't know what you all's excuses are.
Sign In or Register to comment.