ошибка в связи через последовательный порт - PullRequest
1 голос
/ 09 февраля 2010

У меня может быть самая странная ошибка, которую вы слышали сегодня.

У меня есть один (очень длинный) метод внутри потока, который отправляет отформатированные данные на светодиодный дисплей RS232.

Он должен отображать что-то вроде этого

TITLE
SUBTITLE 1
ELEMENT 1
ELEMENT 2
SUBTITLE 2
ELEMENT 1
ELEMENT 2
ELEMENT 3

ну, у каждого свое сообщение.

Я вызываю Thread.Sleep (N) после каждого сообщения (поэтому каждое сообщение отображается N раз).

  • N - количество секунд

Хорошо, все хорошо до сих пор. Дело в том, что если (10 <= N <= 20) я получу следующий вывод:

TITLE
TITLE
TITLE
TITLE
TITLE
TITLE
TITLE
TITLE

Я слышу гудок , когда отправляю сообщение. Я даже установил монитор последовательного порта, чтобы проверить, была ли информация, которую я отправлял, одинаковой.

Итак, подведем итог:

Запись на последовательный порт работает после сна потока для n <= 9 или n> = 20. Любое промежуточное значение приведет к ошибочному выводу, например, если вывод был кэширован или что-то еще

Что это может быть?

Обновление

  • Хорошо, я знаю, что System.Threading.Sleep принимает в качестве аргументов миллисекунды. просто умножьте число на 1000.
  • Всякий раз, когда светодиодный дисплей получает новое хорошо отформатированное сообщение, он издает звуковой сигнал. Я должен был это уточнить.

Вот фрагмент (отправляет первый заголовок)

            using (var ld = new LedScreen(COM))
            {                    
                ld.AddEffect(LedScreen.Effects.Snow);
                ld.AddText(LedScreen.Colors.Red, titulos[ThreadControl.Fase]);
                ld.AddEffect(LedScreen.Effects.DSnow);
                ld.Write();
            }

            //Console.WriteLine(titulos[ThreadControl.Fase]);
            //esperamos N tiempo (titulo)
            Thread.Sleep(TiempoTitulo);

Я написал класс LedScreen. Вот метод записи:

    public void Write()
    {
        //caracteres de terminacion
        buffer.AddRange(new byte[] { 0xBF, 0xB1 });
        try
        {
            if (!sp.IsOpen) sp.Open();
            sp.Write(buffer.ToArray(), 0, buffer.Count);
        }
        finally
        {
            sp.Close();
        }
    }

Обновление 2

Я наконец-то заставил его работать (некрасиво, но, черт возьми.)

Перед каждой записью в последовательный порт я отправляю «пустое» сообщение без задержки. Это очищает экран перед отправкой фактического сообщения. Ура! и это работает в течение любого количества секунд, я сплю нить

Ответы [ 3 ]

1 голос
/ 10 февраля 2010

Есть несколько вещей, которые могут повлиять на вашу ситуацию, не последней из которых является уже упоминавшийся вопрос «вы говорите секунды, но Sleep () принимает аргумент миллисекунды, а не секунды».

Вам также необходимо посмотреть на промежуток времени между отправленными символами. Контроль потока тоже. Параметры последовательного порта (скорость передачи и т. Д.). И вам нужно знать, какова устойчивость вашего устройства. Потеря данных при последовательной передаче обычно означает, что вы перегружаете устройство на другом конце.

1 голос
/ 10 февраля 2010

Знаете ли вы алгоритм устройства для определения конца сообщения (EOM)? Возможно, устройство использует внутрисимвольный тайм-аут. Это может объяснить, почему он работает с N> 20, если в этот раз в буфере не появилось новых символов, тогда устройство может решить, что сообщение было прервано, и отобразить буфер. Если вы ставите код ASCII 10 в конце сообщений, возможно, вы решите, что остальная часть сообщения будет прокручиваться с конца однострочного дисплея и не будет отображаться.

Это не объясняет работу N <9. Возможно, если данные поступают без каких-либо задержек вообще, устройство интерпретирует их как сценарий для последовательного отображения? Это указывает на то, что скорость отображения сообщений не изменяется для N = 0–9, но меняется для всех N> 20. Если N в миллисекундах, вы не сможете подтвердить это.

1 голос
/ 10 февраля 2010

Прежде всего, не могли бы вы уточнить время сна темы? System.Threading.Thread.Sleep () принимает аргумент в миллисекундах, а не в секундах.

Далее, вы знаете, что запись в последовательный порт завершается успешно? (Жестко запрограммированная задержка в 10-20 мсек не всегда является достаточно продолжительной.)

Чтобы предотвратить перегрузку, я делаю что-то вроде:

    public bool Send(byte[] bytes)
    {
        try
        {
            serialPort.Write(bytes, 0, bytes.Length);
            return true;
        }
        catch (Exception ex)
        {
            // log or note the error: can be TimeoutException or InvalidOperationException, etc
            return false;
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...