There's some logic slightly askew with your length calculations:
int clen = input.length()/2;
Ok, so for a (say) 20 character string you have clen=10
.
for (int i=0; i < clen; i+=2)
Ok, so for the first 10 characters of your 20 character string you take alternate ones (0, 2, 4, 6, 8)
What about the last 10 characters? clen
is 10, not 20, since you divided it by 2 at the start.
Decide if you want clen to be half the string length, then count double, or is the whole string length, and you divide it by 2 where you want the final string length. Or have two variables - one before and one after dividing by 2.
Oh, and you should pass your String parameter by reference so you don't duplicate the object and end up fragmenting your heap.
void SendCTRL (String &input)
I haven't gone into depth about the working of your dehex
function, but this is the function I always use and works well:
unsigned char h2d(char hex)
{
if(hex > 0x39) hex -= 7; // adjust for hex letters upper or lower case
return(hex & 0xf);
}
Also you should or your values together, not add them:
cmd[i/2] = (dehex(hin[i])<<4) | dehex(hin[i+1]);
This would go some way to fixing your current issue, since |
has a different precedence to +
. At the moment you have effectively:
cmd[i/2] = dehex(hin[i]) << (4 + dehex(hin[i+1]));
since the +
happens before the <<
, whereas what you want is:
cmd[i/2] = (dehex(hin[i]) << 4) + dehex(hin[i+1]);
However with |
instead you get
cmd[i/2] = (dehex(hin[i]) << 4) | dehex(hin[i+1]);
because the <<
happens before the |
Here is your code written in pure C to run on a PC (faster to debug and test than an Arduino when you're on Linux):
#include <stdio.h>
#include <string.h>
unsigned char dehex(char c)
{
// Get nibble value 0...15 from character c
// Treat digit if c<'A', else letter
return c<'A'? c & 0xF : 9 + (c & 0xF);
}
void SendCTRL (const char *hin)
{
int ilen = strlen(hin);
int clen = ilen / 2;
unsigned char cmd[clen+1]; // Leave a byte for null terminator
for (int i=0; i < ilen; i+=2)
{
cmd[i/2] = dehex(hin[i])<<4 | dehex(hin[i+1]);
printf("%02x\n", cmd[i/2]);
}
cmd[clen] = 0; // Null-byte terminator
for (int i = 0; i < clen; i++) {
printf("%c", cmd[i]);
}
}
void main() {
SendCTRL("010307E40001C549");
}