Автор Тема: Солнечный трекер  (Прочитано 8207 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн ат

  • Member
  • ***
  • Сообщений: 137
  • Имя: Андрей
Солнечный трекер
« : Декабря 14, 2016, 17:10:35 »
Почти собрал, почти готов. На видео прогон трекера.

Трекером управляет микроконтроллер АРДУИНО. Программа при включении сначала устанавливает платформу в вертикальное положение, затем в крайнее на запад, и гонит на восток при этом считает обороты актуатора для последующего расчета положения.. потом находит крайние точки по вертикали и также рассчитывает положение. И в конце концов по текущему времени и дате ориентирует панели на солнце.. Далее будет

Оффлайн ат

  • Member
  • ***
  • Сообщений: 137
  • Имя: Андрей
Re: Солнечный трекер
« Ответ #1 : Декабря 14, 2016, 17:25:55 »
На фото сам микроконтроллер в сборе с управляющими релюшками и часами реального времени.

Оффлайн ат

  • Member
  • ***
  • Сообщений: 137
  • Имя: Андрей
Re: Солнечный трекер
« Ответ #2 : Декабря 14, 2016, 17:33:36 »
Трекер не обычный, прога будет корректно работать только с этим трекером..
и сама программа:


int xSize; // автор программы Торопов Андрей. пишите мне на ящик: intrtrade@gmail.com
int ySize; 
int xPos;
int yPos;
unsigned long pereriv=300000; // время между проверками положения панелей в миллисекундах
int pauz=4000; //для срабатывания геркона
int centrX=0; // поправка для азимута в градусах, числа "-" или "+"
int grad=200; // длина дуги по горизонтали в градусах



#include <DS1302.h>  // библиотеку часов подключаем
DS1302 rtc(2, 3, 4); // на этих пинах "сидит" плата часов
Time t;  // тип переменной такой, да?


int getXpos(int m, int d, int h, int mi){ // начало функции
  // Данные за 1,11 и 21 числа каждого месяца. Время по гринвичу, в минутах от 00:00. 37я ячейка повторяет 1ю
int voshod[37]={326,323,316,303,287,270,254,234,212,189,168,148,130,114,100,90,85,85,89,97,108,122,136,150,166,180,195,209,224,240,257,273,289,303,315,323,326};
int zahod[37]={822,834,848,866,882,899,912,928,943,960,975,990,1005,1020,1034,1046,1055,1059,1059,1055,1046,1032,1016,997,975,954,933,911,890,871,857,835,823,815,812,814,822};
int azimutV[37]={125,123,120,115,110,105,100,94,88,82,76,70,65,60,56,53,51,51,51,53,56,60,65,70,76,81,87,93,99,105,111,115,120,123,125,126,125};
int azimutZ[37]={234,236,239,244,249,254,259,265,271,277,283,289,294,298,302,306,308,308,308,306,303,299,294,289,283,277,272,266,260,254,248,243,239,236,234,233,234};

int v; //время восхода
int z; //время захода
int azV; // азимут восхода
int azZ; // азимут захода
int v2;
int z2;
int azV2;
int azZ2;
float x;

if (d==1){
   m=m*3;
  m=m-3;
  v=voshod[m];
  z=zahod[m];
  azV=azimutV[m];
  azZ=azimutZ[m];
  goto label;
}
if (d==11){
 m=m*3;
  m=m-2;
  v=voshod[m];
  z=zahod[m];
  azV=azimutV[m];
  azZ=azimutZ[m];
  goto label; 
}
 if (d==21){
 m=m*3;
  m=m-1;
  v=voshod[m];
  z=zahod[m];
  azV=azimutV[m];
  azZ=azimutZ[m];
  goto label;
}
// теперь с остальными датами. Вычисляем восход как средний меж двух дат. Определяем между каких мы дат (3 варианта)
if (d<11){
  d=d-1;
  m=m*3;
  m=m-3;
  v=voshod[m];
  z=zahod[m];
  azV=azimutV[m];
  azZ=azimutZ[m];
  m=m+1; //следующая ячейка в массивах
   v2=voshod[m];
  z2=zahod[m];
  azV2=azimutV[m];
  azZ2=azimutZ[m];
  if (v>v2){
    x=v-v2;
    x=x/9;
     x=x*d;
    v=v-x; // среднее время восхода вычислено !!!!
  }
else {
  x=v2-v;
   x=x/9;
  x=x*d;
   v=v+x; // среднее время восхода вычислено
}
 if (z>z2){
    x=z-z2;
    x=x/9;
      x=x*d;
    z=z-x; // среднее время захода вычислено !!!!
  }
else {
  x=z2-z;
   x=x/9;
     x=x*d;
   z=z+x; // среднее время захода вычислено
}
 if (azV>azV2){
    x=azV-azV2;
    x=x/9;
     x=x*d;
    azV=azV-x; //!!!
  }
else {
  x=azV2-azV;
   x=x/9;
      x=x*d;
    azV=azV+x;
}
 if (azZ>azZ2){
    x=azZ-azZ2;
    x=x/9;
      x=x*d;
    azZ=azZ-x; //!!!
  }
else {
  x=azZ2-azZ;
   x=x/9;
     x=x*d;
   azZ=azZ+x;
}
goto label;
}

if (d<21){
  d=d-11; // переменная больше не понадобится, по этому приводим дату к удобному числу
  m=m*3;
  m=m-2;
  v=voshod[m];
  z=zahod[m];
  azV=azimutV[m];
  azZ=azimutZ[m];
  m=m+1; //следующая ячейка в массивах
   v2=voshod[m];
  z2=zahod[m];
  azV2=azimutV[m];
  azZ2=azimutZ[m];
  if (v>v2){
    x=v-v2;
    x=x/10;
     x=x*d;
    v=v-x; // среднее время восхода вычислено !!!
  }
else {
  x=v2-v;
   x=x/10;
     x=x*d;
   v=v+x; // среднее время восхода вычислено
}
 if (z>z2){
    x=z-z2;
    x=x/10;
      x=x*d;
    z=z-x; // среднее время захода вычислено !!!
  }
else {
  x=z2-z;
   x=x/10;
      x=x*d;
   z=z+x; // среднее время захода вычислено
}
 if (azV>azV2){
    x=azV-azV2;
    x=x/10;
     x=x*d;
    azV=azV-x; //!!!!
  }
else {
  x=azV2-azV;
   x=x/10;
      x=x*d;
    azV=azV+x;
}
 if (azZ>azZ2){
    x=azZ-azZ2;
    x=x/10;
     x=x*d;
    azZ=azZ-x; //!!!!
  }
else {
  x=azZ2-azZ;
   x=x/10;
      x=x*d;
   azZ=azZ+x;
}
goto label;
}

if (d>21){
  d=d-21; // переменная больше не понадобится, по этому приводим дату к удобному числу
  m=m*3;
  m=m-1;
  v=voshod[m];
  z=zahod[m];
  azV=azimutV[m];
  azZ=azimutZ[m];
  m=m+1; //следующая ячейка в массивах
   v2=voshod[m];
  z2=zahod[m];
  azV2=azimutV[m];
  azZ2=azimutZ[m];
  if (v>v2){
    x=v-v2;
    x=x/10;
     x=x*d;
    v=v-x; // среднее время восхода вычислено !!!!
  }
else {
  x=v2-v;
   x=x/10;
    x=x*d;
   v=v+x; // среднее время восхода вычислено
}
 if (z>z2){
    x=z-z2;
    x=x/10;
     x=x*d;
    z=z-x; // среднее время захода вычислено !!!!
  }
else {
  x=z2-z;
   x=x/10;
     x=x*d;
   z=z+x; // среднее время захода вычислено
}
 if (azV>azV2){
    x=azV-azV2;
    x=x/10;
     x=x*d;
    azV=azV-x; //!!!!
  }
else {
  x=azV2-azV;
   x=x/10;
      x=x*d;
    azV=azV+x;
}
 if (azZ>azZ2){
    x=azZ-azZ2;
    x=x/10;
      x=x*d;
    azZ=azZ-x; //!!!!
  }
else {
  x=azZ2-azZ;
   x=x/10;
      x=x*d;
   azZ=azZ+x;
}
goto label;
}

// преобразуем время в минуты
label:
h=h*60;
mi=mi+h;

float az; // вычисляемый азимут
x=z-v; // сколько времени от меньшего азимута до большего
if (mi<v){ // солнце еще не взошло возвращаем азимут восхода
  return azV;
}
if (mi>z){ //солнце уже зашло за горизонт
  return azZ;
}
mi=mi-v; // время от восхода
az=azZ-azV;
az=az/x;
az=az*mi;
az=azV+az; //азимут вычислен.
return az;

}  // конец функции




int getUgolY(int m, int d){ // начало функции
int sunUgol[13]={0,2087,3021,4100,5263,6096,6421,6124,5289,4148,3009,2087,1734}; // 21 число каждого месяца в полдень

// дата= дата-21 день,из-за того что массив углов на 21 число
d=d-21;
if (d<1){
  d=30+d;
  if (m<1){
    m=12;
  }
m=m-1;
} // теперь дата преобразована
int x;
if (m!=11){
x=sunUgol[m]-sunUgol[m+1];
}
else {
x=sunUgol[m]-sunUgol[0]; 
}
x=x/30;
x=x*d;
x=sunUgol[m]-x;
x=x/100;
return x;
}  // конец функции



int motorX (int obr) {   // функция начинается тут
unsigned long msec;
int pauza =0;
int z=0;
int x;
int y;
y=digitalRead (6); // значение геркона
msec = millis();

if (obr>0) // крутим в +
{
digitalWrite (10,HIGH);
digitalWrite (11,LOW);

while(pauza < pauz){   // цикл продолжаем пару секунд если не срабатывает геркон
  x=digitalRead (6); // геркон горизонтали
  if (x!=y){         // если не равны значит геркон сработал и мотор крутится
    msec = millis(); // обновляем точку отсчета
    y=x;  // теперь значение геркона является "устаревшим"
 z ++;
 if (z >=obr){
  digitalWrite (10,LOW);
digitalWrite (11,LOW);
return z;
 }
 }

  else {
   pauza= (millis()-msec);  // выясняем сколько времени выполняется цикл
  }
}
 digitalWrite (10,LOW); // сработала пауза
digitalWrite (11,LOW);
return z;
}
if (obr<0) // крутим в -
{
digitalWrite (10,LOW);
digitalWrite (11,HIGH);

while(pauza < pauz){   // цикл продолжаем пару секунд если не срабатывает геркон
  x=digitalRead (6); // геркон горизонтали
  if (x!=y){         // если не равны значит геркон сработал и мотор крутится
    msec = millis(); // обновляем точку отсчета
    y=x;  // теперь значение геркона является "устаревшим"
 z --;
 if (z <=obr){
  digitalWrite (10,LOW);
digitalWrite (11,LOW);
return z;
 }
}
  else {
   pauza= (millis()-msec);  // выясняем сколько времени выполняется цикл
  }
}
 digitalWrite (10,LOW); // сработала пауза
digitalWrite (11,LOW);
return z;
}
return z; // на входе был "0"
} // конец тела функции



int motorY (int obr) {   // функция начинается тут
unsigned long msec;
int pauza =0;
int z=0;
int x;
int y;
y=digitalRead (5); // значение геркона
msec = millis();

if (obr>0) // крутим в +
{
digitalWrite (8,HIGH);
digitalWrite (9,LOW);

while(pauza < pauz){   // цикл продолжаем пару секунд если не срабатывает геркон
  x=digitalRead (5); // геркон горизонтали
  if (x!=y){         // если не равны значит геркон сработал и мотор крутится
    msec = millis(); // обновляем точку отсчета
    y=x;  // теперь значение геркона является "устаревшим"
 z ++;
 if (z >=obr){
  digitalWrite (8,LOW);
digitalWrite (9,LOW);
return z;
 }
 }

  else {
   pauza= (millis()-msec);  // выясняем сколько времени выполняется цикл
  }
}
 digitalWrite (8,LOW); // сработала пауза
digitalWrite (9,LOW);
return z;
}
if (obr<0) // крутим в -
{
digitalWrite (8,LOW);
digitalWrite (9,HIGH);

while(pauza < pauz){   // цикл продолжаем пару секунд если не срабатывает геркон
  x=digitalRead (5); // геркон горизонтали
  if (x!=y){         // если не равны значит геркон сработал и мотор крутится
    msec = millis(); // обновляем точку отсчета
    y=x;  // теперь значение геркона является "устаревшим"
 z --;
 if (z <=obr){
  digitalWrite (8,LOW);
digitalWrite (9,LOW);
return z;
 }
}
  else {
   pauza= (millis()-msec);  // выясняем сколько времени выполняется цикл
  }
}
 digitalWrite (8,LOW); // сработала пауза
digitalWrite (9,LOW);
return z;
}
return z; // на входе был "0"
} // конец тела функции



int letY(int ugol){  //функция начало
float f;
int x;
int y;
f= (float)ySize/90;
ugol=ugol*f; // угол перевели в нужные обороты актуатора от "0"
if (yPos>ugol){
  x=yPos-ugol;
  x=x*-1; //знак "-"
 y= motorY(x);
yPos=yPos+y;  // позиция поменялась
return x;
}
if (yPos<ugol){
  x=ugol-yPos;
  y=motorY(x);
  yPos=yPos+y; // позиция поменялась
  return x;
}
return 0; // позиция равна углу
} //конец функции


int letX(int azimut){  //функция начало
float f;
int x;
int y;
int p;
p=360-grad;
p=p/2;
p=p+centrX; // дополнительная поправка
azimut=azimut-p; // попытка номер III
f= (float)xSize/grad;
azimut=(float)azimut*f; // угол перевели в нужные обороты актуатора от "0"

if (xPos>azimut){
  x=xPos-azimut;
  x=x*-1; //знак "-"
 y= motorX(x);
xPos=xPos+y;  // позиция поменялась
return x;
}
if (xPos<azimut){
  x=azimut-xPos;
   y=motorX(x);
  xPos=xPos+y; // позиция поменялась
  return x;
}
return 0; // позиция равна углу
} // конец функции





void setup()
{
  Serial.begin(9600);
//rtc.setTime(19, 33, 0);     // Set the time to 12:00:00 (24hr format)
//rtc.setDate(27, 11, 2016);   // Set the date to August 6th, 2010

pinMode (8,OUTPUT);
pinMode (9,OUTPUT);
pinMode (10,OUTPUT);
pinMode (11,OUTPUT);
t = rtc.getTime(); // получаем текущее время

 Serial.print("mouns: ");
  Serial.print(t.mon,DEC);
 Serial.print("  date: ");
Serial.println(t.date, DEC);
 Serial.print("  ");
    Serial.print(t.hour, DEC);
  Serial.print(" : ");
  Serial.print(t.min, DEC);
  Serial.println();
 

// устанавливаем панели в крайнее верхнее положение для безопасного прогона горизонтали и вертикали последующими шагами.
ySize= motorY (9999);
 
  // прогоняем панели на восток и считаем количество оборотов двигателя
xPos= motorX (9999);
xSize= motorX (-9999);
xSize= xSize*-1; //меняю знак на "+"
int xmedium;
xmedium=xSize/2;
xPos= motorX (xmedium);  // устанавливаем (горизонталь) в среднее положение (на ЮГ)


 // переводим панели в вертикальное положение и считаем обороты в вертикальной оси
ySize= motorY(-9999);
ySize= ySize*-1;  //меняю знак на "+"
yPos=0;
}

void loop()
{
 
// вычисляем нужный угол по вертикали
int m;
int d;
 m=t.mon;
 d=t.date;


int ugolY;
ugolY=getUgolY(m,d);
letY(ugolY); // функция установит панели в положение угол ugolY
int h;
int mi;
t = rtc.getTime(); // получаем текущее время
h=t.hour;
mi=t.min;
int azimut;
azimut=getXpos(m,d,h,mi);
letX(azimut); // функция установит панели по азимуту

unsigned long stopTime;
stopTime=millis();
unsigned long pauza=0;
while (pauza<pereriv){ // ждем
    pauza= (millis()-stopTime);
}
}

Оффлайн votasum

  • Moderator
  • Member
  • *****
  • Сообщений: 5085
  • Вынудите-рвану
  • Имя: Сергей
  • Откуда: Печорский р-он. Рес. Коми п. Кожва Недалеко от ж\д моста через р. Печора.
Re: Солнечный трекер
« Ответ #3 : Декабря 14, 2016, 17:49:06 »
ат, :shok::shok::shok::shok: Эт что за матерные слова. :shok::shok::shok:

Оффлайн ат

  • Member
  • ***
  • Сообщений: 137
  • Имя: Андрей
Re: Солнечный трекер
« Ответ #4 : Декабря 14, 2016, 18:05:17 »
итак, что особенного в моем трекере..Главная особенность заключается в том, что при выставлении панели по азимуту, правильный угол по вертикали, относительно солнца, выставляется автоматически. Достигается это тем, что ось горизонтали расположена не вертикально, а под определенным углом..благодаря этому, в течении дня приходится корректировать только азимут, используя только один мотор. Для вертикали же, на самом деле можно вообще не ставить актуатор, а ограничится лишь какой-то ручной регулировкой, и выставлять вертикальный угол будет достаточно один раз в 20 дней, и это даст погрешность всего в 4 градуса.. Знаю, при первом взгляде кажется что все усложнено, но это не так, на самом деле конструкция до гениальности проста. Я не в курсе делал ли кто чего подобное, возможно нет.
   Ось горизонтали рассчитывается по простой формуле, для разный широт она своя, рассчитывается индивидуально.  Например для экватора эта ось будет 0 градусов.

Оффлайн ат

  • Member
  • ***
  • Сообщений: 137
  • Имя: Андрей
Re: Солнечный трекер
« Ответ #5 : Декабря 14, 2016, 18:11:29 »
ат, :shok::shok::shok::shok: Эт что за матерные слова. :shok::shok::shok:

Еще месяц назад я бы также реагировал)

Оффлайн leon10010

  • Member
  • *****
  • Сообщений: 4710
Re: Солнечный трекер
« Ответ #6 : Декабря 14, 2016, 18:33:05 »
ат, :shok::shok::shok::shok: Эт что за матерные слова. :shok::shok::shok:

Еще месяц назад я бы также реагировал)
У нас поле подсолнухов без всяких контроллеров за солнцем следит. :biggrin:

Оффлайн АРКАДИЧ

  • Member
  • *****
  • Сообщений: 2433
  • информированный оптимист
  • Имя: Сергей
  • Откуда: Вологодская обл.
Re: Солнечный трекер
« Ответ #7 : Декабря 14, 2016, 19:18:55 »
без всяких контроллеров

Можно и проще сделать , или у китайцев купить :blush:


Оффлайн leon10010

  • Member
  • *****
  • Сообщений: 4710
Re: Солнечный трекер
« Ответ #8 : Декабря 14, 2016, 19:23:53 »
итак, что особенного в моем трекере..Главная особенность заключается в том, что при выставлении панели по азимуту, правильный угол по вертикали, относительно солнца, выставляется автоматически. Достигается это тем, что ось горизонтали расположена не вертикально, а под определенным углом..благодаря этому, в течении дня приходится корректировать только азимут, используя только один мотор. Для вертикали же, на самом деле можно вообще не ставить актуатор, а ограничится лишь какой-то ручной регулировкой, и выставлять вертикальный угол будет достаточно один раз в 20 дней, и это даст погрешность всего в 4 градуса.. Знаю, при первом взгляде кажется что все усложнено, но это не так, на самом деле конструкция до гениальности проста. Я не в курсе делал ли кто чего подобное, возможно нет.
   Ось горизонтали рассчитывается по простой формуле, для разный широт она своя, рассчитывается индивидуально.  Например для экватора эта ось будет 0 градусов.
Посмотрите устройства слежения телескопов.  Раньше одной механикой обходились. Сейчас электроники добавили. Там погрешности сотые  доли секунды в сутки. При фотографировании слабых объектов.

Оффлайн leon10010

  • Member
  • *****
  • Сообщений: 4710
Re: Солнечный трекер
« Ответ #9 : Декабря 14, 2016, 19:29:48 »
Вот форум астрономов. Только тут разделы очень бестолково построены, нет разделения по конкретике. Надо копать все сообщения. ссылка Покопайтесь в разделе Практическая астрономия

Оффлайн ат

  • Member
  • ***
  • Сообщений: 137
  • Имя: Андрей
Re: Солнечный трекер
« Ответ #10 : Декабря 14, 2016, 21:26:36 »
без всяких контроллеров

Можно и проще сделать , или у китайцев купить :blush:
АРКАДИЧ, недостаток варианта на фоторезисторах в том, что когда облачно он "сходит с ума" и гоняется за облаками. То что вы предложили купить у китайцев именно оно и есть, к тому же на одну ось, на две стоит 60 долларов и та же чепуха. А мой трекер четко знает где солнце, даже когда его нет, и не тратит электричество на лишнее дерганье. Представьте себе трекер размером с крышу вашего дома который гоняется за облаками!!! или за фонариком соседского ребенка.. Так что не сравнивайте даже

Оффлайн ат

  • Member
  • ***
  • Сообщений: 137
  • Имя: Андрей
Re: Солнечный трекер
« Ответ #11 : Декабря 14, 2016, 21:30:46 »
Вот форум астрономов. Только тут разделы очень бестолково построены, нет разделения по конкретике. Надо копать все сообщения. ссылка Покопайтесь в разделе Практическая астрономия
А зачем копаться?
Неужели вы видели что-то лучшее?? :)

Онлайн Dil

  • Administrator
  • *****
  • Сообщений: 9240
  • Велика Россия, а запарковаться негде.
  • Имя: Михаил
  • Откуда: Рязань
Re: Солнечный трекер
« Ответ #12 : Декабря 14, 2016, 22:17:27 »
ат, ты на фабрике фотоэлементов работаешь? Вроде за деньги их покупать нерентабельно :blush:

Оффлайн leon10010

  • Member
  • *****
  • Сообщений: 4710
Re: Солнечный трекер
« Ответ #13 : Декабря 14, 2016, 22:32:04 »
А зачем копаться?
Неужели вы видели что-то лучшее?? :)
Вы же пишете, что
на самом деле конструкция до гениальности проста. Я не в курсе делал ли кто чего подобное, возможно нет.
Вот там постоянно это делают.
 На протяжении сотен лет, с момента изобретения фотографии и телескопа.

Оффлайн ат

  • Member
  • ***
  • Сообщений: 137
  • Имя: Андрей
Re: Солнечный трекер
« Ответ #14 : Декабря 14, 2016, 22:56:11 »
Dil, В некоторых случаях очень даже рентабельно, например когда нет поблизости электростолбов (или как ихтам зовут) или если ты живешь на украине и подключил себе "зеленый тариф" и продаешь электричество государству по 16 евроцентов за киловатт. Я думаю что есть еще какие-то случаи когда это выгодно, иначе не ставили бы солнечные электростанции по всему миру, и даже в России (все-таки северные широты)..