Arduino (serial) + Visual studio C# - помогите пжт разобраться.

finker
Offline
Зарегистрирован: 27.04.2012

 Задумка такая:

С ПК управлять 2мя светодиодами по serial arduino uno.

НА пк создаем программку на Visual studio C# с 4мя кнопками и одним окошком которое выдает состояние включен или выключено светодиод.

Суть вопроса в том что управление для 1го светодиода понял как сделать, а как для двух не могу понять

помогите пжт - как присвоить значение для разных светодиодов ?

что прописывать в C# и ARDUINO - как определить для какого светодиода подается команда ?

код для arduino 

void setup()   
{                
  pinMode(13, OUTPUT); 
  Serial.begin(9600);  
}

void loop()                     
{
  if(Serial.available())
  {
    int c = Serial.read();
    if (c == '1')
    {    
      digitalWrite(13,HIGH);
      
    }
    else if (c == '0')
    {
      digitalWrite(13,LOW);
    }
  } 
}

код для C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace SerialCommunication
{
    public partial class Form1 : Form

    {
        bool ledState = false;
        public Form1()
        {
            InitializeComponent();
            serialPort1.PortName = "COM3";
            serialPort1.BaudRate = 9600;
            serialPort1.Open();

           
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            serialPort1.Write("1");
            textBox1.Text = "1 LED ON";
            button1.Enabled = false;
            button2.Enabled = true;
            ledState = true;   

        }

        private void button2_Click(object sender, EventArgs e)
        {
            serialPort1.Write("0");
            textBox1.Text = "1 LED OFF";
            button1.Enabled = true;
            button2.Enabled = false;
            ledState = false;

          }

        private void button3_Click(object sender, EventArgs e)
        {
            serialPort1.Write("1");
            textBox1.Text = "2 LED ON";
            button3.Enabled = false;
            button4.Enabled = true;
            ledState = true;
        }

        private void button4_Click(object sender, EventArgs e)
        {
            serialPort1.Write("0");
            textBox1.Text = "2 LED OFF";
            button3.Enabled = true;
            button4.Enabled = false;
            ledState = false;
        }
    }
}

 

 

finker
Offline
Зарегистрирован: 27.04.2012

 простите 2 раза скрин прикрепил - и небольшая ошибка в название кнопки "1LED OFF" - так правильно.

Intr
Offline
Зарегистрирован: 15.06.2012

Здравствуйте

вот посмотрите мой код вот тут http://arduino.ru/forum/programmirovanie/pomogite-s-kodom-0 Там основано управление всеми портами с командами типа 01-54(h-l) тоесть захотели включить 13 пин послали в порт 13h а если выключить 13l

Kitam1n
Offline
Зарегистрирован: 11.04.2012

Ну код ты походу не сам писал, почему у тебя C# отправляет одни и те же команды "0" и "1"? поменяй на вторые две кнопки на 2 и 3 например.

А в скетче нужно добавить что при получении 2 и 3 соответсвенно будет включаться например 12 пин.

leshak
Offline
Зарегистрирован: 29.09.2011

Ну самый "тупой" вариант - увеличить количество комманд. Сейчас вы шлете "1" "0" включить выключить, можно просто "раскопипастать код" и абсолютно аналогично слать "1/0" для первого диода, "2/3" - для второго, "3/4" для третьего и т.п. Это если делать "в индусячем стиле" (им когда-то платили за работу "построчно", отсюда и стиль такой пошел). Более умно - перейти от однобайтовых комманд, к двух-байтовым. Слать два байта. Например первым - номер диода, вторым - что с ним нужно сделать. Какие-то команды вида "0N" - влючить первый, "2N" - включить третий, "1F" выключить второй. Тогда, со стороны ардуины, вы будете работать примерно так:

if(Serial.avaliable()){
  byte ledIndex=Serial.read()-48; // прочитали индекс диода и сразу перевели его из строки, в целое
  
   //по хорошему тут нужно еще сделать проверку, что индекс у нас в допустимых значених, что это "не какой-то мусор".
   while(!Serial.avaliable()){} // ждем пока не прийдется следующий символ
   char action=Serial.read();
   switch(action){
     case 'N':
            digitalWrite(LED_PINS[ledIndex],HIGH);
            break;
     case 'F":
            digitalWrite(LED_PINS[ledIndex],LOW);
            break;
     default: 
            Serial.println("Error:Unknown command");
   }
}

А можно, вместо изобретения "своего протокола", посмотреть в сторону библиотеки http://arduino.cc/en/Reference/Firmata

Где уже реализован протокол для управления пинами через Serial (и опрос их состояний). Если погуглить - думаю и со стороны C# имеются либы реализующие этот протокол.

 

finker
Offline
Зарегистрирован: 27.04.2012

 всем огромное спасибо ! с кодом и C# разобрался.

 

finker
Offline
Зарегистрирован: 27.04.2012

 вот готовый код программы и скрин

для ARDUINO 

void setup()   
{                
  pinMode(13, OUTPUT); 
  Serial.begin(9600);  
  delay(1000);
}

void loop()                     
{
  if(Serial.available())
  {
    int c = Serial.read();
    if (c == 'a')
    {    
      digitalWrite(13,HIGH);
      
    }
    else if (c == 'b')
    {
      digitalWrite(13,LOW);
    }
    
    if (c == 'c')
    {    
      digitalWrite(12,HIGH);
      
    }
    else if (c == 'd')
    {
      digitalWrite(12,LOW);
  } 
  }
}


ДЛЯ C#


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace SerialCommunication
{
    public partial class Form1 : Form

    {
        bool ledState = false;
        public Form1()
        {
            InitializeComponent();
            serialPort1.PortName = "COM8";
            serialPort1.BaudRate = 9600;
            serialPort1.Open();

           
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            serialPort1.Write("a");
            textBox1.Text = "LED1 ON";
            button1.Enabled = false;
            button2.Enabled = true;
            ledState = true;   

        }

        private void button2_Click(object sender, EventArgs e)
        {
            serialPort1.Write("b");
            textBox1.Text = "LED1 OFF";
            button1.Enabled = true;
            button2.Enabled = false;
            ledState = false;

        }

        private void button3_Click(object sender, EventArgs e)
        {
            serialPort1.Write("c");
            textBox2.Text = "LED2 ON";
            button3.Enabled = false;
            button4.Enabled = true;
            ledState = true;   
        }

        private void button4_Click(object sender, EventArgs e)
        {
            serialPort1.Write("d");
            textBox2.Text = "LED2 OFF";
            button3.Enabled = true;
            button4.Enabled = false;
            ledState = false;
        }

        

       
                    
        }
    }
}

 

finker
Offline
Зарегистрирован: 27.04.2012

 парни помогите пжт создать еще 2 условия

1) условие:

Как в коде прописать чтобы по выключению программы на ПК - выключались светодиоды на ардуинке ???

 

2) условие:

Хочу немного доработать программку вместо окошечка с надписями "1LED ON" .... был просто статус (какое-нибудь окошечко которое просто индицирует цветом что светодиод включен) - копать в сторону "progressbar" ?

leshak
Offline
Зарегистрирован: 29.09.2011

 >Как в коде прописать чтобы по выключению программы на ПК - выключались светодиоды на ардуинке ???

На на событии закрытя приложения/окна отсылать "bd" или сделать еще одну букву "f" которая "гасит все" и отсылать ее.

Но это будет работать только если "приложение нормально закрыли". Если тупо "выдернули шнур", "срубили процесс", выключили комп из розестки - это не сработает.

Если нужно и такие ситуации отрабатывать, то нужно что-бы дуина слала, например, раз в пол секунды, какую-то букву компу, а тот должен отвечать. Если ответа нет, скажем в течении секунды - гасить все.

 

>2) условие:

Ну это скорее уже на форумах под .net искать нужно. Среди тех кто до сих пор на WinForms пишет. Посмотреть что-то типа custom контрол. Где ты сам отрисовку задаешь. Отрисовать какой-то прямоугольник, ну и менять его цвет его отрисовки в зависимости от состояния.

Если лениво кастомынй делать - можно взять банальную кнопку. Не писать на нее никаого текста. Сделать ее disable. Ну и менять ей свойство типа Background color. Или не кнопку а label, с пустой строкой. Вообщем подобрать что-то из стандартных котролов и "замаскировать их под прямоугольник" выставляем свойств.

snailmaster
snailmaster аватар
Offline
Зарегистрирован: 15.12.2011

Подскажите в какой С# вы работаете , или дайте ссылочку на програму

finker пишет:

 Задумка такая:

С ПК управлять 2мя светодиодами по serial arduino uno.

НА пк создаем программку на Visual studio C# с 4мя кнопками и одним окошком которое выдает состояние включен или выключено светодиод.

Суть вопроса в том что управление для 1го светодиода понял как сделать, а как для двух не могу понять

помогите пжт - как присвоить значение для разных светодиодов ?

что прописывать в C# и ARDUINO - как определить для какого светодиода подается команда ?

код для arduino 



void setup()   
{                
  pinMode(13, OUTPUT); 
  Serial.begin(9600);  
}

void loop()                     
{
  if(Serial.available())
  {
    int c = Serial.read();
    if (c == '1')
    {    
      digitalWrite(13,HIGH);
      
    }
    else if (c == '0')
    {
      digitalWrite(13,LOW);
    }
  } 
}

код для C#



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace SerialCommunication
{
    public partial class Form1 : Form

    {
        bool ledState = false;
        public Form1()
        {
            InitializeComponent();
            serialPort1.PortName = "COM3";
            serialPort1.BaudRate = 9600;
            serialPort1.Open();

           
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            serialPort1.Write("1");
            textBox1.Text = "1 LED ON";
            button1.Enabled = false;
            button2.Enabled = true;
            ledState = true;   

        }

        private void button2_Click(object sender, EventArgs e)
        {
            serialPort1.Write("0");
            textBox1.Text = "1 LED OFF";
            button1.Enabled = true;
            button2.Enabled = false;
            ledState = false;

          }

        private void button3_Click(object sender, EventArgs e)
        {
            serialPort1.Write("1");
            textBox1.Text = "2 LED ON";
            button3.Enabled = false;
            button4.Enabled = true;
            ledState = true;
        }

        private void button4_Click(object sender, EventArgs e)
        {
            serialPort1.Write("0");
            textBox1.Text = "2 LED OFF";
            button3.Enabled = true;
            button4.Enabled = false;
            ledState = false;
        }
    }
}

 

 

Intr
Offline
Зарегистрирован: 15.06.2012


void setup()   
{                
  pinMode(13, OUTPUT); 
pinMode(10, OUTPUT); 
  Serial.begin(9600);  
}

void loop()                     
{
  if(Serial.available())
  {
    int c = Serial.read();
    if (c == '1')
    {    
      digitalWrite(13,HIGH);
      
    }
    else if (c == '0')
    {
      digitalWrite(13,LOW);
    }
else if (c=='3');  //Тут ловиш с компа число 3 и включаешь 10 пин
{
digitalWrite(10,HIGH);
}
    else if (c == '4') // Тут ловиш 4 и выключаеш 10 пин
    {
      digitalWrite(10,LOW);
    }

  } 
}

В программе на button3 и 4 замени отсылаемые циферки на соответствующие

С кодом могу ошибаться если чесно но суть надеюсь ясна :))) просто с мобилки во первых не удобно писать да и не занимался ардуинкой уже 100 лет забыл уже что и как.

 
 
snailmaster
snailmaster аватар
Offline
Зарегистрирован: 15.12.2011

Попытался я повторить ваш пример , чтото у меня нечего не получилось при компиляции пишет 

Ошибка 2 Имя "serialPort1" отсутствует в текущем контексте c:\users\snail\documents\visual studio 2012\Projects\WindowsFormsApplication1\WindowsFormsApplication1\Form1.cs 20 13 WindowsFormsApplication1

Где и что надо исправить???

Intr
Offline
Зарегистрирован: 15.06.2012
using System;
02	using System.Collections.Generic;
03	using System.ComponentModel;
04	using System.Data;
05	using System.Drawing;
06	using System.Linq;
07	using System.Text;
08	using System.Windows.Forms;
09	 
10	namespace SerialCommunication
11	{
12	    public partial class Form1 : Form
13	 
14	    {
15	        bool ledState = false;
16	        public Form1()
17	        {
18	            InitializeComponent();
19	            serialPort1.PortName = "COM3";
20	            serialPort1.BaudRate = 9600;
21	            serialPort1.Open();
22	 
23	            
24	        }
25	 
26	        private void textBox1_TextChanged(object sender, EventArgs e)
27	        {
28	 
29	        }
30	 
31	        private void Form1_Load(object sender, EventArgs e)
32	        {
33	 
34	        }
35	 
36	        private void button1_Click(object sender, EventArgs e)
37	        {
38	            serialPort1.Write("1");
39	            textBox1.Text = "1 LED ON";
40	            button1.Enabled = false;
41	            button2.Enabled = true;
42	            ledState = true;  
43	 
44	        }
45	 
46	        private void button2_Click(object sender, EventArgs e)
47	        {
48	            serialPort1.Write("0");
49	            textBox1.Text = "1 LED OFF";
50	            button1.Enabled = true;
51	            button2.Enabled = false;
52	            ledState = false;
53	 
54	          }
55	 
56	        private void button3_Click(object sender, EventArgs e)
57	        {
58	            serialPort1.Write("3");  //Тут изменения
59	            textBox1.Text = "2 LED ON";
60	            button3.Enabled = false;
61	            button4.Enabled = true;
62	            ledState = true;
63	        }
64	 
65	        private void button4_Click(object sender, EventArgs e)
66	        {
67	            serialPort1.Write("4");  //Тут изменения
68	            textBox1.Text = "2 LED OFF";
69	            button3.Enabled = true;
70	            button4.Enabled = false;
71	            ledState = false;
72	        }
73	    }
74	}

А что за ошибка я без понятия...

snailmaster
snailmaster аватар
Offline
Зарегистрирован: 15.12.2011

Вот что пишет

Intr
Offline
Зарегистрирован: 15.06.2012

Если не ошибаюсь нужно подключить соответствующую библиотеку.

snailmaster
snailmaster аватар
Offline
Зарегистрирован: 15.12.2011

Intr пишет:

Если не ошибаюсь нужно подключить соответствующую библиотеку.

Подскажи как это зделать и какую ?

 

Intr
Offline
Зарегистрирован: 15.06.2012

А вот в этом я не советчик :)) с вижул студио никогда не работал ))) как то все делфя и блокнот )))

leshak
Offline
Зарегистрирован: 29.09.2011

Не, библиотеку подключать это если-бы оно вопило что "я не знаю что это за имя класса". А оно вопит "я не знаю что за ПЕРЕМЕННАЯ serialPort1".

Значит вам нужно либо-таки объявить самому эту переменную (поле) типа System.IO.Ports.SerialPort и создать ее через вызов конструктора либо "бросить компонент Serial и дать ему имя " на эту форму в визуальном конструкторе формы serialPort1 (что видимо и делал Intr).

Обратите внимение на слово partial в объявлении класса. Оно значит что в этом файле мы видим только "кусочек описания класса Form1", а где-то в другом файле есть еще описание его методов, свойст, полей. Это "еще" генерится конструктором формы автоматом. Вот вы же пользуетесь переменнымы/полями button1, button2, textBox3.... а объявления их не видно :) Это потому что вы "бросили их на форму" и вижуал студиа уже сгенерировала в связанном файле их объявления и инициализацию. Вот и serial1 нужно так же "бросить".

Только не пытайтесь править руками этот "автоматом сгенеренный". Оно все равно будет еге перегенеривать при любом изменении формы. Так что либо "в визуальном конструкторе добавляйте", либо руками в тот файл листинг которого приведен выше.

 

 

 

snailmaster
snailmaster аватар
Offline
Зарегистрирован: 15.12.2011

Вот текс программы вроде с ком портом разобрался , теперь матерится на строку "SerialPort.Write("1");" говорит что надо зделать ссылку на объект , не могу понять как!!!

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



namespace SerialCommunication
{
public partial class Form1 : Form

{
bool ledState = false;
public Form1()
{
SerialPort _serialPort = new SerialPort("COM2");

_serialPort.Open();
}

private void textBox1_TextChanged_1(object sender, EventArgs e)
{

}

private void Form1_Load(object sender, EventArgs e)
{

}

private void button1_Click_1(object sender, EventArgs e)
{
SerialPort.Write("1");
textBox1.Text = "LED1 ON";
button1.Enabled = false;
button2.Enabled = true;
ledState = true;
}

private void button2_Click_1(object sender, EventArgs e)
{
SerialPort.Write("0");
textBox1.Text = "LED1 OFF";
button1.Enabled = true;
button2.Enabled = false;
ledState = false;
}

private void button3_Click_1(object sender, EventArgs e)
{
SerialPort.Write("3");
textBox1.Text = "LED2 ON";
button3.Enabled = false;
button4.Enabled = true;
ledState = true;
}

private void button4_Click_1(object sender, EventArgs e)
{
SerialPort.Write("4");
textBox1.Text = "LED2 OFF";
button3.Enabled = true;
button4.Enabled = false;
ledState = false;
}

}
}

 

snailmaster
snailmaster аватар
Offline
Зарегистрирован: 15.12.2011

Всем спосибо , разобрался , подскажите как теперь создать рабочее приложение???? , как его прокомпилировать???

artem9317
Offline
Зарегистрирован: 12.08.2015

Скажите пожалуйста а как разобрались? У меня то же самое "атерится на строку "SerialPort.Write("1");" говорит что надо зделать ссылку на объект , не могу понять как!!!"

artem9317
Offline
Зарегистрирован: 12.08.2015

А так же пишет

Имя "serialPort1" отсутствует в текущем контексте