Помогите с кодом ардуино и visual studio

vova271
Offline
Зарегистрирован: 13.11.2020

ДВС. От программирования далек, больше паяю. Но возникла необходимость (или блажь?) в применении ардуины. Уже НЕДЕЛЮ бьюсь над освоением arduino.exe и visual studio, ничего не получается. Может подскажите, покажете что где не так. При  раздельном выполнении кодов для сервоприводов x и y проблем нет. Как только объединяю скетчи в один глючит серво x. Он вроде поворачивается согласно положению трекбара, но всё время срывается в положение 0 градусов. И кнопки управления серво y срабатывают через раз.

Собственно скетч ардуино:

#include <Servo.h> // подключаем библиотеку для серво
Servo y; // объявляем переменную серво
Servo x;
int val; // переменная чтения с com
int angle; // переменная для угла поворота серво y
int xval;// переменная для угла поворота серво x

void setup() {
   Serial.begin(115200); // подключаем com порт
   y.attach(6); // привязываем серво к выходу 6
   y.write(0);
   x.attach(5); // привязываем серво к выходу 5
   x.write(0);
}
//управление сервой y посредством кнопок с проги с 90 до  0 и обратно
void loop() {
   // проверяем, поступают ли какие-то команды
   if (Serial.available())
 {
      val = Serial.read(); // переменная val равна полученной команде

       if (val == 'C') 
{
  // цикл для поворота от 0 до 90 градусов при передаче в com с проги буквы С
  while (angle < 90) // чтоб кнопки в проге не срабатывали по нескольку раз
{
  for (angle = 0; angle <= 90; angle++) {
    y.write(angle); // сообщаем серво угол поворота
    delay(20);}} // ждем 20 мс, пока серво не сделает поворот
  }
}
      if (val == 'D') 
{
  // цикл для поворота c 90 до 0 градусов при передаче в com с проги буквы D
  while (angle > 0) // чтоб кнопки в проге не срабатывали по нескольку раз
{
  for (angle = 90; angle >= 0; angle--) {
    y.write(angle); // сообщаем серво угол поворота
    delay(20);}} // ждем 10 мс, пока серво не сделает поворот
  }
}
//управление сервой x посредством трекбара с проги для поворота c 0 до 180
void serialEvent() {
  xval = Serial.parseInt();
  if(xval!=0) {
    x.write(xval);
  }
}

Код студио:

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 Microscop
{
    public partial class Form1 : Form
    {
        SerialPort port;
        private void init()
        {
            port = new SerialPort();
            port.PortName = "COM2";
            port.BaudRate = 115200;

            try
            {
                port.Open();
            }

            catch (Exception e1)
            {
                MessageBox.Show(e1.Message);
            }
        }
        public Form1()
        {
            InitializeComponent();
            init();
        }
        

        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            port.WriteLine(trackBar1.Value.ToString());
            label3.Text = "Угол наклона " + trackBar1.Value.ToString();

        }

        private void button1_Click(object sender, EventArgs e)
        {
            port.Write("C");

        }

        private void button2_Click(object sender, EventArgs e)
        {
            port.Write("D");

        }

        private void label3_Click(object sender, EventArgs e)
        {

        }
    }
}

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Хрень получается потому что входящие данные анализируются в двух местах по разным принципам. И срабатывают псевдослучайным образом.

Примерно как ловить в аквариуме с двумя угрями какого-то конкретного, закрыв при этом глаза.

И "где-то" тут исправить невозможно. Нужно просто реализовать правильный алгоритм, а не на трусы пришивать варежки.

vova271
Offline
Зарегистрирован: 13.11.2020

Надо что то типа триггера или личного адреса к каждому серво ?

b707
Offline
Зарегистрирован: 26.05.2017

vova271 пишет:

Надо что то типа триггера или личного адреса к каждому серво ?

нет, надо либо управлять серво буквенными командами ( 'D'  'C'), либо цифровыми, но никак не теми и другими сразу

vova271
Offline
Зарегистрирован: 13.11.2020

Буду пробовать, спасибо.

b707
Offline
Зарегистрирован: 26.05.2017

и еще вдогонку - читаем сериал либо через Serial.availiable(), либо serialEvent() .    А вместе - это как раз "варежки к трусам". как удачно выразился Садман - работать не будет.

У вас вообще весь код просто сшит из двух частей, так не программируют

sadman41
Offline
Зарегистрирован: 19.10.2016

Я даже подскажу как: шлёшь с компа 0...180 для указания угла, 230, например, вместо D, 240 вместо C.

На Ардуине читаешь байт через read(), если он 230 - нужно совершить действие D, если 240 - действие C, от 0 до 180 - выставить угол поворота сервы. parseInt() со всем обвесом - потереть к чертям.

vova271
Offline
Зарегистрирован: 13.11.2020

Я мысль понял.

vova271
Offline
Зарегистрирован: 13.11.2020

Спасибо, щас попробую.