How to convert received messages to integers? (MQTT)



  • Hi,

    I'm puzzled how message receive happens. I am building a infrared transmitter. I decoded the NEC signals from original remote, they look like this (hex): 0xF7C03F. This is power on command.

    Now I want to send those signals over MQTT, which mysgw transfers over NRF24L01+ to arduino. But how to convert messages so that they look alike at both ends? is that number too big to send (3 bytes)?

    As I send that exact command from arduino:

    #define CMD_ON        0xF7C03F
    ...
    send(msg_ir.set(CMD_ON));
    

    it looks like this on MQTT looking from mosquitto_sub:
    MySensorsGW/out/7/1/1/0/32 16236607

    When I send that back:
    mosquitto_pub -h droidcam.ikenet -p 1883 -t MySensorsGW/in/7/1/1/0/32 -m 16236607

    the code:

    uint32_t ircode;
    ircode = atoi( message.data );
    ...
            Serial.print( "V_IR_SEND data invalid: " );
            Serial.print( message.data );
            Serial.print( ", ircode: " );
            Serial.println( ircode );
    

    prints it out like this:
    V_IR_SEND data invalid: 16236607, ircode: 4294950975

    the numbers don't match. 16236607 is not the original CMD_ON code.

    This is the receive function:

    // IR remote command codes
    #define CMD_BRIGHTER  0xF700FF
    #define CMD_DIMMER    0xF7807F
    #define CMD_OFF       0xF740BF
    #define CMD_ON        0xF7C03F
    #define CMD_FLASH     0xF7D02F
    #define CMD_STROBE    0xF7F00F
    #define CMD_FADE      0xF7C837
    #define CMD_SMOOTH    0xF7E817
    #define CMD_RED       0xF720DF
    #define CMD_RED1      0xF710EF
    #define CMD_RED2      0xF730CF
    #define CMD_RED3      0xF708F7
    #define CMD_RED4      0xF728D7
    #define CMD_GREEN     0xF7A05F
    #define CMD_GREEN1    0xF7906F
    #define CMD_GREEN2    0xF7B04F
    #define CMD_GREEN3    0xF78877
    #define CMD_GREEN4    0xF7A857
    #define CMD_BLUE1     0xF7609F
    #define CMD_BLUE      0xF750AF
    #define CMD_BLUE2     0xF7708F
    #define CMD_BLUE3     0xF748B7
    #define CMD_BLUE4     0xF76897
    
    void receive(const MyMessage &message)
    {
      uint32_t ircode;
      Serial.print( "Received something of type: " );
      Serial.println( message.type );
    
    	if (message.type == V_IR_SEND) {
    		Serial.println( "V_IR_SEND command received..." );
    
    		ircode = atoi( message.data );
        //ircode = message.data;
        switch (ircode) {
          case CMD_BRIGHTER:
          case CMD_DIMMER:
          case CMD_OFF:
          case CMD_ON:
          case CMD_FLASH:
          case CMD_STROBE:
          case CMD_FADE:
          case CMD_SMOOTH:
          case CMD_RED:
          case CMD_RED1:
          case CMD_RED2:
          case CMD_RED3:
          case CMD_RED4:
          case CMD_GREEN:
          case CMD_GREEN1:
          case CMD_GREEN2:
          case CMD_GREEN3:
          case CMD_GREEN4:
          case CMD_BLUE1:
          case CMD_BLUE:
          case CMD_BLUE2:
          case CMD_BLUE3:
          case CMD_BLUE4:
          {
            Serial.print( "V_IR_SEND code received: ");
            Serial.println( message.data );
            send_ircode(ircode);
            ack_ir_to_controller(ircode);
            break;
          }
          default:
          {
            Serial.print( "V_IR_SEND data invalid: " );
            Serial.print( message.data );
            Serial.print( ", ircode: " );
            Serial.println( ircode );
    			  return;
    		   }
        }
      }
      for (int i=0; i<5; i++) {
        digitalWrite(LED_PIN, HIGH);
        wait(100);
        digitalWrite(LED_PIN, LOW);
        wait(100);
      }
    }
    

    I suppose it has to do with data length and auto conversion of variables. It perhaps worked if I use smaller numbers to set the IR code value. But however, I'd like to understand how this is supposed to work?

    BR,
    -ikke

    PS, this is IR controlled LED light bulb from LIDL, and commands do work with the given codes.


  • Admin

    #define CMD_ON 0xF7C03F

    It might help if you add a L to indicate long on the defines.

    Like this
    #define CMD_ON 0xF7C03FL



  • Thanks, now it looks different, doesn't still work though. Perhaps the atoi doesn't do longs properly?

    Received something of type: 32
    V_IR_SEND command received...
    V_IR_SEND data invalid: 16236607, ircode: 4294950975
    

    that turns out to be:

    echo "obase=16;4294950975"|bc
    FFFFC03F
    

    How does it come up with that? Need to hurry to work now, later...



  • The point in the above is, the Serial.print converts it correct, the atoi doesn't.


  • Hero Member

    @ikkeT
    The ato.. functions are very basic and do only what they are supposed to do:

    • atoi parses to int
    • atof parses to float
    • atol parses to long

    You can also consider the str.... functions (e.g. strtoul()) as a more robust alternative.

    Replacing the defines by const will help with type checking.
    i.e. replace #define CMD_BLUE4 0xF76897ul (you can add UL to indicate a constant is unsigned long which can hold 4 bytes 0xFFFFFFFF) with const unsigned long CMD_BLUE4 = 0xF76897ul ;



  • Excellent, thank you. It's too long since I've done serious coding, I didn't remember that. atoi -> atol fixed it.


Log in to reply
 

1.0k
Online

6.9k
Users

7.8k
Topics

82.9k
Posts

Looks like your connection to MySensors Forum was lost, please wait while we try to reconnect.