Home AMX User Forum NetLinx Studio

Help with NEC Command/Response

This is a command to get the "Running Sense" on a NEC projector
Command: 00H 81H 00H 00H 00H 81H

Response: At the time of a success 20H 81H 01H xxH 01H DATA01 CKS

Data Portion Contents ----------------------------------------------------------- -------- DATA01	Status of operation
Bit 7: Power On/Off processing 0 = No execution (Normal condition) 1 = During execution
Bit 6: Selecting signal processing 0 = No execution (Normal condition) 1 = During execution
Bit 5: Cooling processing 0 = No execution (Normal condition) 1 = During execution
Bit 4: External control mode 0 = OFF 1 = ON
Bit 3: No Power-Off period 0 = Power-Off Possible (Normal condition) 1 = Power-Off Impossible
Bit 2: Reserved
Bit 1: Projector status 0 = Idling 1 = Power On Bit 0: Reserved

I don't understand the bits for DATA01. Do these somehow get added together for the total?

These are my responses
Projector off: $20,$81$01$10$01$00$B3
Projector on: $20,$81$01$10$01$02$B5

I don't understand how the "bits" are put together for the 6th value in the return string.

Thanks

Comments

  • ericmedleyericmedley Posts: 4,177
    Think of it in terms of it being a binary number

    Off message data byte is
    00000000 which is represented as $00

    On message is
    00000010 which is $02 in hex.

    I'd guess that the cooling message might look like
    00010000 which would be $10 in hex.
  • jabramsonjabramson Posts: 106
    Got it, thanks
  • JasonSJasonS Posts: 229
    Bit masks are the way to get individual bit values of a byte or word. So if you were interested in the state of the cooling bit and none of the ohers, you would do a bitwise and (&) of Data01 with $10.

    01111010 - random value for Data01
    00010000 - $10
    00010000 - result of bitwise and

    when you do the bitwise and only the bits that are 1 in the mask and Data01 are 1 in the result. It is then easiest to treat your result as a boolean value. Here are the functions that I use when I need to check or set the state of a bit in a CHAR.
    DEFINE_CONSTANT
    //SET_cBit_State() & GET_cBit_State() Functions Constants
    CHAR cBitMasks[] = {$01, $02, $04, $08, $10, $20, $40, $80}
    
    DEFINE_FUNCTION INTEGER GET_cBit_State(CHAR Byte, INTEGER Passed_Bit, INTEGER Bit_Zero)
    {
        STACK_VAR CHAR bytResult
        STACK_VAR INTEGER iBit
        iBit = Passed_Bit
        IF (Bit_Zero)
        {
    	iBit = iBit + 1
        }
        IF (iBit > 0 AND iBit <= 8)
        {
    	bytResult = Byte BAND cBitMasks[iBit]
    	IF (bytResult > 0)
    	{
    	    RETURN TRUE
    	}
        }
        RETURN FALSE
    }
    
    DEFINE_FUNCTION SET_cBit_State(CHAR Byte, INTEGER Passed_Bit, INTEGER State, INTEGER Bit_Zero)
    {
        STACK_VAR INTEGER iBit
        STACK_VAR CHAR InvBitMask
        
        iBit = Passed_Bit
        IF (Bit_Zero)
        {
    	iBit = iBit + 1
        }
        IF (iBit > 0 AND iBit <= 8)
        {
    	IF (State)
    	{
    	    IF (!GET_cBit_State(Byte, Passed_Bit, Bit_Zero))
    	    {
    		Byte = Byte + cBitMasks[iBit]
    	    }
    	}
    	ELSE
    	{
    	    IF (GET_cBit_State(Byte, Passed_Bit, Bit_Zero))
    	    {
    		Byte = Byte - cBitMasks[iBit]
    	    }
    	}
        }
    }
    

    Set Bit_Zero to true if you are using 0-7 to identify your bits intstead of 1-8.
  • Joe HebertJoe Hebert Posts: 2,159
    Shifting gears

    Another option is this 1 line function to check bits 0-15 using bit shifting to create the mask:
    DEFINE_FUNCTION CHAR isBitSet (integer number, char bit) {
         RETURN number & (1<<bit) = 1<<bit
    }
    
  • JasonSJasonS Posts: 229
    Joe Hebert wrote: »
    Another option is this 1 line function to check bits 0-15 using bit shifting to create the mask:
    DEFINE_FUNCTION CHAR isBitSet (integer number, char bit) {
         RETURN number & (1<<bit) = 1<<bit
    }
    

    Nice!


    Stupid 10 character minimum to post!
  • PhreaKPhreaK Posts: 966
    As it's only a single byte that you're checking you could drop that back to a char. You can also remove the equivalency check as anything non-zero will evaluate to true.
    define_function char isBitSet(char number, char bit) {
         return number & (1<<bit)
    }
    

    A super common way to do this though is just set up some constants for the different bit masks that your protocol uses:
    define_variable
    
    // bit masks for NEC projector status
    constant char PROJ_POWER = $2
    constant char PROJ_AUTO_OFF = $8
    constant char PROJ_EXT_CONTROL = $10
    constant char PROJ_COOLING = $20
    ...
    

    You can then just grab your DATA01 byte (after verifying the checksum), lets call this 'projectorStatus' then check status in a nice readable way.
    projector.isOn = projectorStatus & PROJ_POWER
    projector.autoOff = projectorStatus & PROJ_AUTO_OFF
    ...
    
  • Joe HebertJoe Hebert Posts: 2,159
    PhreaK wrote:
    As it's only a single byte that you're checking you could drop that back to a char.

    As stated above the generic function checks bits 0-15 which is why it it’s an integer but if you want to limit the function to only be capable of checking bits 0-7 then that’s the way to do it.
    PhreaK wrote:
    You can also remove the equivalency check as anything non-zero will evaluate to true.

    Doing so changes the RETURN value. The function is intended to RETURN a 0 (false) if the bit is not set and RETURN a 1 (true) if the bit is set. The function will not do that with your modification. You’ll also need to deal with the warning when you compile it.
Sign In or Register to comment.