16 сервоприводов. Библиотека Adafruit_PWMServoDriver.h
- Войдите на сайт для отправки комментариев
Всем привет!
Прошу помочь разобраться с библитекой Adafruit_PWMServoDriver.h.
Купил Adafruit 16-Channel Servo Driver (НЕ РЕКЛАМА! ссылка на картинку+документацию https://learn.adafruit.com/downloads/pdf/16-channel-pwm-servo-driver.pdf ).
Ранее работал с servo.h, с ней все достаточно просто. С этой у меня пошло туго, в документации написано сделайте: pulselength = map(degrees, 0, 180, SERVOMIN, SERVOMAX); и получите градусы. Но куда впихнуть, и как вызвать?
В примерах библиотеки все завязано на циклах, ШИМ и тучи непонятных мне параметров. Не могу понять как хотя бы одну определенную серву повернуть в -90 град, затем в +90 град. Там все завязано на setPWM(channel, on, off):
Arguments channel:
The channel that should be updated with the new values (0..15)
on: The tick (between 0..4095) when the signal should transition from low to high
off:the tick (between 0..4095) when the signal should transition from high to low
Как всем этим чудом управлять ума не приложу, прошу помочь с самым простым скетчем, или ткните меня в ман, что почитать, где посмотреть.
Сейчас скеч выглядит так для 4-х серв:
/*************************************************** This is an example for our Adafruit 16-channel PWM & Servo driver Servo test - this will drive 16 servos, one after the other Pick one up today in the adafruit shop! ------> http://www.adafruit.com/products/815 These displays use I2C to communicate, 2 pins are required to interface. For Arduino UNOs, thats SCL -> Analog 5, SDA -> Analog 4 Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! Written by Limor Fried/Ladyada for Adafruit Industries. BSD license, all text above must be included in any redistribution ****************************************************/ #include <Wire.h> #include <Adafruit_PWMServoDriver.h> // called this way, it uses the default address 0x40 Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); // you can also call it with a different address you want //Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41); // Depending on your servo make, the pulse width min and max may vary, you // want these to be as small/large as possible without hitting the hard stop // for max range. You'll have to tweak them as necessary to match the servos you // have! #define SERVOMIN 125 // this is the 'minimum' pulse length count (out of 4096) #define SERVOMAX 580 // this is the 'maximum' pulse length count (out of 4096) // our servo # counter uint8_t servonum = 0; void setup() { Serial.begin(9600); Serial.println("16 channel Servo test!"); #ifdef ESP8266 Wire.pins(2, 14); // ESP8266 can use any two pins, such as SDA to #2 and SCL to #14 #endif pwm.begin(); pwm.setPWMFreq(60); // Analog servos run at ~60 Hz updates yield(); } // you can use this function if you'd like to set the pulse length in seconds // e.g. setServoPulse(0, 0.001) is a ~1 millisecond pulse width. its not precise! void setServoPulse(uint8_t n, double pulse) { double pulselength; // pulselength = 1000000; // 1,000,000 us per second // pulselength /= 60; // 60 Hz Serial.print(pulselength); Serial.println(" us per period"); // pulselength /= 4096; // 12 bits of resolution Serial.print(pulselength); Serial.println(" us per bit"); // pulse *= 1000; // pulse /= pulselength; // Serial.println(pulse); // pwm.setPWM(n, 0, pulse); } void loop() { // Drive each servo one at a time Serial.println(servonum); for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) { pwm.setPWM(servonum, 0, pulselen); } delay(500); for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) { pwm.setPWM(servonum, 0, pulselen); } delay(500); servonum ++; if (servonum > 3) servonum = 0; }
уважаемые форумчане, что я не так пишу?)
Как тут получить ответ, как формулировать вопрос? Или мне с такими вопросами заказывать код нужно?
Или вопрос совсем идиотский?
уважаемые форумчане, что я не так пишу?)
Как тут получить ответ, как формулировать вопрос? Или мне с такими вопросами заказывать код нужно?
Или вопрос совсем идиотский?
Вы, по сути, просите Вас быстренько научить всему, чтобы разобраться с конкретным случаем. На форуме Вам помогут, если "куча непонятных параметров" будет Вам понятна, Вы "в полном соответствии" все делаете, а "оно не лезет", когда должно "лезть". Вот тогда Ваш конкретный случай Вам помогут разобрать.
А что вас смутило-то? В параметрах к функции всё четко прописано: номер канала, сервы; длительность части периода "on"; длительность части периода "off" и даже диапазон указан .. Вы не знаете КАК управляются Сервы? Как раз этими самыми "длительностями". В даташите на каждую, они честно прописаны в миллисекундах "от" (-90), "до" (+90) или по другим углам.. что "непонятно"-то? Как значение в градусах преобразовать в длительности? Так сами же и приводите функцию map() .. ею.
Хотите, чтобы вам сделали готовый "пирог"? Ну так вы разделом ошиблись, как понимаю. Вам верно ответили: есть конкретные непонятки - спрашивайте, ответят.
Понял, спасибо, буду думать. Вроде руки из Ж... не растут, но нечерта не выходит. Все легкие задачи без проблем решаются, стоит логику придумать из двух двигателей, ультразвукового датчика и сервы все идет лесом. Будем книжки читать.
Логика управления не содержит ничего заумного. Тег "автоматное программирование" вам в руки, дерзайте. :)
Letro привет!
ну, да, не очень деликатно, но мол ...иди и учись. Что ж, может чем и помогу. То же только постигаю азы С++ с Ардуино. Мне инужно эти сервы (чуть больше 20 ) управлять вручную (от тумблером) нагруженных на расширитель MCP23016.
Брал Ваш, скетч (он из примера по PWM 16 channels),
поигрался вот с этим
Шикарная библиотека, шикарный шильд. Для лучшего понимания работы посмотрите второй пример, который идет с данной библиотекой. А вооще главное отличие от библиотеки servo.h в том, что на указзном шильде стоит 12битный контроллер PWM с управлением по i2c.
Если в стандартной библиотеке мы задаем просто градус, на который нужно отклониться, то здесь будем управлять исключительно длительностью импульса. Хотя даже не длительностью, а 12битной последовательностью (4096 значений).
К примеру:
Пусть диапазон длительностей управляющих импульсов сервы равен: 800 мкс до 2000 мкс.
Частота следования управляющих импульстов 50 ГЦ (период 20 мс)
Пересчитаем в управляющий код:
1.000.000 мкс / 4096 / 50 ГЦ = 4,88 - это вес единицы в последовательности
т.е. 800 мкс управления обычной сервой будет соответсвовать значению = 800/4,88 = 164
а 2000 мкс = 410
т.е. что бы загнать сервы в одно крайнее положение нужно лишь написать
pwm.setPWM(servonum, 0, 164)а вдругое
pwm.setPWM(servonum, 0, 410)Ну для удобства можно все пересчитывать через угол посредтсвом команды map()
так что сложного ничего тут нет. Зато позволяет задействовав всего 2 порта управлять 16 двигателями.
Точно!!! я так и поступил. И спасибо за помощь Sindbad !!! Провел натурные испытания, проверил необходимые мне углы отклонения и в обновленном скетче я использовалТочно!!! я так и поступил. И спасибо за помощь Sindbad !!! Провел натурные испытания, проверил необходимые мне углы отклонения и в обновленном скетче я использовал
if (AC[i] == 0) { //Serial.print ("Servo # "); Serial.print (servonum); Serial.println (" Left"); pwm.setPWM(servonum, 0, 330); } else { //Serial.print ("Servo # "); Serial.print (servonum); Serial.println (" Right"); pwm.setPWM(servonum, 0, 380); }Что-то зазбоило. Будет здорово если модератор удалит предыдущее сообщение...
Извиняюсь.
Добрый день!
Решил более глубоко разобраться с библиотекой Adafruit_PWMServoDriver.h. Но не смог найти ответа на два вопроса:
1. Что за тип переменной uint8_t и uint16_t ? В чём их разница?
2. Почему у 12-ти битной последовательности 4096 значений? Как это высчитывается?
1) uint8_t - 8 bit - 1 byte (в Arduino - byte), uint16_t - 16 bit - 2 byte (в Arduino - unsigned int)
2) 2^12 = 4096
Добрый день!
Решил более глубоко разобраться с библиотекой Adafruit_PWMServoDriver.h. Но не смог найти ответа на два вопроса:
1. Что за тип переменной uint8_t и uint16_t ? В чём их разница?
2. Почему у 12-ти битной последовательности 4096 значений? Как это высчитывается?
1. беззнаковое 8 бит, беззнаковое 16 бит
2. 8 бит - 256, 9-бит -512, 10 бит - 1024, 11 бит -2048, 12 бит - 4096
Так понятно?
Первый вопрос примерно - да. А второй вопрос нет, я знал эту зависимость, но не понимаю почему 8 бит это именно 256, а 12 бит это 4096... Может не верно гуглу вопросы задавал, ответа найти не смог.
И какие вопросу вы гуглу задавали?
https://www.google.com/search?q=почему+8+бит+это+256
cpp data types
но не понимаю почему 8 бит это именно 256, а 12 бит это 4096... Может не верно гуглу вопросы задавал, ответа найти не смог.
Допустимое число неповторяющихся комбинаций ноликов и единичек при заданном количестве разрядов.
Допустимое число неповторяющихся комбинаций ноликов и единичек при заданном количестве разрядов.
Спасибо, самый короткий и мне понятный ответ. :)
Спасибо Вам и всем, кто ответил. :)
День добрый а как то можно в данной библиотеке отрегулировать скорость вращения сервоприводов? Пока не понял как( Если кто может тыкните
День добрый а как то можно в данной библиотеке отрегулировать скорость вращения сервоприводов? Пока не понял как( Если кто может тыкните
А почему Вы решили, что скорость сервоприводов вообще поддается регулировке?
Поворачивать на один грасус с разной задеркой? Не?
Тогда скорость будет изменяться ступенчато.
И, кстати, почему именно на один градус? Почему не на 0.8 или 0.006?
У Гайвера есть библиотека, даже с платкой-расширителем работает.
https://alexgyver.ru/servosmooth/
А самому можно регулировать скорость по алгоритму "из угла А в угол В за время t" это и будет угловая скорость.
А самому можно регулировать скорость по алгоритму "из угла А в угол В за время t" это и будет угловая скорость.
Тогда что Вам еще нужно?
Лично мне ничего :-), это "Селтвику" надо.
И, кстати, почему именно на один градус? Почему не на 0.8 или 0.006?
Потому что работать не будет. Даже с 1 градусом. У дешевых серво мертвая полоса больше градуса. И движение будет со скачками, а не с ровной скоростью.
Ранее работал с servo.h, с ней все достаточно просто. С этой у меня пошло туго, в документации написано сделайте: pulselength = map(degrees, 0, 180, SERVOMIN, SERVOMAX); и получите градусы. Но куда впихнуть, и как вызвать?
В общем тут вам не помогут потому как сидят одни снобы и могут только умничать, все уже позабыли как были в начале пути и как сложно что то понять, особо если не хочется ради мелкой фигни учить всю мат часть. И уж тем более не понимают что люди может вовсе и не собираются на программиста учиться им тупо надо свой проект сделать, чтоб в комнате свет включался и всё.
Короче строчку pulselength = map(degrees, 0, 180, SERVOMIN, SERVOMAX); все сайты бездумно копируют а выдрана она вообще с гитхаба пендосовского, вот ссылка: https://gist.github.com/Injac/ddf7459038bd2e4a6bd5
//полностью этот кусок кода выглядит так
for(uint8_t degrees = 1; degrees <=180;degrees++) { pulsedegree = map(degrees, 0, 180, SERVOMIN, SERVOMAX); pwm.setPWM(0, 0, pulsedegree); delay(1); Serial.println(degrees); }А вообще чтоб не корячиться с импульсами уже давно есть библиотека под плату PCA9685 нужная под градусы
Вот видео посмотри https://youtu.be/V0BRwptjp10
тут вам не помогут потому как сидят одни снобы и могут только умничать, все уже позабыли как были в начале пути и как сложно что то понять, особо если не хочется ради мелкой фигни учить всю мат часть. И уж тем более не понимают что люди может вовсе и не собираются на программиста учиться им тупо надо свой проект сделать, чтоб в комнате свет включался и всё.
вы правы, таким, которым "не хочется учить всю матчасть" чтоб "тупо один проект сделать" - тут помогают только за деньги. Но что за печаль, форумов в мире много, выберите какой-нить другой.
А у нас тут иная направленность, мы хотим общаться с теми, кому и матчасть интересна, и с теми кто на практических проектах не очень зациклен - нехай ниче не работает. зато в документации разобрался :)))
PS кстати. нашел ваш вопрос поиском - вам там почти в первом же сообщении дали верный ответ - а если вы его не поняли. или, что точнее - НЕ ЗАХОТЕЛИ ПОНЯТЬ - так обижаться надо только на себя
И уж тем более не понимают что люди может вовсе и не собираются на программиста учиться им тупо надо свой проект сделать, чтоб в комнате свет включался и всё.
Напротив, это Вы не понимаете, что те, кто не хочет учиться, на этом форуме - чужаки, и потому не имеют права на бесплатную консультацию.