Интернет-магазин

Просмотр корзины
В корзине:

товаров - 0 шт.



§ 2.2. Считывание информации с внешних ключей, кнопок

Дмитрий Иванов, 22 марта 2008

Файлы к статье скачать
Имя: KA002_02.zip (ZIP архив)
Размер: 127 КБ

В прошлой статье мы рассмотрели то как можно настроить ту или иную линию модуля на вход, чтобы можно было считывать с нее входную информацию. Давайте настроим часть линий модуля на вход. Вы можете сделать это как вам будет удобнее - с помощью программы из прошлой статьи или в терминале. Например, пусть линии с 18-ой по 24-ую будут входными.

Собираем схему как на рисунке ниже. К тем линиям которые настроены на выход по прежнему подключены светодиоды (желательно через токоограничивающие резисторы, которые на схеме не показаны), а вот те которые мы только что сделали входными подключены простейшие источники двоичной информации - ключ или кнопка, кому как конструктивно будет более удобно.

нажмите для увеличения

Рисунок 1. Схема подключения кнопок (ключей) к линиям модуля Ke-USB24A

Для чтения значения на входной линии предназначена команда $KE,RD. Она также имеет две модификации: одна из них позволяет за одно обращение прочесть информацию со всех входных линий, другая - с одной конкретной линии. В программе для этой статьи мы будем использовать последнюю модификацию.

Займемся программным обеспечением. Проект вы можете найти в файлах к этой статье. Пример написан на С++ с использованием MFC в среде Microsoft Visual Studio C++ 6.0. Окно программы имеет вот такой "незамысловатый" вид:

Модуль Ke-USB24A

Рисунок 2. Пример программы для считывания информации с входных дискретных линий модуля Ke-USB24A

Обратимся к коду обработчика кнопки чтения данных. В начале идет проверка данных, формирование команды и ее запись в порт. Теперь нам нужно получить ответ модуля, содержащий интересующую нас информацию о входной информации на линии модуля.

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

Здесь же мы используем самый простой вариант - просто сделаем небольшую задержку, необходимую для того что бы модуль успел выполнить команду и выдать ответ. Затем, мы считываем данные из порта и начинаем их "разбор".

void CLineReaderDlg::OnRead() 
{
  // TODO: Add your control notification handler code here
  UpdateData(true);
  
  if(this->m_hFile == NULL)
  {
    MessageBox("You should open\nport first", "Info", MB_ICONINFORMATION);
    return;
  }
 
  if(this->m_Line <= 0 || this->m_Line > 24)
  {
    MessageBox("Please, select\ncorrect line number", "Info", MB_ICONINFORMATION);
    return;
  }  

  DWORD lpdwBytesWritten;
  char buf[32];

  int len = sprintf(buf, "$KE,RD,%d\r\n", this->m_Line); 
  WriteFile(m_hFile, buf, len, &lpdwBytesWritten, NULL);  

  // Make littele pause for wait module anser
  Sleep(20); // Wait 20 ms
  
  DWORD dwBytesRead;
  unsigned char pBuff[128];

  ReadFile(m_hFile, &pBuff, sizeof(pBuff), &dwBytesRead, NULL);
  
  if(dwBytesRead > 0)
  {
    // We must get anser like this: #RD,<LineNumber>,<Value>

    char waitBuf[32];
    int wLen = sprintf(waitBuf, "#RD,%02d,", this->m_Line);

    if( memcmp(pBuff, waitBuf, wLen) == 0)  // identical
    {
      int value = atoi((char*)(&pBuff[wLen]));
      if(value < 0 || value > 1)
      {
        MessageBox("Read Line fail1", "Info", MB_ICONERROR);
        return;
      }

      CString s1;
      s1.Format("Read Line:\nLine: %d\nValue: %d", this->m_Line, value);
      MessageBox(s1, "Info", MB_ICONINFORMATION);
    }
    else
    {
      if(memcmp(pBuff, "#RD,WRONGLINE", 13) == 0)
      {
        MessageBox("This line setup as OUTPUT\nCan`t read data.", "Info", MB_ICONINFORMATION);
        return;
      }
      MessageBox("Read Line fail2", "Info", MB_ICONERROR);
    }
  }
  else
  {
    MessageBox("Read Line fail3", "Info", MB_ICONERROR);
  }	
}

Интересный вопрос - а что будет, если мы попытаемся считаь данные с линии которая настроена на выход? В этом случае модуль выдаст предупреждение о возникновении такой ситуации - #RD,WRONGLINE. Код представленный выше анализирует такой ответ и в случае нашей ошибки выдаст соответствующее сообщение.



© Дмитрий Иванов
22 марта 2008 года
http://www.kernelchip.ru



© KERNELCHIP 2006 - 2017