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

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

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



§ 2.3. Простой USB вольтметр на основе Ke-USB24A

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

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

Помимо возможности управлять линиями ввода-вывода, модуль Ke-USB24A имеет в своем составе интегрированный аналого-цифровой преобразователь (АЦП). Разрядность АЦП - 10 бит, динамический диапазон входного напряжения от 0 до +5 В. Продемонстрируем на примере как его можно использовать на практике.


Благодаря наличию АЦП из модуля можно всего за пару минут сделать компьютерный USB вольтметр. Для начала давайте соберем схему. Методика подачи входного аналогового сигнала на вход АЦП модуля показана на рисунке ниже. Для простоты демонстрации, для данной статьи в качестве теста предлагается схема, показанная на рисунке справа. На вход АЦП будет подаваться напряжение, снимаемое с движка переменного резистора. Изменяя положение движка можем получать любое напряжение в диапазоне от 0 до 5 В. Номи- нальная величина резистора не имеет принципиального значения, здесь я использовал на 2.2 кОм.

Схема подачи сигнала на вход АЦП

Рисунок 1. Схема подачи сигнала на вход АЦП

Для этой статьи я написал небольшую программку, которая выглядит вот так. Если мы будем изменять положение движка резистора (читай изменять входное напряжение для АЦП) то в соответствующем поле окна программы будет отображаться величина входного напряжения.

USB-вольтметр

Рисунок 2. Программа "USB-вольтметр"

Рассмотрим поближе код этой программы. Вот здесь функция открытия порта притерпела некоторые изменения, поэтому с нее и начнем. Она полностю повторяет код из предыдущих статей, но в ее конце мы подаем в порт команду $KE,ADC,5. Это означает что модуль будет автоматически считывать состояние АЦП с частотой 5 Гц и выдавать соответствующее сообщение в порт с такой же частотой. Ke-USB24A позволяет устанавливать частоту автоматического опроса до 400 Гц. Для задач простого вольтметра измерение напряжения 5 раз в секунду нам вполне хватит. Далле мы запускаем таймер с частотой срабатывания 4 Гц (период 250 мс). Именно в обработчике сообщений таймера мы будем считывать информацию из порта.

void CUSBVoltmeterDlg::OnOpen() 
{
  // TODO: Add your control notification handler code here
  UpdateData(true);

  ....................
	
  MessageBox("Open OK", "Info", MB_ICONINFORMATION);

  DWORD lpdwBytesWritten;
  char buf[32];
  int len = sprintf(buf, "$KE,ADC,5\r\n"); 
  WriteFile(m_hFile, buf, len, &lpdwBytesWritten, NULL);    

  SetTimer(1, 250, NULL);	
}

А вот собственно и сам обработчик таймера. Что мы тут делаем? Читаем некоторый объем данных из порта. Там теоритически должны находиться 5 сообщений модуля, содержащих числовой код, соответствующий входному аналоговому напряжению. Зная структуру сообщения, отыскиваем в пролученных данных первое валидное сообщение и "вытаскиваем" из него оцифрованную величину напряжения. Затем по формуле (см. подробнее описание команд управления) персчитываем полученное значение в напряжение и отображаем его в окне программы.

void CUSBVoltmeterDlg::OnTimer(UINT nIDEvent) 
{  
  DWORD dwBytesRead;
  unsigned char pBuff[128];

  ReadFile( m_hFile, &pBuff, sizeof(pBuff), &dwBytesRead, NULL ); 

  unsigned int offset = 0;
  int adc_value = 0;
  char data[4];
  
  if( dwBytesRead > 0 )
  {
    while( offset < dwBytesRead )
    {
      if( memcmp(pBuff + offset, "#ADC,", 5) == 0 ) 
      {        
        memcpy( data, pBuff + 5, 4 );
        adc_value = atoi( data );
        break;
      }
      offset += 1;
    }
  }

  double fadc = ((double)adc_value*5.0)/1023.0;
  this->m_vol.Format("%f V", fadc); 
  UpdateData( false );
	  
  PurgeComm( m_hFile, PURGE_TXCLEAR | PURGE_RXCLEAR );

  CDialog::OnTimer(nIDEvent);
}

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



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



© KERNELCHIP 2006 - 2017