Прошу помощи
- Войдите на сайт для отправки комментариев
Сб, 23/09/2017 - 18:42
Приветствую, уважаемые форумчане!
Сам я дилетант в этом деле, поэтому строго не судите.
Хочу сделать следующее:
Некое устройство состоящее из сервы, 2х оптопар и светодиода.
Принцип работы:
при закрытии одной оптопары, начинается отсчет импульсов со второй, по истечении 5 импульсов срабатывает серва, которая работает на протяжении 4х импульсов, далее цикл закончен.
Для контроля срабатывания первой оптопары имеется светодиод, который гаснет по факту срабатывания. Так же серва фиксируется в положении + 10 градусов.
Проблема в следующем: после прохождения 5 импульсов серва начинает беспорядочно шевелиться и все...
#include <Servo.h>
Servo servo;
int sensePin = 12;
boolean Impuls, OldImpuls;
int sensor;
int encoder;
void setup()
{
pinMode(10, INPUT_PULLUP); //sen
pinMode(11, INPUT_PULLUP); //enc
pinMode(8, OUTPUT);// светодиод
servo.attach(12);//серва
}
void loop()
{
if (digitalRead(10)) //если сенсор закрыт
servo.write(10); //серво + 10
else (servo.write(0));//серво 0
if (digitalRead(10)) //если сенсор закрыт
digitalWrite(8, LOW); // светодиод не горит
else (digitalWrite(8, HIGH));// светодиод горит
if (digitalRead(10)) //если сенсор замкнут
{
OldImpuls = Impuls; // Запоминаем состояние предыдущего импульса
if (digitalRead(11))
{
Impuls = true; //то запоминаем
}
else //иначе
{
Impuls = false; // запоминаем 0
}
if (Impuls && !OldImpuls) //Если текущий импульс 1, а предыдущий 0
{
encoder++; //Считаем импульсы
}
if (encoder >= 5) // 5 импульса
servo.write(90);// серва +90
{
if (digitalRead(10))//если сенсор закрыт
{ OldImpuls = Impuls; // Запоминаем состояние предыдущего импульса
if (digitalRead(11))
{
Impuls = true; //то запоминаем
}
else //иначе
{
Impuls = false; // запоминаем 0
}
if (Impuls && !OldImpuls) //Если текущий импульс 1, а предыдущий 0
{
encoder++; //Считаем импульсы
}
if (encoder >= 4) // 4 импульса
{
servo.write(0);// серва 0
}
}
}
}
}
Заранее спасибо.
#include <Servo.h> Servo servo; int sensePin = 12; boolean Impuls, OldImpuls; int sensor; int encoder; void setup() { pinMode(10, INPUT_PULLUP); //sen pinMode(11, INPUT_PULLUP); //enc pinMode(8, OUTPUT);// светодиод servo.attach(12);//серва } void loop() { if (digitalRead(10)) //если сенсор закрыт { servo.write(10); //серво + 10 digitalWrite(8, LOW); // светодиод не горит OldImpuls = Impuls; // Запоминаем состояние предыдущего импульса if (digitalRead(11)) { Impuls = true; //то запоминаем } else //иначе { Impuls = false; // запоминаем 0 } } else { (servo.write(0));//серво 0 (digitalWrite(8, HIGH));// светодиод горит } if (Impuls && !OldImpuls) //Если текущий импульс 1, а предыдущий 0 { encoder++; //Считаем импульсы OldImpuls = Impuls; // Запоминаем состояние предыдущего импульса if (encoder >= 5) // 5 импульса { servo.write(90);// серва +90 delay(1000); encoder = 0; } else if (encoder >= 4) // 4 импульса { servo.write(0);// серва 0 delay(1000); } } }Спасибо за ответ!
Все отлично работает, но не так как надо. Требуемый алгоритм работы несколько отличается от Вашего. В Вашем случае по прошествии 5 импульсов серво +90 на 1 секунду, мне же надо - серво +90 на 4 импульса, без задержек. В написании кода я полный профан, т.к. с програмированием сталкивался в школе/институте на уровне бейсика и то 20 лет назад, поэтому и нагородил огород в попытке сделать так как нужно.
Кстати вопрос: почему заданное количество импульсов несколько отличатся от реальных? Просим 5 имп. срабатывает в диапазоне от 3 до 5.
Спасибо за ответ. Попробую описать что нужно на реальном примере:
Есть некий постоянно идущий конвейер, на валу которого закреплено колесо с прорезями, с этого колеса читает прерывания энкодер 11 пин (постоянно). При закрытии сенсора 10 пин, начинается исполнение цикла в котором по прошествии х-импульсов включается исполнительный механизм (скажем серва, пин 12) и выключается через у-импульсов. Всего время работы сервы исчисляется в количестве импульсов (у), а общий цикл х+у. Я не могу понять каким образом можно встроить одно за другим. Поэтому я и пытался внутрь одной функции вставить другую.
Удалось зафиксировать серво в положении +90
#include <Servo.h> Servo servo; int sensePin = 12; int pos = 90;//рабочая позиция серво int nul = 0;//нулева позиция серво boolean Impuls, OldImpuls; int sensor; int encoder; void setup() { pinMode(10, INPUT_PULLUP); //sen pinMode(11, INPUT_PULLUP); //enc pinMode(8, OUTPUT);// светодиод servo.attach(12);//серва servo.write(nul);//нулевая позиция серво } void loop() { if (digitalRead(10)) //если сенсор закрыт { digitalWrite(8, LOW); // светодиод не горит OldImpuls = Impuls; // Запоминаем состояние предыдущего импульса if (digitalRead(11)) { Impuls = true; //то запоминаем } else //иначе { Impuls = false; // запоминаем 0 } } else { (digitalWrite(8, HIGH));// светодиод горит servo.write(nul);// серва 0 } if (Impuls && !OldImpuls) //Если текущий импульс 1, а предыдущий 0 { encoder++; //Считаем импульсы OldImpuls = Impuls; // Запоминаем состояние предыдущего импульса if (encoder == 6) // 6 импульсов { servo.write(pos);// серва +90 encoder = 0; } } }Теперь бы как-нить расфиксировать через n-импульсов, т.е. вернуть в исходное состояние.
Не хочется вам пересказывать как программировать на Си++ , использовать ООП и в результате вы все равно не будет ни в зуб ногой. Да что говорить. Вы даже скетч не отладите.
Прекрасный по своей развернутости ответ!
Наша с Вами разница, уважаемый qwone, в следующем: Вам есть что пересказать о программировании на С++, в моем случае даже аббревиатура "ООП", заставила меня гуглить.
Судя по Вашему описанию - в диапазоне от 3 до 5 - Вам подсказали основную идею - дребезг и необходимость его подавления.
Судя по Вашему описанию - в диапазоне от 3 до 5 - Вам подсказали основную идею - дребезг и необходимость его подавления.
В последнем скетче нет никакого дребезга, серва встает в назначенное рабочим положение четко по истечении 6 импульсов, теперь не могу сделать так, чтоб серва возвращалась через несколько импульсов в исходную (ноль).
Т.е. 6 импульсов - серва +90, после еще, скажем, 6 импульсов серва в ноль, цикл закончен.
ПС: А это для того что бы я не показался вам вруном.http://arduino.ru/forum/programmirovanie/klassy-arduino-po-qwone-dlya-chainikov
Qwone, я не считаю Вас голословным, можно было с этого и начать, мол, дорогой %username%, есть такая штука как классы, объекты и прочая святотень, обратите свой ясный взор на вот эту тему %линк%, там я для всех "программистов" в примерах разъяснил как это работает.
Именно по причине его простоты я и взялся за процедурный подход. Тема эта мне интересна для гаражного DIY, посему хочется все и сразу. Конкретная задача, очевидно, не требует каких либо сложных решений, но в силу отсутствия знаний, даже эта задача, как оказалось, мне не под силу. Иначе мы с Вами и не общались бы.
Ежели все так просто - направьте в нужное русло, подскажите. Я ведь сам по крупицам (доступным и понятным мне) пытаюсь собрать информацию.
Разумеется ваши оптопары можно рассматривать как обычные бездребезговые кнопки, в программном разумеется смысле. Так что код у них примерно такой.
/**/ unsigned long mill; // переменная под millis() typedef void (*handler)() ; //-------------------------------- class Cl_Device { protected: public: Cl_Device() {} void setup() {} void loop() {} }; //------Cl_Btn---------------------- // класс кнопка class Cl_Btn { protected: const byte pin; handler Do1, Do2; bool btn = 1, oldBtn; unsigned long past; public: Cl_Btn(byte pin_, handler Do1_, handler Do2_): pin(pin_), Do1(Do1_) , Do2(Do2_) {} void setup() { pinMode(pin, INPUT_PULLUP); oldBtn = digitalRead(pin); } void loop() { btn = digitalRead(pin); if (!oldBtn && btn) { oldBtn = 1; Do1(); } if (!oldBtn && btn) { btn = 0; Do2(); } } }; //---Компоновка----------------------------- void Do1_btn1() {} void Do2_btn1() {} void Do1_btn2() {} void Do2_btn2() {} Cl_Btn btn1(/*пин*/10,/*наж*/Do1_btn1,/*отж*/Do2_btn1); Cl_Btn btn2(/*пин*/11,/*наж*/Do1_btn2,/*отж*/Do2_btn2); //---main----------------------------- int main() { init(); //setup() btn1.setup(); btn2.setup(); for (;;) { //loop() mill = millis(); btn1.loop(); btn2.loop(); } return 0; } /* Скетч использует 1012 байт (3%) памяти устройства. Всего доступно 30720 байт. Глобальные переменные используют 35 байт (1%) динамической памяти, оставляя 2013 байт для локальных переменных. */А с вашим компонентов который управляет сервой тоже все просто. Каждый простой объект имеет состояние (переменую состояние) Монета 2 состояния орел решка, кубик - шесть. А у вашего объекта (x+y) состояний. от 0 до x серва в одном положении а с x+1 до x+y в другом. и так по кругу. Перекрыли одну оптопару у вас сброс, а перекрытие другой у вас шаг состояние на 1. И все.
из Вашего кода мне понятно, что используется время, у меня мерило расстояние, не пойму применения времени...
из Вашего кода мне понятно, что используется время, у меня мерило расстояние, не пойму применения времени...
Процессор один, а объектов много. Подошло время - сработал компонент, нет- просто вошел и вышел. Быстрый loop все связывает в кучу.
А можно более конкретно прокоментировать код:
Куда привязывть значения прерываний?
Что значит Do1, Do2?
Cl_Btn btn1(/*пин*/10,/*наж*/Do1_btn1,/*отж*/Do2_btn1); - пин, наж, отж - это комменты?
Куда теперь девать серву?
Кто такой handler Do1, Do2; и за что отвечает.
#include <Servo.h> Servo servo; int sensePin = 12; int pos = 90;//рабочая позиция серво int nul = 0;//нулева позиция серво boolean Impuls, OldImpuls; bool value; int sensor; int encoder; void setup() { pinMode(10, INPUT_PULLUP); //sen pinMode(11, INPUT_PULLUP); //enc pinMode(8, OUTPUT);// светодиод servo.attach(12);//серва servo.write(nul);//нулевая позиция серво } void loop() { if (digitalRead(10)) //если сенсор закрыт { digitalWrite(8, LOW); // светодиод не горит OldImpuls = Impuls; // Запоминаем состояние предыдущего импульса if (digitalRead(11)) { Impuls = true; //то запоминаем } else //иначе { Impuls = false; // запоминаем 0 } } else { (digitalWrite(8, HIGH));// светодиод горит servo.write(nul);// серва 0 value = 0; } if (Impuls && !OldImpuls) //Если текущий импульс 1, а предыдущий 0 { encoder++; //Считаем импульсы OldImpuls = Impuls; // Запоминаем состояние предыдущего импульса if (encoder == 6) // 6 импульсов { value = !value; if (value)servo.write(pos); // серва +90 else servo.write(nul);// серва 0 encoder = 0; } } }Ой спасибо! А если разные значения?
Как то так на 26 или другое количество тиков
#include <Servo.h> Servo servo; int sensePin = 12; int pos = 90;//рабочая позиция серво int nul = 0;//нулева позиция серво boolean Impuls, OldImpuls; bool value; int sensor; int encoder; void setup() { pinMode(10, INPUT_PULLUP); //sen pinMode(11, INPUT_PULLUP); //enc pinMode(8, OUTPUT);// светодиод servo.attach(12);//серва servo.write(nul);//нулевая позиция серво } void loop() { if (digitalRead(10)) //если сенсор закрыт { digitalWrite(8, LOW); // светодиод не горит OldImpuls = Impuls; // Запоминаем состояние предыдущего импульса if (digitalRead(11)) { Impuls = true; //то запоминаем } else //иначе { Impuls = false; // запоминаем 0 } } else { (digitalWrite(8, HIGH));// светодиод горит servo.write(nul);// серва 0 value = 0; } if (Impuls && !OldImpuls) //Если текущий импульс 1, а предыдущий 0 { encoder++; //Считаем импульсы OldImpuls = Impuls; // Запоминаем состояние предыдущего импульса if (encoder == 6 && !value) // 6 импульсов { value = !value; servo.write(pos); // серва +90 encoder = 0; } if (encoder == 26 && value) // 26 импульсов { value = !value; servo.write(nul);// серва 0 encoder = 0; } } }Куда теперь девать серву?
Вышли мне по почте.
Куда теперь девать серву?
Вышли мне по почте.
Что взамен предложишь, у меня серв много всяких…
Как то так на 26 или другое количество тиков
#include <Servo.h> Servo servo; int sensePin = 12; int pos = 90;//рабочая позиция серво int nul = 0;//нулева позиция серво boolean Impuls, OldImpuls; bool value; int sensor; int encoder; void setup() { pinMode(10, INPUT_PULLUP); //sen pinMode(11, INPUT_PULLUP); //enc pinMode(8, OUTPUT);// светодиод servo.attach(12);//серва servo.write(nul);//нулевая позиция серво } void loop() { if (digitalRead(10)) //если сенсор закрыт { digitalWrite(8, LOW); // светодиод не горит OldImpuls = Impuls; // Запоминаем состояние предыдущего импульса if (digitalRead(11)) { Impuls = true; //то запоминаем } else //иначе { Impuls = false; // запоминаем 0 } } else { (digitalWrite(8, HIGH));// светодиод горит servo.write(nul);// серва 0 value = 0; } if (Impuls && !OldImpuls) //Если текущий импульс 1, а предыдущий 0 { encoder++; //Считаем импульсы OldImpuls = Impuls; // Запоминаем состояние предыдущего импульса if (encoder == 6 && !value) // 6 импульсов { value = !value; servo.write(pos); // серва +90 encoder = 0; } if (encoder == 26 && value) // 26 импульсов { value = !value; servo.write(nul);// серва 0 encoder = 0; } } }UPD: Заработало, еще раз спасибо.
Разумеется ваши оптопары можно рассматривать как обычные бездребезговые кнопки, в программном разумеется смысле. Так что код у них примерно такой.
...
void loop() { btn = digitalRead(pin); if (!oldBtn && btn) { oldBtn = 1; Do1(); } if (!oldBtn && btn) { btn = 0; Do2(); } }Что-то не могу понять, когда может сработать второе условие?
Никогда, просто Квон обкурился немного когда это писал.