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
 

Suggested Topics

  • 3
  • 5
  • 6
  • 2
  • 1
  • 8

0
Online

11.4k
Users

11.1k
Topics

112.7k
Posts