0

I'm writing a char array to a device with an arduino mega that should be giving me an echo back, instead, I'm getting an array back with different chars that correspond to my sent function, but not in a way I can figure out. for example {1,6,250,0,91,233,252} returns the array {127,62,1,146,90,0,0} As 1 is always returning 127, I'm guessing it has something to to with how I'm casting my received data, but after messing with it for a few hours, I can't seem to get it to cast correctly.

Main Function

gets destination address and data, echos back if requested

calls CRC(this works fine) and SkRead(the problem area)

void Create_Message(int Address, int Data, bool echo)
{
  lcd.setCursor(0,1);
  lcd.print(Address);
  lcd.print(" ");
  lcd.print(Data);
  Address--;
  byte SvAdd = 1;
  byte FuCode = 6;
  byte AddHi = Address>>8;
  byte AddLo = Address;
  byte DatHi = Data>>8;
  byte DatLo = Data;
  byte AdDa[] = {SvAdd,FuCode,AddHi,AddLo,DatHi,DatLo};
  uint16_t crc=CRC(AdDa,sizeof(AdDa)/sizeof(AdDa[0]));
  byte CrcHi = crc >> 8;
  byte CrcLo = crc & 0xFF;
  /*U8 Slave Address, U8, Function Code, U16 Address, U16 Data, U16 CRC
  * to
  *[U8 Address Split High, U8 Address Split Low, U8 Data Split High, U8 Data Split Low, U8 Function Code]
  */
  unsigned char cmd[8]={SvAdd,FuCode,AddHi,AddLo,DatHi,DatLo,CrcLo,CrcHi};
  for (int i=0; i< 8; i++)
  {
  Serial1.write(cmd[i]);   // Send string
  if(echo){Serial.print(cmd[i]);Serial.print('.');}
  }
  if(echo){Serial.println();}
  if (SkRead(echo) == cmd)
  {
  Serial.print(Address);
  Serial.print('\t');
  Serial.println(Data);  
  }
  //clear line  
}

CRC

(works fine, just wanted to show full code)

/*---Create CRC Function---*/    
uint16_t CRC(byte AdDa[], int Size )
{
  uint16_t crc16 = 0xFFFF;
  int pos = 0;
  int i = 0;
  /*Write CRC*/
  for (pos = 0; pos < Size; pos++) 
  {
    crc16 ^= AdDa[pos];          // XOR byte into least sig. byte of crc
    for (i = 8; i!= 0; i--) // Loop over each bit
    { 
      if ((crc16 & 0x0001) != 0)        // If the LSB is set
      {
        crc16 >>= 1;                      // Shift right and XOR 0xA001
        crc16 ^= 0xA001;
      }
      else
      {
        crc16 >>= 1;                      // Shift right
      }
    }
  }
  /*Note, this number has low and high bytes swapped,
  so use it accordingly (or swap bytes)*/
  return crc16;
}

SkRead

This is my problem area, I'm sure the data is being sent and read correctly, but one of my assignments is throwing it off so the received echo is not received in a way that matches what is sent.

unsigned char SkRead(bool echo)
{
  digitalWrite(Pin13LED, HIGH);  // Show activity
  outputstring = "";
  unsigned long bide=millis()+2000;
  byte inChar;
  while(Serial1.available()<8 && bide>millis()){}
  while(Serial1.available())
  {
    inChar = (byte)Serial1.read();
    outputstring += (char)inChar;
  }
  //Serial.println(outputstring);
  digitalWrite(Pin13LED, LOW);  // Show activity
  int charl = outputstring.length() + 1;
  unsigned char outputschar[charl];
  outputstring.toCharArray(outputschar,charl);
  if (echo)
  {
    for (int i=0; i< charl; i++)
    {
     Serial.print(outputschar[i]);
     Serial.print('.');
    }
    Serial.println();
  }
  return outputschar;
}
  • One thing I notice: You have CrcHi and CrcLo reversed in the array definition. Is it supposed to be? – Johnny Mopp Jun 26 '17 at 17:24
  • Yes, low comes first. – ATE-ENGE Jun 26 '17 at 17:50
1

I don't know where to start.

  • You did not provide a full sketch. There is, for example, no Serial.begin1() in sight.
  • You did not provide enough information about the device. If you don't want to tell us what it is, then give an indication of its age. In the 1980's it was common to have 7E1 format (7 data bits, even parity, 1 stop bit).
  • You have to be sure what the baudrate is. To detect a wrong baudrate, you need a oscilloscope or logic analyzer. When the device has a processor and the baudrate is derived from it's clock, the baudrate could be different from the specified baudrate by a few percentage. That is already a problem with the Arduino.
  • It could be a problem with inverse voltage levels. What does the device use as idle and as active level ? The Arduino Mega uses +5V at the TX pin when idle, and low is active. That means that the TX pin is normally high, and the first low pulse is the start bit.
  • The device could return an error code instead of an echo.
  • Your SkRead function can be improved:
  • Using a String object to collect the incoming data and after that converting the String object to a unsigned char array to use it, is not the most elegant solution. You could just use a unsigned char array to read the incoming data.
  • It is not okay to add something to the millis value. That is a problem when millis does a rollover (after 50 days or so).
  • Normally a character is read as soon as it is available. You wait until 8 characters are in a buffer. No one else does that.

To solve this puzzle you need more information. Try to capture the RX and TX signals with a oscilloscope or logic analyzer. Or else try to write a very small sketch that creates the problem.

My best guess is that it is not your sketch, but perhaps a combination of inverse levels, parity and baudrate.

[ADDED]
After writing down the bits over the serial bus, it might indeed be inverse voltage levels and maybe something with 7 bits or parity. That would also explain the last bytes to be 255. Those 255 are not valid data.

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.