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

  • ericmedley
    ericmedley Senior Member - 3709 Posts
    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.
  • jabramson
    jabramson Junior Member
    Got it, thanks
  • JasonS
    JasonS If I had known it was going to be that kind of party...
    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 Hebert
    Joe Hebert Junior Member
    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
    }
    
  • JasonS
    JasonS If I had known it was going to be that kind of party...
    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!
  • PhreaK
    PhreaK Senior Member
    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 Hebert
    Joe Hebert Junior Member
    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.