Ви не увійшли.
Я рахую,тре всьо спробувати...та вчитися!
І краще розмовляти з ШІ ніж з їбаньками з форумів,таких як Радіокот (правда там є і нормальні)
Мені ще подобається Чорний форум - також норм допомогають.
І ще замічаю ,що інет став нууу дуже грошовий ....усі кинулися заробляти...за прошивку 2017 року ,яка нещо давно вільно була на оффсайті Acer хотят гроші....гроші....гроші....
Неактивний
Чорний форум - wtf??
На сьогодні єнкодер видає 10 імпульсів на оборот. Стоїть резистор 10кОм + конденсатори 0.1 мкФ на A (A → GND)
Є скетч для керування мотором та підтримкою швидкості Але двигун не підтримує швидкість. Постійно крутиться з максимальною швидкістю
/*
* Мотор + энкодер 10 PPR
* Стабильный расчёт RPM (среднее за 1 секунду + сглаживание)
* Arduino Uno
* Энкодер: A→2, B→4, Vcc→5V, GND→GND
* Мотор (L298N): IN1→10, IN2→11, ENA→9
*/
// ====================== ПИНЫ ======================
#define ENC_A 2
#define ENC_B 4
#define MOTOR_1 10
#define MOTOR_2 11
#define MOTOR_PWM 9
// ====================== КОНСТАНТЫ ЭНКОДЕРА ======================
const int PULSES_PER_REV = 10; // импульсов за один оборот
// ====================== ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ ======================
volatile long totalPulses = 0; // суммарное количество импульсов
volatile int lastEncA = HIGH; // предыдущее состояние канала A
volatile unsigned long lastIntTime_us = 0;
const unsigned long DEBOUNCE_us = 5000; // 5 мс антидребезг
long revolutions = 0; // totalPulses / 10 (целые обороты)
// ---- Переменные для RPM (стабильный расчёт) ----
unsigned long lastRpmTime_ms = 0;
long prevTotalPulses = 0;
float smoothRPM = 0.0;
const float RPM_SMOOTH = 0.1; // сильное сглаживание (0..1)
const unsigned long RPM_INTERVAL_ms = 1000; // интервал измерения 1 секунда
// ---- Управление мотором ----
int targetRevolutions = 0; // 0 – бесконечно, иначе остановить по достижении
bool motorEnabled = false;
int currentSpeed = 200; // текущая скорость (0-255)
bool rpmVisible = true; // показывать RPM в логе
// ====================== SETUP ======================
void setup() {
Serial.begin(9600);
// Энкодер
pinMode(ENC_A, INPUT_PULLUP);
pinMode(ENC_B, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(ENC_A), encoderISR, CHANGE);
/*
* Мотор + энкодер 10 PPR + П-регулятор скорости
* Поддерживает заданные обороты в минуту (RPM)
*/
#define ENC_A 2
#define ENC_B 4
#define MOTOR_1 10
#define MOTOR_2 11
#define MOTOR_PWM 9
const int PULSES_PER_REV = 10;
volatile long totalPulses = 0;
volatile int lastEncA = HIGH;
volatile unsigned long lastIntTime_us = 0;
const unsigned long DEBOUNCE_us = 5000;
long revolutions = 0;
unsigned long lastRpmTime_ms = 0;
long prevTotalPulses = 0;
float smoothRPM = 0.0;
const float RPM_SMOOTH = 0.1;
const unsigned long RPM_INTERVAL_ms = 1000;
bool motorEnabled = false;
int currentSpeed = 0; // текущая ШИМ (0-255)
float targetRPM = 0.0; // целевая скорость (0 = выкл)
float Kp = 2.0; // коэффициент П-регулятора (настраивается)
const int minPWM = 0;
const int maxPWM = 255;
void setup() {
Serial.begin(9600);
pinMode(ENC_A, INPUT_PULLUP);
pinMode(ENC_B, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(ENC_A), encoderISR, CHANGE);
pinMode(MOTOR_1, OUTPUT);
pinMode(MOTOR_2, OUTPUT);
pinMode(MOTOR_PWM, OUTPUT);
stopMotor();
Serial.println(F("=== ПИД-регулятор скорости (П-регулятор) ==="));
Serial.println(F("Команды:"));
Serial.println(F(" r <об/мин> - установить целевую скорость, например r100"));
Serial.println(F(" s - стоп"));
Serial.println(F(" k <коэфф> - изменить Kp (по умолч. 2.0)"));
Serial.println(F(" status - показать параметры"));
Serial.println();
}
void loop() {
// Обновление счётчика оборотов
long newRevs = totalPulses / PULSES_PER_REV;
if (newRevs != revolutions) revolutions = newRevs;
// Расчёт RPM (раз в секунду)
unsigned long now = millis();
if (now - lastRpmTime_ms >= RPM_INTERVAL_ms) {
long delta = totalPulses - prevTotalPulses;
float revs = (float)delta / PULSES_PER_REV;
float sec = (now - lastRpmTime_ms) / 1000.0;
float instant = (revs / sec) * 60.0;
if (instant < 0) instant = -instant;
if (smoothRPM < 0.1) smoothRPM = instant;
else smoothRPM = RPM_SMOOTH * instant + (1 - RPM_SMOOTH) * smoothRPM;
prevTotalPulses = totalPulses;
lastRpmTime_ms = now;
}
// П-регулятор: подстраиваем ШИМ, чтобы smoothRPM стремился к targetRPM
if (targetRPM > 0 && motorEnabled) {
float error = targetRPM - smoothRPM;
int newPWM = constrain(currentSpeed + Kp * error, minPWM, maxPWM);
if (newPWM != currentSpeed) {
// Сохраняем направление (определяем по текущим выходам)
bool forward = (digitalRead(MOTOR_1) == HIGH && digitalRead(MOTOR_2) == LOW);
setMotor(newPWM, forward);
}
}
// Вывод состояния (каждые 200 мс)
static unsigned long lastPrint = 0;
if (now - lastPrint >= 200) {
Serial.print(F("Об.: ")); Serial.print(revolutions);
Serial.print(F(" имп.: ")); Serial.print(totalPulses % PULSES_PER_REV);
Serial.print(F(" RPM: ")); Serial.print(smoothRPM, 1);
if (targetRPM > 0) {
Serial.print(F(" / целевая: ")); Serial.print(targetRPM, 1);
Serial.print(F(" ШИМ: ")); Serial.print(currentSpeed);
}
Serial.println();
lastPrint = now;
}
// Обработка команд
if (Serial.available()) {
String cmd = Serial.readStringUntil('n');
cmd.trim();
parseCommand(cmd);
}
delay(1);
}
void encoderISR() {
unsigned long now = micros();
if (now - lastIntTime_us < DEBOUNCE_us) return;
lastIntTime_us = now;
int a = digitalRead(ENC_A);
int b = digitalRead(ENC_B);
if (a != lastEncA) {
if (a == b) totalPulses++;
else totalPulses--;
lastEncA = a;
}
}
void setMotor(int speed, bool forward) {
speed = constrain(speed, 0, 255);
currentSpeed = speed;
if (speed == 0) { stopMotor(); return; }
digitalWrite(MOTOR_1, forward ? HIGH : LOW);
digitalWrite(MOTOR_2, forward ? LOW : HIGH);
analogWrite(MOTOR_PWM, speed);
motorEnabled = true;
}
void stopMotor() {
digitalWrite(MOTOR_1, LOW);
digitalWrite(MOTOR_2, LOW);
analogWrite(MOTOR_PWM, 0);
motorEnabled = false;
targetRPM = 0;
currentSpeed = 0;
}
void parseCommand(String cmd) {
if (cmd.length() == 0) return;
char first = cmd.charAt(0);
if (first == 'r') {
float rpm = cmd.substring(1).toFloat();
if (rpm > 0) {
targetRPM = rpm;
// Запускаем мотор с текущим ШИМ (можно начать с любого, например 100)
if (!motorEnabled) setMotor(100, true);
Serial.print(F("Целевая скорость установлена: "));
Serial.print(targetRPM);
Serial.println(F(" об/мин"));
} else {
targetRPM = 0;
stopMotor();
Serial.println(F("Регулятор отключён"));
}
}
else if (first == 's') {
stopMotor();
Serial.println(F("Стоп"));
}
else if (first == 'k') {
float newK = cmd.substring(1).toFloat();
if (newK >= 0) {
Kp = newK;
Serial.print(F("Kp = "));
Serial.println(Kp);
}
}
else if (cmd.equalsIgnoreCase("status")) {
Serial.print(F("Оборотов: ")); Serial.print(revolutions);
Serial.print(F(", RPM: ")); Serial.print(smoothRPM, 1);
Serial.print(F(", целевая: ")); Serial.print(targetRPM, 1);
Serial.print(F(", ШИМ: ")); Serial.print(currentSpeed);
Serial.print(F(", Kp: ")); Serial.println(Kp);
}
else {
Serial.println(F("Команды: r<об/мин>, s, k<коэфф>, status"));
}
}
В результаті
Целевая скорость установлена: 100.00 об/мин
Об.: 0 имп.: 1 RPM: 0.0 / целевая: 100.0 ШИМ: 255
Об.: 0 имп.: 1 RPM: 0.0 / целевая: 100.0 ШИМ: 255
Об.: 0 имп.: 1 RPM: 0.0 / целевая: 100.0 ШИМ: 255
Неактивний
Я рахую,тре всьо спробувати...та вчитися!
І краще розмовляти з ШІ ніж з їбаньками з форумів,таких як Радіокот (правда там є і нормальні)
Мені ще подобається Чорний форум - також норм допомогають.
І ще замічаю ,що інет став нууу дуже грошовий ....усі кинулися заробляти...за прошивку 2017 року ,яка нещо давно вільно була на оффсайті Acer хотят гроші....гроші....гроші....
шановний nickjust ви знаєте когось хто може виконати роботу за гроші? ключове це виконати, а не консультувати або подивитися скетч. Я в Києві. Дякую
Неактивний