EleksTubeHAX icon indicating copy to clipboard operation
EleksTubeHAX copied to clipboard

Added support for IPSTUBE clocks - Model H401 and H402

Open Martinius79 opened this issue 1 year ago • 19 comments

Added support for IPSTUBE clocks

Just the minimum changes, to support the model with this branch.

The IPSTUBE clock has 8MB flash, so no default board from PIO is fitting. I created a JSON file with the modified values (esp32dev8MB.json) under the subfolder "boards" so it can be used in the PIO project.

I created a new "partition table file" (partition_noOta_1Mapp_7Mspiffs.csv) for the 8MB flash version. 1,2MB app partition, 6,8MB SPIFFS partition

I added a new environment in the platform.ini file (env:esp32dev8MB), to use the new board configuration file and the new partition table file.

Because each environment has its own target directory (PROJECTDIR.pio\build\ENVNAME), the helper scripts to copy and modify the libs files needs another target folder. So I created script_adjust_gesture_sensor_lib_8MB.py and script_configure_tft_lib_8MB.py and added it to the new env. I modified them, to get the board definition from the PlatformIO build settings and use the right target folders.

I added/copied a section to define the IPSTUBE clocks configs in the GLOBAL_DEFINES.H file. See section "#ifdef HARDWARE_IPSTUBE_CLOCK" in the file. Specials: New defintion for a one button menu (#define ONE_BUTTON_ONLY_MENU), because only one hardware button is available for IPSTUBE. Removed the shift register pin config definitions (CSSR_DATA_PIN,CSSR_CLOCK_PIN, CSSR_LATCH_PIN). Added "#define TOUCH_CS -1" to get rid of a warning (also possible with #define DISABLE_ALL_LIBRARY_WARNINGS). Set TFT_CS to -1 Added ACTIVATEDISPLAYS and DEACTIVATEDISPLAYS defines, because power on/off is switched for IPSTUBEs.

I modified the _USER_DEFINES - empty.h file Added "#define HARDWARE_IPSTUBE_CLOCK as "Type of clock"

I modified the ChipSelect class. Moved inline defined methods from ChipSelect.H file to ChipSelect.CPP file. Modified the existing "digit" select methods, that they work with IPSTUBE and other clocks. Normaly by keeping the existing logic and just switching or leaving out code where needed by checking, which hardware is defined. Added the array for the CS pins of the IPSTUBE. Added some IPSTUBE specific methods to select the right LCDs. enableDigitCSPins, disableDigitCSPins, enableAllCSPins and disableAllCSPins. So the existing logic for selecting and activating/disabling the LCDs from the TFTs class can be used without modification.

I modified the TFTs class. Moved some inline defined methods from TFTs.H file to TFTs.CPP file (enableAllDisplays, disableAllDisplays, toggleAllDisplays). Modified existing methods that they work with IPSTUBE and other clocks (using DEACTIVATEDISPLAYS and ACTIVATEDISPLAYS). Normaly by keeping the existing logic and just switching or leaving out code where needed by checking, which hardware is defined.

I renamed the Button.CPP file to Buttons.CPP and modified the header file as well to use the new file. I modified the Button class. I added some public helper methods, to be able to set button states from outside of the instance of the class (setDownLongEdgeState, setUpEdgeState, setUpLongEdgeState)

I modified the Buttons class. Two constructors are needed now, depending on the definition of ONE_BUTTON_ONLY_MENU or not. Classic way, Buttons instance with four buttons is created, new, Buttons instance with only one button is created. Moved some inline defined methods for Buttons class from Buttons.H file to Buttons.CPP file (loop, begin, stateChanged). Also for the one button menu implementation.

I modified the Menu class. Two loop methods are now implemented. One for the one button menu (ONE_BUTTON_ONLY_MENU defined) ot the classic one, with four buttons. The "edge" logic for the buttons is changed now, from "down_edge" to "up_edge". So the software (here the menu) only reacts, if a button is "released", not while it is pressed. This makes "long pressed button" possible without having a "wrong" button state left. So in the one button mode, a long press of the button, is interpreted as a "move to the right" (right button). I added a method to print out the names of the menu states (getStateStr).

I modified the Clock class file. IPSTUBE is using the DS1302 as RTC chip, so needs to be defined as well, to use another driver as for HARDWARE_SI_HAI_CLOCK. Modified to "#if defined(HARDWARE_SI_HAI_CLOCK) || defined(HARDWARE_IPSTUBE_CLOCK)"

Modified the main.cpp file. Init TFTs first, before gesture in the setup function.

Working and Not-Working list for IPSTUBE:

Working: All "normal" clock functions are working. Possible to flash all needed partitions to the clock (button needs to be pressed while connecting USB-C cable and then released to go into download mode every time you want to flash) Passing the setup() function with initalizing messages on the LCDs. Connecting to Wifi network. Getting time from NTP server. Loading the images for the clock faces from the SPIFFS partition. Showing the actual time on the LCDs with the loaded clock face images. Running the main loop function. Menu is working (see below for limitations with the one button menu). Able to go through all sub-menu points and select the functionalities (backlight pattern selection, backlight color if pattern is constant, backlight intensity, 24/12h clock, blank zero, time zone offset hours, time zone offset 15 min, clock face selection, WPS menu if activated). Loading and storing config values from the config partition. Connecting to the MQTT broker server for sending and receiving MQTT messages. "Dimming" the images of the clock face. "Normal" LED backlights on the bottom of each LCD are working. Turning on and off is possible. Dimming is possible. All patters working. Night and Daytime mode is working. LED stripe on the bottom of the clock, as a continuation of the normal 6 backlight LEDs.

Can't tell if working: Geolocation broker based time zone selection -> no account, so not tested. WPS connect -> never used, never tested.

Limited working: Button: The PCB has only one button! There is a special menu mode activated for the IPSTUBE hardware, that short pressing brings up the menu and long pressing changes the value of the actual selected menu then. The value always changes "to the right", because the long button press is emulating a "right button" press in the menu only in the moment. This limits the setup of the timezone values and makes the selection of the other menu values a bit "unhandy", because you have to pass all values, to be at first option again, but it works for now.

TFT LCD disable/enable: Depending on the board version of the IPSTUBEs, the transistor Q1 is present on the board or not. If the transistor is present, the displays can be turned on and off like on other clocks. If the transistor is not present, the TFT LCDs can NOT turned on or off by software without modifing the hardware!

EDIT: After initialzing the TFT_eSPI class, the displays are showing a wild black and white noise pattern. So I added a fillScreen(TFT_BLACK) directly after init, to avoid longer showing this as needed.

I noticed, that the partition table changed a bit in the main branch and I added the changes to the 8MB version here as well.

Martinius79 avatar Sep 11 '24 22:09 Martinius79

Added the branch https://github.com/Martinius79/EleksTubeHAX/tree/ModifiedReadMeFilesAndContentForIt into this branch and PR now.

Martinius79 avatar Sep 15 '24 20:09 Martinius79

I build the firmware and everything works fine, including mqtt home assistant discovery.

Can simply be flashed via the USB-C port by pressing the button while connecting USB.

For backup I had to reduce the baud rate to 460800, otherwise reading the flash would always fail, restoring the backup also works.

kub3let avatar Oct 07 '24 21:10 kub3let

I build the firmware and everything works fine, including mqtt home assistant discovery.

For backup I had to reduce the baud rate to 460800, otherwise reading the flash would always fail, restoring the backup also works.

Happy to hear, that everything is working for you! Feel free to add any comments or suggestions :)

And yes, there are no prebuild firmware files included yet for this models...but the process of self building it, is not that complicated, thanks to aly-flys transition to PlatformIO and Visual Studio Code...

I am thinking about adding automated firmware file building into the build process, but it makes the platform.ini not very readable. Most easy way, would be, to release it on GitHub after build action took place... If I find the time, I will give it a try...

Martinius79 avatar Oct 08 '24 10:10 Martinius79

Sadly I have to report back that for some reason it breaks randomly, noticed 3-12 hours after start 3x times now.

All displays are dark, no back light even. Ambient light still stays on. MQTT stops responding.

Only starts working again after a power cycle, maybe something special needed here with the display drivers, or is there a memory leak ?

I will try another power supply for now. My guess it's crashing due to OOM, but the IPSTube shows no serial output over usb to verify that.

That all displays get dark is kinda weird, I would expect them to freeze and just not update anymore.

Edit: I added memory reporting to my branch https://github.com/kub3let/EleksTubeHAX/tree/AddedIPSTUBEs and it does not look like it's increasing so far.

Edit2: has been running for 6 hours now and doesn't look like a memory leak, will continue to monitor it.

Edit3: Guess it was the power supply, working so far

image

kub3let avatar Oct 09 '24 14:10 kub3let

It seems that, at least for H402, it is possible to somehow cleanly dim TFT backlight brightness without resorting to blending hacks.

Somehow the original firmware can do that, therefore, it is possible to accomplish.

I have tested brightness with the original firmware at levels 100, 10, 5, 2 and 1. A torch on background is for reference light so that phone does not overexpose the displays. On the last photo it can be seen that dimming is clean backlight dim, not an image blending.

100 20241010_022550

10 20241010_022622

5 20241010_022638

2 20241010_022716

1 20241010_022735

1 (without focus on torch) 20241010_022748

20241010_022756

1 (without torch - we can see black is really dark. 20241010_022806

Skydev0h avatar Oct 09 '24 23:10 Skydev0h

It seems that, at least for H402, it is possible to somehow cleanly dim TFT backlight brightness without resorting to blending hacks. Somehow the original firmware can do that, therefore, it is possible to accomplish.

You mean H402 hardware. On the original EleksTube clocks and all copies the BL pin of the display (backlight supply) is hardwired to the supply rail, therefore it is not possible to dim the BL without substantially modifying each LCD display and motherboard. Believe me, I would happily implement that, if it would be available. Original EleksTube has quite a few hardware bugs like this. H402 designer has put way more thought into the design.

aly-fly avatar Oct 10 '24 06:10 aly-fly

It seems that, at least for H402, it is possible to somehow cleanly dim TFT backlight brightness without resorting to blending hacks.

Your pictures show the H401 revision.

The H402 actually has a couple transistors, which could be used to pwm control the backlight, on the H401 there is an empty transistor slot. Would need to trace the PCB to figure it out.

I can also upload a dump of the original firmware if someone want's to reverse engineer it.

H401 PCB

H402 PCB

Overall what I noticed not sure if it's related to this branch / IPSTube, If you turn the main light off and back on, It takes 4-5 seconds for the displays to come on and show the correct image, first it's starts with a white blank, then iterates random numbers until it has the correct one.

This effect is very unpleasing, changing background brightness to 1% and back to 100% looks a lot better.

kub3let avatar Oct 10 '24 08:10 kub3let

It seems that, at least for H402, it is possible to somehow cleanly dim TFT backlight brightness without resorting to blending hacks.

Your pictures show the H401 revision.

Interesting, because from placement of USB port and button, it looks more like H402 PCB.

Have not disassembled yet, although (removing black acrylic slab in one piece is difficult).

Skydev0h avatar Oct 10 '24 10:10 Skydev0h

The H402 actually has a couple transistors, which could be used to pwm control the backlight, on the H401 there is an empty transistor slot. Maybe it's controlled directly by the ESP as well, would need to trace the PCB to figure it out.

I can also upload a dump of the original firmware if someone want's to reverse engineer it.

Usually it is easier to trace stuff with an oscillograph rather than try to reverse ESP32 firmware.

But I am quite unsure on how to safely detach the bottom acrylic lid, it appears to be quite stiff and ... glued?

Upd: I have finally disassembled it, and it is really a H401/H403 unit (with soldered Q1 transistor).

Skydev0h avatar Oct 10 '24 12:10 Skydev0h

@kub3let I have analyzed two contacts of the Q1 transistor and got the following results for different brightnesses:

Bottom contact and then top right contact: 20241010_162632 20241010_162831

100% brightness 20241010_162640 20241010_162849

50% 20241010_162657 20241010_162907

10% 20241010_162713 image

1% image image

To find out the pin and check it I have set brightness to 33% 20241010_163413 20241010_163606 20241010_163611

So, it seems, that the GPIO4 is used to PWM the backlight (by grounding it for the % of the brightness).

Skydev0h avatar Oct 10 '24 13:10 Skydev0h

@aly-fly thus, it seems, that they do not PWM the BL, they PWM the ground of the LCDs (if I undestood correctly the purpose and connection of the Q1 transistor).

Skydev0h avatar Oct 10 '24 13:10 Skydev0h

20241010_172432

It seems that PWM-dimming GPIO4 works perfectly. Maybe such approach can be reused with other models. (Although mind the inverting of LOW / HIGH signals for different models)

Skydev0h avatar Oct 10 '24 14:10 Skydev0h

@aly-fly thus, it seems, that they do not PWM the BL, they PWM the ground of the LCDs (if I understood correctly the purpose and connection of the Q1 transistor).

This is not logical. Who in the right mind would lift the GND of the complete display. This would disrupt the SPI data transfer. Sometimes, on the more "raw" displays, there is not a BL pin (high impedance control input), but you have direct access to LED+ and LED- connections of the backlight. I am pretty sure this is the case here: +Vsupply --> LED+ --> Backlight --> LED- --> Transistor --> GND This is a very common scheme to alter brightness of a LED. You can verify this by googling for the pinout on the LCD. Other clock models have LED+ tied together with Vdd of the LCD and LED- together with GND. So it is not possible to inject PWM signal without a hardware modification - splitting GND and LED- signals and adding a new transistor.

aly-fly avatar Oct 10 '24 14:10 aly-fly

+Vsupply --> LED+ --> Backlight --> LED- --> Transistor --> GND

That may be the case, because after turning off the displays (by setting GPIO4 to HIGH) and turning them on again there is a slight moment when old numbers are displayed before reinitialization.

Thus, it seems that you are right indeed.

Also, maybe, in such case, it is not necessary to reinitialize the displays and do the "random digits" stuff because it may be possible to keep working with the displays and update them even when they are "disabled".

Skydev0h avatar Oct 10 '24 14:10 Skydev0h

When I design PCB's I also toggle GND, since it's easiest to implement with a NPN transistor. (But I'm a total newbie, floating grounds might not be good but never had problems with it)

I'm pretty sure it's only toggling the backlight GND, not the full display.

I will implement backlight control using PWM for IPSTube in my branch and then use that for power off/on as well, so no need to reinitialize everything on power on.

edit: @Skydev0h I see you already did that https://github.com/Martinius79/EleksTubeHAX/pull/1

kub3let avatar Oct 10 '24 17:10 kub3let

no need to reinitialize everything on power on.

~~I did not do this part because I am unsure about state transitions of TFTs when reinit is called, but PWM control is working (including for power off).~~

Edit: added as a feature that can be disabled

Skydev0h avatar Oct 10 '24 17:10 Skydev0h

Sadly I have to report back that for some reason it breaks randomly, noticed 3-12 hours after start 3x times now.

Edit: I added memory reporting to my branch https://github.com/kub3let/EleksTubeHAX/tree/AddedIPSTUBEs and it does not look like it's increasing so far.

Edit2: has been running for 6 hours now and doesn't look like a memory leak, will continue to monitor it.

Edit3: Guess it was the power supply, working so far

I have three IPSTUBEs here and all of them was running for more then 48h in a row for me, so I don't think, it is the software in the first place...But never say never :)

Tell us, if the new power supply is working for you for a longer time.

Martinius79 avatar Oct 10 '24 21:10 Martinius79

Sadly I have to report back that for some reason it breaks randomly, noticed 3-12 hours after start 3x times now. Edit: I added memory reporting to my branch https://github.com/kub3let/EleksTubeHAX/tree/AddedIPSTUBEs and it does not look like it's increasing so far. Edit2: has been running for 6 hours now and doesn't look like a memory leak, will continue to monitor it. Edit3: Guess it was the power supply, working so far

I have three IPSTUBEs here and all of them was running for more then 48h in a row for me, so I don't think, it is the software in the first place...But never say never :)

Tell us, if the new power supply is working for you for a longer time.

Yeah must have been the power supply, has been running for >24 hours now.

I need to get a source of good quality 5v power supplies, all those 3-5$ supplies from aliexpress are crap, although I tested them with a load tester and they are in spec and even PD3 works just fine.

The power supply that gave me trouble was this one https://de.aliexpress.com/item/1005005181533968.html, but I also added 3 meter of cable extension which might be related...

kub3let avatar Oct 11 '24 10:10 kub3let

Cheap PSUs might be okay, but they are really bad at delivering current spikes, also emit lots of noise. So if you add a good filtration and a few extra capacitors to the clock, it should work. I use one from Ikea, that is similar level of "performance", but it works. 3 meters of a thin cable might be the real culprit here.

aly-fly avatar Oct 12 '24 21:10 aly-fly

Hey everyone, i got the IPSTUBE 401 clock today and flashed the current version and it works perfectly.

If some one can help me with selecting the resistors and their connections, i would be willing to solder one and test out the dimming.

TheMasterofBlubb avatar Nov 14 '24 00:11 TheMasterofBlubb

Hey everyone, i got the IPSTUBE 401 clock today and flashed the current version and it works perfectly.

If some one can help me with selecting the resistors and their connections, i would be willing to solder one and test out the dimming.

should work out of the box unless you got the version without the transistor soldered.

just test the dimming and report if it works or not.

kub3let avatar Nov 14 '24 10:11 kub3let

Hey everyone, i got the IPSTUBE 401 clock today and flashed the current version and it works perfectly. If some one can help me with selecting the resistors and their connections, i would be willing to solder one and test out the dimming.

should work out of the box unless you got the version without the transistor soldered.

Tested it and mine does NOT work out of the box

TheMasterofBlubb avatar Nov 14 '24 11:11 TheMasterofBlubb

Hey everyone, i got the IPSTUBE 401 clock today and flashed the current version and it works perfectly. If some one can help me with selecting the resistors and their connections, i would be willing to solder one and test out the dimming.

Hello TheMasterOfBlubb! First, I am happy, that everthing is working for you.

For the hardware modifications, I am a bit sceptical that it can be done easily, because on my boards without the Q1, the connections are not like there are on the one with them...

See https://github.com/Martinius79/EleksTubeHAX/pull/1

As a mentioned there, the solder headers for the resistors seems to be missing.

I also tried to trace the schematics. See the GIMP xcf file under https://github.com/Martinius79/EleksTubeHAX/tree/OneDisplayTestH401/TryoutH401

I also have a lot of other pictures ;)

I ordered myself some parts from AliExpress...Transistor should be a 3401: https://www.aliexpress.com/item/32990534792.html

Resistors should be 10k and 1k: https://www.aliexpress.com/item/1005005600798857.html

But I had no time to try it out yet...

Martinius79 avatar Nov 14 '24 21:11 Martinius79

Do you by chance know which resistor goes on which side?

TheMasterofBlubb avatar Nov 15 '24 00:11 TheMasterofBlubb

Hello again,

I updated the schematics in this branch. Extraced screenshot from there and marked the important parts:

image

R5 and R6 are not the orginal name on the boards (H401 and H402 have different numbers - R14 and R21 on the H402 and R32 and R33 on the H401).

My analysis so far, with a little help from the AI to correct the text.


MOSFET Configuration (A19TF/3401): Drain (D): Connected to the load (LCD VDD lines). Source (S): Directly connected to +3.3V. Gate (G): Connected to GPIO4 through R5 (1kΩ) and to +3.3V through R6.

Resistors: R5 (1kΩ): Gate Drive: This resistor limits the current flowing into the gate when GPIO4 is high. Excessive gate current can damage the MOSFET. R6 (Pull-Up Resistor): Gate Pull-Up: When GPIO4 is low, R6 ensures that the gate voltage is pulled high, keeping the MOSFET in the off state. Current Limiting: It also limits the current flowing into the gate, preventing excessive current and potential damage.

Operation: Turning On: When GPIO4 is high, it directly pulls the gate high, exceeding the source voltage and turning the MOSFET on. Current flows from the +3.3V supply, through the MOSFET's channel, and into the load. Turning Off: When GPIO4 is low, R21 pulls the gate voltage down, ensuring the MOSFET remains off.


For a H401 without Q1 I checked the board visually and the header drain is already connected to the VDD lines. I am not sure, if the source header is connected to 3.3V, need to measure it, but no time yet. Gate header is connected to PIO4 and needs to be cut and the R5 needs to be soldered between. R6 between 3.3V and gate header also.

Actually I can be totaly wrong...

Tell me, what you think...

Ah, working one from H401: image

And a very bad sketch: image

Martinius79 avatar Nov 16 '24 22:11 Martinius79

@Martinius79 Sorry to bother, but dumb question - is there a 'trick' to getting serial to work on the IPSTUBE units? They're coming up as a serial port on windows and linux, but esptool is just doing the 'Connecting.......................\nA fatal error occurrect: Failed to connect to Espressif device' thing - I've tried manually setting baud rates, changing cables, using different machines with different versions of windows, and live-booting linux, it just doesn't seem to want to talk to the unit.. It's coming up as a CH340, but then not talking.. Hoping you might have an idea?

rendragnet avatar Nov 25 '24 20:11 rendragnet

is there a 'trick' to getting serial to work on the IPSTUBE

Hold the button next to the USB connector while connecting the cable.

eku avatar Nov 26 '24 09:11 eku

'Connecting.......................\nA fatal error occurrect: Failed to connect to Espressif device'

Pin GPIO 0 must be tied low during reset to enter the bootloader. There are also other (a bit less important) bootstrapping pins.

  1. Connect the port and have the terminal listen the incoming data.
  2. Reset the ESP32 into normal mode.
  3. Check if existing firmware sends anything on any baudrate (115200 is typical on startup).
  4. Tie GPIO 0 low.
  5. Reset the ESP32.
  6. Check if received message is any different. When you successfully enter the Bootloader you will be greeted with something like: rst:0x1 (POWERON_RESET),boot:0x5 (DOWNLOAD_BOOT(UART0/UART1/SDIO_FEI_REO_V2)) waiting for download

aly-fly avatar Nov 26 '24 09:11 aly-fly

is there a 'trick' to getting serial to work on the IPSTUBE

Hold the button next to the USB connector while connecting the cable.

Ohhh, that is it, thankyou 😀 I'd searched a bunch of Elekstube type repos, and none of their instructions for backing up the flash had mentioned that, so thankyou!! Now I can get to doing this secret santa present :D (I'm going to have it count down days/hours/minutes to 5:00pm on the last weekday of the calendar month - I got one of the Billing department ladies for Secret Santa, and she should find it annoyingly humourous!)

** Edit: And I just realised I was viewing the main repo when reading the instructions for backing up the flash, not the one being merged in.. Which specifically mentions holding the button 🤦

rendragnet avatar Nov 26 '24 09:11 rendragnet

I'm going to have it count down days/hours/minutes to 5:00pm on the last weekday of the calendar month

This is such a cool idea. How about we add a Christmas oriented clock face. Clock then counts down from 99 hours to NYE midnight using this (hidden?) font. It switches between regular clock (1 minute with classic font) and countdown (1 minute with xmas font). This mode is only active between 27.Dec and 1.Jan (0:00). That could be a fun un-documented easter egg :)

aly-fly avatar Nov 26 '24 11:11 aly-fly