Пакет Modbus RX вызывает ошибку после отправки. Как остановить «фантомный» буферный ввод? - PullRequest
0 голосов
/ 12 апреля 2019

Я пытаюсь перенести версию 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;
}
...