Ви не увійшли.
Може хто зна підкажіть:
Є Arduino Pro 8 МГц 3,3В в системі радіокерування, все вже пращює, АЛЕ з PWM сигналами - як завжди знайшлися ГРАБЛІ...
Городити щось додатково недоцільно, задумка у простоті і можливості міксувати канали керування
Сигнал "брудний" - на екрані осцилографа імпульси керування смикаються у часі, тупі китайскі серви погоджуються і на такий, а от драйвер BLDC двигуна вже посила на три літери...

По центру імпульс нормального сигналу, лівіше хибний імпульс(він по екрану біга). Скетч не додаю, я вже вирізав з основного циклу все - мікроконтролер не робе нічого окрім генерації PWM сигналу, а проблема є!!!
Библіотека Servo8Bit з ATMega32 наче не працюэ і з менеджера бібліотек не встановлюється, є ідеї як змусити Arduino Pro нормально генерувати PWM сигнал?
Неактивний
Є Arduino Pro 8 МГц 3,3В ... Библіотека Servo8Bit з ATMega32 наче не працюэ
Уточніть, Pro / Pro Mini з Atmega328P чи Pro Micro з Atmega32u4?
Скетч не додаю, я вже вирізав з основного циклу все - мікроконтролер не робе нічого окрім генерації PWM сигналу
Так покажіть же. Тим більше, у вас там ще якесь міксування каналів. Ви на увімкненому PWM реконфігуруєте піни, чи що?
є ідеї як змусити Arduino Pro нормально генерувати PWM сигнал?
Найкращий варіант - не використовувати фреймворк ардуіно, а програмувати таймер напряму.
Неактивний
Для серви PWM не обов'язково - насправді їй досить 1 імпульса.
А так фреймворк arduino не забороняє смикати за таймер напряму.
Та і готовий конвертор csrf-pwm не так дорого коштує. Без розуміння умови задачі хз як її правильно розв'язувати.
Для серви PWM не обов'язково - насправді їй досить 1 імпульса.
Повернутись - досить, але утримувати задану позицію не буде. У автора взагалі драйвер BLDC. Навряд чи він запамʼятовує останній імпульс і тримає відповідний PWM на виході при відсутності нових імпульсів.
Без розуміння умови задачі хз як її правильно розв'язувати.
+
Взагалі не дуже зрозуміло, за яким критерієм автор розрізняє нормальний і хибний імпульс на картинці. Осцилограф же за який зачепиться, той і показує посередині. Якщо тривалість тих імпульсів порядка 1-2 мс, то між ними десь і є 20 мс (50 Гц). Але тоді на екрані їх було би більше ніж 2 (хоча тут залежить від алгоритму синхронізації в осцилі).
Чи проблема в тому, що період слідування імпульсів нестабільний?
Неактивний
Осцилограф - ₴#@но
добитися синхронізаціі на ньому складно.
Як відповідати індивідуально не знаю, тому формат відповіді: № повідомлення - відповідь..
№3 - Atmega328P, скетчу фактично нема - у основному циклі лише SerV.attach(6,150,2400); і SerV.write(0); Взяв іншу плату з кварцем на 16 МГц, залив той самий скетч - на осцилографі чіткий сигнал...
№4 - варіант з таймером якраз колупаю, підозрюю що вийде щось типу "лікування зубів через сраку"... Додаткові модулі не варіант, принципово, тоді вже краще стандартну плату квадрика з Али..
№5 - критерій простий, на платі з кварцем 16 МГц усе працює, на платі де кварц 8 МГц, осцилограмма коса, драйвер двигуна калібраватися і переходити у робочій режим не бажа... Напруги сигналу 100% вистача - перевіренно!!!
№6 - "₴#@но sad" чудово синхронізується сигналом Китайского сервотестера і з платою де кварц 16 МГц...
Неактивний
Ну дивіться. В коді що ви показали є коментар
// Неприятный сюрприз - 8 МГц ардуинка 1000 прерываний не тянет :( Ну не дуже годна схема.
Я для 2 серв робив так. Рахував заздалегідь скільки тіків таймера займає кожний високий рівень. Ставив servo 1 high. Програмував таймер на interrupt. по interrupt ставив servo 1 low, servo 2 high. програмував таймер на interrupt. по interrupt ставив servo 2 low, програмував таймер на низький рівень щоб добити до 20 мс. І так по колу. Але це було STC8, там таймер сильно ущербний - рахує виключно в доповненому коді, і тактова частота крива. На atmega повинно бути простіше; як мінімум заздалегідь рахувати нічого.
Походу я винайшов бібліотеку Servo
В неї всередині саме так все влаштовано.
у основному циклі лише SerV.attach(6,150,2400); і SerV.write(0);
Ну не треба так робити. attach виконується 1 раз. його місце в setup(). write(0) немає смислу смикати постійно, вставте якийсь delay() хоча б.
Неактивний
у основному циклі лише SerV.attach(6,150,2400); і SerV.write(0);
Як вже сказали, не треба так. Для початку винесіть SerV.attach() і SerV.write() в setup(), а loop() залиште пустим.
150 мікросекунд - не замало для мінімального імпульса? На 8 мегагерцах це лише 1200 тактів.
Скільки вашому BLDC потрібно для мінімального рівня?
Спробуйте поставити min 1000 і max 2000. А у write передайте 90. Подивіться, чи відповідають тривалості імпульсів очікуваним 1500 мкс.
Взяв іншу плату з кварцем на 16 МГц
На Pro та інших міні-платах зазвичай не кварц, а кераміка. Але у вашому випадку це не має суттєво впливати.
залив той самий скетч - на осцилографі чіткий сигнал...
Так в чому саме полягає "нечіткість" сигналу? По одній розмитій фотці з двома імпульсами не дуже зрозуміло. Період слідування імпульсів плаває? На скільки мілісекунд відхиляється від 20 мс? Чи тривалості не відповідають очікуваним?
Неактивний
№4 - варіант з таймером якраз колупаю, підозрюю що вийде щось типу "лікування зубів через сраку"...
Якщо підходити до задачі серйозно, то для початку потрібно визначитись із граничними параметрами: мінімальна тривалість імпульсів, максимальна тривалість, гранулярність (кількість кроків між мінімумом та максимумом, або ж тривалість одного крока), допустиме відхилення.
А також: чи допустимо генерувати імпульси послідовно, наприклад, при 4 каналах - з інтервалом по 5 мс між каналами, або ж передні фронти на всіх каналах мають бути синхронними. Скільки часу допустимо з точки зору інших компонентів ПЗ проводити в обробнику переривання (у вас же не лише PWM буде, а і якась комунікація з іншою периферією), і т.д.
При не дуже жорстких умовах напрошується очевидне просте рішення: в обробнику періодичного переривання по таймеру виставляти всі канали в одиниці, потім тупо крутити спінлок, скидаючи потрібний канал через заданий проміжок часу.
Неактивний
З bldc взагалі не зрозуміло. Є ще один контроллер з управлінням PWM? Чи хочеться з ардуїни отримати 3фазний сигнал для двигуна?
№9 - бібліотека Servo.h працює по таймеру, тому що там у основному циклі неважливо, просто буде виконуватися повільніше.
BLDC - Китайский драйвер для квадрокоптера 1-2S, але драйвер з продвинутих...
Нечіткість сигналу - той імпульс що по центру генерується стабільно, а от той що зліва "мерегтить" і "плава" ліворучь-праворучь..
№10 - Вже й так спробував, але тупонув - на усіх 4-х каналах сигнал синхронізовано, вийшло накладно по ресурсам, с"огодні буду пробувати переписати для послідовного формування імпульсів.
По ресурсам/комунікації нема нічого "важкого" і критичного по часу виконання..
№11 - контроллер з управлінням PWM, але контролер продвинутий - те що зжирають Китайскі серви його не влаштовує...
Неактивний
№9 - бібліотека Servo.h працює по таймеру, тому що там у основному циклі неважливо, просто буде виконуватися повільніше.
Обробник самої Servo виконується певний час і може блокувати інші переривання, наприклад, від UART, внаслідок чого починаючи з певних бітрейтів губитимуться байти.
Там TCNT1 та OCR1A апдейтяться прямо в обробнику COMPA з поправками на час виконання коду. Такий підхід має певні граничні умови, які, можливо, у вашому випадку не виконуються.
Бібліотека Servo написана дилетантами для дилетантів і не призначена для використання в промислових рішеннях. Втім, як і весь ардуіно фреймворк.
Нечіткість сигналу - той імпульс що по центру генерується стабільно, а от той що зліва "мерегтить" і "плава" ліворучь-праворучь..
Це імпульси при єдиному активному каналі, як розумію? Кажу ж, може осцил чіпляється за останній впійманий, а подальші просто не малює. А насправді плаває інтервал між усіма імпульсами.
Якби ви показали мінімальний відтворюваний приклад, можна було б зібрати його у себе, прошити і подивитись поведінку на осцилографі в реальному часі. Показати код не заради цікавості просять, а щоб відтворити проблему і проаналізувати її.
Необхідну мінімальну триваліть імпульсів так поки не озвучили.
Неактивний
При спробі завантажити код виходить якась ху.....
Код у попередн"ому перегляді відображається нормально, дата остан"ого повідомлення на форумі змінюється, але саме повідомлення не відображається
Неактивний
При спробі завантажити код виходить якась ху.....
Ну завантажте як файл і дайте посилання на нього.
8-МГц плат щось я у себе не знайшов, ось запустив на 8 мегагерцах наступний код на Nano з 16 МГц резонатором:
#include <Arduino.h>
#include <Servo.h>
Servo servo;
void setup()
{
{
uint8_t sreg = SREG;
cli();
CLKPR = _BV(CLKPCE);
CLKPR = 0b0001;
SREG = sreg;
}
pinMode(LED_BUILTIN, OUTPUT);
servo.attach(6, 150, 2400);
servo.write(0);
}
void loop()
{
static bool state = false;
digitalWrite(LED_BUILTIN, (state = !state));
delay(500);
}platformio.ini:
[env:pro8MHzatmega328]
platform = atmelavr
board = pro8MHzatmega328
framework = arduino
lib_deps =
arduino-libraries/Servo@1.3.0Блимання світлодіодом в loop() - це чисто щоб впевнитись, що працює на 8 МГц.
Нічого не смикається, чіткі імпульси кожні 20 мс тривалістю 150 мкс. Тривалість самих імпульсів коливається в межах декількох мікросекунд, що цілком очікувано.
Остання редакція dimich (2026-07-18 17:52:31)
Неактивний
Те що генерує ваша:
Далі відео:
Налаштування осцилографа не змінювалися, заливав прошивку, переставляв щуп.
Синій сигнал - китайский сервотестер
Ваш код
https://www.youtube.com/watch?v=z_B7b96iI2c
Стандартна Servo
https://youtu.be/S91GYQ1sLrc
Моя, сжера 40% ресурсу
https://youtu.be/Sgz3m2NhGO0
Завтра можу дістати екшен камеру і зняти усе одним відео
Неактивний
Прожерливий код який формує суму стабільну осцилограму - частота виклику 25 кГц...
ISR(TIMER1_COMPA_vect)
{
Time = Time+1;
if (Time==1) {
// Высокий уровень выставляется на всех выходах одновременно
digitalWrite(2, HIGH); // Установка на выводе 2 высокого уровня, начало формирования импульса
digitalWrite(4, HIGH); // Установка на выводе 4 высокого уровня, начало формирования импульса
digitalWrite(7, HIGH); // Установка на выводе 7 высокого уровня, начало формирования импульса
digitalWrite(8, HIGH); // Установка на выводе 8 высокого уровня, начало формирования импульса
}
// Низкий уровень выставляется для каждого вывода индивидуально в зависимости от величины управляющего сигнала
if (Time==PD_2) {digitalWrite(2, LOW);} // Установка на выводе 2 низкого уровня, конец формирования импульса
if (Time==PD_4) {digitalWrite(4, LOW);} // Установка на выводе 4 низкого уровня, конец формирования импульса
if (Time==PD_7) {digitalWrite(7, LOW);} // Установка на выводе 7 низкого уровня, конец формирования импульса
if (Time==PB_0) {digitalWrite(8, LOW);} // Установка на выводе 8 низкого уровня, конец формирования импульса
if (Time==500) {
Time = 0; // Формирование паузы и обнуление переменой Time
}
}Неактивний
Те що генерує ваша
Ваш код
Код, що я запостив, на початку setup() понижує тактову частоту вдвічі, щоб на 16-мегагерцовій платі працювало як на 8-мегагерцовій. Тому коли запускаєте на 8-мегагерцовій, інтервали будуть збільшені вдвічі. А по суті це те ж саме що "Стандартна Servo".
Але на фото масштаб 20 мс/, між імпульсами виходить 80 мс, тобто збільшені в 4 рази чомусь.
У вас там часом не 4 МГц резонатор? Чи може не ту частоту обираєте при збірці?
Чим взагалі збираєте? Покажіть, які опції передаються компілятору.
А так, на фото інтервали-то рівні. На відео - таке враження, що осцил просто не може засинхронізуватись. Зменшіть часовий масштаб, щоб з десяток імпульсів було видно.
Стандартна Servo
Знову ж таки, осцил не синхронізується.
Таке враження, що імпульси від ардуіни йдуть з набагато меншою частотою ніж від сервотестера.
Покажіть у меншому масштабі.
Моя, сжера 40% ресурсу
частота виклику 25 кГц...
Тобто гранулярність 40 мкс. Для діапазона 160-2400 мкс виходть 56 кроків. Якщо цього достатньо, то чому б і ні?
Неактивний
Не люблю ютуб-проекти.. 1 листок схеми займає 20 хвилин відео про тяжке життя
Це щось від Алекса Гувера? ![]()
Осцилограф - г%%но, стверджую як власник
Складно добитись синхронізації, але таки спробуйте. Hold натисніть.
Може щось з частотами - це можливо якщо в налаштуваннях Arduino IDE вибрати трохи не ту плату - за що я його не люблю. В Platformio є спосіб вказати частоту резонатора. F_OSC при компіляції чому у вас дорівнює?
Якщо ваш варіант з 40% ресурсу влаштовує - саме час тактоложества; замість digitalwrite пишіть в регістр напряму. Можна на асемблері ![]()
Можна також припустити що у вас щось не те з платою чи резонатором на ній. Є інший екземпляр? Взагалі не бачу смислу упарюватись саме в pro mini. Є 100500 контроллерів, і швидших, і дешевших.
Неактивний
замість digitalwrite пишіть в регістр напряму. Можна на асемблері
Там можна після завершення останнього імпульса заряджати таймер одразу на початок наступного цикла. Бо майже 90% викликів ISR іде вхолосту. Зручніше це, мабуть, буде в режимі FastPWM замість CTC.
Або використати один компаратор для 20 мс циклу, а другий для відмірювання інтервалів дригання пінами.
І якщо піни обрати з однієї банки, то й виставляти їх одночасно однією інструкцією.
Непахане поле для оптимізації.
Неактивний
Або взяти чи зробити плату на якій воно точно працюватиме.
№18 По кварц не скажу, занадто дрібний, але при переносі коду на плату 16 МГц частота подвоюється, відповідно встановлено 8 МГц...
Так що з вашим кодом, що з стандартною біліотекою Servo є проблеми з синхронізацією, якщо осцилограф поганий то проблеми з синхронізацією мали бути і при виконані мого коду...
"56 кроків", 40% і т.д. влаштовує не дуже, основний цикл виконується лише з частотою 30 Гц, занадто повільно, а ще 100% будуть доповнення...
№20 digitalwrite виконуються 8 раз за цикл, а 6 операторів "if" - 500 раз, багато виграю часу?
Сенс простий - напруга живлення 3,3 вольта, один стабілізатор і для Ардуіни, і для nRF24L01...
Можна, тільки я не програміст, а Ардуіну більшь-меньшь нормально знаю...
№21 Щось подібне вже почав писати, але прикладів з поясненнями нема, так що "Винайдення велосипеда"...
Неактивний
№18 По кварц не скажу, занадто дрібний
Там же Atmega328P в TQFP корпусі? Подивіться оцилом на XTAL2 (8-й пін).
але при переносі коду на плату 16 МГц частота подвоюється, відповідно встановлено 8 МГц...
При переносі скомпільованого коду чи при компіляції коду під 16 МГц плату?
Всі таймінги в одиницях часу (мілі- та мікросекунди) спираються на значення макроса F_CPU, що передається під час компіляції. Яке значення передається у вас?
Так що з вашим кодом, що з стандартною біліотекою Servo є проблеми з синхронізацією
Втретє кажу: виставте часовий масштаб, щоб було видно багато імпульсів. 100 мс на поділку, наприклад. І покажіть разом із сигналом від сервотестера.
Неактивний
Ну можна в 16 мгц платі ldo перепаяти на 3.3в, 3 грн ціна питання.
Можна взяти stm32 blue pill , чи rp2040, чи esp32 - arduino сумісні, але мегагерців більше.
Можна взагалі ще один стабілізітор допаяти. І узгодження рівнів на резисторах, це буде швидше ніж вирішувати невідому проблему незрозумілими способами.
Ну якщо без велосипеда ніяк - винайдіть свою реалізацію servo. Це нескладно, таймер генерує interrupt, в кожному interrupt таймер перепрограмується на наступний інтервал часу, якщо на словах. і логічні рівні перемикати в залежності ві того який інтервал спрацював.