Использование Windows Form в качестве последовательного коммуникатора для Arduino Uno - PullRequest
0 голосов
/ 05 сентября 2018

Я новичок в Arduino и последовательной связи, и я давно не программировал, но я пытаюсь сделать то, что, на мой взгляд, должно быть довольно простым, и у меня было много проблем. Я хотел бы создать простой графический интерфейс в Windows Forms и управлять Arduino. Кажется, я каждый раз сталкиваюсь с разными проблемами.

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

Когда я пытаюсь вызвать функцию blink, она не мигает должным образом в операторе if по сравнению с тем, удерживаю ли я ее в цикле. Я не уверен, как и где отправить значение из Winform в Arduino.

Отличается ли Winform от команд последовательного монитора?

EDIT1: я отошел от своего компьютера, и теперь, когда я запускаю форму Windows, она не показывает ошибок, но программа завершила работу с кодом 0 (0x0). У меня был таймер, и я его пока что не особо испортил, но раньше он не сообщал мне об этой ошибке, и форма работала нормально.

Мой код Arduino:

// Define Function Prototypes that use User Types below here or use a .h file

    int dorun;
    int Blinks;

    void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(9600);
getBlinks();
    }

    // the loop function runs over and over again forever
    void loop()
    {


if (Serial.available() > 0)
    /*
{
    byte Blinktimes = Serial.readBytes[];

}
*/
{
    String serialInput = Serial.readString();
    //Toggle LED
    if (serialInput == "On")    
        {
            digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); //I have this just to see that the LED is staying on and off, and will need to change things.
             for (int x = 1; x = Blinks; x++)
                {
                        blink();
                }
        }
    else
        {
            digitalWrite(LED_BUILTIN, LOW);   // turn the LED on (LOW is the voltage level)

        }
    Serial.flush();                         //Clear Serial
}
/*
digitalWrite(LED_BUILTIN, HIGH);
if ((Serial.available()))
{
    int dorun = Serial.read();
    if (dorun = 1)
    {
        blink();
    }
    else
    {
        digitalWrite(LED_BUILTIN, LOW);
    }
}
*/



/*turnon();
if (dorun == 1)
{
    blink();
}
else
{
    digitalWrite(LED_BUILTIN, LOW);
}
*/

    }
    void getBlinks()
    {
        byte message[3];
        if (Serial.available())        
        {
            Serial.readBytes(message, 3);
            Blinks = message[3];
        }
    }

    void blink()
    {
        digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the 
        voltage level)
        delay(250);                       // wait for a second
        digitalWrite(LED_BUILTIN, LOW);  //!digitalRead(LED_BUILTIN);    // turn the LED off by making the voltage LOW
        delay(1000);
    }

    void turnon()
    {
        if (Serial.available()> 0)
        {
            String run = Serial.readString();
            if (run == "Run")
            {
                dorun == 1;
            }
            if (run == "Off")
            {
                dorun == 0;
            }
        }
    }                

Мой код формы Windows

using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using System.IO.Ports;


    namespace WindowsFormsApp9
    {

        public partial class Form1 : Form
        {
            SerialPort serial;          // create serial port
                                        /*
    * public class Port
    {
    public string Name { get; set; }
    public int Value { get; set; }
    public Port(string n, int i)
    {
        Name = n;
        Value = i;
    }
    }
                                    */
            SerialPort port;
            string[] availablePorts = SerialPort.GetPortNames();
            public Form1()
            {
                InitializeComponent();
            }
        private void button1_Click(object sender, EventArgs e)
            {
        port = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
        port.Open();
        port.Write("On");
        port.Close();

    }
private void button2_Click(object sender, EventArgs e)
    {
        port = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
        port.Open();
        port.Write("Off");
        port.Close();

    }
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
    {
        UpdateBlink();
    }
void UpdateBlink()
    {
        port = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
        port.Open();
        const byte messageType = 2;
        byte Blinkcount = (byte)numericUpDown1.Value;
        byte[] serialBlink = { messageType, Blinkcount };
        serialPort1.Write(serialBlink, 0, serialBlink.Length);
        port.Close();

    }





    private void timer1_Tick(object sender, EventArgs e)
    {

    }

    private void Form1_Load(object sender, EventArgs e)
    {

    }

    private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    {

    }

Я проверял эти ссылки:

Нажмите здесь Как переключить светодиод

Нажмите здесь Как вернуть int, так как NumericUpDown возвращает десятичную Нажмите [здесь] (https://www.instructables.com/id/Arduino-Visual-Studio-Serial-Communication/) Arduino Visual Studio. Таймер последовательной связи Нажмите [здесь] (https://www.instructables.com/id/Communication-From-a-WinForms-to-a-TinyDuino/) инструкции о Winforms to TinyDuino, они должны использовать те же команды, что и Arduino, верно?


Поэтому я решил сделать небольшой ремонт. Вместо того, чтобы пытаться справиться с отправкой нескольких различных типов входных данных (String и int), я решил просто изменить все в байтовый массив и затем отправить все сразу.

Относительно 1. Мне действительно просто было интересно, можно ли было бы создать функцию, возвращающую значение, а не просто построить код в функции void. Поэтому я попробовал, и это сработало, отсюда и изменения Из того, что я понял и увидел, что ваше защищенное переопределение bool ProcessCmdKey, в основном вы хотели увидеть, является ли клавиша клавишей со стрелкой. Если это было так, верни истину. Так что я сделал в основном, если это один из выбранных цветов, вернул значение, соответствующее цвету.

  1. Я просто надеялся, что вы либо поможете мне понять соединение через последовательный и COM-порт, либо если у вас есть ссылка для более подробного объяснения. Ранее, когда я пытался отправить строку (вкл. / Выкл.), А затем отправить числовое значение (byte / int), чтобы установить количество морганий, я не мог понять, похож ли COM-порт на отдельный канал. Если я отправляю строку из формы Windows, могу ли я отправить байт int / в том же канале? Теперь, когда все состоит из одного ключевого слова (байта), я могу просто создать байтовый массив и выяснить связь между Windows Form и Arduino. Я немного запутался по поводу основного аспекта Serial. Когда я увидел твой код, я начал думать немного по-другому.

В вашем коде, если я правильно понимаю, кажется, что MyVCOM - это способ обмена данными, как port.Write. Я считаю, что это единственное число, так как оно в основном похоже на старую телефонную линию, если я нахожусь на вызове, и вы звоните, попробуйте позвонить мне, ваш вызов заблокирован, так как моя линия уже используется.Итак, в вашем ConnReset вы хотите убедиться, что COM не открыты, чтобы вы могли настроить связь. Таким образом, ваш ConReset очистит линию, если она уже открыта. Что меня смущает, так это остальная часть. Если ваш порт не открыт, откройте COM + PortNumber, поэтому в основном откройте канал, чтобы вы могли общаться, но вы объявили номер порта равным 8, поэтому вы не должны просто использовать:

MyVCOM.PortName = "COM8";

Где пользователь выбирает, какой COM? Все общение происходит на COM8, не так ли? Или эта часть является частью встроенной библиотеки? Я считаю, что все, что мне нужно сейчас сделать, - это отправить мой байтовый массив в Arduino, а затем поработать на бэк-энде, чтобы получить данные, которые отправляет форма Windows.

        public int Colorselection(string label3, int color)     //Toggle a pin 
    {
        if (label3 == "Red")
        {
            color = 6;
        }
        else if (label3 == "Green")
        {
            color = 5;
        }
        else if (label3 == "Blue")
        {
            color = 3;
        }
        return color;
    }
    private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
    {
        String label4 = LEDColor.SelectedItem.ToString();               //Generate A string of selected Color
        int xled = Colorselection(label4, color);                       //Toggle the string into an int
        LEDLabel.Text = xled.ToString();                                //Generate a string from the int
    }

    private void Run_Click(object sender, EventArgs e)                  //Generate byte to send instead of sending strings and int/byte
    {
        byte RGBLED = Convert.ToByte(color);
        byte BlinkNum = Convert.ToByte(number1.Value);
        byte BlinkDur = Convert.ToByte(number2.Value);
        byte[] array2 = new byte[] { RGBLED, BlinkNum, BlinkDur };
        port = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
        /*
        port.Open();
        port.Write(array2, 0, 2);
        port.Close();
        */
    }

1 Ответ

0 голосов
/ 05 сентября 2018

Ваше приложение WinForms предполагает, что ваш Arduino подключен к COM3. Вы знаете, так ли это на самом деле, или это пример кода, который вы просто копируете и вставляете? (Проверьте диспетчер устройств Windows в разделе COM-порты, чтобы увидеть, какие порты доступны, затем отключите / подключите ваше устройство, чтобы увидеть, к какому порту оно подключено)

Кроме того, пытались ли вы отладить свой код Arduino на цели, чтобы увидеть, что, если вообще что-то, на самом деле принимается?

Из документации MS не ясно, как команда SerialPort.Write работает точно с точки зрения синхронизации, поэтому может быть плохой идеей закрыть порт сразу после отправки вашей команды. К сожалению, поскольку у меня нет Arduino, я не могу проверить ваш код. Но я создал WinForms GUI для выполнения по существу той же задачи (и больше, что вам, вероятно, не нужно) несколько лет назад, которую я с тех пор опубликовал на github (https://github.com/mbhul/RoboCOM). Дайте мне знать, если это поможет, в противном случае расскажите, пожалуйста, подробнее о вашей среде разработки.

...