├── .gitattributes ├── .github └── workflows │ └── tg-send.yml ├── LICENSE ├── README.md ├── README_EN.md ├── examples ├── GyverMotor │ ├── motor_control_10bit │ │ └── motor_control_10bit.ino │ ├── motor_control_31kHz │ │ └── motor_control_31kHz.ino │ ├── motor_demo │ │ └── motor_demo.ino │ ├── multi_motor │ │ └── multi_motor.ino │ ├── multi_motor_tank │ │ └── multi_motor_tank.ino │ └── smooth_control │ │ └── smooth_control.ino └── GyverMotor2 │ ├── demo │ └── demo.ino │ ├── potControl │ └── potControl.ino │ └── serialControl │ └── serialControl.ino ├── keywords.txt ├── library.properties └── src ├── GyverMotor.cpp ├── GyverMotor.h └── GyverMotor2.h /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.github/workflows/tg-send.yml: -------------------------------------------------------------------------------- 1 | 2 | name: Telegram Message 3 | on: 4 | release: 5 | types: [published] 6 | jobs: 7 | build: 8 | name: Send Message 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: send telegram message on push 12 | uses: appleboy/telegram-action@master 13 | with: 14 | to: ${{ secrets.TELEGRAM_TO }} 15 | token: ${{ secrets.TELEGRAM_TOKEN }} 16 | disable_web_page_preview: true 17 | message: | 18 | ${{ github.event.repository.name }} v${{ github.event.release.tag_name }} 19 | ${{ github.event.release.body }} 20 | https://github.com/${{ github.repository }} 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 AlexGyver 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![latest](https://img.shields.io/github/v/release/GyverLibs/GyverMotor.svg?color=brightgreen)](https://github.com/GyverLibs/GyverMotor/releases/latest/download/GyverMotor.zip) 2 | [![PIO](https://badges.registry.platformio.org/packages/gyverlibs/library/GyverMotor.svg)](https://registry.platformio.org/libraries/gyverlibs/GyverMotor) 3 | [![Foo](https://img.shields.io/badge/Website-AlexGyver.ru-blue.svg?style=flat-square)](https://alexgyver.ru/) 4 | [![Foo](https://img.shields.io/badge/%E2%82%BD%24%E2%82%AC%20%D0%9F%D0%BE%D0%B4%D0%B4%D0%B5%D1%80%D0%B6%D0%B0%D1%82%D1%8C-%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B0-orange.svg?style=flat-square)](https://alexgyver.ru/support_alex/) 5 | [![Foo](https://img.shields.io/badge/README-ENGLISH-blueviolet.svg?style=flat-square)](https://github-com.translate.goog/GyverLibs/GyverMotor?_x_tr_sl=ru&_x_tr_tl=en) 6 | 7 | [![Foo](https://img.shields.io/badge/ПОДПИСАТЬСЯ-НА%20ОБНОВЛЕНИЯ-brightgreen.svg?style=social&logo=telegram&color=blue)](https://t.me/GyverLibs) 8 | 9 | # GyverMotor 10 | Библиотека для удобного управления коллекторными моторами через драйвер 11 | - Контроль скорости и направления вращения 12 | - Работа с ШИМ любого разрешения 13 | - Плавный пуск и изменение скорости 14 | - Активный тормоз 15 | - Порог минимального ШИМ 16 | - Deadtime 17 | - Поддержка 5 типов драйверов 18 | 19 | > Библиотека "состоит" из двух библиотек: GyverMotor и GyverMotor2. Вторая версия новее, легче, лучше оптимизирована и проще в использовании! 20 | 21 | ### Совместимость 22 | Совместима со всеми Arduino платформами (используются Arduino-функции) 23 | - Для esp8266 (до SDK v2.7.4) не забудь переключить управление в 10 бит! 24 | 25 | ### Документация 26 | К библиотеке есть [расширенная документация](https://alexgyver.ru/GyverMotor/) 27 | 28 | ## Содержание 29 | - [Установка](#install) 30 | - [Инициализация](#init) 31 | - [Использование](#usage) 32 | - [Пример](#example) 33 | - [Версии](#versions) 34 | - [Баги и обратная связь](#feedback) 35 | 36 | 37 | ## Установка 38 | - Библиотеку можно найти по названию **GyverMotor** и установить через менеджер библиотек в: 39 | - Arduino IDE 40 | - Arduino IDE v2 41 | - PlatformIO 42 | - [Скачать библиотеку](https://github.com/GyverLibs/GyverMotor/archive/refs/heads/main.zip) .zip архивом для ручной установки: 43 | - Распаковать и положить в *C:\Program Files (x86)\Arduino\libraries* (Windows x64) 44 | - Распаковать и положить в *C:\Program Files\Arduino\libraries* (Windows x32) 45 | - Распаковать и положить в *Документы/Arduino/libraries/* 46 | - (Arduino IDE) автоматическая установка из .zip: *Скетч/Подключить библиотеку/Добавить .ZIP библиотеку…* и указать скачанный архив 47 | - Читай более подробную инструкцию по установке библиотек [здесь](https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA) 48 | ### Обновление 49 | - Рекомендую всегда обновлять библиотеку: в новых версиях исправляются ошибки и баги, а также проводится оптимизация и добавляются новые фичи 50 | - Через менеджер библиотек IDE: найти библиотеку как при установке и нажать "Обновить" 51 | - Вручную: **удалить папку со старой версией**, а затем положить на её место новую. "Замену" делать нельзя: иногда в новых версиях удаляются файлы, которые останутся при замене и могут привести к ошибкам! 52 | 53 | 54 | 55 | 56 | ## Инициализация (GyverMotor2) 57 | Типы драйверов: 58 | 59 | | Драйвер | Описание | Пины | Сигнал вперёд | Сигнал назад | 60 | |--------------------------|----------------------------------------|-----------------|---------------|--------------| 61 | | `DRIVER2WIRE` | двухпроводной драйвер с инверсией шим | GPIO, PWM | 0, PWM | 1, ~PWM | 62 | | `DRIVER2WIRE_NO_INVERT` | двухпроводной драйвер без инверсии ШИМ | GPIO, PWM | 0, PWM | 1, PWM | 63 | | `DRIVER2WIRE_PWM` | двухпроводной драйвер с двумя ШИМ | PWM, PWM | 0, PWM | PWM, 0 | 64 | | `DRIVER2WIRE_PWM_INVERT` | двухпроводной драйвер с двумя ШИМ | PWM, PWM | PWM, 1 | 1, PWM | 65 | | `DRIVER3WIRE` | трёхпроводной драйвер | GPIO, GPIO, PWM | 0, 1, PWM | 1, 0, PWM | 66 | | `RELAY2WIRE` | реле в качестве драйвера | GPIO, GPIO | 0, 1 | 1, 0 | 67 | 68 | Для двухпроводных мостовых драйверов стоит отдавать предпочтение типу **DRIVER2WIRE_PWM**. Он требует два ШИМ пина, 69 | но драйвер работает более правильно и меньше нагружается, а также скорость будет одинаковая в обе стороны, в отличие от простого **DRIVER2WIRE**. 70 | 71 | > `DRIVER2WIRE_PWM` даёт мотору более высокую скорость, а `DRIVER2WIRE_PWM_INVERT` - более высокий момент 72 | 73 | ```cpp 74 | GMotor2<тип> motor(пин1, пин2, пин3); // разрядность ШИМ 8 бит (0.. 255) 75 | GMotor2<тип, разрядность> motor(пин1, пин2, пин3); // общий случай, разрядность ШИМ в битах 76 | ``` 77 | 78 | 79 | 80 | ## Использование (GyverMotor2) 81 | ```cpp 82 | void setMinDuty(uint16_t mduty); // установить минимальный ШИМ (умолч. 0) 83 | void setMinDutyPerc(uint16_t mduty); // установить минимальный ШИМ в % (умолч. 0) 84 | void setDeadtime(uint16_t us); // установить deadtime в микросекундах (умолч. 0) 85 | void reverse(bool r); // реверс направления (умолч. false) 86 | 87 | void stop(); // остановка. Если включен плавный режим, то плавная 88 | void brake(); // активный тормоз 89 | void setSpeed(int16_t s); // установить скорость (-макс.. макс) 90 | void setSpeedPerc(int16_t s); // установить скорость в процентах (-100.. 100%) 91 | 92 | int8_t getState(); // получить статус: мотор крутится (1 и -1), мотор остановлен (0) 93 | int16_t getSpeed(); // получить текущую скорость мотора 94 | 95 | void smoothMode(bool mode); // установить режим плавного изменения скорости (умолч. false) 96 | void tick(); // плавное изменение к указанной скорости, вызывать в цикле 97 | void setSmoothSpeed(uint8_t s); // установить скорость изменения скорости (умолч. 20) 98 | void setSmoothSpeedPerc(uint8_t s); // установить скорость изменения скорости в процентах 99 | ``` 100 | 101 | ### Разрядность ШИМ 102 | В AVR Arduino по умолчанию используется 8-ми битный ШИМ (0.. 255). В esp8266 используется 10-ти битный (0.. 1023). 103 | При инициализации библиотеки можно настроить нужную разрядность, она может быть любой. 104 | 105 | ### Скорость 106 | Скорость задаётся в `setSpeed(-макс ШИМ.. макс ШИМ)` в величине ШИМ сигнала, либо в `setSpeedPerc(-100.. 100)` в процентах. Скорость может быть отрицательной, 107 | тогда мотор будет крутиться в обратную сторону. При значении 0 мотор остановится и драйвер будет отключен. 108 | 109 | ### Режимы работы 110 | Вызов `stop()` равносилен `setSpeed(0)`. При прямом управлении мотор будет сразу остановлен, при плавном - остановится плавно. Драйвер отключится, вал мотора будет освобождён. 111 | Вызов `brake()` остановит мотор и переключит драйвер в режим активного торможения (замкнёт мотор через себя). Вал мотора будет сопротивляться вращению. 112 | Вызов `reverse(true)` инвертирует направление вращения мотора для всех функций. 113 | 114 | ### Минимальный ШИМ 115 | В `setMinDuty(-макс ШИМ.. макс ШИМ)` можно установить минимальную скорость, при которой мотор начинает вращение, это удобно в большинстве применений. 116 | Установленная в `setSpeed()` скорость будет автоматически масштабироваться с учётом минимальной. 117 | Также можно задать минимальную скорость в процентах `setMinDutyPerc(-100.. 100)`. 118 | 119 | ### Плавный режим 120 | В плавном режиме установленная в `setSpeed()` скорость применяется не сразу, а плавно в течением времени. Для включения 121 | плавного режима нужно вызвать `smoothMode(true)` и поместить в основном цикле программы функцию-тикер `tick()`. 122 | Внутри этой функции скорсть будет плавно меняться по встроенному таймеру (период - 50мс). 123 | Можно настроить скорость изменения скорости - `setSmoothSpeed()` в величинах ШИМ и `setSmoothSpeedPerc()` в процентах. 124 | 125 | 126 | 127 | ## Пример 128 | Остальные примеры смотри в **examples**! 129 | ```cpp 130 | #include 131 | GMotor2 motor(5, 6); 132 | //GMotor2 motor(5, 6); 133 | //GMotor2 motor(5, 6); 134 | //GMotor2 motor(5, 6, 11); 135 | //GMotor2 motor(5, 6); 136 | 137 | void setup() { 138 | motor.setMinDuty(70); // мин. ШИМ 139 | //motor.reverse(1); // реверс 140 | //motor.setDeadtime(5); // deadtime 141 | } 142 | 143 | void loop() { 144 | motor.setSpeed(10); 145 | delay(1000); 146 | motor.setSpeed(-100); 147 | delay(1000); 148 | motor.setSpeed(50); 149 | delay(1000); 150 | motor.setSpeed(255); 151 | delay(1000); 152 | motor.brake(); 153 | delay(3000); 154 | } 155 | ``` 156 | 157 | 158 | 159 | ## Версии 160 | - v1.1 - убраны дефайны 161 | - v1.2 - возвращены дефайны 162 | - v2.0: 163 | - Программный deadtime 164 | - Отрицательные скорости 165 | - Поддержка двух типов драйверов и реле 166 | - Плавный пуск и изменение скорости 167 | - v2.1: небольшие фиксы и добавления 168 | - v2.2: оптимизация 169 | - v2.3: добавлена поддержка esp (исправлены ошибки) 170 | - v2.4: совместимость с другими библами 171 | - v2.5: добавлен тип DRIVER2WIRE_NO_INVERT 172 | - v3.0: переделана логика minDuty, добавлен режим для ШИМ любой битности 173 | - v3.1: мелкие исправления 174 | - v3.2: улучшена стабильность плавного режима 175 | - v3.2.1: вернул run() в public 176 | - v4.0: исправлен баг в GyverMotor. Добавлен GyverMotor2 177 | 178 | 179 | 180 | ## Баги и обратная связь 181 | При нахождении багов создавайте **Issue**, а лучше сразу пишите на почту [alex@alexgyver.ru](mailto:alex@alexgyver.ru) 182 | Библиотека открыта для доработки и ваших **Pull Request**'ов! 183 | 184 | При сообщении о багах или некорректной работе библиотеки нужно обязательно указывать: 185 | - Версия библиотеки 186 | - Какой используется МК 187 | - Версия SDK (для ESP) 188 | - Версия Arduino IDE 189 | - Корректно ли работают ли встроенные примеры, в которых используются функции и конструкции, приводящие к багу в вашем коде 190 | - Какой код загружался, какая работа от него ожидалась и как он работает в реальности 191 | - В идеале приложить минимальный код, в котором наблюдается баг. Не полотно из тысячи строк, а минимальный код -------------------------------------------------------------------------------- /README_EN.md: -------------------------------------------------------------------------------- 1 | This is an automatic translation, may be incorrect in some places. See sources and examples! 2 | 3 | # Gyvermotor 4 | Library for convenient management of collector engines through the driver 5 | - speed control and direction of rotation 6 | - Work with ShIM of any resolution 7 | - smooth start and speed change 8 | - Active brake 9 | - threshold of minimum shim 10 | - Deadtime 11 | - Support 5 types of drivers 12 | 13 | > The library "consists" of two libraries: Gyvermotor and Gyvermotor2.The second version is more new, easier, better optimized and easier to use! 14 | 15 | ## compatibility 16 | Compatible with all arduino platforms (used arduino functions) 17 | - For ESP8266 (to SDK v2.7.4), do not forget to switch the control of 10 bits! 18 | 19 | ### Documentation 20 | There is [expanded documentation] to the library (https://alexgyver.ru/gyvermotor/) 21 | 22 | ## Content 23 | - [installation] (# Install) 24 | - [initialization] (#init) 25 | - [use] (#usage) 26 | - [Example] (# Example) 27 | - [versions] (#varsions) 28 | - [bugs and feedback] (#fedback) 29 | 30 | 31 | ## Installation 32 | - The library can be found by the name ** gyvermotor ** and installed through the library manager in: 33 | - Arduino ide 34 | - Arduino ide v2 35 | - Platformio 36 | - [download the library] (https://github.com/gyverlibs/gyvermotor/archive/refs/heads/main.zip) .Zip archive for manual installation: 37 | - unpack and put in * C: \ Program Files (X86) \ Arduino \ Libraries * (Windows X64) 38 | - unpack and put in * C: \ Program Files \ Arduino \ Libraries * (Windows X32) 39 | - unpack and put in *documents/arduino/libraries/ * 40 | - (Arduino id) Automatic installation from. Zip: * sketch/connect the library/add .Zip library ... * and specify downloaded archive 41 | - Read more detailed instructions for installing libraries [here] (https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%BD%D0%BE%BE%BE%BED0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA) 42 | ### Update 43 | - I recommend always updating the library: errors and bugs are corrected in the new versions, as well as optimization and new features are added 44 | - through the IDE library manager: find the library how to install and click "update" 45 | - Manually: ** remove the folder with the old version **, and then put a new one in its place.“Replacement” cannot be done: sometimes in new versions, files that remain when replacing are deleted and can lead to errors! 46 | 47 | 48 | 49 | ## initialization 50 | Types of drivers: 51 | - ** driver2wire ** - two -wire driver with inversion shim (Dir + PWM) 52 | - ** driver2wire_no_invert ** - two -wire driver without inversion shim (DIR + PWM) 53 | - ** driver2wire_pwm ** - two -wire driver with two shim (PWM + PWM) 54 | - ** driver3wire ** - three -wire driver (Dir + Dir + PWM) 55 | - ** Relay2wire ** - Relay as a driver (Dir + Dir) 56 | 57 | For two -wire bridge drivers, it is worth giving preference to the type ** driver2wire_pwm **.He requires two Shim Pin, 58 | But the driver works more correctly and less loaded, and the speed will be the same in both directions.Unlike simple ** driver2wire **. 59 | 60 |
61 | gyvermotor 62 | 63 | `` `CPP 64 | // Prevention options depending on the type of driver: 65 | Gmotor Motor (Driver2wire, Dig_pin, Pwm_pin, (Low / High)); 66 | Gmotor Motor (Driver2Wire_No_invert, Dig_pin, Pwm_pin, (Low / High)); 67 | Gmotor Motor (Driver3wire, Dig_pin_a, Dig_pin_b, Pwm_pin, (Low/High)); 68 | Gmotor Motor (Relay2wire,dig_pin_a, dig_pin_b, (low/high)); 69 | /* 70 | dig_pin, dig_pin_a, dig_pin_b - any digital PIN MK 71 | Pwm_pin - any shim pin mk 72 | Low / High - Driver level.If, with an increase in speed, the motor, on the contrary, slows down, change the level 73 | */ 74 | `` ` 75 |
76 | 77 |
78 | gyvermotor2 79 | 80 | `` `CPP 81 | Gmotor2 Motor (PIN1, PIN2, PIN3);// discharge shim 8 bits (0 .. 255) 82 | Gmotor2 Motor (PIN1, PIN2, PIN3);// General case, discharge of shim in bits 83 | 84 | // Types and quantity of pins depending on the driver 85 | Gmotor2 Motor (GPIO, PWM); 86 | Gmotor2 motor (GPIO, PWM); 87 | Gmotor2 Motor (PWM, PWM); 88 | Gmotor2 Motor (GPIO, GPIO, PWM); 89 | GMOTOR2 MOTOR (GPIO, GPIO); 90 | `` ` 91 |
92 | 93 | 94 | ## Usage 95 |
96 | gyvermotor 97 | 98 | `` `CPP 99 | Gmotor (GM_DRIVERTYPE TYPE, Int8_T PARAM1 = _GM_NC, Int8_T PARAM2 = _GM_NC, Int8_T PARAM3 = _GM_NC, Int8_T PARAM4 = _GM_NC); 100 | // Three options for creating an object depending on the driver: 101 | // Gmotor Motor (Driver2wire, Dig_pin, Pwm_pin, (Low/High)) 102 | // Gmotor Motor (Driver3wire, Dig_pin_a, Dig_pin_b, Pwm_pin, (Low/High)) 103 | // Gmotor Motor (Relay2wire, Dig_pin_a, Dig_pin_b, (Low/High)) 104 | 105 | // speed installation -255..255 (8 bits) and -1023..1023 (10 bits) 106 | VOID SetSpeed (Int16_T Duty); 107 | 108 | // Change the mode of operation of the motor: 109 | // Forward - forward 110 | // backward - back 111 | // Stop - Stop 112 | // Brake - active brake 113 | // auto - subordinates setspeed (-255 .. 255) 114 | VOID setmode (gm_workmode mode); 115 | 116 | // Direction of rotation 117 | // norm - ordinary 118 | // Reverse - reverse 119 | VOID Setdirection (Bool Direction); 120 | 121 | // Install minimal well (at which the motor begins to spin) 122 | VOID setminduty (intlety); 123 | 124 | // Set the PWM resolution in bits 125 | VOID Setresolution (Byte Bit); 126 | 127 | // Install Deadtime (in microseconds).By the silence 0 128 | VOID Setdeadtime (Uint16_t Deadtime); 129 | 130 | // set the driver's level (by the silence high) 131 | VOID Setlevel (Int8_T LEVEL); 132 | 133 | // smooth change to the indicated speed (to the value of the PWM) 134 | VOID smoothtick (int16_t duty); 135 | 136 | // speed change speed 137 | VOID setsmoothSpeed (Uint8_t Speed); 138 | 139 | // Returns -1 during rotation of Backward, 1 at Forward and 0 when stopping and braking 140 | int Getstate (); 141 | 142 | // internal variable well for debugging 143 | int16_t _duty = 0; 144 | 145 | // Curvature with old versions 146 | // Install an output of 8 bits 147 | VOID Set8BITMODE (); 148 | 149 | // Set a 10 bite output 150 | VOID set10BITMODE (); 151 | `` ` 152 | 153 | ### Logic of Work 154 | In Setminduty () you can set the minimum speed (0..255), in which the motor begins rotation. 155 | Further speed settings will be automatically scaled, taking into account the minimum. 156 | Setdirection () sets the global direction of the motor, which automatically affects all speed functions. 157 | 158 | ### Original mode 159 | Setmode (Forward) for moving forward, setmode (backward) is launched. 160 | The speed is set in SetSpeed () or Run (Forward/Backward, speed).You can stop setmode (Stop). 161 | 162 | #### Auto mode 163 | Setmode (auto) is launched, the speed is set in SetSpeed (), negative values for rotation are maintained in the other direction. 164 | You can stop setmode (Stop). 165 | 166 | #### Smooth mode 167 | For starting, you need to install setmode (Auto).In smooth mode, you need to call Smoothtick more often with the target speed.With a value of 0, the motor itself will stop smoothly. 168 | For a sharp stop, you can use setmode (Stop). 169 | 170 |
171 | 172 |
173 | gyvermotor2 174 | 175 | `` `CPP 176 | VOID setminduty (uint16_t mduty);// Install the minimum PWM (silence 0) 177 | VOID setmindutyperc (Uint16_T MDUTY);// Install the minimum PWM in % (silence 0) 178 | VOID Setdeadtime (Uint16_T US);// Install Deadtime in microseconds (silence 0) 179 | VOID Reverse (Bool R);// Reverses of the direction (silence. FALSE) 180 | 181 | VOID Stop ();// Stop.If a smooth mode is turned on, then smooth 182 | VOID Brake ();// Active brake 183 | VOID SetSpeed (Int16_T S);// set speed (-max ..Max) 184 | VOID SetSpeDPERC (Int16_T S);// set the speed in percent (-100 .. 100%) 185 | 186 | int8_t gettate ();// Get status: the motor is spinning (1 and -1), the motor is stopped (0) 187 | Int16_T GetSpeed ();// get the current motor speed 188 | 189 | VOID SMOOTHMODE (Bool Mode);// Set a smooth speed change regime (silence. FALSE) 190 | VOID Tick ();// smooth change to the specified speed, call in the cycle 191 | VOID setsmoothSpeed (uint8_t s);// set the speed of speed change (silence 20) 192 | VOID setsmoothSpeedPERC (UINT8_T S);// set the speed of speed change as a percentage 193 | `` ` 194 | 195 | ### Disgusting Shim 196 | The default Avr Arduino uses 8 bit shim (0 .. 255).The ESP8266 uses 10-bit (0 .. 1023). 197 | When initializing the library, you can configure the desired bit, it can be any. 198 | 199 | ### Speed 200 | The speed is set in `setspeded (-max shim .. max shim)` in the size of the PWM signal, or in `setSpeedPERC (-100 .. 100)` as a percentage.The speed can be negative 201 | Then the motor will spin in the opposite direction.With a value of 0, the motor will stop and the driver will be disconnected. 202 | 203 | ### operating modes 204 | Calling `Stop ()` equivalent `setspeed (0)`.With direct control, the motor will be immediately stopped, with smooth - it will stop smoothly.The driver will turn off, the motor shaft will be released. 205 | The call `Brake ()` will stop the motor and switch the driver to the active braking mode (the motor will be closed through itself).The shaft of the motor will resist rotation. 206 | Call `Reverse (True)` inverts the direction of rotation of the motor for all functions. 207 | 208 | ## Minimum shim 209 | In `setminduty (-max shim .. max shim)` you can set the minimum speed at which the motor starts rotation, this is convenient in most applications. 210 | The speed installed in `setSpeed ()` speed will be automatically scale taking into account the minimum. 211 | You can also set the minimum percentage `setmindutyperc (-100 .. 100)`. 212 | 213 | ### smooth mode 214 | In smooth mode, the speed set in `setSpeed ()` The speed is not used immediately, but smoothly over time.For inclusion 215 | The smooth mode must be called `smoothmode (True)` and place in the main cycle of the program, the function-tick `tick ()`. 216 | Inside this function, the skill will smoothly change along the built -in timer (period - 50ms). 217 | You can configure the speed of speed change - `setsmoothSpeed ()` in the values of Shim and `setsmoothspeedperc ()` percent. 218 |
219 | 220 | 221 | ## Example 222 | The rest of the examples look at ** Examples **! 223 | `` `CPP 224 | #include 225 | Gmotor2 Motor (5, 6); 226 | // gmotor2 motor (5, 6); 227 | // gmotor2 motor (5, 6); 228 | // Gmotor2 Motor (5, 6, 11); 229 | // Gmotor2 Motor (5, 6); 230 | 231 | VOID setup () { 232 | Motor.Setminduty (70);// min.Shim 233 | //motor.reverse(1);// reverse 234 | //motor.Setdeadtime(5);// Deadtime 235 | } 236 | 237 | VOID loop () { 238 | Motor.SetSpeed (10); 239 | DELAY (1000); 240 | Motor.SetSpeed (-100); 241 | DELAY (1000); 242 | Motor.SetSpeed (50); 243 | DELAY (1000); 244 | Motor.SetSpeed (255); 245 | DELAY (1000); 246 | Motor.brake (); 247 | Delay (3000); 248 | } 249 | `` ` 250 | 251 | 252 | ## versions 253 | - V1.1 - Defaine removed 254 | - v1.2 - Defaines returned 255 | - V2.0: 256 | - software Deadtime 257 | - negative speeds 258 | - Support for two types of drivers and relay 259 | - smooth start and speed change 260 | - v2.1: small fixes and adds 261 | - V2.2: Optimization 262 | - V2.3: Added ESP support (errors corrected) 263 | - V2.4: Compatibility with other biblors 264 | - V2.5: Added type Driver2Wire_NO_invert 265 | - v3.0: Minduty logic is converted, a mode for PWM of any bitterness has been added 266 | - V3.1: Small corrections 267 | - V3.2: Improved smooth stability 268 | - v3.2.1: Returned Run () to Public 269 | - V4.0: Fixed a bug in Gyvermotor.Added gyvermotor2 270 | 271 | 272 | ## bugs and feedback 273 | Create ** Issue ** when you find the bugs, and better immediately write to the mail [alex@alexgyver.ru] (mailto: alex@alexgyver.ru) 274 | The library is open for refinement and your ** pull Request ** 'ow! 275 | 276 | 277 | When reporting bugs or incorrectoh work of the library must be indicated: 278 | - The version of the library 279 | - What is MK used 280 | - SDK version (for ESP) 281 | - version of Arduino ide 282 | - whether the built -in examples work correctly, in which the functions and designs are used, leading to a bug in your code 283 | - what code has been loaded, what work was expected from it and how it works in reality 284 | - Ideally, attach the minimum code in which the bug is observed.Not a canvas of a thousand lines, but a minimum code -------------------------------------------------------------------------------- /examples/GyverMotor/motor_control_10bit/motor_control_10bit.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Пример управления мотором при помощи драйвера полного моста и потенциометра 3 | на ШИМ 10 бит 4 | */ 5 | 6 | #include "GyverMotor.h" 7 | GMotor motor(DRIVER2WIRE, 2, 9, HIGH); 8 | 9 | // варианты инициализации в зависимости от типа драйвера: 10 | // GMotor motor(DRIVER2WIRE, dig_pin, PWM_pin, (LOW / HIGH) ) 11 | // GMotor motor(DRIVER3WIRE, dig_pin_A, dig_pin_B, PWM_pin, (LOW/HIGH) ) 12 | // GMotor motor(RELAY2WIRE, dig_pin_A, dig_pin_B, (LOW/HIGH) ) 13 | /* 14 | DRIVER2WIRE - двухпроводной драйвер (направление + ШИМ) 15 | DRIVER3WIRE - трёхпроводной драйвер (два пина направления + ШИМ) 16 | RELAY2WIRE - реле в качестве драйвера (два пина направления) 17 | 18 | dig_pin, dig_pin_A, dig_pin_B - любой цифровой пин МК 19 | PWM_pin - любой ШИМ пин МК 20 | LOW / HIGH - уровень драйвера. Если при увеличении скорости мотор наоборот тормозит - смени уровень 21 | */ 22 | 23 | void setup() { 24 | // разгоняем ШИМ на пинах 9 и 10 (atmega328) до 16 кГц 10 бит 25 | // читай тут: https://alexgyver.ru/lessons/pwm-overclock/ 26 | TCCR1A = 0b00000011; // 10bit 27 | TCCR1B = 0b00001001; // x1 fast pwm 28 | 29 | // активируем 10-битный режим библиотеки 30 | motor.setResolution(10); 31 | 32 | // ключ на старт! 33 | motor.setMode(FORWARD); 34 | } 35 | 36 | void loop() { 37 | // потенциометр на А0 38 | // преобразуем значение в -1023.. 1023 39 | int val = 1023 - analogRead(0) * 2; 40 | 41 | motor.setSpeed(val); 42 | // в данном случае мотор будет остановлен в среднем положении рукоятки 43 | // и разгоняться в противоположные скорости в крайних её положениях 44 | 45 | delay(10); // задержка просто для "стабильности" 46 | } 47 | -------------------------------------------------------------------------------- /examples/GyverMotor/motor_control_31kHz/motor_control_31kHz.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Пример управления мотором при помощи драйвера полного моста и потенциометра 3 | на разогнанном ШИМе 4 | */ 5 | 6 | #include "GyverMotor.h" 7 | GMotor motor(DRIVER2WIRE, 2, 3, HIGH); 8 | 9 | // варианты инициализации в зависимости от типа драйвера: 10 | // GMotor motor(DRIVER2WIRE, dig_pin, PWM_pin, (LOW / HIGH) ) 11 | // GMotor motor(DRIVER3WIRE, dig_pin_A, dig_pin_B, PWM_pin, (LOW/HIGH) ) 12 | // GMotor motor(RELAY2WIRE, dig_pin_A, dig_pin_B, (LOW/HIGH) ) 13 | /* 14 | DRIVER2WIRE - двухпроводной драйвер (направление + ШИМ) 15 | DRIVER3WIRE - трёхпроводной драйвер (два пина направления + ШИМ) 16 | RELAY2WIRE - реле в качестве драйвера (два пина направления) 17 | 18 | dig_pin, dig_pin_A, dig_pin_B - любой цифровой пин МК 19 | PWM_pin - любой ШИМ пин МК 20 | LOW / HIGH - уровень драйвера. Если при увеличении скорости мотор наоборот тормозит - смени уровень 21 | */ 22 | 23 | void setup() { 24 | // разгоняем ШИМ на пинах 3 и 11 (atmega328) до 31 кГц 25 | // читай тут: https://alexgyver.ru/lessons/pwm-overclock/ 26 | TCCR2B = 0b00000001; // x1 27 | TCCR2A = 0b00000001; // phase correct 28 | 29 | // ключ на старт! 30 | motor.setMode(FORWARD); 31 | } 32 | 33 | void loop() { 34 | // потенциометр на А0 35 | // преобразуем значение в -255.. 255 36 | int val = 255 - analogRead(0) / 2; 37 | 38 | motor.setSpeed(val); 39 | // в данном случае мотор будет остановлен в среднем положении рукоятки 40 | // и разгоняться в противоположные скорости в крайних её положениях 41 | 42 | delay(10); // задержка просто для "стабильности" 43 | } 44 | -------------------------------------------------------------------------------- /examples/GyverMotor/motor_demo/motor_demo.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Пример управления мотором при помощи драйвера полного моста и потенциометра 3 | */ 4 | #include "GyverMotor.h" 5 | GMotor motor(DRIVER2WIRE, 2, 3, HIGH); 6 | 7 | // варианты инициализации в зависимости от типа драйвера: 8 | // GMotor motor(DRIVER2WIRE, dig_pin, PWM_pin, (LOW / HIGH) ) 9 | // GMotor motor(DRIVER2WIRE_NO_INVERT, dig_pin, PWM_pin, (LOW / HIGH) ) 10 | // GMotor motor(DRIVER3WIRE, dig_pin_A, dig_pin_B, PWM_pin, (LOW/HIGH) ) 11 | // GMotor motor(RELAY2WIRE, dig_pin_A, dig_pin_B, (LOW/HIGH) ) 12 | /* 13 | DRIVER2WIRE - двухпроводной драйвер (направление + ШИМ) 14 | DRIVER2WIRE_NO_INVERT - двухпроводной драйвер, в котором при смене направления не нужна инверсия ШИМ 15 | DRIVER3WIRE - трёхпроводной драйвер (два пина направления + ШИМ) 16 | RELAY2WIRE - реле в качестве драйвера (два пина направления) 17 | 18 | dig_pin, dig_pin_A, dig_pin_B - любой цифровой пин МК 19 | PWM_pin - любой ШИМ пин МК 20 | LOW / HIGH - уровень драйвера. Если при увеличении скорости мотор наоборот тормозит - смени уровень 21 | */ 22 | 23 | void setup() { 24 | // установка программного deadtime на переключение направления, микросекунды 25 | // по умолчанию стоит 0: deadtime отключен 26 | // motor.setDeadtime(200); 27 | 28 | // ГЛОБАЛЬНАЯ смена направления вращения мотора 29 | // например чтобы FORWARD совпадал с направлением движения "вперёд" у машинки 30 | motor.setDirection(REVERSE); 31 | motor.setDirection(NORMAL); // умолч. 32 | 33 | // смена режима работы мотора 34 | motor.setMode(FORWARD); // вперёд 35 | motor.setMode(BACKWARD); // назад 36 | motor.setMode(BRAKE); // активный тормоз 37 | motor.setMode(STOP); // стоп, холостой (мотор отключен) 38 | 39 | // смена уровня драйвера (аналогично при инициализации) 40 | // Если при увеличении скорости мотор наоборот тормозит - смени уровень 41 | motor.setLevel(LOW); 42 | motor.setLevel(HIGH); // по умолч. 43 | 44 | 45 | // для работы в 10 бит необходимо также настроить ШИМ на 10 бит!!! 46 | // читай тут https://alexgyver.ru/lessons/pwm-overclock/ 47 | // motor.setResolution(10); 48 | 49 | // минимальный сигнал (по модулю), который будет подан на мотор 50 | // Избавляет от ситуаций, когда мотор покоится и "пищит" 51 | motor.setMinDuty(150); 52 | 53 | // ключ на старт! 54 | motor.setMode(FORWARD); 55 | } 56 | 57 | void loop() { 58 | // потенциометр на А0 59 | // преобразуем значение в -255.. 255 60 | int val = 255 - analogRead(0) / 2; 61 | 62 | // установка скорости: 63 | // * (0..255) при ручном выборе направления (setMode: FORWARD/BACKWARD) 64 | // * (-255..255) при автоматическом (поставить setMode(FORWARD)) 65 | // * (0..1023) в режиме 10 бит при ручном выборе направления (setMode: FORWARD/BACKWARD) 66 | // * (-1023..1023) в режиме 10 бит при автоматическом (поставить setMode(FORWARD)) 67 | 68 | motor.setSpeed(val); 69 | // в данном случае мотор будет остановлен в среднем положении рукоятки 70 | // и разгоняться в противоположные скорости в крайних её положениях 71 | 72 | delay(10); // задержка просто для "стабильности" 73 | } 74 | -------------------------------------------------------------------------------- /examples/GyverMotor/multi_motor/multi_motor.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Пример управления двумя моторами 3 | */ 4 | #include "GyverMotor.h" 5 | GMotor motor1(DRIVER2WIRE, 2, 3, HIGH); 6 | GMotor motor2(DRIVER2WIRE, 4, 11, HIGH); 7 | // используем оба ШИМа таймера 2 (пины 3 и 11) 8 | 9 | // варианты инициализации в зависимости от типа драйвера: 10 | // GMotor motor(DRIVER2WIRE, dig_pin, PWM_pin, (LOW / HIGH) ) 11 | // GMotor motor(DRIVER3WIRE, dig_pin_A, dig_pin_B, PWM_pin, (LOW/HIGH) ) 12 | // GMotor motor(RELAY2WIRE, dig_pin_A, dig_pin_B, (LOW/HIGH) ) 13 | /* 14 | DRIVER2WIRE - двухпроводной драйвер (направление + ШИМ) 15 | DRIVER3WIRE - трёхпроводной драйвер (два пина направления + ШИМ) 16 | RELAY2WIRE - реле в качестве драйвера (два пина направления) 17 | 18 | dig_pin, dig_pin_A, dig_pin_B - любой цифровой пин МК 19 | PWM_pin - любой ШИМ пин МК 20 | LOW / HIGH - уровень драйвера. Если при увеличении скорости мотор наоборот тормозит - смени уровень 21 | */ 22 | 23 | void setup() { 24 | // ключ на старт! 25 | motor1.setMode(FORWARD); 26 | motor2.setMode(FORWARD); 27 | } 28 | 29 | void loop() { 30 | // потенциометр на А0 31 | // преобразуем значение в -255.. 255 32 | int val_1 = 255 - analogRead(0) / 2; 33 | 34 | // потенциометр на А1 35 | // преобразуем значение в -255.. 255 36 | int val_2 = 255 - analogRead(1) / 2; 37 | 38 | motor1.setSpeed(val_1); 39 | motor2.setSpeed(val_2); 40 | // в данном случае мотор будет остановлен в среднем положении рукоятки 41 | // и разгоняться в противоположные скорости в крайних её положениях 42 | 43 | delay(10); // задержка просто для "стабильности" 44 | } 45 | -------------------------------------------------------------------------------- /examples/GyverMotor/multi_motor_tank/multi_motor_tank.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Пример управления двумя моторами при помощи одного джойстика по танковой схеме 3 | */ 4 | #include "GyverMotor.h" 5 | GMotor motorR(DRIVER2WIRE, 2, 3, HIGH); 6 | GMotor motorL(DRIVER2WIRE, 4, 11, HIGH); 7 | // используем оба ШИМа таймера 2 (пины 3 и 11) 8 | 9 | // варианты инициализации в зависимости от типа драйвера: 10 | // GMotor motor(DRIVER2WIRE, dig_pin, PWM_pin, (LOW / HIGH) ) 11 | // GMotor motor(DRIVER3WIRE, dig_pin_A, dig_pin_B, PWM_pin, (LOW/HIGH) ) 12 | // GMotor motor(RELAY2WIRE, dig_pin_A, dig_pin_B, (LOW/HIGH) ) 13 | /* 14 | DRIVER2WIRE - двухпроводной драйвер (направление + ШИМ) 15 | DRIVER3WIRE - трёхпроводной драйвер (два пина направления + ШИМ) 16 | RELAY2WIRE - реле в качестве драйвера (два пина направления) 17 | 18 | dig_pin, dig_pin_A, dig_pin_B - любой цифровой пин МК 19 | PWM_pin - любой ШИМ пин МК 20 | LOW / HIGH - уровень драйвера. Если при увеличении скорости мотор наоборот тормозит - смени уровень 21 | */ 22 | 23 | void setup() { 24 | // ключ на старт! 25 | motorR.setMode(FORWARD); 26 | motorL.setMode(FORWARD); 27 | } 28 | 29 | void loop() { 30 | // джойстик на А0 и А1 31 | int signalX = 255 - analogRead(0) / 2; 32 | int signalY = 255 - analogRead(1) / 2; 33 | 34 | // преобразуем по танковой схеме 35 | int dutyR = signalY + signalX; 36 | int dutyL = signalY - signalX; 37 | 38 | motorR.setSpeed(dutyR); 39 | motorL.setSpeed(dutyL); 40 | 41 | delay(10); // задержка просто для "стабильности" 42 | } 43 | -------------------------------------------------------------------------------- /examples/GyverMotor/smooth_control/smooth_control.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Пример плавного управления мотором при помощи драйвера полного моста и потенциометра 3 | */ 4 | #include "GyverMotor.h" 5 | GMotor motor(DRIVER2WIRE, 2, 3, HIGH); 6 | 7 | // варианты инициализации в зависимости от типа драйвера: 8 | // GMotor motor(DRIVER2WIRE, dig_pin, PWM_pin, (LOW / HIGH) ) 9 | // GMotor motor(DRIVER3WIRE, dig_pin_A, dig_pin_B, PWM_pin, (LOW/HIGH) ) 10 | // GMotor motor(RELAY2WIRE, dig_pin_A, dig_pin_B, (LOW/HIGH) ) 11 | /* 12 | DRIVER2WIRE - двухпроводной драйвер (направление + ШИМ) 13 | DRIVER3WIRE - трёхпроводной драйвер (два пина направления + ШИМ) 14 | RELAY2WIRE - реле в качестве драйвера (два пина направления) 15 | 16 | dig_pin, dig_pin_A, dig_pin_B - любой цифровой пин МК 17 | PWM_pin - любой ШИМ пин МК 18 | LOW / HIGH - уровень драйвера. Если при увеличении скорости мотор наоборот тормозит - смени уровень 19 | */ 20 | 21 | void setup() { 22 | Serial.begin(9600); 23 | 24 | // установка скорости изменения скорости (ускорения) мотора 25 | motor.setSmoothSpeed(20); 26 | 27 | // ключ на старт! 28 | motor.setMode(FORWARD); 29 | } 30 | 31 | void loop() { 32 | // потенциометр на А0 33 | // преобразуем значение в -255.. 255 34 | int val = 255 - analogRead(0) / 2; 35 | 36 | // данную функцию рекомендуется вызывать чаще чем каждые 50 мс 37 | // (работает по встроенному таймеру) 38 | // она будет плавно менять скорость мотора к заданной 39 | motor.smoothTick(val); 40 | 41 | // отладка. Откройте Инструменты/Плоттер по последовательному порту 42 | Serial.print(val); // первый график - установленная скорость 43 | Serial.print(','); 44 | Serial.println(motor._duty); // второй график - реальный сигнал на мотор 45 | 46 | delay(10); // задержка просто для "стабильности" 47 | } 48 | -------------------------------------------------------------------------------- /examples/GyverMotor2/demo/demo.ino: -------------------------------------------------------------------------------- 1 | #include 2 | GMotor2 motor(5, 6); 3 | //GMotor2 motor(5, 6); 4 | //GMotor2 motor(5, 6); 5 | //GMotor2 motor(5, 6, 11); 6 | //GMotor2 motor(5, 6); 7 | 8 | void setup() { 9 | motor.setMinDuty(70); // мин. ШИМ 10 | //motor.reverse(1); // реверс 11 | //motor.setDeadtime(5); // deadtime 12 | } 13 | 14 | void loop() { 15 | motor.setSpeed(10); 16 | delay(1000); 17 | motor.setSpeed(-100); 18 | delay(1000); 19 | motor.setSpeed(50); 20 | delay(1000); 21 | motor.setSpeed(255); 22 | delay(1000); 23 | motor.brake(); 24 | delay(3000); 25 | } 26 | -------------------------------------------------------------------------------- /examples/GyverMotor2/potControl/potControl.ino: -------------------------------------------------------------------------------- 1 | // потенциометр на A0 2 | 3 | #include 4 | GMotor2 motor(5, 6); 5 | 6 | void setup() { 7 | motor.setMinDuty(70); // мин. ШИМ 8 | //motor.reverse(1); // реверс 9 | //motor.setDeadtime(5); // deadtime 10 | } 11 | 12 | void loop() { 13 | // переводим в диапазон -255.. 255 14 | int val = analogRead(0) / 2 - 512; 15 | motor.setSpeed(val); 16 | delay(100); 17 | } 18 | -------------------------------------------------------------------------------- /examples/GyverMotor2/serialControl/serialControl.ino: -------------------------------------------------------------------------------- 1 | // открой плоттер на скорости 9600. Команды: 2 | // q<скорость> - скорость в процентах (пример: q0, q50, q90) 3 | // w - stop() 4 | // e - brake() 5 | 6 | #include 7 | GMotor2 motor(5, 6); 8 | 9 | void setup() { 10 | Serial.begin(9600); 11 | Serial.setTimeout(40); 12 | motor.setMinDuty(70); // мин. ШИМ 13 | //motor.reverse(1); // реверс 14 | //motor.setDeadtime(5); // deadtime 15 | motor.smoothMode(1); // плавный режим 16 | } 17 | 18 | void loop() { 19 | motor.tick(); 20 | 21 | // вывод графика 22 | static uint32_t tmr; 23 | if (millis() - tmr > 50) { 24 | tmr = millis(); 25 | Serial.println(motor.getSpeed()); 26 | } 27 | 28 | if (Serial.available() > 0) { 29 | char key = Serial.read(); 30 | int val = Serial.parseInt(); 31 | switch (key) { 32 | case 'q': motor.setSpeedPerc(val); break; 33 | case 'w': motor.stop(); break; 34 | case 'e': motor.brake(); break; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For GyverMotor 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | GMotor KEYWORD1 9 | GyverMotor KEYWORD1 10 | GMotor2 KEYWORD1 11 | GyverMotor2 KEYWORD1 12 | 13 | ####################################### 14 | # Methods and Functions (KEYWORD2) 15 | ####################################### 16 | setSpeed KEYWORD2 17 | setMode KEYWORD2 18 | setDirection KEYWORD2 19 | setResolution KEYWORD2 20 | setDeadtime KEYWORD2 21 | setLevel KEYWORD2 22 | setMinDuty KEYWORD2 23 | getState KEYWORD2 24 | run KEYWORD2 25 | 26 | smoothTick KEYWORD2 27 | setSmoothSpeed KEYWORD2 28 | 29 | set8bitMode KEYWORD2 30 | set10bitMode KEYWORD2 31 | 32 | reverse KEYWORD2 33 | stop KEYWORD2 34 | brake KEYWORD2 35 | tick KEYWORD2 36 | smoothMode KEYWORD2 37 | getSpeed KEYWORD2 38 | setSpeedPerc KEYWORD2 39 | setMinDutyPerc KEYWORD2 40 | setSmoothSpeedPerc KEYWORD2 41 | 42 | ####################################### 43 | # Constants (LITERAL1) 44 | ####################################### 45 | DRIVER2WIRE_NO_INVERT LITERAL1 46 | DRIVER2WIRE_PWM LITERAL1 47 | DRIVER2WIRE LITERAL1 48 | DRIVER3WIRE LITERAL1 49 | RELAY2WIRE LITERAL1 50 | 51 | NORMAL LITERAL1 52 | REVERSE LITERAL1 53 | 54 | FORWARD LITERAL1 55 | BACKWARD LITERAL1 56 | STOP LITERAL1 57 | BRAKE LITERAL1 58 | AUTO LITERAL1 -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=GyverMotor 2 | version=4.1.3 3 | author=AlexGyver 4 | maintainer=AlexGyver 5 | sentence=Library for motor driver control 6 | paragraph=Library for motor driver control 7 | category=Device Control 8 | url=https://github.com/GyverLibs/GyverMotor 9 | architectures=* 10 | -------------------------------------------------------------------------------- /src/GyverMotor.cpp: -------------------------------------------------------------------------------- 1 | #include "GyverMotor.h" 2 | 3 | GMotor::GMotor(GM_driverType type, int8_t param1, int8_t param2, int8_t param3, int8_t param4) { 4 | _type = type; 5 | switch (_type) { 6 | case DRIVER2WIRE_NO_INVERT: 7 | case DRIVER2WIRE: 8 | _digA = param1; 9 | _pwmC = param2; 10 | if (param3 != _GM_NC) _level = !param3; 11 | break; 12 | case DRIVER3WIRE: 13 | _digA = param1; 14 | _digB = param2; 15 | _pwmC = param3; 16 | if (param4 != _GM_NC) _level = !param4; 17 | break; 18 | case RELAY2WIRE: 19 | _digA = param1; 20 | _digB = param2; 21 | if (param3 != _GM_NC) _level = !param3; 22 | break; 23 | } 24 | 25 | if (_digA != _GM_NC) pinMode(_digA, OUTPUT); 26 | if (_digB != _GM_NC) pinMode(_digB, OUTPUT); 27 | if (_pwmC != _GM_NC) pinMode(_pwmC, OUTPUT); 28 | 29 | setMode(STOP); 30 | } 31 | 32 | void GMotor::setSpeed(int16_t duty) { 33 | if (_mode < 2) { // FORWARD/BACKWARD/AUTO 34 | _duty = constrain(duty, -_maxDuty, _maxDuty); 35 | 36 | // фикс стандартного analogWrite(пин, 255) для >8 бит 37 | if (_maxDuty > 255 && abs(_duty) == 255) _duty++; 38 | 39 | if (duty == 0) run(STOP, 0); 40 | else { 41 | if (duty > 0) { 42 | if (_minDuty != 0) _duty = _duty * _k + _minDuty; // сжимаем диапазон 43 | run(_mode, _duty); 44 | } else { 45 | if (_minDuty != 0) _duty = _duty * _k - _minDuty; // сжимаем диапазон 46 | run(BACKWARD, -_duty); 47 | } 48 | } 49 | } 50 | } 51 | 52 | void GMotor::run(GM_workMode mode, int16_t duty) { 53 | // дедтайм 54 | if (_deadtime > 0 && _lastMode != mode) { 55 | _lastMode = mode; 56 | setPins(_level, _level, 0); // выключить всё 57 | delayMicroseconds(_deadtime); 58 | } 59 | 60 | // инверт 61 | if (_direction) { 62 | if (mode == FORWARD) mode = BACKWARD; 63 | else if (mode == BACKWARD) mode = FORWARD; 64 | } 65 | 66 | switch (mode) { 67 | case FORWARD: 68 | setPins(_level, !_level, duty); 69 | _state = 1; 70 | break; 71 | case BACKWARD: 72 | setPins(!_level, _level, (_type == DRIVER2WIRE) ? (_maxDuty - duty) : (duty)); 73 | _state = -1; 74 | break; 75 | case BRAKE: 76 | setPins(!_level, !_level, !_level * 255); 77 | _state = 0; 78 | break; // при 0/255 analogWrite сделает 0/1 79 | case STOP: 80 | setPins(_level, _level, _level * 255); 81 | _duty = _dutyS = 0; 82 | _state = 0; 83 | break; 84 | } 85 | } 86 | 87 | void GMotor::setPins(bool a, bool b, int c) { 88 | if (_digA != _GM_NC) digitalWrite(_digA, a); 89 | if (_digB != _GM_NC) digitalWrite(_digB, b); 90 | if (_pwmC != _GM_NC) analogWrite(_pwmC, c); 91 | } 92 | 93 | void GMotor::smoothTick(int16_t duty) { 94 | if (millis() - _tmr >= _SMOOTH_PRD) { 95 | _tmr = millis(); 96 | if (abs(_dutyS - duty) > _speed) _dutyS += (_dutyS < duty) ? _speed : -_speed; 97 | else _dutyS = duty; 98 | setSpeed(_dutyS); 99 | } 100 | } 101 | 102 | int GMotor::getState() { 103 | return _state; 104 | } 105 | 106 | void GMotor::setResolution(byte bit) { 107 | _maxDuty = (1 << bit) - 1; // -1 для смещения 108 | setMinDuty(_minDuty); // пересчитаем k 109 | } 110 | 111 | void GMotor::setMinDuty(int duty) { 112 | _minDuty = duty; 113 | _k = 1.0 - (float)_minDuty / _maxDuty; 114 | } 115 | 116 | void GMotor::setMode(GM_workMode mode) { 117 | if (_mode == mode) return; 118 | _mode = mode; 119 | run(mode, _duty); 120 | } 121 | 122 | void GMotor::setSmoothSpeed(uint8_t speed) { 123 | _speed = speed; 124 | } 125 | 126 | void GMotor::setDirection(bool direction) { 127 | _direction = direction; 128 | } 129 | 130 | void GMotor::setDeadtime(uint16_t deadtime) { 131 | _deadtime = deadtime; 132 | } 133 | 134 | void GMotor::setLevel(int8_t level) { 135 | _level = !level; 136 | } 137 | 138 | // совместимость 139 | void GMotor::set8bitMode() { 140 | setResolution(8); 141 | } 142 | 143 | void GMotor::set10bitMode() { 144 | setResolution(10); 145 | } -------------------------------------------------------------------------------- /src/GyverMotor.h: -------------------------------------------------------------------------------- 1 | /* 2 | Библиотека для удобного управления коллекторными моторами через драйвер 3 | Документация: https://alexgyver.ru/gyvermotor/ 4 | GitHub: https://github.com/GyverLibs/GyverMotor 5 | Возможности: 6 | - Контроль скорости и направления вращения 7 | - Работа с ШИМ любого разрешения 8 | - Плавный пуск и изменение скорости 9 | - Активный тормоз 10 | - Порог минимального ШИМ 11 | - Deadtime 12 | - Поддержка 5 типов драйверов 13 | 14 | AlexGyver, alex@alexgyver.ru 15 | https://alexgyver.ru/ 16 | MIT License 17 | 18 | Версии: 19 | v1.1 - убраны дефайны 20 | v1.2 - возвращены дефайны 21 | v2.0: 22 | - Программный deadtime 23 | - Отрицательные скорости 24 | - Поддержка двух типов драйверов и реле 25 | - Плавный пуск и изменение скорости 26 | v2.1: небольшие фиксы и добавления 27 | v2.2: оптимизация 28 | v2.3: добавлена поддержка esp (исправлены ошибки) 29 | v2.4: совместимость с другими библами 30 | v2.5: добавлен тип DRIVER2WIRE_NO_INVERT 31 | v3.0: переделана логика minDuty, добавлен режим для ШИМ любой битности 32 | v3.1: мелкие исправления 33 | v3.2: улучшена стабильность плавного режима 34 | v3.2.1: вернул run() в public 35 | v4.0: исправлен баг в GyverMotor. Добавлен GyverMotor2 36 | */ 37 | 38 | #ifndef _GyverMotor_h 39 | #define _GyverMotor_h 40 | #include 41 | #define _SMOOTH_PRD 50 // таймер smoothTick, мс 42 | 43 | enum GM_driverType { 44 | DRIVER2WIRE_NO_INVERT, // двухпроводной драйвер, в котором при смене направления не нужна инверсия ШИМ 45 | DRIVER2WIRE, // двухпроводной драйвер (направление + ШИМ) 46 | DRIVER3WIRE, // трёхпроводной драйвер (два пина направления + ШИМ) 47 | RELAY2WIRE, // реле в качестве драйвера (два пина направления) 48 | }; 49 | 50 | #define NORMAL 0 51 | #define REVERSE 1 52 | 53 | enum GM_workMode { 54 | FORWARD, 55 | BACKWARD, 56 | STOP, 57 | BRAKE, 58 | AUTO = 0, 59 | }; 60 | 61 | static const int8_t _GM_NC = -1; // not connected 62 | 63 | class GMotor { 64 | public: 65 | GMotor(GM_driverType type, int8_t param1 = _GM_NC, int8_t param2 = _GM_NC, int8_t param3 = _GM_NC, int8_t param4 = _GM_NC); 66 | // три варианта создания объекта в зависимости от драйвера: 67 | // GMotor motor(DRIVER2WIRE, dig_pin, PWM_pin, (LOW/HIGH) ) 68 | // GMotor motor(DRIVER3WIRE, dig_pin_A, dig_pin_B, PWM_pin, (LOW/HIGH) ) 69 | // GMotor motor(RELAY2WIRE, dig_pin_A, dig_pin_B, (LOW/HIGH) ) 70 | 71 | // установка скорости -255..255 (8 бит) и -1023..1023 (10 бит) 72 | void setSpeed(int16_t duty); 73 | 74 | // сменить режим работы мотора: 75 | // FORWARD - вперёд 76 | // BACKWARD - назад 77 | // STOP - остановить 78 | // BRAKE - активный тормоз 79 | // AUTO - подчиняется setSpeed (-255.. 255) 80 | void setMode(GM_workMode mode); 81 | 82 | // направление вращения 83 | // NORM - обычное 84 | // REVERSE - обратное 85 | void setDirection(bool direction); 86 | 87 | // дать прямую команду мотору (без смены режима) 88 | void run(GM_workMode mode, int16_t duty = 0); 89 | 90 | // установить минимальную скважность (при которой мотор начинает крутиться) 91 | void setMinDuty(int duty); 92 | 93 | // установить разрешение ШИМ в битах 94 | void setResolution(byte bit); 95 | 96 | // установить deadtime (в микросекундах). По умолч 0 97 | void setDeadtime(uint16_t deadtime); 98 | 99 | // установить уровень драйвера (по умолч. HIGH) 100 | void setLevel(int8_t level); 101 | 102 | // плавное изменение к указанной скорости (к значению ШИМ) 103 | void smoothTick(int16_t duty); 104 | 105 | // скорость изменения скорости 106 | void setSmoothSpeed(uint8_t speed); 107 | 108 | // возвращает -1 при вращении BACKWARD, 1 при FORWARD и 0 при остановке и торможении 109 | int getState(); 110 | 111 | // внутренняя переменная скважности для отладки 112 | int16_t _duty = 0; 113 | 114 | // свовместимость со старыми версиями 115 | // установить выход в 8 бит 116 | void set8bitMode(); 117 | 118 | // установить выход в 10 бит 119 | void set10bitMode(); 120 | 121 | protected: 122 | void setPins(bool a, bool b, int c); 123 | int16_t _dutyS = 0; 124 | int _minDuty = 0, _state = 0; 125 | ; 126 | int8_t _digA = _GM_NC, _digB = _GM_NC, _pwmC = _GM_NC; 127 | bool _direction = false; 128 | int8_t _level = LOW; // логика инвертирована! 129 | int _maxDuty = 255; 130 | GM_workMode _mode = FORWARD, _lastMode = FORWARD; 131 | GM_driverType _type; 132 | uint16_t _deadtime = 0; 133 | uint8_t _speed = 20; 134 | uint32_t _tmr = 0; 135 | float _k; 136 | }; 137 | #endif -------------------------------------------------------------------------------- /src/GyverMotor2.h: -------------------------------------------------------------------------------- 1 | #ifndef _GyverMotor2_h 2 | #define _GyverMotor2_h 3 | #include 4 | 5 | enum GM_driver { 6 | DRIVER2WIRE, // двухпроводной драйвер с инверсией шим (dir + PWM) 7 | DRIVER2WIRE_NO_INVERT, // двухпроводной драйвер без инверсии ШИМ (dir + PWM) 8 | DRIVER2WIRE_PWM, // двухпроводной драйвер с двумя ШИМ (PWM + PWM) 9 | DRIVER2WIRE_PWM_INVERT, // двухпроводной драйвер с двумя ШИМ (PWM + PWM) 10 | DRIVER3WIRE, // трёхпроводной драйвер (dir + dir + PWM) 11 | RELAY2WIRE, // реле в качестве драйвера (dir + dir) 12 | }; 13 | 14 | #define _GM_SMOOTH_PRD 50 // период таймера плавной скорости, мс 15 | 16 | template 17 | class GMotor2 { 18 | public: 19 | // инициализация с указанием пинов 20 | GMotor2(uint8_t pa, uint8_t pb, uint8_t pc = 255) : pinA(pa), pinB(pb), pinC(pc) { 21 | pinMode(pinA, OUTPUT); 22 | pinMode(pinB, OUTPUT); 23 | if (pinC != 255) pinMode(pinC, OUTPUT); 24 | setAll(0); 25 | } 26 | 27 | // установить минимальный ШИМ (умолч. 0) 28 | void setMinDuty(uint16_t val) { 29 | mduty = val; 30 | } 31 | 32 | // установить минимальный ШИМ в % (умолч. 0) 33 | void setMinDutyPerc(uint16_t val) { 34 | val = constrain(val, 0, 100); 35 | mduty = (int32_t)getMax() * val / 100; 36 | } 37 | 38 | // реверс направления (умолч. false) 39 | void reverse(bool r) { 40 | rev = r ? -1 : 1; 41 | run(duty); 42 | } 43 | 44 | // остановка. Если включен плавный режим, то плавная 45 | void stop() { 46 | setSpeed(0); 47 | } 48 | 49 | // активный тормоз 50 | void brake() { 51 | setAll(1); 52 | speed = duty = 0; 53 | } 54 | 55 | // установить скорость (-макс.. макс) 56 | void setSpeed(int16_t s) { 57 | speed = s; 58 | if (!smooth) duty = speed; 59 | run(duty); 60 | } 61 | 62 | // установить скорость в процентах (-100.. 100%) 63 | void setSpeedPerc(int16_t s) { 64 | s = constrain(s, -100, 100); 65 | setSpeed((int32_t)getMax() * s / 100); 66 | } 67 | 68 | // установить deadtime в микросекундах (умолч. 0) 69 | void setDeadtime(uint16_t us) { 70 | deadtime = us; 71 | } 72 | 73 | // плавное изменение к указанной скорости, вызывать в цикле 74 | void tick() { 75 | if ((speed || duty) && smooth && ((uint8_t)((uint8_t)millis() - tmr) >= _GM_SMOOTH_PRD)) { 76 | tmr = millis(); 77 | if (abs(duty - speed) > ds) duty += (duty < speed) ? ds : -ds; 78 | else duty = speed; 79 | run(duty); 80 | } 81 | } 82 | 83 | // установить скорость изменения скорости (умолч. 20) 84 | void setSmoothSpeed(uint8_t s) { 85 | ds = s; 86 | } 87 | 88 | // установить скорость изменения скорости в процентах 89 | void setSmoothSpeedPerc(uint8_t s) { 90 | s = constrain(s, 0, 100); 91 | ds = (int32_t)getMax() * s / 100; 92 | } 93 | 94 | // установить режим плавного изменения скорости (умолч. false) 95 | void smoothMode(bool mode) { 96 | smooth = mode; 97 | } 98 | 99 | // получить статус: мотор крутится (1 и -1), мотор остановлен (0) 100 | int8_t getState() { 101 | return dir; 102 | } 103 | 104 | // получить текущую скорость мотора 105 | int16_t getSpeed() { 106 | return duty; 107 | } 108 | 109 | private: 110 | // макс ШИМ при разрешении 111 | inline int16_t getMax() { 112 | return (1 << GM_RES) - 1; 113 | } 114 | 115 | // установка скорости -макс.. макс 116 | void run(int16_t sp) { 117 | if (!sp) return setAll(0); // стоп 118 | 119 | int8_t ndir = (sp > 0) ? rev : -rev; 120 | if (deadtime && ndir != dir) { // направление изменилось 121 | setAll(0); 122 | delayMicroseconds(deadtime); 123 | } 124 | dir = ndir; 125 | int16_t maxD = getMax(); 126 | sp = constrain(sp, -maxD, maxD); 127 | if (mduty) sp = (int32_t)sp * (maxD - mduty) >> GM_RES; 128 | sp = abs(sp) + mduty; 129 | if (GM_RES > 8 && sp == 255) sp++; // защита от 255 при разрешении > 8 бит 130 | 131 | switch (GM_TYPE) { 132 | case DRIVER2WIRE: 133 | digitalWrite(pinA, dir < 0); 134 | analogWrite(pinB, (dir > 0) ? sp : (maxD - sp)); 135 | break; 136 | 137 | case DRIVER2WIRE_NO_INVERT: 138 | digitalWrite(pinA, dir < 0); 139 | analogWrite(pinB, sp); 140 | break; 141 | 142 | case DRIVER2WIRE_PWM: 143 | if (dir > 0) { 144 | digitalWrite(pinA, 0); 145 | analogWrite(pinB, sp); 146 | } else { 147 | analogWrite(pinA, sp); 148 | digitalWrite(pinB, 0); 149 | } 150 | break; 151 | 152 | case DRIVER2WIRE_PWM_INVERT: 153 | if (dir < 0) { 154 | digitalWrite(pinA, 1); 155 | analogWrite(pinB, sp); 156 | } else { 157 | analogWrite(pinA, sp); 158 | digitalWrite(pinB, 1); 159 | } 160 | break; 161 | 162 | case DRIVER3WIRE: 163 | digitalWrite(pinA, dir < 0); 164 | digitalWrite(pinB, dir > 0); 165 | analogWrite(pinC, sp); 166 | break; 167 | 168 | case RELAY2WIRE: 169 | digitalWrite(pinA, dir < 0); 170 | digitalWrite(pinB, dir > 0); 171 | break; 172 | } 173 | } 174 | 175 | // установить все пины 176 | void setAll(bool val) { 177 | if (GM_TYPE == DRIVER2WIRE_PWM) { 178 | analogWrite(pinA, val ? getMax() : 0); 179 | analogWrite(pinB, val ? getMax() : 0); 180 | } else { 181 | digitalWrite(pinA, val); 182 | digitalWrite(pinB, val); 183 | if (pinC != 255) digitalWrite(pinC, val); 184 | } 185 | dir = 0; 186 | } 187 | 188 | const uint8_t pinA, pinB, pinC; 189 | bool smooth = 0; 190 | int8_t dir = 0, rev = 1; 191 | uint8_t deadtime = 0; 192 | int16_t mduty = 0, speed = 0, duty = 0, ds = 20; 193 | uint8_t tmr = 0; 194 | }; 195 | #endif --------------------------------------------------------------------------------