Sfoglia il codice sorgente

Sending 14Hz and counting input works

Thomas Chef 3 anni fa
parent
commit
3d5c46cca0
6 ha cambiato i file con 175 aggiunte e 44 eliminazioni
  1. 1 1
      main/CMakeLists.txt
  2. 8 0
      main/config.h
  3. 0 43
      main/hello_world_main.c
  4. 40 0
      main/led_test_inout.c
  5. 47 0
      main/main.c
  6. 79 0
      main/pcnt_functions.c

+ 1 - 1
main/CMakeLists.txt

@@ -1,2 +1,2 @@
-idf_component_register(SRCS "hello_world_main.c"
+idf_component_register(SRCS "pcnt_functions.c" "main.c" "led_test_inout.c" "pcnt_functions.c"
                     INCLUDE_DIRS "")

+ 8 - 0
main/config.h

@@ -0,0 +1,8 @@
+
+#define PCNT_H_LIM_VAL      10
+#define PCNT_L_LIM_VAL     -10
+#define PCNT_THRESH1_VAL    5
+#define PCNT_THRESH0_VAL   -5
+#define PCNT_INPUT_SIG_IO   4  // Pulse Input GPIO
+#define PCNT_INPUT_CTRL_IO  5  // Control GPIO HIGH=count up, LOW=count down
+#define LEDC_OUTPUT_IO      18 // Output GPIO of a sample 1 Hz pulse generator

+ 0 - 43
main/hello_world_main.c

@@ -1,43 +0,0 @@
-/* Hello World Example
-
-   This example code is in the Public Domain (or CC0 licensed, at your option.)
-
-   Unless required by applicable law or agreed to in writing, this
-   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-   CONDITIONS OF ANY KIND, either express or implied.
-*/
-#include <stdio.h>
-#include "sdkconfig.h"
-#include "freertos/FreeRTOS.h"
-#include "freertos/task.h"
-#include "esp_system.h"
-#include "esp_spi_flash.h"
-
-void app_main(void)
-{
-    printf("Hello world!\n");
-
-    /* Print chip information */
-    esp_chip_info_t chip_info;
-    esp_chip_info(&chip_info);
-    printf("This is %s chip with %d CPU cores, WiFi%s%s, ",
-            CONFIG_IDF_TARGET,
-            chip_info.cores,
-            (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "",
-            (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "");
-
-    printf("silicon revision %d, ", chip_info.revision);
-
-    printf("%dMB %s flash\n", spi_flash_get_chip_size() / (1024 * 1024),
-            (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external");
-
-    printf("Free heap: %d\n", esp_get_free_heap_size());
-
-    for (int i = 10; i >= 0; i--) {
-        printf("Restarting in %d seconds...\n", i);
-        vTaskDelay(1000 / portTICK_PERIOD_MS);
-    }
-    printf("Restarting now.\n");
-    fflush(stdout);
-    esp_restart();
-}

+ 40 - 0
main/led_test_inout.c

@@ -0,0 +1,40 @@
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/queue.h"
+#include "driver/ledc.h"
+#include "driver/pcnt.h"
+#include "esp_attr.h"
+#include "esp_log.h"
+
+#include "config.h"
+
+/* Configure LED PWM Controller
+ * to output sample pulses at 1 Hz with duty of about 10%
+ */
+void ledc_init(void)
+{
+    // Prepare and then apply the LEDC PWM timer configuration
+    ledc_timer_config_t ledc_timer;
+    ledc_timer.speed_mode       = LEDC_LOW_SPEED_MODE;
+    ledc_timer.timer_num        = LEDC_TIMER_0;
+    ledc_timer.duty_resolution  = LEDC_TIMER_13_BIT;
+    ledc_timer.freq_hz          = 14;
+    ledc_timer.clk_cfg          = LEDC_AUTO_CLK;
+    ledc_timer_config(&ledc_timer);
+
+    // Prepare and then apply the LEDC PWM channel configuration
+    ledc_channel_config_t ledc_channel;
+    ledc_channel.speed_mode = LEDC_LOW_SPEED_MODE;
+    ledc_channel.channel    = LEDC_CHANNEL_0;
+    ledc_channel.timer_sel  = LEDC_TIMER_0;
+    ledc_channel.intr_type  = LEDC_INTR_DISABLE;
+    ledc_channel.gpio_num   = LEDC_OUTPUT_IO;
+    ledc_channel.duty       = 0; // set duty at about 10%
+    ledc_channel.hpoint     = 0;
+    ledc_channel_config(&ledc_channel);
+
+    // Set duty to 50%
+    ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, 409)); // Set duty to 5%. ((2 ** 13) - 1) * 50% = 409
+    // Update duty to apply the new value
+    ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0));
+}

+ 47 - 0
main/main.c

@@ -0,0 +1,47 @@
+#include <stdio.h>
+#include "sdkconfig.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "esp_system.h"
+#include "esp_spi_flash.h"
+#include "freertos/queue.h"
+#include "driver/ledc.h"
+#include "driver/pcnt.h"
+#include "esp_attr.h"
+#include "esp_log.h"
+#include "config.h"
+
+// Externs
+extern void ledc_init(void);
+extern void init_pcnt_unit(int unit);
+
+const int pcnt_unit = PCNT_UNIT_0;
+
+// Chip info:
+// This is esp32 chip with 2 CPU cores, WiFi/BT/BLE, silicon revision 1, 4MB external flash
+
+/** Electric meter:
+ * 10000 impulses per kWh
+ * Some normal max number could be 120 kWh/24h = 5 kWh/hour = 50000 pulses/hour = 833 pulses/min = 14 pulses/sec
+ * 
+ * Counter is 16 bit signed = Max 32768 pulses = Will NOT work for one hour !!!!!
+ * So we need some other way of counting higher numbers that will last for one h
+ * Probably we need to use interrupts !
+
+void app_main(void)
+{
+    printf("HomeEnergyMeter ESP32\n");
+
+    init_pcnt_unit(pcnt_unit);
+    ledc_init();
+
+    for (int i = 600; i >= 0; i--) {
+        int16_t count = 0;
+        pcnt_get_counter_value(pcnt_unit, &count);
+        printf("%d\n",count);
+        vTaskDelay(1000 / portTICK_PERIOD_MS);
+    }
+    printf("Restarting now.\n");
+    fflush(stdout);
+    esp_restart();
+}

+ 79 - 0
main/pcnt_functions.c

@@ -0,0 +1,79 @@
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/queue.h"
+#include "driver/ledc.h"
+#include "driver/pcnt.h"
+#include "esp_attr.h"
+#include "esp_log.h"
+#include "config.h"
+
+/* Decode what PCNT's unit originated an interrupt
+ * and pass this information together with the event type
+ * the main program using a queue.
+ */
+static void IRAM_ATTR pcnt_example_intr_handler(void *arg)
+{
+    int pcnt_unit = (int)arg;
+}
+
+/* Initialize PCNT functions:
+ *  - configure and initialize PCNT
+ *  - set up the input filter
+ *  - set up the counter events to watch
+ */
+void init_pcnt_unit(int unit)
+{
+    /* Prepare configuration for the PCNT unit */
+    pcnt_config_t pcnt_config = {
+        // Set PCNT input signal and control GPIOs
+        .pulse_gpio_num = PCNT_INPUT_SIG_IO,
+        .ctrl_gpio_num = PCNT_INPUT_CTRL_IO,
+        .channel = PCNT_CHANNEL_0,
+        .unit = unit,
+        // What to do on the positive / negative edge of pulse input?
+        .pos_mode = PCNT_COUNT_INC,   // Count up on the positive edge
+        .neg_mode = PCNT_COUNT_DIS,   // Keep the counter value on the negative edge
+        // What to do when control input is low or high?
+        .lctrl_mode = PCNT_MODE_REVERSE, // Reverse counting direction if low
+        .hctrl_mode = PCNT_MODE_KEEP,    // Keep the primary counter mode if high
+        // Set the maximum and minimum limit values to watch
+        .counter_h_lim = 0,
+        .counter_l_lim = 0,
+    };
+    /* Initialize PCNT unit */
+    pcnt_unit_config(&pcnt_config);
+
+    pcnt_event_disable(unit, PCNT_EVT_H_LIM);
+    pcnt_event_disable(unit, PCNT_EVT_L_LIM);
+    pcnt_event_disable(unit, PCNT_EVT_ZERO);
+    pcnt_filter_disable(unit);
+
+    //uint32_t c = p_pcnt_obj->hal.dev.hw.conf_unit[unit];
+
+
+    /* Configure and enable the input filter */
+
+    //pcnt_set_filter_value(unit, 100);
+    //pcnt_filter_enable(unit);
+
+    /* Set threshold 0 and 1 values and enable events to watch */
+    //pcnt_set_event_value(unit, PCNT_EVT_THRES_1, PCNT_THRESH1_VAL);
+    //pcnt_event_enable(unit, PCNT_EVT_THRES_1);
+    //pcnt_set_event_value(unit, PCNT_EVT_THRES_0, PCNT_THRESH0_VAL);
+    //pcnt_event_enable(unit, PCNT_EVT_THRES_0);
+    /* Enable events on zero, maximum and minimum limit values */
+    //pcnt_event_enable(unit, PCNT_EVT_ZERO);
+    //pcnt_event_enable(unit, PCNT_EVT_H_LIM);
+    //pcnt_event_enable(unit, PCNT_EVT_L_LIM);
+
+    /* Initialize PCNT's counter */
+    pcnt_counter_pause(unit);
+    pcnt_counter_clear(unit);
+
+    /* Install interrupt service and add isr callback handler */
+    //pcnt_isr_service_install(0);
+    //pcnt_isr_handler_add(unit, pcnt_example_intr_handler, (void *)unit);
+
+    /* Everything is set up, now go to counting */
+    pcnt_counter_resume(unit);
+}