#1 2015-04-15 08:01:26

baspav
Учасник
Зареєстрований: 2015-04-02
Повідомлень: 12

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

Собираю самонаводящийся солар трекер. после ДОЛГОГО И УПОРНОГО серфинга в нете нарыл проэкт мистера Адама http://www.instructables.com/id/Arduino … /?ALLSTEPS, но в нем используются отсутствующие у меня (по причине зашитых карманов) 360-градусные серво. Решил переделать его под 2 ULN2003A + 2 28BYJ-48-5V (по цене 2+2 дешевле чем 1 серво-360). Статей о подключении такой схемы не нашел. Решил попробовать запустить сперва схему без фотосенсора.  Нашел в нете понятный мне скетч и, поколдовав, получил это:

-----------------------------------------------------------------------------------

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

 Скачать sketch.
 v.01 вправо влево Arduino Шаговый двигатель 28BYJ-48 – 5V Stepper Motor
 [url]https://yadi.sk/d/9trcfiK7ULkQS[/url]
 
 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 (q == 1)anticlockwise_1(); // Мотор 1 крутим влево.

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

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

  else clockwise_2(); // Мотор 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));
}

--------------------------------------------------------------------

Заработало. Направление кнопками меняется успешно.
Но:
1. шаговики ступают по очереди
Вопрос: как сделать, чтоб они крутились независимо?
2. При нажатии на одну кнопку останавливаются оба двигателя, а потом на соответствующем меняется направление.
Вопрос: как сделать, чтоб при нажатии на одну кнопку останавливался только один мотор, который должен менять направление?

Если заинтересует - могу залить видео работы сборки.

Остання редакція baspav (2015-04-26 11:37:02)

Неактивний

#2 2015-04-26 11:04:35

baspav
Учасник
Зареєстрований: 2015-04-02
Повідомлень: 12

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

Нашел способ заставить моторы крутиться только в случае нажатой кнопки. Но почему-то работает только с первой кнопкой. Когда аналогично прописываю вторую кнопку - пишет: 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 (2015-04-26 12:45:47)

Неактивний

#3 2015-04-27 00:45:11

vvr
Учасник
Зареєстрований: 2015-04-12
Повідомлень: 875

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

внимательно посмотрите алгоритм работы первой кнопки и повторите со второй - там нет в коде нескольких условий при прописывании работы второй кнопки.

Остання редакція vvr (2015-04-27 00:45:59)

Неактивний

#4 2015-04-27 06:05:54

baspav
Учасник
Зареєстрований: 2015-04-02
Повідомлень: 12

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

Спасибо, нашел.
Ну что ж, склеил части двух скетчей и получил следующее:

Двуосевой трекер для солнечной батареи на шаговых двигателях.
Ардуино ПРО МИНИ + 2 ULN2003A + 2 28BYJ-48-5V

#define TILTL 2
 #define TILTH 3
 #define BOTTOM 2
 #define TOPLEFT 0
 #define TOPRIGHT 1
// #include <AccelStepper.h>
 #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;                   

// фиксируем нажатие на первую и вторую кнопку соответственно.
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 () {
   // divisor = 10; // this controls the speed of the servo. lower number = higher speed
   sensitivity = 10; // 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(19200); // 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);
 digitalWrite(TILTL, HIGH);
 digitalWrite(TILTH, HIGH);
  }

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

 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("UP!");
 }else if((tavg < bsense) && (diff > sensitivity) && (tiltl == LOW) && (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("UP!");
 }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("DOWN!");
 }else if((tavg > bsense) && (diff > sensitivity) && (tiltl == HIGH) && (tilth == LOW)){ // 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("DOWN!");
 }else{ // for every other instance
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
 
 clockwise_1(); // Мотор 1 крутим вправо.
 
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
 //Serial.print("\tState: "); Serial.print("STOP!");
 }

 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("LEFT!");
 }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("RIGHT!");
 }else{ // for every other instance
 
  digitalWrite(motorPin5, LOW);
  digitalWrite(motorPin6, LOW);
  digitalWrite(motorPin7, LOW);
  digitalWrite(motorPin8, LOW);
 
 //Serial.print("\tState: "); Serial.print("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));
}

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);
}

Мне посоветовали сделать его на библиотеке Accelstepper, но я в ней только запутался - с Ардуино столкнулся впервые и то именно по причине монтажа солар трекера. - и потому сделал, как смог.
Скетч скомпилился и в дуинке успешно заработал.
Но хотелось бы увеличить "слепую" зону, чтоб трекер не дергался туда-сюда при малейшем изменении освещености.
Поможете?

Неактивний

#5 2015-04-27 07:55:51

vvr
Учасник
Зареєстрований: 2015-04-12
Повідомлень: 875

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

автор написал
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
поиграйтесь с коэф.

Неактивний

#6 2015-05-03 13:11:53

baspav
Учасник
Зареєстрований: 2015-04-02
Повідомлень: 12

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

Все оказалось намного проще. Там для этого предусмотрено
   sensitivity = 10; // this controls the sensitivity of the tracker. lower number = higher sensitivity. if your tracker is constantly jittering back and forth increase the number

и дальше в скетче
if ...  && (diff > sensitivity)...

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

В результате, после регулировок параметров есть скетч, который полностью удовлетворяет моим требованиям
Так что если кому-то нужен
Солнечный трекер на Ардуино ПРО МИНИ  + 2 ULN2003A + 2 шаговика - вот он:

Solar-Tracker-Duino-Pro-Mini.jpeg

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



Скетч:

#define TILTL 2
 #define TILTH 3
 #define BOTTOM 2
 #define TOPLEFT 0
 #define TOPRIGHT 1
// #include <AccelStepper.h>
 #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);
 //digitalWrite(TILTL, HIGH);
 //digitalWrite(TILTH, HIGH);
  
   }

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

 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
 
 //clockwise_1(); // Мотор 1 крутим вправо.
 
  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
 
 //anticlockwise_1(); // Мотор 1 крутим влево.
  
  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);
 
 //clockwise_1(); // Мотор 1 крутим вправо.
 
 // digitalWrite(motorPin1, LOW);
 // digitalWrite(motorPin2, LOW);
 // digitalWrite(motorPin3, LOW);
 // digitalWrite(motorPin4, LOW);
 //Serial.print("\tState: "); Serial.print("STOP!");
 }

 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));
}

Успехов!

Неактивний

#7 2015-05-05 11:22:19

brigadir
Учасник
Зареєстрований: 2015-03-04
Повідомлень: 17

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

baspav, респект!
Покажеш, як працює в польових умовах?

Неактивний

#8 2015-05-05 13:41:05

baspav
Учасник
Зареєстрований: 2015-04-02
Повідомлень: 12

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

Ок. Механическая часть пока не готова, как работает сама электроника, "с руки" так сказать могу показать уже. Или Вам полностью готовый нужен?

Неактивний

#9 2015-11-05 19:40:36

Дмитрий Харитонов
Гість

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

Доброго времени суток. Очень интересна ваша тема. Я задался идеей собрать виндер для механических часов на arduino.Управление одним двигателем это не проблема, но вот уже неделю мучаюсь с подключением двух. Не могли бы вы показать свою электрическую схему.

#10 2015-11-05 19:40:40

Дмитрий Харитонов
Гість

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

Доброго времени суток. Очень интересна ваша тема. Я задался идеей собрать виндер для механических часов на arduino.Управление одним двигателем это не проблема, но вот уже неделю мучаюсь с подключением двух. Не могли бы вы показать свою электрическую схему.

#11 2015-11-05 19:41:02

Дмитрий Харитонов
Гість

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

Доброго времени суток. Очень интересна ваша тема. Я задался идеей собрать виндер для механических часов на arduino.Управление одним двигателем это не проблема, но вот уже неделю мучаюсь с подключением двух. Не могли бы вы показать свою электрическую схему.

Швидке повідомлення

Введіть повідомлення і натисніть Надіслати

Підвал форуму