Procházet zdrojové kódy

looks like its working to read pulses

Thomas Chef před 3 roky
rodič
revize
71042e0409
4 změnil soubory, kde provedl 49 přidání a 51 odebrání
  1. 3 4
      main/config.h
  2. 1 1
      main/led_test_inout.c
  3. 11 10
      main/main.c
  4. 34 36
      main/pcnt_functions.c

+ 3 - 4
main/config.h

@@ -1,8 +1,7 @@
 
-#define PCNT_H_LIM_VAL      10
-#define PCNT_L_LIM_VAL     -10
-#define PCNT_THRESH1_VAL    5
-#define PCNT_THRESH0_VAL   -5
+#define PULSES_PER_KWH      10000
+
+
 #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

+ 1 - 1
main/led_test_inout.c

@@ -18,7 +18,7 @@ void ledc_init(void)
     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.freq_hz          = 14;   // Should be 14 for some kind of max kWh
     ledc_timer.clk_cfg          = LEDC_AUTO_CLK;
     ledc_timer_config(&ledc_timer);
 

+ 11 - 10
main/main.c

@@ -13,9 +13,8 @@
 
 // Externs
 extern void ledc_init(void);
-extern void init_pcnt_unit(int unit);
-
-const int pcnt_unit = PCNT_UNIT_0;
+extern void init_pcnt_unit();
+extern float getkWh();
 
 // Chip info:
 // This is esp32 chip with 2 CPU cores, WiFi/BT/BLE, silicon revision 1, 4MB external flash
@@ -27,21 +26,23 @@ const int pcnt_unit = PCNT_UNIT_0;
  * 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);
+    init_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);
+    float kWh;
+
+    while( true ) {
+
+        kWh = getkWh();
+
+        printf("%f\n",kWh);
         vTaskDelay(1000 / portTICK_PERIOD_MS);
     }
-    printf("Restarting now.\n");
-    fflush(stdout);
     esp_restart();
 }

+ 34 - 36
main/pcnt_functions.c

@@ -7,21 +7,31 @@
 #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.
- */
+#include "soc/dport_reg.h"
+
+// Example-code: https://github.com/espressif/esp-idf/blob/master/examples/peripherals/pcnt/pulse_count_event/main/pcnt_event_example_main.c
+
+// Counts full kWh
+static uint32_t kWh_Counter = 0;
+
+const int pcntUnit = PCNT_UNIT_0;
+
+float getkWh() {
+
+    pcnt_intr_disable(pcntUnit);
+    volatile int32_t count = DPORT_REG_READ(0x3FF57060);
+    volatile uint32_t kWh = kWh_Counter;
+    pcnt_intr_enable(pcntUnit);
+
+    return (float)kWh + ((float)count/PULSES_PER_KWH);
+}
+
 static void IRAM_ATTR pcnt_example_intr_handler(void *arg)
 {
-    int pcnt_unit = (int)arg;
+    kWh_Counter++;
 }
 
-/* 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)
+void init_pcnt_unit()
 {
     /* Prepare configuration for the PCNT unit */
     pcnt_config_t pcnt_config = {
@@ -29,7 +39,7 @@ void init_pcnt_unit(int unit)
         .pulse_gpio_num = PCNT_INPUT_SIG_IO,
         .ctrl_gpio_num = PCNT_INPUT_CTRL_IO,
         .channel = PCNT_CHANNEL_0,
-        .unit = unit,
+        .unit = pcntUnit,
         // 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
@@ -37,43 +47,31 @@ void init_pcnt_unit(int unit)
         .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_h_lim = PULSES_PER_KWH,
         .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);
-
+    // How to read a periphial-register:
     //uint32_t c = p_pcnt_obj->hal.dev.hw.conf_unit[unit];
-
+    //printf("Reg: %08x\n",(uint32_t)DPORT_REG_READ(0x3FF57000));
 
     /* Configure and enable the input filter */
+    pcnt_set_filter_value(pcntUnit, 100);
+    pcnt_filter_enable(pcntUnit);
 
-    //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);
+    /* Enable int on high count limit */
+    pcnt_event_enable(pcntUnit, PCNT_EVT_H_LIM);
 
     /* Initialize PCNT's counter */
-    pcnt_counter_pause(unit);
-    pcnt_counter_clear(unit);
+    pcnt_counter_pause(pcntUnit);
+    pcnt_counter_clear(pcntUnit);
 
     /* Install interrupt service and add isr callback handler */
-    //pcnt_isr_service_install(0);
-    //pcnt_isr_handler_add(unit, pcnt_example_intr_handler, (void *)unit);
+    pcnt_isr_service_install(0);
+    pcnt_isr_handler_add(pcntUnit, pcnt_example_intr_handler, (void *)pcntUnit);
 
     /* Everything is set up, now go to counting */
-    pcnt_counter_resume(unit);
+    pcnt_counter_resume(pcntUnit);
 }