MFC_data.ino 28.4 KB
Newer Older
Guilherme Porto's avatar
Guilherme Porto committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815

#include <Wire.h>  
#include "FS.h"
#include "SD.h"
#include "SPI.h"
/*
Biblioteca para Cartão SD - comunicação SPI. 
*/

#include <Adafruit_ADS1X15.h>  
/*
Biblioteca para conversor ADC - ADS1015 
Gerenciador de bibliotecas IDE Arduíno 
Versão 2.2.0
*/

#include <time.h> 
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include "esp_wpa2.h"
/*
Biblioteca para conexão com a rede WiFi comum.   
#include <WiFi.h>
Biblioteca para conexão com a rede WiFi privada/autentificação.   
#include <WiFiClientSecure.h>
#include "esp_wpa2.h"
*/

/**********************************************************************************************/

/*
#define EAP_ANONYMOUS_IDENTITY ""         // Identidade anônima - Sem caracteres para Eduroam UFRGS
#define EAP_IDENTITY "xxxxxx@ufrgs.br"    // Nro Cartão UFRGS + @ufrgs,br 
#define EAP_PASSWORD "Senha"              // Senha portal UFRGS

const char* ssid = "eduroam";             // eduroam SSID - Identificação da rede 
const char* host = "ufrgs.br";            // external server domain for HTTPS connection
int counter = 0;                          // Contador para reconexão com o servidor. 

 
// Chave de autentificação da rede privada (Eduroam UFRGS) 

const char* test_root_ca = \
                           "-----BEGIN CERTIFICATE-----\n" \
                            "MIIFCTCCA/GgAwIBAgIQV0cXGWPWQYpD97TkhRl8LzANBgkqhkiG9w0BAQsFADCB\n" \
                            "DELMAkGA1UEBhMCQlIxHzAdBgNVBAgTFlJpbyBHcmFuZGUgZG8gU3VsIC0gUlMx\n" \
                            "FTATBgNVBAcTDFBvcnRvIEFsZWdyZTE6MDgGA1UEChMxVW5pdmVyc2lkYWRlIEZl\n" \
                            "ZGVyYWwgZG8gUmlvIEdyYW5kZSBkbyBTdWwgLSBVRlJHUzEvMC0GA1UECxMmQ2Vu\n" \
                            "dHJvIGRlIFByb2Nlc3NhbWVudG8gZGUgRGFkb3MgLSBDUEQxHDAaBgNVBAMTE0FD\n" \
                            "IFJhaXogZGEgVUZSR1MgdjIwHhcNMTIwNDA5MTQyNTQ2WhcNMzIwNDA5MTQzNTQ1\n" \
                            "WjCB0DELMAkGA1UEBhMCQlIxHzAdBgNVBAgTFlJpbyBHcmFuZGUgZG8gU3VsIC0g\n" \
                            "UlMxFTATBgNVBAcTDFBvcnRvIEFsZWdyZTE6MDgGA1UEChMxVW5pdmVyc2lkYWRl\n" \
                            "IEZlZGVyYWwgZG8gUmlvIEdyYW5kZSBkbyBTdWwgLSBVRlJHUzEvMC0GA1UECxMm\n" \
                            "Q2VudHJvIGRlIFByb2Nlc3NhbWVudG8gZGUgRGFkb3MgLSBDUEQxHDAaBgNVBAMT\n" \
                            "E0FDIFJhaXogZGEgVUZSR1MgdjIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\n" \
                            "AoIBAQDvCmjv3cCM0wZHaF7fHlFIQwbFimXNGQxMAajDaDC6QAubbRVYGuIqscoY\n" \
                            "8IlBgXXrFlrZVj377S9Ve5PncEh3bJeJuvIhgo2Vt6QGBiquiMqciWFtgXIFIqjn\n" \
                            "rZnGa3UumxMgY+jWsfM29Lk69pARdW31XyPbiVwOKZcZ/RyB01RRS2NLOvssvKaS\n" \
                            "XB6vXi4MJ42EoXtLV8tEFh1+ut7RzwzzsvN6rCWLE3I2cXlPBHOHdVECWgricxZA\n" \
                            "4Q6m9GZF3Rx0MY5Lrx8B9cCDbHRfxMVS4vzEviMrBid+S8pvd8GwliH6AXEEJZeW\n" \
                            "AJG1sRVCT1wTlUs21asYXJ17t1D9AgMBAAGjgdwwgdkwCwYDVR0PBAQDAgGGMA8G\n" \
                            "A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFPC2+TnNd301pBWHLhXqXNNStGz8MD0G\n" \
                            "A1UdHwQ2MDQwMqAwoC6GLGh0dHA6Ly93d3cudWZyZ3MuYnIvcGtpL0xDUkFDUmFp\n" \
                            "elVGUkdTdjIuY3JsMBAGCSsGAQQBgjcVAQQDAgEAMEkGCCsGAQUFBwEBBD0wOzA5\n" \
                            "BggrBgEFBQcwAoYtaHR0cDovL3d3dy51ZnJncy5ici9wa2kvY2VydEFDUmFpelVG\n" \
                            "UkdTdjIuY3J0MA0GCSqGSIb3DQEBCwUAA4IBAQBkaJBm2uNtKx9OEdUuvhT3hGLt\n" \
                            "lScQJfC29Vgsk7zDGEvN2xKDH8JDGsox8G9ZYsPkyNOT5TfAc334YxALq4LWZSuY\n" \
                            "l0xsuv4th+8qGIfZjjO1ye0/Z8paLcRLsEC+OR7S+kozsDjibLjSsWqYG04d7jvG\n" \
                            "W8Vhr+0yJqyGN9NiCPpRRTzvpbVpVN0scOhZpZ9vZSfbYnm04ueOEWBgybPXBZPD\n" \
                            "gurFALXB+uONxuNfR33T15PYLeVaaaDlXQ1krupKj9SbiKtBXghTau7ob8pCSBX4\n" \
                            "960mgdCu70CgA6lIFhhW3uaYifAS/h7hdOON3++dFj4FH8My1AUzwnvUtxs0\n" \
                           "-----END CERTIFICATE-----\n";
// You can use x.509 client certificates if you want
//const char* test_client_key = "";   //to verify the client
//const char* test_client_cert = "";  //to verify the client

*/

/**********************************************************************************************/

const char* ssid     = "CLARO_2G75B792";            // Idetificação rede comum
const char* password = "EF75B792";                  // Senha rede comum

long timezone = 1; 
byte daysavetime = 1;

/*
 * Verificação para checar se a versão do microcontrolador usado é compatível com a biblioteca 
 * SimpleTimer.h
*/

#ifndef ESP32
  #error This code is designed to run on ESP32 platform, not Arduino nor ESP8266! Please check your Tools->Board setting.
#elif ( ARDUINO_ESP32S2_DEV || ARDUINO_FEATHERS2 || ARDUINO_ESP32S2_THING_PLUS || ARDUINO_MICROS2 || \
        ARDUINO_METRO_ESP32S2 || ARDUINO_MAGTAG29_ESP32S2 || ARDUINO_FUNHOUSE_ESP32S2 || \
        ARDUINO_ADAFRUIT_FEATHER_ESP32S2_NOPSRAM )
  #define USING_ESP32_S2_TIMER_INTERRUPT            true
#endif

// Configurações para timer

// These define's must be placed at the beginning before #include "ESP32TimerInterrupt.h"
// _TIMERINTERRUPT_LOGLEVEL_ from 0 to 4
// Don't define _TIMERINTERRUPT_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.
// Don't define TIMER_INTERRUPT_DEBUG > 2. Only for special ISR debugging only. Can hang the system.
#define TIMER_INTERRUPT_DEBUG         0
#define _TIMERINTERRUPT_LOGLEVEL_     0

#include "ESP32TimerInterrupt.h"  
#include "ESP32_ISR_Timer.h"

#include <SimpleTimer.h>              // https://github.com/jfturcot/SimpleTimer

/**********************************************************************************************/

int sel_ADC[4]={ 0x48, 0x49, 0x4A, 0x4B }, sel = 0, nR=1, pisca = 2500;
/* Endreço dos conversores ADC - - ID do resistor - frequêcia do LED*/ 

double MFC_16i[16], MFC_8d[8];
/*Dados dos canais dos conversores ADCs - CH - DIFF*/

float ADJ_gain = 0.1875F; 
/* Ajuste de ganho para ganho 1 (ONE)*/

String DATA;
/* Variavel dados enviados: data*/

String HORA;
/* Variavel dados enviados: hora*/

String TENSAO_DIFF ="CH01; CH23;";
/* Variavel dados enviados: Canal diferencial*/

String TENSAO_CH = "CH0; CH1; CH2; CH3";
/* Variavel dados enviados: Canal individual*/

String NOME_PASTA;
/* Variavel para nomeclatura: pasta*/

String NOME_TXT_INFO;
/* Variavel para nomeclatura: Arquivo de informações*/

String NOME_TXT_DIFF;
/* Variavel para nomeclatura: Arquivo de Canais diferenciais*/

String NOME_TXT_CH;
/* Variavel para nomeclatura: Arquivo de Canais individuais*/

byte chaves = B11111111;
/* Variavel para posição inicial das chaves - Todas desligadas*/

int pos_chave[8] = { 254, 253, 251, 247, 239, 223, 191, 127};
/* Vetor para posições das chaves - Alternam entre as posições*/

/**********************************************************************************************/

#define led_pin 2
/* Led indicador definido no PORT2*/

#define CLR 32
/* Shif Resgister pin CLR definido no PORT32*/

#define A 27
/* Shif Resgister pin A definido no PORT27*/

#define B 14
/* Shif Resgister pin B definido no PORT14*/

#define CK 33
/* Shif Resgister pin CK definido no PORT33*/

#define RST 0
/* Botão de comando definido no PORT32*/

ESP32Timer ITimer(1);
/* Inicia interrupção Timer 1*/

ESP32_ISR_Timer ISR_Timer;
/* Inicia interrupação ESP*/

#define SIMPLE_TIMER_MS 2000L
/* Tempo de para ativar função de envio de dados - Tempo de amostragem*/

/**********************************************************************************************/

/* Interrupção para ESP32*/
#if USING_ESP32_S2_TIMER_INTERRUPT
  void IRAM_ATTR TimerHandler(void * timerNo)
#else
  void IRAM_ATTR TimerHandler()
#endif
{
#if USING_ESP32_S2_TIMER_INTERRUPT
  /////////////////////////////////////////////////////////
  // Always call this for ESP32-S2 before processing ISR
  TIMER_ISR_START(timerNo);
  /////////////////////////////////////////////////////////
#endif
  
  #if USING_ESP32_S2_TIMER_INTERRUPT
  /////////////////////////////////////////////////////////
  // Always call this for ESP32-S2 after processing ISR
  TIMER_ISR_END(timerNo);
  /////////////////////////////////////////////////////////
#endif
}

/**********************************************************************************************/

Adafruit_ADS1115  ads;  
/* Use this for the 16-bit version 
 * Nomeando funções ADS1015
*/

//WiFiClientSecure client; 
/* Habilitar quando usar rede privada (Eduroam)*/


SimpleTimer simpleTimer;
/* Nomeando funções SimpleTimer*/

/**********************************************************************************************/

void setup()
{
  Serial.begin(115200);
/* Inicial serial - Baud rate 115200*/  

/**********************************************************************************************/

    Serial.println();
    Serial.println();
    Serial.print("Connecting to ");
    Serial.println(ssid);
/* Envia o nome da rede que irá se conectar*/

    WiFi.begin(ssid, password);
/* Inicia a conexão com a rede wifi*/

   while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
/* Agurada conexão com a rede*/

    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
    Serial.println("Contacting Time Server");
/* Mensagem de confirmação de acessoa rede Wifi*/

/*
Quando utilizar a conexão com a rede comentar a conficuração de Wifi da para rede local/comum.
Retirar dos comentarios as configurações de Wifi para rede empresarial/privada.
*/
/**********************************************************************************************/

  /*
  WiFi.disconnect(true);  
  /* Desconecta do wifi para nova conexão*
  
  WiFi.mode(WIFI_STA); 
  /* Inicia o modo Wifi_STA*

  esp_wifi_sta_wpa2_ent_set_identity((uint8_t *)EAP_ANONYMOUS_IDENTITY, strlen(EAP_ANONYMOUS_IDENTITY)); //provide identity
  /* Seta a identidade do usuario*

  esp_wifi_sta_wpa2_ent_set_username((uint8_t *)EAP_IDENTITY, strlen(EAP_IDENTITY)); //provide username
  /* Seta a nome do usuario*

  esp_wifi_sta_wpa2_ent_set_password((uint8_t *)EAP_PASSWORD, strlen(EAP_PASSWORD)); //provide password
  /* Seta a senha do usuario*

  esp_wifi_sta_wpa2_ent_enable(); // Diferença entre IDE
  /*
  Habilita o wpa2
  Lnha de código diferente entre sa versãoes de IDE 
  *
    
  WiFi.begin(ssid); //connect to wifi
  /* Envia o nome da rede que irá se conectar*
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    counter++;
    if (counter >= 60) { //after 30 seconds timeout - RST board (on unsucessful connection)
      ESP.restart();
    }
  }
  /* Agurada a conexão por 60 segundo
   Ocorrendo fakha reinicia o microcontrolador
   *

  client.setCACert(test_root_ca);
  //client.setCertificate(test_client_cert); // for client verification - certificate
  //client.setPrivateKey(test_client_key);  // for client verification - private key
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address set: ");
  Serial.println(WiFi.localIP()); //print LAN IP
  /* Mensagem de confirmação de acessoa rede Wifi*
  */ 

/**********************************************************************************************/

  configTime(3600*timezone, daysavetime*3600, "time.nist.gov", "0.pool.ntp.org", "1.pool.ntp.org");
  /* Configura o horario com base no servidor*/

  abre_SD ();
  /* Chama a função que inicia a configuração do cartão SD*/

  simpleTimer.setInterval(SIMPLE_TIMER_MS, envio_dados);
  /* Configura a chamada da função no estouro do timer*/
  
  pinMode(led_pin, OUTPUT);
  digitalWrite(led_pin, LOW);
  /* Declara como saída digital o pino led - inicialmete desligada*/

  pinMode(CLR, OUTPUT); pinMode(A, OUTPUT); pinMode(B, OUTPUT); pinMode(CK, OUTPUT);
  /* Declara como saída digital o pinos para contole do Shift register - ClR, A, B, CK*/

  pinMode(RST, INPUT);  
  /*Declara como entrada o pino RST - Botaõ integrado no módulo ESP NODE-MCU32S */
}

void loop()
{
 R_rotina();
 /* Chama a função que realiza a rotina do experiemnto*/
      
 shiftOut(B, CK, LSBFIRST, chaves);
 /* Atualiza a posição do chaveamnto dos resistores*/

 simpleTimer.run();      
 /* Chama a função envio_dados após o estouro do Timer*/

 digitalWrite(led_pin, HIGH);
 delay(pisca);
 digitalWrite(led_pin, LOW);
 delay(pisca); 
/* piscs o led para verificação se não ocorreram falhas na execução da rotina*/
}

/**********************************************************************************************/

/* Função configura os módulos dos conversores ADC*/
void Inicia_MFC (int n)
{
    ads.begin(sel_ADC[n]);
    /* Inicializa o conversor ADC conforme a endereço - 0x48, 0x49, 0x4A, 0x4B*/
      
    ads.setGain(GAIN_TWOTHIRDS);
    /* Seta o ganho do ADC conforme faxa de operação - GAIN_TWOTHIRDS/ONE/TWO/FOUR*/  

}

/* Função realiza as leituras dos módulo e canais dos conversores ADC*/  
void Le_MFC ()
{
    for (int i = 0; i < 2; i++) 
    {
       Inicia_MFC (i);
       /* Chama a função que inicializa o módulo 'i' módulos para ler canal Diferencial */  
    
       MFC_8d[i]=ads.readADC_Differential_0_1();
       MFC_8d[i+4]=ads.readADC_Differential_2_3();
       /* Grava os dados dos canais diferenciais na var. 'MFC_8d' */
       
    }
    /* Realiza a varredura dos 'n' módulos para ler canal Diferencial */  
    
    for (int i = 0; i < 2; i++){
      Inicia_MFC (i);
      /* Chama a função que inicializa o módulo 'i' módulos para ler canal Individual */
      
     for (int j = 0; j < 4; j++)
      MFC_16i[i*4+j]=ads.readADC_SingleEnded(j);
      /* Grava os dados dos canais individuais na var. 'MFC_16i' */
        
   }
   /* Realiza a varredura dos 'n' módulos para ler canal Individual */

}

/* Função realiza o envio dados dados coletados via serial - realiza o backup na cartão SD*/    
void envio_dados()
{ 
  sel=!sel;
  /* Variavel auxiliar para troca de envio entre canais diferenciais e canais individuias */
  
  Le_MFC ();
  /* Chama função que le e grava os dados dos conversores ADC */

  Serial.println(" Inicio da envio ");
  /* Sinaliza o inicio do envio de dados via Serial*/

  /* Verifica a troca de envio entre canais diferenciais e canais individuias */
  if (sel==0)
  {  
   save_DATA_HORA ();
   /* Coleta a data e hora atual do envio*/
   
   appendFile(SD, NOME_TXT_DIFF.c_str(), DATA.c_str());
   /* Salva a data do envio no arquivo .txt das leituras diferenciais*/
   
   appendFile(SD, NOME_TXT_DIFF.c_str(), HORA.c_str());
   /* Salva a hora do envio no arquivo .txt das leituras diferenciais*/
   
    for (int i = 0; i < 2; i++) 
    {  
        Serial.print("  ADC_"); Serial.print(i); Serial.print(" _MFC_1"); Serial.print(" ");
        Serial.print(MFC_8d[i]*ADJ_gain); Serial.print(" mV "); Serial.print(" Resistor nro: "); Serial.println(nR);
        TENSAO_DIFF = String (MFC_8d[i]*ADJ_gain) + "; ";
        /* Envio dos dados canais diferencias_0_1 via Serial*/
        
        escreve_TENSAO_DIFF ();
        /* Envio dos dados canais diferencias_0_1 via Cartão SD*/

        Serial.print("  ADC_"); Serial.print(i); Serial.print(" _MFC_2"); Serial.print(" ");
        Serial.print(MFC_8d[i+4]*ADJ_gain);Serial.print(" mV "); Serial.print(" Resistor nro: "); Serial.println(nR); 
        TENSAO_DIFF = String (MFC_8d[i+4]*ADJ_gain) + "; ";
        /* Envio dos dados canais diferencias_2_3 via Serial*/
        
        escreve_TENSAO_DIFF ();
        /* Envio dos dados canais diferencias_2_3 via Cartão SD*/

    }
    /* Fim da varredura pelo módulo dos canais doferenciais*/
    
    appendFile(SD, NOME_TXT_DIFF.c_str(), "\n");
    /* Sinaliza o fim do envio para o arquivo .txt*/
    
  } 
  else 
  {
   save_DATA_HORA ();
   /* Coleta a data e hora atual do envio*/
   
   appendFile(SD, NOME_TXT_CH.c_str(), DATA.c_str());
   /* Salva a data do envio no arquivo .txt das leituras individuais*/
   
   appendFile(SD, NOME_TXT_CH.c_str(), HORA.c_str());
   /* Salva a hora do envio no arquivo .txt das leituras individuais*/
   
    for (int i = 0; i < 8; i++) 
    {  
        Serial.print("  ADC_"); Serial.print(i/4); Serial.print(" _MFC_"); Serial.print(i%4);
        Serial.print(" ");
        Serial.print(MFC_16i[i]*ADJ_gain); Serial.print(" mV "); Serial.print(" Resistor nro: "); Serial.println(nR);
        TENSAO_CH = String (MFC_16i[i]*ADJ_gain) + "; ";
        /* Envio dos dados canais individuais 'i' via Serial*/
        
        escreve_TENSAO_CH ();  
        /* Envio dos dados canais individuais 'i' via Cartão SD*/
        
    }
    /* Fim da varredura pelo módulo dos canais diferenciais*/
    
    appendFile(SD, NOME_TXT_CH.c_str(), "\n");
    /* Sinaliza o fim do envio para o arquivo .txt*/
    
   }  
    Serial.println(" Fim da envio ");
    /* Sinaliza o inicio do envio de dados via Serial*/
}

/**********************************************************************************************/

/* Função que atualiza a hora e data atual*/   
void save_DATA_HORA (){
    
    struct tm tmstruct;
    /* Variavel tipo struct que recebe os dados de data e hora*/   
    
    tmstruct.tm_year = 0; tmstruct.tm_mon = 0; tmstruct.tm_mday = 0;
    tmstruct.tm_hour = 0; tmstruct.tm_min = 0; tmstruct.tm_sec = 0;    
    /* Inicia os campos com valor '0'*/   
     
    getLocalTime(&tmstruct, 5000);
    /* a variavel tmstruct recebe os dados de data e hora*/
    
    Serial.printf("\nNow is : %d-%02d-%02d %02d:%02d:%02d\n",(tmstruct.tm_year)+1900,( tmstruct.tm_mon)+1, tmstruct.tm_mday,tmstruct.tm_hour , tmstruct.tm_min, tmstruct.tm_sec);
    /*os dados de data e hora são enviado via serial*/
    
    DATA = String((tmstruct.tm_year)+1900) + "/" + String(( tmstruct.tm_mon)+1) + "/" + String(tmstruct.tm_mday) + "; " ;
    /*os dados de data são tranformados em tipo String e salvos na variavel 'DATA'*/
    
    HORA = String(tmstruct.tm_hour) + ":" + String(tmstruct.tm_min) + ":" + String(tmstruct.tm_sec) + "; " ; 
    /*os dados de hora são tranformados em tipo String e salvos na variavel 'HORA'*/
    
    Serial.println("");
    /*Comando para nova linha via Serial*/
    
  } 

/* Função que atualiza o nomeia a pasta de acordo com a hora e data criada*/
void nome_PASTA () {
  
    struct tm tmstruct;
    /* Variavel tipo struct que recebe os dados de data e hora*/

    tmstruct.tm_year = 0; tmstruct.tm_mon = 0; tmstruct.tm_mday = 0;
    tmstruct.tm_hour = 0; tmstruct.tm_min = 0; tmstruct.tm_sec = 0;    
    /* Inicia os campos com valor '0'*/ 
     
    getLocalTime(&tmstruct, 5000);
    /* a variavel tmstruct recebe os dados de data e hora*/
    
    NOME_PASTA = "/EXP-" + String((tmstruct.tm_year)+1900) + "-" + String(( tmstruct.tm_mon)+1) + "-" + String(tmstruct.tm_mday)+ "-" + String(tmstruct.tm_hour) + "-" + String(tmstruct.tm_min) + "-" + String(tmstruct.tm_sec);
    /* Variavel cuja string irá nomear a pasta criada durante o experimento*/
    
}

/* Função que atualiza o nomeia os arquivos .txt de acordo com a hora e data criada*/
void nome_TXT () {
    struct tm tmstruct;
    /* Variavel tipo struct que recebe os dados de data e hora*/

    tmstruct.tm_year = 0; tmstruct.tm_mon = 0; tmstruct.tm_mday = 0;
    tmstruct.tm_hour = 0; tmstruct.tm_min = 0; tmstruct.tm_sec = 0;    
    /* Inicia os campos com valor '0'*/ 
    
    getLocalTime(&tmstruct, 5000);
    /* a variavel tmstruct recebe os dados de data e hora*/
    
    NOME_TXT_INFO = String(NOME_PASTA) + "/INFO-" + String(tmstruct.tm_hour) + "-" + String(tmstruct.tm_min) + "-" + String(tmstruct.tm_sec) + ".txt";
    /* Variavel cuja string irá nomear o arquivo .txt de informações criada durante o experimento*/
    
    NOME_TXT_DIFF = String(NOME_PASTA) + "/v_DIFF-" + String(tmstruct.tm_hour) + "-" + String(tmstruct.tm_min) + "-" + String(tmstruct.tm_sec) + ".txt";
    /* Variavel cuja string irá nomear o arquivo .txt DIFF criado durante o experimento*/
    
    NOME_TXT_CH = String(NOME_PASTA) + "/v_CH-" + String(tmstruct.tm_hour) + "-" + String(tmstruct.tm_min) + "-" + String(tmstruct.tm_sec) + ".txt"; 
    /* Variavel cuja string irá nomear o arquivo .txt CH criado durante o experimento*/
    
}

/**********************************************************************************************/

/* Função que incia o cartão SD cria e nomeia a pasta e arquivos do experimento*/
void abre_SD (){

    /* Varifica se a inicialização do cartão SD fracassou*/
    if(!SD.begin()){
        Serial.println("Cartao SD - Nao conectado");
        /* mensagem via Serial de falha na inicialização do cartão SD*/
        
        pisca = 100;
        /* Altera a frequência do Led indicando erro*/
 
        return;
    }
    
    uint8_t cardType = SD.cardType();
    /* Variavel recebe o tipo de variável*/
    
    /* Varifica se a conexão do cartão SD fracassou*/
    if(cardType == CARD_NONE){
        Serial.println("Cartao SD - Nao conectado");
        /* mensagem via Serial de falha na abertura do cartão SD*/
        
        pisca = 100;
        /* Altera a frequência do Led indicando erro*/
        
        return;
    }

    /* Verifica o tipo de cartão SD*/
    Serial.print("SD Card Type: ");
    
    if(cardType == CARD_MMC){
        Serial.println("MMC");
        
    } else if(cardType == CARD_SD){
        Serial.println("SDSC");
        
    } else if(cardType == CARD_SDHC){
        Serial.println("SDHC");
        
    } else {
        Serial.println("UNKNOWN");
    }
    /* Envia o tipo de cartão SD via Serial*/
    
    uint64_t cardSize = SD.cardSize() / (1024 * 1024);
    /* Variavel recebe a tamanho da memoria do cartão SD*/
    
    Serial.printf("SD Card Size: %lluMB\n", cardSize);
    /* Envia o tamanho do cartão SD via Serial*/
    
    listDir(SD, "/", 0);
    /* Envia a lista de diretorios contido no cartão SD via Serial*/
    
    //removeDir(SD, "mydir");
    /* Comando que exclui diretoris contidosn o cartão SD*/
    
    nome_PASTA ();
    nome_TXT ();
    /* Cria novos nomes para pasta e arquivos com hora e data atualizadas*/
  
    createDir(SD, NOME_PASTA.c_str());
    /* Cria novas pasta e arquivos com hora e data atualizadas*/
    
    new_Info_Geral ();
    /* Chama função que cria novos arquivos .txt com o cabeçalho*/
    
}

/* Função que cria e nomeia a pasta e arquivos do experimento*/
void new_Info_Geral (){
   
   writeFile (SD, NOME_TXT_INFO.c_str(), "Experimento: 01 \n");
   /* Cria um arquivo .txt novo para informações e escreve primeiros dados nele*/
   
   appendFile(SD, NOME_TXT_INFO.c_str(), "Data Inicio: \n");
   appendFile(SD, NOME_TXT_INFO.c_str(), "Hora inicio: \n");
   appendFile(SD, NOME_TXT_INFO.c_str(), "Responsavel: \n");
   appendFile(SD, NOME_TXT_INFO.c_str(), "Organismo nome: \n");
   /* Adiciona demais dados no arquivo criado anteriormente para informações*/

   writeFile(SD, NOME_TXT_DIFF.c_str(), "Data; Hora; DATA_0_MFC_01; DATA_0_MFC_23; DATA_1_MFC_01; DATA_1_MFC_23 \n");
   /* Cria um arquivo .txt novo para DIFF e escreve o cabeçalho*/
  
   writeFile(SD, NOME_TXT_CH.c_str(), "Data; Hota; DATA-0_MFC_0; DATA-0_MFC_1; DATA-0_MFC_2; DATA-2_MFC_3; DATA-1_MFC_0; DATA-1_MFC_1; DATA-1_MFC_2; DATA-1_MFC_3 \n"); 
   /* Cria um arquivo .txt novo para CH e escreve o cabeçalho*/  
}

void escreve_TENSAO_DIFF (){
   appendFile(SD, NOME_TXT_DIFF.c_str(), TENSAO_DIFF.c_str());
   /* Adiciona demais dados no arquivo criado anteriormente para DIFF*/
   
}

void escreve_TENSAO_CH (){
   appendFile(SD, NOME_TXT_CH.c_str(), TENSAO_CH.c_str());
   /* Adiciona demais dados no arquivo criado anteriormente para CH*/
    
}

/**********************************************************************************************/

/* Função que altera o chaveamento dos resistores e cria a rotina para leitura dos canais dos ADC*/
void R_rotina()
{

  /* Verifica se a rotina deve retornar ao passo inicial*/
  if (digitalRead(RST)==LOW)
  {
    while (digitalRead(RST)==LOW);
    /* Agurada o botão ser solto*/
    
    nR=1;  
    /* Varaiável que indica qual etapa da rotina está - retorna para fase 1*/
    
  }
  else{

    /* Se a rotina não chegou ao fim*/
    if (nR<=7) 
    {
      chaves = pos_chave[nR];
      /* Atualiza a posição do chaveamento dos relé - Troca o resistor*/
      
      nR = nR+1;
      /* Define nova etapa da rotina*/
      
    }
    else
    {  
      nR=1;
      /* Varaiável que indica qual etapa da rotina está - retorna para fase 1*/
      
      chaves = pos_chave[nR];
      /* Atualiza a posição do chaveamento dos relé - Troca o resistor*/
      
    }
  }
}

/**********************************************************************************************/

/* Função que lista os diretorios no cartão SD - nativa do Arduíno*/
void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
    Serial.printf("Listing directory: %s\n", dirname);

    File root = fs.open(dirname);
    if(!root){
        Serial.println("Failed to open directory");
        return;
    }
    if(!root.isDirectory()){
        Serial.println("Not a directory");
        return;
    }

    File file = root.openNextFile();
    while(file){
        if(file.isDirectory()){
            Serial.print("  DIR : ");
            Serial.print (file.name());
            time_t t= file.getLastWrite();
            struct tm * tmstruct = localtime(&t);
            Serial.printf("  LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n",(tmstruct->tm_year)+1900,( tmstruct->tm_mon)+1, tmstruct->tm_mday,tmstruct->tm_hour , tmstruct->tm_min, tmstruct->tm_sec);
            if(levels){
                listDir(fs, file.path(), levels -1);
            }
        } else {
            Serial.print("  FILE: ");
            Serial.print(file.name());
            Serial.print("  SIZE: ");
            Serial.print(file.size());
            time_t t= file.getLastWrite();
            struct tm * tmstruct = localtime(&t);
            Serial.printf("  LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n",(tmstruct->tm_year)+1900,( tmstruct->tm_mon)+1, tmstruct->tm_mday,tmstruct->tm_hour , tmstruct->tm_min, tmstruct->tm_sec);
        }
        file = root.openNextFile();
    }
}

/* Função que cria novo diretrio no cartão SD - nativa do Arduíno*/
void createDir(fs::FS &fs, const char * path){
    Serial.printf("Creating Dir: %s\n", path);
    if(fs.mkdir(path)){
        Serial.println("Dir created");
    } else {
        Serial.println("mkdir failed");
    }
}

/* Função que remove diretrio no cartão SD - nativa do Arduíno*/
void removeDir(fs::FS &fs, const char * path){
    Serial.printf("Removing Dir: %s\n", path);
    if(fs.rmdir(path)){
        Serial.println("Dir removed");
    } else {
        Serial.println("rmdir failed");
    }
}

/* Função que lê arquivo no cartão SD - nativa do Arduíno*/
void readFile(fs::FS &fs, const char * path){
    Serial.printf("Reading file: %s\n", path);

    File file = fs.open(path);
    if(!file){
        Serial.println("Failed to open file for reading");
        return;
    }

    Serial.print("Read from file: ");
    while(file.available()){
        Serial.write(file.read());
    }
    file.close();
}

/* Função que escreve no arquivo gerendo um novo ou subtituindo no cartão SD - nativa do Arduíno*/
void writeFile(fs::FS &fs, const char * path, const char * message){
    Serial.printf("Writing file: %s\n", path);

    File file = fs.open(path, FILE_WRITE);
    if(!file){
        Serial.println("Failed to open file for writing");
       //pisca = 1000;
        return;
    }
    if(file.print(message)){
        Serial.println("File written");
      //pisca = 500;
    } else {
        Serial.println("Write failed");
      //pisca = 1000;
    }
    file.close();
}

/* Função que acrescenta nova informação no arquivo no cartão SD - nativa do Arduíno*/
void appendFile(fs::FS &fs, const char * path, const char * message){
    Serial.printf("Appending to file: %s\n", path);

    File file = fs.open(path, FILE_APPEND);
    if(!file){
        Serial.println("Failed to open file for appending");
        //pisca = 2000;
        return;
    }
    if(file.print(message)){
      Serial.println("Message appended");
      //pisca = 500;
    } else {
        Serial.println("Append failed");
        //pisca = 2000;
    }
    file.close();
}

/* Função que renomeia arquivo no cartão SD - nativa do Arduíno*/
void renameFile(fs::FS &fs, const char * path1, const char * path2){
    Serial.printf("Renaming file %s to %s\n", path1, path2);
    if (fs.rename(path1, path2)) {
        Serial.println("File renamed");
    } else {
        Serial.println("Rename failed");
    }
}

/* Função que deleta arquivo no cartão SD - nativa do Arduíno*/
void deleteFile(fs::FS &fs, const char * path){
    Serial.printf("Deleting file: %s\n", path);
    if(fs.remove(path)){
        Serial.println("File deleted");
    } else {
        Serial.println("Delete failed");
    }
}