The Code Below now works:
void SendCTRL (String &input)
{
const char *hin = input.c_str(); // Get character array
int clen = input.length()/2;
unsigned char cmd[clen+1]; // Leave a byte for null terminator
for (int i=0; i < 2*clen; i+=2)
{
cmd[i/2] = dehex(hin[i])<<4 | dehex(hin[i+1]);
}
cmd[clen] = 0; // Null-byte terminator
digitalWrite(SSerialTxControl, RS485Transmit); // Enable RS485 Transmit
for (int i=0; i< clen; i++)
{
RS485Serial.write(cmd[i]); // Send string someplace
//Serial.write(cmd[i]);
}
delay(clen/4);
digitalWrite(SSerialTxControl, RS485Receive); // Disable RS485 Transmit
Serial.println();
}
byte 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);
}
byte 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);
}
Input is a series of ASCII-encoded hex digits and getting the output to print the byte values of the hex.
1 Answer 1
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");
}
-
Ok! that got the writing working. Unfortunately, it just seems to output jibberish.ATE-ENGE– ATE-ENGE2017年05月15日 15:09:22 +00:00Commented May 15, 2017 at 15:09
-
1I have posted my version of a hex to dec converter. It may work better, or may not...Majenko– Majenko2017年05月15日 15:12:49 +00:00Commented May 15, 2017 at 15:12
-
1@Majenko,
c<'A'? c & 0xF : 9 + (c & 0xF)
will work with a...f as well as A...F as representatives of 0xA...0xF. Also, Addition vs Or makes no difference here, because the low 4 bits ofdehex(hin[i])<<4
are clear, and so are the high 4 bits ofdehex(hin[i+1])
.James Waldby - jwpat7– James Waldby - jwpat72017年05月15日 15:31:49 +00:00Commented May 15, 2017 at 15:31 -
1@JamesWaldby-jwpat7 yes, it should all work fine in this situation - but it's good practice to get into the habit of combining with OR rather than with ADD.Majenko– Majenko2017年05月15日 15:33:30 +00:00Commented May 15, 2017 at 15:33
-
1Because you're using
+
instead of|
you have a precedence error. See my edit.Majenko– Majenko2017年05月15日 15:57:46 +00:00Commented May 15, 2017 at 15:57
Explore related questions
See similar questions with these tags.