Возможности ардуино

Ярий
Offline
Зарегистрирован: 04.02.2020

Здравствуйте. Подскажите пожалуйста, может ли arduino параллельно обрабатывать два и более выхода? Например, крутить шаговик и управлять ШИМ. Т.е. не между сигналами ШИМ делать шаг, а параллельно, не прерывая работу одного из двигателей.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

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

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Как работает шаговик - подали сигнал на один шаг, выдержали паузу нужную для плучения требуемой скорости вращения, сделали следующий шаг. На выполнение действий для переключения катушек (шага) требуются микросекунды. Время ожидания следующего шага может быть и миллисикунды и  больше. То есть пока ждет следующего шага процессор может переделать кучу других вещей. Главное все правильно это запрограммировать.

sadman41
Offline
Зарегистрирован: 19.10.2016

Можно ещё на двух хардварных таймерах запараллелить пульсацию. Тогда все будет по-честному.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

sadman41 пишет:
Можно ещё на двух хардварных таймерах запараллелить пульсацию. Тогда все будет по-честному.

Можно, но это не для начинающих. Плюч три четверти (а может и больше) библиотек работать не будут.

Ярий
Offline
Зарегистрирован: 04.02.2020

Спасибо огромное! Зная это, будет проще реализовывать задумку. Делаю станок для заточки фрез. Про ардуино узнал пару месяцев назад. Станок должен выполнять движения вправо/влево и очень медленно на меня. Для продольной подачи я взял двигатель с шуруповёрта. Регулировать обороты решил ШИМом, но почему-то при скважности 100% его мощность была гораздо ниже, чем при питании 12 вольт. К тому же при попытке уменьшить обороты ниже 80% контроллер зависал. Попытался отследить монитором ком порта. При зависании в порте появлялся различный мусор. Я посчитал что это из за наводок на длинные провода, между переменными резисторами, кнопками и самопальным драйвером (использовал нано).Взял uno + шилд с экраном 16х2. Пока изучаю тонкости написания меню решил пообщаться с грамотными людьми, может чему и научусь ) Ещё раз спасибо.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

sadman41 пишет:
Можно ещё на двух хардварных таймерах запараллелить пульсацию. Тогда все будет по-честному.

И это не будет параллельным выполнением кода, по определению ;) Всё равно всё выполняется последовательно, просто по прерываниям, которые вклиниваются, когда им надо. Но это не параллельность выполнения процессов, ты же в курсе ;)

sadman41
Offline
Зарегистрирован: 19.10.2016

DIYMan пишет:

sadman41 пишет:
Можно ещё на двух хардварных таймерах запараллелить пульсацию. Тогда все будет по-честному.

И это не будет параллельным выполнением кода, по определению ;)

Пащиму, нащальникама? Один таймер запускаем в PWM, второй в CTC, к примеру. Переключаемся не в прерывании, а хардварно перекидывая ногу. Или запускаем на аксельстеппере движок, а PWM-ом пусть продолжает рулить analogWrite().

Движки же ему не в мегагерцах крутить, полагаю, требуется, так что все должно быть OK с параллельностью.

sadman41
Offline
Зарегистрирован: 19.10.2016

asam пишет:

sadman41 пишет:
Можно ещё на двух хардварных таймерах запараллелить пульсацию. Тогда все будет по-честному.

Можно, но это не для начинающих. Плюч три четверти (а может и больше) библиотек работать не будут.

Насчет совместимости с библиотеками не было требований ;)

 

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Ярий пишет:

 Для продольной подачи я взял двигатель с шуруповёрта. Регулировать обороты решил ШИМом, но почему-то при скважности 100% его мощность была гораздо ниже, чем при питании 12 вольт. К тому же при попытке уменьшить обороты ниже 80% контроллер зависал. 

Хм.. И как вы этот двинатель к ардуино подключили? Желательно схему привести.

Ярий
Offline
Зарегистрирован: 04.02.2020

sadman41 пишет:
Можно ещё на двух хардварных таймерах запараллелить пульсацию. Тогда все будет по-честному.
 

А можно ссылочку, для изучения, как это сделать? Или своими словами, может соображу. 

Ярий
Offline
Зарегистрирован: 04.02.2020

Прошу прощения, я пока не разобрался как картинки прикреплять ( Постараюсь разораться и всё прикреплю и отправлю.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Ярий пишет:

sadman41 пишет:
Можно ещё на двух хардварных таймерах запараллелить пульсацию. Тогда все будет по-честному.
 

А можно ссылочку, для изучения, как это сделать? Или своими словами, может соображу. 

http://electricalschool.info/elprivod/1864-upravlenie-shagovyjj-dvigatelem.html

https://www.sparkfun.com/datasheets/Components/SMD/ATMega328.pdf  - разделы 8-bit Timer/Counter0 with PWM и далее про остальные таймеры

 

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Ярий пишет:

Прошу прощения, я пока не разобрался как картинки прикреплять ( Постараюсь разораться и всё прикреплю и отправлю.

http://arduino.ru/forum/obshchii/sokhranenie-kartinok-na-forume

Ярий
Offline
Зарегистрирован: 04.02.2020

Ярий
Offline
Зарегистрирован: 04.02.2020

Вытравил плату, посадил на радиатор (на всякий случай). Более-менее работало...

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Ярий пишет:

Вытравил плату зде, посадил на радиатор (на всякий случай). Более-менее работало...

Зачем плату здесь? Схему надо. И код (скетч)

Ярий
Offline
Зарегистрирован: 04.02.2020

asam, Спасибо, вроде разобрался.

Ярий
Offline
Зарегистрирован: 04.02.2020

Ну, схема не отличается от платы. А на счёт кода, прошу не пинать, только осваиваю...

boolean butt_flag=0;
boolean butt;
boolean led13=0;
boolean naprav=0; // направление движения
unsigned long last_press;
unsigned long last_time;
#define potent_pin 1 // потенциометр изменения скорости вращения
#define potent_speed_pin 2  // потенциометр изменения продолжительности вращения в одну сторону
int val; // переменная val отвечает за скорость вращения двигателя
int time_1; // время движения двигателя в одну сторону
 
void setup() {
  pinMode(A0, INPUT_PULLUP);
  pinMode(13, OUTPUT);
  Serial.begin(9600);
  Serial.println("Запуск ");
  pinMode(9, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(5, OUTPUT);
}
 
void loop() {
  val = analogRead(potent_pin);
  val = map(val, 0, 1023, 150, 255);
  val = constrain(val, 150, 255);
  time_1 = analogRead(potent_speed_pin);
  time_1 = map(time_1, 0, 1023, 0, 150);
  time_1 = constrain(time_1, 0, 150);
  
  Serial.print("Потенциометр: ориг - "); Serial.print(analogRead(potent_pin) ); Serial.print("  После мап - "); Serial.println(val);
  Serial.print(" Смена направления - "); Serial.print(analogRead(potent_speed_pin) ); Serial.print("  После мап - "); Serial.println(time_1);
 
  if (millis() - last_time >time_1*50) {
    last_time = millis();
    naprav = !naprav;
  }
  butt = !digitalRead(A0);
  if (butt == 1 && butt_flag == 0 && millis() - last_press > 20) {
    butt_flag = 1;
    led13 = !led13;
    digitalWrite(13, led13);
    last_press = millis();
    }
    if (butt == 0 && butt_flag == 1) {
      butt_flag = 0;      
      digitalWrite(5, 0);
      digitalWrite(6, 0);
      digitalWrite(9, 0);
      digitalWrite(3, 0);
    }
    if (led13 == 1) {
//      Serial.println("   ----- Питание подано ----");
      if (naprav == 0) {      
        Serial.println("   Вправо");
        digitalWrite(5, 0);
        digitalWrite(6, 0);
        digitalWrite(9, 1);
        analogWrite(3, val);
      } else {
        Serial.println("   Влево");
      digitalWrite(3, 0);
      digitalWrite(9, 0);
      digitalWrite(6, 1);
      analogWrite(5, val);
      }
    }
}
Ярий
Offline
Зарегистрирован: 04.02.2020

На плате указаны контакты для подключения ардуино.

Ярий
Offline
Зарегистрирован: 04.02.2020

Извиняйте за "Serial.print", не мог понять почему контролер зависает. Подчищать не стал.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Ярий пишет:

На плате указаны контакты для подключения ардуино.

Во-первых: Удосужтесь прочитать правила форума вообще и в частности вставить код правильно - http://arduino.ru/forum/obshchii/pesochnitsa-dlya-vsekh-novichkov

Во-вторых на плате не указаны ни номиналы резисторов ни тип транзисторов.

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

Ярий
Offline
Зарегистрирован: 04.02.2020

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

Ярий
Offline
Зарегистрирован: 04.02.2020

Код по правилам. 

boolean butt_flag=0;
boolean butt;
boolean led13=0;
boolean naprav=0; // направление движения
unsigned long last_press;
unsigned long last_time;
#define potent_pin 1 // потенциометр изменения скорости вращения
#define potent_speed_pin 2  // потенциометр изменения продолжительности вращения в одну сторону
int val; // переменная val отвечает за скорость вращения двигателя
int time_1; // время движения двигателя в одну сторону

void setup() {
  pinMode(A0, INPUT_PULLUP);
  pinMode(13, OUTPUT);
  Serial.begin(9600);
  Serial.println("Запуск ");
  pinMode(9, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(5, OUTPUT);
}

void loop() {
  val = analogRead(potent_pin);
  val = map(val, 0, 1023, 150, 255);
  val = constrain(val, 150, 255);
  time_1 = analogRead(potent_speed_pin);
  time_1 = map(time_1, 0, 1023, 0, 150);
  time_1 = constrain(time_1, 0, 150);
  
  Serial.print("Потенциометр: ориг - "); Serial.print(analogRead(potent_pin) ); Serial.print("  После мап - "); Serial.println(val);
  Serial.print(" Смена направления - "); Serial.print(analogRead(potent_speed_pin) ); Serial.print("  После мап - "); Serial.println(time_1);

  if (millis() - last_time >time_1*50) {
    last_time = millis();
    naprav = !naprav;
  }
  butt = !digitalRead(A0);
  if (butt == 1 && butt_flag == 0 && millis() - last_press > 20) {
    butt_flag = 1;
    led13 = !led13;
    digitalWrite(13, led13);
    last_press = millis();
    }
    if (butt == 0 && butt_flag == 1) {
      butt_flag = 0;      
      digitalWrite(5, 0);
      digitalWrite(6, 0);
      digitalWrite(9, 0);
      digitalWrite(3, 0);
    }
    if (led13 == 1) {
      if (naprav == 0) {      
        Serial.println("   Вправо");
        digitalWrite(5, 0);
        digitalWrite(6, 0);
        digitalWrite(9, 1);
        analogWrite(3, val);
      } else {
        Serial.println("   Влево");
      digitalWrite(3, 0);
      digitalWrite(9, 0);
      digitalWrite(6, 1);
      analogWrite(5, val);
      }
    }
}

 

Ярий
Offline
Зарегистрирован: 04.02.2020

транзистор IRF 3205

Ярий
Offline
Зарегистрирован: 04.02.2020

Все параллельные резисторы имеют одинаковый номинал.

sadman41
Offline
Зарегистрирован: 19.10.2016

А шаговый какой?

Ярий
Offline
Зарегистрирован: 04.02.2020

Простенький 28BYJ-48.

sadman41
Offline
Зарегистрирован: 19.10.2016

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

Ярий
Offline
Зарегистрирован: 04.02.2020

Меня asam спрашивал, как я двигатель подключал, вот я и основной код и выкинул.  

А шаговик я тупо, сам запускал, между проходами.

//        Shagovik.step(Steps); // Делаем количество шагов (300) определённые в описании
    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);

    digitalWrite( in1, HIGH ); 
    digitalWrite( in2, LOW ); 
    digitalWrite( in3, LOW ); 
    digitalWrite( in4, HIGH );
    delay(dl); 
        Serial.println("   запускаем шаговик");
        start_flag = !start_flag;
        smenaNapr = 0;

 

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Ярий пишет:

транзистор IRF 3205

 

Они не открываются полностью от 5В

Ярий
Offline
Зарегистрирован: 04.02.2020

Ого, вот этого не ожидал, многие ютуберы используют его для управления светодиодной ленты. А я и не додумался в датащит посмотреть. Спасибо. (Не доверяй никому)

sadman41
Offline
Зарегистрирован: 19.10.2016

Даже с делеями код не будет прерывать работу хардварного PWM. При данном раскладе изучение таймеров не особо нужно. Скорее всего, как asam и пишет, проблема в транзисторах. А кажется, как-будто ардуина не тащит.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

sadman41 пишет:

Пащиму, нащальникама? Один таймер запускаем в PWM, второй в CTC, к примеру. Переключаемся не в прерывании, а хардварно перекидывая ногу. Или запускаем на аксельстеппере движок, а PWM-ом пусть продолжает рулить analogWrite().

Движки же ему не в мегагерцах крутить, полагаю, требуется, так что все должно быть OK с параллельностью.

Ок, принимается. Я, собственно, немножко про другое: есть два куска кода прошивки, которые надо выполнять параллельно. Шо получается? Только через псевдомногозадачность: выполнили кусочек, переключились на другой контекст, выполнили кусочек, далее по кругу.

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

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Ярий пишет:

Ого, вот этого не ожидал, многие ютуберы используют его для управления светодиодной ленты. А я и не додумался в датащит посмотреть. Спасибо. (Не доверяй никому)

Ну если добавить транзистор, то и 5ю вольтами можно будет полностью открыть. А насчет лент - из-за нелинейного восприятия яркости человеком, неполное открыте  МОСФЕТа не сильно заметно, особенно если сравнить не с чем.