Солнечный трекер

Alexandr1432
Offline
Зарегистрирован: 12.11.2015
#include <AccelStepper.h> // Подключение библиотеки управления шаговым двигателем

#define HALFSTEP 8 //Включение полушагового режима работы двигателя

// Определение пинов для управления двигателем
#define motorPin1  7 // Номер порта на плате Arduino подключаемый к порту IN4 на драйвере ULN2003
#define motorPin2  6 // Номер порта на плате Arduino подключаемый к порту IN3 на драйвере ULN2003
#define motorPin3  5 // Номер порта на плате Arduino подключаемый к порту IN2 на драйвере ULN2003
#define motorPin4  4 // Номер порта на плате Arduino подключаемый к порту IN1 на драйвере ULN2003
int v1 = 0; // Номер порта, к которому подключен потенциометр
int val = 0; // Переменная для хранения считываемого значения с потенциометра
unsigned long time; // Переменная для хранения времени отсчёта
int flag_1 = 0;
int flag_2 = 0;
int flag_3 = 0; // Переменные-ключи
int Kol = 100;                    // Сколько раз проводить измерения

long ADC_code_sr=0;     // Переменная для усреднения

int Volt=0;                      // Результируюшая переменная    

AccelStepper stepper1(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4); // Инициализация с последовательностью выводов IN1-IN3-IN2-IN4
// для использования библиотеки AccelStepper с двигателем 28BYJ-48
void setup() //Стартовые установки
{
  stepper1.setMaxSpeed(1500.0); // Задаем начальную скорость вращения вала двигателя
  stepper1.setAcceleration(10000.0); // Задаем темп разгона/торможения двигателя
  stepper1.moveTo(-4096); //Старт движения двигателя против часовой стрелки до датчика
  Serial.begin(9600);
}

void loop() //Основной цикл
{

  val = analogRead(v1); //считываем значение с потенциометра и заносим в переменную val
  
  if (val > 900 && flag_1 == 0) //Условие остановки двигателя
  { stepper1.stop(); //Остановка двигателя
    stepper1.setCurrentPosition(0); //Принимаем точку остановки - начальной точкой отсчёта
    flag_1 = 1;
    flag_2 = 1;
    flag_3 = 1; //Переключение переменных-ключей для отключения выполненных(ненужных) условий
  }

  if (flag_3 == 1) //задержка перед стартом обратного вращения вала (для уменьшения дребезга)
  { delay(500);
    flag_3 = 0;
  }

  if (flag_2 == 1 && flag_3 == 0) //Условие начала вращение вала по часовой стрелке 
  {  
    int K=113; //угол поворота в цикле поиска наилучшей выработки батареи ( вращение по 10 градусов вперед)
    for (int X=1; X<=2048; X=X+K)
    {
         
      for(int i=0; i<Kol; i++) //сглаживающий фильтр 
    {
      ADC_code_sr=ADC_code_sr+analogRead(A5);
    }
      ADC_code_sr=ADC_code_sr/Kol;

      Volt=ADC_code_sr;
      Serial.println(X); 
      Serial.println(Volt); 
      
      stepper1.runToNewPosition(X); //Задаем двигателю вращать вал на каждые 10 градусов вперед
      delay(1000);
         }
   }
     stepper1.run(); //Запуск вращения вала
  }

Вот такой вот кодик накропал. Хочу сделать что-то типо солнечного трекера. Солнечная батарея стоит на конструкции над шаговым двигателем. На данный момент в коде: при включении питания шаговый двигатель вращает батарею до датчика и я обозначаю это положению нулевым. Затем задал угол движения 10 градусов и панель движется и так скажем сканирует окружение где-то на 180 градусов по часовой стрелке. На каждом итерации поворота я снимаю напряжение с панели (напряжение скачет поэтому поставил что-то вроде сглаживающего фильтра).

В программировании новичек, на C начал писать только как с неделю.

Вопрос 1: строка 53 почему когда делаю X=0 двигатель не начинает вращаться и "сканировать", а только с X>0.

Вопрос 2: после прохода на 180 градусов мне нужно чтобы были записаны положения панели и соответсвующие им напряжения на панели. А дальше необходимо, чтобы двигателю было задано повернуться до положения соотвествующее максимальному напряжению. И вот в чём вопрос я не понимаю как хранить эти данные...думал записывать значения положений(X) и напряжений(Volt) в два массива...но я не понимаю как с ними работать.

Посоветуйте как сделать по-вашему лучше.

 

 

Seth
Offline
Зарегистрирован: 01.02.2014

А для чего массив?

if(ADC_code_sr > Volt){
  Volt=ADC_code_sr;
  BestX = X;
}

int BestX - понятно, глобальная переменная, как Volt

По окончании сканирования выставляй в BestX, потомучто там хранится больший Volt. Все просто.

Alexandr1432
Offline
Зарегистрирован: 12.11.2015

Seth пишет:

А для чего массив?

if(ADC_code_sr > Volt){
  Volt=ADC_code_sr;
  BestX = X;
}

int BestX - понятно, глобальная переменная, как Volt

По окончании сканирования выставляй в BestX, потомучто там хранится больший Volt. Все просто.

Мммм...сейчас подумаю как реализовать. Мозг пухнет уже от этого программирования )