Управление двигателем джойстиком с поправкой на потенциометр.

MorAlex
Offline
Зарегистрирован: 12.10.2015

Всем добрый день!

Двигатель управляется джойстиком через драйвер двигателей. Схема банальная, простая и объяснять смысла нет.  Она прекрасно работает. Но есть необходимость дополнительным потенциометром подключенным к ардуине ограничивать скорость вращения двигателя. Что бы она была не выше порога установленным потенциометром. Всю голову сломал, но не придумал как это сделать в программе. Может кто нибудь подскажет как это реализовать?

Вот, что у меня:

void Motor1()
{
  int SPD_PTN = map(analogRead(SpeedPTN), 0, 1023, 0, 120); // ограничивающий потенциометр
  xValue = map(analogRead(xPin), 0, 1023, 0, 255); // одна ось джойстика

  if (xValue > 118) //назад
    {
      digitalWrite(in1, LOW);
      digitalWrite(in2, HIGH);
      analogWrite(ENA, ((xValue-127)-SPD_PTN));
    }
  if (xValue < 131) //вперёд
    {
     digitalWrite(in1, HIGH);
     digitalWrite(in2, LOW);
     analogWrite(ENA, ((127-xValue)-SPD_PTN));
    }
  if (xValue > 118 && xValue <= 131) //стоп
    {
      digitalWrite(ENA, LOW);
      digitalWrite(in1, LOW);
      digitalWrite(in2, LOW);
    }
    Serial.print(SPD_PTN);

В этом случае скорость можно абы как ограничивать, но при начальном изменении положения джойстика и отпускании происходит рывок. Что собственно логично. Значения в этот момент изменяются не плавно. И вот как сделать сообразить не могу.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Кто-то сильно гулял на уроках алгебры. Или преподаватель или вы. А может произошла реформа образования и алгебру объединили с физкульткрой.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Блин, так Вы делайте в два шага

1. просто маппируйте показания джойстика по потенциометру (чтобы из показаний джойстика сделать число от 0 до показаний потенциометра).

2. потом уж то, что получилось смаппируйте в 0-255.

И всё. Чего огород-то городить? Я понятно описал?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

qwone пишет:

Кто-то сильно гулял на уроках алгебры.

Правльна делал! Как говорил Андрей Александрович Фурсенко, математика убивает креативность :)

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

ЕвгенийП пишет:

Правльна делал! Как говорил Андрей Александрович Фурсенко, математика убивает креативность :)

Фусенко видно тоже гулял по черному. Математика это сплошная креативность. 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

qwone пишет:

Фусенко видно тоже гулял по черному. Математика это сплошная креативность. 

Как?!?!

Вы не согласны с целым председателем попечительского совета Российского научного фонда, . действительным государственным советником Российской Федерации 1 класса, помощником президента?

Вы не согласны с человеком, отлившим в граните бессмертную формулу: "недостатком советской системы образования была попытка формировать человека-творца, а сейчас задача заключается в том, чтобы взрастить квалифицированного потребителя, способного квалифицированно пользоваться результатами творчества других".

Да, Вы, батенька прямо оппозиционер и пятая колонна!

И вообще, креативность, это член на мосту нарисовать, яйца к брусчатке прибить, куриц в вагины засовывать, а вы тут со своими синусами лезете :)

MorAlex
Offline
Зарегистрирован: 12.10.2015

Евгений, спасибо за совет! qwone, у Вас дефицит общения? Постебаться и я неплохо могу.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

MorAlex пишет:
qwone, у Вас дефицит общения? Постебаться и я неплохо могу.

Вот нетренированому человеку , тяжело поднять тяжелый груз. Но если человек регуляроно тренируется, то ему не сложно. Уроки Алгебры именно натаскивают на решение этих задач, развивают математические мускулы. Этим и сильна была советская образовательная школа. И вот с тренироваными мозгами уже легко решать задачи. Вот ваша задача из этой серии .  Если вам тяжело решать в уме эту задачу, решайте на листочке. Так нагляднее. Сделайте координатную сетку ХY. По X значение от 0- до 1023. А по Y значение которые вы хотите получить. Вот так у вас получится ломаная линия. Которую вы запрограммируете. Нарисуйте 2-3 линии с разным значением потенциометра и все станет ясно.

ПС: Да и тренируйте ваши мозги, это главный инстумент человека. От сюда и мой стеб. 

MorAlex
Offline
Зарегистрирован: 12.10.2015

С алгеброй у меня всё в порядке, не переживайте. Так же как и со схемотехникой. А то, что я начал пытаться программировать на незнакомом мне языке пару месяцев назад и попросил помощи у опытных людей, моих знаний не умоляет. И мозг, и память натренированы программированием в ассемблере (если вам вообще это знакомо). Я вам не мальчик заставший ЕГЭ и с мозгами у меня всё в порядке. 

qwone, Ваши ответы обсолютно неинформативны и бессмысленны. Про ЕГЭ и политику разговаривают на других форумах. Да и флудят в других местах. Если можете только «погнуть» пальцы показывая какой Вы спец., а новички заслуживают только насмешек, то не стоит тратить время. Не можете или не собираетесь помочь, пожалейте своё время и клавиатуру. Я таких как Вы за свою жизнь навидался...

kasper007
Offline
Зарегистрирован: 23.05.2016

MorAlex пишет:

...А то, что я начал пытаться программировать на незнакомом мне языке пару месяцев назад ..... И мозг, и память натренированы программированием в ассемблере (если вам вообще это знакомо)

Алгоритму все равно на каком языке его реализуют.

MorAlex
Offline
Зарегистрирован: 12.10.2015

Вот только я не знаю как его реализовать на этом языке.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

MorAlex пишет:

Вот только я не знаю как его реализовать на этом языке.

1.поскольку программисту безразличен язык.На знакомом просто удобнее, вывод - вы не программист.

2.Вопрос ваш был не по языку а по простому линейному преобразованию, не имеющему отношения ни к какому языку, а только к школьной успеваемости.

3. Понтов, в ответ на дружеский подкол, вы развели ведро.

4. Вывод - недалекий неуч с амбициями. Трудно вам будет. Спрашивающий должен вести себя тихо и вежливо, ибо УЖЕ унижается, самим фактом вопроса. Унижающийся с понтами - смешон.

MorAlex
Offline
Зарегистрирован: 12.10.2015

Где я сказал, что я программист? Решили, что я когдато на ассемблере программировал? И вопрос был как это сделать на языке arduino. Научитесь читать вопрос.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

MorAlex пишет:

... как это сделать на языке arduino...

Уточните для заднего ряда - на каком-каком языкке?

А то мы тут пропустили момент создания нового языка программирования. Интересно же!

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

MorAlex пишет:

Где я сказал, что я программист? Решили, что я когдато на ассемблере программировал? И вопрос был как это сделать на языке arduino. Научитесь читать вопрос.

Могу посоветовать следующий подход:

1. Записываете алгоритм на том языке, который Вам знаком в достаточной степени (например, на русском).

2. Когда алгоритм готов, переводите его на тот язык, который нужно (в данном случае Си или Си++).

Если последний Вам абсолютно незнаком, воспользуйтесь справочником по языку (хотя бы Керниган и Ритчи). 

Практика показывает, что если тщательно выполнен пункт 1, то с пунктом 2 проблем не возникает.

MorAlex
Offline
Зарегистрирован: 12.10.2015

Без всякого стёба и глупых нравоучений. Возможно кому нибудь пригодится.

/*
 * Управление головкой операторского крана. 
 * Два двигателя, тумблер реверса, потенциометр ограничения скорости.
 * 
 * Arduino Nano + драйвер двигателей L298.
 */

int ENA = 10;
int ENB = 11;

//  int in1 = 5; int in2 = 6; int in3 = 7; int in4 = 8;

int xJoy = A0; int yJoy = A1; int SpeedPot = A2; int RevBtn = 2;

int SPD_Pot;
int X; int x1; int x2;
int Y; int y1; int y2;

void setup()
{
  pinMode(ENA, OUTPUT);
  pinMode(ENB, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(xJoy, INPUT);
  pinMode(yJoy, INPUT);
  pinMode(2, INPUT_PULLUP);
  pinMode(SpeedPot, INPUT);

  PORTB &= ~(1<<2);                         // analogWrite(ENA, 0);
  PORTB &= ~(1<<3);                         // analogWrite(ENB, 0);
  PORTD &= ~(1<<5);                         // digitalWrite(in1, LOW);
  PORTD &= ~(1<<6);                         // digitalWrite(in2, LOW);
  PORTD &= ~(1<<7);                         // digitalWrite(in3, LOW);
  PORTB &= ~(1<<0);                         // digitalWrite(in4, LOW);

  TCCR1B = TCCR1B & 0b11111000 | 0x01;      // Установка максимальнойчастоты ШИМ
  TCCR2B = TCCR2B & 0b11111000 | 0x01;      // (что бы двигатели не свистели)
}

void loop()
{
  if (digitalRead(RevBtn) == 0)
    {
      Motor_X();
      Motor_Y();
    }
      else
    {
      PORTB &= ~(1<<2);                     // digitalWrite (ENA, LOW);
      PORTD &= ~(1<<5);                     // digitalWrite (in1, LOW);
      PORTD &= ~(1<<6);                     // digitalWrite (in2, LOW);
    }
  if (digitalRead(RevBtn) == 1)
    {
      Motor_X_Rev();
      Motor_Y_Rev();
    } 
}

//______________________ ПРЯМОЕ ВРАЩЕНИЕ ДВИГАТЕЛЕЙ _____________________//

void Motor_X()
{
  SPD_Pot = map(analogRead(SpeedPot), 0, 1023, 135, 254);    // ограничение
  X = map(analogRead(xJoy), 0, 1023, 0, SPD_Pot);            // джойстик
  x1 = ((SPD_Pot/2) - X)*2;
  x2 = (X - (SPD_Pot/2))*2;

  if (x2 > 10)
    {
      analogWrite  (ENA, x2);
      PORTD &= ~(1<<5);                  // digitalWrite (in1, LOW);
      PORTD |= (1<<6);                   // digitalWrite (in2, HIGH);
    }
      else
    {
      PORTB &= ~(1<<2);                   // digitalWrite (ENA, LOW);
      PORTD &= ~(1<<5);                   // digitalWrite (in1, LOW);
      PORTD &= ~(1<<6);                   // digitalWrite (in2, LOW);
    }
  if (x1 > 10) // Х - вправо
    {
      analogWrite  (ENA, x1);
      PORTD |= (1<<5);                     // digitalWrite (in1, HIGH);
      PORTD &= ~(1<<6);                    // digitalWrite (in2, LOW);
    }
}

//------------------------------------------------------------------------//

void Motor_Y()
{
  SPD_Pot = map(analogRead(SpeedPot), 0, 1023, 135, 254);    // ограничение
  Y = map(analogRead(yJoy), 0, 1023, 0, SPD_Pot);            // джойстик
  y1 = ((SPD_Pot/2) - Y)*2;
  y2 = (Y - (SPD_Pot/2))*2;

  if (y2 > 10)
    {
      analogWrite  (ENB, y2);
      PORTD &= ~(1<<7);                       // digitalWrite (in3, LOW);
      PORTB |= (1<<0);                        // digitalWrite (in4, HIGH);
    }
      else
    {
      PORTB &= ~(1<<3);                       // digitalWrite (ENB, LOW);
      PORTD &= ~(1<<7);                       // digitalWrite(in3, LOW);
      PORTB &= ~(1<<0);                       // digitalWrite(in4, LOW);
    }
  if (y1 > 10)
    {
      analogWrite  (ENB, y1);
      PORTD |= (1<<7);                        // digitalWrite (in3, HIGH);
      PORTB &= ~(1<<0);                       // digitalWrite(in4, LOW);
    }
}

//____________________ ОБРАТНОЕ ВРАЩЕНИЕ ДВИГАТЕЛЕЙ ____________________//

void Motor_X_Rev()
{
  SPD_Pot = map(analogRead(SpeedPot), 0, 1023, 135, 254);   // ограничение
  X = map(analogRead(xJoy), 0, 1023, 0, SPD_Pot);           // джойстик
  x1 = ((SPD_Pot/2) - X)*2;
  x2 = (X - (SPD_Pot/2))*2;

  if (x2 > 10)
    {
      analogWrite  (ENA, x2);
      PORTD |= (1<<5);                          // digitalWrite (in1, HIGH);
      PORTD &= ~(1<<6);                         // digitalWrite (in2, LOW);
    }
      else
    {
      PORTB &= ~(1<<2);                         // digitalWrite (ENA, LOW);
      PORTD &= ~(1<<5);                         // digitalWrite (in1, LOW);
      PORTD &= ~(1<<6);                         // digitalWrite (in2, LOW);
    }
  if (x1 > 10)
    {
      analogWrite  (ENA, x1);
      PORTD &= ~(1<<5);                         // digitalWrite (in1, LOW);
      PORTD |= (1<<6);                          // digitalWrite (in2, HIGH);
    }
}

//-------------------------------------------------------------------------//

void Motor_Y_Rev()
{
  SPD_Pot = map(analogRead(SpeedPot), 0, 1023, 135, 254);    // ограничение
  Y = map(analogRead(yJoy), 0, 1023, 0, SPD_Pot);            // джойстик
  y1 = ((SPD_Pot/2) - Y)*2;
  y2 = (Y - (SPD_Pot/2))*2;

  if (y2 > 10) 
    {
      analogWrite  (ENB, y2);
      PORTD |= (1<<7);                    // digitalWrite (in3, HIGH);
      PORTB &= ~(1<<0);                   // digitalWrite (in4, LOW);
    }
      else
    {
      PORTB &= ~(1<<3);                   // digitalWrite (ENB, LOW);
      PORTD &= ~(1<<7);                   // digitalWrite (in3, LOW);
      PORTB &= ~(1<<0);                   // digitalWrite (in4, LOW);
    }
  if (y1 > 10)
    {
      analogWrite  (ENB, y1);
      PORTD &= ~(1<<7);                   // digitalWrite (in3, LOW);
      PORTB |= (1<<0);                    // digitalWrite (in4, HIGH);
    }
}
qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Похоже ТС живет по правилу: "Алгебра не бойся, я тебя не трону". 

MorAlex
Offline
Зарегистрирован: 12.10.2015

Ну так покажите свой класс. Или Вы только болтать и стебаться умеете?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

MorAlex пишет:

Ну так покажите свой класс. Или Вы только болтать и стебаться умеете?

Я вот попытался составить скетч аналог и потом заметил, что я пишу на Си++ ,то есть с классами, так что вы врят ли поймете. А проще не получается :(

MorAlex
Offline
Зарегистрирован: 12.10.2015

qwone пишет:

MorAlex пишет:

Ну так покажите свой класс. Или Вы только болтать и стебаться умеете?

Я вот попытался составить скетч аналог и потом заметил, что я пишу на Си++ ,то есть с классами, так что вы врят ли поймете. А проще не получается :(

Вот это нормальный ответ.

Конечно же я не пойму. Но можно было бы и сразу это сказать. Ведь я не профессиональный программист поэтому и попросил помощи. Хотя задачу я всётаки решил. Всё идеально работает. Даже лучше чем со старой электроникой от этого крана.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Вот вам так принцип 

const byte joyPin = A0;
int a, b;
const byte RPin = A1;
void setup() {
  Serial.begin(9600);

}

void loop() {
  delay (100);
  a = analogRead(joyPin) / 10;
  b = analogRead(RPin) / 10;
  float var ;
  if (a < 40) {
    var  = (40 - a) * b / 18 ;
    Serial.println();
    Serial.print("forward");
    Serial.print("  ");
    Serial.print(var);
  }
  else if (a > 62 ) {
    var  = (a - 62) * b / 18;
    Serial.println();
    Serial.print("backward");
    Serial.print("  ");
    Serial.print(var);
  }
  else {
    Serial.println();
    Serial.print("stop");
  }
}

ПС: про это вам ЕвгенийП говорил.