Трекер не обычный, прога будет корректно работать только с этим трекером..
и сама программа:
int xSize; // автор программы Торопов Андрей. пишите мне на ящик:
intrtrade@gmail.comint 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);
}
}