Ардуино ПРО МИНИ + 2 ULN2003A + 2 шаговика

baspav
Offline
Зарегистрирован: 16.04.2015

 

Нашел способ заставить моторы крутиться только в случае нажатой кнопки. Но почему-то работает только с первой кнопкой. Когда аналогично прописываю вторую кнопку - пишет: collect2.exe: error: ld returned 5 exit status.
 

/* Исходный скетчДмитрий Осипов. http://www.youtube.com/user/d36073?feature=watch

v.01 button resistor Arduino Шаговый двигатель 28BYJ-48 – 5V Stepper Motor

----------------------------------------
Скачать sketch.
v.01 вправо влево Arduino Шаговый двигатель 28BYJ-48 – 5V Stepper Motor
https://yadi.sk/d/9trcfiK7ULkQS

v.01 button resistor Arduino Шаговый двигатель 28BYJ-48 – 5V Stepper Motor

*/


///////////////////////////////////////////////////////////////

// Назначение пинов выводам для UNL 2003A 1 мотора
int motorPin1 = 6;
int motorPin2 = 7;
int motorPin3 = 8;
int motorPin4 = 9;

// Назначение пинов выводам для UNL 2003A 2 мотора
int motorPin5 = 10;
int motorPin6 = 11;
int motorPin7 = 12;
int motorPin8 = 13;

// Назначение пинов выводам кнопок (один вывод кнопок - соответственно, а второй - на GND)
int buttonPin_1 = 2;
int buttonPin_2 = 3;

// фиксируем нажатие на первую и вторую кнопку соответственно.
boolean q;
boolean w;

// установить скорость шагового двигателя.
//variable to set stepper speed.
int motorSpeed = 14000;

int lookup_1[8] = {
B01000, B01100, B00100, B00110, B00010, B00011, B00001, B01001};
int lookup_2[8] = {
B01000, B01100, B00100, B00110, B00010, B00011, B00001, B01001};

/////////////////////////////////////////////////////////////////

void setup() {
// Заявляем пины моторов как выходные
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(buttonPin_1, INPUT);
pinMode(buttonPin_2, INPUT);

//Устанавливаем высокий сигнал на пинах отжатых кнопок
digitalWrite(buttonPin_1, HIGH);
digitalWrite(buttonPin_2, HIGH);
// Serial.begin(9600);
}

////////////////////////////////////////////////////////////////

void loop(){

if (digitalRead(buttonPin_1) == LOW) // если кнопка 1 нажата.
{
q = !q; // меняем значение q на противоположное 0 на 1 или 1 на 0.
delay(500); // защита от дребезга кнопки.
}

if (digitalRead(buttonPin_1) == LOW) {// если кнопка 1 нажата.

if (q == 1){
while (digitalRead(buttonPin_1) == LOW){
anticlockwise_1(); // Мотор 1 крутим влево.
}

} else {
while (digitalRead(buttonPin_1) == LOW){
clockwise_1(); // Мотор 1 крутим вправо.
}
}
} else {

digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);
}

/////////////////////////////
if (digitalRead(buttonPin_2) == LOW) // если кнопка 2 нажата.
{
w = !w; // меняем значение q на противоположное 0 на 1 или 1 на 0.
delay(500); // защита от дребезга кнопки.
}
// эти две строки - работают, но постоянно с перерывом на время работы мотора_1
if (w == 1) anticlockwise_2(); // Мотор_2 крутим влево.
else clockwise_2(); // Мотор_2 крутим вправо.

}
/* // А вот с этим фрагментом вместо предыдущих двух строчек почему-то не работает пишет collect2.exe: error: ld returned 5 exit status.

if (w == 1){
while (digitalRead(buttonPin_2) == LOW){
anticlockwise_2(); // Мотор 2 крутим влево.
}

} else {
while (digitalRead(buttonPin_2) == LOW){
clockwise_2(); // Мотор 2 крутим вправо.
}
}
} else {

digitalWrite(motorPin5, LOW);
digitalWrite(motorPin6, LOW);
digitalWrite(motorPin7, LOW);
digitalWrite(motorPin8, LOW);
}
*/

// //////////////////////////////////////////////////////////////

// функция поворачивает мотор 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 setStop_1(int out)
{
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);
}

void setStop_2(int out)
{
digitalWrite(motorPin5, LOW);
digitalWrite(motorPin6, LOW);
digitalWrite(motorPin7, LOW);
digitalWrite(motorPin8, LOW);
}

Все проверил - вроде все правильно. Убираю "while (digitalRead(buttonPin_1) == LOW)" - ошибки нет, но мотор_2 продолжает крутиться при разомкнутой кнопке.
Мне же нужно чтоб кнопка_2 работала точно так же, как кнопка_1 и при замыкании двух кнопок оба мотора работали одновременно и независимо.
Помогите, пожалуйста.

baspav
Offline
Зарегистрирован: 16.04.2015

Исправил сам - обе кнопки работают аналогично. Но как сделать, чтоб они работали одновременно и независимо?

/* Исходный скетчДмитрий Осипов. http://www.youtube.com/user/d36073?feature=watch
 
 v.01 button resistor Arduino Шаговый двигатель 28BYJ-48 – 5V Stepper Motor
 
 ----------------------------------------
 Скачать sketch.
 v.01 вправо влево Arduino Шаговый двигатель 28BYJ-48 – 5V Stepper Motor
 https://yadi.sk/d/9trcfiK7ULkQS
 
 v.01 button resistor Arduino Шаговый двигатель 28BYJ-48 – 5V Stepper Motor
 
  */


///////////////////////////////////////////////////////////////

// Назначение пинов выводам для UNL 2003A 1 мотора
int motorPin1 = 6; 
int motorPin2 = 7; 
int motorPin3 = 8; 
int motorPin4 = 9; 

// Назначение пинов выводам для UNL 2003A 2 мотора
int motorPin5 = 10;
int motorPin6 = 11;
int motorPin7 = 12; 
int motorPin8 = 13;

// Назначение пинов выводам кнопок (один вывод кнопок - соответственно, а второй - на GND)
int buttonPin_1 = 2;                      
int buttonPin_2 = 3;                       

// фиксируем нажатие на первую и вторую кнопку соответственно.
boolean  q;    
boolean  w;   

// установить скорость шагового двигателя.
//variable to set stepper speed.
int motorSpeed = 14000;        

int lookup_1[8] = {
  B01000, B01100, B00100, B00110, B00010, B00011, B00001, B01001};
int lookup_2[8] = {
  B01000, B01100, B00100, B00110, B00010, B00011, B00001, B01001};
  
/////////////////////////////////////////////////////////////////

void setup() {
  // Заявляем пины моторов как выходные
  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(buttonPin_1, INPUT);
  pinMode(buttonPin_2, INPUT);
  
  //Устанавливаем высокий сигнал на пинах отжатых кнопок  
  digitalWrite(buttonPin_1, HIGH);
  digitalWrite(buttonPin_2, HIGH);
  // Serial.begin(9600);
}

////////////////////////////////////////////////////////////////

void loop(){

  if (digitalRead(buttonPin_1) == LOW) // если кнопка 1 нажата.
  {
    q = !q; // меняем значение q на противоположное 0 на 1 или 1 на 0.
    delay(500); // защита от дребезга кнопки.
  }

 if (digitalRead(buttonPin_1) == LOW) {// если кнопка 1 нажата.
  
  if (q == 1){
     while (digitalRead(buttonPin_1) == LOW){
    anticlockwise_1(); // Мотор 1 крутим влево.
  }

} else {
   while (digitalRead(buttonPin_1) == LOW){
  clockwise_1(); // Мотор 1 крутим вправо.
   }
 }
 } else {

  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
 }
 
 ///////////////////////////// 
  if (digitalRead(buttonPin_2) == LOW) // если кнопка 2 нажата.
  {
    w = !w; // меняем значение q на противоположное 0 на 1 или 1 на 0.
    delay(500); // защита от дребезга кнопки.
  }
   if (digitalRead(buttonPin_2) == LOW) {// если кнопка 1 нажата.
  
  if (w == 1){
     while (digitalRead(buttonPin_2) == LOW){
    anticlockwise_2(); // Мотор 2 крутим влево.
  }

} else {
   while (digitalRead(buttonPin_2) == LOW){
  clockwise_2(); // Мотор 2 крутим вправо.
   }
 }
 } else {

  digitalWrite(motorPin5, LOW);
  digitalWrite(motorPin6, LOW);
  digitalWrite(motorPin7, LOW);
  digitalWrite(motorPin8, LOW);
 }
 }
 
 
// //////////////////////////////////////////////////////////////

// функция поворачивает мотор 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));
}


 

maksim
Offline
Зарегистрирован: 12.02.2012

AccelStepper пример MultiStepper

baspav
Offline
Зарегистрирован: 16.04.2015

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

Есть маленькие нюансы, которые хотелось бы исправить, но после теста вижу, что скетч на 95% удовлетворяет моим требованиям.

Если кому пригодится - вот материалы по моему проэкту.

 

Солнечный трекер на Ардуино ПРО МИНИ + 2 ULN2003A + 2 шаговика - вот он:

Детали:
Макетная плата - 1шт
Подставка под микросхему подходящая к ПРО МИНИ - 1 шт
Ардуино ПРО МИНИ - 1 шт
ULN2003A - 2 шт
шаговики - 2 шт
оры 10 КОм - 5 шт
Фото резисторы - 3 шт

Концевики - 2 шт
Проводки, гнезда, гнезда питания - по потребности

Скетч:



#define TILTL 2
#define TILTH 3
#define BOTTOM 2
#define TOPLEFT 0
#define TOPRIGHT 1
#include "math.h"

// Назначение пинов выводам для UNL 2003A 1 мотора
int motorPin1 = 6;
int motorPin2 = 7;
int motorPin3 = 8;
int motorPin4 = 9;

// Назначение пинов выводам для UNL 2003A 2 мотора
int motorPin5 = 10;
int motorPin6 = 11;
int motorPin7 = 12;
int motorPin8 = 13;

// Назначение пинов выводам кнопок (один вывод кнопок - соответственно, а второй - на GND)
int tlsense;
int trsense;
int bsense;
int tavg;
int diff;
int spd;
int divisor;
int sensitivity;
int tiltl;
int tilth;


// установить скорость шагового двигателя.
//variable to set stepper speed.
int motorSpeed = 14000;

int lookup_1[8] = {
B01000, B01100, B00100, B00110, B00010, B00011, B00001, B01001};
int lookup_2[8] = {
B01000, B01100, B00100, B00110, B00010, B00011, B00001, B01001};

/////////////////////////////////////////////////////////////////

void setup () {
divisor = 10; // this controls the speed of the servo. lower number = higher speed
sensitivity = 30; // this controls the sensitivity of the tracker. lower number = higher sensitivity. if your tracker is constantly jittering back and forth increase the number
Serial.begin(9600); // open serial com
Serial.print("SolarTracker ready!");
pinMode(BOTTOM, INPUT); // set the inputs
pinMode(TOPLEFT, INPUT);
pinMode(TOPRIGHT, INPUT);
pinMode(TILTL, INPUT);
pinMode(TILTH, INPUT);
pinMode(motorPin1, OUTPUT);
pinMode(motorPin2, OUTPUT);
pinMode(motorPin3, OUTPUT);
pinMode(motorPin4, OUTPUT);
pinMode(motorPin5, OUTPUT);
pinMode(motorPin6, OUTPUT);
pinMode(motorPin7, OUTPUT);
pinMode(motorPin8, OUTPUT);

}

///////////////////////////////////////////////////////

void loop () {

tiltl = digitalRead(TILTL); // read the tilt sensor
tilth = digitalRead(TILTH);
tlsense = analogRead(TOPLEFT); // read the light sensors
trsense = analogRead(TOPRIGHT);
bsense = analogRead(BOTTOM);
bsense = bsense * 1.05; // I had to adjust the value of this sensor to make it more accurate. you might have to do the same but start by leaving it alone
tavg = (tlsense + trsense)/2; // get an average value for the top 2 sensors
diff = abs(tavg - bsense); // this judges how far the tracker must turn
spd = diff/divisor; // and adjusts the speed of the reaction accordingly
spd = max(spd, 1); // sets the minimum speed to 1
Serial.print("\nTOP: "); Serial.print(tavg, DEC); // print the sensor values to the serial com
Serial.print("\tBOTTOM:"); Serial.print(bsense, DEC);
Serial.print("\tLEFT:"); Serial.print(tlsense, DEC);
Serial.print("\tRIGHT:"); Serial.print(trsense, DEC);

if((tavg < bsense) && (diff > sensitivity) && (tiltl == HIGH) && (tilth == HIGH)){ // if the average value of the top sensors is smaller (more light) than the bottom sensor and the tilt sensor is in the correct range

clockwise_1(); // Мотор 1 крутим вправо.

Serial.print("\tState: "); Serial.print("V_UP!");
}else if((tavg < bsense) && (diff > sensitivity) && (tiltl == HIGH) && (tilth == LOW)){ // if the average value of the top sensors is smaller (more light) than the bottom sensor and the tilt sensor is in the correct range

digitalWrite(motorPin1, LOW); //останавливаем мотор
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);

Serial.print("\tState: "); Serial.print("V_STOP!");
}else if((tavg > bsense) && (diff > sensitivity) && (tiltl == HIGH) && (tilth == HIGH)){ // if the value of the bottom sensor is smaller (more light) than the average value of the top sensors and the tilt sensor is in the correct range

anticlockwise_1(); // Мотор 1 крутим влево.

Serial.print("\tState: "); Serial.print("V_DOWN!");
}else if((tavg > bsense) && (diff > sensitivity) && (tiltl == LOW) && (tilth == HIGH)){ // if the value of the bottom sensor is smaller (more light) than the average value of the top sensors and the tilt sensor is in the correct range

digitalWrite(motorPin1, LOW); //останавливаем мотор
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);

Serial.print("\tState: "); Serial.print("V_STOP!");
}else{ // for every other instance
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);

}

tlsense = analogRead(TOPLEFT); // read the top 2 sensors again because they have probably changed
trsense = analogRead(TOPRIGHT);
trsense = trsense * 1.03; // again I had to adjust the value of one sensor to make the tracker more accurate
diff = abs(tlsense - trsense); // reset the diff variable for the new values
spd = diff/divisor; // and generate a speed accordingly
spd = max(spd, 1); // set the minimum speed to 1

if((tlsense < trsense) && (diff > sensitivity)){ // if the top left sensor value is smaller (more light) than the top right sensor

clockwise_2(); // Мотор 2 крутим вправо.

Serial.print("\tState: "); Serial.print("H_RIGHT!");
}else if((tlsense > trsense) && (diff > sensitivity)){ // if the top left sensor value is larger (less light) than the top right sensor

anticlockwise_2(); // Мотор 2 крутим влево.

Serial.print("\tState: "); Serial.print("H_LEFT!");
}else{ // for every other instance

digitalWrite(motorPin5, LOW);
digitalWrite(motorPin6, LOW);
digitalWrite(motorPin7, LOW);
digitalWrite(motorPin8, LOW);

Serial.print("\tState: "); Serial.print("H_STOP!");
}

delay(10); // delay 10ms
}

// //////////////////////////////////////////////////////////////

// функция поворачивает мотор 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));
}

Успехов!