0

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.

2

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 May 15 '17 at 15:09
  • 1
    I have posted my version of a hex to dec converter. It may work better, or may not... – Majenko May 15 '17 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 of dehex(hin[i])<<4 are clear, and so are the high 4 bits of dehex(hin[i+1]). – James Waldby - jwpat7 May 15 '17 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 May 15 '17 at 15:33
  • 1
    Because you're using + instead of | you have a precedence error. See my edit. – Majenko May 15 '17 at 15:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.