Serial.readString() Help

Hey,

So I've been working on a little project to control some LED lights that came with an IR remote to turn them on and off and change the colours and what not. I've created an app in visual studio that sends the IR codes over the com port and to the arduino, this part works perfectly. I was initially sending single characters and then using a lot of if statements to check what the character was and had the IR code, hard coded. My girlfriend got some similar lights but a different brand so the IR codes are different. Her remote is a little dodgy so I said I would make her an app like mine so she can control her lights from her computer, but she's all about aesthetic and because my original app was just me using it, it didn't really look too good, but it was functional. So I've recreated the app so she can change how the button's look and change the background etc... and while I was recreating it, I though hey, instead of having a load of if statements in the arduino code, why don't I just send the IR codes over the serial port, and then forward them on. This way, I can use a config file on the computer app and then change the codes in there and other people would be able to use it without having to rewrite parts.

But the problem I'm having is that I'm using the library IRremote, made by shirrif and when I try to store the Serial.readString as a variable and then pipe it to the IR LED, it pops up with an error saying that it can't use strings with the IRsend.NEC(string, int).

So I was hoping if any one has any simple and easy to follow solutions to this? If any one needs to see my arduino code, I can post it, I just didnt want this to be a wall of text.

Yeah people will need to see your code and the full error message. Please put them in code tags (so the forum software doesn't mangle the formatting).

Serial.readString() reads input and assigns it to a String (uppercase S, ie a String object).

What data type does the send() function require ?

This is the code;

#include <IRremote.h>

IRsend irsend;

void setup()
{
  Serial.begin(9600);
  int code;
}

void loop() {
  String code;

code = Serial.readString();


if (code != ""){
		irsend.sendNEC(code, 32);
}

	
}

And the error message is;

C:\Users\liam.kay\Desktop\Light_Test2\Light_Test2.ino: In function 'void loop()':

Light_Test2:29:26: error: no matching function for call to 'IRsend::sendNEC(String&, int)'

   irsend.sendNEC(code, 32);

                          ^

In file included from C:\Users\liam.kay\Desktop\Light_Test2\Light_Test2.ino:13:0:

C:\Users\liam.kay\Documents\Arduino\libraries\IRremote/IRremote.h:290:10: note: candidate: void IRsend::sendNEC(long unsigned int, int)

    void  sendNEC        (unsigned long data,  int nbits) ;

          ^

C:\Users\liam.kay\Documents\Arduino\libraries\IRremote/IRremote.h:290:10: note:   no known conversion for argument 1 from 'String' to 'long unsigned int'

exit status 1
no matching function for call to 'IRsend::sendNEC(String&, int)'

UKHeliBob:
Serial.readString() reads input and assigns it to a String (uppercase S, ie a String object).

What data type does the send() function require ?

I'm not entirely sure to be honest, arduino isn't my strongest language, I've been working mostly with vbnet, and a tiny bit of C#. I did open an issue on the github for the library and some one responded with this;

Yes it takes a 32 bit unsigned integer.

either convert the hex string to an integer before calling the send function or just Send & read it in from the app as a binary value over Serial.

The only thing, is that I have no idea how to do that.

Give a simple example of a string that you are sending from the InputBox of the Serial Monitor.

so I'm sending 0xFFE01F from my app to the arduino.

this works fine in the arduino;

irsend.sendNEC(0xFFE01F, 32);

but as you can see I'm trying to pipe it in from the serial.readstring() and to be honest my heads a little blagged.

Whilst the use of Strings is deprecated in the small memory environment of the Arduino does the String library not have a toInt() function to convert the String to an int ?

but if I convert the string to an integer wouldn't it remove the letters?

It depends if the toInt method knows about hex values.
And unsigned longs, and not just ints.

Time to get experimenting.

knil92:
but if I convert the string to an integer wouldn't it remove the letters?

Why is the String in hex in the first place ?

Try the following code:

irsend.sendNEC(&code, 32);

GolamMostafa:
Try the following code:

irsend.sendNEC(&code, 32);

That compiles perfectly fine so I'll test that tonight when I'm home. But what exactly does the & do?

knil92:
That compiles perfectly fine so I’ll test that tonight when I’m home. But what exactly does the & do?

It’s there to confuse you.
Not exactly why @GolamMostafa would want to do that.

TheMemberFormerlyKnownAsAWOL:
It's there to confuse you.
Not exactly why @GolamMostafa would want to do that.

So are you saying that it will compile but won't work in practise?

knil92:
but if I convert the string to an integer wouldn't it remove the letters?

I think you misunderstand how this works.

irsend.sendNEC(0xFFE01F, 32);

This does not send letters and numbers to the .sendNEC() function, it converts OxFFEO1F to a long (32-bit) integer, then sends that number to the function. Ox indicates to the compiler that you are entering the number in hexidecimal, you could have used the equivalent decimal or binary number and it would work just as well.

I’m saying it compiles (but gives you a warning) because you are allowed to convert a pointer to a String to an unsigned long.
But it won’t do anything remotely like you want or expect.

/home/**/Arduino/CloudStation/foobar/foobar.ino: In function 'void loop()':
/home/**/Arduino/CloudStation/foobar/foobar.ino:18:20: warning: invalid conversion from 'String*' to 'long unsigned int' [-fpermissive]
     irsend.sendNEC(&code, 32);
                    ^~~~~
In file included from /home/**/Arduino/CloudStation/foobar/foobar.ino:1:0:
/home/**/Arduino/CloudStation/libraries/IRremote/IRremote.h:290:10: note:   initializing argument 1 of 'void IRsend::sendNEC(long unsigned int, int)'
    void  sendNEC        (unsigned long data,  int nbits) ;
          ^~~~~~~

There must be loads of examples of converting the ASCII representation of a hex constant in a String, to its integer representation.

knil92:
That compiles perfectly fine so I'll test that tonight when I'm home. But what exactly does the & do?

The syntax of your code is:

void  IRsend::sendNEC (unsigned long data,  int nbits)

The first argument is a 32-bit number. The value that you have received from InputBox is a string, and you have saved it in the variable code. Therefore, if you pass the address of the holding variable (the code), the function will automatically convert it into long data (some kind of function overloading?). That's what I am thinking! (The character & (ampersand) is used to pass the address of the storage space that holds the value (s) of a variable.) (edit)

david_2018:
I think you misunderstand how this works.
This does not send letters and numbers to the .sendNEC() function, it converts OxFFEO1F to a long (32-bit) integer, then sends that number to the function. Ox indicates to the compiler that you are entering the number in hexidecimal, you could have used the equivalent decimal or binary number and it would work just as well.

So basically these are both the same;

irsend.sendNEC(0xFFE01F, 32)

irsend.sendNEC(16769055, 32)

and from what AWOL was saying is that I can convert the string from serial.readstring to an int, and because the decimal value is all numbers then it should work?

GolamMostafa:
The syntax of your code is:

void  IRsend::sendNEC (unsigned long data,  int nbits)

The first argument is a 32-bit number. The value that you have received from InputBox is a string, and you have saved it in the variable code. Therefore, if you pass the address of the holding variable (the code), the function will automatically convert it into long data (some kind of function overloading?).

Thanks Golam, I'll try both of these tonight when I get home, but you guys have nudged me in the right direction. I was literally about to go back to sending commands and just having everything hard coded lol but yeah, if I can get it working like it, then I might put it on github, so people can use my app and change the look of it to suit their needs etc... Again, thank you guys :smiley:

The inappropriately-named String method “toInt” returns a long.

So, if you send the IR code as ASCII decimal, not hex, you’ll be able to use “toInt” on the received String, and then simply cast the returned value to “unsigned long”.

(I’m assuming “toInt” will barf on ASCII hex)