Всем добрый день! Пытаюсь подключить к Attiny13 и сервопривод, но что-то какие-то глюки... Суть работы проста: Установить серву в 90, если на 4 пине логическая "1" то установить серву в 60, если на 3 пине "1" то установить серву в 120. Если на пинах 3 и 4 "0", то установить серву в начальное положение - 90. К пинам 3 и 4 подпаяны резисторы по 20кОм к земле что бы избежать ложных срабатываний. Питается все это от аккумулятора 18650. Заранее оговорюсь: серва нормально работает от 3.3 вольта, проверял на Ардуино ДУЕ! Почему-то серва не хочет нормально позиционироваться. Поворачивается не туда, или вообще не поворачивается... или ровно в 90 не хочет становиться, а стает +- 5-10...
Пишу все это через Ардуино
вот код:
Спойлер
Серва может потреблять большой ток при повороте, может питание просаживается? Попробуйте начертить схему в протеусе и поглядеть виртуальный осциллографом что за сигнал у Вас идет.
Для управления сервой лучше использовать аппаратный ШИМ.
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Знаю что ШИМ было бы лучше, но для меня это темный лес....
По питанию все нормально, точнее, пробовал питать отдельно от 5 вольт - результат тот же. 100% проблема в коде.
Сделать своими руками всегда интересней чем просто купить и пользоваться
Это издалека так кажется, на самом деле там только три тополя.
Для поиска ошибки упростите свой код. Выкиньте все лишнее. Оставте только код для какого-то фиксированного положения сервы. Если работает, попробуйте в другом фиксированном положении. Если и это работает, то тогда уже добавляйте обработчик состояния пинов. И мне кажется, будет лучше всего использовать оператор switch, вместо страшной кучи "ифов".
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Вот код. ШИМ аппаратный. Выход ШИМ PB1. Входа PB3 и PB4 подтянутые к пит. внутр. резистором. Внутренний генератор 9,6МГц. У тиньки 13 счетчик только 8ми битный, что не дает точно выставить ШИМ. Расчетные углы 50, 89, 127 градусов. Частота ШИМ близка к 50Гц.
Спойлер
После долгих экспериментов выяснил что проблему вызывает именно "функция" отключающая повторное обращение к серво. Попробую описать словами. В коде я использовал lastPos = для того чтобы команда для сервы отправлялась только 1 раз (для экономии батареи и др.). Но эта функция вызывала сбой: серва почему-то не успевала позиционироваться в нужное место. Вот что у меня получилось:
Спойлер
#include <avr/io.h>
#include <util/delay.h>
const byte servo = 0; // Servo pin on ATtiny
int tPulse = 4000; // Total pulse length on 1 Mhz clock
int hPulse = 60; // High pulse time (60=0deg -> 280=180deg)
boolean lastPosL = false;
boolean lastPosR = false;
boolean lastPosU = false;
void setup() {
DDRB |= (1<<0);
hPulse = 110;
DDRB &= ~(1<<3);
hPulse = 170;
_delay_ms(100);
pulseOut();
pulseOut();
pulseOut();
}
void loop() {
if (PINB & (1<<PINB3) && lastPosL == false){ //Поворачиваем влево
lastPosL = true;
lastPosR = false;
lastPosU = false;
hPulse = 133;
pulseOut();
pulseOut();
pulseOut();
}
else if (PINB & (1<<PINB4) && lastPosR == false){ //Поворачиваем вправо
lastPosL = false;
lastPosR = true;
lastPosU = false;
hPulse = 240;
pulseOut();
pulseOut();
pulseOut();
}
else if (!(PINB & (1<<PINB3)) && !(PINB & (1<<PINB4)) && lastPosU == false) //Исходное положение
{
lastPosL = false;
lastPosR = false;
lastPosU = true;
hPulse = 170;
pulseOut();
pulseOut();
pulseOut();
pulseOut();
}
delayMicroseconds(500); // Give servo some time to move before giving it a new position
}
void pulseOut(){
PORTB |= (1<<0);
delayMicroseconds(hPulse); // High pulse angle data
PORTB &= ~(1<<0);
delayMicroseconds(tPulse-hPulse);
}
Немного поясню код:
Функция pulseOut() отвечает за управление сервой. Ее вызов и является самой большой проблемой. Если в функциях поворотов влево-вправо-возврат сделать вызов pulseOut() только 1 раз то pulseOut() может сработать не корректно, особенно это касается функции возврата в исходное положение, там нормально не срабатывает вовсе. Я пробовал делать паузу сразу после вызова функции - эффект тот же. pulseOut() работает только если ее вызывать несколько раз подряд. Причем если в самой функции pulseOut() сделать цикл for.. то pulseOut() опять таки работает не корректно. Но же касается и вызова функции из функций поворотов - если ставлю вызов функции pulseOut() в цикл то получаю те же проблемы... Потому я просто написал вызов pulseOut() несколько раз. Работает без проблем. Если знаете из-за чего такая непонятка с работой кода, подскажите пожалуйста, буду очень благодарен.
Z_h_e Спасибо! Буду пробовать! Для меня ШИМ и таймеры пока темный лес... Z_h_e, похожий код я находил для Attiny2313, но я не смог его переделать для Attiny13 так как не нашел в даташите как настроить предделитель счетчика, и что это за параметр: CLKPR тоже не понял...
Попробовал ваш код - тишина, серва молчит. При подключении "+" к портам 3 и 4 ничего не происходит.
Последний раз редактировалось forfrends Вс авг 14, 2016 19:40:50, всего редактировалось 1 раз.
Сделать своими руками всегда интересней чем просто купить и пользоваться
Хм... та же история. Проверил фьюзы - настроен на 9.6мГц. Пробовал менять на 1.2 - результат тот же. Но код что я писал выше меня, пока, устраивает. Хотя ваш почти в 5 раз меньше места занимает! Круто!
Сделать своими руками всегда интересней чем просто купить и пользоваться
Я пробовал в протеусе, работает.
Вы обратили внимание что выход ШИМ идет с порта PB1?
1.2 МГц, это видимо Вы ставили генератор на 9,6 и делитель на 8. Значение делителя это и есть регистр CLKPR. Так что в моем коде не важно установили Вы делитель на 8 или нет. А вот генератор должен быть 9,6.
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
COKPOWEHEU писал(а):Первый раз слышу про оператор loop в языке Си. Не подскажете где про него можно почитать?
Упс!
Прошу прощения. Попутал с VBA. У Си только FOR и WHILE.
Но в любом случае не стоит называть свои функции также как и стандартные операторы языков. Хорошо если "ругнется" компилятор, а вот линковщик может и не ругнуться, а найти ошибку будет значительно сложней.
Доброго времени суток!
Помогите разобраться с проблемой.
тини13 + сенсорная кнопка + серво + транзисторный ключ
Тини в повердаун режиме, если коснуться сенсорной кнопки на 6 ногу (PB1) приходит сигнал 0, что бы тинька вышла из сна.
Дальше на это все дело повешано прерывание INT0, в функции которая его обрабатывает пытаюсь ключить транзисторный ключ (нога 3 PB4), потом после этого со значения 150 сервой повернуться до 200 и назад 150, выключить ключ, и заснуть
Если с просыпанием и засыпанием все ок, то с сервой полный треш - серва живет своей жиснь. Никак не могу разобраться как шим и прерывание собрать вместе.
Скорее всего я не до конца понимаю как настраивать и работать с шим для сервы.
Серва Tower ProSG90