#2 Re: Програмування Arduino » проблем: солнечный трекер промахивается мимо "Солнца" » 2017-12-05 14:40:32

Уважаемый ВР, я уже в финале!
Модель работает.
Дальше можно говорить лишь об оптимизации, но это уже вопрос развития, а не школьного проекта первоклассника.
Но я не оспариваю ваше право на свой вариант и не против обсудить преимущества разных подходов.

#3 Re: Програмування Arduino » проблем: солнечный трекер промахивается мимо "Солнца" » 2017-12-05 13:04:32

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

#4 Re: Програмування Arduino » проблем: солнечный трекер промахивается мимо "Солнца" » 2017-12-05 08:16:06

Ура! заработала

обнаружил, что когда вручную кручу башню, выход из цикла есть, но при автоматическом повороте от мотора из цикла не выходит, хотя по показаниям датчиков вижу, что условие   dhoriz > tol должно выполниться

добавил в цикл
  if (dhoriz > tol) {break;}
теперь есть и выход и остановка точно под лампой.

дальше буду отлаживать вертикаль

ПС: почему не работает выход из цикла по  while (dhoriz > tol) ???
Может быть дело в скорости, типа контроллер не успевает послать команду СТОП вовремя и моторы продолжают крутиться, проходя "мертвую зону"?

#5 Re: Програмування Arduino » проблем: солнечный трекер промахивается мимо "Солнца" » 2017-12-05 07:56:58

Коллеги, добавил отладочную часть:
  Serial.print("end loop while");
  Serial.print(" ");

  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(500);              // wait for a second
  digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
  delay(500);              // wait for a second

кручу руками, вижу, что из цикла while выход  есть
видимо что-то не так в этой части:
    analogWrite (ENA, 0);
    digitalWrite (IN2, LOW);
    digitalWrite (IN1, LOW);


может быть неправильно использую analogWrite ?

#6 Re: Програмування Arduino » проблем: солнечный трекер промахивается мимо "Солнца" » 2017-12-04 16:10:53

Про мертвую зону:
Разве это не она?
dhoriz > tol

Tol - Это порог , если разница по горизонтали или по вертикали больше него, то включаю соответствующие моторы, иначе - выключаю.
Только они не выключаются

#7 Re: Програмування Arduino » проблем: солнечный трекер промахивается мимо "Солнца" » 2017-12-04 15:58:34

Может вы и правы насчёт расположения датчиков. Но проверил монитором , что на датчиках в момент поворота:  башня трекера продолжала двигаться , когда разница была меньше порога - должна была остановиться.

#8 Re: Програмування Arduino » проблем: солнечный трекер промахивается мимо "Солнца" » 2017-12-04 00:34:12

SOLAR_3

//датчики
int ldrlt = A1; //LDR top left - верх лево
int ldrrt = A2; //LDR top rigt - верх право
int ldrld = A4; //LDR down left - низ лево
int ldrrd = A3; //ldr down rigt - низ право

int tol = 50; //чувствительность 100

//motors
int ENA = 9; //мотор А - горизонталь
int IN1 = 7;
int IN2 = 6;

int IN3 = 5; // Input1 подключен к выводу 5 
int IN4 = 4;
int ENB = 3; //мотор В - вертикаль
int i=150; // speed motor
//
  int lt; // top left верх лево
  int rt ;// top right верх пр
  int ld ;// down left низ лево
  int rd ;// down rigt низ право

 // средние значения по четырем сторонам
  int avt; // average value top - среднее верх
  int avd; // average value down- -- низ
  int avl; // average value left - -- левое
  int avr; // average value right -- правое

//  разницу между верхом и низом, правой и левой сторонами
  int dvert; // check the diffirence of up and down
  int dhoriz;// check the diffirence of left and right

void setup()
{
//moto
  pinMode (ENA, OUTPUT);
  pinMode (IN1, OUTPUT);
  pinMode (IN2, OUTPUT);
  pinMode (ENB, OUTPUT);
  pinMode (IN4, OUTPUT);
  pinMode (IN3, OUTPUT);
	
  Serial.begin(300); 
  
}

void loop()
{
  // первая итерация
  //получаем показания с датчиков
   lt = analogRead(ldrlt); // top left верх лево
   rt = analogRead(ldrrt); // top right верх пр
   ld = analogRead(ldrld); // down left низ лево
   rd = analogRead(ldrrd); // down rigt низ право

 //вычисляем средние значения по четырем сторонам
   avt = (lt + rt) / 2; // average value top - среднее верх
   avd = (ld + rd) / 2; // average value down- -- низ
   avl = (lt + ld) / 2; // average value left - -- левое
   avr = (rt + rd) / 2; // average value right -- правое

// вычисляем разницу между верхом и низом, правой и левой сторонами
   dvert = abs(avt - avd); // check the diffirence of up and down
   dhoriz = abs(avl - avr);// check the diffirence of left and right

//дальше все происходит в цикле, пока разница по горизонтали менгше порога tol
//принимаем решение по горизонтали
 while (dhoriz > tol) {
    analogWrite(ENA, i);
    if (avl > avr) //левое больше правого
    {
    digitalWrite (IN2, HIGH);
    digitalWrite (IN1, LOW); 
    //delay(30);
    }
    else if (avl < avr) //правое больше левого  
    {
    digitalWrite (IN1, HIGH);
    digitalWrite (IN2, LOW); 
    //analogWrite(ENA, i);
    //delay(30);
     }

  //получаем показания с датчиков
   lt = analogRead(ldrlt); // top left верх лево
   rt = analogRead(ldrrt); // top right верх пр
   ld = analogRead(ldrld); // down left низ лево
   rd = analogRead(ldrrd); // down rigt низ право

 //вычисляем средние значения по четырем сторонам
   avt = (lt + rt) / 2; // average value top - среднее верх
   avd = (ld + rd) / 2; // average value down- -- низ
   avl = (lt + ld) / 2; // average value left - -- левое
   avr = (rt + rd) / 2; // average value right -- правое

// вычисляем разницу между верхом и низом, правой и левой сторонами
   dvert = abs(avt - avd); // check the diffirence of up and down
   dhoriz = abs(avl - avr);// check the diffirence of left and right

/*    
  Serial.print("avt: ");
  Serial.print(avt);
  Serial.print(" ");
  Serial.print("avd: ");
  Serial.print(avd);
  Serial.print(" ");
  Serial.print("avl: ");
  Serial.print(avl);
  Serial.print(" ");
  Serial.print("avr: ");
  Serial.println(avr);
*/
//вывод показаний на серийный порт
  Serial.print("up left lt/A1: ");
  Serial.print(lt);
  Serial.print(" ");
  Serial.print("   dwn left ld/A4: ");
  Serial.print(ld);
  Serial.print(" ");
  Serial.print("   up rigt rt/A2: ");
  Serial.print(rt);
  Serial.print(" ");
  Serial.print("   dwn rigt rd/A3: ");
  Serial.println(rd);
  Serial.print(" ");
  Serial.print(" ");

 }
//  if // иначе = стоп по горизонтали
 // {
	 
	 //после выхода из цикла безусловный стоп по горизонтали
    analogWrite (ENA, 0);
    digitalWrite (IN2, LOW);
    digitalWrite (IN1, LOW); 
    // delay(1000);
 // }
/*
//////////////////////////////////// ЭТО НЕ ТЕСТИРОВАЛОСЬ, т.к. ПО ГОРИЗОНТАЛИ НЕТ СТОПА
///принимаем решение по вертикали///
  if (dvert > tol)
  {
	
    if (avt > avd) //верх больше низа
    {
    digitalWrite (IN4, HIGH);
		digitalWrite (IN3, LOW); 
		analogWrite(ENB, i);
		//delay(30);
    }
    else if (avt < avd) //низ больше верха
    {
    digitalWrite (IN3, HIGH);
		digitalWrite (IN4, LOW); 
		analogWrite(ENB, i);
    }
	
  }
  else // иначе = стоп
	{
	//  analogWrite (ENB, 0);
    digitalWrite (IN4, LOW);
    digitalWrite (IN3, LOW); 
   
	  delay(1000);

	}
//	} //-- от раздела СТОП по горизонтали
*/
}

#9 Re: Програмування Arduino » проблем: солнечный трекер промахивается мимо "Солнца" » 2017-12-04 00:32:03

ТЕКСТ ПРОГРАММЫ SOLAR_2

//SOLAR_2

//датчики
int ldrlt = A1; //LDR top left - верх лево
int ldrrt = A2; //LDR top rigt - верх право
int ldrld = A4; //LDR down left - низ лево
int ldrrd = A3; //ldr down rigt - низ право

int tol = 50; //чувствительность 100

//motors
int ENA = 9; //мотор А - горизонталь
int IN1 = 7;
int IN2 = 6;

int IN3 = 5; // Input1 подключен к выводу 5 
int IN4 = 4;
int ENB = 3; //мотор В - вертикаль
int i=150; // speed motor
//
void setup()
{
//moto
  pinMode (ENA, OUTPUT);
  pinMode (IN1, OUTPUT);
  pinMode (IN2, OUTPUT);
  pinMode (ENB, OUTPUT);
  pinMode (IN4, OUTPUT);
  pinMode (IN3, OUTPUT);
	
  Serial.begin(300); 
}

void loop()
{
  //получаем показания с датчиков
  int lt = analogRead(ldrlt); // top left верх лево
  int rt = analogRead(ldrrt); // top right верх пр
  int ld = analogRead(ldrld); // down left низ лево
  int rd = analogRead(ldrrd); // down rigt низ право

 //вычисляем средние значения по четырем сторонам
  int avt = (lt + rt) / 2; // average value top - среднее верх
  int avd = (ld + rd) / 2; // average value down- -- низ
  int avl = (lt + ld) / 2; // average value left - -- левое
  int avr = (rt + rd) / 2; // average value right -- правое

// вычисляем разницу между верхом и низом, правой и левой сторонами
  int dvert = abs(avt - avd); // check the diffirence of up and down
  int dhoriz = abs(avl - avr);// check the diffirence of left and right

/*  
 *   
 *   
  Serial.print("avt: ");
  Serial.print(avt);
  Serial.print(" ");
  Serial.print("avd: ");
  Serial.print(avd);
  Serial.print(" ");
  Serial.print("avl: ");
  Serial.print(avl);
  Serial.print(" ");
  Serial.print("avr: ");
  Serial.println(avr);
*/
//вывод показаний на серийный порт
  Serial.print("up left lt/A1: ");
  Serial.print(lt);
  Serial.print(" ");
  Serial.print("   dwn left ld/A4: ");
  Serial.print(ld);
  Serial.print(" ");
  Serial.print("   up rigt rt/A2: ");
  Serial.print(rt);
  Serial.print(" ");
  Serial.print("   dwn rigt rd/A3: ");
  Serial.println(rd);
  Serial.print(" ");
  Serial.print(" ");

//принимаем решение по горизонтали
  if (dhoriz > tol) //
  {
    if (avl > avr) //левое больше правого
    {
		digitalWrite (IN2, HIGH);
		digitalWrite (IN1, LOW); 
		analogWrite(ENA, i);
		//delay(30);
    }
    else if (avl < avr) //правое больше левого  
    {
		digitalWrite (IN1, HIGH);
		digitalWrite (IN2, LOW); 
		analogWrite(ENA, i);
		//delay(30);
     }
  }
	else // иначе = стоп по горизонтали
	{
	  analogWrite (ENA, 0);
    digitalWrite (IN2, LOW);
    digitalWrite (IN1, LOW); 
 
    delay(1000);

// движение по вертикали начинаю , когда по вертикали СТОП	
//принимаем решение по вертикали
  if (dvert > tol)
  {
	
    if (avt > avd) //верх больше низа
    {
		digitalWrite (IN4, HIGH);
		digitalWrite (IN3, LOW); 
		analogWrite(ENB, i);
		//delay(30);
    }
    else if (avt < avd) //низ больше верха
    {
		digitalWrite (IN3, HIGH);
		digitalWrite (IN4, LOW); 
		analogWrite(ENB, i);
    }
	
  }
  else // иначе = стоп по вертикали
	{
	//  analogWrite (ENB, 0);
    digitalWrite (IN4, LOW);
    digitalWrite (IN3, LOW); 
   
	  delay(1000);
	}
	} //-- от раздела СТОП по горизонтали
}

#10 Програмування Arduino » проблем: солнечный трекер промахивается мимо "Солнца" » 2017-12-04 00:06:06

Денис_К
відповідей: 24

Всем всего доброго!

Суть проблемы такова:
делаем с сыном модель солнечного трекера из конструкторов для солнечной батареи, все собрали, спаяли, но что-то с отладкой не клеится.
По замыслу платформа должна нацелиться на источник света и остановиться, когда показания датчиков примерно сравняются - сначала по горизонтали, потом - по вертикали. (программу писал не с нуля - сборная со всего союза)
Но она не останавливается.
Когда подключены оба мотора, они работают одновременно и вся конструкция "гуляет" во всех направлениях, но правда видно, что на лампу реагирует.
В случае отключения вертикального мотора - тоже непрерывно крутится около лампы.
пример того, что происходит:
https://yadi.sk/i/dJFeeY463QDtyN    (пардон, около 100 Мб, но суть видна уже на первых секундах)

код программы (два варианта):
solar_2 - использую if..else
solar_3 - использую цикл while с условием (dhoriz > tol)
Поведение в обоих случаях одинаковое.

О системе:
Датчики - четыре фоторезистора с подстроечными переменными резисторами, подключенные к аналоговым портам ардуино по схеме делителя напр.. Их я предварительно примерно уравнял в показаниях через монитор серийного порта. Тут же протестировал, но без моторов.
Управление моторами - через драйвер моторов (Н-мост). Схема во вложении. Моторы постоянного тока с редукторами, использованы шестерни и червячные передачи.

Опыта в этой части не хватает.
Прошу помощи с отладкой: идеи, как отловить ошибку кончились.
Гуглил на тему трекеров, но везде использованы сервомоторы. В нашем случае - моторы постоянного тока: есть напряжение - крутит, поменял полярность - обратно крутит, нет напр. - стоп. Все просто, только СТОП - нет.

Товарищи, помогите сохранить авторитет в семье!
Да и стыдно своей рукож...ти ((

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