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 !!! Провел натурные испытания, проверил необходимые мне углы отклонения и в обновленном скетче я использовал
Что-то зазбоило. Будет здорово если модератор удалит предыдущее сообщение...
Извиняюсь.
Добрый день!
Решил более глубоко разобраться с библиотекой 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
//полностью этот кусок кода выглядит так
А вообще чтоб не корячиться с импульсами уже давно есть библиотека под плату PCA9685 нужная под градусы
Вот видео посмотри https://youtu.be/V0BRwptjp10
тут вам не помогут потому как сидят одни снобы и могут только умничать, все уже позабыли как были в начале пути и как сложно что то понять, особо если не хочется ради мелкой фигни учить всю мат часть. И уж тем более не понимают что люди может вовсе и не собираются на программиста учиться им тупо надо свой проект сделать, чтоб в комнате свет включался и всё.
вы правы, таким, которым "не хочется учить всю матчасть" чтоб "тупо один проект сделать" - тут помогают только за деньги. Но что за печаль, форумов в мире много, выберите какой-нить другой.
А у нас тут иная направленность, мы хотим общаться с теми, кому и матчасть интересна, и с теми кто на практических проектах не очень зациклен - нехай ниче не работает. зато в документации разобрался :)))
PS кстати. нашел ваш вопрос поиском - вам там почти в первом же сообщении дали верный ответ - а если вы его не поняли. или, что точнее - НЕ ЗАХОТЕЛИ ПОНЯТЬ - так обижаться надо только на себя
И уж тем более не понимают что люди может вовсе и не собираются на программиста учиться им тупо надо свой проект сделать, чтоб в комнате свет включался и всё.
Напротив, это Вы не понимаете, что те, кто не хочет учиться, на этом форуме - чужаки, и потому не имеют права на бесплатную консультацию.