Официальный сайт компании Arduino по адресу arduino.cc
Прошу помощи (проблема с одновременной работой шаговых двигателей)
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Всем привет!
Уважаемые форумчане, прошу сильно не пинать, никогда не занимался программированием, поэтому многое лежит за гранью моего понимания.
Повторюсь, я не программист и свой скетч собрал методом 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]
я не программист и свой скетч собрал методом ctrl+C - ctrl+V :)
Вот это и есть самое странное.
Попытайтесь взять газету, сделать из нее нарезку слов и из них составить рассказ на заданную тему. Думаю, Вы очень скоро обнаружите, что для "написания" рассказа методом ctrl+C - ctrl+V требуется гораздо более высокая квалификация, нежели при обычного вводе с клавиатуры.
Так что гораздо ПРОЩЕ писать программу с нуля, чем пытаться составить ее рекомендуемым Вами способом.
Соответсвенно, на мой взгляд, не очень этично предлагать другим решать ВАВшу пргблему заведомо неоптимальным способом.
У Вас существет два варианта действий:
1. Научиться программировать в достаточной для решения Вашей задачи степени.
2. Заказать работу в разделе "Ищу исполнителя" за соответствующее вознаграждение.
PS. Только не надо ничего говорить насчет "помощи". Во-первых, написать за Вас - это не помощь. Помощь может заключаться в содействии изучения Вами программирования. А во-вторых, форум предназначен не для помощи (вопроеки устойчивому заблуждению просящих здесь помощь), а для общения по интересам.
По Поводу скорости - так и будет при принятом Вами методе управления - подумайте о создании функции одновременного поворота двигателей с одной задержкой.
А вот насчет пропусков - странно, возможно, у Вас просто не хватает мощности источника питания для одновременного проворачивания двух двигателей - тогда создание вышеуказанной функции только усугубит проблему.
По Поводу скорости - так и будет при принятом Вами методе управления - подумайте о создании функции одновременного поворота двигателей с одной задержкой.
А вот насчет пропусков - странно, возможно, у Вас просто не хватает мощности источника питания для одновременного проворачивания двух двигателей - тогда создание вышеуказанной функции только усугубит проблему.
По поводу мощности я уже думал, питание на драйверы взял с отдельного источника 5В 2А, оба мотора тянут приблизительно 600мА.
А насчет функции с одной задержкой....если бы знал как, то не просил бы помощи.
Все примеры, которые я рассматривал, не работают одновременно с двумя и более двигателями. С библиотеками вообще не смог запустить два сразу, только поочередно.
Может подскажете как это реализовать?
Для UNO могу показать на 1 или 2 одновременно работающих шаговика.
Под Мега надо переделывать таймер и порт.
Для UNO могу показать на 1 или 2 одновременно работающих шаговика.
Под Мега надо переделывать таймер и порт.
Был бы очень признателен за пример.
Честно перечитал всю тему, но не знаю, что с этим всем делать.
Насколько я понимаю тормоза в моем скетче начинаются вот в этом месте
motorSpeed = 1000 мсек, значит после каждого шага происходит задержка в 1 секунду, а в случае одновременного вращения двух двигателей, время задержки увеличивается вдвое - отсюда и тормоза.
А вот как сделать правильно я не знаю.
p/s а если motorSpeed ставить меньше 1000 моторы вообще перестают крутиться, только гудят.
Если есть УНО или мини, нано то можно собрать на ней, у Вас не так много пинов используется чтобы ставить Мегу,
От делай надо избавляться в любом коде - он тормозит систему. В моём примере есть таймер который через (сейчас настроен на 2 мс.) 2 мс. в прерывании меняет переменную. А в лооп я роверяю - есть что вращать и сработал ли таймер - делаю 1 шаг и сбрасую переменную, дльше жду сработки таймера и проверяю есть ли что вращать и так пока не выработаю все вращение. Точно также работает и второй, третий двигатель.
Если есть УНО или мини, нано то можно собрать на ней, у Вас не так много пинов используется чтобы ставить Мегу,
Спасибо! Завтра буду разбираться.
От делай надо избавляться в любом коде - он тормозит систему. В моём примере есть таймер который через (сейчас настроен на 2 мс.) 2 мс. в прерывании меняет переменную. А в лооп я роверяю - есть что вращать и сработал ли таймер - делаю 1 шаг и сбрасую переменную, дльше жду сработки таймера и проверяю есть ли что вращать и так пока не выработаю все вращение. Точно также работает и второй, третий двигатель.
в момент проверки количества оставшихся шагов можно и проверку кнопок вставить? Если нажималась кнопка или движок достиг максимального положения - останавливаем и сбрасываем питание, правильно?
Это я понимаю, буду разбираться с предложенным кодом, он для меня выглядит как китайская грамота....
Спасибо за подсказки!
И это еще только легкая часть.
А можно теперь про псевдопараллельную многозадачность?
Немножко переделал, так как в первом коде кнопки стояли на 12м и 13м пине то надо светодиод на 13 пине выпаивать. Сейчас кнопки переставил на 2й и 3й пин и ничего выпаивать не надо.
Немножко переделал, так как в первом коде кнопки стояли на 12м и 13м пине то надо светодиод на 13 пине выпаивать. Сейчас кнопки переставил на 2й и 3й пин и ничего выпаивать не надо.
Добрый день.
Попробывал сейчас код на ардуино нано...моторы гудят, но не двигаются...на драйверах светодиоды в полнакала.
В какую сторону копать?
В строке 42 увеличуем время
OCR1A = 250;
// сравнить регистр (скорость!!!(2ms=125 - если медлиннее - УВЕЛИЧУЕМ)
Или меняем ножки подключения катушек
В строке 42 увеличуем время
OCR1A = 250;
// сравнить регистр (скорость!!!(2ms=125 - если медлиннее - УВЕЛИЧУЕМ)
Или меняем ножки подключения катушек
Время менял, ноги тоже - результат тот же.
Ладно поставте тогда OCR1A = 25000; и посмотрите как движутся светодиоды. Они должны меняться один за другим в одну сторону или в другую, в зависимости от нажатй кнопки
Эфект должен быть такой https://drive.google.com/file/d/11hKs2jn7QEVbozBVutC71aiDwVW5yB6d/view?usp=sharing
Вот еще https://drive.google.com/file/d/1WDQjHNLRlAvMqHKy9zp6owsHHJPmdWxj/view?usp=sharing
Ладно поставте тогда OCR1A = 25000; и посмотрите как движутся светодиоды. Они должны меняться один за другим в одну сторону или в другую, в зависимости от нажатй кнопки
Все правильно, так и работает. А с большей скоростью не хочет.
Если при такой скорости вращается то пробуйте медленно увеличивать скорость чтобы найти его предел. У меня такойже с таким драйвером вращается при скорости 2 мс (т.е. 125) при меньшем значении подвисал!
Если при такой скорости вращается то пробуйте медленно увеличивать скорость чтобы найти его предел. У меня такойже с таким драйвером вращается при скорости 2 мс (т.е. 125) при меньшем значении подвисал!
Я не правильно выразился....светодиоды бегают в нужной последовательности и направлении, а вот моторы только вибрируют и стоят на месте.
Ну здесь вывод однозначен -катушки подключены не правильно
Ну здесь вывод однозначен -катушки подключены не правильно
Подключено всё правильно, поигрался с цифрами....добился вращения, но усилия вообще нет, они сами себя еле крутят.
Не может быть! Я у себя удержать не могу. Какое напряжение Вы подаете на драйвер? Мощность блока питания?
Не может быть! Я у себя удержать не могу. Какое напряжение Вы подаете на драйвер? Мощность блока питания?
лабораторник до 6А, подаю 4.96В при вращении 260мА
при скорости 250 максимальное усилие.
Сейчас дал 6 вольт, при скорости 175 хорошее усилие и вращение, 380мА
Питание написанно 5-12в. По току гдето видел 450 или 550ма.
Питание написанно 5-12в. По току гдето видел 450 или 550ма.
На драйвере да, к нему можно и 12В движки прицепить. А если движки на 5вольт? Можно на на драйвер давать 9 или 12 вольт?
Нет все правильно двигатель 5 вольтовый. 9-12 нельзя
Нет все правильно двигатель 5 вольтовый. 9-12 нельзя
подал 9В, скорость выставил 125, потребление выросло до 480 мА, работает изумительно! Скорость хорошая, пальцами не удержишь. Ничего не греется.
Нет все правильно двигатель 5 вольтовый. 9-12 нельзя
подал 9В, скорость выставил 125, потребление выросло до 480 мА, работает изумительно! Скорость хорошая, пальцами не удержишь. Ничего не греется.
Вы знаете я вот сейчас специально собрал схему с таким как у Вас драйвером и двигателем подал питание 5.6в скорость 125 Ток пказал 0.06А. Работает безшумно, удержать, (чтобы не повредить шестерни) нельзя. Все таки чтото у Вас с подключением. Минуса Вы соеденили.
Вы знаете я вот сейчас специально собрал схему с таким как у Вас драйвером и двигателем подал питание 5.6в скорость 125 Ток пказал 0.06А. Работает безшумно, удержать, (чтобы не повредить шестерни) нельзя. Все таки чтото у Вас с подключением. Минуса Вы соеденили.
Минуса конечно соединил, всё собрано на макетке, возможно есть недоконтакт. Но меня и такой результат устраивает, может когда всё пропаяется будет лучше....
Я теперь репу чешу, как это всё впихнуть в мой скетч....вернее как это всё теперь написать по-новой...
Стесняюсь спросить.....Вы не возьметесь? Если да, то во сколько это мне обойдется?
Давайте мы попробуем сделать это вместе и Вам ничего это не будет стоить, кроме как большего понимания контролера.
Давайте мы попробуем сделать это вместе и Вам ничего это не будет стоить, кроме как большего понимания контролера.
Огромное человеческое спасибо!
Я сейчас читаю о том как управлять напрямую портами, вроде бы смысл понял, но не знаю с чего начинать.
Боюсь, что я запутаюсь во всех этих битах, сдвигах...
Вот только идиотское у вас управление. Лучше только 2 кнопками обойтись. Одна управляет правой шторой вторая левой. Нажали раз штора открывается, нажали второй стоп, третий закрывается , четвертый стоп, и дальше по кругу.
Вот только идиотское у вас управление. Лучше только 2 кнопками обойтись. Одна управляет правой шторой вторая левой. Нажали раз штора открывается, нажали второй стоп, третий закрывается , четвертый стоп, и дальше по кругу.
Вы знаете я тоже думал что 2 кноки достаточно но потом представил ситуацию - остановили мы штору по средине и свет вырубился следствие корекция сбита. Вот тут нам и понадобится 3я кнопка для калибровки
Вот только идиотское у вас управление. Лучше только 2 кнопками обойтись. Одна управляет правой шторой вторая левой. Нажали раз штора открывается, нажали второй стоп, третий закрывается , четвертый стоп, и дальше по кругу.
Можно, конечно, и так...
Но я думаю, что с кнопкой выбора шторы интересней и удобней.
Когда выбирается штора, загорается светодиод, указывающий какая штора в данный момент активна, если горят два светодиода, то соответственно активны обе шторы. Этой же кнопкой при длительном нажатии происходит вход в режим калибровки нуля(на случай пропуска шагов двигателем, всегда можно откалибровать начальное положение).
А кнопками вверх и вниз уже управлять шторами.
Огромное человеческое спасибо!
Я сейчас читаю о том как управлять напрямую портами, вроде бы смысл понял, но не знаю с чего начинать.
Боюсь, что я запутаюсь во всех этих битах, сдвигах...
А Вы хотели за 2 дня все освоить?
А начинать надо с простого - помигать светодиодом чирез регистры. Для этого советую поставить симулятор и проверять на нем, чтобы не гонять каждый раз Ардуино.
Как называется программа или онлайн симулятор?
Вы знаете я тоже думал что 2 кноки достаточно но потом представил ситуацию - остановили мы штору по средине и свет вырубился следствие корекция сбита. Вот тут нам и понадобится 3я кнопка для калибровки
На случай отключения питания, я сохраняю положение каждой шторы в eeprom, а вот если движок пропускает шаги, тогда и нужна калибровка. Возможно сейчас пропусков не будет и эта функция нужна будет только при начальной калибровке.
Вы знаете я тоже думал что 2 кноки достаточно но потом представил ситуацию - остановили мы штору по средине и свет вырубился следствие корекция сбита. Вот тут нам и понадобится 3я кнопка для калибровки
И она работает как shift. При нажатой 3 кнопке открытие (или закрытие) будет идти до ручного стопа. А EEPROM не зачем использовать.
А как тогда определять положение после отключения питания?
А чем плох ручной стоп повторным нажатием любой кнопки?
Из симуляторов мне нравитя Протеус!
Из симуляторов мне нравитя Протеус!
Сейчас поищу...я уже скачиваю VirtualBreadBoard...что о ней можете сказать?
Добрый день.
Практически всё верно, немного уточню.
1-MENU
2-UP
3-DOWN
MENU -Первое, второе и третье нажатие как Вы написали, четвертое нажатие это переход в 1-ю позицию.
Длительное нажатие (более 3 сек) - переход в режим калибровки.
В режиме калибровки также короткое нажатие переход по шторам 1 и 2 (обе шторы одновременно не активируются), а длинное нажатие (более 3 сек) сохраняет позиции штор в EEPROM и выход из режима калибровки.
UP - в рабочем режиме (если в EEPROM есть значения позиций) поднимает штору до "0" позиции. При повторном нажатии любой кнопки штора останавливается(значения записывается в EEPROM).
В режиме калибровки пока нажата кнопка штора поднимается, отпустили кнопку или достигли "0" - останавливается.
DOWN - аналогично кнопке UP, только к позиции MAX.
Позиции MAX для двух штор разные, я их вычислял в режиме калибровки через монитор порта и жестко присваивал в описании констант.