Уважаемые знатоки, HELP!!!Arduino+Visual C++2010 Чтение COM-порта непрерывно!!!
- Войдите на сайт для отправки комментариев
Чт, 19/09/2013 - 16:48
Друзья!!!Имею простенький рабочий код для дальномера на основе HC-SR04 (использую этот вариант для отладки) Ардуино моя подключена на COM2
#define Trig 8
#define Echo 9
void setup()
{
pinMode(Trig, OUTPUT); //инициируем как выход
pinMode(Echo, INPUT); //инициируем как вход
Serial.begin(9600);
/* задаем скорость общения. В нашем случае с компьютером */
}
unsigned int impulseTime=0;
unsigned int distance_sm=0;
void loop()
{
digitalWrite(Trig, HIGH);
/* Подаем импульс на вход trig дальномера */
delayMicroseconds(10); // равный 10 микросекундам
digitalWrite(Trig, LOW); // Отключаем
impulseTime=pulseIn(Echo, HIGH); // Замеряем длину импульса
distance_sm=impulseTime/58; // Пересчитываем в сантиметры
Serial.println(distance_sm); // Выводим на порт, далее на VC++2010
delay(100);
}
Далее простенький код , написанный в Visual Studio C++ 2010 Windows Forms
#pragma once
namespace ultrazvuk {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::IO::Ports;
/// <summary>
/// Summary for Form1
/// </summary>
public ref class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
//
//TODO: Add the constructor code here
//
}
protected:
/// <summary>
/// Clean up any resources being used.
/// </summary>
~Form1()
{
if (components)
{
delete components;
}
}
private: System::Windows::Forms::Button^ button1;
protected:
private: System::Windows::Forms::Button^ button2;
private: System::Windows::Forms::Label^ label1;
private: System::IO::Ports::SerialPort^ serialPort1;
private: System::Windows::Forms::Button^ button3;
private: System::ComponentModel::IContainer^ components;
private:
/// <summary>
/// Required designer variable.
/// </summary>
#pragma region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
void InitializeComponent(void)
{
this->components = (gcnew System::ComponentModel::Container());
this->button1 = (gcnew System::Windows::Forms::Button());
this->button2 = (gcnew System::Windows::Forms::Button());
this->label1 = (gcnew System::Windows::Forms::Label());
this->serialPort1 = (gcnew System::IO::Ports::SerialPort(this->components));
this->button3 = (gcnew System::Windows::Forms::Button());
this->SuspendLayout();
//
// button1
//
this->button1->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 8.25F, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point,
static_cast<System::Byte>(204)));
this->button1->Location = System::Drawing::Point(166, 46);
this->button1->Name = L"button1";
this->button1->Size = System::Drawing::Size(100, 49);
this->button1->TabIndex = 0;
this->button1->Text = L"Открыть порт";
this->button1->UseVisualStyleBackColor = true;
this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
//
// button2
//
this->button2->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 8.25F, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point,
static_cast<System::Byte>(204)));
this->button2->Location = System::Drawing::Point(166, 116);
this->button2->Name = L"button2";
this->button2->Size = System::Drawing::Size(100, 45);
this->button2->TabIndex = 1;
this->button2->Text = L"Закрыть порт";
this->button2->UseVisualStyleBackColor = true;
this->button2->Click += gcnew System::EventHandler(this, &Form1::button2_Click);
//
// label1
//
this->label1->AutoSize = true;
this->label1->Location = System::Drawing::Point(43, 82);
this->label1->Name = L"label1";
this->label1->Size = System::Drawing::Size(35, 13);
this->label1->TabIndex = 2;
this->label1->Text = L"label1";
//
// button3
//
this->button3->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 8.25F, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point,
static_cast<System::Byte>(204)));
this->button3->Location = System::Drawing::Point(166, 184);
this->button3->Name = L"button3";
this->button3->Size = System::Drawing::Size(100, 42);
this->button3->TabIndex = 3;
this->button3->Text = L"Считать данные";
this->button3->UseVisualStyleBackColor = true;
this->button3->Click += gcnew System::EventHandler(this, &Form1::button3_Click);
//
// Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(292, 266);
this->Controls->Add(this->button3);
this->Controls->Add(this->label1);
this->Controls->Add(this->button2);
this->Controls->Add(this->button1);
this->Name = L"Form1";
this->Text = L"Form1";
this->ResumeLayout(false);
this->PerformLayout();
}
#pragma endregion
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
if(!this->serialPort1->IsOpen) //открываем порт
{
this->serialPort1->PortName="COM2"; //у меня ардуино подключен к COM2
this->serialPort1->BaudRate=Int32::Parse("9600"); //скорость подключения
this->serialPort1->Open();
this->button1->Enabled = false;
this->button2->Enabled = true;
}
}
private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) {
this->serialPort1->Close(); //закрываем порт
this->button1->Enabled = true;
this->button2->Enabled = false;
}
private: System::Void button3_Click(System::Object^ sender, System::EventArgs^ e) {
this->label1->Text=this->serialPort1->ReadLine(); //читаем данные ультразвукового датчика и выводим их на метку
}
};
}
Проблема собственно в непрерывном чтении COM-порта в виндовс программе. Работает только по нажатию кнопки (по событию если быть точным), выводятся данные датчика от ардуино в метку. А мне оооооооочень нужно считывать данные непрерывно в реальном времени.
Проблем с управлением например соленоидами подачи воды и прочей периферией с виндовс программы через ардуино не возникает, а вот с чтением ком порта просто тупик. Перелопатил кучу форумов,в том числе и англоязычных, но способ реализовать задачу так и не нашел(возможно в силу своей неопытности). Поэтому прошу помочь умельцев (как последнюю инстанцию) объяснить как считывать порт в реальном времени.
Вам не кажется что вы ошиблись форумом?
string DataRecived = null; private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { DataRecived = serialPort1.ReadLine(); this.Invoke(new EventHandler(TextOut)); } private void TextOut(object sender, EventArgs e) { textBox1.Text = DataRecived; }Вам не кажется что вы ошиблись форумом?
Это уже как минимум второй сумасшедший программист, который без проблем читает показания датчиков из дуино в винду, но не может прочитаь компорт.
Форумом безусловно ошибся!!!Но ошибся сознательно!!!Как показывает практика, когда требуется связать Arduino и Visual C++ именно здешние спецы компетентны и оказывают хорошую помощь (за что ИМ огромное спасибо!!!).
По поводу "второй сумасшедший программист" повеселило)))))))))Ситуация действительно глупая!!!Да получается через ком порт посылать команды на Ардуино ,а ею управлять всевозможными КИПовскими примочками,но вот читать непрерывно порт не выходит!( Так как сам не программист,а КИПовец,но нынешняя задача требует от меня связать это воедино!
maksim ,огромное спасибо Вам за помощь!!! Но в силу малых знаний в данной сфере все утро сегодня пытаюсь связать свой код с Вашим комментарием!Делаю кучу ошибок( Если Вас не затруднит, опишите подробнее как мне скомпоновать мой кодик с Вашим!!!Пока мониторил интернет по данной проблеме, находил посты ребят с такой же проблемой,а благодаря Вам здесь многие смогут найти ответ!!!
Вы просто некомпетентны в программировании вообще. Читать компорт можно как по таймеру так и по событию наличия данных. А вы даже в гугле набрать "Visual c++ serial port recive data event" поленились. http://msdn.microsoft.com/ru-ru/library/system.io.ports.serialport.datareceived.aspx
NeiroN, по поводу некомпетентности , меня это не обижает, так так и есть!А по поводу лени позвольте!!!!!!!!!!!!!!!!!Знаю что ком порт нужно читать отдельным потоком(и именно в нем читать порт), а главный поток должен заниматься всем остальным!Иначе прога попросту зависает(это и неудивительно)так как программа занимается помимо порта еще и прорисовкой и событиями обьектов и так далее!!!!!!!!Пробовал и таймер и цикл while и через BackgroundWorker!!!Поэтому за некомпетентность + ,а за лень -!!!!!!
Но эта полемика проблему не отменяет,а посему если можете растолковать что к чему, будуочень благодарен!!!
Так в чем проблема то ??? Что не получается???
Если я правильно понял, то я должен читать ком порт только по событию!Событием является поступление данных(если что то пришло то только тогда читать данные и прога не будет виснуть) А вот прописать в своем коде правильно обработку этого события не удаетсяне удается.
У меня был написан такой бред, когда нажимаем кнопку button3 то считываем данные с порта
private: System::Void button3_Click(System::Object^ sender, System::EventArgs^ e) { this->label1->Text=this->serialPort1->ReadLine(); //читаем данные ультразвукового датчика и выводим их на метку }А как прописать через DataReceived ?
А как прописать через DataReceived ?
Ну дык вам же ссылочку выше дали, вы ее смотрели? Вы не поверите но там пример именно на DataReceived.
Да вообщем-то и код Максима тоже через DataReceived. Только не на C++, а на C#. Но смысл у них все равно идентичный. Только синтаксис подправить под C++.
#pragma once namespace ultrazvuk { using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; using namespace System::IO::Ports; /// <summary> /// Summary for Form1 /// </summary> public ref class Form1 : public System::Windows::Forms::Form { public: Form1(void) { InitializeComponent(); // //TODO: Add the constructor code here // } protected: /// <summary> /// Clean up any resources being used. /// </summary> ~Form1() { if (components) { delete components; } } private: System::Windows::Forms::Button^ button1; protected: private: System::Windows::Forms::Button^ button2; private: System::Windows::Forms::Label^ label1; private: System::IO::Ports::SerialPort^ serialPort1; private: System::Windows::Forms::Button^ button3; private: System::Windows::Forms::TextBox^ textBox1; private: System::ComponentModel::IContainer^ components; private: /// <summary> /// Required designer variable. /// </summary> #pragma region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> void InitializeComponent(void) { this->components = (gcnew System::ComponentModel::Container()); this->button1 = (gcnew System::Windows::Forms::Button()); this->button2 = (gcnew System::Windows::Forms::Button()); this->label1 = (gcnew System::Windows::Forms::Label()); this->serialPort1 = (gcnew System::IO::Ports::SerialPort(this->components)); this->button3 = (gcnew System::Windows::Forms::Button()); this->textBox1 = (gcnew System::Windows::Forms::TextBox()); this->SuspendLayout(); // // button1 // this->button1->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 8.25F, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point, static_cast<System::Byte>(204))); this->button1->Location = System::Drawing::Point(166, 46); this->button1->Name = L"button1"; this->button1->Size = System::Drawing::Size(100, 49); this->button1->TabIndex = 0; this->button1->Text = L"Открыть порт"; this->button1->UseVisualStyleBackColor = true; this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click); // // button2 // this->button2->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 8.25F, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point, static_cast<System::Byte>(204))); this->button2->Location = System::Drawing::Point(166, 116); this->button2->Name = L"button2"; this->button2->Size = System::Drawing::Size(100, 45); this->button2->TabIndex = 1; this->button2->Text = L"Закрыть порт"; this->button2->UseVisualStyleBackColor = true; this->button2->Click += gcnew System::EventHandler(this, &Form1::button2_Click); // // label1 // this->label1->AutoSize = true; this->label1->Location = System::Drawing::Point(43, 82); this->label1->Name = L"label1"; this->label1->Size = System::Drawing::Size(35, 13); this->label1->TabIndex = 2; this->label1->Text = L"label1"; // // serialPort1 // this->serialPort1->DataReceived += gcnew System::IO::Ports::SerialDataReceivedEventHandler(this, &Form1::serialPort1_DataReceived); // // button3 // this->button3->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 8.25F, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point, static_cast<System::Byte>(204))); this->button3->Location = System::Drawing::Point(166, 184); this->button3->Name = L"button3"; this->button3->Size = System::Drawing::Size(100, 42); this->button3->TabIndex = 3; this->button3->Text = L"Считать данные"; this->button3->UseVisualStyleBackColor = true; this->button3->Click += gcnew System::EventHandler(this, &Form1::button3_Click); // // textBox1 // this->textBox1->Location = System::Drawing::Point(46, 184); this->textBox1->Name = L"textBox1"; this->textBox1->Size = System::Drawing::Size(100, 20); this->textBox1->TabIndex = 4; // // Form1 // this->AutoScaleDimensions = System::Drawing::SizeF(6, 13); this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font; this->ClientSize = System::Drawing::Size(292, 266); this->Controls->Add(this->textBox1); this->Controls->Add(this->button3); this->Controls->Add(this->label1); this->Controls->Add(this->button2); this->Controls->Add(this->button1); this->Name = L"Form1"; this->Text = L"Form1"; this->ResumeLayout(false); this->PerformLayout(); } #pragma endregion private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { if(!this->serialPort1->IsOpen) //открываем порт { this->serialPort1->PortName="COM2"; //у меня ардуино подключен к COM2 this->serialPort1->BaudRate=Int32::Parse("9600"); //скорость подключения this->serialPort1->Open(); this->button1->Enabled = false; this->button2->Enabled = true; } } private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) { this->serialPort1->Close(); //закрываем порт this->button1->Enabled = true; this->button2->Enabled = false; } string DataRecived = null; private: System::Void serialPort1_DataReceived(System::Object^ sender, System::IO::Ports::SerialDataReceivedEventArgs^ e) { { DataRecived = serialPort1.ReadLine(); this.Invoke(new EventHandler(TextOut)); } private void TextOut(object sender, EventArgs e) { textBox1.Text = DataRecived; } } }; }Пробую вот так и конечно ничего не выходит!В примере инициализация ком порта выполнена в теле static void Main(), а у меня по нажатию кнопки Button 1. Вообщем запутался в край!!!Еще там используют #using <System.dll> Мне тоже использовать эту длл-ку?
{ DataRecived = serialPort1.ReadLine(); this.Invoke(new EventHandler(TextOut)); } private void TextOut(object sender, EventArgs e) { textBox1.Text = DataRecived; } Ага одна из ошибок моих!Эта часть наC# ,а я её втулил в таком же виде в C++!!!!!!!!Переписал так
{ DataRecived = serialPort1->ReadLine(); this->Invoke(new EventHandler(TextOut)); } private void TextOut(object sender, EventArgs e) { textBox1->Text = DataRecived; }Тоже не катит(
Да и убрал обработку третьей кнопки ,да и вообще её убрал
>В примере инициализация ком порта выполнена в теле static void Main()
Вот и вы начните с этого примера. Обычная консольная аппликуха. Вначале в ней научитесь читать порт по событию, а не из основного потока.
А то вы сразу схватились за приложение на WinForms. Там, извините, порог вхождения намного больше чем в ардуино. Ардуино - намного проще того что нынче требуется для того что-бы написать приличное windows-приложение. Пользователи - они балованные стали. Потом разберетесь с жизненным циклом Form. Какие события происходят при загрузке формы, при старте приложения. При закрытии (освобождать порт тоже нужно не забывать). Научитесь апдейтить UI не из главного потока.
Вот тогда и формочка напишется. Если "серьезно и красиво" хотите, а не поделку "три кнопки, два поля". То лучше, наверное перейти на C#/WPF. Но там и с XAML прийдется разбиратся, учится строить правильную архитектуру. Познакомится с MVC и хреновой тучей его реализаций.....
По поводу вашей попытки.
Ну во первых нужно пнуть за "тоже не катит". Очень информативно. Не компилируется, не ловит, зависает? Что вам тут ответить? Ну значит "где-то лажа".
Во вторых, вы явно не поняли сути события. Оно срабатывает когда в сериал пришли данные. Но вам никто не гарантировал что "они пришли целиком". Может только пол строки к этому моменту успело попасть в буффер. Поэтому ReadLine - немного не уместно. Вам нужно "прочитать что пришло". Если вы собираетесь "сразу выводить" - можете вывести и кусочек, если хотите что-бы выводило построчно, значит нужно "куда-то запомнить". Пока не прийдется следующая порция данных. Когда пришла очередная, ищете в ней символ \n (символ конца строки), когда пришло - вот тогда уже выводите что вы там из кусочков "насобирали". Все это "натренироватся" можно в консольном приложении.
В третьих: вас не смущает что вы попытались слепить два примера написанных на разных языках? Один на C++ второй на C# . Я вроде даже указал что пример Максима на C# написан и нужно править синтаксис.
Тут кстати, если новичок, то не очень понятен изначальный выбор C++ в качестве языка написания. C# оно как-бы меньше способов выстрелить себе в ногу, не нужно с указателями быть на "Вась-Вась" и т.п.. Да и у Visual Studio это все-таки "основной язык". Расплата за это, конечно - необходимость иметь на машине .net framework, что автоматом означает что работать будет только под windows. Но если прога пришется "для себя", то не такая уж и большая плата за удобство. К тому же, даже если вы на C++ напишите с использованием WinForms - не уверен что но где-то кроме винды запустится.
Приложение пишу для себя и использовать буду только под виндовс. Нужно это по работе. Для управления проливной установкой для уровнемеров. Нужно из программы управлять подачей воды и сливом воды (нажатием кнопок в программе). Эта часть получилась без проблем, открываю порт и шлю комады в ардуино, все работает!!!А считывать ком порт необходимо так как хочу внизу установки поместить датчик избыточного давления (отградуированного в ммВодяного столба) а по его показаниям определять уровень воды в установке. Показания датчика хочу выводить в любое место программы, хоть в lable хоть в textBox не принципиально!Вот все что нужно!!!!!!Только чтоб данные выводились в реальном времени!!!Как это исполнить?
>Как это исполнить?
Ну видимо - никак. Ответы вам уже дали, но вам они ничего не говорят. Что тут дальше можно? Два варианта, либо повторить все еще раз, либо садится и писать за вас код.
Вы хотя-бы пример из ссылки взяли, запустили его?
Только чтоб данные выводились в реальном времени!!!Как это исполнить?
Я запретил виндузятникам читать компорт в реальном времени, поэтому - только командная строка.
К чему пост ??????????????????????????????
Господа,благодарю адекватных людей за помощь, если говорите что по вышесказанному можно реализовать задачу, значит разберусь, по окончанию выложу код здесь. Чтобы люди могли пользоваться. В любом случае сделаем с Вами полезное дело!!!
Господа,благодарю адекватных людей за помощь, если говорите что по вышесказанному можно реализовать задачу, значит разберусь, по окончанию выложу код здесь. Чтобы люди могли пользоваться. В любом случае сделаем с Вами полезное дело!!!
это правильно - неадекватных благодарить не нужно.
Добрый день. Тоже вожусь с COM портом. В принципе давно всё работает. Но сейчас у меня задача отправлять очень большой поток данных, и к сожалению установленная скорость в 115200бит/сек не достигается.
С учетом стартовых и стоповых битов скорость должна быть около 11520байт/сек, но в реале наблюдаю раз в десять меньше. Полагаю что это из-за ОС Windows. Т.е. информация дошла вовремя, но вот получение ее заторможена сторонними событиями. (т.к. Windows не есть RTOS).
Решил обойти эту неловкую ситуацию следующим образом:
1.) Получаю первай байт - он будет сигнализировать о начале передачи большого пакета (8000байт).
2.) отключаю событие по приему данных через последовательный порт (здесь проблема.... не пойму как это сделать)
3.) Выжидаю 1 сек ( при скорости11520байт/с этого должно быть более чем достаточно)
4.) Читаю все полученные 8000байт
Уважаемые форумчанене, имеет ли такой план право на жизнь ? Если да то как быть со вторым пунктом (пишу на с++ в Windows Form).
Заранее благодарю.
Могу посоветовать только это
http://www.hiasm.com/sdk.html
Долго мучался с C++, для C# полно примеров, а для VC++ их нет. Пример из MSDN'a неудобный - он не позволяет выводить текст из COM-порта в элементы формы. Спустя 3 часа мучений наклепал правильный код:
//В самом начале кода формы объявляем делегат public delegate void updateDelegate(String^ message); //Затем в конструкторе формы добавляем к объекту SerialPort (у меня имя serialPort1) событие DataReceived //После добавления в коде конструктора формы появится такая строчка this->serialPort1->DataReceived += gcnew System::IO::Ports::SerialDataReceivedEventHandler(this, &Form1::serialPort1_DataReceived); //И процедура serialPort1_DataReceived. В нее пишем такой код private: System::Void serialPort1_DataReceived(System::Object^ sender, System::IO::Ports::SerialDataReceivedEventArgs^ e) { SerialPort^ sp = (SerialPort^)sender; String^ message = sp->ReadLine(); this->BeginInvoke(gcnew updateDelegate(this, &Form1::DataReceivedDelegate), message); } private: System::Void DataReceivedDelegate(String^ message) { if (message->IndexOf("arduino") > -1) { //У меня кодовое слово - "arduino" ))) //Тут можно сделать любые нужные вам манипуляции с сообщением из COM-порта textBox1->Text = message; //Выводим сообщение в текстовое поле. } else { textBox1->Text = "Пришел некорректный ответ"; } serialPort1->Close(); }Если есть вопросы - задавайте
Помогите. Arduino UNO. Посылает две строки со значениями.
{
Serial.print("T");
Serial.println(analogRead(A0));
delay(1);
Serial.print("H");
Serial.println(analogRead(A1));
delay(1);
}
Как этот массив принять в textBoxы я могу его принять полностью он состоит из двух строк
Как эти строки разложить в разные textBox1 и textBox2 и убрать первые символы "H" , "T" потому что
должны остаться циферные значения для преобразования в int тип. СПАСИБО БОЛЬШОЕ. Пишу на Visual Studio C++
Здравствуйте. Если вам не сложно можете помочь мне.
Нужно отправить массив значений в COM порт.
У меня есть массив DataDiscrete
не получается отправить
#pragma once unsigned __int8 DataDiscrete[8] = {1,1,1,1,1,1,1,1}; // Массив который нужно отправить namespace My { using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; using namespace System::IO::Ports; ary> private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) { this->serialPort1->Close(); //закрываем порт this->button1->Enabled = true; this->button2->Enabled = false; this->PortText->Text = "ЗАКРЫТ"; } private: System::Void but4_Click(System::Object^ sender, System::EventArgs^ e) { DataDiscrete[2] = 1; } private: System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e) { //if(this->but1->IsClick) {DataDiscrete |= 1;} else {DataDiscrete &= ~1;} //-------------------- ДАЛЕЕ МНОГО КОДА--------------------// // ЗДЕСЬ ОБРАБОТЧИК ТАЙМЕРА if(this->serialPort1->IsOpen) { this->serialPort1->Write(DataDiscrete,0,7); //В этой строчке ошибка !!!!!!!!!!!!!!!!!!!!!!!!!!!!! } // Конец обработчика private: System::Void but2_Click(System::Object^ sender, System::EventArgs^ e) { DataDiscrete[1] = 1; } private: System::Void but3_Click(System::Object^ sender, System::EventArgs^ e) { DataDiscrete[1] = 0; DataDiscrete[2] = 0; } private: System::Void but5_Click(System::Object^ sender, System::EventArgs^ e) { DataDiscrete[3] = 1; } private: System::Void but7_Click(System::Object^ sender, System::EventArgs^ e) { DataDiscrete[4] = 1; } private: System::Void but6_Click(System::Object^ sender, System::EventArgs^ e) { DataDiscrete[3] = 0; DataDiscrete[4] = 0; } private: System::Void but8_Click(System::Object^ sender, System::EventArgs^ e) { DataDiscrete[5] = 1; } private: System::Void but10_Click(System::Object^ sender, System::EventArgs^ e) { DataDiscrete[6] = 1; } private: System::Void but9_Click(System::Object^ sender, System::EventArgs^ e) { DataDiscrete[5] = 0; DataDiscrete[6] = 0; } }; }