RuiViana

ESP32_FreqMeter_0.38.0.ino

Jul 21st, 2020 (edited)
1,390
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Atual ESP32_FreqMeter_0.33.0.ino    Antigo NovoTeste08.ino
  2.  
  3. // V01 Teste com pcnt
  4. // V02 teste com timer
  5. // V03 Teste de interrupt
  6. // V04 Definicao com escala baseada no prescaler
  7. // V05 Calculos com interrupt
  8. // V06 Versão inicial do frequeciimetro com ESP32 nao esta preciso , Seleciona a escala.
  9. // V07 Modificacoes no loop pra melhorar a escala  funcionou bem
  10. // V07_A Fixando o valor de prescaler em 80   Criada 5a escala
  11. // V07_B teste de erro na rotina pcnt
  12. // V08 Sem escala, fixando o prescaler e o timer e contando os overflows
  13. // V09 Limpando a V08
  14. // V10 Testes com rotina de contagem de overflow
  15. // V11 Teste de overflow de pcnt e timer  funciona  teste com frequenci DE 10 khZ  Copia do frequencimetro 2 modificado
  16. // V12 Resumir e limpar V11  enroscou a partir de 300 KHz
  17. // V13 Consegui bom resultado deste aqui até 20MHz Usando RMT com referencia de tempo
  18. // V14 Interrupt de pcnt e contar tempo de RMT
  19. // V15 Novo teste com RMT
  20. // V16 Qtde de pulsos entre ocorrencias de interrupt
  21. // V17 Outro teste de ocorrencias de interrupt
  22. // V18 Teste com rotina de interrupt com poucas funcoes
  23. // V19 Teste com esp-timer  e interrupt no fim do pulso do esp-timer
  24. // V20 Teste = V19
  25. // V20a Preparada para IDF
  26. // V20aGustavo Sem interrupt de esp-timer
  27. // V21 Inclusao de LCD com diretivas de compilacao
  28. // 0.0.21 = V21
  29. // 0.0.22  Pontuação do numero
  30. // V23 Teste com 2 rotinas de pontuacao
  31. // V24 Parametros de ledc calculados   Diretivas de compilacao para ARDUINO e IDF
  32. // V25 Nova rotina de pontuação
  33. // V26 Usando printf na rotina de pontuacao
  34. // V27 Teste com IDF  Compilou com a IDF do CEI
  35. // V28 Teste com nova rotina de pontuacao e printf
  36. // V30 Rotina de teste depois de erro no IDF e limpeza de variaveis desnecessarias e organização
  37. // V31 Nova Diretiva de compilação  ARDUINO   Inclusão de LCD  ok
  38. // V32 Novamente com rotinas de LCD Mudanca do formato dos port GPIO
  39. // V33 Calculo de Resolucao com base na frequencia e duty de 50%, inclusao de LCD I2C com diretiva e teste gpio matrix incluido
  40. // V34 medir o Duty do pulso recebido até 50HKz funcionou mas não ficou boa Removi
  41. // V35 testar LCD com IDF   Funcionou muito bem Necessita 1 blilioteca hd44780.h.   https://github.com/UncleRus/esp-idf-lib
  42. // V36  testar com LCD I2C IDF   teste Necessita 3 bliliotecas i2cdev.h, pcf8574.h, hd44780.h.  https://github.com/UncleRus/esp-idf-lib
  43. // V37  testar com LCD I2C IDF   Funcionou muito bem   Necessita 3 bliliotecas i2cdev.h, pcf8574.h, hd44780.h.  https://github.com/UncleRus/esp-idf-lib
  44.  
  45. // V38 = V37 reorganizado e com diretivas  Necessita 3 bliliotecas i2cdev.h, pcf8574.h, hd44780.h.  https://github.com/UncleRus/esp-idf-lib
  46. //                                                          comentadas as linhas  #include "esp_idf_lib_helpers.h" nas 3 blibliotecas
  47.  
  48.  
  49. /*
  50.  
  51.   Desenvolvedores: Rui Viana e Gustavo Murta   08/jul/2020
  52.  
  53.   Para desenvolver este projeto, foram aproveitadas partes de códigos dos desenvolvedores
  54.   abaixo referenciados.
  55.  
  56.   O Projeto:
  57.   Um frequencímetro usando ESP32, sem necessidade de escalas e mostrando até 8 dígitos,
  58.   medindo com precisão até 20MHz ou mais.
  59.   Este projeto pode ser compilado com a IDE do arduino ou com o IDF
  60.  
  61.   Definições:
  62.  
  63.   #define PCNT_INPUT_SIG_IO     GPIO_NUM_34                                 // Freq Meter Input GPIO 34
  64.   #define LEDC_HS_CH0_GPIO      GPIO_NUM_25
  65.  
  66.   #define PCNT_INPUT_CTRL_IO    GPIO_NUM_35                                 // Count Control GPIO HIGH=count up, LOW=count down GPIO 25
  67.   #define OUTPUT_CONTROL_GPIO   GPIO_NUM_32                                 // Saida do timer GPIO 2
  68.  
  69.   PORT de entrada do frequencímetro PCNT_INPUT_SIG_IO (GPIO 34)
  70.   PORT de entrada de controle PCNT_INPUT_CTRL_IO      (GPIO 35)
  71.   PORT de saída do timer OUTPUT_CONTROL_GPIO          (GPIO 32)
  72.   O PORT de entrada de controle (GPIO 35) deve ser ligado ao PORT de saída do timer (GPIO 32).
  73.   Estes são os ports usados no projeto, mas podem ser modificados para sua melhor conveniência.
  74.  
  75.   O frequencímetro é dividido em 5 partes:
  76.     1. Contador de pulsos;
  77.     2. Controle de tempo de contagem;
  78.     3. Impressão do resultado;
  79.     4. Espaço para outras funções.
  80.     5. Gerador de sinais programado para 2  Hz  (ou 50.000)
  81.  
  82.   1. O contador de pulso usa o pcnt do ESP32.
  83.      O pcnt tem os seguintes parâmetros:
  84.       a. port de entrada;
  85.       b. canal de entrada;
  86.       c. port de controle;
  87.       d. contagem na subida do pulso;
  88.       e. contagem na descida do pulso;
  89.       f. contagem só com o controle em nível elevado;
  90.       g. limite máximo de contagem.
  91.  
  92.   2. O Controle de tempo de contagem usa o esp-timer.
  93.      O esp-timer tem o seguinte parâmetro:
  94.       a. controle do tempo;
  95.  
  96.   5. Gerador de frequncias para testes usa o ledc
  97.      O ledc tem o seguinte parâmetro:
  98.       a. port de saida;
  99.       b. canal de lcd;
  100.       c. frequencia;
  101.       d. resolucao do ledc;
  102.       e. duty cycle em 5;
  103.  
  104.  
  105.   Funcionamento:
  106.     O port de controle de contagem em nível alto, libera o contador para contar os pulsos que chegam no port de entrada de pulsos.
  107.   Os pulsos são contado tanto na subida quanto na descida do pulso, para melhorar a media de contagem.
  108.   O tempo de contagem é definido pelo esp-timer, e esta' definido em 1 segundo, na variável janela.
  109.   Se a contagem for maior que 20000 pulsos durante o tempo de contagem, ocorre overflow e a cada overflow que ocorre
  110.   e' contabilizado na variável multPulses, e o contador de pulso retorna a zero continuando a contar.
  111.     Quando o tempo de leitura termina, uma rotina é chamada e o valor do no contador de pulsos e' lido e salvo,
  112.     um flag e' ligado indicando que terminou a leitura dos pulsos
  113.  
  114.     No loop, ao verificar que o flag indica que terminou a leitura dos pulsos, o valor é calculado multiplicando
  115.   o numero de overflow por 20000 e somando ao numero de pulsos restantes e dividindo por 2, pois contou 2 vezes.
  116.   Como o pulsos são contados na subida e na descida, a contagem e´ o dobro da frequência.
  117.     Na frequência é insserido pontos e impressa no serial monitor.
  118.   Os registradores são resetados e o port de controle de entrada é novamente elevado para nível alto e a contagem de
  119.   pulsos se inicia.
  120.  
  121.   Tem também um gerador de sinais que gera 50.000 Hz, e pode ser usado para testes.
  122.   Este gerador pode ser alterado para gerar frequencias até 40 MHz.
  123.   Usamos o recurso ledc do ESP32 para gerar frequencia que pode ser usada como teste.
  124.     O valor da frequencia base é 2 (ou 50.000) Hz, mas pode ser digitavo outo valor no serial monitor
  125.     O duty foi fixado como 50%
  126.     A resulução é calculada.
  127.   O Port de saida deste gerador é definido na linha #define LEDC_GPIO.
  128.   Atualmente está definido como GPIO 25.
  129.  
  130.   Internamente usando GPIO matrix,o pulso de entrada foi direcionado para o LED nativo do ESP32,
  131.   assim o LED piscara na frequencia de entrada.
  132.  
  133.   O compilador usa as diretivas de compilacaoo para selecionar:
  134.    Compilador Arduino ou IDF    automatico
  135.    Uso de LCD                   LCD_ON ou LCD_OFF
  136.    Uso de LCD I2C               LCD_I2C_ON ou LCD_I2C_OFF
  137.  
  138.   Referências:
  139.   author=krzychb https://github.com/espressif/esp-idf/tree/master/examples/peripherals/pcnt
  140.   resposta by Deouss » Thu May 17, 2018 3:07 pm no tópico https://esp32.com/viewtopic.php?t=5734
  141.   Gerador de sinais Gustavo https://github.com/Gustavomurta/ESP32_frequenceMeter/blob/master/ESP32OscilatorV03.ino
  142.   Formatação de numero https://arduino.stackexchange.com/questions/28603/the-most-effective-way-to-format-numbers-on-arduino
  143.   https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/esp_timer.html
  144.   https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/pcnt.html
  145.   Bibliotecas LCD e LCD I2C  https://github.com/UncleRus/esp-idf-lib
  146. */
  147.  
  148. #define LCD_ON                                                            // Define LCD_ON, para usar LCD, se não, defina LCD_OFF
  149. #define LCD_I2C_OFF                                                       // Define LCD_I2C_ON, para usar LCD I2C, se não, defina LCD_I2C_OFF
  150.  
  151. #include <stdio.h>
  152. #include "freertos/FreeRTOS.h"
  153. #include "freertos/portmacro.h"
  154. #include "freertos/task.h"
  155. #include "freertos/queue.h"
  156. #include "driver/periph_ctrl.h"
  157. #include "driver/ledc.h"
  158. #include "driver/gpio.h"
  159. #include "driver/pcnt.h"
  160. #include "driver/ledc.h"
  161. #include "esp_attr.h"
  162. #include "esp_log.h"
  163. #include "esp_timer.h"
  164. #include "sdkconfig.h"
  165. #include "math.h"
  166.  
  167. #include "driver/i2c.h"
  168. #include "hd44780.h"
  169. #include "pcf8574.h"
  170.  
  171. #define PCNT_COUNT_UNIT       PCNT_UNIT_0                                 // Unidade 0 do pcnt
  172. #define PCNT_COUNT_CHANNEL    PCNT_CHANNEL_0                              // Canal 0 do pcnt
  173.  
  174. //                 Para usar teste jumper GPIO 25 com GPIO 34
  175. //                 Port de entrada do frequencimetro  GPIO 34
  176. #define PCNT_INPUT_SIG_IO     GPIO_NUM_34                                 // Freq Meter Input GPIO 34
  177. #define LEDC_HS_CH0_GPIO      GPIO_NUM_25                                 // Saida do ledc gerador de pulsos
  178.  
  179. //                  Necessario jumper entre GPIO 32 e GPIO 35
  180. #define PCNT_INPUT_CTRL_IO    GPIO_NUM_35                                 // Count Control GPIO HIGH = count up, LOW = count down
  181. #define OUTPUT_CONTROL_GPIO   GPIO_NUM_32                                 // Saida do timer GPIO 32 Controla a contagem
  182.  
  183. #define IN_BOARD_LED          (gpio_num_t)2                               // LED nativo ESP32 GPIO 2
  184.  
  185. #define LEDC_HS_CH0_CHANNEL   LEDC_CHANNEL_0                              // LEDC no canal 0
  186. #define LEDC_HS_MODE          LEDC_HIGH_SPEED_MODE                        // LEDC em high speed
  187. #define LEDC_HS_TIMER         LEDC_TIMER_0                                // Usar timer0 do ledc
  188.  
  189. uint32_t         overflow  =  20000;                                      // Valor maximo para overflow de pcnt
  190. #define PCNT_H_LIM_VAL        overflow                                    // Limite superior de contagem
  191.  
  192. esp_timer_create_args_t create_args;                                      // Argumentos do esp-timer
  193. esp_timer_handle_t timer_handle;                                          // Instancia de esp-timer
  194.  
  195. //  Calculo do ajustes para cada faixa de frequencia
  196. //  Resolucao = log2(Clock(80MHz)/f) + 1   ex: 50.000 HZ = 80.0000/50.000 = 1.600 log2(1600) = 10 + 1 = 11
  197. //  Duty 50%  = (2**Resolucao)/2       ex: 2**11 = 2048   2048/2 = 1024
  198.  
  199. bool            flag          = true;                                     // Indicador de fim de contagem libera impressao
  200. int16_t         pulses        = 0;                                        // Contador de pulsos de entrada
  201. uint32_t        multPulses    = 0;                                        // Contador de overflows de pcnt
  202. uint32_t        janela        = 1000000;                                  // Janela de 1 segundo para a contagem de pulsos
  203. uint32_t        oscilator     = 2;                                        // Frequencia em Hz
  204. uint32_t        mDuty         = 0;                                        // Valor calculado do duty
  205. uint32_t        resolucao         = 0;                                    // Valor calculado da resolucao
  206.  
  207. #ifdef LCD_I2C_ON                                                         // Se tem LCD I2C
  208. #define SDA_GPIO gpio_num_t(16)                                           // GPIO I2C SDA para o LCD
  209. #define SCL_GPIO gpio_num_t(17)                                           // GPIO I2C SCL para o LCD
  210. #define I2C_ADDR 0x38                                                     // Endereco I2C do PCF8574
  211. static i2c_dev_t pcf8574;                                                 // Instancia PCF8574
  212. #endif                                                                    // LCD I2C
  213.  
  214. #if defined LCD_ON || defined LCD_I2C_ON                                  // Se tem LCD
  215. hd44780_t lcd = {};                                                       // Instancia LCD
  216. #endif                                                                    // LCD
  217.  
  218. portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;                     // variavel tipo portMUX_TYPE para sincronismo
  219. //----------------------------------------------------------------------------------------
  220. #ifdef LCD_I2C_ON                                                         // Se tem LCD I2C
  221.  
  222. void configI2C() {                                                        // Configuracao LCD i2c
  223.   i2c_config_t conf;                                                      // Cria o confif
  224.   conf.mode = I2C_MODE_MASTER;                                            // Mode de operacao
  225.   conf.sda_io_num = SDA_GPIO;                                             // GPIO SDA
  226.   conf.scl_io_num = SCL_GPIO;                                             // GPIO SCL
  227.   conf.sda_pullup_en = GPIO_PULLUP_ENABLE;                                // Pullup no SDA
  228.   conf.scl_pullup_en = GPIO_PULLUP_ENABLE;                                // Pullup no SCL
  229.   conf.master.clk_speed = 100000;                                         // Clock do i2s
  230.   i2c_param_config(I2C_NUM_0, &conf);                                     //  Configura
  231.  
  232.   i2c_driver_install(I2C_NUM_0, I2C_MODE_MASTER, 0, 0, 0);                // Inicia o i2c
  233. }
  234. //----------------------------------------------------------------------------------------
  235. static esp_err_t write_lcd_data(const hd44780_t *lcd, uint8_t data)
  236. {
  237.   return pcf8574_port_write(&pcf8574, data);                              // Grava dados no PCF8574
  238. }
  239. //----------------------------------------------------------------------------------------
  240. void lcd_test()
  241. {
  242.   //  hd44780_t lcd = {};
  243.   lcd.write_cb = write_lcd_data,                                          // Chama rotina de gravar dados no PCF8574
  244.       lcd.font = HD44780_FONT_5X8,                                        // Define formato do caracter
  245.           lcd.lines = 2,                                                  // Numero de linhas do LCD
  246.   lcd.pins = {                                                            // Pinos do LCD no PCF8574
  247.     .rs = 0,                                                              // RS
  248.     .e  = 2,                                                              // Enable
  249.     .d4 = 7,                                                              // D4
  250.     .d5 = 6,                                                              // D5
  251.     .d6 = 5,                                                              // D6
  252.     .d7 = 4,                                                              // D7
  253.     .bl = 3                                                               // LEd de iluminacao do LCD
  254.   };
  255.  
  256.   memset(&pcf8574, 0, sizeof(i2c_dev_t));                                 // Aloca espaco na memoria para o PCF8574
  257.   ESP_ERROR_CHECK(pcf8574_init_desc(&pcf8574, i2c_port_t(0), I2C_ADDR, SDA_GPIO, SCL_GPIO)); // Inicializa o  PCF8574
  258.   ESP_ERROR_CHECK(hd44780_init(&lcd));                                    // Inicialisa o hd44780
  259.   hd44780_switch_backlight(&lcd, true);                                   // Liga o LED
  260. }
  261. #endif                                                                    // LCD I2C
  262. //----------------------------------------------------------------------------------------
  263. #ifdef LCD_ON                                                             // Se tem LCD DIRETO
  264.  
  265. void lcd_init()                                                           // Rotina para inicialisar o LCD DIRETO
  266. {
  267.   lcd.font = HD44780_FONT_5X8,                                            // Define formato do caracter
  268.       lcd.lines = 2;                                                      // Numero de linhas do DIRETO
  269.   lcd.pins = {                                                            // Pinos do LCD DIRETO
  270.     .rs = GPIO_NUM_5,                                                     // RS
  271.     .e  = GPIO_NUM_18,                                                    // Enable
  272.     .d4 = GPIO_NUM_19,                                                    // D4
  273.     .d5 = GPIO_NUM_21,                                                    // D5
  274.     .d6 = GPIO_NUM_22,                                                    // D6
  275.     .d7 = GPIO_NUM_23,                                                    // D7
  276.     .bl = HD44780_NOT_USED                                                // LEd de iluminacao do LCD DIRETO
  277.   };
  278.   ESP_ERROR_CHECK(hd44780_init(&lcd));                                    // Inicialisa o hd44780
  279. }
  280. #endif                                                                    // LCD DIRETO
  281. //----------------------------------------------------------------------------------------
  282. // Sem comentarios originais  https://arduino.stackexchange.com/questions/28603/the-most-effective-way-to-format-numbers-on-arduino
  283. char *ultos_recursive(unsigned long val, char *s, unsigned radix, int pos)
  284. {
  285.   int c;
  286.   if (val >= radix)
  287.     s = ultos_recursive(val / radix, s, radix, pos + 1);
  288.   c = val % radix;
  289.   c += (c < 10 ? '0' : 'a' - 10);
  290.   *s++ = c;
  291.   if (pos % 3 == 0) *s++ = '.';
  292.   return s;
  293. }
  294. //----------------------------------------------------------------------------------------
  295. // Sem comentarios originais  https://arduino.stackexchange.com/questions/28603/the-most-effective-way-to-format-numbers-on-arduino
  296. char *ltos(long val, char *s, int radix)
  297. {
  298.   if (radix < 2 || radix > 36) {
  299.     s[0] = 0;
  300.   } else {
  301.     char *p = s;
  302.     if (radix == 10 && val < 0) {
  303.       val = -val;
  304.       *p++ = '-';
  305.     }
  306.     p = ultos_recursive(val, p, radix, 0) - 1;
  307.     *p = 0;
  308.   }
  309.   return s;
  310. }
  311. //----------------------------------------------------------------------------
  312. void ledcInit ()
  313. {
  314.   resolucao = log((80000000 / oscilator) + 1) / log(2);                   // Calculo da resolucao para ledc
  315.   if (resolucao > 20) resolucao = 20;                                     // Maxima resolucao é 20
  316.   //  Serial.println(resolucao);                                          // Print
  317.   mDuty = (pow(2, resolucao)) / 2;                                        // Calculo do duty para ledc
  318.   //  Serial.println(mDuty);                                              // Print
  319.  
  320.   ledc_timer_config_t ledc_timer = {};                                    // Instancia a configuracao do timer do ledc
  321.  
  322.   ledc_timer.duty_resolution =  ledc_timer_bit_t(resolucao);              // Configura resolucao
  323.   //ledc_timer.duty_resolution = (ledc_timer_bit_t) + resolucao;          // Configura resolucao
  324.   ledc_timer.freq_hz    = oscilator;                                      // Frequencia de oscilacao
  325.   ledc_timer.speed_mode = LEDC_HIGH_SPEED_MODE;                           // Mode de operacao em high speed
  326.   ledc_timer.timer_num = LEDC_TIMER_0;                                    // Usar timer0 do ledc
  327.   ledc_timer_config(&ledc_timer);                                         // Configurar o timer do ledc
  328.  
  329.   ledc_channel_config_t ledc_channel = {};                                // Instancia a configuracao canal do ledc
  330.  
  331.   ledc_channel.channel    = LEDC_HS_CH0_CHANNEL;                          // Configura canal0
  332.   ledc_channel.duty       = mDuty;                                        // Valor calculado do duty em %
  333.   ledc_channel.gpio_num   = LEDC_HS_CH0_GPIO;                             // Saida no GPIO defino no inicio
  334.   ledc_channel.intr_type  = LEDC_INTR_DISABLE;                            // Desabilita interrupt de ledc
  335.   ledc_channel.speed_mode = LEDC_HIGH_SPEED_MODE;                         // Mode de operacao do canal em high speed
  336.   ledc_channel.timer_sel  = LEDC_TIMER_0;                                 // Usar timer0 do ledc
  337.  
  338.   ledc_channel_config(&ledc_channel);                                     // Configurar o canal do ledc
  339. }
  340. //----------------------------------------------------------------------------------
  341. void tempo_controle(void *p)                                              // Fim de tempo de leitura de pulsos
  342. {
  343.   gpio_set_level(OUTPUT_CONTROL_GPIO, 0);                                 // Controle do PCount - stop count
  344.   pcnt_get_counter_value(PCNT_COUNT_UNIT, &pulses);                       // Obtem o valor contado
  345.   flag = true;                                                            // Informa que ocorreu interrupt de controle
  346. }
  347. //----------------------------------------------------------------------------------
  348. static void IRAM_ATTR pcnt_intr_handler(void *arg)                        // Overflow de contagem de pulsos
  349. {
  350.   portENTER_CRITICAL_ISR(&timerMux);                                      // Desabilita interrupção ?
  351.   multPulses++;                                                           // Incrementa contador de overflow
  352.   PCNT.int_clr.val = BIT(PCNT_COUNT_UNIT);                                // Limpa indicador de interrupt
  353.   portEXIT_CRITICAL_ISR(&timerMux);                                       // Libera novo interrupt
  354. }
  355. //----------------------------------------------------------------------------------
  356. void pcnt_init(void)                                                      // Rotina de inicializacao do pulse count
  357. {
  358.   pcnt_config_t pcnt_config = { };                                        // Instancia pulse config
  359.  
  360.   pcnt_config.pulse_gpio_num = PCNT_INPUT_SIG_IO;                         // Port de entrada dos pulsos
  361.   pcnt_config.ctrl_gpio_num = PCNT_INPUT_CTRL_IO;                         // Controle da contagem
  362.   pcnt_config.unit = PCNT_COUNT_UNIT;                                     // Unidade de contagem
  363.   pcnt_config.channel = PCNT_COUNT_CHANNEL;                               // Canal de contagem
  364.   pcnt_config.counter_h_lim = PCNT_H_LIM_VAL;                             // Limite maximo de contagem
  365.   pcnt_config.pos_mode = PCNT_COUNT_INC;                                  // Conta na subida do pulso
  366.   pcnt_config.neg_mode = PCNT_COUNT_INC;                                  // Conta na descida do pulso
  367.   pcnt_config.lctrl_mode = PCNT_MODE_DISABLE;                             // Nao usado
  368.   pcnt_config.hctrl_mode = PCNT_MODE_KEEP;                                // Se HIGH conta incrementando
  369.   pcnt_unit_config(&pcnt_config);                                         // Inicializa PCNT
  370.  
  371.   pcnt_counter_pause(PCNT_COUNT_UNIT);                                    // Inicializa o contador PCNT
  372.   pcnt_counter_clear(PCNT_COUNT_UNIT);                                    // Zera o contador PCNT
  373.  
  374.   pcnt_event_enable(PCNT_COUNT_UNIT, PCNT_EVT_H_LIM);                     // Limite superior de contagem
  375.   pcnt_isr_register(pcnt_intr_handler, NULL, 0, NULL);                    // Rotina de Interrupt de pcnt
  376.   pcnt_intr_enable(PCNT_COUNT_UNIT);                                      // Habilita interrup de pcnt
  377.  
  378.   pcnt_counter_resume(PCNT_COUNT_UNIT);                                   // inicia a contagem
  379. }
  380. //----------------------------------------------------------------------------------
  381. void myInit()
  382. {
  383. #ifdef LCD_ON                                                             // LCD direto
  384.   lcd_init();                                                             // LCD direto
  385. #endif                                                                    // LCD direto
  386.  
  387. #ifdef LCD_I2C_ON                                                         // LCD  I2C
  388.   configI2C();                                                            // LCD  I2C
  389.   ESP_ERROR_CHECK(i2cdev_init());                                         // LCD  I2C
  390.   lcd_test();                                                             // LCD  I2C
  391. #endif                                                                    // LCD  I2C
  392.  
  393.   ledcInit();                                                             // Inicializa o ledc
  394.   pcnt_init();                                                            // Inicializa o pulse count
  395.   gpio_pad_select_gpio(OUTPUT_CONTROL_GPIO);                              // Define o port decontrole
  396.   gpio_set_direction(OUTPUT_CONTROL_GPIO, GPIO_MODE_OUTPUT);              // Define o port de controle como saida
  397.  
  398.   create_args.callback = tempo_controle;                                  // Instancia o tempo de controle
  399.   esp_timer_create(&create_args, &timer_handle);                          // Cria parametros do timer
  400.  
  401.   gpio_set_direction(IN_BOARD_LED, GPIO_MODE_OUTPUT);                     // Port LED como saida
  402.  
  403.   gpio_matrix_in(PCNT_INPUT_SIG_IO, SIG_IN_FUNC226_IDX, false);           // Direciona a entrada de pulsos
  404.   gpio_matrix_out(IN_BOARD_LED, SIG_IN_FUNC226_IDX, false, false);        // Para o LED do ESP32
  405. }
  406. //---------------------------------------------------------------------------------
  407. void app_main(void)
  408. {
  409. #ifndef ARDUINO                                                           // IDF
  410.   myInit();                                                               // IDF
  411.   while (1)                                                               // IDF
  412.   {
  413. #endif                                                                    // IDF
  414.     if (flag == true)                                                     // Se a contagem tiver terminado
  415.     {
  416.       flag = false;                                                       // Impede nova impresao
  417.       float frequencia = 0;                                               // Variavel para calculo de frequencia
  418.       frequencia = (pulses + (multPulses * overflow)) / 2  ;              // Calcula qtos pulsos ocorreram
  419.       char buf[32];                                                       // Buffer para guardar a pontuacao
  420.       printf("frequencia: %s", (ltos(frequencia, buf, 10)));              // Imprime pontuado
  421.       printf(" Hz \n");                                                   // Sufixo
  422. #if defined LCD_ON || defined LCD_I2C_ON                                                        // LCD
  423.       hd44780_gotoxy(&lcd, 2, 0);                                         // Posiciona cusros na posicao 2 da linha 0
  424.       hd44780_puts(&lcd, "frequencia:");                                  // Print
  425.       hd44780_gotoxy(&lcd, 2, 1);                                         // Posiciona cusros na posicao 2 da linha 1
  426.       hd44780_puts(&lcd, (ltos(frequencia, buf, 10)));                    // Print
  427.       hd44780_puts(&lcd, " Hz              ");                            // Print
  428. #endif
  429.       multPulses = 0;                                                     // Zera contador de overflow
  430.       // Aqui pode rodar qq funcao                                        // Espaco para qualquer função
  431.       vTaskDelay(1);
  432.       // Aqui pode rodar qq funcao                                        // Espaco para qualquer função
  433.       pcnt_counter_clear(PCNT_COUNT_UNIT);                                // Zera o contador PCNT
  434.       esp_timer_start_once(timer_handle, janela);                         // Inicia contador de tempo de 1 segundo
  435.       gpio_set_level(OUTPUT_CONTROL_GPIO, 1);                             // Porta de controle habilita contagem dos pulsos
  436.     }
  437. #ifndef ARDUINO                                                           // IDF
  438.   }                                                                       // IDF
  439. #endif                                                                    // IDF
  440. }
  441. //---------------------------------------------------------------------------------
  442. #ifdef ARDUINO                                                            // Arduino
  443. void setup()                                                              // Arduino
  444. {
  445.   Serial.begin(115200);                                                   // Inicializa a serial
  446.   myInit();                                                               // Chaama inicializacao
  447. }                                                                         // Arduino
  448. //---------------------------------------------------------------------------------
  449. void loop()                                                               // Arduino
  450. {
  451.   app_main();                                                             // Roda rotina principal
  452.   String inputString = "";                                                // Temporaria transformar o valor da frequencia
  453.   oscilator = 0;                                                          // Limpa valor original
  454.   while (Serial.available())                                              // Enquanto tiver dados na serial
  455.   { //
  456.     char inChar = (char)Serial.read();                                    // Le um byte:
  457.     inputString += inChar;                                                // Adicione na string:
  458.     if (inChar == '\n')                                                   // Se new line:
  459.     {
  460.       oscilator = inputString.toInt();                                    // Transforma a string em inteiro
  461.       inputString = "";                                                   // Limpa a string
  462.     }
  463.   }
  464.   if (oscilator != 0)                                                     // Se foi digitado algum valor
  465.   {
  466.     ledcInit();                                                           // Reconfigura ledc
  467.   }
  468. }
  469. #endif                                                                    // Arduino
RAW Paste Data