Прошу помощи (проблема с одновременной работой шаговых двигателей)

sheff
Offline
Зарегистрирован: 14.11.2017

Всем привет! 

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

Повторюсь, я не программист и свой скетч собрал методом ctrl+C - ctrl+V :) попросту подходящие куски разных скетчей слепил воедино.
Проблема заключается в следующем: 
 Есть рулонные шторы к которым я присоединил шаговые моторчики 28BYJ-48 с драйвером ULN2003.

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

Можно ли увеличить скорость вращения моторов? Если да, то как?

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

Схема подключения.

[code]
#include <EEPROM.h>

#include <SoftwareSerial.h>//для порта
 
// Определение пинов для управления двигателем
#define motorPin1  22 // IN1 на 1-м драйвере ULN2003
#define motorPin2  23 // IN2 на 1-м драйвере ULN2003
#define motorPin3  24 // IN3 на 1-м драйвере ULN2003
#define motorPin4  25 // IN4 на 1-м драйвере ULN2003
#define motorPin5  26 // IN1 на 2-м драйвере ULN2003
#define motorPin6  27 // IN2 на 2-м драйвере ULN2003
#define motorPin7  28 // IN3 на 2-м драйвере ULN2003
#define motorPin8  29 // IN4 на 2-м драйвере ULN2003

#define kn_menu 9   //кнопка меню (выбор шторы)
#define kn_open 10  //кнопка "открыть"
#define kn_close 11 //кнопка "закрыть"

const int led1 = 7; //индикатор шторы 1
const int led2 = 6; //индикатор шторы 2

const int ton = 12;//пищалка
//Таймеры
long previousMillisSerial = 0; // время, когда состояние обновлялось
long intervalSerial = 1000; // интервал для вывода данных

//Переменные
int reg=1;  //Режим работы штор (1 или 2 штора)
int reg_k=0;  //Режим калибровки "0" (1 или 2 штора)
int flag_o=0; // чтобы исключить ошибочное нажатие кнопки "вверх"
int flag_c=0; // чтобы исключить ошибочное нажатие кнопки "вниз"
int motorSpeed = 1000; // пауза между шагами двигателя, чем меньше, тем быстрей скорость (1000 оптимально)
boolean start = false;  //если "True" двигатель работает, иначе остановлен
boolean kalibr=false; // если "True" включена калибровка "0"
bool     button_state      = false; //для короткого нажатия кнопки "меню"
bool     button_long_state = false; //для длинного нажатия кнопки "меню"
uint32_t ms_button = 0; // таймер для отслеживания длительности нажатия кнопки "меню"
// переменные для счета шагов двигателя
int r=0;
int pos1=0;
int max1=7185;// количество шагов для полного закрытия шторы 1
int min1=0;        
int pos2=0;
int max2=6950;// количество шагов для полного закрытия шторы 2
int min2=0;        
//команды для управления двигателями
int lookup_1[8] = {
  B01000, B01100, B00100, B00110, B00010, B00011, B00001, B01001};
int lookup_2[8] = {
  B01000, B01100, B00100, B00110, B00010, B00011, B00001, B01001};

// чтение
int EEPROM_int_read(int addr) {   
  byte raw[2];
  for(byte i = 0; i < 2; i++) raw[i] = EEPROM.read(addr+i);
  int &num = (int&)raw;
  return num;
}
// запись
void EEPROM_int_write(int addr, int num) {
  if (EEPROM_int_read(addr)!= num){//если сохраняемое отличается
  byte raw[2];
  (int&)raw = num;
  for(byte i = 0; i < 2; i++) EEPROM.write(addr+i, raw[i]);
}
}

void setup(){
                             //назначение пинов для кнопок
    pinMode(kn_menu,INPUT);
    pinMode(kn_open,INPUT);
    pinMode(kn_close,INPUT);
                             //назначение пинов для светодиодов
    pinMode(led1,OUTPUT);   
    pinMode(led2,OUTPUT);   
    digitalWrite(led1,LOW);
    digitalWrite(led2,LOW);
                             //назначение пинов для двигателей
    pinMode(motorPin1, OUTPUT);
    pinMode(motorPin2, OUTPUT);
    pinMode(motorPin3, OUTPUT);
    pinMode(motorPin4, OUTPUT);
    pinMode(motorPin5, OUTPUT);
    pinMode(motorPin6, OUTPUT);
    pinMode(motorPin7, OUTPUT);
    pinMode(motorPin8, OUTPUT);

    pinMode(ton,OUTPUT);//пищалка
    Serial.begin(9600);
    if (EEPROM_int_read(4)!=1)
    {
      pos1=0;
      pos2=0;
    }
    else
    {
      pos1 = EEPROM_int_read(0);
      pos2 = EEPROM_int_read(2);
    }
}

// функция поворачивает мотор 1 против часовой стрелки.
void anticlockwise_1()
{
  for(int i = 0; i < 8; i++)
  {
    setOutput_1(i);
    delayMicroseconds(motorSpeed);
  }
}

// функция поворачивает мотор 1 по часовой стрелке.
void clockwise_1()
{
  for(int i = 7; i >= 0; i--)
  {
    setOutput_1(i);
    delayMicroseconds(motorSpeed);
  }
}
// функция поворачивает мотор 2 против часовой стрелки.
void anticlockwise_2()
{
  for(int j = 0; j < 8; j++)
  {
    setOutput_2(j);
    delayMicroseconds(motorSpeed);
  }
}

// функция поворачивает мотор 2 по часовой стрелке.
void clockwise_2()
{
  for(int j = 7; j >= 0; j--)
  {
    setOutput_2(j);
    delayMicroseconds(motorSpeed);
  }
}

 void setOutput_1(int out)
{
  digitalWrite(motorPin1, bitRead(lookup_1[out], 0));
  digitalWrite(motorPin2, bitRead(lookup_1[out], 1));
  digitalWrite(motorPin3, bitRead(lookup_1[out], 2));
  digitalWrite(motorPin4, bitRead(lookup_1[out], 3));
}

void setOutput_2(int out)
{
  digitalWrite(motorPin5, bitRead(lookup_2[out], 0));
  digitalWrite(motorPin6, bitRead(lookup_2[out], 1));
  digitalWrite(motorPin7, bitRead(lookup_2[out], 2));
  digitalWrite(motorPin8, bitRead(lookup_2[out], 3));
}


void Stop_motor_1()
{
            digitalWrite(motorPin1, LOW); //останавливаем мотор
            digitalWrite(motorPin2, LOW);
            digitalWrite(motorPin3, LOW);
            digitalWrite(motorPin4, LOW);  
}
void Stop_motor_2()
{
            digitalWrite(motorPin5, LOW); //останавливаем мотор
            digitalWrite(motorPin6, LOW);
            digitalWrite(motorPin7, LOW);
            digitalWrite(motorPin8, LOW);  
}
void Beep() //короткий звук, переключение шторы
{
  tone(ton,500,500);
  delay(200);
  noTone(ton);
}
void Beep_long()  //длинный звук, вход и выход из режима калибровки "0"
{
  tone(ton,200,1000);
  delay(200);
  noTone(ton);
}
 
void loop(){
//----------------------------------------------------------------------------------------------------------------
//Калибровка "0", Выбор шторы (1 или 2)
//----------------------------------------------------------------------------------------------------------------
   uint32_t ms    = millis();
   bool pin_state = digitalRead(kn_menu);
// Фиксируем нажатие кнопки "меню" (переключение шторы)  
   if( pin_state  == HIGH && !button_state && !kalibr && ( ms - ms_button ) > 50 ){
      button_state      = true;
      button_long_state = false;  
      ms_button         = ms;
   }
// Фиксируем длинное нажатие кнопки "меню"(вход в режим калибровки "0")  
   if( pin_state  == HIGH && !button_long_state && !kalibr && ( ms - ms_button ) > 2000 ){
      button_long_state = true;
      kalibr=true;  //включаем режим калибровки "0"
      EEPROM_int_write(4, 0); // адрес 4 (+2 байта)если калибровка не проведена, сохраняем 0
      reg=0;
      reg_k=0;
      Beep_long();
      Serial.println("Long press key");    
   }
// Фиксируем отпускание кнопки (переключение меню в работе)   
   if( pin_state == LOW && button_state && !kalibr && ( ms - ms_button ) > 50  ){
      button_state      = false;   
      ms_button         = ms;
      reg++;
      Beep();
      delay(200);
      if (reg>3)
      {reg=1;}
      if( !button_long_state )Serial.println("Press key");
   }
// Фиксируем нажатие кнопки "меню" (переключение штор в режиме калибровки)  
   if( pin_state  == HIGH && !button_state && kalibr && ( ms - ms_button ) > 50 ){
      button_state      = true;
      button_long_state = false;  
      ms_button         = ms;
   }
// Фиксируем длинное нажатие кнопки (выход из режима калибровки "0")  
   if( pin_state  == HIGH && !button_long_state && kalibr && ( ms - ms_button ) > 2000 ){
      button_long_state = true;
      kalibr=false;
      EEPROM_int_write(4, 1); // адрес 4 (+2 байта)если калибровка проведена, сохраняем 1
      reg=0;
      reg_k=0;
      Beep_long();
      pos1=0; // устанавливаем позицию шторы 1 как "0" 
      pos2=0; // устанавливаем позицию шторы 2 как "0"
      Serial.println("Long press key kalibr");    
   }
   //переключение меню в режиме калибровки "0"
   if( pin_state == LOW && button_state && kalibr && ( ms - ms_button ) > 50  ){
      button_state      = false;   
      ms_button         = ms;
      reg_k++;
      Beep();
      delay(200);
      if (reg_k>2)
      {reg_k=1;}
      if( !button_long_state )Serial.println("Press key kalibr");
   }

  
//----------------------------------------------------------------------------------------------------------------
//Выбор шторы (1 или 2)
//----------------------------------------------------------------------------------------------------------------
  if (reg==1)
    {                                                           //включаем 1 светодиод и выключаем 2
      digitalWrite(led1,HIGH);
      digitalWrite(led2,LOW);
    }
  if (reg==2)
    {                                                       //включаем 2 светодиод и выключаем 1
      digitalWrite(led2,HIGH);
      digitalWrite(led1,LOW);
    }
  if (reg==3)
    {                                                       //включаем 2 светодиода
      digitalWrite(led2,HIGH);
      digitalWrite(led1,HIGH);
    }
    if (reg_k==1)
    {                                                       //включаем 1 светодиод и выключаем 2
      digitalWrite(led1,HIGH);
      digitalWrite(led2,LOW);      
    }
  if (reg_k==2)
    {                                                       //включаем 2 светодиод и выключаем 1
      digitalWrite(led2,HIGH);
      digitalWrite(led1,LOW);
    }

//--------------------------------------------------------------------------
//Управляем двигателями в режиме работа
//--------------------------------------------------------------------------
//закрываем шторы
  if (digitalRead(kn_open)==1 && start==false && flag_o==0 && !kalibr)
      {
       flag_o=1; 
       start=true;
       delay(500);
        switch (reg)
        {
          //---------------------------------------------------------------------------------------------------------------------------------------------
          //Закрываем первую штору. Если во время движения нажимается любая кнопка, то штора останавливается, иначе закрывается до максимального значения
          //---------------------------------------------------------------------------------------------------------------------------------------------
          case 1:
          for (int r=pos1; r<max1+1;r++)
          {
          anticlockwise_1(); // Мотор 1 крутим влево.
          if (digitalRead(kn_open)==1 || digitalRead(kn_close)==1 || digitalRead(kn_menu)==1)
          {
            Stop_motor_1();//останавливаем мотор
            pos1=r;
            EEPROM_int_write(0, pos1); // адрес 0 (+2 байта)
            start=false;
            break;
          }
          else 
          {
            Stop_motor_1();//останавливаем мотор
            pos1=r;
            EEPROM_int_write(0, pos1); // адрес 0 (+2 байта)
          }
          start=false;
          }
          break;
          //---------------------------------------------------------------------------------------------------------------------------------------------
          //Закрываем вторую штору. Если во время движения нажимается любая кнопка, то штора останавливается, иначе закрывается до максимального значения
          //---------------------------------------------------------------------------------------------------------------------------------------------
          case 2:
          for (int r=pos2; r<max2+1;r++)
          {
          clockwise_2(); //Мотор 2 крутим вправо.
          if (digitalRead(kn_open)==1 || digitalRead(kn_close)==1 || digitalRead(kn_menu)==1)
          {
            Stop_motor_2();//останавливаем мотор
            pos2=r;
            EEPROM_int_write(2, pos2); // адрес 2 (+2 байта)
            start=false;
            break;
          }
          else 
          {
            Stop_motor_2();//останавливаем мотор
            pos2=r;
            EEPROM_int_write(2, pos2); // адрес 2 (+2 байта)
          }
          start=false;
          }
          break;
          //---------------------------------------------------------------------------------------------------------------------------------------------
          //Закрываем обе шторы. Если во время движения нажимается любая кнопка, то шторы останавливаются, иначе закрываются до максимального значения.
          //Вторая штора останавливается первой, потому что для неё максимальное значение меньше чем у первой. Вторая штора продолжает движение до своего
          //максимального значения.
          //---------------------------------------------------------------------------------------------------------------------------------------------
          case 3:
          //---------------------------------------------------------------------------------------------------------------------------------------------
          if (pos1<pos2)//если вторая штора ниже первой, то даем команду первой шторе сравняться со второй
          {
            for (int r=pos1; r<pos2+1;r++)
            {
              anticlockwise_1();
          if (digitalRead(kn_open)==1 || digitalRead(kn_close)==1 || digitalRead(kn_menu)==1)
          {
            Stop_motor_1();//останавливаем мотор
            pos1=r;
            EEPROM_int_write(0, pos1); // адрес 0 (+2 байта)
            start=false;
            break;
          }
          else 
          {
            Stop_motor_1();//останавливаем мотор
            pos1=r;
            EEPROM_int_write(0, pos1); // адрес 2 (+2 байта)
          }
              
            }
          }
          //---------------------------------------------------------------------------------------------------------------------------------------------
          if (pos1>pos2)//если первая штора ниже второй, то даем команду второй шторе сравняться с первой
          {
            for (int r=pos2; r<pos1+1;r++)
            {
              clockwise_2();
          if (digitalRead(kn_open)==1 || digitalRead(kn_close)==1 || digitalRead(kn_menu)==1)
          {
            Stop_motor_2();//останавливаем мотор
            pos2=r;
            EEPROM_int_write(2, pos2); // адрес 2 (+2 байта)
            start=false;
            break;
          }
          else 
          {
            Stop_motor_2();//останавливаем мотор
            pos2=r;
            EEPROM_int_write(2, pos2); // адрес 2 (+2 байта)
          }
              
            }
          }
          //---------------------------------------------------------------------------------------------------------------------------------------------
          if (pos1==pos2)//если шторы находятся на одном уровне
          {
          for (int r=pos1; r<max2+1;r++)//даем команду на оба мотора
          {
            anticlockwise_1();
            clockwise_2();
          if (digitalRead(kn_open)==1 || digitalRead(kn_close)==1 || digitalRead(kn_menu)==1)//если нажата любая кнопка, останавливаем моторы
          {
            Stop_motor_1();//останавливаем мотор
            Stop_motor_2();//останавливаем мотор
            //сохраняем позиции штор
            pos1=r;
            pos2=r;
            EEPROM_int_write(0, pos1); // адрес 0 (+2 байта)
            EEPROM_int_write(2, pos2); // адрес 2 (+2 байта)
            start=false;
            break;
          }
          else 
          {
            Stop_motor_1();//останавливаем мотор
            Stop_motor_2();//останавливаем мотор
            pos1=r;
            pos2=r;
            EEPROM_int_write(0, pos1); // адрес 0 (+2 байта)
            EEPROM_int_write(2, pos2); // адрес 2 (+2 байта)
          }
            start=false;
          }
          }
          //-------------------------------------------------------------------------------------
          if (pos1==max2 || pos2==max2)//если шторы достигли максимального значения второй шторы
          {
          for (int r=pos1; r<max1+1;r++)//даем команду первому мотору на закрытие
          {
            anticlockwise_1();
          if (digitalRead(kn_open)==1 || digitalRead(kn_close)==1 || digitalRead(kn_menu)==1)
          {
            Stop_motor_1();//останавливаем мотор
            pos1=r;
            EEPROM_int_write(0, pos1); // адрес 0 (+2 байта)  
            start=false;
            break;
          }
          else 
          {
            Stop_motor_1();//останавливаем мотор
            pos1=r;
            EEPROM_int_write(0, pos1); // адрес 0 (+2 байта)
          }
            start=false;
          }
            
          }
          break;
        }
      }
  if (digitalRead(kn_open)==0 && flag_o==1 && !kalibr)
    {
      flag_o=0;
      flag_c=0;
      delay(500);
    }


//открываем шторы
  if (digitalRead(kn_close)==1 && start==false && flag_c==0 && !kalibr)
      {
       flag_c=1; 
       start=true;
       delay(500);
        switch (reg)
        {
          //---------------------------------------------------------------------------------------------------------------------------------------------
          //Открываем первую штору. Если во время движения нажимается любая кнопка, то штора останавливается, иначе открывается до минимального значения
          //---------------------------------------------------------------------------------------------------------------------------------------------
          case 1:
          for (int r=pos1; r>min1-1;r--)
          {
          clockwise_1(); // Мотор 1 крутим вправо.
          if (digitalRead(kn_open)==1 || digitalRead(kn_close)==1 || digitalRead(kn_menu)==1)
          {
            Stop_motor_1();//останавливаем мотор
            pos1=r;
            EEPROM_int_write(0, pos1); // адрес 0 (+2 байта)
            start=false;
            break;
          }
          else
          {
            Stop_motor_1();//останавливаем мотор
            pos1=r;
            EEPROM_int_write(0, pos1); // адрес 0 (+2 байта)
          }
            start=false;
          }
          break;
          //---------------------------------------------------------------------------------------------------------------------------------------------
          //Открываем вторую штору. Если во время движения нажимается любая кнопка, то штора останавливается, иначе открывается до минимального значения
          //---------------------------------------------------------------------------------------------------------------------------------------------
          case 2:
          for (int r=pos2; r>min2-1;r--)
          {
          anticlockwise_2(); //Мотор 2 крутим влево.
          if (digitalRead(kn_open)==1 || digitalRead(kn_close)==1 || digitalRead(kn_menu)==1)
          {
            Stop_motor_2();//останавливаем мотор
            pos2=r;
            EEPROM_int_write(2, pos2); // адрес 2 (+2 байта)
            start=false;
            break;
          }
          else
          {
            Stop_motor_2();//останавливаем мотор
            pos2=r;
            EEPROM_int_write(2, pos2); // адрес 2 (+2 байта)
          }
            start=false;
          }
          break;
          //---------------------------------------------------------------------------------------------------------------------------------------------
          //Открываем обе шторы. Если во время движения нажимается любая кнопка, то шторы останавливаются, иначе открываются до минимального значения.
          //Первая штора сравнивается со второй и потом обе открываются одновременно до минимального значения.
          //---------------------------------------------------------------------------------------------------------------------------------------------
          case 3:
          //---------------------------------------------------------------------------------------------------------------------------------------------
          if (pos1>pos2)
          {
          for (int r=pos1; r>pos2-1;r--)
          {
          clockwise_1(); // Мотор 1 крутим вправо.
          if (digitalRead(kn_open)==1 || digitalRead(kn_close)==1 || digitalRead(kn_menu)==1)
          {
            Stop_motor_1();//останавливаем мотор
            pos1=r;
            EEPROM_int_write(0, pos1); // адрес 0 (+2 байта)
            start=false;
            break;
          }
          else
          {
            Stop_motor_1();//останавливаем мотор
            pos1=r;
            EEPROM_int_write(0, pos1); // адрес 0 (+2 байта)
          }
            start=false;
          }
          }
          //-------------------------------------------------------------------------------------------------------------------------------------------
          if (pos1<pos2)
          {
          for (int r=pos2; r>pos1-1;r--)
          {
          anticlockwise_2(); //Мотор 2 крутим влево.
          if (digitalRead(kn_open)==1 || digitalRead(kn_close)==1 || digitalRead(kn_menu)==1)
          {
            Stop_motor_2();//останавливаем мотор
            pos2=r;
            EEPROM_int_write(2, pos2); // адрес 2 (+2 байта)
            start=false;
            break;
          }
          else
          {
            Stop_motor_2();//останавливаем мотор
            pos2=r;
            EEPROM_int_write(2, pos2); // адрес 2 (+2 байта)
          }
            start=false;
          }
            
          }
          //-------------------------------------------------------------------------------------------------------------------------------------------
          if (pos1==pos2)
          {
          for (int r=pos1; r>min1-1;r--)
          {
          clockwise_1(); // Мотор 1 крутим вправо.
          anticlockwise_2(); //Мотор 2 крутим влево.
          if (digitalRead(kn_open)==1 || digitalRead(kn_close)==1 || digitalRead(kn_menu)==1)
          {
            Stop_motor_1();//останавливаем мотор
            Stop_motor_2();//останавливаем мотор
            pos1=r;
            pos2=r;
            EEPROM_int_write(0, pos1); // адрес 0 (+2 байта)
            EEPROM_int_write(2, pos2); // адрес 2 (+2 байта)
            start=false;
            break;
          }
          else
          {
            Stop_motor_1();//останавливаем мотор
            Stop_motor_2();//останавливаем мотор
            pos1=r;
            pos2=r;
            EEPROM_int_write(0, pos1); // адрес 0 (+2 байта)
            EEPROM_int_write(2, pos2); // адрес 2 (+2 байта)
          }
            start=false;
          }
            
          }
          //-------------------------------------------------------------------------------------------------------------------------------------------
          break;
        }
      }
  if (digitalRead(kn_close)==0 && flag_c==1 && !kalibr)
    {
      flag_o=0;
      flag_c=0;
      delay(500);
    }


//--------------------------------------------------------------------------
//Управляем двигателями в режиме калибровка
//--------------------------------------------------------------------------
//закрываем шторы
  if (digitalRead(kn_open)==1 && kalibr && reg_k==1)  //пока кнопка "вверх" нажата в режиме калибровки "0", поднимаем штору 1
      {
          anticlockwise_1(); // Мотор 1 крутим влево.
          }
  if (digitalRead(kn_open)==1 && kalibr && reg_k==2)  //пока кнопка "вверх" нажата в режиме калибровки "0", поднимаем штору 2
      {
          clockwise_2(); // Мотор 2 крутим вправо.
          }
  if (digitalRead(kn_close)==1 && kalibr && reg_k==1) //пока кнопка "вниз" нажата в режиме калибровки "0", опускаем штору 1
      {
          clockwise_1(); // Мотор 1 крутим вправо.
          }
  if (digitalRead(kn_close)==1 && kalibr && reg_k==2) //пока кнопка "вверх" нажата в режиме калибровки "0", опускаем штору 2
      {
          anticlockwise_2(); // Мотор 2 крутим влево.
          }
  if (digitalRead(kn_close)==0 && digitalRead(kn_open)==0 && kalibr)  //если обе кнопки отжаты, останавливаем двигатели
  {
            Stop_motor_1();//останавливаем мотор
            Stop_motor_2();//останавливаем мотор
          }


//  вывод информации в порт (для отслеживания позиций двигателей в режиме отладки и подсчета максимальных позиций штор)
unsigned long currentMillisSerial = millis();                       // текущее время в миллисекундах
  
  if(currentMillisSerial - previousMillisSerial > intervalSerial)
  {
                                                                 // сохраняем последний момент, когда делался замер
    previousMillisSerial = currentMillisSerial;
     Serial.begin(9600);
     Serial.print("Позиция_1 ");
     Serial.print(pos1);
     Serial.print(" Позиция_2 ");
     Serial.print(pos2);
     Serial.print(" Ячейка_1 ");
     Serial.print(EEPROM_int_read(0));
     Serial.print(" Ячейка_2 ");
     Serial.print(EEPROM_int_read(2));
     Serial.print(" Калибровка ");
     Serial.println(EEPROM_int_read(4));

  }    
}
[/code]

 

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

sheff пишет:
Уважаемые форумчане, прошу сильно не пинать, никогда не занимался программированием, поэтому многое лежит за гранью моего понимания. Повторюсь, я не программист и свой скетч собрал методом ctrl+C - ctrl+V :) попросту подходящие куски разных скетчей слепил воедино.
И что вы хотите от остальных? Копаться в вашей простыне? Сделать макет в железе и проверить. Обучить вас проектированию таких систем?  Вы же не ребенок и должны понимать, что для того что бы написать коротенький рассказ, не достаточно знать русские буквы, а так же знать ,что есть знаки препинания и правило их вставки в текст. Самое важное это уметь читать лучшие тексты, которые представлены в русской литературе. Вот так и в программировании, в котором программирование занимает малую часть, а остальное это чтение лучшего чужого кода.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

sheff пишет:

 я не программист и свой скетч собрал методом ctrl+C - ctrl+V :)

Вот это и есть самое странное.

Попытайтесь взять газету, сделать из нее нарезку слов и из них составить рассказ на заданную тему. Думаю, Вы очень скоро обнаружите, что для "написания" рассказа методом ctrl+C - ctrl+V требуется гораздо более высокая квалификация, нежели при обычного вводе с клавиатуры.

 

Так что гораздо ПРОЩЕ писать программу с нуля, чем пытаться составить ее рекомендуемым Вами способом. 

Соответсвенно, на мой взгляд, не очень этично предлагать другим решать ВАВшу пргблему заведомо неоптимальным способом.

У Вас существет два варианта действий:

1. Научиться программировать в достаточной для решения Вашей задачи степени.

2. Заказать работу в разделе "Ищу исполнителя" за соответствующее вознаграждение.

 

PS. Только не надо ничего говорить насчет "помощи". Во-первых, написать за Вас - это не помощь. Помощь может заключаться в содействии изучения Вами программирования. А во-вторых, форум предназначен не для помощи (вопроеки устойчивому заблуждению просящих здесь помощь), а для общения по интересам.

GarryC
Offline
Зарегистрирован: 08.08.2016

По Поводу скорости - так и будет при принятом Вами методе управления - подумайте о создании функции одновременного поворота двигателей с одной задержкой.

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

sheff
Offline
Зарегистрирован: 14.11.2017

GarryC пишет:

По Поводу скорости - так и будет при принятом Вами методе управления - подумайте о создании функции одновременного поворота двигателей с одной задержкой.

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

По поводу мощности я уже думал, питание на драйверы взял с отдельного источника 5В 2А, оба мотора тянут приблизительно 600мА.

А насчет функции с одной задержкой....если бы знал как, то не просил бы помощи.
Все примеры, которые я рассматривал, не работают одновременно с двумя и более двигателями. С библиотеками вообще не смог запустить два сразу, только поочередно. 

Может подскажете как это реализовать?

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

sheff пишет:
Может подскажете как это реализовать?
Один из вариантов #25

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

Для  UNO могу показать на 1 или 2 одновременно работающих шаговика.

Под Мега надо переделывать таймер и порт.

sheff
Offline
Зарегистрирован: 14.11.2017

vosara пишет:

Для  UNO могу показать на 1 или 2 одновременно работающих шаговика.

Под Мега надо переделывать таймер и порт.

Был бы очень признателен за пример.

sheff
Offline
Зарегистрирован: 14.11.2017

qwone пишет:

sheff пишет:
Может подскажете как это реализовать?
Один из вариантов #25

Честно перечитал всю тему, но не знаю, что с этим всем делать.

Насколько я понимаю тормоза в моем скетче начинаются вот в этом месте

[code]
// функция поворачивает мотор 1 против часовой стрелки.
void anticlockwise_1()
{
  for(int i = 0; i < 8; i++)
  {
    setOutput_1(i);
    delayMicroseconds(motorSpeed);
  }
}

// функция поворачивает мотор 1 по часовой стрелке.
void clockwise_1()
{
  for(int i = 7; i >= 0; i--)
  {
    setOutput_1(i);
    delayMicroseconds(motorSpeed);
  }
}
// функция поворачивает мотор 2 против часовой стрелки.
void anticlockwise_2()
{
  for(int j = 0; j < 8; j++)
  {
    setOutput_2(j);
    delayMicroseconds(motorSpeed);
  }
}

// функция поворачивает мотор 2 по часовой стрелке.
void clockwise_2()
{
  for(int j = 7; j >= 0; j--)
  {
    setOutput_2(j);
    delayMicroseconds(motorSpeed);
  }
}

 void setOutput_1(int out)
{
  digitalWrite(motorPin1, bitRead(lookup_1[out], 0));
  digitalWrite(motorPin2, bitRead(lookup_1[out], 1));
  digitalWrite(motorPin3, bitRead(lookup_1[out], 2));
  digitalWrite(motorPin4, bitRead(lookup_1[out], 3));
}

void setOutput_2(int out)
{
  digitalWrite(motorPin5, bitRead(lookup_2[out], 0));
  digitalWrite(motorPin6, bitRead(lookup_2[out], 1));
  digitalWrite(motorPin7, bitRead(lookup_2[out], 2));
  digitalWrite(motorPin8, bitRead(lookup_2[out], 3));
}

[/code]

motorSpeed = 1000 мсек, значит после каждого шага происходит задержка в 1 секунду, а в случае одновременного вращения двух двигателей, время задержки увеличивается вдвое - отсюда и тормоза.

А вот как сделать правильно я не знаю.

p/s а если motorSpeed ставить меньше 1000 моторы вообще перестают крутиться, только гудят.

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

Если есть УНО или мини, нано то можно собрать на ней, у Вас не так много пинов используется чтобы ставить Мегу, 

//**********  (РЕЖИМ 1-ШАГ) Крутим с помощью сдвига --рабочая - крутит туда сюда без потери шагов - ускоряет - отключает катушки после бездействия
//PORTB - 8, 9, 10, 11 - Шаговик. && 12, 13 - Вход сигнал от 2х кнопок (влево - вправо)
//PORTD - 4, 5, 6, 7 - Шаговик. && 2, 3 - остаются для переферии 
#define uskor 2 //Задаем ускорение
byte n1 = 1;// Сдвигаем 1 бит
byte n3 = 0x10;
byte f_tim = 0;
long int perem_X = 0;
long int perem_Z = 0;
byte sped_Xt = uskor;//Начальная скорость
byte sped_X = 0; //Ускорение
byte sped_Zt = uskor;//Начальная скорость
byte sped_Z = 0; //Ускорение

bool f_run1X = 0;//Сброс после остановки 3 переменные.
bool f_run2X = 0;
unsigned long no_runX; //Переменная для прошедшего периода

bool f_run1Z = 0;//Сброс после остановки 3 переменные.
bool f_run2Z = 0;
unsigned long no_runZ; //Переменная для прошедшего периода



void setup() {
  //  пин, 8, 9, 10, 11 - Шаговик, как выход. 12, 13-кнопки, вход
  DDRB = 0xCF;
  //Устанавлюем значение выходов в 0 а входы - подтягивающий резистор
  PORTB = 0x30;
  //   PORTD, подключенный к двигателю 3 как выход, Две кнопки с подтяжкой pin2-3
  DDRD = DDRD | B11110000;
  //Устанавлюем значение выходов PORTD в 0
  PORTD = PORTD | B00000100;//x0F;

  //Serial.begin(9600);

  // Инициализировать TIMER1
  noInterrupts (); // отключить все прерывания
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  OCR1A = 125; // сравнить регистр (скорость!!!(2ms=125 - если медлиннее - УВЕЛИЧУЕМ)
  TCCR1B |= (1 << WGM12); // Режим СТС
  TCCR1B |= (1 << CS12); // 256 делитель
  TIMSK1 |= (1 << OCIE1A ); // включить таймер сравнить прерываний
  interrupts(); // включить все прерывания
}

ISR (TIMER1_COMPA_vect) // Функция прерывания таймера
{
  // Serial.println(f_tim);
  f_tim = B1111;
}

//Функция вращения  dvigatel 1
void RunX ()
{
  f_tim &= B1110;
  if (perem_X > 0) {
    n1 = (n1 >> 1) | (n1 << 3); //Сдвигаем
    --perem_X;
  }
  else {
    n1 = (n1 << 1) | (n1 >> 3); //Сдвигаем
    ++perem_X;
  }
  n1 = 0x0F & n1; //Маскируем кнопки
  PORTB = (PORTB & 0xF0) | n1; //Очищаем Младшие биты и пишем туда n1
}

//Функция dvigatel 3
void RunZ ()
{
  f_tim &= B1011;
  if (perem_Z > 0) {
    n3 = (n3 >> 1) | (n3 << 3); //Сдвигаем
    --perem_Z;
  }
  else {
    n3 = (n3 << 1) | (n3 >> 3); //Сдвигаем
    ++perem_Z;
  }
  n3 = 0xF0 & n3;//Маскируем
  PORTD = (PORTD & 0xF) | n3; //Очищаем старшие биты и пишем туда n3
  //Serial.println(n3);
}

void loop() {

  //Кнопки 1 и 2 служат для демонстрации работы. Считается замкнутой при подаче МИНУСА
  if (!(PINB & (1 << 4))) //проверяем кнопку 1 - нажали? Можно использовать if(!digitalRead(12))
  {
    //Задаем количество шагов для дв.- ВПРАВО "perem_X = Количеству шагов;"
    perem_X = 25;
    perem_Z = 75;
  }
  //else perem_X = 0; // ВНИМАНИЕ если задаём количество шагов - эту строчку удаляем!!!

  if (!(PINB & (1 << 5))) //проверяем кнопку 2 - нажали? Можно использовать if(!digitalRead(13))
  {
    //Задаем количество шагов для дв.- ВЛЕВО "perem_X = -Количеству шагов;"
    perem_X = -25;
    perem_Z = -75;
  }

  /////////////////////////// Запуск 1го двигателя если " perem_X != 0 "
  if (perem_X != 0) {
    f_run1X = 1;
    f_run2X = 0;

    if (f_tim & (1 << 0)) {
      if (!sped_X) {
        RunX();
        if (sped_Xt > 0) {
          --sped_Xt;
          sped_X = sped_Xt;
        }
      }
      else {
        --sped_X;
        f_tim &= B1110;
      }
    }
  }
  else {
    sped_Xt = uskor;
    sped_X = 0; // для пропуска 1го тика
  }

  /////////////////Запуск 3го двигателя если " perem_Z != 0 "

  if (perem_Z != 0) {
    f_run1Z = 1;
    f_run2Z = 0;

    if (f_tim & (1 << 2)) {
      if (!sped_Z) {
        RunZ();
        if (sped_Zt > 0) {
          --sped_Zt;
          sped_Z = sped_Zt;
        }
      }
      else {
        --sped_Z;
        f_tim &= B1011;
      }
    }
  }
  else {
    sped_Zt = uskor;
    sped_Z = 0; // для пропуска 1го тика
  }

  //Снимаеммаем напряжение с катушек двигателя X
  if (f_run1X && perem_X == 0) //Служит для запуска отключения катушек
  {
    f_run1X = 0;
    f_run2X = 1;
    no_runX = millis();
  }

  if (f_run2X && millis() - no_runX >= 1000)// Проверяем закончилось ли время
  {
    f_run2X = 0;
    //Снимаем напряжение с катушек
    PORTB &= 0xF0;
  }

  //Снимаеммаем напряжение с катушек двигателя Z
  if (f_run1Z && perem_Z == 0) //Служит для запуска отключения катушек
  {
    f_run1Z = 0;
    f_run2Z = 1;
    no_runZ = millis();
  }

  if (f_run2Z && millis() - no_runZ >= 1000)// Проверяем закончилось ли время
  {
    f_run2Z = 0;
    //Снимаем напряжение с катушек
    PORTD &= 0xF;
  }
}

 

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

От делай надо избавляться в любом коде - он тормозит систему. В моём примере есть таймер который через (сейчас настроен на 2 мс.) 2 мс. в прерывании меняет переменную. А в лооп я роверяю - есть  что вращать и сработал ли таймер - делаю 1 шаг и сбрасую переменную, дльше жду сработки таймера и проверяю есть ли что вращать и так пока не выработаю все вращение. Точно также работает и второй, третий двигатель.

sheff
Offline
Зарегистрирован: 14.11.2017

vosara пишет:

Если есть УНО или мини, нано то можно собрать на ней, у Вас не так много пинов используется чтобы ставить Мегу, 

Спасибо! Завтра буду разбираться.

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

sheff пишет:
А вот как сделать правильно я не знаю.
Вы должны организовать псевдопараллельную многозадачность- 5 паралельных процессов :2 шаговых двигатели и 3 кнопки. А у вас текст програмы работает на одну. И если надо запустить вторую у вас лезут траблы.

sheff
Offline
Зарегистрирован: 14.11.2017

vosara пишет:

От делай надо избавляться в любом коде - он тормозит систему. В моём примере есть таймер который через (сейчас настроен на 2 мс.) 2 мс. в прерывании меняет переменную. А в лооп я роверяю - есть  что вращать и сработал ли таймер - делаю 1 шаг и сбрасую переменную, дльше жду сработки таймера и проверяю есть ли что вращать и так пока не выработаю все вращение. Точно также работает и второй, третий двигатель.

в момент проверки количества оставшихся шагов можно и проверку кнопок вставить? Если нажималась кнопка или движок достиг максимального положения - останавливаем и сбрасываем питание, правильно?

sheff
Offline
Зарегистрирован: 14.11.2017

qwone пишет:

sheff пишет:
А вот как сделать правильно я не знаю.
Вы должны организовать псевдопараллельную многозадачность- 5 паралельных процессов :2 шаговых двигатели и 3 кнопки. А у вас текст програмы работает на одну. И если надо запустить вторую у вас лезут траблы.

Это я понимаю, буду разбираться с предложенным кодом, он для меня выглядит как китайская грамота....
Спасибо за подсказки!

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
/**/
unsigned long mill; // переменная под millis()
//--------------------------------
// класс шаговый двигатель
class Cl_StepMotor {
  protected:
  public:
    /*конструктор*/
    Cl_StepMotor() {}
    /*инициализация-вставить в setup()*/
    void init() {
    }
    /*работа-вставить в loop()*/
    void run() {}
};
//------Cl_Btn----------------------
// класс кнопка
class Cl_Btn {
  protected:
  public:
    /*конструктор*/
    Cl_Btn() {}
    /*инициализация-вставить в setup()*/
    void init() {
    }
    /*работа-вставить в loop()*/
    void run() {}
};
//---Компоновка-----------------------------
Cl_StepMotor StepMotor1;
Cl_StepMotor StepMotor2;
Cl_Btn Btn1;
Cl_Btn Btn2;
Cl_Btn Btn3;
//---main-----------------------------
void setup() {
  StepMotor1.init();
  StepMotor2.init();
  Btn1.init();
  Btn2.init();
  Btn3.init();
}

void loop() {
  mill = millis();
  StepMotor1.run();
  StepMotor2.run();
  Btn1.run();
  Btn2.run();
  Btn3.run();
}
/*Скетч использует 482 байт (1%) памяти устройства. Всего доступно 32256 байт.
  Глобальные переменные используют 13 байт (0%) динамической памяти, оставляя 2035 байт для локальных переменных. Максимум: 2048 байт.
*/

И это еще только легкая часть.

5N62V
Offline
Зарегистрирован: 25.02.2016

qwone пишет:

И это еще только легкая часть.

А можно теперь про псевдопараллельную многозадачность?

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

Немножко переделал, так как в первом коде кнопки стояли на 12м и 13м пине то надо светодиод на 13 пине выпаивать. Сейчас кнопки переставил на 2й и 3й пин и ничего выпаивать не надо.

//**********  (РЕЖИМ 1-ШАГ) Крутим с помощью сдвига --рабочая - крутит туда сюда без потери шагов - ускоряет - отключает катушки после бездействия
//PORTB - 8, 9, 10, 11 - Шаговик. && 12, 13 - Вход сигнал от 2х кнопок (влево - вправо)
//PORTD - 4, 5, 6, 7 - Шаговик. && 2, 3 - остаются для переферии 
#define uskor 2 //Задаем ускорение
byte n1 = 1;// Сдвигаем 1 бит
byte n3 = 0x10;
byte f_tim = 0;
long int perem_X = 0;
long int perem_Z = 0;
byte sped_Xt = uskor;//Начальная скорость
byte sped_X = 0; //Ускорение
byte sped_Zt = uskor;//Начальная скорость
byte sped_Z = 0; //Ускорение

bool f_run1X = 0;//Сброс после остановки 3 переменные.
bool f_run2X = 0;
unsigned long no_runX; //Переменная для прошедшего периода

bool f_run1Z = 0;//Сброс после остановки 3 переменные.
bool f_run2Z = 0;
unsigned long no_runZ; //Переменная для прошедшего периода



void setup() {
  //  пин, 8, 9, 10, 11 - Шаговик, 2, 3- переферия
  DDRB = 0xCF;
  //Устанавлюем значение выходов в 0 а входы - подтягивающий резистор
  PORTB = 0x30;
  //   PORTD, подключенный к двигателю 3 как выход, Две кнопки с подтяжкой pin2-3
  DDRD = DDRD | B11110000;
  //Устанавлюем значение выходов PORTD в 0
  PORTD = PORTD | B00001100;//x0F;

  //Serial.begin(9600);

  // Инициализировать TIMER1
  noInterrupts (); // отключить все прерывания
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  OCR1A = 125; // сравнить регистр (скорость!!!(2ms=125 - если медлиннее - УВЕЛИЧУЕМ)
  TCCR1B |= (1 << WGM12); // Режим СТС
  TCCR1B |= (1 << CS12); // 256 делитель
  TIMSK1 |= (1 << OCIE1A ); // включить таймер сравнить прерываний
  interrupts(); // включить все прерывания
}

ISR (TIMER1_COMPA_vect) // Функция прерывания таймера
{
  // Serial.println(f_tim);
  f_tim = B1111;
}

//Функция вращения  dvigatel 1
void RunX ()
{
  f_tim &= B1110;
  if (perem_X > 0) {
    n1 = (n1 >> 1) | (n1 << 3); //Сдвигаем
    --perem_X;
  }
  else {
    n1 = (n1 << 1) | (n1 >> 3); //Сдвигаем
    ++perem_X;
  }
  n1 = 0x0F & n1; //Маскируем кнопки
  PORTB = (PORTB & 0xF0) | n1; //Очищаем Младшие биты и пишем туда n1
}

//Функция dvigatel 3
void RunZ ()
{
  f_tim &= B1011;
  if (perem_Z > 0) {
    n3 = (n3 >> 1) | (n3 << 3); //Сдвигаем
    --perem_Z;
  }
  else {
    n3 = (n3 << 1) | (n3 >> 3); //Сдвигаем
    ++perem_Z;
  }
  n3 = 0xF0 & n3;//Маскируем
  PORTD = (PORTD & 0xF) | n3; //Очищаем старшие биты и пишем туда n3
  //Serial.println(n3);
}

void loop() {

  //Кнопки 1 и 2 служат для демонстрации работы. Считается замкнутой при подаче МИНУСА
  if (!(PIND & (1 << 2))) //проверяем кнопку 1 - нажали? Можно использовать if(!digitalRead(2))
  {
    //Задаем количество шагов для дв.- ВПРАВО "perem_X = Количеству шагов;"
    perem_X = 25;
    perem_Z = 75;
  }
  //else perem_X = 0; // ВНИМАНИЕ если задаём количество шагов - эту строчку удаляем!!!

  if (!(PIND & (1 << 3))) //проверяем кнопку 2 - нажали? Можно использовать if(!digitalRead(3))
  {
    //Задаем количество шагов для дв.- ВЛЕВО "perem_X = -Количеству шагов;"
    perem_X = -25;
    perem_Z = -75;
  }

  /////////////////////////// Запуск 1го двигателя если " perem_X != 0 "
  if (perem_X != 0) {
    f_run1X = 1;
    f_run2X = 0;

    if (f_tim & (1 << 0)) {
      if (!sped_X) {
        RunX();
        if (sped_Xt > 0) {
          --sped_Xt;
          sped_X = sped_Xt;
        }
      }
      else {
        --sped_X;
        f_tim &= B1110;
      }
    }
  }
  else {
    sped_Xt = uskor;
    sped_X = 0; // для пропуска 1го тика
  }

  /////////////////Запуск 3го двигателя если " perem_Z != 0 "

  if (perem_Z != 0) {
    f_run1Z = 1;
    f_run2Z = 0;

    if (f_tim & (1 << 2)) {
      if (!sped_Z) {
        RunZ();
        if (sped_Zt > 0) {
          --sped_Zt;
          sped_Z = sped_Zt;
        }
      }
      else {
        --sped_Z;
        f_tim &= B1011;
      }
    }
  }
  else {
    sped_Zt = uskor;
    sped_Z = 0; // для пропуска 1го тика
  }

  //Снимаеммаем напряжение с катушек двигателя X
  if (f_run1X && perem_X == 0) //Служит для запуска отключения катушек
  {
    f_run1X = 0;
    f_run2X = 1;
    no_runX = millis();
  }

  if (f_run2X && millis() - no_runX >= 1000)// Проверяем закончилось ли время
  {
    f_run2X = 0;
    //Снимаем напряжение с катушек
    PORTB &= 0xF0;
  }

  //Снимаеммаем напряжение с катушек двигателя Z
  if (f_run1Z && perem_Z == 0) //Служит для запуска отключения катушек
  {
    f_run1Z = 0;
    f_run2Z = 1;
    no_runZ = millis();
  }

  if (f_run2Z && millis() - no_runZ >= 1000)// Проверяем закончилось ли время
  {
    f_run2Z = 0;
    //Снимаем напряжение с катушек
    PORTD &= 0xF;
  }
}

 

sheff
Offline
Зарегистрирован: 14.11.2017

vosara пишет:

Немножко переделал, так как в первом коде кнопки стояли на 12м и 13м пине то надо светодиод на 13 пине выпаивать. Сейчас кнопки переставил на 2й и 3й пин и ничего выпаивать не надо.


Добрый день.

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

В какую сторону копать?

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

В строке 42 увеличуем время

OCR1A = 250; // сравнить регистр (скорость!!!(2ms=125 - если медлиннее - УВЕЛИЧУЕМ)

Или меняем ножки подключения катушек

sheff
Offline
Зарегистрирован: 14.11.2017

vosara пишет:

В строке 42 увеличуем время

OCR1A = 250; // сравнить регистр (скорость!!!(2ms=125 - если медлиннее - УВЕЛИЧУЕМ)

Или меняем ножки подключения катушек

Время менял, ноги тоже  - результат тот же.

 

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

Ладно поставте тогда OCR1A = 25000; и посмотрите как движутся светодиоды. Они должны меняться один за другим в одну сторону или в другую, в зависимости от нажатй кнопки

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

vosara пишет:

Ладно поставте тогда OCR1A = 25000; и посмотрите как движутся светодиоды. Они должны меняться один за другим в одну сторону или в другую, в зависимости от нажатй кнопки

Все правильно, так и работает. А с большей скоростью не хочет.

 

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

Если при такой скорости вращается то пробуйте медленно увеличивать скорость чтобы найти его предел. У меня такойже с таким драйвером вращается при скорости 2 мс (т.е. 125) при меньшем значении подвисал!

sheff
Offline
Зарегистрирован: 14.11.2017

vosara пишет:

Если при такой скорости вращается то пробуйте медленно увеличивать скорость чтобы найти его предел. У меня такойже с таким драйвером вращается при скорости 2 мс (т.е. 125) при меньшем значении подвисал!

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

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

Ну здесь вывод однозначен -катушки подключены не правильно

sheff
Offline
Зарегистрирован: 14.11.2017

vosara пишет:

Ну здесь вывод однозначен -катушки подключены не правильно

Подключено всё правильно, поигрался с цифрами....добился вращения, но усилия вообще нет, они сами себя еле крутят.

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

Не может быть! Я у себя удержать не могу. Какое напряжение Вы подаете на драйвер? Мощность блока питания?

sheff
Offline
Зарегистрирован: 14.11.2017

vosara пишет:

Не может быть! Я у себя удержать не могу. Какое напряжение Вы подаете на драйвер? Мощность блока питания?

лабораторник до 6А, подаю 4.96В при вращении 260мА

при скорости 250 максимальное усилие.

Сейчас дал 6 вольт, при скорости 175 хорошее усилие и вращение, 380мА

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

Питание написанно 5-12в. По току гдето видел 450 или 550ма.

sheff
Offline
Зарегистрирован: 14.11.2017

vosara пишет:

Питание написанно 5-12в. По току гдето видел 450 или 550ма.

На драйвере да, к нему можно и 12В движки прицепить. А если движки на 5вольт? Можно на на драйвер давать 9 или 12 вольт?

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

Нет все правильно двигатель 5 вольтовый. 9-12 нельзя

sheff
Offline
Зарегистрирован: 14.11.2017

vosara пишет:

Нет все правильно двигатель 5 вольтовый. 9-12 нельзя

подал 9В, скорость выставил 125, потребление выросло до 480 мА, работает изумительно! Скорость хорошая, пальцами не удержишь. Ничего не греется.

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

sheff пишет:

vosara пишет:

Нет все правильно двигатель 5 вольтовый. 9-12 нельзя

подал 9В, скорость выставил 125, потребление выросло до 480 мА, работает изумительно! Скорость хорошая, пальцами не удержишь. Ничего не греется.

Вы знаете я вот сейчас специально собрал схему с таким как у Вас драйвером и двигателем подал питание 5.6в скорость 125 Ток пказал 0.06А. Работает безшумно,  удержать, (чтобы не повредить шестерни) нельзя. Все таки чтото у Вас с подключением. Минуса Вы соеденили.

sheff
Offline
Зарегистрирован: 14.11.2017

vosara пишет:

Вы знаете я вот сейчас специально собрал схему с таким как у Вас драйвером и двигателем подал питание 5.6в скорость 125 Ток пказал 0.06А. Работает безшумно,  удержать, (чтобы не повредить шестерни) нельзя. Все таки чтото у Вас с подключением. Минуса Вы соеденили.

Минуса конечно соединил, всё собрано на макетке, возможно есть недоконтакт. Но меня и такой результат устраивает, может когда всё пропаяется будет лучше....
Я теперь репу чешу, как это всё впихнуть в мой скетч....вернее как это всё теперь написать по-новой...

Стесняюсь спросить.....Вы не возьметесь? Если да, то во сколько это мне обойдется?

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

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

sheff
Offline
Зарегистрирован: 14.11.2017

vosara пишет:

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

Огромное человеческое спасибо!
Я сейчас читаю о том как управлять напрямую портами, вроде бы смысл понял, но не знаю с чего начинать.
Боюсь, что я запутаюсь во всех этих битах, сдвигах...

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

Вот только идиотское у вас управление. Лучше только 2 кнопками обойтись. Одна управляет правой шторой вторая левой. Нажали раз штора открывается, нажали второй стоп, третий закрывается , четвертый стоп, и дальше по кругу. 

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

qwone пишет:

Вот только идиотское у вас управление. Лучше только 2 кнопками обойтись. Одна управляет правой шторой вторая левой. Нажали раз штора открывается, нажали второй стоп, третий закрывается , четвертый стоп, и дальше по кругу. 

Вы знаете я тоже думал что 2 кноки достаточно но потом представил ситуацию - остановили мы штору по средине и свет вырубился следствие корекция сбита. Вот тут нам и понадобится 3я кнопка для калибровки

sheff
Offline
Зарегистрирован: 14.11.2017

qwone пишет:

Вот только идиотское у вас управление. Лучше только 2 кнопками обойтись. Одна управляет правой шторой вторая левой. Нажали раз штора открывается, нажали второй стоп, третий закрывается , четвертый стоп, и дальше по кругу. 

Можно, конечно, и так...
Но я думаю, что с кнопкой выбора шторы интересней и удобней.
Когда выбирается штора, загорается светодиод, указывающий какая штора в данный момент активна, если горят два светодиода, то соответственно активны обе шторы. Этой же кнопкой при длительном нажатии происходит вход в режим калибровки нуля(на случай пропуска шагов двигателем, всегда можно откалибровать начальное положение).
А кнопками вверх и вниз уже управлять шторами.

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

sheff пишет:

Огромное человеческое спасибо!

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

А Вы хотели за 2 дня все освоить?

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

sheff
Offline
Зарегистрирован: 14.11.2017

Как называется программа или онлайн симулятор?

sheff
Offline
Зарегистрирован: 14.11.2017

vosara пишет:

Вы знаете я тоже думал что 2 кноки достаточно но потом представил ситуацию - остановили мы штору по средине и свет вырубился следствие корекция сбита. Вот тут нам и понадобится 3я кнопка для калибровки

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

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

vosara пишет:

Вы знаете я тоже думал что 2 кноки достаточно но потом представил ситуацию - остановили мы штору по средине и свет вырубился следствие корекция сбита. Вот тут нам и понадобится 3я кнопка для калибровки

И она работает как shift. При нажатой 3 кнопке открытие (или закрытие) будет идти до ручного стопа. А EEPROM не зачем использовать.

sheff
Offline
Зарегистрирован: 14.11.2017

qwone пишет:

И она работает как shift. При нажатой 3 кнопке открытие (или закрытие) будет идти до ручного стопа. А EEPROM не зачем использовать.

А как тогда определять положение после отключения питания?

А чем плох ручной стоп повторным нажатием любой кнопки?

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

Из симуляторов мне нравитя Протеус! 

sheff
Offline
Зарегистрирован: 14.11.2017

vosara пишет:

Из симуляторов мне нравитя Протеус! 

Сейчас поищу...я уже скачиваю VirtualBreadBoard...что о ней можете сказать?

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014
Давайте определимся с алгоритмом по кнопкам. У Вас есть 3 кнопки.
1- UP
2- DOWN
3- MENU
Если я правильно понял Вы хотите:
MENU- Первое нажатие вк.1й светодиод и кнопками 1,2 поднимаем\опускаем 1ю штору. 
           Второе нажатие вк.2й светодиод и кнопками 1,2 поднимаем\опускаем 2ю штору
           Третье нажатие вк.1й и 2й. светодиод и кнопкам 1,2 поднимаем\опускаем обе шторы
           Четвертое нажатие - выходим из меню и на кнопки не реагируем
А как быть с калибровко? Может использовать длинное нажатие (например удержание более 1сек)
UP - DOWN - Если стоим в калибровке - UP опускает в 0 первую штору \ DOWN  опускает в 0 вторую штору.      
  Или я понячтото не так
sheff
Offline
Зарегистрирован: 14.11.2017

vosara пишет:

Давайте определимся с алгоритмом по кнопкам. У Вас есть 3 кнопки.
1- UP
2- DOWN
3- MENU
Если я правильно понял Вы хотите:
MENU- Первое нажатие вк.1й светодиод и кнопками 1,2 поднимаем\опускаем 1ю штору. 
           Второе нажатие вк.2й светодиод и кнопками 1,2 поднимаем\опускаем 2ю штору
           Третье нажатие вк.1й и 2й. светодиод и кнопкам 1,2 поднимаем\опускаем обе шторы
           Четвертое нажатие - выходим из меню и на кнопки не реагируем
А как быть с калибровко? Может использовать длинное нажатие (например удержание более 1сек)
UP - DOWN - Если стоим в калибровке - UP опускает в 0 первую штору \ DOWN  опускает в 0 вторую штору.      
  Или я понячтото не так

Добрый день.
Практически всё верно, немного уточню.
1-MENU
2-UP
3-DOWN
MENU -Первое, второе и третье нажатие как Вы написали, четвертое нажатие это переход в 1-ю позицию.
Длительное нажатие (более 3 сек) - переход в режим калибровки.
В режиме калибровки также короткое нажатие переход по шторам 1 и 2 (обе шторы одновременно не активируются), а длинное нажатие (более 3 сек) сохраняет позиции штор в EEPROM и выход из режима калибровки.
UP - в рабочем режиме (если в EEPROM есть значения позиций) поднимает штору до "0" позиции. При повторном нажатии любой кнопки штора останавливается(значения записывается в EEPROM).
В режиме калибровки пока нажата кнопка штора поднимается, отпустили кнопку или достигли "0" - останавливается.
DOWN -  аналогично кнопке UP, только к позиции MAX.
Позиции MAX для двух штор разные, я их вычислял в режиме калибровки через монитор порта и жестко присваивал в описании констант.