Descrevendo as Programações - Arduino

Esta seção remete à descrição das programações, desmembrando-a em alguns quadros que explicitam as funções ou parte principais e procuram orientar o entendimento do que se esta realizando, ou seja, de como o experimento ocorre.



Quadro 1- Programação envolvendo comando do teclado, via Ethernet. Esta programação somente é acionada para ajuste do giro da rede de difração, montada sobre o eixo do motor de passo.
1.       #include
2.       #include "Wire.h"
3.       #include "Adafruit_TCS34725.h"
4.       #include
5.        
6.       IRsend irsend; //commando para iniciar envoi dos dados pelo sensor IR.
7.        
8.       //variaveis de passos para giro do motor//
9.       const int stepsPerRevolution = 48;
10.    Stepper myStepper(stepsPerRevolution, 22, 23, 24, 25);
11.    int passos; // numero de passos necessarios para mover o motor para a próxima posicao
12.    int posicaoAtual;
13.    int posicaoFutura;
14.     
15.    //para calculos de comprimento de onda//
16.    float lambdaVermelha; // comprimento de onda da componente da cor Vermelha
17.    float lambdaVerde; // comprimento de onda da componente da cor Verde
18.    float lambdaAzul; // comprimento de onda da componente da cor Azul
19.    float d = pow(10,-6);// parametro de rede
20.    float l = 0.112; // dist da rede ao anteparo
21.     
22.    boolean ReceberColetaDados; //definição para variavel booleana do tipo verdadeira ou falsa.
23.    //sensor de cor//
24.    Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_101MS, TCS34725_GAIN_60X);
25.     
26.     
27.    void setup(){
28.      Serial.begin(9600);
29.      Serial.println("Mestrado TIDD - Analise Seus espectro");
30.      myStepper.setSpeed(40);
31.      delay(100);
32.      DetectaCores();
33.     
34.    }
35.     
36.    void loop() {
37.       ligar_motor();
38.       delay(200);
39.       int client = Serial.available();
40.       if (client) {
41.         Serial.println("novo cliente");
42.         char c = Serial.read();
43.         if (c == 'i') { // Testamos se os bytes que vieram do Client conectado sao para uma nova coleta
44.           IniciarColeta();
45.         }
46.       }
47.       if (ReceberColetaDados == true) {
48.         ColetaDados();
49.         ColetaCores();
50.       }
51.    }


A seguir, no Quadro 2, mostramos considerações acerca do sistema de acionamento do giro do motor, com base na calibração do sistema (para se saber o número de passos necessários para rodar a rede de difração entre uma componente e outra, a partir a da informação de ângulo de passo, fornecida pela datasheet do motor de passo), de modo a varrer o espectro de irradiância por comprimentos de onda, e ao chegar até a última componente, voltar os mesmo passos em sentido oposto para se voltar à posição original, de frente à projeção da fenda.


Quadro 2 - Programação da Segunda parte da programação do Experimento Off-Line: Ajuste de posicionamento das componentes das cores do espectro, com cálculo dos comprimentos de onda e detecção de cores.
1.       void IniciarColeta() {
2.             ReceberColetaDados = true;
3.             Serial.println("Coleta de Dados do Experimento");
4.             motor.step(-(stepsPerRevolution));
5.             delay(100);
6.       }
7.        
8.       void ColetaDados(){
9.         ReceberColetaDados = true;
10.      delay(10);
11.          myStepper.step(-(stepsPerRevolution));
12.      delay(100);
13.      myStepper.step(0);
14.     int geralPassos = 0;
15.      delay(1000);
16.      Serial.println("Pronto Para comecar!");
17.    }
18.     
19.    void(*resetFunc)(void)=0;
20.     
21.    void PararCliente(){
22.      delay(200);
23.        Serial.println("resetando...");
24.        resetFunc();
25.        delay(100);
26.        Serial.println("OK. Pronto para novo Cliente");
27.    }
28.     
29.    void posiciona_motor_vermelho(){
30.          delay(50);
31.          myStepper.step(0);
32.          lambda_componenteVermelha();
33.          Serial.print("Comprimento de Onda = ");
34.          Serial.print(" ");
35.          Serial.println(lambdaVermelha,DEC);
36.          delay(500);//para leitura da componente vermelha
37.          ColetaCores();
38.          delay(50);
39.          myStepper.step((0)); // volta à posição original
40.          PararCliente();
41.          delay(10);
42.          Serial.println("Proximo Cliente...");
43.    }
44.    void posiciona_motor_verde(){
45.          delay(50);
46.          myStepper.step(7); // para leitura da componente verde (a partir da cond inicial).
47.          lambda_componenteVerde();
48.          Serial.print("Comprimento de Onda = ");
49.          Serial.print(" ");
50.          Serial.println(lambdaVerde,DEC);
51.          delay(500);
52.          ColetaCores();
53.          delay(50);
54.          myStepper.step(-(7)); // volta à posição original   
55.          PararCliente();
56.          delay(10);
57.          Serial.println("Proximo Cliente...");
58.    }
59.    void posiciona_motor_azul(){
60.          delay(50);
61.          myStepper.step(11); // para leitura da componente azul (a partir da con inicial)
62.          lambda_componenteAzul();
63.          Serial.print("Comprimento de Onda = ");
64.          Serial.print(" ");
65.          Serial.println(lambdaAzul,DEC);
66.          delay(500);
67.          ColetaCores();
68.          delay(50);
69.          myStepper.step(-(11)); // volta à posição original
70.          PararCliente();
71.          delay(10);
72.          Serial.println("Proximo Cliente...");
73.    }
74.    void posiciona_motor_branco(){
75.    //vermelho
76.          delay(50);
77.          myStepper.step(0);
78.          lambda_componenteVermelha();
79.          Serial.print("Comprimento de Onda = ");
80.          Serial.print(" ");
81.          Serial.println(lambdaVermelha,DEC);
82.          delay(500);//para leitura da componente vermelha
83.          ColetaCores();
84.          delay(500);
85.    //verde     
86.          delay(50);
87.          myStepper.step(7); // para leitura da componente verde - considerando a partir da componente vermelha.
88.          lambda_componenteVerde();
89.          Serial.print("Comprimento de Onda = ");
90.          Serial.print(" ");
91.          Serial.println(lambdaVerde,DEC);
92.          ColetaCores();
93.          delay(500);
94.    //azul
95.          delay(50);
96.          myStepper.step(4); // para leitura da componente azul - considerando a partir da componente verde.
97.          lambda_componenteAzul();
98.          Serial.print("Comprimento de Onda = ");
99.          Serial.print(" ");
100.        Serial.println(lambdaAzul,DEC);
101.        ColetaCores();
102.        delay(500);
103.        myStepper.step(-(11)); // volta à posição original
104.        PararCliente();
105.        delay(10);
106.        Serial.println("Proximo Cliente...");
107.  }
108.  void posiciona_motor_comb1(){ //comb1 = vermelho + verde
109.  //vermelha
110.        delay(50);
111.        myStepper.step(0);
112.        lambda_componenteVermelha();
113.        Serial.print("Comprimento de Onda = ");
114.        Serial.print(" ");
115.        Serial.println(lambdaVermelha,DEC);
116.        ColetaCores();
117.        delay(500);//para leitura da componente vermelha
118.  //verde
119.        delay(50);
120.        myStepper.step(7); // para leitura da componente verde - considerando a partir da componente vermelha.
121.        lambda_componenteVerde();
122.        Serial.print("Comprimento de Onda = ");
123.        Serial.print(" ");
124.        Serial.println(lambdaVerde,DEC);
125.        ColetaCores();
126.        delay(500);
127.        myStepper.step(-(7)); // volta ao inicio.   
128.        PararCliente();
129.        delay(10);
130.        Serial.println("Proximo Cliente...");
131.  }
132.  void posiciona_motor_comb2(){ // comb2 = verde + azul
133.  // verde
134.        delay(50);
135.        myStepper.step(7);// para leitura da componente verde - considerando a partir da componente vermelha.
136.        lambda_componenteVerde();
137.        Serial.print("Comprimento de Onda = ");
138.        Serial.print(" ");
139.        Serial.println(lambdaVerde,DEC);
140.        ColetaCores();
141.        delay(500);//para leitura da componente verde
142.  //azul
143.        delay(50);
144.        myStepper.step(4); // para leitura da componente azul - considerando a partir da componente verde.
145.        lambda_componenteAzul();
146.        Serial.print("Comprimento de Onda = ");
147.        Serial.print(" ");
148.        Serial.println(lambdaAzul,DEC);
149.        ColetaCores();
150.        delay(500);
151.        myStepper.step(-(11)); // volta ao inicio.
152.        PararCliente();
153.        delay(10);
154.        Serial.println("Proximo Cliente...");
155.  }
156.  void posiciona_motor_comb3(){ // comb3 = vermelho + azul
157.  //vermelho
158.        delay(50);
159.        myStepper.step(0);
160.        lambda_componenteVermelha();
161.        Serial.print("Comprimento de Onda = ");
162.        Serial.print(" ");
163.        Serial.println(lambdaVermelha,DEC);
164.        ColetaCores();
165.        delay(500);
166.  //verde
167.        delay(50);//para leitura da componente verde
168.        myStepper.step(11); // para leitura da componente verde - considerando a partir da componente vermelha.
169.        lambda_componenteAzul();
170.        Serial.print("Comprimento de Onda = ");
171.        Serial.print(" ");
172.        Serial.println(lambdaAzul,DEC);
173.        ColetaCores();
174.        delay(500);
175.        myStepper.step(-(11)); // volta ao inicio.
176.        PararCliente();
177.        delay(10);
178.        Serial.println("Proximo Cliente...");
179.  }



Nas linhas de programação da IDE do Arduino também são colocadas (vide Anexo 3) funções de cálculo de comprimento de onda, relacionadas aos cálculos para o comprimento de onda da componente vermelha (lambda_componenteVermelha()), da componente verde (lambda_componenteVerde()) e da componente azul (lambda_componenteAzul()), as quais dependem do arranjo geométrico e da distância rede-anteparo (que varia conforme o giro da rede), determinada pelo sensor infravermelho SHARP (modelo GP2Y0A21YK0F). Esses cálculos junto às informações coletadas pelo sensor conversor de frequência (informações de irradiância, em W/m²), nos mostram a curva de distribuição espectral, de irradiância (W/m²) por comprimento de onda (nm).

Junto a essas informações, para coleta dos dados para o gráfico,também fica disponível na programação a função para detecção (DetectaCores()) do sensor detector de cores (TCS 34725) e finalmente a função para leitura e detecção das cores (ColetaCores()), a partir da qual, com o sensor colocado de frente à projeção da fenda, se pode detectar as proporções das componentes vermelha, verde e azul, com fins de comparação às informações que se obtém pelo gráfico. Essas funções, tanto do sensor conversor de frequência quanto do detector de cores podem ser observadas no quadro 3.





Quadro 3 - Programação da Terceira parte da programação do Experimento Off-Line: Aqui são calculados os valores de irradiância (através de programação do sensor TCS 34725) por comprimento de onda (através de cálculo considerando o arranjo geométrico – ver Anexo 2).
1.       ////Descrições das funções de cãlculos de comprimento de onda///////
2.       void lambda_componenteVermelha(){
3.         lambdaVermelha = ((d*0.093)/sqrt(pow(l,2)+pow(0.093,2)))*pow(10,9);
4.         delay(100);
5.       }
6.       void lambda_componenteVerde(){
7.         lambdaVerde = (((d*0.117)/sqrt(pow(l,2)+pow(0.117,2)))-sin((((d*0.117)/sqrt(pow(l,2)+pow(0.117,2)))-((d*0.069)/sqrt(pow(l,2)+pow(0.069,2))))))*pow(10,9);
8.         delay(100);
9.       }
10.    void lambda_componenteAzul(){
11.      lambdaAzul = (((d*0.129)/sqrt(pow(l,2)+pow(0.129,2)))-sin((((d*0.129)/sqrt(pow(l,2)+pow(0.129,2)))-((d*0.057)/sqrt(pow(l,2)+pow(0.057,2))))))*pow(10,9);
12.      delay(100);
13.    }
14.     
15.    ////////descrições das funções de detecção do sensor de cores e da leitura do mesmo///////////////////
16.    void DetectaCores(){
17.            /*programação de inicialização do sensor detector de cores TCS34725
18.            Mais detalhes em https://learn.adafruit.com/adafruit-color-sensors/program-it */
19.           Serial.println("Detectando cores");
20.           if (tcs.begin()) {
21.              Serial.println("Sensor encontrado:");
22.              } else {
23.                  Serial.println("Sem TCS34725! Check conections!");
24.                  while (1);
25.              }
26.     }
27.    void ColetaCores(){
28.      ReceberColetaDados = true;
29.      uint16_t clearcol, red, green, blue;
30.      float average, r, g, b;
31.      delay(100);
32.      tcs.getRawData(&red, &green, &blue, &clearcol);

33.      average = (red + green + blue) / 3;
34.      r = red / average;
35.      g = green / average;
36.      b = blue / average;
37.      Serial.print("\t NADA:"); Serial.print(clearcol);
38.      Serial.print("\t VERMELHO:"); Serial.print(r);
39.      Serial.print("\t VERDE:"); Serial.print(g);
40.      Serial.print("\t AZUL:"); Serial.print(b);
41.     
42.      if ((r > 1.7) && (g < 1.0) && (b < 1.0)) {
43.           Serial.print("\t VERMELHO");
44.      }
45.      else if ((r < 0.5) && (g > 1.50) && (b < 1.00)) {
46.           Serial.print("\t VERDE");
47.      }
48.      else if ((r < 0.5) && (g < 1.5) && (b > 1.45)) {
49.           Serial.print("\t AZUL");
50.      }
51.       else {
52.            Serial.print("\t NENHUMA COR ENCONTRADA");
53.      }
54.      
55.      Serial.println(" ");
56.      delay(100);
57.    }



A interface de controle comanda remotamente o envio de sinais ao emissor IR, e este, por sua vez, envia os sinais ao receptor IR (dentro da lâmpada de LED). A programação e o processo de decodificação dos sinais do controle remoto da lâmpada são melhor apresentados no item 9.4.2.3.2, referente ao sensor infra-vermelho). Ao receber estes sinais enviados pela interface até a saída serial, a lâmpada muda de cor. Ao se mudar as cores, a programação aciona as funções descritas anteriormente relacionadas ao posicionamento do motor (posiciona_motor-vermelho(), posiciona_motor_verde(), etc...), para as respectivas cores que representam as diferentes combinações das cores da componente do espectro.


Consequentemente, com estas funções sendo acionadas, o motor também é acionado e roda os determinados números de passos, fazendo com que as componentes das cores cheguem ao conversor de frequência (TSL235R), o qual coleta os dados de irradiância, que se junta aos valores anteriormente calculados para comprimentos de onda . Paralelamente, o sensor detector de cores (TCS34725) coleta as informações de proporção de cada componente (vermelho, verde e azul)na projeção da fenda, que se encontra sobre tal sensor.Ao fim de cada procedimento, o motor roda de volta à posição original, esperando pelo próximo cliente. Nesta parte da programação, o comando de ligar (letra “L”, via botão da interface de controle, acionada por usuário remoto) aciona a função IniciarColeta(), e o comando de desligar (letra “D”, via botão da interface de controle) aciona o comando PararCliente(), a fim de se encerrar a conexão e parar o motor.


Essa parte da programação é apresentada no quadro 4, a seguir

Quadro 4 - Programação comando via teclado para acionamento das cores da lâmpada de LED. Nesta parte da programação, associa-se as programações apresentadas anteriormente, através da função posiciona_motor().
1.       void ligar_motor() {
2.         if (Serial.available() > 0) {
3.           char tecla = Serial.read();
4.        
5.           if (tecla == '1') {
6.             for (int i = 0; i < 1; i++) {
7.               irsend.sendNEC(0xFFA05F, 32); // Sony TV power code
8.               delay(200);
9.             }
10.          delay(200);
11.          Serial.println ("Aumenta Brilho");
12.        }
13.        if (tecla == '0') {
14.          for (int i = 0; i < 1; i++) {
15.            irsend.sendNEC(0xFF20DF, 32); // Sony TV power code
16.            delay(200);
17.          }
18.          delay(200);
19.          Serial.println ("Diminui Brilho");
20.        }
21.        if (tecla == 'D') {
22.          for (int i = 0; i < 1; i++) {
23.            irsend.sendNEC(0xFF609F, 32); // Sony TV power code
24.            delay(400);
25.            Serial.println ("DESLIGA");
26.          }
27.          myStepper.step((stepsPerRevolution));
28.          delay(200);
29.          PararCliente();
30.          Serial.println ("Ate a proxima!");
31.        }
32.        if (tecla == 'L') {
33.          for (int i = 0; i < 1; i++) {
34.            irsend.sendNEC(0xFFE01F, 32); // Sony TV power code
35.            Serial.println ("LIGA");
36.            delay(400);
37.          }
38.          IniciarColeta();
39.          Serial.println ("Dispositivo pronto para coletar dados!");
40.        }
41.        if (tecla == 'R') {
42.          for (int i = 0; i < 1; i++) {
43.            irsend.sendNEC(0xFF906F, 32); // Sony TV power code
44.            delay(400);
45.          }
46.          Serial.println ("Vermelho");
47.          posiciona_motor_vermelho();
48.          delay(30);
49.        }
50.        if (tecla == 'G') {
51.          for (int i = 0; i < 1; i++) {
52.            irsend.sendNEC(0xFF10EF, 32); // Sony TV power code
53.            delay(400);
54.            Serial.println ("Verde");
55.          }
56.          posiciona_motor_verde();
57.          delay(30);
58.        }
59.        if (tecla == 'B') {
60.          for (int i = 0; i < 1; i++) {
61.            irsend.sendNEC(0xFF50AF, 32); // Sony TV power code
62.            delay(400);
63.            Serial.println ("Azul");
64.          }
65.          posiciona_motor_azul();
66.          delay(30);
67.        }
68.        if (tecla == 'W') {
69.          for (int i = 0; i < 1; i++) {
70.            irsend.sendNEC(0xFFD02F, 32); // Sony TV power code
71.            delay(400);
72.            Serial.println ("Branco");
73.          }
74.          posiciona_motor_branco();
75.          delay(30);
76.        }
77.        if (tecla == 'o') {
78.          for (int i = 0; i < 1; i++) {
79.            irsend.sendNEC(0xFFB04F, 32); // Sony TV power code
80.            delay(400);
81.            Serial.println ("Laranja");
82.          }
83.          posiciona_motor_comb1();
84.          delay(30);
85.        }
86.        if (tecla == 'g') {
87.          for (int i = 0; i < 1; i++) {
88.            irsend.sendNEC(0xFF30CF, 32); // Sony TV power code
89.            delay(400);
90.            Serial.println ("Verde Claro");
91.          }
92.          posiciona_motor_comb2();
93.          delay(30);
94.        }
95.        if (tecla == 'b') {
96.          for (int i = 0; i < 1; i++) {
97.            irsend.sendNEC(0xFF708F, 32); // Sony TV power code
98.            delay(400);
99.            Serial.println ("Azul Esmeralda");
100.        }
101.        posiciona_motor_comb3();
102.        delay(30);
103.      }
104.      if (tecla == 'F') {
105.        for (int i = 0; i < 1; i++) {
106.          irsend.sendNEC(0xFFF00F, 32); // Sony TV power code
107.          delay(400);
108.        }
109.        Serial.println ("Flash");
110.      }
111.      if (tecla == 'O') {
112.        for (int i = 0; i < 1; i++) {
113.          irsend.sendNEC(0xFFA857, 32); // Sony TV power code
114.          delay(400);
115.          Serial.println ("Laranja Escuro");
116.        }
117.        posiciona_motor_comb1();
118.        delay(30);
119.      }
120.      if (tecla == 'z') {
121.        for (int i = 0; i < 1; i++) {
122.          irsend.sendNEC(0xFF28D7, 32); // Sony TV power code
123.          delay(400);
124.          Serial.println ("Azul Anil");
125.        }
126.        posiciona_motor_comb2();
127.        delay(30);
128.      }
129.      if (tecla == 'x') {
130.        for (int i = 0; i < 1; i++) {
131.          irsend.sendNEC(0xFF6897, 32); // Sony TV power code
132.          delay(400);
133.          Serial.println ("Roxo");
134.        }
135.        posiciona_motor_comb3();
136.        delay(30);
137.      }
138.   
139.      if (tecla == 'S') {
140.        for (int i = 0; i < 1; i++) {
141.          irsend.sendNEC(0xFFE817, 32); // Sony TV power code
142.          delay(400);
143.        }
144.        Serial.println ("Estrobo");
145.      }
146.      if (tecla == 'y') {
147.        for (int i = 0; i < 1; i++) {
148.          irsend.sendNEC(0xFF9867, 32); // Sony TV power code
149.          delay(400);
150.          Serial.println ("Amarelo Claro");
151.        }
152.        posiciona_motor_comb1();
153.        delay(30);
154.      }
155.      if (tecla == 'c') {
156.        for (int i = 0; i < 1; i++) {
157.          irsend.sendNEC(0xFF18E7, 32); // Sony TV power code
158.          delay(400);
159.          Serial.println ("Azul Turquesa");
160.        }
161.        posiciona_motor_comb2();
162.        delay(30);
163.      }
164.      if (tecla == 'P') {
165.        for (int i = 0; i < 1; i++) {
166.          irsend.sendNEC(0xFF58A7, 32); // Sony TV power code
167.          delay(400);
168.          Serial.println ("Pink");
169.        }
170.        posiciona_motor_comb3();
171.        delay(30);
172.      }
173.      if (tecla == '<') {
174.        for (int i = 0; i < 1; i++) {
175.          irsend.sendNEC(0xFFD827, 32); // Sony TV power code
176.          delay(400);
177.        }
178.        Serial.println ("Fade");
179.      }
180.      if (tecla == 'Y') {
181.        for (int i = 0; i < 1; i++) {
182.          irsend.sendNEC(0xFF8877, 32); // Sony TV power code
183.          delay(400);
184.          Serial.println ("Amarelo");
185.        }
186.        posiciona_motor_comb1();
187.        delay(30);
188.      }
189.      if (tecla == 'C') {
190.        for (int i = 0; i < 1; i++) {
191.          irsend.sendNEC(0xFF08F7, 32); // Sony TV power code
192.          delay(400);
193.          Serial.println ("Verde-Agua");
194.        }
195.        posiciona_motor_comb2();
196.        delay(30);
197.      }
198.      if (tecla == 'V') {
199.        for (int i = 0; i < 1; i++) {
200.          irsend.sendNEC(0xFF48B7, 32); // Sony TV power code
201.          delay(400);
202.          Serial.println ("Violeta");
203.        }
204.        posiciona_motor_comb3();
205.        delay(30);
206.      }
207.      if (tecla == '-') {
208.        for (int i = 0; i < 1; i++) {
209.          irsend.sendNEC(0xFFC837, 32); // Sony TV power code
210.          delay(400);
211.        }
212.        Serial.println ("Smooth");
213.      }
214.      Serial.println("\n");
215.    }
216.  }






Para fins de completude, embora apresentada anteriormente convém lembrar que a função que encerra a conexão com o cliente e para o motor quando volta a posição inicial é novamente apresentada a seguir:


Quadro 5 - Programação de encerramento de conexão com o cliente e parada do motor na posição inicial.
void(*resetFunc)(void)=0;              // comando que diz ao Arduino que as próximas instruções devem ser executadas,até 
                                                        // se chegar a função resetFunc, a qual esta dentro da função PararCliente()
void PararCliente(){                       // função que faz a ordem de parar a medição e fecha conexão com o cliente até se
                                                       //estabelecer outra.
  delay(200);
    Serial.println("resetando...");
    resetFunc();                                // função que reseta a leitura de dados, fechando a conexão com o cliente.
    delay(100);
    Serial.println("OK. Pronto para novo Cliente");
}

Nenhum comentário :

Postar um comentário

Deixe aqui seus comentários, críticas, sugestões de melhorias, dúvidas, o que quiser. Mas por favor, seja educado e claro. OK?