SolderedElectronics / Inkplate-Arduino-library

Inkplate family Arduino library. The easiest way to add e-paper to your project.
https://inkplate.readthedocs.io/en/latest/arduino.html
GNU Lesser General Public License v3.0
249 stars 78 forks source link

Inkplate_Wake_Up_On_Touchpads Doesn't Work on 6COLOR #179

Open GiantSox opened 1 year ago

GiantSox commented 1 year ago

Hi there!

The Inkplate_Wake_Up_On_Touchpads sample doesn't seem to work on my 6COLOR. I've been tapping all 3 touchpads and nothing happens.

What does work:

Any help would be appreciated!

ifadiga commented 1 year ago

Hi, Can you try a solution from issue https://github.com/SolderedElectronics/Inkplate-Arduino-library/issues/169#issuecomment-1383619196 I think that it will help you.

GiantSox commented 1 year ago

@ifadiga Thanks for the link -- saw that issue but somehow totally missed the touchpad-related parts.

I specifically want to figure out how to wake the MCU from sleep when a touchpad is pressed, as the sample suggests I can do. My goal is to be able to use the Inkplate as a sign that runs on battery, and change its state when I press a touchpad.

I'm new to this so apologies for the potentially very basic questions.

ifadiga commented 1 year ago

Hi, I'm sorry for not getting back to you sooner. Can you send a picture of your Inkplate to me? I need to know which Inkplate 6COLOR you have to help you.

BornaBiro commented 1 year ago

@GiantSox Can you please send the picture(s) of the Inkplate that you have, just to be sure, so we can give you a few solutions to this problem?

GiantSox commented 1 year ago

PXL_20230310_034033639

Sorry for my delay--this is just a hobby project and life has gotten very busy for me these past few weeks.

If I understand correctly, the touchpads are connected to the IO multiplexer, which is connected over i2c, and I'm a bit clueless as to how to make it wake up the ESP from sleep. I haven't had time to dedicate to this project in a few weeks but I was thinking that writing a ULP program to poll the touchpad state might work. If there's a simpler solution that'd be great, but learning how to program the ULP processor sounds like a fun learning experience for me when I eventually have more time :)

matthewmmorrow commented 1 year ago

@GiantSox Can you share links to the "Inkplate_Wake_Up_On_Touchpads" and "Inkplate_Touchpads" you've tried? I'm trying to get the same thing working but I don't see any examples for the 6COLOR, only other boards. When I try one of the other examples, I can't build the sketch because readTouchpads doesn't seem to be defined for the 6COLOR.

I'm trying to wake from deep sleep when pressing a touchpad. I have the wakeup button working with esp_sleep_enable_ext0_wakeup(GPIO_NUM_36, LOW); GPIO_NUM_34 which is for some of the other boards' touchpads is always low. Does anyone know which pin the I/O extender INT is connected to on the 6COLOR and what is it's active state?

Trying to use getTouchpadState from linked comment didn't give me any change in output to the serial monitor but I'm not sure if I was calling it correctly.

My board looks the same as in the picture. I'm using 6.0.0 of the library and 3.0.1 of the board definition.

BornaBiro commented 1 year ago

@GiantSox There is no need to poll the I/O expander with ULP on the I2C bus, as the expander has a pin change interrupt functionality. That means an INT pulse will fire from the I/O expander whenever a certain pin changes its state. And INT pin from the I/O expander is connected to the GPIO34 of the ESP32. So by just enabling interrupt on one of the I/O expander pins and enabling ESP32 to be woken up on GPIO34, you can wake up ESP32 with touchpads.

@matthewmmorrow For some reason, this example is missing from the library. It must have been accidentally removed when the library was updated (and also the library broke for the same reason and you see this error). We will fix that and push an update on the library as soon as possible. Thanks for pointing that out! BTW: By using the function getTouchpadState() did the output stuck at 0 or 1 for each touchpad?

bernji commented 1 year ago

First of all, congratulations in this nice product and the effort you guys put into this. I have the same (old) 6Color board and issue.

@BornaBiro The issue is open over a month. When can we expect the touchpads to be working? I would love to wake up the board when a touchpad has been pressed and find out which one. Ideally with a working example for each of them or an example for both working together. As I am not a pro I do not really understood your guide of how to wake up the board on I7O expander and on how to enable the wakeup of touchpads press. An example would be ideal.

KarloLeksic commented 1 year ago

Hi @bernji,

Sorry for the late response, we are a bit busy. Here is an unofficial version of this example. You can use it, it should work, but maybe it will change a little.

bernji commented 1 year ago

Hi @KarloLeksic,

thank you. How do I find out which button has been pressed?

KarloLeksic commented 1 year ago

Hi @bernji,

The PCAL expander remembers which pin triggered the interrupt, and if you read its register at the beginning of the code, you should be able to read from which pin. But if you call display.begin(), that register will be deleted. You can initialize i2c communication with Wire.begin(), then call display.getINT(). That function returns uint16_t and each bit represents one pin from which the interrupt occurred. One bit should be set to 1, and the position of that bit represents the pin from which the interrupt occurred.

bernji commented 1 year ago

Hi @KarloLeksic. I cannot confirm that the code for wakeup on touchpads works that you pointed to (Here)

When i run the code I see errors as follows and the board restarts and shows "Wakeup caused by touchpads" although I have never touched any touchpad.

rst:0x5 (DEEPSLEEP_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) configsip: 0, SPIWP:0xee clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO, clock div:1 load:0x3fff0030,len:1344 load:0x40078000,len:13864 load:0x40080400,len:3608 entry 0x400805f0 ets Jul 29 2019 12:21:4`

Are you sure that code works on the "old" 6COLOR boards? Because of this error I could also not test what you suggested to find out which touchpad has been pressed (via display.getINT())

KarloLeksic commented 1 year ago

Hi @bernji,

It works perfectly for me. Can you please send me a photo of the Inkplate from the back side to check something?

These messages aren't errors, it is a messages from ESP when it wakes up, restarts, etc.

There were problems with the touchpads because they remained charged, and since they are calibrated at the beginning, then it turns out that they are constantly pressed.

bernji commented 1 year ago

Mhh strage. Yes, it seems that the board "thinks" that the touchpads are constantly pressed... BUT I would expect that display.getINT() returns some touchpad being pressed but it is always "00". I call it before dispay,begin() and before I call Wire.begin().

Picture attached 2023-04-24 15 59 47

KarloLeksic commented 1 year ago

In order to read the interrupt register (display.getINT()), it must occur. PCAL (gpio expander) catches an interrupt on change, and if the touchpads are "constantly pressed", then there is no change.

Can you please measure the voltage on the jumpers for touchpads? image

If you read logic one constantly, that's the problem. I'll explain how you need to discharge the charge from the touchpads.

bernji commented 1 year ago

there are 3x3 points (I assume 3 for each touch pad) where should I exactly measure?

BornaBiro commented 1 year ago

@bernji Sorry for not getting back to you sooner, we are a little busy right now.

There are three groups of jumpers and each group has three SMD jumper pads. Each group represents one touchpad. You need to measure a voltage with a voltmeter between the SMD pad in the center of one group and the ground. If you are not touching the touchpad, the voltmeter should show close to 0V and Inkplate should not wake up. As soon as you touch the touchpad, the voltmeter should read 3.3V and Inkplate should wake up. If for some reason voltmeter is showing a 3.3V and you did not touch the touchpads it can mean one of two things:

Fixing the first problem is relatively easy. While powering on, there should be nothing on the touchpads otherwise it just constantly report that touch is detected. The second issue that can occur is that touchpad or capacitor can be charged and that can mess up the touchpad IC reading thinking there is touch detected. This can be fixed by discharging the white capacitor to the left of the touchpad IC. You can even discharge it with your fingers, put one finger on ESP32 metal shield and the other finger on the touchpad, and leave it like that for a few seconds. Do this for all touchpads and on power on it should work fine. I have to mention that you should do this discharge procedure while Inkplate is powered off.

matthewmmorrow commented 1 year ago

I got back to this project today. I uploaded the example sketch and I'm having the same issue as @bernji. The screen constantly wakes up and says "caused by touchpads". I measured the voltage from GND to the middle SMD pad on each touchpad and I'm getting 0V until I touch a pad and then I get 3.7V. I tried discharging the touchpads and no difference. What else should I try?

BornaBiro commented 1 year ago

Can you check if these two jumper pads are connected together? image

image

matthewmmorrow commented 1 year ago

There is no solder there (or on the uSD jumpers either). I tried to check the resistance and I think they are connected but it's hard to tell if I got the probes on the tiny pads. Here's the question: should they be connected?

BornaBiro commented 1 year ago

Yes, they need to be connected in order for the I/O expander interrupt to work. On newer Inkplate boards there can be a PCB track between the pads instead of the solder bridge. All jumpers have a small white line below or above SMD pads that shows what pads need to be connected together.

Also, try adding a 10k pull-up from the center SMD pad of the GPIO Exp to 3V3. Some very early Inkplate6COLOR boards have this problem. image image

matthewmmorrow commented 1 year ago

Yay! I added the resistor like in the photo and it's no longer constantly waking up. If I wait, I get the timer wakeup and if I press a touchpad then I get the touchpad wakeup.

Are there any other hardware corrections for this board?

matthewmmorrow commented 1 year ago

Ok, so I think I've tested it and there are a few gotchas:

  1. Using getTouchpadState() from #169 is working to check the touchpad on wakeup if Wire.begin() is done first. Check the pads before display.begin() since they get cleared and it takes forever. However, it looks like the 3 + _t - 1 should be 2 + _t - 1 in the code. I was getting 0 0 1 when nothing or pad 1 was pressed, 1 0 1 for pad 2 and 0 1 1 for pad 3. I get all 3 values with the above correction. Is there a reason reading the touchpads is not in the library for newer boards?
  2. With a quick touch, sometimes the pad state isn't read fast enough so it looks like nothing is pressed. This isn't a big deal since I'll just sleep right away if nothing was found. The user will have to push the button again.
  3. Seems like when the touchpads states are found, the device will wake up again when your finger is removed, even if you remove it before it goes back to sleep. Again, not a big deal since I'll just sleep again.
  4. It seems like you can't have the RTC, touchpads, and wake-up button as wakeup interrupts all at the same time. You can use esp_sleep_enable_ext0_wakeup and esp_sleep_enable_ext1_wakeup to set 2 out of the 3. You can use esp_sleep_enable_timer_wakeup but that uses the internal timer which uses more power?
BornaBiro commented 1 year ago

I'm glad that this simple fix helped. :) No there are no more hardware problems as far as we know.

  1. Yes, there is indeed a bug in the code. You can either do that, or you can read the touchpads with arguments from 0 to 2 by modifying if (_t > 4 || _t < 1) return -1; to if (_t > 3 || _t < 0) return -1;
  2. Problem is the speed of the ESP32; it takes time to boot and read I2C data from the IO expander, but you can read InterruptState with getINT(). Do that before display.begin() and after Wire.begin(). It should work and it should be much faster.
  3. Yes, which is actually a limitation of the I/O expander. While MCP23017 can detect falling and rising edge on pin and generate an interrupt pulse only on selected changes, PCAL6416 can't do that, it can only create interrupt only on pin change, and since the finger is removed, a new change on pin is created and new interrupt pulse is generated.
  4. You can have esp_sleep_enable_ext0_wakeup, esp_sleep_enable_ext1_wakeup and esp_sleep_enable_timer_wakeup at the same time. But, you can't have multiple wake up sources on esp_sleep_enable_ext0_wakeup, but you can on esp_sleep_enable_ext1_wakeup. If you are worried about current consumption, you can use wake up with RTC, plus it's more precise than ESP32 internal timer.
matthewmmorrow commented 1 year ago

Do you have an example of using multiple wake sources on esp_sleep_enable_ext1_wakeup ? I can easily create the pin wakeup mask but the issue is that the pins are high and fall when being triggerred. There is ESP_EXT1_WAKEUP_ANY_HIGH and ESP_EXT1_WAKEUP_ALL_LOW for conditions but neither of those would work since we need to know when just one pin goes low. One of either the RTC, touchpads, or wake button pins.

matthewmmorrow commented 6 months ago

Asking again if there are any examples for esp_sleep_enable_ext1_wakeup that include pins 39 (rtc), 36 (button), and 34 (touchpads). Since the pins are normally high we need to create an interrupt when just one of them is low but that's not an option.