Hello group:
I'm communicating with another target over TTL-level serial bus at 57600 baud. Sending only 8 bytes ending in two bytes of CRC.
Example:
Sending (HEX): 05 1B 00 02 1C 00 1C 38
Received at Target: 05 1B 00 02 1C 00 9C 8E
Last two byte data seems to be shifted (maybe).
Target receives data from other targets correctly.
Any thoughts on why only last two byte corrupted? THANKS!
void loop()
{
// Modbus server accept incoming connections
EthernetClient client = EthServer.available();
if (client.connected())
{
modbusTCPServer.accept(client);
// poll for Modbus TCP requests, while client connected
modbusTCPServer.poll();
digitalWrite(3, LOW); // set BiBuffer Low to begin transfer
delay (1);
Serial.print("poll");
}
AdjustBuf[0]= 0x05; //magic number
AdjustBuf[1]= 0x1B; //op code LSB
AdjustBuf[2]= 0x00; //op code MSB
AdjustBuf[3]= 0x02; //body length
AdjustBuf[4]= 0x1C; //body LSB (byte 1)
AdjustBuf[5]= 0x00; //body MSB (byte 2)
AdjustBuf[6]= 0x1C; //cksum LSB
AdjustBuf[7]= 0x38; //body MSB
Serial1.write (AdjustBuf,8); //Send request to target to change value
delay(30);
digitalWrite(3, HIGH); // set BiBuffer Low to begin transfer
delay(3000);
}
Please post ALL the code. If you are using SoftwareSerial, that is the problem.
What's the distance and what's the cable? Any drivers used?
It sounds too ambitious to me using that baudrate.
Complete code:
#include <Ethernet.h>
#include <ArduinoModbus.h>
bool _5s;
unsigned long TimeAct, TimePrev, HoldingResult, InputResult, HeartBeat, i, StartingAddr;
long Cmd, Cmd2;
EthernetServer EthServer(502);
ModbusTCPServer modbusTCPServer;
char Param;
char NewValue;
byte AdjustBuf[4];
const int BUFFER_SIZE = 66;
byte DataBufOut[BUFFER_SIZE]; //holds data going out to Modbus connection
byte DataBufIn[BUFFER_SIZE]; //holdds data coming in from Modbus connection
bool DataDirection= false; //data in/out flag from Modbus
unsigned int seed;
unsigned int ckSum;
void setup() {
// Ethernet Settings
byte mac[] = { 0x4E, 0xA0, 0xBE, 0x3F, 0xFE, 0x0F }; // Define MAc address
byte ip[] = { 192, 168, 1, 100 }; // Define IP address
byte subnet[] = { 255, 255, 255, 0 }; // Define SubNEt mask
//UART Settings
pinMode(3, OUTPUT); // set BiBuffer as output pin
digitalWrite(3, HIGH); // set BiBuffer High to start
Serial1.begin(57600); // initialize UART with baud rate of 57600 bps
Serial.begin(9600);
// initialize the ethernet device
Ethernet.begin(mac, ip, subnet); // Assign MAC, IP, and subnet mask
EthServer.begin(); // start listening for clients
modbusTCPServer.begin(); // start listening for clients
// Define Holding register:
HoldingResult = modbusTCPServer.configureHoldingRegisters(0, 100);
InputResult = modbusTCPServer.configureInputRegisters(0, 100);
//Serial.print("Holding Reg init result =");
//Serial.print(HoldingResult);
//Serial.print("\n");
//Serial.print("Input Reg init result =");
//Serial.print(InputResult);
//Serial.print("\n");
//Serial.print("Modbus server address=");
//Serial.println(Ethernet.localIP());
//Serial.print("\n");
}
unsigned int Fletcher16(unsigned int val, unsigned int seed)
{
unsigned int high = seed >> 8;
unsigned int low = seed & 0xFFL;
unsigned int ret = 0;
low = low + val;
high = high + low;
low = low & 0xFF;
high = high & 0xFF;
ret = high << 8;
ret = ret | low;
return ret;
}
//================================================================================================
//Main Loop
//================================================================================================
void loop()
{
// Modbus server accept incoming connections
EthernetClient client = EthServer.available();
if (client.connected())
{
modbusTCPServer.accept(client);
// poll for Modbus TCP requests, while client connected
modbusTCPServer.poll();
digitalWrite(3, LOW); // set BiBuffer Low to begin transfer
delay (1);
Serial.print("poll");
}
AdjustBuf[0]= 0x05; //magic number
AdjustBuf[1]= 0x1B; //op code LSB
AdjustBuf[2]= 0x00; //op code MSB
AdjustBuf[3]= 0x02; //body length
AdjustBuf[4]= 0x1C; //body LSB (byte 1)
AdjustBuf[5]= 0x00; //body MSB (byte 2)
AdjustBuf[6]= 0x1C; //cksum LSB
AdjustBuf[7]= 0x38; //body MSB
Serial1.write (AdjustBuf,8); //Send request to AGC-7 to change value
delay(30);
digitalWrite(3, HIGH); // set BiBuffer Low to begin transfer
delay(3000);
}
Good point if it didn't just go through a 1 inch header. On oscilloscope data looks virtually noiseless and square.
Thanks,
What is receiving the data, and what does the receive code look like?
Okey.
TTL level and Ethernet sounds new. Are special drivers/receivers used?
You understand I'm outside my comfort zone now....
Group: THANKS for your help
Target uses a Microchip 8 bit device. Code was compiled using the CCS compiler and is extremely complex and proprietary so I can't post it. Do know that the Microchip-based target receives the same 8 bit sequence correctly and that combination has been working well for years.
Additional information:
If I "pack" 0xFF and 0xFF into the last two buffer locations, communication is correct. If I "pack" 0x00 and 0x00 into the last two buffer locations, I get 0x80 0x80. Pretty crazy.
No, TTL level for serial communications, Ethernet works correctly and uses traditional driver and magnetics.
Thanks
āUnbalancedā TTL comms is only reliable for about 60-100cm in a fairly clean environment.
Stray capacitance, voltage drop can bring problemsā¦. If you can, try running at a lower bit rate to test. I expect youāll be surprised
Factors like āenergy density lin the continuous setiial signal can cause unexpected reception.
TYPOS FIXED
Yes, I suspect some type of baud rate mismatch issue between the Arduino and the other target. That accumulated mismatch might be affecting the latter bytes.
Donāt know how to skew the baud rate slightly on either target.
Iāll keep the group posted
Itās not a slight mismatch, they could perfectā¦ judging by the ācorrectā messages.
More likely signal distortion on that length of wire.
Thatās why I mentioned energy density ā¦
Try the code sending a string of āU5U5U5āā¦ the hex for that is 0x35 and 0x55,
which provides continuous alternating data bits.
Sending combinations of 0x00 and 0xFF sequentially does a similar thing, with sequential blocks of 000000 and 1111111 to test the link integrity,
1 Like
Iāll give that a try. BTW- only one inch header between the boards, no no real distance. Iāve successfully communicated 57600 TTL over several inches without drivers during tests.
Thanks
guix
August 26, 2023, 2:15am
16
byte AdjustBuf[4];
...
AdjustBuf[4]= 0x1C; //body LSB (byte 1)
AdjustBuf[5]= 0x00; //body MSB (byte 2)
AdjustBuf[6]= 0x1C; //cksum LSB
AdjustBuf[7]= 0x38; //body MSB
Don't write outside of an array, it will corrupt your program.
4 Likes
Can you set the sender to 8N2? If so, does that fix the problem?
The problem there is I canāt change the targets code. Good suggestion
though
Please fix the egregious error noted in post #16 and let us know if the problem is solved.
1 Like
A Pox upon me! Great catch guix! A stupid copy and paste error. Fixed!
However, issue still exists
Changed bytes sent to: 0x05 0x1B 0x00 0x02 0x18 0x00 0x35 ox55
Get at target: 0x05 0x1B 0x00 0x02 0x18 0x00 0x9A oxAA
Last two bytes are shifted. All other bytes are fine. Strange!
Yeah, it's a baud rate mismatch between the two ends, or the start/stop bits aren't being handled correctly. There's a one-bit shift when it goes wrong:
0x35 is 0b 00110101
0x9A is 0b 10011010
And I believe it's sent LS bit first. So maybe the receiver is reading the end of the start bit as the first data bit. So unless my thinking is backwards, the transmitter is slow. Edit: Or, you know, the receiver is fast.
Similarly for 0x55 (01010101) and 0xAA (10101010).
Looking at your code it appears you are using a hardware serial port for Serial1. Which Arduino are you using?
Is it a MEGA2560 based board or something else?
Is it a custom designed board or an off the shelf board?