Я пытаюсь перенести версию SimpleModbus из Arduino в Mbed.Мое устройство Mbed работает как подчиненное устройство и подключается к моему компьютеру через MAX485 и конвертер последовательного USB.Я использую ModbusPoll на моем компьютере для имитации мастера.Скорость передачи 9600.
Система работает для одного запроса функции, затем переходит в ошибку.Ведущий отправляет запрос функции подчиненному устройству (функция 3 для чтения регистров), все в порядке и передает контрольную сумму и т. Д., Мой кадр заполняется из буфера и формируется пакет данных для отправки обратно.Пакет отправляется обратно, и регистр на моем ведущем устройстве обновляется, он работает.
Проблема теперь возникает, когда ведущее устройство пытается снова запросить запрос. Ведомое устройство почти читает «фантомный» байт.Буфер увеличивается до единицы, а затем прекращает прием, это приводит к повреждению пакета, потому что буфер недостаточно велик, и ведомое устройство отклоняет и пытается снова.
Теперь, хотя все как в кадре, смещено вперед,пропустить первый бит принятого пакета, а также добавить первый бит следующего пакета в конец.Итак, что должно быть:
3 3 0 0 0 2 197 233
Становится:
3 0 0 02 197 233 3
Что вызывает контрольную суммуошибка конечно.
У меня есть результаты на серийной печати, но из-за того, что это мой первый пост, я изо всех сил пытаюсь опубликовать скриншоты.
Я совершенно озадачен тем, как это исправить, я потратилДостаточно много времени для изучения протокола Modbus, и я уверен, что у меня есть правильные временные интервалы для 1,5 и 3,5
Я просто не вижу, как он читает 1 буфер после отправки пакета, независимо от того, какие задержки или что-либо еще я вставил. Я почти уверен, что проблема в том, как я отправляю данные пакета обратномастеру и, может быть, это как-то связано с функцией Flush?Я не уверен, что это вообще нужно, но это было в версии Arduino.
Я все еще только учусь в университете, поэтому любые советы / советы и помощь будут высоко оценены, заранее спасибо.
КОД:
modbus_update(unsigned int *holdingRegs){
slaveID = 3;
holdingRegsSize = 2;
unsigned char buffer = 0;
unsigned char overflow = 0;
if (MBPort.readable()) { // is there something to check?
unsigned char overflowFlag = 0;
buffer = 0;
while (MBPort.readable()) {
if (overflowFlag)
MBPort.getc();
else {
if (buffer == BUFFER_SIZE)
overflowFlag = 1;
frame[buffer] = MBPort.getc();
buffer++;
pc.printf("Buffer == %d\n", buffer);
}
wait_us(T1_5); //1718us intercharacter
}
for (unsigned char i = 0; i < 8; i++) {
pc.printf("Frame == %d\n", frame[i]);
}
if (overflow)
return errorCount++;
// The minimum request packet is 8 bytes for function 3 & 16
if (buffer > 6) {
unsigned char id = frame[0];
//pc.printf("ID recieved == %d\n", id);
//pc.printf("MBED ID == %d\n", slaveID);
//---------- carries on to the function selection part -------------
//---------- function to send the packet of data -------------------
sendPacket(unsigned char bufferSize){
TxEnablePin = 1;
for (unsigned char i = 0; i < bufferSize; i++) {
MBPort.putc(frame[i]);
}
//flushSerialBuffer();
// allow a frame delay to indicate end of transmission
wait_us(T3_5); //4010us
TxEnablePin = 0;
}
* РЕДАКТИРОВАТЬ *
Я остановил ведомое устройство после чтения байта "фантома" после отправкиобратно пакет.Это было достигнуто с помощью функции flushSerialBuffer, опубликованной ниже.
ОДНАКО, это не остановило проблему всех пакетов данных, полученных после смещения.
void Slave::flushSerialBuffer(void)
{
char char1 = 0;
while (MBPort.readable()) {
char1 = MBPort.getc();
}
return;
}