плавный пуск DC мотора с ручной регулировкой оборотов( коряво работает)
- Войдите на сайт для отправки комментариев
Добрый день, форумчане! Прошу помощи или дельного совета по моей проблеме. Суть такова: есть китайский 775 движок на 150 Ватт, питается от 24 вольт( стоит в ЧПУ станке CNC 1610), ему нужно устройство плавного пуска- чтоб БП в защиту по току не уходил, и станок не подпрыгивал)). Решил собрать данное устройство на arduino, принцип работы следующий- при поступлении на 5 пин команды включения шпинделя от платы станка, на 9 выводе ардуинки появляется 8 бит ШИМ ( на затвор мощного полевика), его значение растёт до максимума(255) в течении какого-то времени( движок набирает обороты), и держится, пока на 5 пине уровень 5 вольт. как только на 5 пине 0, шим выключается. это всё одновременно с ростом шим выводится в виде аналоговой шкалы( прогресс-бар) на дисплей 1602, есть 2 кнопки + и - для регулировки скорости вручную после выхода в режим. А теперь проблема- оно не работает как написано: либо только вручную, либо плавный старт, но без индикации. Скетч прилагаю, сильно не пинайте( что-то писал сам, что-то взял из готового)
//запуск шпинделя с задержкой, с выводом на дисплей в виде аналоговой шкалы и корректировкой скорости на ходу, //только оно не работает как хотелось, либо старт плавно, либо только вручную #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x3f,16,2); int pinPWM = 9; // Присваиваем имя PWM цифровому выводу 9, к которому подключен шпиндель //int pinDRV = 10; //вывод шим, альтернативный, для плавного старта int pinRELE = 11; //реле или оптрон, замыкающие кнопку "+" int speedMot = 0; // переменная для задания шага скорости int stepping = 5; // шаг изменения скорости int buttonPlus=2; // Номер Pin к которому подключена кнопка "+" int buttonMinus=3; // Номер Pin к которому подключена кнопка "-" int pinGRBL =5; //номер пин, который получает сигнал с платы станка //int s; //объявим переменную uint8_t symbol[8] = {31,31,31,31,31,31,31,31}; // Определяем массив который содержит полностью закрашенный символ //boolean state = LOW; объявим тип данных, присвоим изначально 0 void setup() { pinMode(pinGRBL,INPUT); // инициализируем вход для плавного старта pinMode(pinPWM, OUTPUT); // Инициализируем цифровой вывод pinPWM (pin 9) как выход //pinMode(pinDRV,OUTPUT);//инициализируем выход для плавного старта pinMode(pinRELE,OUTPUT);//инициализируем выход для оптрона( блокировка кнопки +) Serial.begin(9600); // инициализируем порт, скорость 9600 lcd.init(); // инициализация LCD lcd.backlight(); //включаем подсветку lcd.setCursor(2,0); lcd.print("SPEED"); //выводим слово " скорость" } void loop() { // Этот цикл будет выполняться бесконечное количество раз. if(digitalRead(pinGRBL)==HIGH) {//если на входе сигнал от "дятла" digitalWrite(pinRELE,HIGH);//включаем реле //state = !state;//меняем бит //if(state) {//не вдуплил нах оно тут нужно //for(s = 0; s < 255; s++) {//пока переменная s не достигнет значения 255, увеличиваем её //analogWrite(pinDRV,s);//на вывод даём шим //digitalWrite(pinRELE,LOW);// delay(5); digitalWrite(pinRELE,LOW);// выключаем реле } if (digitalRead(pinGRBL)==LOW){ analogWrite(pinPWM, LOW); //} else { // for(s = 255; s = 255;) {//как только шим достиг предела // analogWrite(pinDRV, LOW);//на вывод даём шим //digitalWrite(pinRELE,LOW);// выключаем реле delay(10);} if (digitalRead(buttonPlus) == LOW) {speedMot += stepping;} //если на выводе 2 (кнопка "+") низкий уровень (нажата), то // прибавляем значение скорости с шагом stepping if (digitalRead(buttonMinus) == LOW) {speedMot -= stepping;}//если на выводе 3 (кнопка "-") низкий уровень (нажата), то // уменьшаем значение скорости с шагом stepping speedMot = constrain(speedMot, 0, 255); // Эта функция задает крайние точки диапазона для переменной speedMot 0 и 255 analogWrite(pinPWM, speedMot); // устанавливаем на выводе pinPWM значение скорости speedMot delay(5); // Пауза 5 миллисекунд. int x = speedMot; lcd.setCursor(8,0); lcd.print(x); lcd.print(" "); lcd.setCursor(0,1); lcd.createChar(1, symbol); lcd.print(" "); // Загружаем символ из массива symbol в первую ячейку ОЗУ дисплея lcd.setCursor(0,1); uint8_t j=map( x,0,255,0,17); // Определяем переменную j которой присваиваем значение x преобразованное от диапазона 0...255 к диапазону 0...17 for(uint8_t i=0; i<16; i++){ // Выполняем цикл 16 раз для вывода шкалы из 16 символов начиная с позиции в которую ранее был установлен курсор lcd.write(j>i? 1:32);} // Выводим на дисплей символ по его коду, либо 1 (символ из 1 ячейки ОЗУ дисплея), либо 32 (символ пробела) // После вывода каждого символа, курсор дисплея сдвигается автоматически } //} //} //}Похоже очередной изобретатель "вечного двигателя" не знакомый с законами физики.
Похоже очередной изобретатель "вечного двигателя" не знакомый с законами физики.
Потому что есть целый курс института, как регулировать двигатели постояного тока. На который вы похоже забили.
хорошо, тогда как обеспечить плавный старт движка с использованием контроллера? есть что конкретно по делу сказать? как, по вашему в станке обороты движка регулируются, есть там мощный полевик стоит без радиатора? ШИМ, причём довольно шустрый. Обгадить каждый может, а вот подсказать - тут надо мозг включать
это ручная регулировка, заполнение шкалы по мере возрастания скорости
Ну вы видели движки на промышленных станках. Мощность размеры.Почему стоят коробки переключения скоростей. А теперь двигатели для вентиляции. Там ничего этого нет. Вы что ставите движок для обдува? или сверления. Похоже для сверления. И что я вижу. маломощный игрушечный моторчик, игрушечный контроллер и похоже "игрушечный мозг" ,а желания и требования уже не игрушечные.
ПС: Куйня у вас выйдет со всем этим.
как обеспечить плавный старт движка
Взять специализированную микросхему "драйвер коллеторного DC мотора" работающую с нуными током и напряжением и уже ею управлять из контроллера. Микросхему можно выбрать, поковырявшись по спискам производителей и посравнивав хракетиристики и цены. Пример подобного списка
Это будет не на коленке из дерьма и палок, а нормальное профессиональное решение.
Уважаемый, 33 и 43 строка в взаимоисключающие, поэтому есть смысл в 43 строке использовать else. А вот автоматического увеличения скорости я так и не увидел...
готовое решение, купленное в магазине- напрочь убивает желание заниматься творчеством, проще тогда всё покупать, следуя Вашей логике. А если кто не в теме, что это и зачем нужно- вот ссторонняя ссылка, там и видео есть( делаю подобное устройство)http://www.cnc-club.ru/forum/viewtopic.php?f=147&t=19734 там в каждый G-код добавляется хренова гора строк.....но зачем это нужно каждый раз писать
брат! Ты попал на мрачное состояние форумчан. ;) Конечно DC мотор прекрасно регулируется ШИМом, и вполне себе через полевик. Только код у тебя полное говно, но это можно поправить.
готовое решение, купленное в магазине- напрочь убивает желание заниматься творчеством, проще тогда всё покупать,
.....но зачем это нужно каждый раз писать
if(digitalRead(pinGRBL)==HIGH) {//если на входе сигнал от "дятла"- тут остается тока гадать, что там за сигнал и с чем его ...- ТС, мы же тут не ясновидящие, чтобы к нам с неба падали алгоритмы работы вашего станка//if(state) {//не вдуплил нах оно тут нужно
-вот уже подозреваю, что это состояние старт или работа
сигнал от " дятла" это тупо логическая 1- включить шпиндель(дятел- это плата станка woodpecker)
готовое решение, купленное в магазине- напрочь убивает желание заниматься творчеством
А готовое решение, выклянченное на форуме - наоборот, способствует творческому росту!
Попробуйте так. из за отсутствия библилтеки - не прверял
//запуск шпинделя с задержкой, с выводом на дисплей в виде аналоговой шкалы и корректировкой скорости на ходу, //только оно не работает как хотелось, либо старт плавно, либо только вручную #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x3f,16,2); int pinPWM = 9; // Присваиваем имя PWM цифровому выводу 9, к которому подключен шпиндель //int pinDRV = 10; //вывод шим, альтернативный, для плавного старта int pinRELE = 11; //реле или оптрон, замыкающие кнопку "+" int speedMot = 0; // переменная для задания шага скорости int stepping = 5; // шаг изменения скорости int buttonPlus=2; // Номер Pin к которому подключена кнопка "+" int buttonMinus=3; // Номер Pin к которому подключена кнопка "-" int pinGRBL =5; //номер пин, который получает сигнал с платы станка //int s; //объявим переменную uint8_t symbol[8] = {31,31,31,31,31,31,31,31}; // Определяем массив который содержит полностью закрашенный символ boolean state = LOW;// объявим тип данных, присвоим изначально 0 void setup() { pinMode(pinGRBL,INPUT); // инициализируем вход для плавного старта pinMode(pinPWM, OUTPUT); // Инициализируем цифровой вывод pinPWM (pin 9) как выход //pinMode(pinDRV,OUTPUT);//инициализируем выход для плавного старта pinMode(pinRELE,OUTPUT);//инициализируем выход для оптрона( блокировка кнопки +) pinMode(buttonPlus, INPUT_PULLUP); pinMode(buttonMinus, INPUT_PULLUP); //Serial.begin(9600); // инициализируем порт, скорость 9600 lcd.init(); // инициализация LCD lcd.backlight(); //включаем подсветку lcd.setCursor(2,0); lcd.print("SPEED"); //выводим слово " скорость" } void loop() { // Этот цикл будет выполняться бесконечное количество раз. if(digitalRead(pinGRBL)==HIGH) {//если на входе сигнал от "дятла" digitalWrite(pinRELE,HIGH);//включаем реле if(!state){ state = 1;//меняем бит for(int i = speedMot; i < 255; i++) { speedMot++; delay(5);// } } } if (digitalRead(pinGRBL)==LOW){ state = 0;//меняем бит speedMot = 0; digitalWrite(pinRELE,LOW);// выключаем реле } if (digitalRead(buttonPlus) == LOW) { speedMot++; } //если на выводе 2 (кнопка "+") низкий уровень (нажата), то // прибавляем значение скорости с шагом stepping if (digitalRead(buttonMinus) == LOW) { speedMot--; }//если на выводе 3 (кнопка "-") низкий уровень (нажата), то // уменьшаем значение скорости с шагом stepping speedMot = constrain(speedMot, 0, 255); // Эта функция задает крайние точки диапазона для переменной speedMot 0 и 255 analogWrite(pinPWM, speedMot); // устанавливаем на выводе pinPWM значение скорости speedMot int x = speedMot; lcd.setCursor(8,0); lcd.print(x); lcd.print(" "); lcd.setCursor(0,1); lcd.createChar(1, symbol); lcd.print(" "); // Загружаем символ из массива symbol в первую ячейку ОЗУ дисплея lcd.setCursor(0,1); uint8_t j=map( x,0,255,0,17); // Определяем переменную j которой присваиваем значение x преобразованное от диапазона 0...255 к диапазону 0...17 for(uint8_t i=0; i<16; i++){ // Выполняем цикл 16 раз для вывода шкалы из 16 символов начиная с позиции в которую ранее был установлен курсор lcd.write(j>i? 1:32); } // Выводим на дисплей символ по его коду, либо 1 (символ из 1 ячейки ОЗУ дисплея), либо 32 (символ пробела) // После вывода каждого символа, курсор дисплея сдвигается автоматически } //} //} //}код рабочий, только всё вместе не работает, вот тут и прошу помочь, разобраться с кодом, указать на косяки, готовое решение никто не будет писать под конкретную задачу
vosara ,щас попробую запустить
Ну понятие что такое рабочий код , что говнокод, а что простое гавно индивидуально.
Рассказывать Вам про цифровой автомат и решение через него- зачем. Это же придушит ваше "творчество" на корню.
в коде включается реле потому, что у меня при плавном запуске прогресс бар ничего не отображает, только при управлении с кнопок
т а если шпиндель вращается, там что 0 ?
нет, там "0" только когда приходит команда выключить шпиндель. пришлось извращаться с реле, ибо не пойму как это совместно запустить
не отображает так что с того, зачем отображать?
можете понизить стартовые обороты, выставить их не макс, а средние, а потом уже рулить ручками.
непонятно, зачем создавать себе проблему на ровном месте
судя по коду, двигатель на разгон должн выходить около 1,5 сек и из-за этого нужно городить огород?
ну, не умею я писать красивые коды, не умею.....хотелось и плавный старт и регулировку с отображением процесса, не используя разные там хитрые микросхемы и промышленные решения. изначально задумка была с энкодером, но там вообще тёмный лес с этими прерываниями и портами
Попробуйте так. из за отсутствия библилтеки - не прверял
Спасибо за поправку-попробовал, работает,отображается и движок пускается, только быстро....
понял в чём была моя ошибка, надо было везде использовать ранее объявленные переменные i и speedMot, а не создавать новые, INPUT_PULLUP я не ставил у себя, потому что подтяжка уже внешними резисторами на портах.
стал на вывод ШИМ осциллографом, там уровень резко возрастает при подаче управляющего сигнала, вручную- там именно шим, но без управляющего сигнала, не работает. Как сделать if(digitalRead(pinGRBL)==HIGH) {//если на входе сигнал от "дятла"- необязательным условием запуска? ибо контроллер в цикле ждёт пока не появится этот сигнал, и соответственно ничё не работает
стал на вывод ШИМ осциллографом, там уровень резко возрастает при подаче управляющего сигнала, вручную- там именно шим, но без управляющего сигнала, не работает. Как сделать if(digitalRead(pinGRBL)==HIGH) {//если на входе сигнал от "дятла"- необязательным условием запуска? ибо контроллер в цикле ждёт пока не появится этот сигнал, и соответственно ничё не работает
А ты в ручном режиме хочешь без контроллера тоже управлять? Я не понял.
иногда бывает нужно, без запуска G-кода, включить движок
стал на вывод ШИМ осциллографом, там уровень резко возрастает при подаче управляющего сигнала, вручную- там именно шим, но без управляющего сигнала, не работает. Как сделать if(digitalRead(pinGRBL)==HIGH) {//если на входе сигнал от "дятла"- необязательным условием запуска? ибо контроллер в цикле ждёт пока не появится этот сигнал, и соответственно ничё не работает
Ну, дык, алгоритм писать, аднака.
Ну, дык, алгоритм писать, аднака.
ну дык он написан, ток кривой, как .......
ну дык он написан, ток кривой, как .......
Не, уважаемый, написана кривая программа, а алгоритм как раз не написан. Алгоритм - это, в идеале, такая схема с квадратиками и ромбиками, а также связи между ними. Ромбик - "дятел стукнул?" -ДА -НЕТ, на ДА прямоугольник "Включаем реле, включаем ШИМ" и т.д.
иногда бывает нужно, без запуска G-кода, включить движок
Тогда вот:
Тут, если сигнал от контроллера пропал, значение мощности остается на месте для ручного изменения и если появился - тоже, расти начнет с того же места, где была в момент включения "дятла", как ты его назвал.
Если во время автоматического роста нажать + или -, то система перейдет в ручной режимне, не перейдет, это от старого осталось. ;)))
#include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27,16,2); const uint32_t stepTime = 10; //время шага увеличения мощности const byte stepPWM = 1; //величина приращения на шаг const byte On = 1; const byte Off = 0; const byte UNNOWN = 0xff; const byte SwitchOn_level = LOW; const byte SwitchOff_level = HIGH; const byte plusBtn = 0; const byte minusBtn = 1; const byte NSwitches = 2; const byte Switch2pin[NSwitches] = {2,3}; const byte motorPin = 9; const byte grblPin = 5; const uint32_t intervalDebonce = 20; void setup() { lcd.init(); lcd.setCursor(0,0); lcd.print(" SPEED = "); pinMode(motorPin,OUTPUT); for (byte i = 0; i < NSwitches; i++) pinMode (Switch2pin[i],INPUT_PULLUP); } void loop() { const byte sAuto = 0; const byte sManu = 1; static int motor = 0; static byte state = sAuto; static uint32_t om = millis(); uint32_t nm = millis(); Switches(0); //регулярное обновление значений кнопок if (digitalRead(grblPin) == LOW) state = sManu; if (state == sAuto) { //в состоянии Авто - растем, как назначено if (nm - om > stepTime) { motor += stepPWM; om = nm; } if (Switches(plusBtn) == On || Switches(minusBtn) == On) state = sManu; //если состояние Автои нажата кнопка - переходим в ручное управление } else { //ручное управление if (Switches( plusBtn) == On) motor += stepPWM; if (Switches(minusBtn) == On) motor -= stepPWM; if (digitalRead(grblPin) == HIGH) state = sAuto; } if (motor < 0) motor = 0; if (motor > 255) motor = 255; // ограничения значений analogWrite(motorPin,motor); lcd.setCursor(9,0); lcd.print(motor); lcd.print(" "); lcd.setCursor(0,1); for (byte i = 0; i < 16; i++) if (i < (motor >> 4)) lcd.write(255); else lcd.write(32); } byte Switches(byte __switch) { static uint32_t om = millis(); uint32_t nm = millis(); static byte Switch [NSwitches] = {0}; byte i; for (i = 0; i < NSwitches; i++) if (Switch[i] != digitalRead(Switch2pin[i])) { om = nm; Switch[i] = digitalRead(Switch2pin[i]); } if (nm - om > intervalDebonce) if (Switch[__switch] == SwitchOn_level) return On; else return Off; return UNNOWN; }Сейчас подправил, должен работать правильно. Пробуйте и анализируйте
//запуск шпинделя с задержкой, с выводом на дисплей в виде аналоговой шкалы и корректировкой скорости на ходу, //только оно не работает как хотелось, либо старт плавно, либо только вручную #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x3f,16,2); #define pinPWM 9 // Присваиваем имя PWM цифровому выводу 9, к которому подключен шпиндель #define pinRELE 11 //реле или оптрон, замыкающие кнопку "+" uint8_t speedMot = 0; // переменная для задания шага скорости uint8_t speedMot2 = 1; int stepping = 5; // шаг изменения скорости #define buttonPlus 2 // Номер Pin к которому подключена кнопка "+" #define buttonMinus 3 // Номер Pin к которому подключена кнопка "-" #define pinGRBL 5 //номер пин, который получает сигнал с платы станка uint32_t time1; boolean state = LOW;// объявим тип данных, присвоим изначально 0 uint8_t symbol[8] = { 31,31,31,31,31,31,31,31}; // Определяем массив который содержит полностью закрашенный символ void setup() { pinMode(pinGRBL,INPUT); // инициализируем вход для плавного старта pinMode(pinPWM, OUTPUT); // Инициализируем цифровой вывод pinPWM (pin 9) как выход pinMode(pinRELE,OUTPUT);//инициализируем выход для оптрона( блокировка кнопки +) pinMode(buttonPlus, INPUT_PULLUP); pinMode(buttonMinus, INPUT_PULLUP); //Serial.begin(9600); // инициализируем порт, скорость 9600 lcd.init(); // инициализация LCD lcd.backlight(); //включаем подсветку lcd.setCursor(2,0); lcd.print("SPEED"); //выводим слово " скорость" } void loop() { // Этот цикл будет выполняться бесконечное количество раз. if(digitalRead(pinGRBL)==HIGH) {//если на входе сигнал от "дятла" digitalWrite(pinRELE,HIGH);//включаем реле if(!state){ state = 1;//меняем бит for(int i = speedMot; i < 255; i++) { speedMot++; delay(5);// } } } if (digitalRead(pinGRBL)==LOW){ state = 0;//меняем бит speedMot = 0; digitalWrite(pinRELE,LOW);// выключаем реле } //если на выводе 2 (кнопка "+") низкий уровень (нажата), то прибавляем значение скорости if (digitalRead(buttonPlus) == LOW) { if(millis() - time1 >= 300) { time1 = millis(); speedMot++; } } //если на выводе 3 (кнопка "-") низкий уровень (нажата), то уменьшаем значение скорости if (digitalRead(buttonMinus) == LOW) { if(millis() - time1 >= 300) { time1 = millis(); speedMot--; } } speedMot = constrain(speedMot, 0, 255); // Эта функция задает крайние точки диапазона для переменной speedMot 0 и 255 analogWrite(pinPWM, speedMot); // устанавливаем на выводе pinPWM значение скорости speedMot if(speedMot2 != speedMot)//Выводим на монитор только если значения изменились { speedMot2 = speedMot; int x = speedMot; lcd.setCursor(8,0); lcd.print(x); lcd.print(" "); lcd.setCursor(0,1); lcd.createChar(1, symbol); lcd.print(" "); // Загружаем символ из массива symbol в первую ячейку ОЗУ дисплея lcd.setCursor(0,1); uint8_t j=map( x,0,255,0,17); // Определяем переменную j которой присваиваем значение x преобразованное от диапазона 0...255 к диапазону 0...17 for(uint8_t i=0; i<16; i++){ // Выполняем цикл 16 раз для вывода шкалы из 16 символов начиная с позиции в которую ранее был установлен курсор lcd.write(j>i? 1:32); } // Выводим на дисплей символ по его коду, либо 1 (символ из 1 ячейки ОЗУ дисплея), либо 32 (символ пробела) // После вывода каждого символа, курсор дисплея сдвигается автоматически } }Он, либо есть, либо нет. Кривого алгоритма не бывает, бывает поток сознания. А значит, этот поток надо переделать в алгоритм, исключив все неопределенности.
P/S Пока корябал, уже ответили.
спасибо, буду пробовать и анализировать
Я так понял что ручное управление выполняется только когда станок уже запущен, а если надо в выключеном состоянии запустить ручное то надо немного подправить код. Пишите
стал на вывод ШИМ осциллографом, там уровень резко возрастает при подаче управляющего сигнала, вручную- там именно шим.
попробуйте для себя составить блоксхему алгоритма работы, все состояния системы в ней отразить. ИМХО. вы пока не представляете всей логики, которая вам нужна, а если бы представляли попытались бы впихнуть ее в код.
напишите кусок кода с плавным разгоном и торможением до установленого потенциометром значения, что бы при старте не рвал с места, а плавно набирал. Используйсте какой-нибудь таймер, ну на край делей.
(из-за делей будут проблемы с кнопками)
Вам бы разделить вашу задачу на части, и научиться писать код (понимать что пишете) для каждого элемента.
Тут, если сигнал от контроллера пропал, значение мощности остается на месте для ручного изменения и если появился - тоже, расти начнет с того же места, где была в момент включения "дятла", как ты его назвал.
не совсем. Пропадание сигнала-обязательное выключение движка, включение может быть и автоматом плавно и с кнопок вручную, а выключение всегда - иначе будет авария
Тут, если сигнал от контроллера пропал, значение мощности остается на месте для ручного изменения и если появился - тоже, расти начнет с того же места, где была в момент включения "дятла", как ты его назвал.
не совсем. Пропадание сигнала-обязательное выключение движка, включение может быть и автоматом плавно и с кнопок вручную, а выключение всегда - иначе будет авария
запрограммировать можно хоть чорта лысого, но это противоречит желанию управлять вручную.
Если сигнала от контроллера нет, то движок остановлен, так? И как эта ситуация алгоритмически отличается от простого желания управлять руками?
Есть варианты: например прошло время, или дополнительная кнопка, или еще что-то, но нужно определить, чем ситуации различны.
Вот такой вариант поведения.
1. Если из выключенного состояния мотор запущен руками, то система не реагирует на сигнал от "дятла", пока скорость не выставлена в НОЛЬ;
2. Если мотор запущен в автомате от "дятла", то, даже если скорость изменить руками, при выключении "дятла" мотор остановится.
Вроде все, как ты хотел?
#include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27,16,2); const uint32_t stepTime = 10; //время шага увеличения мощности const byte stepPWM = 1; //величина приращения на шаг const byte On = 1; const byte Off = 0; const byte UNNOWN = 0xff; const byte SwitchOn_level = LOW; const byte SwitchOff_level = HIGH; const byte plusBtn = 0; const byte minusBtn = 1; const byte NSwitches = 2; const byte Switch2pin[NSwitches] = {2,3}; const byte motorPin = 9; const byte grblPin = 5; const uint32_t intervalDebonce = 20; void setup() { lcd.init(); lcd.setCursor(0,0); lcd.print(" SPEED = "); pinMode(motorPin,OUTPUT); for (byte i = 0; i < NSwitches; i++) pinMode (Switch2pin[i],INPUT_PULLUP); } void loop() { const byte sAuto = 0; const byte sManu = 1; const byte sManu1 = 2; static int motor = 0; static byte state = sAuto; static uint32_t om = millis(); uint32_t nm = millis(); Switches(0); //регулярное обновление значений кнопок if (state != sManu && digitalRead(grblPin) == LOW) { state = sManu; motor = 0; } if (state == sAuto) { //в состоянии Авто - растем, как назначено if (nm - om > stepTime) { motor += stepPWM; om = nm; } if (Switches(plusBtn) == On || Switches(minusBtn) == On) state = sManu1; //если состояние Автои нажата кнопка - переходим в ручное управление } else { //ручное управление if (Switches( plusBtn) == On) motor += stepPWM; if (Switches(minusBtn) == On) motor -= stepPWM; if (motor == 0 && digitalRead(grblPin) == HIGH) state = sAuto; } if (motor < 0) motor = 0; if (motor > 255) motor = 255; // ограничения значений analogWrite(motorPin,motor); lcd.setCursor(9,0); lcd.print(motor); lcd.print(" "); lcd.setCursor(0,1); for (byte i = 0; i < 16; i++) if (i < (motor >> 4)) lcd.write(255); else lcd.write(32); } byte Switches(byte __switch) { static uint32_t om = millis(); uint32_t nm = millis(); static byte Switch [NSwitches] = {0}; byte i; for (i = 0; i < NSwitches; i++) if (Switch[i] != digitalRead(Switch2pin[i])) { om = nm; Switch[i] = digitalRead(Switch2pin[i]); } if (nm - om > intervalDebonce) if (Switch[__switch] == SwitchOn_level) return On; else return Off; return UNNOWN; }спасибо , отлично!, переформатили полностью мой код, теперь работает как хотелось, ток ничё не пойму, что за что отвечает?
Перед сном увидел. Сейчас отвечу, если еще что, то завтра. Я старый больной человек. ;))) Мне еще час на кислороде перед сном лежать.
Да, ты угадал. x>>4 то же самое, что и x/16. Но 256/16=16. Это вместо map().
255 - код символа "черный квадрат", который ты зачем-то пытался сделать пользовательский. Он и так есть в стандартном знакогенераторе китайского экрана, да и нашего МЭЛТ тоже.
Да, уже совсем почти ушел, но нужно скзать, что мотором, типовым ардуиновским ШИМом - плохо управлять - гудит. 20 КГц - не обязательно, но 8-10 - было бы позитивно. Если не найдешь сам правильную библиотеку, то тут, на форуме, есть от ЕвгенияП ШИМ на любых частотах. Если и это не найдешь, я тебе завтра покажу, как это делать.
И силовой Мосфет драйвером рули. Это микросхема такая, Гугли "драйвер нижнего плеча MOSFET". Иначе при высокой частоте ШИМ, он греться начнет.
я себе собрал генератор DDS на ардуино, с этого форума, офигенный аппарат