Здравствуйте всем! Делаю подводный буксир. Мотор бесщеточный 140kv. Батарея 4s li-ion. ESC BLHELI 60A. В полной нагрузке в воде ток 22А. ESC работает исправно. Если пользоваться серво тестером, скачков нет, дерганий нет. Пульт управления сделал на датчике холла 49E. Он похож на курок и диапазон значений составляет от 600 до 668. Не получается удержать обороты на двигателе с помощью этого пульта и поэтому мотор немного дергается. Пришла мысль сделать условно три скорости, но не знаю как правильно сделать. Например 1 скорость, если от 620-640 диапазон, 2-ая если значение от 641-655 и 3-я от 656 до 680. Если курок не нажимать то значение прыгает от 603 до 605. В ардуино это мой первый опыт и скетч лишь немного правил под свой датчик и свой ESC. Пожалуйста скажите реально применить такую функцию использовав датчик холла?
Вот мой скетч:
#include <Servo.h>
Servo motor;
void setup() {
motor.attach(2);
Serial.begin(9600);
}
void loop() {
int val = map(analogRead(0), 620, 660, 1100, 1900);
val = constrain(val, 1100, 1900);
motor.writeMicroseconds(val);
Serial.println(analogRead(0));
delay(100);
}
я написал в каком диапазоне работает датчик холла. это от 1100 до 1900 оборотов. на полностью выжатом курке при значении 667-669, то есть полный газ - мотор не дёргается. он нормально работает, так как уже при 660 считается полный газ.
Обычно исчерпывающая информация о библиотеке содержится в тексте самой библиотеки.
И очень часто какие-либо другие источники информации о конкретной библиотеке напрочь отсутствуют.
непонятно, почему так сильно датчик моросит, у меня на обычном резисторе всего 1 по значениям, надо смотреть в эту сторону, устранишь скачки
можно конечно сделать три диапазона с зазорами и получить три скорости, зазоры по 5 единиц (датчика)
Спасибо за подсказку! Состряпал код. В терминале вроде все правильно, но не работает. Инициализация не нужна. От серво тестера работает норм. Что не так в коде? Что-то где упустил. Подскажите пожалуйста
#include <Servo.h>
Servo motor;
// Пороговые значения
const int lowThreshold = 620; // Нижняя граница для низкой скорости
const int midThresholdLow = 630; // Нижняя граница для средней скорости
const int midThresholdHigh = 650; // Верхняя граница для средней скорости
const int highThresholdLow = 650; // Нижняя граница для высокой скорости
const int highThresholdHigh = 750; // Верхняя граница для высокой скорости
void setup() {
motor.attach(2);
Serial.begin(9600);
}
void loop() {
int sensorValue = analogRead(A0);
int speed;
// Если значение меньше 620, останавливаем двигатель
if (sensorValue < lowThreshold) {
speed = 0; // Остановка
}
// Низкая скорость
else if (sensorValue >= lowThreshold && sensorValue < midThresholdLow) {
speed = 1100; // Низкая скорость
}
// Средняя скорость
else if (sensorValue >= midThresholdLow && sensorValue <= midThresholdHigh) {
speed = 1500; // Средняя скорость
}
// Высокая скорость с учетом гистерезиса
else if (sensorValue > highThresholdHigh) {
speed = 1900; // Высокая скорость
}
// Проверка на высокую скорость в пределах гистерезиса
else if (sensorValue >= highThresholdLow && sensorValue <= highThresholdHigh) {
speed = 1900; // Высокая скорость
}
// Промежуточное значение между низкой и высокой скоростью
else {
speed = constrain(map(sensorValue, lowThreshold, highThresholdHigh, 1100, 1900), 1100, 1900);
}
motor.writeMicroseconds(speed);
Serial.print("Analog Value: ");
Serial.print(sensorValue);
Serial.print(" Speed: ");
Serial.println(speed);
delay(100);
}
поясняю Петровича, у Вас зазоров между 630 и 650 нету, а должны быть, датчик моросит на 2 единицы, чтобы мотор не дергал зазор надо удвоить а то и утроить, то есть не 630, а 627 к примеру а второй отрезок начнётся с 633
PS если не выпендриваться со знанием языка, а написать по простому в стиле ардуино, это будет сразу видно:
#include <Servo.h>
Servo motor;
// Пороговые значения
const int lowThreshold = 620; // Нижняя граница для низкой скорости
const int midThresholdLow = 630; // Нижняя граница для средней скорости
const int midThresholdHigh = 650; // Верхняя граница для средней скорости
const int highThresholdLow = 650; // Нижняя граница для высокой скорости
const int highThresholdHigh = 750; // Верхняя граница для высокой скорости
void setup() {
motor.attach(2);
Serial.begin(9600);
}
void loop() {
int sensorValue = analogRead(A0);
int speed;
// Если значение меньше 620, останавливаем двигатель
if (sensorValue < 620) {
speed = 0; // Остановка
}
// Низкая скорость
else if (sensorValue >= 620 && sensorValue < 630) {
speed = 1100; // Низкая скорость
}
// Средняя скорость
else if (sensorValue >= 630 && sensorValue <= 650) {
speed = 1500; // Средняя скорость
}
// Высокая скорость с учетом гистерезиса
else if (sensorValue > 750) {
speed = 1900; // Высокая скорость
}
// Проверка на высокую скорость в пределах гистерезиса
else if (sensorValue >= 650 && sensorValue <= 750) {
speed = 1900; // Высокая скорость
}
// Промежуточное значение между низкой и высокой скоростью
else {
speed = constrain(map(sensorValue, 620, 750, 1100, 1900), 1100, 1900);
}
motor.writeMicroseconds(speed);
Serial.print("Analog Value: ");
Serial.print(sensorValue);
Serial.print(" Speed: ");
Serial.println(speed);
delay(100);
}
Всем спасибо за помощь. Непросто было разобраться, но я как то смог. Всё работает отлично. Да. На радостях в первой версиях кода забыл о гистерезисе, сейчас всё сделал. Теперь у меня 3 скорости. Есть пороги переключений. Еще может добавлю чуть более плавное переключение скоростей, потому что с1 на 2 чувствуется сильный толчок, а вот с 2 на 3 его совсем не заметно так как уже мотор достаточно раскручен (нудить физикой не хочу =) . Вот полностью рабочий код для тех кто хочет управлять мотором 140KV со сборкой 4s li-ion с помощью датчика холла E49 с блоком ESC (BLHELI, ZMR и другими подобными) на arduino хоть на китайской. В моём случае LGT8F328P. Ход датчика управления 1,9 мм. Магнит извините, не помню, но сами можете подобрать. У меня с какого то CD rom.
#include <Servo.h>
Servo motor;
// Пороговые значения для скоростей
const int lowSpeedLowerBound = 620; // Нижняя граница для первой скорости
const int lowSpeedUpperBound = 629; // Верхняя граница для первой скорости
const int midSpeedLowerBound = 633; // Нижняя граница для второй скорости
const int midSpeedUpperBound = 650; // Верхняя граница для второй скорости
const int highSpeedLowerBound = 655; // Нижняя граница для третьей скорости
const int highSpeedUpperBound = 680; // Верхняя граница для третьей скорости
int currentSpeed = 0;
bool midSpeedActive = false; // Флаг для отслеживания состояния второй скорости
void setup() {
motor.attach(2);
Serial.begin(9600);
// Инициализация ESC
motor.writeMicroseconds(2000); // Максимальное значение
delay(2000); // Подождите 2 секунды
motor.writeMicroseconds(1000); // Минимальное значение
delay(2000); // Подождите 2 секунды
}
void regulateSpeed(int sensorValue) {
// Логика переключения скоростей
if (sensorValue < lowSpeedLowerBound) {
currentSpeed = 0; // Остановка
midSpeedActive = false; // Сброс флага
}
else if (sensorValue >= lowSpeedLowerBound && sensorValue <= lowSpeedUpperBound) {
currentSpeed = 1500; // Первая скорость
midSpeedActive = false; // Сброс флага
}
else if (sensorValue >= midSpeedLowerBound && sensorValue <= midSpeedUpperBound) {
if (!midSpeedActive) {
currentSpeed = 1750; // Вторая скорость
midSpeedActive = true; // Устанавливаем флаг
}
}
else if (sensorValue >= highSpeedLowerBound && sensorValue <= highSpeedUpperBound) {
currentSpeed = 1900; // Третья скорость
midSpeedActive = false; // Сброс флага
}
// Проверяем, если вторая скорость активна, и значение падает ниже 626
if (midSpeedActive && sensorValue <= 626) {
currentSpeed = 1500; // Возвращаемся к первой скорости
midSpeedActive = false; // Сброс флага
}
}
void debug(int sensorValue) {
Serial.print("Analog Value: ");
Serial.print(sensorValue);
Serial.print(" Current Speed: ");
Serial.println(currentSpeed);
}
void loop() {
int sensorValue = analogRead(A0);
regulateSpeed(sensorValue);
motor.writeMicroseconds(currentSpeed);
debug(sensorValue);
delay(100);
}
Второй раз встречается одна и та же ошибка, я о строках калибровки (20-25)
калибровка регулятора осуществляется под данные реального канала, почему - в программе регулятора уже заложен необходимый запас снизу на старт двигателя, к примеру если с канал пришел сигнал максимума 1900 а сигнал минимума 1100, то регулятор вносит эти константы и пуск двигателя будет где-то с 1150, поэтому процедура и называется - калибровка