Ви не увійшли.
Сторінки 1
Вітаю
Знайомий купив сервотестер за 400 грн,взяв спробувати ...не сподобався
Зробив свій ,може кому знадобиться
#include <Servo.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// === OLED 128x64 (измени на 32, если у тебя 0.91") ===
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// === Пины ===
const int BUTTON_PIN = A1; // ADKeyboard
const int POT_PIN = A3; // Потенциометр
const int SERVO_PIN = 9;
// === Диапазоны ШИМ ===
const int MIN1 = 900, MAX1 = 2100; // Режим 1
const int MIN2 = 700, MAX2 = 2300; // Режим 2
const int MIN3 = 500, MAX3 = 2500; // Режим 3
// === ADC значения ADKey (QYF-995) ===
const int ADC_MODE1 = 786; // Переключает: MANUAL → AUTO → R-POS
const int ADC_LEFT = 145; // Влево
const int ADC_MODE2 = 493; // Меняет скорость в AUTO
const int ADC_MODE3 = 0; // Переключает режимы 1→2→3
const int ADC_RIGHT = 304; // Вправо
const int ADC_TOLERANCE = 50;
// === Режимы управления ===
enum ControlMode { MANUAL, AUTO, RPOS };
ControlMode controlMode = MANUAL;
// === Переменные ===
Servo myservo;
int mode = 1; // 1,2,3 — диапазон
int pos1 = 1500, pos2 = 1500, pos3 = 1500;
int currentMicros = 1500;
// === Авто-режим ===
unsigned long lastAutoMove = 0;
bool autoDirection = true;
int autoStep = 10;
// === Скорость в AUTO ===
int autoSpeedIndex = 1;
int autoSpeeds[3] = {300, 150, 80}; // ms
// === Тихий режим (отключение сервы при покое) ===
unsigned long lastMoveTime = 0;
bool isDetached = false;
// === Для удержания кнопок ===
int lastButton = -1;
unsigned long lastPressTime = 0;
const int DEBOUNCE_DELAY = 200;
// === Прототипы функций ===
int readButton(int adcValue);
void switchMode(int newMode);
int getMin();
int getMax();
void updateDisplay();
void setup() {
Serial.begin(9600);
Serial.println("=== Servo Tester: Final Build ===");
// === OLED ===
delay(100);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("OLED not found!");
while (1);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Starting...");
display.display();
delay(1000);
switchMode(1);
currentMicros = 1500;
myservo.writeMicroseconds(currentMicros);
lastMoveTime = millis();
updateDisplay();
}
void loop() {
int adcValue = analogRead(BUTTON_PIN);
int button = readButton(adcValue);
// === Обработка нажатий ===
if (button != -1 && button != lastButton) {
lastPressTime = millis();
lastButton = button;
// === MODE 3: смена диапазона ===
if (button == 3) {
mode = (mode % 3) + 1;
switchMode(mode);
updateDisplay();
}
// === MODE 2: смена скорости в AUTO ===
else if (button == 2 && controlMode == AUTO) {
autoSpeedIndex = (autoSpeedIndex + 1) % 3;
updateDisplay();
}
// === MODE 1: смена режима управления ===
else if (button == 0) {
if (controlMode == MANUAL) controlMode = AUTO;
else if (controlMode == AUTO) controlMode = RPOS;
else if (controlMode == RPOS) controlMode = MANUAL;
updateDisplay();
}
}
// === Выход из AUTO или R-POS при LEFT/RIGHT ===
if (controlMode != MANUAL && (button == 1 || button == 4)) {
controlMode = MANUAL;
updateDisplay();
}
// === Ручное управление ===
if (controlMode == MANUAL) {
if (button == 1 && currentMicros > getMin()) {
if (millis() - lastPressTime > 100) {
currentMicros -= (millis() - lastPressTime > 500) ? 20 : 10;
if (currentMicros < getMin()) currentMicros = getMin();
attachAndWrite(); // включает серву, если была отключена
lastMoveTime = millis();
updateDisplay();
lastPressTime = millis();
}
}
if (button == 4 && currentMicros < getMax()) {
if (millis() - lastPressTime > 100) {
currentMicros += (millis() - lastPressTime > 500) ? 20 : 10;
if (currentMicros > getMax()) currentMicros = getMax();
attachAndWrite();
lastMoveTime = millis();
updateDisplay();
lastPressTime = millis();
}
}
}
// === Авто-режим ===
if (controlMode == AUTO) {
if (millis() - lastAutoMove > autoSpeeds[autoSpeedIndex]) {
lastAutoMove = millis();
if (autoDirection) {
currentMicros += autoStep;
if (currentMicros >= getMax()) {
currentMicros = getMax();
autoDirection = false;
}
} else {
currentMicros -= autoStep;
if (currentMicros <= getMin()) {
currentMicros = getMin();
autoDirection = true;
}
}
attachAndWrite();
lastMoveTime = millis();
updateDisplay();
}
}
// === Управление от потенциометра ===
if (controlMode == RPOS) {
int potValue = analogRead(POT_PIN);
int target = map(potValue, 0, 1023, getMin(), getMax());
if (abs(currentMicros - target) > 5) {
currentMicros += (currentMicros < target) ? 5 : -5;
attachAndWrite();
lastMoveTime = millis();
updateDisplay();
}
}
// === Авто-отключение сервы при покое (тихий режим) ===
if (!isDetached && millis() - lastMoveTime > 3000) {
myservo.detach();
isDetached = true;
}
// === Сброс кнопки ===
if (button == -1 && lastButton != -1) {
lastButton = -1;
}
delay(5);
}
// === Функция: включить серву и отправить сигнал ===
void attachAndWrite() {
if (isDetached) {
myservo.attach(SERVO_PIN, getMin(), getMax());
isDetached = false;
}
myservo.writeMicroseconds(currentMicros);
}
// === Определение кнопки ===
int readButton(int adcValue) {
if (abs(adcValue - ADC_MODE1) < ADC_TOLERANCE) return 0;
if (abs(adcValue - ADC_LEFT) < ADC_TOLERANCE) return 1;
if (abs(adcValue - ADC_MODE2) < ADC_TOLERANCE) return 2;
if (abs(adcValue - ADC_MODE3) < ADC_TOLERANCE) return 3;
if (abs(adcValue - ADC_RIGHT) < ADC_TOLERANCE) return 4;
return -1;
}
// === Переключение режима ===
void switchMode(int newMode) {
if (mode == 1) pos1 = currentMicros;
if (mode == 2) pos2 = currentMicros;
if (mode == 3) pos3 = currentMicros;
mode = newMode;
if (mode == 1) {
myservo.attach(SERVO_PIN, MIN1, MAX1);
currentMicros = pos1;
} else if (mode == 2) {
myservo.attach(SERVO_PIN, MIN2, MAX2);
currentMicros = pos2;
} else if (mode == 3) {
myservo.attach(SERVO_PIN, MIN3, MAX3);
currentMicros = pos3;
}
myservo.writeMicroseconds(currentMicros);
lastMoveTime = millis();
isDetached = false;
}
// === Мин/макс текущего режима ===
int getMin() { return (mode == 1) ? MIN1 : (mode == 2) ? MIN2 : MIN3; }
int getMax() { return (mode == 1) ? MAX1 : (mode == 2) ? MAX2 : MAX3; }
// === Обновление дисплея ===
void updateDisplay() {
display.clearDisplay();
display.setCursor(0, 0);
display.print("Control:");
if (controlMode == MANUAL) display.println("MANUAL");
else if (controlMode == AUTO) display.println("AUTO");
else if (controlMode == RPOS) display.println("R-POS ");
display.setCursor(0, 12);
display.print("Range:");
display.print(getMin());
display.print("-");
display.print(getMax());
display.setCursor(0, 24);
display.print("Position:");
display.print(currentMicros);
if (controlMode == AUTO) {
display.setCursor(0, 36);
display.print("Spd:");
if (autoSpeedIndex == 0) display.println("Slow");
else if (autoSpeedIndex == 1) display.println("Medium");
else display.println("Fast");
} else {
display.setCursor(0, 36);
display.println("Speed:---");
}
// Прогресс-бар
int bar = map(currentMicros, getMin(), getMax(), 0, 126);
display.drawRect(1, 54, 126, 6, SSD1306_WHITE);
display.fillRect(2, 55, bar, 4, SSD1306_WHITE);
display.display();
}
Інструкція з використання тестера сервоприводу
Цей пристрій призначений для тестування сервоприводів з можливістю зміни діапазону керування, режимів роботи та візуальним відображенням на дисплеї OLED.
Підключення:
Підключіть сервопривід до піну PWM (сигнальний дріт — жовтий/білий).
Підключіть живлення:Бажано використовувати окреме джерело 5–12 В для сервоприводу.
Загальна "земля" (GND) повинна бути спільною з Arduino.
Керування кнопками ADKeyboardКнопка MODE 1:
Перемикає режим керування:
MANUAL-AUTO-R-POSITIONКнопка MODE 3:
Перемикає діапазон ШІМ:
900–2100 us
700–2300
500–2500Кнопка MODE 2:
У режимі AUTO: змінює швидкість руху:
повільно > середньо > швидкоКнопка LEFT у режимі MANUAL: переміщує сервопривід вліво
Кнопка RIGHT у режимі MANUAL: переміщує сервопривід вправо
Режими керування
1. MANUAL (ручний режим)Керування кнопками LEFT і RIGHT.
При короткому натисканні — малий крок (10 мкс).
При довгому утриманні — плавне прискорення (до 20 мкс за крок).
Вихід з режимів AUTO або R-POSITION — натисніть LEFT або RIGHT.
2. AUTO (автоматичний режим)
Сервопривід автоматично рухається від мінімального до максимального положення і назад.
Швидкість змінюється кнопкою MODE 2.
Вихід: натисніть LEFT або RIGHT.
3. R-POS (керування від потенціометра)
Оберіть потенціометр на A3, щоб керувати положенням сервоприводу.
Вихід: натисніть LEFT або RIGHT.
Інформація на OLED-дисплеїНа дисплеї відображається:
Ctrl: поточний режим керування (MANUAL, AUTO, R-POSITION)
Range: діапазон ШІМ (наприклад, 900-2100)
Position: поточне положення сервоприводу в мікросекундах (мкс)
Speed: швидкість у режимі AUTO (Slow, Medium, Fast)
Прогрес-бар: візуальне відображення положення сервоприводу
Тихий режим (автоматичне відключення):Якщо сервопривід не рухається 3 секунди, він автоматично відключається (detach),
щоб не гудів.При наступному керуванні він автоматично підключається назад.
Поради та зауваження:Якщо сервопривід гудить у спокої — це нормально для дешевих моделей (SG90, MG996R).
Він намагається утримати положення.Для стабільної роботи використовуйте окреме джерело
живлення.
Остання редакція nickjust (2025-08-31 15:52:19)
Неактивний
Маю запитання !
Хто мав справу с сервоприводами з літаючих "тварин"
наприклад SERV 01.02-150-15-PWM
Не можу запустити ,веде себе не адекватно
Візуально цілий
Живлення 12В. BLDC-сервопривід с енкодером з PWM
Неактивний
У вас талант ставити питання розпливчато Неадекватно це як?
Гуглиться відео про підключення серви від Шахеда.
Сорян, те що гуглиться - просто обзор. Дивіться, тут червоний проводок а тут аж 2 чорних.
хттпс://www.youtube.com/shorts/_nfCpUB943s
Після падіння може що завгодно бути.від мікротріщини до пошкодження резистора що міряє кут.
Про сервотестер. Все значно простіше . Коли мені був потрібен, я припаяв резистор і конденсатор до ардуїни, залив Examples - Servo - Knob. Така конструкція як у вас може мати смисл, коли цих приводів треба крутити 100 штук в день.
А живлення ви нормальне подаєте? Від двигуна можуть бути непогані імпульсні завади. Зашунтуйте живлення low esr конденсатором на 1000 мкф.
В мене при живленні від USB серва іноді може ребутнути ардуїну. Там завади нормальні. Спробуйте з конденсатором. Воно ж на роботу від акумулятора розраховане, там внутрішній опір мізерний.
Сторінки 1