Melhorar codigo

Olá pessoal! Eu estou desenvolvendo um projeto utilizando motores de passo para realizar a movimentação de um painel solar a partir de mecanismos de rastreamento (Solar Tracker). Para a movimentação de cada eixo eu estou utilizando um motor de passo. Como o movimento do sistema de rastreamento será biaxial (eixo vertical e eixo horizontal), utilizaremos dois motores. No presente código, eu coloquei uma função de rastreamento, que permite que, a partir das leituras dos LDR's (dois LDR's em posições opostas para cada eixo), o sistema se movimente até que não haja uma diferença entre as leituras dos LDR's do mesmo eixo! Além disso, coloquei uma função Média Movel a fim de filtrar os sinais captados pelo sensor, garantindo uma maior estabilidade! Eu gostaria de otimizar meu código, visto que há duas funções Média Movel (uma para cada eixo) e duas funções Rastreamento (uma para cada eixo). Diante disso, seria melhor utilizar a mesma estrutura de função e escrever apenas uma função para controlar a Média Movel de ambos e uma função para controlar o Rastreamento de ambos! Eu gostaria de apenas intercambiar os comandos para cada um dos dois pares de sensores (4 ldr's) sem necessitar escrever duas vezes o mesmo código! Isso é possível? Como faço isso?


#define NUMREADINGS 7

int pinoDrive[6] = {9, 10, 8, 2, 3, 4}; // stepper pin//direction pin//Reset Pin//Mode 0 pin//Mode 1 pin// Mode 2 pin//
pinoDrive[0] == 9;
pinoDrive[1] == 10;
pinoDrive[2] == 8;

int pinoLDRS [4] = {0,1,2,3}; //LdrE Pin// LdrD Pin// LdrE1 Pin// LdrD1Pin//
pinoLDRS[0] == 0;
pinoLDRS[1] == 1;
pinoLDRS[2] == 2;
pinoDrive[3] == 3;

const int nstepsMin = 10;
const int nstepsMax = 25;
const float numbersStepsMin = 1;
const float numbersStepsMax = 3453;
const float mintolerance = 2;
const float maxtolerance = 60;
const int stepDelay = 1000; //time between steps//

boolean dir;

int readingsE[NUMREADINGS];
int readingsD[NUMREADINGS]; //number of readings
int readingsE1[NUMREADINGS];
int readingsD1[NUMREADINGS];
int indice = 0; // current index
int leituraE, leituraD, leituraE1, leituraD1; // variable to store sensor readings//
float totalD, total E, totalD1 , totalE1 = 0; // total moving average//
float error;
int newCustom ;

float ldrEvalue, ldrDvalue, ldrE1value, ldrD1value= 0;
float difldr,difldr1= 0; // difference between the two LDR's in the same axis//
const int K = 1.28;
const int K1 = 1.44;
const float angulominimo = -169.73;
const float angulomaximo = 169.73;

int contadorpinodrive; // used to store the pins attached to Driver
int contadorpinoLDR; //used to store the pins attached to the LDR sensor
int nP = 6; // number of pins attached to the DRV8825
int nLDR=4; // number of LDR's (2 for each axis)


void setup() {

for (contadorpinodrive=0;contadorpinodrive<nP;contadorpinodrive++) {
pinMode(pinoDrive[contadorpinodrive], OUTPUT); // Drive attached to the digital pins //
}

for (contadorpinoLDR=0; contadorpinoLDR<nLDR; contadorpinoLDR++){
pinMode(pinoLDRS[contadorpinoLDR], INPUT); // Sensor attached to the analogic pins//
}

digitalWrite(Mode0,HIGH); /// DRV8825 step modes (1/8 mode)
digitalWrite(Mode1, HIGH);
digitalWrite(Mode2, LOW);
Serial.begin(9600);

for (int i = 0; i < NUMREADINGS; i++){ //numbers of readings in moving average//
readingsE, readingsD, readingsE1, readingsD1 = 0; // start all the reading with 0//
}
}

void loop()
{
rastreamento();
rastreamento1();
delay(1000);
}

void mediamovel () { //do 7 readings to obtain a average value for the LDR's readings //
totalE -= readingsE[indice];
totalD -= readingsD[indice]; // substract the last reading //
leituraE = analogRead(pinoLDRS[0]); // read the sensor//
leituraD = KanalogRead(pinoLDRS[1]); // read the sensor//
readingsE[indice] = sqrt(10
analogRead(pinoLDRS[0]));// use of a square function to equalize the reading//
readingsD[indice] = sqrt(10*analogRead(pinoLDRS[1]));
totalE += readingsE[indice]; // add reading to total //
totalD += readingsD[indice]; //
indice = (indice + 1); // go to the next //

if (indice >= NUMREADINGS) { // if the index is in the end of the vector//
indice = 0; } } // ... it comes back to the begin of the index (or 0)
ldrEvalue = (totalE)/ NUMREADINGS;
ldrDvalue = (totalD)/ NUMREADINGS; // // calculate the moving average //
}


void mediamovel1 () { // it works at the same way that the previous function (mediamovel)

totalE1 -= readingsE1[indice];
totalD1 -= readingsD1[indice];
leituraE1 = analogRead(pinoLDRS[2]);
leituraD1 = K1analogRead(pinoLDRS[3]);
readingsE1[indice] = sqrt(10
analogRead(pinoLDRS[2]));
readingsD1[indice] = sqrt(10*analogRead(pinoLDRS[3]));
totalE1 += readingsE1[indice];
totalD1 += readingsD1[indice];
indice = (indice + 1);

if (indice >= NUMREADINGS)
indice = 0;
ldrE1value = (totalE1)/ NUMREADINGS;
ldrD1value = (totalD1)/ NUMREADINGS;
}

void rastreamento (){ // this function is responsible for tracking the sun, by making comparison between the two LDR's in one axis//

for(int i=1;i<=7;i++)
{
mediamovel(); // call for the function seven times to fill in the matrix of moving average and generate the average value from the readings //
}
float medValue = ((ldrEvalue + ldrDvalue)/2) ; // calculate the average value between the LDRs located in opposite sides//
difldr = (ldrEvalue - ldrDvalue); // calculate the difference between the average value from each side (left or right) //
float correction = 100*(difldr/medValue);
error = abs(correction); //value for making comparison to minimum thresold//
while(error > mintolerance)
{
mediamovel(); // call for the function moving average //
float medValue = ((ldrEvalue + ldrDvalue)/2) ;
difldr = (ldrEvalue - ldrDvalue);
float correction = 100*(difldr/medValue);
error = abs(correction);
digitalWrite(pinoDrive[2],HIGH); // turn on the RESET Pin//
if (correction<0)
{
dir = HIGH; if the signal of the correction is negative, the motor wil rotate to one direction
}
else
{
dir = LOW; if the signal of the correction is positive, the motor wil rotate to other direction
}
newCustom = map(error,mintolerance,maxtolerance,nstepsMin,nstepsMax); // function to generate the numbers of steps acording to the error (thresold)//
digitalWrite(pinoDrive[1],dir); //set the Direction Pin//
for(int i =1; i<=newCustom;i++){ //number of iterations acording to the numbers of steps//
digitalWrite(pinoDrive[0], HIGH); // turn on the Step Pin//
delayMicroseconds(stepDelay);
digitalWrite(pinoDrive[0],LOW); // turn off the Step Pin//
delayMicroseconds(stepDelay);
}
}

void rastreamento1 (){ it works at the same way as the previous function (rastreamento)//
for(int i=1;i<=7;i++)
{
mediamovel1();
}
float medValue = ((ldrE1value + ldrD1value)/2) ;
difldr1 = (ldrE1value - ldrD1value);
float correction = 100*(difldr1/medValue);
error = abs(correction);
while(error > mintolerance)
{
mediamovel1();
float medValue = ((ldrE1value + ldrD1value)/2) ;
difldr1 = (ldrE1value - ldrD1value);
float correction = 100*(difldr1/medValue);
error = abs(correction);
digitalWrite(pinoDrive[2],HIGH);
if (correction<0)
{
dir = HIGH;
}
else
{
dir = LOW;
}
newCustom = map(error,mintolerance,maxtolerance,nstepsMin,nstepsMax);
digitalWrite(pinoDrive[1],dir);
for(int i =1; i<=newCustom;i++){
digitalWrite(pinoDrive[0], HIGH);
delayMicroseconds(stepDelay);
digitalWrite(pinoDrive[0],LOW);
delayMicroseconds(stepDelay);
}
}


Isto está errado:

pinoDrive[0] == 9;
pinoDrive[1] == 10;
pinoDrive[2] == 8;
...
pinoLDRS[0] == 0;
pinoLDRS[1] == 1;
pinoLDRS[2] == 2;
pinoDrive[3] == 3;

Isto está bem feito.

for (contadorpinodrive=0;contadorpinodrive<nP;contadorpinodrive++) {
pinMode(pinoDrive[contadorpinodrive], OUTPUT); // Drive attached to the digital pins //
}

for (contadorpinoLDR=0; contadorpinoLDR<nLDR; contadorpinoLDR++){
pinMode(pinoLDRS[contadorpinoLDR], INPUT);  // Sensor attached to the analogic pins//
}

Isto está deveras errado:

for (int i = 0; i < NUMREADINGS; i++){ //numbers of readings in moving average//
readingsE, readingsD, readingsE1, readingsD1 = 0; // start all the reading with 0//
}

Só olhei para a tua função mediamovel e o que precisas de fazer seria talvez o uso de estruturas.

Porque não fazeres a leitura num sítio para dentro do array e depois uma função que tem como variável de entrada o array e saída a média?

float mediamovel (int * array, int size){
   long total = 0; 
   for (int i = 0; i < size; i++) 
      total += array[i];
   return (float) total/size; 
}

Assim podes chamar a função várias vezes operando nas variáveis que quiseres. Suponho que o mesmo se aplique ao tracking e se quiseres podes usar estruturas em vez de arrays para isso.

Caro bubulindo, muito obrigado pela resposta! Foi de grande auxílio! Mas fiquei na dúvida!
Como eu faço essa parte que você falou: "Porque não fazeres a leitura num sítio para dentro do array " ?

unsigned int leituras[10]; 
unsigned char leituras_ptr = 0; 

void adquire_dados() {

leituras[leituras_ptr] = analogRead(pino_leituras);
if (++leituras_ptr == 10) leituras_ptr = 0; // se chegaste ao 10, então volta a escrever no zero. 
}

float mediamovel (int * array, int size){
   long total = 0;
   for (int i = 0; i < size; i++)
      total += array[i];
   return (float) total/size;
}

// dentro da tua função loop... 

adquire_dados();
media = mediamovel(leituras, 10);

Assim o código fica mais contido e limpo quando chamas da função principal.

A função adquire dados, pode também ser modificada para funcionar de forma diferente:

void adquire_dados(unsigned int * dados, unsigned char *ptr, unsigned char pino) {

dados[*ptr] = analogRead(pino);
if (++*ptr == 10) *ptr = 0; // se chegaste ao 10, então volta a escrever no zero. 
}



unsigned int leiturasE[10];
unsigned char E_ptr = 0; 
unsigned int leiturasD[10];
unsigned char D_ptr = 0; 

//dentro da tua função loop()... 

adquire_dados(leiturasE, &E_ptr, pinoLDRE);
adquire_dados(leiturasD, &D_ptr, pinoLDRD);

Menos código para atingir o mesmo...