pulse_cnt works using GPIO35 but not GPIO25 for input

ksanger
Posts: 5
Joined: Sun Apr 02, 2023 7:29 pm

pulse_cnt works using GPIO35 but not GPIO25 for input

Postby ksanger » Sun Apr 02, 2023 7:56 pm

I've programmed a pulse counter to use gpio35 for counting up and gpio25 for counting down. We are using two optical detector pcbs to drive the input. Counting up on gpio35 works. But counting down does not. GPIO25 out is always high. Its as if the esp-idf is driving the output and I don't know how to turn it off. GPIO35 is an input only without any pullup or pull down resistors and its working as expected. GPIO25 however makes my optical detectors indicate that they are on all the time and the optical detector output can not drive it low. If I short GPIO to ground and connect/disconnect multiple times the counter counts down as it should.

Looking through pcnt.h and pcnt.c it looks like the gpio pins are pulled up and driven with a loopback feature. Since GPIO35 is not an output it works but GPIO25 does not. Is this a bug? Or is there a method or means to change this? I've tried changing the flags in pcnt.h so that the output is not pulled up but then we generate a bunch of errors. I am not driving the levels for chan a nor b. Just using the edges for a and b. With a on GPIO35 to count up and b on GPIO25 to count down always.

I've tried other optical switches on GPIO25 without success. Haven't tried using a transistor to drive the input lower. But the optical switch is a pulled up npn transistor output already and I really don't want to burn out the esp32 wroom ic if its driving the output high.

ESP_Sprite
Posts: 9746
Joined: Thu Nov 26, 2015 4:08 am

Re: pulse_cnt works using GPIO35 but not GPIO25 for input

Postby ESP_Sprite » Mon Apr 03, 2023 12:30 am

What hardware are you using? Can you show the relevant bits of your code?

ksanger
Posts: 5
Joined: Sun Apr 02, 2023 7:29 pm

Re: pulse_cnt works using GPIO35 but not GPIO25 for input

Postby ksanger » Mon Apr 03, 2023 12:58 pm

<r>First I made a mistake in my post. GPIO25 pin out is low. I have to tie it to 3.3V to get the counter to see a high input. If I attach a 1k pullup resistor between GPIO25 and 3.3V the pin is still low. This implies to me that GPIO25 is driven low by the part. I've since created a second up/down counter using GPIO 32 and 26. Both of these pins are low and only activate the counter if I switch them with a jumper to 3.3V. Again they act like they are driven low.<br/>
<br/>
The IC used is ESP-WROOM-32 and the back of the pcb its on has ESP32 DEVKITV1 label.<br/>
The inputs to the part are IR Obstacle Avoidance Sensors which have an output using an LM393 Comparator pulled up with 10K in parallel with an LED in series with a 1K resistor. We are powering these sensors off of the 3.3V pin on the ESP32 DEVKITV1 pcb. Previously we have read these inputs using the ESP32 programmed to sense them. Also we had run the rotary encoder example using GPIO 26 and 33 as inputs and it did count up and down. We used this example to create our UpDownCounter.cpp class file. We use this file to make two up/down counters in Counters.cpp. Our cpp_pthread.cpp file is modified from the original example file to add the Counters class and read the counters in one of threads.<br/>
<br/>
// UpDownCounter.cpp
<CODEBOX codebox="cpp" file="UpDownCounter.cpp"><s>
  1. </s>extern "C" <br/>
  2. {<br/>
  3.     #include "driver/gpio.h"<br/>
  4.     #include "driver/pulse_cnt.h"<br/>
  5.     #include "esp_log.h"<br/>
  6. }<br/>
  7. static const char *TAG = "UpDownCounter";<br/>
  8. <br/>
  9. static const int PCNT_HIGH_LIMIT = 100;<br/>
  10. static const int PCNT_LOW_LIMIT  = -100;<br/>
  11. static const int MAX_GLITCH_NS   = 500;<br/>
  12. <br/>
  13. /**<br/>
  14.  * UpDownCounter uses one channel to count up and one channel to count down.<br/>
  15.  * Counts using the rising edge.<br/>
  16. */<br/>
  17. class UpDownCounter<br/>
  18. {<br/>
  19. private:<br/>
  20.     /* data */<br/>
  21.     pcnt_unit_config_t unit_config;<br/>
  22.     pcnt_unit_handle_t pcnt_unit;<br/>
  23.     pcnt_chan_config_t chan_a_config;<br/>
  24.     pcnt_channel_handle_t pcnt_chan_a;<br/>
  25.     pcnt_chan_config_t chan_b_config;<br/>
  26.     pcnt_channel_handle_t pcnt_chan_b;<br/>
  27.     pcnt_glitch_filter_config_t filter_config;<br/>
  28. <br/>
  29. public:<br/>
  30.     UpDownCounter(int gpio_pin_cnt_up, int gpio_pin_cnt_down);<br/>
  31.     ~UpDownCounter();<br/>
  32.     void clearCount();<br/>
  33.     void startCounter();<br/>
  34.     void stopCounter();<br/>
  35.     int getCount();<br/>
  36. };<br/>
  37. <br/>
  38. UpDownCounter::UpDownCounter(int gpio_pin_cnt_up, int gpio_pin_cnt_down)<br/>
  39. {<br/>
  40.     // initialize the counter<br/>
  41.     ESP_LOGI(TAG, "install pcnt unit");<br/>
  42.     unit_config.high_limit = PCNT_HIGH_LIMIT;<br/>
  43.     unit_config.low_limit  = PCNT_LOW_LIMIT;<br/>
  44.     pcnt_unit = NULL;<br/>
  45.     ESP_ERROR_CHECK(pcnt_new_unit(&unit_config, &pcnt_unit));<br/>
  46. <br/>
  47.     ESP_LOGI(TAG, "set glitch filter");<br/>
  48.     filter_config = {<br/>
  49.         .max_glitch_ns = MAX_GLITCH_NS,<br/>
  50.     };<br/>
  51.     ESP_ERROR_CHECK(pcnt_unit_set_glitch_filter(pcnt_unit, &filter_config));<br/>
  52. <br/>
  53.     ESP_LOGI(TAG, "install pcnt channels");<br/>
  54.     chan_a_config.edge_gpio_num = gpio_pin_cnt_up;  // Edge Input Pin<br/>
  55.     chan_a_config.level_gpio_num = -1;              // Virtual Level Input Pin<br/>
  56.     <br/>
  57.     pcnt_chan_a = NULL;<br/>
  58.     ESP_ERROR_CHECK(pcnt_new_channel(pcnt_unit, &chan_a_config, &pcnt_chan_a));<br/>
  59.     chan_b_config.edge_gpio_num = gpio_pin_cnt_down;  // Edge Input Pin<br/>
  60.     chan_b_config.level_gpio_num = -1;                // Virtual Level Input Pin<br/>
  61.     pcnt_chan_b = NULL;<br/>
  62.     ESP_ERROR_CHECK(pcnt_new_channel(pcnt_unit, &chan_b_config, &pcnt_chan_b));<br/>
  63. <br/>
  64.     ESP_LOGI(TAG, "set edge and level actions for pcnt channels");<br/>
  65.     ESP_ERROR_CHECK(pcnt_channel_set_edge_action(pcnt_chan_a, PCNT_CHANNEL_EDGE_ACTION_INCREASE, PCNT_CHANNEL_EDGE_ACTION_HOLD));<br/>
  66.     ESP_ERROR_CHECK(pcnt_channel_set_level_action(pcnt_chan_a, PCNT_CHANNEL_LEVEL_ACTION_KEEP, PCNT_CHANNEL_LEVEL_ACTION_KEEP));<br/>
  67. <br/>
  68.     ESP_ERROR_CHECK(pcnt_channel_set_edge_action(pcnt_chan_b, PCNT_CHANNEL_EDGE_ACTION_DECREASE, PCNT_CHANNEL_EDGE_ACTION_HOLD));<br/>
  69.     ESP_ERROR_CHECK(pcnt_channel_set_level_action(pcnt_chan_b, PCNT_CHANNEL_LEVEL_ACTION_KEEP, PCNT_CHANNEL_LEVEL_ACTION_KEEP));    <br/>
  70. <br/>
  71. <br/>
  72.     ESP_LOGI(TAG, "enable pcnt unit");<br/>
  73.     ESP_ERROR_CHECK(pcnt_unit_enable(pcnt_unit));<br/>
  74.     ESP_LOGI(TAG, "clear pcnt unit");<br/>
  75.     ESP_ERROR_CHECK(pcnt_unit_clear_count(pcnt_unit));<br/>
  76.     ESP_LOGI(TAG, "start pcnt unit");<br/>
  77.     ESP_ERROR_CHECK(pcnt_unit_start(pcnt_unit));<br/>
  78. }<br/>
  79. <br/>
  80. UpDownCounter::~UpDownCounter()<br/>
  81. {<br/>
  82.     ESP_LOGI(TAG, "Disable UpDownCounter");<br/>
  83.     ESP_ERROR_CHECK(pcnt_unit_disable(pcnt_unit));<br/>
  84.     ESP_LOGI(TAG, "Delete UpDownCounter Channel a");<br/>
  85.     ESP_ERROR_CHECK(pcnt_del_channel(pcnt_chan_a));<br/>
  86.     ESP_LOGI(TAG, "Delete UpDownCounter Channel b");<br/>
  87.     ESP_ERROR_CHECK(pcnt_del_channel(pcnt_chan_b));<br/>
  88.     ESP_LOGI(TAG, "Delete UpDownCounter pcnt_unit");<br/>
  89.     ESP_ERROR_CHECK(pcnt_del_unit(pcnt_unit));<br/>
  90. }<br/>
  91. <br/>
  92. void UpDownCounter::clearCount() <br/>
  93. {<br/>
  94.     ESP_LOGI(TAG,"cear pcnt unit");<br/>
  95.     ESP_ERROR_CHECK(pcnt_unit_clear_count(pcnt_unit));<br/>
  96. }<br/>
  97. <br/>
  98. int UpDownCounter::getCount() <br/>
  99. {<br/>
  100.     int pulse_count = 0;<br/>
  101.     ESP_LOGI(TAG,"get counter value");<br/>
  102.     ESP_ERROR_CHECK(pcnt_unit_get_count(pcnt_unit, &pulse_count));<br/>
  103.     return pulse_count;<br/>
  104. }<br/>
  105. <br/>
  106. void UpDownCounter::stopCounter()<br/>
  107. {<br/>
  108.     ESP_LOGI( TAG, "stop pcnt unit" );<br/>
  109.     ESP_ERROR_CHECK( pcnt_unit_stop(pcnt_unit) );<br/>
  110. }<br/>
  111. <br/>
  112. void UpDownCounter::startCounter()<br/>
  113. {<br/>
  114.     ESP_LOGI( TAG, "start pcnt unit");<br/>
  115.     ESP_ERROR_CHECK( pcnt_unit_start(pcnt_unit) );<br/>
  116. }<e>
</e></CODEBOX>

// Counters.cpp
<CODEBOX codebox="cpp" file="Counters.cpp"><s>
  1. </s>#include "UpDownCounter.h"<br/>
  2. #include "train_io.h"<br/>
  3. <br/>
  4. class Counters<br/>
  5. {<br/>
  6. private:<br/>
  7.     /* data */<br/>
  8.     UpDownCounter* northCounter; <br/>
  9.     UpDownCounter* southCounter;<br/>
  10. <br/>
  11. public:<br/>
  12.     Counters(/* args */);<br/>
  13.     ~Counters();<br/>
  14.     int getNorthCount();<br/>
  15.     void clearNorthCount();<br/>
  16.     int getSouthCount();<br/>
  17.     void clearSouthCount();<br/>
  18. };<br/>
  19. <br/>
  20. Counters::Counters()<br/>
  21. {<br/>
  22.     northCounter = new UpDownCounter(NE_GPIO, NW_GPIO);<br/>
  23.     southCounter = new UpDownCounter(SE_GPIO, SW_GPIO);<br/>
  24. <br/>
  25. }<br/>
  26. <br/>
  27. Counters::~Counters()<br/>
  28. {<br/>
  29.     //northCounter->~UpDownCounter();<br/>
  30.     delete northCounter;<br/>
  31.     delete southCounter;<br/>
  32. }<br/>
  33. <br/>
  34. int Counters::getNorthCount() <br/>
  35. {<br/>
  36.     return northCounter->getCount();<br/>
  37. }<br/>
  38. <br/>
  39. int Counters::getSouthCount()<br/>
  40. {<br/>
  41.     return southCounter->getCount();<br/>
  42. }<br/>
  43. <br/>
  44. void Counters::clearNorthCount()<br/>
  45. {<br/>
  46.     northCounter->clearCount();<br/>
  47. }<br/>
  48. <br/>
  49. void Counters::clearSouthCount()<br/>
  50. {<br/>
  51.     southCounter->clearCount();<br/>
  52. }<e>
</e></CODEBOX>

// cpp_pthread.cpp Example modified to add a Counters object and display the count values within one of the threads.
<CODEBOX codebox="cpp" file="Untitled.cpp"><s>
  1. </s>/* pthread/std::thread example<br/>
  2. <br/>
  3.    This example code is in the Public Domain (or CC0 licensed, at your option.)<br/>
  4. <br/>
  5.    Unless required by applicable law or agreed to in writing, this<br/>
  6.    software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR<br/>
  7.    CONDITIONS OF ANY KIND, either express or implied.<br/>
  8. */<br/>
  9. <br/>
  10. #include <iostream><br/>
  11. #include <thread><br/>
  12. #include <chrono><br/>
  13. #include <memory><br/>
  14. #include <string><br/>
  15. #include <sstream><br/>
  16. #include <esp_pthread.h><br/>
  17. #include <freertos/FreeRTOS.h><br/>
  18. #include <freertos/task.h><br/>
  19. #include <esp_log.h><br/>
  20. #include "Counters.h"<br/>
  21. <br/>
  22. using namespace std::chrono;<br/>
  23. <br/>
  24. Counters myCounters;<br/>
  25. <br/>
  26. const auto sleep_time = seconds<br/>
  27. {<br/>
  28.     5<br/>
  29. };<br/>
  30. <br/>
  31. void print_thread_info(const char *extra = nullptr)<br/>
  32. {<br/>
  33.     std::stringstream ss;<br/>
  34.     if (extra) {<br/>
  35.         ss << extra;<br/>
  36.     }<br/>
  37.     ss << "Core id: " << xPortGetCoreID()<br/>
  38.        << ", prio: " << uxTaskPriorityGet(nullptr)<br/>
  39.        << ", minimum free stack: " << uxTaskGetStackHighWaterMark(nullptr) << " bytes.";<br/>
  40.     ESP_LOGI(pcTaskGetName(nullptr), "%s", ss.str().c_str());<br/>
  41. }<br/>
  42. <br/>
  43. void print_Counts()<br/>
  44. {<br/>
  45.     printf("North Count Value: %d\n",  myCounters.getNorthCount());<br/>
  46.     printf("South Count Value: %d\n",  myCounters.getSouthCount());<br/>
  47. }<br/>
  48. <br/>
  49. void thread_func_inherited()<br/>
  50. {<br/>
  51.     while (true) {<br/>
  52.         print_thread_info("This is the INHERITING thread with the same parameters as our parent, including name. ");<br/>
  53.         print_Counts();<br/>
  54.         std::this_thread::sleep_for(sleep_time);<br/>
  55.     }<br/>
  56. }<br/>
  57. <br/>
  58. void spawn_another_thread()<br/>
  59. {<br/>
  60.     // Create a new thread, it will inherit our configuration<br/>
  61.     std::thread inherits(thread_func_inherited);<br/>
  62. <br/>
  63.     while (true) {<br/>
  64.         print_thread_info();<br/>
  65.         std::this_thread::sleep_for(sleep_time);<br/>
  66.     }<br/>
  67. }<br/>
  68. <br/>
  69. void thread_func_any_core()<br/>
  70. {<br/>
  71.     while (true) {<br/>
  72.         print_thread_info("This thread (with the default name) may run on any core.");<br/>
  73.         std::this_thread::sleep_for(sleep_time);<br/>
  74.     }<br/>
  75. }<br/>
  76. <br/>
  77. void thread_func()<br/>
  78. {<br/>
  79.     while (true) {<br/>
  80.         print_thread_info();<br/>
  81.         std::this_thread::sleep_for(sleep_time);<br/>
  82.     }<br/>
  83. }<br/>
  84. <br/>
  85. esp_pthread_cfg_t create_config(const char *name, int core_id, int stack, int prio)<br/>
  86. {<br/>
  87.     auto cfg = esp_pthread_get_default_config();<br/>
  88.     cfg.thread_name = name;<br/>
  89.     cfg.pin_to_core = core_id;<br/>
  90.     cfg.stack_size = stack;<br/>
  91.     cfg.prio = prio;<br/>
  92.     return cfg;<br/>
  93. }<br/>
  94. <br/>
  95. extern "C" void app_main(void)<br/>
  96. {<br/>
  97.     // Initialize Counters<br/>
  98.     Counters myCounter;<br/>
  99.     //myCounters = new Counters();<br/>
  100. <br/>
  101.     // Create a thread using default values that can run on any core<br/>
  102.     auto cfg = esp_pthread_get_default_config();<br/>
  103.     esp_pthread_set_cfg(&cfg);<br/>
  104.     std::thread any_core(thread_func_any_core);<br/>
  105. <br/>
  106.     // Create a thread on core 0 that spawns another thread, they will both have the same name etc.<br/>
  107.     cfg = create_config("Thread 1", 0, 3 * 1024, 5);<br/>
  108.     cfg.inherit_cfg = true;<br/>
  109.     esp_pthread_set_cfg(&cfg);<br/>
  110.     std::thread thread_1(spawn_another_thread);<br/>
  111. <br/>
  112.     // Create a thread on core 1.<br/>
  113.     cfg = create_config("Thread 2", 1, 3 * 1024, 5);<br/>
  114.     esp_pthread_set_cfg(&cfg);<br/>
  115.     std::thread thread_2(thread_func);<br/>
  116. <br/>
  117.     // Let the main task do something too<br/>
  118.     while (true) {<br/>
  119.         std::stringstream ss;<br/>
  120.         ss << "core id: " << xPortGetCoreID()<br/>
  121.            << ", prio: " << uxTaskPriorityGet(nullptr)<br/>
  122.            << ", minimum free stack: " << uxTaskGetStackHighWaterMark(nullptr) << " bytes.";<br/>
  123.         ESP_LOGI(pcTaskGetName(nullptr), "%s", ss.str().c_str());<br/>
  124.         std::this_thread::sleep_for(sleep_time);<br/>
  125.     }<br/>
  126. }<e>
</e></CODEBOX>

<br/>
// Counters.h<br/>
  1. #include "UpDownCounter.h"
  2.  
  3. class Counters
  4. {
  5. private:
  6.     /* data */
  7.     UpDownCounter* northCounter;
  8.     UpDownCounter* southCounter;
  9.  
  10. public:
  11.     Counters();
  12.     ~Counters();
  13.     int getNorthCount();
  14.     void clearNorthCount();
  15.     int getSouthCount();
  16.     void clearSouthCount();
  17. };
<br/>
<br/>
// train_io.h<br/>

Code: Select all

// train_io.h

// Counters Input GPIO and pins
#define E_GPIO   34     // pin 4
#define NE_GPIO  35     // pin 5
#define SE_GPIO  32     // pin 6
#define W_GPIO   33     // pin 7
#define NW_GPIO  25     // pin 8
#define SW_GPIO  26     // pin 9
#define EDIR_GPIO 27    // pin 10
#define WDIR_GPIO 13    // pin 13

// STOP Button Run = Active Low
#define STOP_GPIO  15    // pin 18

// Relay Set/Reset Outputs
#define N_EN_GPIO  21       // pin 26
#define N_DIS_GPIO 19       // pin 25
#define S_EN_GPIO  16       // pin 21
#define S_DIS_GPIO 4        // pin 20
#define W_EN_N_GPIO 23      // pin 30
#define W_EN_S_GPIO 22      // pin 29
#define E_EN_N_GPIO 18      // pin 24
#define E_EN_S_GPIO 5       // pin 23

/* East Times for Slow Passenger Train 
#1 Locomotive NE to E      1.62 sec  ET 1.62
#2 Last Car at NE          4.42 sec  ET 6.04
#3 Last Car at E           2.32 sec  ET 8.36
#4 Locomotive return to E  5.15 sec  ET 13.52   13.52 - 1.62 = 11.9 sec
#5 Locomotive return to NE 1.95 sec  ET 15.47   15.47 seconds to return.
#6 Last Car return to E    4.36 sec  ET 19.83   19.83 - 8.36 = 11.47 seconds of no counting at East
#7 Last Car return to NE   1.34 sec  ET 21.18
*/
<br/>

// UpDownCounter.h</r>

Code: Select all

extern "C"
{
    #include "driver/gpio.h"
    #include "driver/pulse_cnt.h"
    #include "esp_log.h"
}


class UpDownCounter
{
private:
    /* data */
    pcnt_unit_config_t unit_config;
    pcnt_unit_handle_t pcnt_unit;
    pcnt_chan_config_t chan_a_config;
    pcnt_channel_handle_t pcnt_chan_a;
    pcnt_chan_config_t chan_b_config;
    pcnt_channel_handle_t pcnt_chan_b;
    pcnt_glitch_filter_config_t filter_config;

public:
    UpDownCounter(int gpio_pin_cnt_up, int gpio_pin_cnt_down);
    ~UpDownCounter();
    void clearCount();
    void startCounter();
    void stopCounter();
    int getCount();
};

ksanger
Posts: 5
Joined: Sun Apr 02, 2023 7:29 pm

Re: pulse_cnt works using GPIO35 but not GPIO25 for input

Postby ksanger » Mon Apr 03, 2023 1:53 pm

When my program starts the terminal shows that the input pins GPIO 25, 32, and 26 are all set for InputEn and OutputEn confirming that the esp32 is driving the input signals I want to count.

Here is the terminal output at the beginning of my code execution: Note lines 559, 569, 619, and 629. These should be inputs only.

Code: Select all

I (539) main_task: Started on CPU0
I (549) main_task: Calling app_main()
I (549) UpDownCounter: install pcnt unit
I (549) UpDownCounter: set glitch filter
I (559) UpDownCounter: install pcnt channels
I (559) [b]gpio: GPIO[35]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 [/b]
I (569) [b]gpio: GPIO[25]| InputEn: 1| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0[/b] 
I (579) UpDownCounter: set edge and level actions for pcnt channels
I (589) UpDownCounter: enable pcnt unit
I (589) UpDownCounter: clear pcnt unit
I (599) UpDownCounter: start pcnt unit
I (599) UpDownCounter: install pcnt unit
I (609) UpDownCounter: set glitch filter
I (609) UpDownCounter: install pcnt channels
I (619) [b]gpio: GPIO[32]| InputEn: 1| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 [/b]
I (629) [b]gpio: GPIO[26]| InputEn: 1| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 [/b]
I (629) UpDownCounter: set edge and level actions for pcnt channels
I (639) UpDownCounter: enable pcnt unit
I (649) UpDownCounter: clear pcnt unit
I (649) UpDownCounter: start pcnt unit
I (659) pthread: This thread (with the default name) may run on any core.Core id: 0, prio: 5, minimum free stack: 1928 bytes.
I (669) Thread 1: Core id: 0, prio: 5, minimum free stack: 1916 bytes.
I (669) Thread 1: This is the INHERITING thread with the same parameters as our parent, including name. Core id: 0, prio: 5, minimum free stack: 1928 bytes.
I (689) UpDownCounter: get counter value
North Count Value: 0
I (689) UpDownCounter: get counter value
South Count Value: 0

ksanger
Posts: 5
Joined: Sun Apr 02, 2023 7:29 pm

Re: pulse_cnt works using GPIO35 but not GPIO25 for input

Postby ksanger » Mon Apr 03, 2023 3:59 pm

Previously we had run the rotary encoder with GPIO 26 and 32 as inputs. I reran them and found that sometimes they come up as Inputs only and sometimes they boot up with input and output enabled. For this application they work when input only, and sometimes they work with input/output. Though sometimes they come up with the output low and fail to work when set as input and output.

I tried to use GPIO 35 (Input Only) and GPIO 25 similar to the rotary encoder example by modifying my code to use channel a 35 edge and 25 level with channel b 25 edge and 35 level. This always gives me an error when I set channel b that 35 may only be used as an input.

Next we went back to using the virtual channel -1 for level and then used the gpio config below to set the inputs to input only. This seems to work. Though its counting many pulses when I activate the optical sensors by hand. We'll try to increase my glitch filters next.

Code: Select all

    // Set the inputs to input only.   Inserted into UpDownCounters.cpp after line 70.  This is run after setting up channels a and b.
    gpio_config_t io_conf = {};
    io_conf.intr_type = GPIO_INTR_DISABLE;
    io_conf.mode = GPIO_MODE_INPUT;
    io_conf.pin_bit_mask = 1ULL<<gpio_pin_cnt_up | 1ULL<<gpio_pin_cnt_down;
    io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
    io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
    ESP_LOGI(TAG, "Set inputs to input only");
    ESP_ERROR_CHECK( gpio_config(&io_conf));
The code above is based on the example gpio_example_main.c however the lines to set the pullup/down resistors using zero had to be replaced with GPIO_PULLDOWN_DISABLE and GPIO_PULLUP_DISABLE in order to compile.

Also note that its unclear how we change the virtual level. I can not find any examples to set the virtual level to keep vs invert though its implied that virtual channels may be set/reset.

Lastly it would be nice if the software and the hardware reference to the pulse counters used the same terminology. When SW is controlling HW and the SW terminology does not match the hardware description then old EE's easily get confused.

ksanger
Posts: 5
Joined: Sun Apr 02, 2023 7:29 pm

Re: pulse_cnt works using GPIO35 but not GPIO25 for input

Postby ksanger » Mon Apr 03, 2023 6:43 pm

So I found that recompiling and downloaded resulted in inconsistent results. GPIO 35 and GPIO 34 both gave me errors if pulse_cnt tried to set them to outputs. As expected since these inputs are input only.

Today; adding chan_a_config.flags.io_loop_back = 0; to turn the loop back off prior to running pcnt_new_channel seams to work. I tried setting the default value to 0 in pulse_cnt.h but that gives us error messages.

ESP_Sprite
Posts: 9746
Joined: Thu Nov 26, 2015 4:08 am

Re: pulse_cnt works using GPIO35 but not GPIO25 for input

Postby ESP_Sprite » Tue Apr 04, 2023 2:07 am

POD (non-object) class members in C++ aren't initialized to anything by default, so your unit_config, chan_a_config etc will all contain random data, and if you don't change that, any function using it can have random behaviour. If you want it to have some defined value, you need to make sure the data is not random, e.g. by using an initializer list to initialize them or by setting them to an explicit value.

Who is online

Users browsing this forum: Baidu [Spider], BipinDangwal, Google [Bot], ignisuti, MicroController and 118 guests