Цифровой вольтметр на Arduino с подключением к ПК через последовательный порт

В этой статье показано как связать Arduino и ПК и передавать на ПК данные с АЦП. Программа для Windows написана с использованием Visual C++ 2008 Express. Программа вольтметра очень проста и имеет обширное поле для улучшений. Основной её целью было показать работу с COM-портом и обмен данными между компьютером и Arduino.

Связь между Arduino и ПК:

  • Снятие показаний с АЦП начинается, когда компьютер посылает Arduino команды 0xAC и 0x1y. у — номер канала АЦП (0-2);
  • Снятие показаний прекращается после получения Arduino команд 0xAC и 0×00;
  • Во время снятия показаний Arduino раз в 50 мс посылает компьютеру команды 0xAB 0xaa 0xbb, где aa и bb максимальные и минимальные результаты измерения.

Программа для Arduino

Подробнее о последовательной связи Вы можете прочесть на arduino.cc. Программа достаточно проста, большую её часть занимает работа с параллельным портом. После окончания снятия данных с АЦП мы получаем 10 битное значение напряжения (0×0000 — 0×0400) в виде 16-битных переменных (INT). Последовательный порт (RS-232) позволяет передавать данные в пакетах по 8 бит. Необходимо разделить 16-битные переменные на 2 части по 8 бит.
Serial.print(voltage>>8,BYTE);
Serial.print(voltage%256,BYTE);
Мы смещаем байты переменной на  8 бит вправо и потом делим на 256 и результат отправляем на компьютер.

Полный исходник ПО для Arduino вы можете скачать здесь

Visual C++

Я предполагаю, что у Вас уже есть базовые знания в области программирования на C + + для Windows, если нет, то используйте Google. Интернет полон уроков для начинающих.

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

После поиска доступных последовательных портов первый порт выбирается по умолчанию. Как это сделано:

array< String ^>^ serialPorts = nullptr;
serialPorts = serialPort1->GetPortNames();
this->comboBox1->Items->AddRange(serialPorts);
this->comboBox1->SelectedIndex=0;

Последовательный порт на ПК может быть использован лишь одним приложением одновременно, так что порт должен быть открыт перед использованием и не закрываться. Простые команды для этого:
serialPort1->Open();
serialPort1->Close();

Для правильного чтения данных из последовательного порта необходимо использовать события (в нашем случае прерывание). Выберите тип события:

Раскрывающийся список при двойном нажатии  «DataReceived».

Код события генерируется автоматически:
private: System::Void serialPort1_DataReceived(System::Object^ sender, System::IO::Ports::SerialDataReceivedEventArgs^ e) {
}

Если первый байт прибывший по последовательному порту 0xAB, если это означает, что остальные байты несут данные о напряжении.  

private: System::Void serialPort1_DataReceived(System::Object^ sender, System::IO::Ports::SerialDataReceivedEventArgs^ e) {
unsigned char data0, data1;

if (serialPort1->ReadByte()==0xAB) {
data0=serialPort1->ReadByte();
data1=serialPort1->ReadByte();

voltage=Math::Round((float(data0*256+data1)/1024*5.00),2);

data_count++;
}
serialPort1->ReadByte();
}

Запись и чтение данных последовательного порта

Для меня небольшой проблемой было послать шестнадцатиричные RAW-данные через последовательный порт. Была использованна команда Write(); но с тремя аргументами: массив, номер стартового байта, кол-во байтов для записи.

private: System::Void button2_Click_1(System::Object^ sender, System::EventArgs^ e) {

unsigned char channel=0;

channel=this->listBox1->SelectedIndex;

array^start ={0xAC,(0x10+channel)};
array^stop ={0xAC,0x00};
if (!adc_on) {
serialPort1->Write(start,0,2);
this->button2->Text=»Stop»;
adc_on=true;

} else {
serialPort1->Write(stop,0,2);
this->button2->Text=»Start»;
adc_on=false;}
}

На этом все!

Оригинал статьи

Добавить комментарий

Ваш адрес email не будет опубликован.