Receiving Hex codes.....will this work?



  • I have a need to send hex codes to a node which then need to be sent via IR emitter attached to the node.
    MyController can send strings, so I wondered if it would be possible to send a string like $"0xDA32FC41" and send via ir like this.....

     receive(const MyMessage &message){        
       if (message.type == V_IR_SEND)
       {
        String code = message.getString()
         irsend.sendNEC(code, 32);
       }
    

    Can anyone see if this would work or have I misunderstood something?

    Thanks!



  • What I posted will not work, so here is the new code in full.....It compiles, but that doesn't mean it will do what I expect!

    My aim is to remove most of the hex code #define statements and have those hex values sent in the button payload of mysensors custom button JSON setup.
    This will save memory on the arduino.

    /*
       Based on IRsendDemo Copyright 2009 Ken Shirriff
       http://arcfn.com
    */
    #include <IRremote.h>
    /*
       Yamaha Amp DSP 592
       Function Code  Len
    */
    #define YTime/Level- 0x5EA1CA35
    #define YTime/Level+ 0x5EA14AB5
    #define YData/Centre 0x5EA1619E
    #define YTest 0x5EA1A15E
    #define YEffect 0x5EA16A95
    #define YProg- 0x5EA19A65
    #define YProg+ 0x5EA11AE5
    #define YProLogic 0x5EA111EE
    #define YEnhanced 0x5EA1916E
    #define YV-AUX 0x5EA1AA55
    #define YVCR 0x5EA1F00F
    #define YTV/DBS 0x5EA12AD5
    #define YDVD/LD 0x5EA1E817
    #define Y2CH/6CH 0x5EA1E11E
    #define YTAPE 0x5EA118E7
    #define YTUNER 0x5EA16897
    #define YCD 0x5EA1A857
    #define YPHONO 0x5EA128D7
    #define YSleep 0x5EA1EA15
    #define YPower 0x5EA1F807
    #define YVOL+ 0x5EA158A7
    #define YVOL- 0x5EA1D827
    /* 
       Optoma HD141X Projector
       Function Code  Len 
    */
    #define Power_ON 0x4CB340BF
    #define Power_OFF 0x4CB3748B
    #define USER1 0x4CB36C93
    #define USER2 0x4CB3A659
    #define USER3 0x4CB36699
    #define Brightness 0x4CB3827D
    #define Contrast 0x4CB342BD
    #define Mode 0x4CB3A05F
    #define Keystone 0x4CB3E01F
    #define Aspect 0x4CB326D9
    #define Optoma3D 0x4CB3916E
    #define Mute 0x4CB34AB5
    #define DB 0x4CB322DD
    #define OSleep 0x4CB3C639
    #define VOL+ 0x4CB38877
    #define VOL- 0x4CB328D7
    #define Source 0x4CB308F7
    #define Re-Sync 0x4CB348B7
    #define Enter 0x4CB3F00F
    #define Menu 0x4CB3708F
    #define HDMI1 0x4CB36897
    #define HDMI2 0x4CB30CF3
    //
    #define power_ON_macro 1111
    #define power_OFF_macro 2222
    #define CHILD_ID_FAN 0
    #define CHILD_ID_HEATER 1
    #define CHILD_ID_IR 2
    #define RELAY_ON 1
    #define RELAY_OFF 0
    #define Fan_ON 1
    #define Fan_OFF 0
    #define Heater_pin 4
    #define Fan_pin 5
    // Enable debug prints
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    #define MY_RF24_PA_LEVEL   RF24_PA_LOW
    #define MY_NODE_ID 61
    #define MY_RF24_CHANNEL (97)
    #define MY_PARENT_NODE_ID 0
    #define MY_PARENT_NODE_IS_STATIC
    //#define MY_REPEATER_FEATURE
    //#define MY_SIGNING_ATSHA204
    //#define MY_SIGNING_REQUEST_SIGNATURES
    unsigned long last_heartbeat_time = 0;
    unsigned long HEARTBEAT_TIME = 5 * 60000;
    unsigned long value = 000000000;
    IRsend irsend;
    #include <Wire.h>
    #include <MySensors.h>
    MyMessage msgFan(CHILD_ID_FAN, V_STATUS);
    MyMessage msgHeater(CHILD_ID_HEATER, V_STATUS);
    MyMessage msgCode(CHILD_ID_IR, V_IR_SEND);
    
    void presentation()
    {
      // Send the sketch version information to the gateway
      sendSketchInfo("MYS-CinemaControl", "0.1");
    
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_FAN, S_BINARY, "Cinema Fan");
      wait(100);
      present(CHILD_ID_HEATER, S_BINARY, "Cinema Heater");
      wait(100);
      present(CHILD_ID_IR, S_IR, "Cinema IR Send");
    }
    
    void setup()
    {
      pinMode(Fan_pin, OUTPUT); //pin 5
      digitalWrite(Fan_pin, LOW);
      pinMode(Heater_pin, OUTPUT); //pin4
      digitalWrite(Heater_pin, LOW);
    }
    
    void loop() {
      if ((millis() - last_heartbeat_time) > HEARTBEAT_TIME) {
        sendHeartbeat();
        last_heartbeat_time = millis();
      }
    }
    
    // process incoming message
    void receive(const MyMessage &message) {
      if (message.type == V_IR_SEND)
      {
        unsigned long  code = message.getString();
        value = strtoul(code, NULL, 16);  
        Serial.print("code = ");
        Serial.print(code);
        Serial.print(" Value = ");
        Serial.println(value);
      
      }
      if (value == power_OFF_macro)
      {
        irsend.sendNEC(YPower, 32);
        delay(500);
        irsend.sendNEC(Power_OFF, 32);
        delay(1000);
        irsend.sendNEC(Power_OFF, 32);
      }
      else if (value == power_ON_macro)
      {
        irsend.sendNEC(YPower, 32);
        delay(500);
        irsend.sendNEC(Power_ON, 32);
      }
        else{
        irsend.sendNEC(value, 32);
        }
    if (message.type == V_STATUS){
        digitalWrite(message.sensor+4, message.getBool()?RELAY_ON:RELAY_OFF);
        } 
    }
    

    I have spent 6 hours today trying to find any info that might help on here and the arduino site, but still can't find an example to base this one....anyone able to help?



  • @skywatch The MySensor message is in a string format and the the irsend.sendNEC is expecting a number.
    Try the following:

     receive(const MyMessage &message){        
       if (message.type == V_IR_SEND)
       {
        unsigned long code = strtoul(message.getString(),NULL,0);
         irsend.sendNEC(code, 32);
       }
    


  • @hard-shovel

    Thank you soooo much! - I will build the node and test this out.
    Once you know the answer it seems so easy....But if you can't work it out, well that's when a little help makes all the difference.

    I'll let you know how it goes!



  • Well it failed to work.

    I know that the data is getting to the arduino from this.....

    5533 TSF:MSG:READ,0-0-61,s=2,c=1,t=32,pt=0,l=10,sg=0:0x5EA1F807
    

    But when I look at the value of 'code' it is showing as decimal equivalent of the hex number the IR is expecting to send. I tried changing '0' to 'HEX' at the end of the strtoul, but that didn't do it either.

    ANother sleepless night tonight?



  • Are you sure, the sending part of your hardware is working?
    In the past I successfully used a comparable code to hard-shovel's proposal (although with a different IRlib).

    As you mentioned the "code" seem to be ok in decimal writing, a hardware defect imho is the most likely cause of your headaches.



  • @rejoe2

    Funny you should mention that - As I was testing just now I noticed that the pro-mini locks up after getting the value the first time. A result of this was that it was holding the output to the led's high. As I had followed the adafruit instructional, there was no current limiting resistor in the led side and things got very hot.

    I am assuming that board is toast now and starting building a new one with 2 ir leds in series with each other and a 47R all on the collector side of a 2n2222 - With a base limiting resistor of about 1K I would hope that will do it.

    I does look promising though with the data getting through OK, so the node and code might well be OK - I'll let you know! 😉



  • All working now thank you both!

    How do you deal with commands that need to repeat? Like volume controls?
    I guess some form of if/for loop with a test to see if the message is still being received, but this may depend on how MyController does this, I'll ask there as well.

    Cheers!



  • @skywatch the Arduino is using the code in the unsigned long format, you can view the code value in decimal or Hex format to check the value.

     receive(const MyMessage &message){        
       if (message.type == V_IR_SEND)
       {
        unsigned long code = strtoul(message.getString(),NULL,0);
      Serial.print("Received Code - Decimal: ");
      Serial.println(code);
      Serial.print("Received Code - Hex: ");
      Serial.println(code, HEX);
    // or to show it in format you whould use to enter hex numbers
      Serial.print("Received Code - Hex:  0x");
      Serial.println(code, HEX);
         irsend.sendNEC(code, 32);
       }
    

    For the volume settings i do not quite understand you usage requirement, are you trying for example to set volume at 50% on the controller and then having to send the require number of volume up / down commands to get to that value so have to track the current volume setting?

    Or is just adjustment up or down, operated from some other signal into the controller, ie pushbutton, can you not just send the command again to the node if the pushbutton is still held down after a timed delay.

    What does the debug output show on the node, from that you should see if your controller is sending multiple commands or just a single instance.



  • @hard-shovel

    Thanks for the response. The volume control is motorised so no need to 'remember' where it is as it is possible to manually change it and there is no feedback that could be used to determine changes.

    The remote control requires you to hold the volume buttons (+&-) down until desired volume level is achieved so I suppose I could start repeating the IRSend code from the node if one valid volune command is received. The first time the node gets a valid volume command it just repeates the send over and over until it gets another identical command which stops the loop. I'll think more about it and also see if the controller has something that might be suitable.

    Edit - Why not just start the volume repeating the code to go in whatever direction you want at a suitable speed and add a volume 'Stop' button - that would be easier! - I think I'll try that at the weekend...... 😉

    Thanks again, I can finally start hiding all the remotes cluttering up the place! 🙂


 

326
Online

7.7k
Users

8.6k
Topics

92.4k
Posts