Inspire-подобная рама своими руками с нуля

rc468

Да, и еще.
Допустим, у вас нажата кнопка.
Тогда срабатывает
myservo.write(90); // лучи в среднем положении

Но вслед за этим проверяется длина сигнала и может сработать что-то еще.
Т.е. если нажата кнопка, то в цикле у вас получится так, что сначала всегда пишется 90, а затем пишется что-то еще в зависимости от длины сигнала.

Slevin757
rc468:

Но вслед за этим проверяется длина сигнала и может сработать что-то еще.

А может тогда дописать еще одно условие после проверки кнопки?

if (digitalRead(button) != HIGH)
{
… и пошло дальше

rc468

Вот такой оптимизированный цикл:
int last_servo_mode = -1;
int servo_mode = -1;

void loop() {
if (digitalRead(button) == HIGH) {
// если кнопка транспортного положения нажата
servo_mode = 90; // лучи в среднем положении
}

duration = pulseIn(pin, HIGH); // считывается длинна сигнала

if (duration > 1800) {
// если тумблер в нижнем положении
servo_mode = 0; // лучи опускаются вниз
} else if (duration > 1200) {
// если тумблер посередине
servo_mode = 180; // лучи поднимаются вверх
} else {
// если тумблер в верхнем положении
// замеряется расстояние до земли:
Serial.flush();
Serial.write(0x55);
delay(10);
if (Serial.available() >= 2) {
HighLen = Serial.read();
LowLen = Serial.read();
Len_mm = HighLen << 8 + LowLen;
Serial.print(Len_mm, DEC);
Serial.println(“mm”);
}

if (Len_mm <= dist) {
// если расстояние ниже, равно пороговому
servo_mode = 0; // лучи лучи опускаются вниз
} else {
// если расстояние выше порогового
servo_mode = 180; // лучи поднимаются вверх
}
}

if (servo_mode != last_servo_mode) {
myservo.write(servo_mode);
last_servo_mode = servo_mode;
}
}

Slevin757:

А может тогда дописать еще одно условие после проверки кнопки?

А у вас кнопка или переключатель имеет приоритет? Если кнопка, то после обработки кнопки надо пропустить остальную часть (поместить ее в else), если переключатель, то оставить как есть. (Но писать все равно один раз за цикл, как я запостил выше).

Slevin757
rc468:

А у вас кнопка или переключатель имеет приоритет?

Кнопка в приоритете. Так как нажимается только при подготовке к полету и при завершении.

я тут пока испробовал код по первой рекомендации - в транспортном положении стоит ровно, не гудит и не дергается. А в остальных режимах дергает.
Сейчас разберусь в коде второй рекомендации. Благодарю, что потратили время на написание.

rc468

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

Slevin757

Вот так?

… if (Len_mm <= dist) {

servo_mode = 0;
}
else
{
servo_mode = 180;
}
}

if (digitalRead(button) == HIGH) {
// если кнопка транспортного положения нажата
myservo.write(90); // лучи в среднем положении
servo_mode = 90;
}

if (servo_mode != last_servo_mode) {
myservo.write(servo_mode);

last_servo_mode = servo_mode;
}

}

На кнопку стал правильно реагировать, но вращение мотора испортилось. После первой рекомендации он в АВТО плохо себя вел, но зато в ручном крутил отлично. А сейчас в обоих режимах в одну сторону крутит, а в другую дергается.

rc468
Slevin757:

Вот так?

Да.

Slevin757:

вращение мотора испортилось

Трудно понять на расстоянии. Буду думать.

Slevin757

Тааакс… Подправил граничные условия в одном месте, вернул старый скетч эхолота и стер фрагмент про кнопку - пошло на пользу. Мотор ровно крутит в обе стороны и в обоих режимах. На сонар реагирует корректно.

Теперь надо фрагмент про кнопку правильно вставить.

Нее, если в то место вставляю, то картина портится.
Попробую в начало

Не, чет не то… Без кнопки все прям прекрасно работает. А фрагмент с кнопкой все резко портит. Андрей, кажется вы писали про оператор Continue, но потом редактировали. Он может помочь при размещении кода кнопки в начале цикла?

Текущее работоспособное состояние цикла без кнопки:

void loop()

{

duration = pulseIn(pin, HIGH);

if (duration > 1800)
{
servo_mode = 0;
} else if ((duration > 1300)&(duration <= 1700))
{
servo_mode = 180;
}
else
{
Serial.flush();
Serial.write(0x55);
delay(10);
if (Serial.available() >= 2)
{
HighLen = Serial.read();
LowLen = Serial.read();
Len_mm = HighLen * 256 + LowLen;
Serial.print(Len_mm, DEC);
Serial.println(“mm”);
}
if (Len_mm <= dist)
{
servo_mode = 0;
}
else
{
servo_mode = 180;
}
}
if (servo_mode != last_servo_mode)
{
myservo.write(servo_mode);
last_servo_mode = servo_mode;
}
}

rc468
Slevin757:

писали про оператор Continue, но потом редактировали

continue это переход на следующий шаг цикла с текущего места, его использовать нельзя, потому что это не цикл for или while, поэтому я и отредактировал. Он не может помочь.
Надо понять, почему кнопка влияет так.

А вы можете наоборот все убрать и оставить только кнопку?

Оставить только кнопку и дополнить реакцию на отжатие:
if (digitalRead(button) == HIGH) {
// если кнопка транспортного положения нажата
servo_mode = 90; // лучи в среднем положении
} else {
servo_mode = 0; // в любом другом положении
}

Slevin757
rc468:

А вы можете наоборот все убрать и оставить только кнопку?

Сама по себе стопорит она нормально. Но своим присутствием этот фрагмент кода влияет на остальной цикл и серва начинает неровно крутиться, стопориться, дергалься

if (digitalRead(button) == HIGH)
{myservo.write(90);
servo_mode = 90;}

Мне кажется хорошо бы воткнуть его вначале, чтобы программа проверила его, и если кнопка включена, то оставшаяся часть кода была бы проигнорирована за ненадобностью.
А если кнопка не нажата, то цикл выполнялся бы полностью.

rc468:

А вы можете наоборот все убрать и оставить только кнопку?

сейчас попробую…

rc468
Slevin757:

Но своим присутствием этот фрагмент кода влияет на остальной цикл и серва начинает неровно крутиться, стопориться, дергалься if (digitalRead(button) == HIGH) {myservo.write(90); servo_mode = 90;}

Погодите, именно этот фрагмент?
С ним будет дергаться, потому что в нем запись происходит. В нем должно быть только servo_mode = 90 и больше ничего. Запись производится после всех проверок один раз в конце цикла.

Slevin757

добавил команду myservo.write(servo_mode), чтоб приняла к исполнению, получилось:

if (digitalRead(button) == HIGH) {
// если кнопка транспортного положения нажата
servo_mode = 90; // лучи в среднем положении
myservo.write(servo_mode);
}
else
{
servo_mode = 0; // в любом другом положении
myservo.write(servo_mode);
}

Вообще-то странно себя ведет. Может сразу запуститься после отпускания кнопки, а может постоять на месте приличное время. Не ожидал сюрприза в таком простом фрагменте.

rc468:

Погодите, именно этот фрагмент?
С ним будет дергаться, потому что в нем запись происходит. В нем должно быть только servo_mode = 90 и больше ничего.

таааакс, сейчас переделаю)

rc468
Slevin757:

Мне кажется хорошо бы воткнуть его вначале, чтобы программа проверила его, и если кнопка включена, то оставшаяся часть кода была бы проигнорирована за ненадобностью.

Это неважно, т.к. запись происходит один раз в конце цикла. Кто последний изменил servo_mode, тот и приоритетнее.
Но вы можете поставить кнопку в начало, а остально завернуть в блок else, так вы избежите ненужных проверок
if (digitalRead(button) == HIGH) {
// если кнопка транспортного положения нажата
servo_mode = 90; // лучи в среднем положении
} else {
// здесь все остальные проверки
}

Slevin757

Попробовал в конец и в начало с Else. Чертовщина какая-то. Весь цикл прекрасно работает пока этот фрагмент не вставлю. Хоть в начало, хоть в конец - все одно - стопорит хорошо, но в “отжатом” положении серва плохо крутится.

Пожалуй надо придумать другой способ входа в транспортный режим, без кнопки.

Андрей, за код премного благодарю! “Авто” и “Ручной” работают как надо. Без вашей помощи не допетрил бы.
А на счет транспортного подумаю еще.

rc468
Slevin757:

но в “отжатом” положении серва плохо крутится.

нет ли в отжатом положении какого-то дребезга кнопки?

Ну и еще такая мысль - может серве не нравится конкретно положение 90? Попробуйте сделать что-то типа 160 или 30, посмотрите как отреагирует.

Slevin757
rc468:

нет ли в отжатом положении какого-то дребезга кнопки?

ну у меня самой кнопки пока нет - ее роль выполняли провода со штекерами мама-папа

rc468:

Попробуйте сделать что-то типа 160 или 30, посмотрите как отреагирует.

я перед экспериментами раскрутил серву (тестовая серва непрерывного вращения), подкрутил энкодер, чтобы четко при 90* стопорилась без гудения. Поэтому встает то она хорошо, а вот влияет нехорошо.

rc468
Slevin757:

Пожалуй надо придумать другой способ входа в транспортный режим, без кнопки.

Мы его добьем 😉 Должно работать. Может быть просто кнопка какая-то особенная и сигнал HIGH появляется только однократно, а не все время пока она нажата? Можно добавить код, который проверяет, как долго кнопка находилась в положении HIGH, и меняет режим сервы, только если прошло полсекунды, например.

Slevin757
rc468:

Мы его добьем Должно работать.

Основательный подход))

rc468:

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

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

Вспомнил странность про которую писал выше, когда вы предложили протестировать чисто код стопорения… Я кнопку оджимал, а серва не торопилась крутиться. Могла сразу начать, а могла секунд пять стоять на месте, а потом начинать вращение… Мне это показалось крайне странным.
То есть как бы даже Через Чур стопорила, если можно так сказать… может это “черезчурстопорение” и вызывает пинки в работе сервы в режимах когда она должна вращаться.

Может микшером каналов на аппаратуре добавить еще одну четвертую ширину импульса для этого канала. Задействовать дополнительный тумблер для транспортного положения.

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

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

Slevin757

Поковырял на пульте программный микшер - в принципе как вариант можно испробовать. Но это уже завтра, ибо утро вечера мудренее)

rc468
Slevin757:

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

Дело в том, что чудес не бывает. Код должен работать. Причина сбоя в какой-то хитрости появления сигнала HIGH.
Давайте займемся только кнопкой.
Я по этой ссылке сделал код, попробуйте ее открыть, а то здесь теряется все форматирование. Там и чатик есть.
collabedit.com/4qfup

CZC

А не пробовали использовать встроенный резистор подтяжки на ардуине. Он как раз служит для того чтобы устранять дребезг контактов.

pinMode(pin,OUTPUT); // выход
pinMode(pin,INPUT); // вход
pinMode(pin,INPUT_PULLUP); // вход с подтяжкой