1. Обязательно представиться на русском языке кириллицей (заполнить поле "Имя").
  2. Фиктивные имена мы не приветствуем. Ивановых и Пупкиных здесь уже достаточно.
  3. Не писать свой вопрос в первую попавшуюся тему - вместо этого создать новую тему.
  4. За поиск, предложение и обсуждение пиратского ПО и средств взлома - бан без предупреждения.
  5. Рекламу и частные объявления "куплю/продам/есть халтура" мы не размещаем ни на каких условиях.
  6. Перед тем как что-то написать - читать здесь и здесь, а студентам - обязательно здесь.
  7. Не надо писать в ЛС администраторам свои технические вопросы. Администраторы форума отлично знают как работает форум, а не все-все контроллеры, о которых тут пишут.

Arduino

Ответить

Автор темы
GiGaStEr_TyT
Сообщения: 1
Зарегистрирован: 23 апр 2019, 20:25
Имя: Кирилл

Arduino

Сообщение GiGaStEr_TyT »

Начал изучать ардуино... Решил сделать часы на шаговом двигателе и появилась проблема, которую не могу исправить.
Принцип работы:
1-когда я нажимаю на кнопку на пине3 - я выбираю скорость вращения вала мотора;
2-потом нажимаю на кнопку на пине4 - мотор начинает движение;
3- когда мотор заканчивает движение, цикл начинается сначала, скорость выбирается, но (проблема) не могу заставить мотор начать движение.
Ну вот и вся проблема. Помогите плиз(((

Код: Выделить всё

// порты для подключения модуля ULN2003 к Arduino
#define in1 8
#define in2 9
#define in3 10
#define in4 11


int count3 = 0;
int count4;
int val3;
int val4;

int x;
int dl; // время задержки между импульсами

void setup() {
    pinMode(in1, OUTPUT);
    pinMode(in2, OUTPUT);
    pinMode(in3, OUTPUT);
    pinMode(in4, OUTPUT);

pinMode(3,INPUT);
pinMode(4, INPUT);

    
 Serial.begin(9600);
    
}

void loop() {
count4=1;

val3=digitalRead(3);
if (val3==HIGH){
  count3=count3+1;
  delay(500);
  Serial.println(count3);
}
if (count3==6){
  count3=1;
}

if (count3==1){
  dl=30;
  analogWrite(A0,1023);
  digitalWrite(7,LOW);
}

if (count3==2){
  dl=450;
  analogWrite(A0, 0);
  analogWrite(A1, 1023);
}

if (count3==3){
  dl=900;
  analogWrite(A1,0);
  digitalWrite(5, HIGH);
}

if (count3==4){
  dl=1350;
  digitalWrite(5,LOW);
  digitalWrite(6,HIGH);
}

if (count3==5){
  dl=1800;
  digitalWrite(6,LOW);
  digitalWrite(7,HIGH);
}



val4=digitalRead(4);
if (val4==HIGH){
  count4=0;
  delay(500);
}


if (count4==0){    
for (x; x<=512; x=x+1){
    digitalWrite(in1, HIGH); 
    digitalWrite(in2, LOW); 
    digitalWrite(in3, LOW); 
    digitalWrite(in4, HIGH);
    delay(dl);

    digitalWrite(in1, HIGH); 
    digitalWrite(in2, HIGH); 
    digitalWrite(in3, LOW); 
    digitalWrite(in4, LOW);
    delay(dl);

    digitalWrite(in1, LOW); 
    digitalWrite(in2, HIGH); 
    digitalWrite(in3, HIGH); 
    digitalWrite(in4, LOW);
    delay(dl);

    digitalWrite(in1, LOW); 
    digitalWrite(in2, LOW); 
    digitalWrite(in3, HIGH); 
    digitalWrite(in4, HIGH);
    delay(dl);

   
}
}
}
Аватара пользователя

CHANt
эксперт
эксперт
Сообщения: 1465
Зарегистрирован: 25 июл 2008, 10:25
Имя: Эдуард Владимирович
Страна: СССР
город/регион: Оренбург
Благодарил (а): 43 раза
Поблагодарили: 93 раза

Arduino

Сообщение CHANt »

Новичок в Ардуино, но на мой взгляд -
1. функция delay - это же прерывание, т.е. остановка всей программы, полностью. У Вас полный разбег по времени получается. Мне кажется, в данном случае, необходимо использовать другие функции таймеров, чтобы не прерывалась программа. Почитайте про millis и тому подобное.
2.

Код: Выделить всё

void loop() {
count4=1;
val3=digitalRead(3);
закрывающая скобка в конце функции луп, а должна быть сразу после действия val3=digitalRead(3);.
3. Повторяющиеся строчки кода вашей программы лучше выделить в отдельные функции
4. Цикл for, там же постоянное delay вызывается, мне кажется что именно эта часть не работает совсем. Надо другой таймер, в принципе вот здесь объясняют хорошо - https://pikabu.ru/story/arduino_dlya_na ... vo_5202527
--------------------------------------------------------------------------------------------

Linkel
осмотрелся
осмотрелся
Сообщения: 124
Зарегистрирован: 30 сен 2017, 21:41
Имя: Тимур
Благодарил (а): 14 раз
Поблагодарили: 7 раз

Arduino

Сообщение Linkel »

Верно! использовать delay плохая привычка, нужно ее искоренять сразу!
И коментить строчки.
Давно не занимался ардуинками, но скорее всего, когда вы жмете кнопку для пин3 или пин4, в этот момент вы попадаете в точку активности delay, а в этот момент, ваш контроллер не принимает никаких сигналов (дискретных и аналоговых).

ПС Была у меня такая же история, когда я писал подобную программу для управления скоростью моторчика для дет.качалки...так же мучался, в итоге пришлось убирать delay из программы вообще!Чего и вам советую
:ext_sleep:
Аватара пользователя

CHANt
эксперт
эксперт
Сообщения: 1465
Зарегистрирован: 25 июл 2008, 10:25
Имя: Эдуард Владимирович
Страна: СССР
город/регион: Оренбург
Благодарил (а): 43 раза
Поблагодарили: 93 раза

Arduino

Сообщение CHANt »

И для примера, мой скетч с таймер-счетчиком. Суть:
каждые 17 секунд сервопривод в цикле дергает под водой за веревку чучела уток, на охоте. Потом пауза 17 сек. У сервопривода, для движения на заданный угол свой вызов таймера. Пауза в 17 сек. из-за powerbank, который без нагрузки отключался через 20 секунд. Скетч без всяких кнопок, сразу после подачи питания. Можно таймер в отдельную функцию вынести, будет удобней применять.

Код: Выделить всё

#include <Servo2.h> //вызываем библиотеку серво2
// создаём объект для управления сервоприводом
Servo2 myservo;
volatile bool timerSERV1On;    //переменная вкл/выкл таймера
bool SERV1On;        //переменная для хранения состояния таймера сервопривода
volatile unsigned long int timerSERV1, timerSERV1Loop; //переменные подсчета мс и
//хранения значения таймера
volatile bool timerSERV2On;
bool SERV2On;
volatile unsigned long int timerSERV2, timerSERV2Loop;

ISR (TIMER0_COMPA_vect) //функция, вызываемая таймером-счетчиком каждые 0,001 сек.
{
  if (timerSERV1On)      //если включен миллисекудный таймер для SERV1 включение самого сервопривода
    timerSERV1++;        //инкремент переменной таймера (+1)

  if (timerSERV2On)      //если включен миллисекудный таймер для SERV2 разрешения цикла работы сервопривода
    timerSERV2++;        //инкремент переменной таймера (+1)
}

void setup()
{
  // подключаем сервопривод к 9 пину
  myservo.attach(9);

  /**** настройка прерывания по таймеру каждую 0,001 сек (вызов функции ISR (TIMER0_COMPA_vect)) ****/
  TCCR0A |= (1 << WGM01);              //сброс при совпадении
  OCR0A = 0xF9;                        //начало отсчета до переполнения (249)
  TIMSK0 |= (1 << OCIE0A);             //разрешить прерывание при совпадении с регистром А
  TCCR0B |= (1 << CS01) | (1 << CS00); //установить делитель частоты на 64
  sei();                               //разрешить прерывания
}

void loop()
{
  
      timerSERV2On = 1;    //разрешение инкремента переменной таймера timerSERV2
      cli();              //остановка прерываний
      timerSERV2Loop = timerSERV2; //сохранение текущего значения таймера
      sei();              //разрешение прерываний

      if (timerSERV2Loop >= 17000) //если таймер отсчитал больше заданного значения
      { //то включить/выключить цикл разрешения и обнулить таймер
        if (SERV2On == 0)  //если цикл разрешения был выключен
        {
          SERV2On = 1;     //поставить флаг включения
        }
        else if (SERV2On == 1) //иначе, если цикл разрешения был включен
                  {
         SERV2On = 0;     //поставить флаг выключения
            }
        cli();    //остановить прерывания
        timerSERV2 = 0;  //обнулить таймер
        sei();    //запустить прерывания

} 
if (SERV2On == 1 )
  // устанавливаем сервопривод в крайнее левое положение
  timerSERV1On = 1;    //разрешение инкремента переменной таймера timerSERV1
  cli();              //остановка прерываний
  timerSERV1Loop = timerSERV1; //сохранение текущего значения таймера
  sei();              //разрешение прерываний

  if (timerSERV1Loop >= 800) //если таймер отсчитал больше заданного значения
  { //то включить/выключить сервопривод и обнулить таймер
    if (SERV1On == 0) //если сервопривод был выключен
    {
      SERV1On = 1;     //поставить флаг включения
      myservo.write(45);   //включить сервопривод
    }
    else //иначе, если сервопривод был выключен
    {
      SERV1On = 0;     //поставить флаг выключения
   myservo.write(150);
    }
    cli();    //остановить прерыания
    timerSERV1 = 0;  //обнулить таймер
    sei();    //запустить прерывания
  }
  else if (SERV2On == 0)
  {
  myservo.write(90); 
  }
}
--------------------------------------------------------------------------------------------
Аватара пользователя

alxndrch
здесь недавно
здесь недавно
Сообщения: 40
Зарегистрирован: 05 ноя 2017, 01:12
Имя: Александр
Страна: Россия
город/регион: Хабаровск
Благодарил (а): 3 раза
Поблагодарили: 3 раза

Arduino

Сообщение alxndrch »

CHANt писал(а): 13 май 2019, 18:19 1. функция delay - это же прерывание, т.е. остановка всей программы, полностью.
Delay это не прерывание, по крайней мере в контексте МК у понятия прерывания совершенно другое значение.

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

keysansa
эксперт
эксперт
Сообщения: 2316
Зарегистрирован: 20 дек 2018, 04:45
Имя: Сергей
Страна: РБ/РФ
город/регион: РФ Сергиев Посад
Благодарил (а): 1642 раза
Поблагодарили: 160 раз

Arduino

Сообщение keysansa »

ИМХО, delay тут не причем. Нормальная в данном случае функция.
В цикле for переменная x не инициализируется. При первом вызове она = 0, при втором 513. Вот и не входит программа в цикл собственно вращения.

Вот, причесал немного, не проверял, просто в блокноте:

Код: Выделить всё

// порты для подключения модуля ULN2003 к Arduino
#define out1 8
#define out2 9
#define out3 10
#define out4 11

#define btn3 3
#define btn4 4


int count3 = 1;
int count4 = 1;
int val3 = 0;
int val4 = 0;

int x;
int dl - ; // время задержки между импульсами

void setup() {
	pinMode(out1, OUTPUT);
	pinMode(out2, OUTPUT);
	pinMode(out3, OUTPUT);
	pinMode(out4, OUTPUT);

	pinMode(btn3, INPUT);
	pinMode(btn4, INPUT);

    
 Serial.begin(9600);
    
}

void loop() {
	
	count4 = 1;

	val3=digitalRead(btn3);
	if (val3==HIGH){
        	if (count3 < 6) {
			count3 += 1;
		} else {
			count3 = 1;
		}
		delay(500);
		Serial.println(count3);
	}

	switch (count3) {
	case 1:
		dl=30;
		analogWrite(A0,1023);
		digitalWrite(7,LOW);
		break;
	case 2:
		dl=450;
		analogWrite(A0, 0);
		analogWrite(A1, 1023);
		break;
	case 3:
		dl=900;
		analogWrite(A1,0);
		digitalWrite(5, HIGH);
		break;
	case 4:
		dl=1350;
		digitalWrite(5,LOW);
		digitalWrite(6,HIGH);
		break;
	case 5:
		dl=1800;
		digitalWrite(6,LOW);
		digitalWrite(7,HIGH);
		break;
	default: count3 = 1; break;	
	}                                    		

	val4 = digitalRead(btn4);
	if (val4==HIGH) {
		count4=0;
		delay(500);
	}


	if (count4==0){    
		for (x = 0; x<=512; x=x+1){
			digitalWrite(out1, HIGH); 
			digitalWrite(out2, LOW); 
			digitalWrite(out3, LOW); 
			digitalWrite(out4, HIGH);
			delay(dl);

			digitalWrite(out1, HIGH); 
			digitalWrite(out2, HIGH); 
			digitalWrite(out3, LOW); 
			digitalWrite(out4, LOW);
			delay(dl);

			digitalWrite(out1, LOW); 
			digitalWrite(out2, HIGH); 
			digitalWrite(out3, HIGH); 
			digitalWrite(out4, LOW);
			delay(dl);

			digitalWrite(out1, LOW); 
			digitalWrite(out2, LOW); 
			digitalWrite(out3, HIGH); 
			digitalWrite(out4, HIGH);
			delay(dl);
		}
	}
}
В трансформаторной будке живет трансформаторная собака (с) Прозрачный гонщик.
Ответить

Вернуться в «Arduino»