плавный пуск DC мотора с ручной регулировкой оборотов( коряво работает)

condensator80
Offline
Зарегистрирован: 24.02.2018

Добрый день, форумчане! Прошу помощи или дельного совета по моей проблеме. Суть такова: есть китайский 775 движок на 150 Ватт, питается от 24 вольт( стоит в ЧПУ станке CNC 1610), ему нужно устройство плавного пуска- чтоб БП в защиту по току не уходил, и станок не подпрыгивал)). Решил собрать данное устройство на arduino, принцип работы следующий- при поступлении на 5 пин команды  включения шпинделя от платы станка, на 9 выводе ардуинки появляется 8 бит  ШИМ ( на затвор мощного полевика), его значение растёт до максимума(255) в течении какого-то времени( движок набирает обороты), и держится, пока на 5 пине уровень 5 вольт. как только на 5 пине 0, шим выключается. это всё одновременно с ростом шим выводится в виде аналоговой шкалы( прогресс-бар) на дисплей 1602, есть 2 кнопки + и - для регулировки скорости вручную после выхода в режим. А теперь проблема- оно не работает как написано: либо только вручную, либо плавный старт, но без индикации. Скетч прилагаю, сильно не пинайте( что-то писал сам, что-то взял из готового)

condensator80
Offline
Зарегистрирован: 24.02.2018
//запуск шпинделя с задержкой, с выводом на дисплей в виде аналоговой шкалы и корректировкой скорости на ходу, 
//только оно не работает как хотелось, либо старт плавно, либо только вручную



#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 (символ пробела)
                                 //  После вывода каждого символа, курсор дисплея сдвигается автоматически
      }
//}
//}
//}                         

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Похоже очередной изобретатель "вечного двигателя" не знакомый с законами физики.

condensator80
Offline
Зарегистрирован: 24.02.2018

qwone пишет:

Похоже очередной изобретатель "вечного двигателя" не знакомый с законами физики.

не понял данного высказывания?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Потому  что есть целый курс института, как регулировать двигатели постояного тока. На который вы похоже забили.

condensator80
Offline
Зарегистрирован: 24.02.2018

хорошо, тогда как обеспечить плавный старт движка с использованием контроллера? есть что конкретно по делу сказать? как, по вашему в станке обороты движка регулируются, есть там мощный полевик стоит без радиатора? ШИМ, причём довольно шустрый. Обгадить каждый может, а вот подсказать - тут надо мозг включать

condensator80
Offline
Зарегистрирован: 24.02.2018

это ручная регулировка, заполнение шкалы по мере возрастания скорости

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ну вы видели движки на промышленных станках. Мощность размеры.Почему стоят коробки переключения скоростей.  А теперь двигатели для вентиляции. Там ничего этого нет.  Вы что ставите движок для обдува? или сверления. Похоже для сверления. И что я вижу. маломощный игрушечный моторчик, игрушечный контроллер и похоже "игрушечный мозг" ,а желания и требования уже не игрушечные.

ПС: Куйня у вас выйдет со всем этим. 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

condensator80 пишет:

как обеспечить плавный старт движка

Взять специализированную микросхему "драйвер коллеторного DC мотора" работающую с нуными током и напряжением и уже ею управлять из контроллера. Микросхему можно выбрать, поковырявшись по спискам производителей и посравнивав хракетиристики и цены. Пример подобного списка

Это будет не на коленке из дерьма и палок, а нормальное профессиональное решение.

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Уважаемый, 33 и 43 строка в взаимоисключающие, поэтому есть смысл в 43 строке использовать else. А вот автоматического увеличения скорости я так и не увидел...

condensator80
Offline
Зарегистрирован: 24.02.2018

готовое решение, купленное в магазине- напрочь убивает желание заниматься творчеством, проще тогда всё покупать, следуя Вашей логике. А если кто не в теме, что это и зачем нужно- вот ссторонняя ссылка, там и видео есть( делаю подобное устройство)http://www.cnc-club.ru/forum/viewtopic.php?f=147&t=19734 там в каждый G-код добавляется хренова гора строк.....но зачем это нужно каждый раз писать

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

брат! Ты попал на мрачное состояние форумчан. ;) Конечно DC мотор прекрасно регулируется ШИМом, и вполне себе через полевик. Только код у тебя полное говно, но это можно поправить.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

condensator80 пишет:

готовое решение, купленное в магазине- напрочь убивает желание заниматься творчеством, проще тогда всё покупать,   

.....но зачем это нужно каждый раз писать

Так вы за творчество или за упрощение.  Творчество это как раз много раз писать, много раз делать и еще очень много дмать. А упрощение купил и решил. Вы уж определитесь , а то "беремена ,но чуть чуть не очень"(с)

ВН
Offline
Зарегистрирован: 25.02.2016

if(digitalRead(pinGRBL)==HIGH) {//если на входе сигнал от "дятла"

- тут остается тока гадать, что там за сигнал и с чем его ...

- ТС, мы же тут не ясновидящие, чтобы к нам с неба падали алгоритмы работы вашего станка

//if(state) {//не вдуплил нах оно тут нужно

-вот уже подозреваю, что это состояние старт или работа

condensator80
Offline
Зарегистрирован: 24.02.2018

сигнал от " дятла" это тупо логическая 1- включить шпиндель(дятел- это плата станка woodpecker)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

condensator80 пишет:

готовое решение, купленное в магазине- напрочь убивает желание заниматься творчеством

А готовое решение, выклянченное на форуме - наоборот, способствует творческому росту!

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Попробуйте так. из за отсутствия библилтеки - не прверял

//запуск шпинделя с задержкой, с выводом на дисплей в виде аналоговой шкалы и корректировкой скорости на ходу, 
//только оно не работает как хотелось, либо старт плавно, либо только вручную



#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 (символ пробела)
  //  После вывода каждого символа, курсор дисплея сдвигается автоматически
}
//}
//}
//}                         

 

condensator80
Offline
Зарегистрирован: 24.02.2018

код рабочий, только всё вместе не работает, вот тут и прошу помочь, разобраться с кодом, указать на косяки, готовое решение никто не будет писать под конкретную задачу

 

condensator80
Offline
Зарегистрирован: 24.02.2018

 vosara ,щас попробую запустить

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ну понятие что такое рабочий код , что говнокод, а что простое гавно индивидуально.
Рассказывать Вам про цифровой автомат и решение через него- зачем. Это же придушит ваше "творчество" на корню.  

condensator80
Offline
Зарегистрирован: 24.02.2018

в коде включается реле потому, что  у меня при плавном запуске прогресс бар  ничего не отображает, только при управлении с кнопок

ВН
Offline
Зарегистрирован: 25.02.2016

condensator80 пишет:
сигнал от " дятла" это тупо логическая 1- включить шпиндель(дятел- это плата станка woodpecker)

т а если шпиндель вращается, там что 0 ?

 

condensator80
Offline
Зарегистрирован: 24.02.2018

нет, там  "0" только когда приходит команда выключить шпиндель. пришлось извращаться с реле, ибо не пойму как это совместно запустить

ВН
Offline
Зарегистрирован: 25.02.2016

condensator80 пишет:
  у меня при плавном запуске прогресс бар  ничего не отображает, только при управлении с кнопок

не отображает так что с того, зачем отображать?

можете понизить стартовые обороты, выставить их не макс, а средние, а потом уже рулить ручками.

непонятно, зачем создавать себе проблему на ровном месте

судя по коду, двигатель на разгон должн выходить около 1,5 сек и из-за этого нужно городить огород?

 

 

condensator80
Offline
Зарегистрирован: 24.02.2018

ну, не умею я писать красивые коды, не умею.....хотелось и плавный старт и регулировку с отображением процесса, не используя разные там хитрые микросхемы и промышленные решения. изначально задумка была с энкодером, но там вообще тёмный лес с этими прерываниями и портами

condensator80
Offline
Зарегистрирован: 24.02.2018

vosara пишет:

Попробуйте так. из за отсутствия библилтеки - не прверял

 

Спасибо за поправку-попробовал, работает,отображается и движок пускается, только быстро....

понял в чём была моя ошибка, надо было везде использовать ранее объявленные переменные i и speedMot, а не создавать новые, INPUT_PULLUP я не ставил у себя, потому что подтяжка уже внешними резисторами на портах.

condensator80
Offline
Зарегистрирован: 24.02.2018

стал на вывод ШИМ осциллографом, там уровень резко возрастает при подаче управляющего сигнала, вручную- там именно шим, но без управляющего сигнала, не работает. Как сделать   if(digitalRead(pinGRBL)==HIGH) {//если на входе сигнал от "дятла"- необязательным условием запуска? ибо контроллер в цикле ждёт пока не появится этот сигнал, и соответственно ничё не работает

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

condensator80 пишет:

стал на вывод ШИМ осциллографом, там уровень резко возрастает при подаче управляющего сигнала, вручную- там именно шим, но без управляющего сигнала, не работает. Как сделать   if(digitalRead(pinGRBL)==HIGH) {//если на входе сигнал от "дятла"- необязательным условием запуска? ибо контроллер в цикле ждёт пока не появится этот сигнал, и соответственно ничё не работает

А ты в ручном режиме хочешь без контроллера тоже управлять?  Я не понял.

condensator80
Offline
Зарегистрирован: 24.02.2018

иногда бывает нужно, без запуска G-кода, включить движок

bwn
Offline
Зарегистрирован: 25.08.2014

condensator80 пишет:

стал на вывод ШИМ осциллографом, там уровень резко возрастает при подаче управляющего сигнала, вручную- там именно шим, но без управляющего сигнала, не работает. Как сделать   if(digitalRead(pinGRBL)==HIGH) {//если на входе сигнал от "дятла"- необязательным условием запуска? ибо контроллер в цикле ждёт пока не появится этот сигнал, и соответственно ничё не работает

Ну, дык, алгоритм писать, аднака.

condensator80
Offline
Зарегистрирован: 24.02.2018

bwn пишет:

Ну, дык, алгоритм писать, аднака.

ну дык он написан, ток кривой, как .......

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

condensator80 пишет:

ну дык он написан, ток кривой, как .......

Не, уважаемый, написана кривая программа, а алгоритм как раз не написан. Алгоритм - это, в идеале, такая схема с квадратиками и ромбиками, а также связи между ними. Ромбик - "дятел стукнул?" -ДА -НЕТ, на ДА прямоугольник "Включаем реле, включаем ШИМ" и т.д.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

condensator80 пишет:

иногда бывает нужно, без запуска 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;
}

 

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Сейчас подправил, должен работать правильно. Пробуйте и анализируйте

//запуск шпинделя с задержкой, с выводом на дисплей в виде аналоговой шкалы и корректировкой скорости на ходу, 
//только оно не работает как хотелось, либо старт плавно, либо только вручную



#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 (символ пробела)
    //  После вывода каждого символа, курсор дисплея сдвигается автоматически
  }
}

 

bwn
Offline
Зарегистрирован: 25.08.2014

Он, либо есть, либо нет. Кривого алгоритма не бывает, бывает поток сознания. А значит, этот поток надо переделать в алгоритм, исключив все неопределенности.

P/S Пока корябал, уже ответили.

condensator80
Offline
Зарегистрирован: 24.02.2018

спасибо, буду пробовать и анализировать

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Я так понял что ручное управление выполняется только когда станок уже запущен, а если надо в выключеном состоянии запустить ручное то надо немного подправить код. Пишите

Гриша
Offline
Зарегистрирован: 27.04.2014

condensator80 пишет:

стал на вывод ШИМ осциллографом, там уровень резко возрастает при подаче управляющего сигнала, вручную- там именно шим.

попробуйте для себя составить блоксхему алгоритма работы, все состояния системы в ней отразить. ИМХО. вы пока не представляете всей логики, которая вам нужна, а если бы представляли попытались бы впихнуть ее в код.

напишите кусок кода с плавным разгоном и торможением до установленого потенциометром значения, что бы при старте не рвал с места, а плавно набирал. Используйсте какой-нибудь таймер, ну на край делей.  

(из-за делей будут проблемы с кнопками)

Вам бы разделить вашу задачу на части, и научиться писать код (понимать что пишете) для каждого элемента. 

condensator80
Offline
Зарегистрирован: 24.02.2018

wdrakula пишет:

Тут, если сигнал от контроллера пропал, значение мощности остается на месте для ручного изменения и если появился - тоже, расти начнет с того же места, где была в момент включения "дятла", как ты его назвал.

 

не совсем. Пропадание сигнала-обязательное выключение движка, включение может быть и автоматом плавно и с кнопок вручную, а выключение всегда - иначе будет авария

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

condensator80 пишет:

wdrakula пишет:

Тут, если сигнал от контроллера пропал, значение мощности остается на месте для ручного изменения и если появился - тоже, расти начнет с того же места, где была в момент включения "дятла", как ты его назвал.

 

не совсем. Пропадание сигнала-обязательное выключение движка, включение может быть и автоматом плавно и с кнопок вручную, а выключение всегда - иначе будет авария

запрограммировать можно хоть чорта лысого, но это противоречит желанию управлять вручную.

Если сигнала от контроллера нет, то движок остановлен, так? И как эта ситуация алгоритмически отличается от простого желания управлять руками?

Есть варианты: например прошло время, или дополнительная кнопка, или еще что-то, но нужно определить, чем ситуации различны.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Вот такой вариант поведения.

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;
}

 

condensator80
Offline
Зарегистрирован: 24.02.2018

спасибо , отлично!, переформатили полностью мой код, теперь работает как хотелось, ток ничё не пойму, что за что отвечает?

condensator80
Offline
Зарегистрирован: 24.02.2018
 
lcd.setCursor(0,1);
    
  for (byte i = 0; i < 16; i++)
    if (i < (motor >> 4)) lcd.write(255);
    else lcd.write(32);
 этот кусок кода отвечает за аналоговую шкалу, как я понимаю?
wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

condensator80 пишет:

 
lcd.setCursor(0,1);
    
  for (byte i = 0; i < 16; i++)
    if (i < (motor >> 4)) lcd.write(255);
    else lcd.write(32);
 этот кусок кода отвечает за аналоговую шкалу, как я понимаю?

Перед сном увидел. Сейчас отвечу, если еще что, то завтра. Я старый больной человек. ;))) Мне еще час на кислороде перед сном лежать.

Да, ты угадал. x>>4 то же самое, что и x/16. Но 256/16=16. Это вместо map().

255 - код символа "черный квадрат", который ты зачем-то пытался сделать пользовательский. Он и так есть в стандартном знакогенераторе китайского экрана, да и нашего МЭЛТ тоже.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Да, уже совсем почти ушел, но нужно скзать, что мотором, типовым ардуиновским ШИМом - плохо управлять - гудит. 20 КГц - не обязательно, но 8-10 - было бы позитивно. Если не найдешь сам правильную библиотеку, то тут, на форуме, есть от ЕвгенияП ШИМ на любых частотах. Если и это не найдешь, я тебе завтра покажу, как это делать.

И силовой Мосфет драйвером рули. Это микросхема такая, Гугли "драйвер нижнего плеча MOSFET". Иначе при высокой частоте ШИМ, он греться начнет.

condensator80
Offline
Зарегистрирован: 24.02.2018

я себе собрал генератор DDS на ардуино, с этого форума, офигенный аппарат