Угол поворота

varvik85
Offline
Зарегистрирован: 28.01.2013

Добрый день. Делаю одно устройство, которое должно будет поворачиваться на заданный угол, точность не сильно высокая по этому в качестве датчика угла поворота планирую использовать простой линейный переменный резистор. Сам поворачивающий механизм к сожалению не сервомашинка, а более мощная штуковина. Задача стоит в следующем: задающим переменный резистором, который будет располагаться на передней панели, оператор задает угол поворота, жмет кнопку и устройство поворачивается на заданный угол. Получается мне нужно сравнивать два переменных резистора между собой, один как задающий, второй прикрепленный к валу поворачивающего механизма. Если сопротивление первого( задающего) резистора больше второго то устройство поворачивается вправо пока сопротивление второго не сравниться с сопротивлением первого, и на оборот, если сопротивление первого меньше, то устройство поворачивается влево, как только их сопротивления уравняются то устройство останавливается. Загвоздка заключается в том, что я не знаю как сравнивать два аналоговых значения между собой и как создать программно такой алгоритм "весов" который всегда бы стремился уравнять значения обоих переменных резисторов при помощи поворотного двигателя одно из них. Может есть наброски, полностью за меня проделать всю работу не прошу, хочу лишь попросить подсказать или направить в правильное русло.

varvik85
Offline
Зарегистрирован: 28.01.2013
наверно как то так, простите за примитивизм, не оформил как подобает, но суть думаю понятна
if (analogread1 > anqlogread2)
digitalWrite(vpravoPin, HIGH);
if (analogread1 < anqlogread2)
digitalWrite(vlevoPin, HIGH);

но я хочу еще задать допуск, допустим + - 5 ком, т.е в этом интервале будет считаться что достигнуто равенство, как это сделать?

Araris
Offline
Зарегистрирован: 09.11.2012

varvik85 пишет:

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

Алгоритм простой и Вы уже его весь правильно расписали. Теперь вместо слов "сопротивление резистора" подставьте слова "значение analogRead()" и все ещё понятнее станет.

Ну а дальше запускаем loop(), читаем показания с резисторов, сравниваем их, принимаем решение о том, в какую сторону и на сколько провернуть вал, исполняем, опять читаем, опять сравниваем и т.д. Начните писать скетч, а там разберёмся дальше. С допуском тоже несложно будет.

varvik85
Offline
Зарегистрирован: 28.01.2013

Спасибо! Я примерно понял, но не могу сообразить как сделать допуск в +- 5 кОм. Если я эти 5кОм оформлю в виде константы буду сравнивать дополнительно значения переменного резистора + - константа, то в итоге у меня будет всего три варианта, когда достигнется равенство. А я хочу чтоб весь отрезок в 5 кОм был "полем" равенства.Может как то массив оформить? Это мне нужно, по скольку постольку механизм будет иметь некую инерционность, и я предвижу что он будет останавливаться немного по инерции проезжать метку потом опять ехать назад, потом вперед, и так шататься около метки,мне это не нужно, да и точность не сильно высокая нужна, главное чтоб повернулся примерно на заданный угол и остановился сразу

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

В простейшем случае предусмотрите 3 ветки:

- модуль разницы показаний меньеш определенной границы,

- разница показаний больше положительной границы,

- разница показаний меньше отрицательной границы.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013
#define LEFT_PIN A1
#define RIGHT_PIN A2
#define GAP 24  // нулевой коридор
// GAP это показания analogRead(A0), к которому подключен резистор 5 кОм


void loop
{
  if (analogread(LEFT_PIN) - GAP/2 > analogread(RIGHT_PIN) + GAP/2)
  {
    digitalWrite(vpravoPin, HIGH);
  }

  if (analogread(LEFT_PIN) + GAP/2 < analogread(RIGHT_PIN) - GAP/2)
  {
    digitalWrite(vlevoPin, HIGH);
  }

}

 

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

Tomasina, нужно три ветки: кто-то ведь когда-нибудь должен записывать в упомянутые пины LOW.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013
#define LEFT_PIN A1
#define RIGHT_PIN A2
#define GAP 24  // нулевой коридор
// GAP это показания analogRead(A0), к которому подключен резистор 5 кОм


void loop
{
  if (analogRead(LEFT_PIN) - GAP > analogRead(RIGHT_PIN) - GAP)
  {
    digitalWrite(vpravoPin, HIGH);
  }
  else if (analogRead(LEFT_PIN) - GAP < analogRead(RIGHT_PIN) - GAP)
  {
    digitalWrite(vlevoPin, HIGH);
  }
  else
  {
    digitalWrite(vpravoPin, LOW);
    digitalWrite(vlevoPin, LOW);
  }

}

Возможно и не так, мне не до конца понятен весь алгоритм управления.

varvik85
Offline
Зарегистрирован: 28.01.2013

Спасибо но это немного не то. Мне нужны не три ветики, а все поле значений. Допустим у меня допуск +- 5 ком, что можно перевести в число, допустим 100, так вот, хотелось бы чтоб все числа от 1 до 100 и от -1 до -100 входили в этот диапазон. Т. е если первый резистор будет выставлен допустим на 50 кОм то устройство сработает если второй резистор окажеться в любой точке диапазона 45-55 ком, например 46 или 52 или 47,85 как то так.

Еще раз скажу зачем это нужно, само устройство поворота будет немного инерционным, т.е оно не остановиться точно в нужном месте. После отключения двигателя оно еще немного проедет пару миллиметров точно, что будет являться выходом из точки сработки устройства, и программа начнет его двигать назад, и опять инерция, так и будет оно в этих + - 2 мм елозить туда сюда, мне это не нужно. Остановилось, ну чуть проехало, ничего страшного, не критично, сильная точность не нужна.По этому хочу и ввести такое число, число допуск, и все его множества должны быть полем сработки программы. Вот. Не знаю как это сделать

Araris
Offline
Зарегистрирован: 09.11.2012

Просто начните писать скетч.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

Так вышеприведенный код именно это и делает.

Если показания с левого потенциометра выходят за диапазон, ограниченный "коридором" (GAP), то доворачиваем вправо:

if (analogRead(LEFT_PIN) - GAP > analogRead(RIGHT_PIN) - GAP)
  {
    digitalWrite(vpravoPin, HIGH);
  }

Аналогично с правой стороной.

Если же показания находятся в диапазоне -GAP...+GAP, то находимся в "точке назначения" и моторы выключены:

digitalWrite(vpravoPin, LOW);
digitalWrite(vlevoPin, LOW);
varvik85
Offline
Зарегистрирован: 28.01.2013

Таки да, ведь если analogRead - GAP больше, то он будет больше при любом значении GAP. Ёмае все просто. А я голова садовая, не догодался. Большое спасибо! Жму руку!

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

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

inspiritus
Offline
Зарегистрирован: 17.12.2012

такой усложненный сельсин

я не стал бы заморачиваться с резисторами (износ ?) поставил бы энкодеры: оптическая метка на валу и оптокоуплер для подсчета оборотов двигателя  (направление мы сами задаем) и просто энкодер в качестве задающего устройства. (не забыть про передаточное число редуктора)

varvik85
Offline
Зарегистрирован: 28.01.2013

Спасибо. Про энкодер я знаю, но тут точность сильная не нужна , а работать устройство будет не так часто, поставлю еще два концевика, на случай если резистор выйдет из строя. Вообще заявляют, что износ 10^5...10^7 циклов, у регулировочных резисторов — 5*10^3...1*10^5, у подстроечных резисторов. Устройство будет примерно 2-3 раза в день использоваться, это значит 4-6 циклов в день, получается его должно хватить на долго.Мне ни разу не попадался нерабочий переменник, да в усилителях звука они со временем начинают шуршать, но не выходят из строя, так чтоб прям совсем в обрыве были. К тому же,при использовании энкодера, устройству придется каждый раз после включения и отключения возвращаться в начальную точку отсчета, что не удобно.Еще момент, устройство повернулось, а тут оп на него произвели какое то механическое воздействие и сместили в сторону, проблема. Можно конечно программно все это обойти, но к чему сложность?

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

Tomasina пишет:

#define LEFT_PIN A1
#define RIGHT_PIN A2
#define GAP 24  // нулевой коридор
// GAP это показания analogRead(A0), к которому подключен резистор 5 кОм


void loop
{
  if (analogRead(LEFT_PIN) - GAP > analogRead(RIGHT_PIN) - GAP)
  {
    digitalWrite(vpravoPin, HIGH);
  }
  else if (analogRead(LEFT_PIN) - GAP < analogRead(RIGHT_PIN) - GAP)
  {
    digitalWrite(vlevoPin, HIGH);
  }
  else
  {
    digitalWrite(vpravoPin, LOW);
    digitalWrite(vlevoPin, LOW);
  }

}

Возможно и не так, мне не до конца понятен весь алгоритм управления.

А зачем к обеим частям условия добавлять одинаковые слагаемые?

Что и как работает, я тоже не знаю, но из общих соображений предложил бы добавить пару строк:

#define LEFT_PIN A1
#define RIGHT_PIN A2
#define GAP 24  // нулевой коридор
// GAP это показания analogRead(A0), к которому подключен резистор 5 кОм


void loop
{
  if (analogRead(LEFT_PIN) - analogRead(RIGHT_PIN) > GAP)
  {
    digitalWrite(vlevoPin, LOW);
    digitalWrite(vpravoPin, HIGH);
  }
  else if (analogRead(LEFT_PIN) - analogRead(RIGHT_PIN) < - GAP)
  {
    digitalWrite(vpravoPin, LOW);
    digitalWrite(vlevoPin, HIGH);
  }
  else
  {
    digitalWrite(vpravoPin, LOW);
    digitalWrite(vlevoPin, LOW);
  }

}
trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Вам крупно повезло....  с нормальным энкодером.....

http://www.banggood.com/6V-100210300RPM-Encoder-Motor-DC-Gear-Motor-p-10...