Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Help figuring out possible support for CB38M2D(PB)-2 #34

Open
Scoff123 opened this issue Sep 11, 2022 · 110 comments
Open

Help figuring out possible support for CB38M2D(PB)-2 #34

Scoff123 opened this issue Sep 11, 2022 · 110 comments

Comments

@Scoff123
Copy link

I'm hoping to work out whether or not this can be used with my Flexispot EQ5 model which uses the CB38M2D(PB)-2 control unit with Sanodesk LCD controller.
The control unit doesn't have a spare RJ45 port. The LCD button panel connects to the Control box with one cable which splits into two - an RJ45 and a 2 pin connector which both go into the control box.
The units appear to be sealed/glued with no easy access so I can't open them to view the boards inside, and with it still being under warranty I'm a bit hesitant to try and split the cases!
Pictures to show the units, but I suppose it's a long shot hoping to get this working unless anyone else with the same model has been brave enough to open the units up to investigate?

20220911_104402
20220911_104412
20220911_110953
20220911_111030
20220911_111054

@IamMattM
Copy link

IamMattM commented May 19, 2023

Any news with regard to the above ?

I have recently acquired an EQ5 and it has "CB38M2H(PB)-2" labelling on the box with "CB38M2H(PB)-1" on the actual PCB which can be accessed by removing the x4 screws on the base of the enclosure (facing the tabletop)

The microcontroller is "STM32G030C8T6" (https://www.mouser.co.uk/datasheet/2/389/stm32g030c6-1826662.pdf)
in "LQFP48" package and the accessible port to the side of the enclosure are for edge-contact SWD JTAG reprogramming/debugging of the microcontroller.

Not sure whether a second UART port (beyond the one made available to connect to the keypad controller) is being made available out of the STM32 and could be wire-tapped to bring out the RX/TX lines necesarry to "command" the EQ5.

@IamMattM
Copy link

IamMattM commented May 19, 2023

image

image

image

image

image

@Scoff123
Copy link
Author

Thanks for posting up pictures of your board, and for the information you've provided. I've not managed to make any progress myself, however I will try to open my controller up and check the board model to see if it's any different to yours. Hopefully someone with more knowledge than myself in this area can help to ascertain whether support of this controller will indeed be possible.

@IamMattM
Copy link

IamMattM commented May 19, 2023

I figured out after looking at datasheet for the STM32 part above that if there was going to be a second UART port that would accept any control commands, it would have to be UART#2 since the other UART#1 is already in use and attaches to the RJ45 port.

UART#2 RX/TX pads are currently untracked so it should be possible to send a few commands to it and see if there are any responses....

image

@IamMattM
Copy link

UART#1 goes to RJ45 (while SWD JTAG debug/progrm goes to edge contacts)
image

@rsiuda
Copy link

rsiuda commented May 22, 2023

I’ve received the same control box (and was hoping for 2 ports).

Did you try to use the port with the ESP32 (and not connect the LCD Panel)? Would that work?

@IamMattM
Copy link

I have not got the opportunity to connect an ESP32 to the one-and-only RJ45 port.

Was first trying to figure out the details for the box...

@Scoff123
Copy link
Author

Great, I look forward to seeing the results. I've also unplugged the 2 pin connector and all functions on the lcd controller work as normal, so I'm also interested in understanding what that connector is used for.

@rsiuda
Copy link

rsiuda commented May 22, 2023

I think it's powering the usb (charging) port

@IamMattM
Copy link

IamMattM commented May 22, 2023

I imagine that with only one controller box port available for the EQ5 , we will need to use the "passthrough" mode of an ESP32 in order to request changes from both the ESP32 ESPHome and the actual keypad:

image

where the ESP32 sits in between the controller box and the keypad and "bridges" the messages across...so there is always only a single UART controller driving into the control box...

Looks like "flexispot_e5b_esp32.yaml" would be the starting point for the ESP32 in pass-through mode....
It features x2 UARTs for the ESP32.

And I think the yaml and the physical suggested connection tie up to it should be do-able:
https://github.com/iMicknl/LoctekMotion_IoT/blob/f4d57e02546af97f19ae47d47f873480fe083f6b/packages/esphome/flexispot_e5b_esp32.yaml

image

Just need to figure out now where the controller line RX (TX from ESP32 point of view) /TX (RX from ESP32 point of view)/PIN20(allow commands)/+5V(provide power to ESP32)/GND
are on the RJ45 pinout...and introduce two rj45 socket connectors off the ESP32 to be able to become the "man in the middle" without cutting any cables from the EQ5 box or keyboard.

And maybe introduce a 3D printed case for the ESP32 with two RJ45 socket
https://www.printables.com/en/model/64174-raspi-esp32-ethernet-keystone-enclosure

@IamMattM
Copy link

IamMattM commented May 23, 2023

I did a bit more investigations on the pinout for the EQ5 RJ45 port and scoped the lines using a back to back RJ45 adapter between the keypad and the EQ5 control box.

WARNING: The UART lines are toggling at the full +5V IO swing !
Note: ESP32 max IO levels are quoted at +3.6Vmax (3.3V+0.3V) => there is the possiblity that the ESP32 IOs (inputs) will eventually die after being exposed to incoming +5V levels without introducing either level shifting and/or limiting series resistors.

PIN20 being an always idling +5V line might be the one most at risk of damaging GPIO22 in the table above.

For now I have worked out the EQ5 to ESP32 and will to the second section which is Kpad to ESP32 later on...

image

@Scoff123
Copy link
Author

Great work and thanks for all of your investigations and contributions so far! I'm going to open up the the case of my CB38M2D(PB)-2 to see what is different to the CB38M2A-1 - hopefully it won't be too dissimilar. I've got an ESP32 DEVKIT V1 board spare, so hopefully with level shifting and RJ-45 connectors, plus a case like the printable one you linked, this is going to be achievable...

@IamMattM
Copy link

IamMattM commented May 23, 2023

With regards to the need (or not) to protect the ESP32 from the 5V levels on its IO inputs:

https://www.qworqs.com/2021/05/19/are-the-esp32-and-esp8266-5v-tolerant-yes-they-officially-are/

I am happy to take the very small risk and will wire directly as much more convenient.
Besides, there seems to be plenty of people having gone ahead and wired their ESP32 to the Flexispot lines (which I imagine are all 5V levels) and I have not come across someone saying their ESP32 died in the process.

I will go ahead and make the necessary connections for testing but it seems from the esp32-e5b.yaml file that it should just work...

Note1: the yaml in the repo is slightly outdated for newest source code and the following lines need to be tweaked from/to in order to compile successfully.

id(desk).open(); => id(desk).make_call().set_command_open();
id(desk).close(); => id(desk).make_call().set_command_close();
id(desk).stop(); => id(desk).make_call().set_command_stop();

Note 2: it calls for the two .h files <desk_height_sensor.h> and <desk_keypad.h>
Those two files need to be found locally by your esphome compiler. I downloaded both and placed in my local /config/ folder where the yaml file also resides.
Compilation succesfull and loaded.

image

@IamMattM
Copy link

A small update to say that the 3D print pointed in the post above seems great for the task required: just need to wire things out correctly now between the two keystone RJ45 sockets and ESP32.
One port dedicated to EQ5 connection (need extra ethernet cable) and second port reciving the lead from the keypad....

Fingers crossed.

image

image

@Scoff123
Copy link
Author

Scoff123 commented May 24, 2023

Wow that looks perfect and could easily pass as part of the factory setup! Great work.

I've taken the rubber feet off my control box and unscrewed the cover to check out the board inside. It looks a bit different to your board, and strangely has a reference of ET201-PB, rather than the CB38M2D(PB)-2 which is on the plastic housing...

20230524_170319
20230524_170655

I'll have to see what the reference is on the chip with the green paint, and try to find the data sheet for it.....

Here we go, it's a STM8S007C8T6 Microcontroller

@Scoff123
Copy link
Author

Scoff123 commented May 24, 2023

20230524_182428

and the datasheet for it https://www.mouser.co.uk/datasheet/2/389/stm8s007c8-1851529.pdf

@IamMattM
Copy link

20230524_182428

and the datasheet for it https://www.mouser.co.uk/datasheet/2/389/stm8s007c8-1851529.pdf

Thanks - Very intersting that for the same EQ5 model it seems that the controller board uses various flavours of the STMxx microcontroller.

Saying that, with the "pass-through" ESP32 method/wiring, as long as the UART out of the control bo tals at the same BAud rte of 9600 and accepts the same commands as the other ones, it should very much "just" work.

@IamMattM
Copy link

IamMattM commented May 24, 2023

20230524_182428

and the datasheet for it https://www.mouser.co.uk/datasheet/2/389/stm8s007c8-1851529.pdf

Thanks - Very intersting to see that for the same EQ5 model, the controller board appears to be different and uses various flavours of the STMxx microcontroller.

Saying that, with the ""man-in-the-middle" pass-through" ESP32 method/wiring, as long as the UART(s) out of the control box and keypad talk at the same Baud rate of 9600 and accepts the same commands as the ones listed in the yaml file, it should very much "just" work.

@IamMattM
Copy link

IamMattM commented May 24, 2023

Looks like the commands to the EQ5 controller out of the ESP32 are working and I can control the motors up and down.
https://drive.google.com/file/d/1YWYhH0tllCWDYCulrfnZ3VSnLo3jmL4k/view?usp=sharing

The keypad and the ESP32 both receive the motor height information from EQ5 controller box and will display height on both keypad and homeassistant.

I have not had a great deal of opportunities to test further but at first glance it is for now encouraging..

The control from the keypad into ESP32.UART0_RX do not appear to be bridged through on ESP32.UART2_TX towards the EQ5 control box so for the time being I was not able to instruct the motor to change height from the keypad.

I need to see if the ESP32 could bridge those keypad messages and redirect towards EQ5 or if perhaps that connection/wire is not properly made.

Anyhow, some progress...

image
image

@Scoff123
Copy link
Author

Well done, looks like you are nearly there! Great to see it in action, and hopefully you can iron out the issue with the keypad commands not reaching the EQ5 controller box.

I don't have a scope so probably can't take the testing on my own board much/any further, so I'm just going to go with the same setup that you've implemented and give it a test. I'll grab a couple of keystone jacks online, flash my ESP32 board and add it to HA, and try connecting things up and see what happens. This has also convinced me it's time to finally invest in a 3D printer :)

@IamMattM
Copy link

IamMattM commented May 25, 2023

Yes, I also did not have a 3D printer until a couple of months ago when there was an offer for the Ender 3 v2 NEO -
Since then I migrated the 3D printer to "klipper+klipper screen android" and have been making full use of it for all those IOT/Smart devices enclosures that I need. Well worth it.

I'll try to figure out where things are not working by comparing the various yaml made available...

I can already see that in my HA integration I do not see the "STOP" button like in the following reference picture so definitely some tweaks required.

I have a scope with UART decode that I can place on KEYPAD side of the cable to check the messages are as expected ...etc...

image

@IamMattM
Copy link

IamMattM commented May 25, 2023

An update with regards to verifying the commands sent out by keypad:
https://drive.google.com/drive/folders/17fUi4JQyRUNruGem4oYe32flX-6Btzhs?usp=sharing

When the keypad is not pressed, it is correctly sending out continuously the "Empty" command,

When pressed,on the various buttons (Up / Down / Preset1=stand / Preset2=sit/ Preset3 /_________/ Memory) it is also correctly sending out the correct command sequence.
*Note: THere is one button that is not yet implemented in the yaml file and that is the PReset4 with command :
[0x9b, 0x06, 0x02, 0x00, 0x01, 0xac, 0x60, 0x9d] as captured below:

image

With the doubt as to whether the keypad was actually sending anything when pressed on the line going to ESP32.UART0_RX (esp32 devkit v1), I can now say for certain that this is indeed happening.

What is NOT happening however is any software "forward" activity of those commands to the ESP32.UART2_TX towards the EQ5...

Maybe the UART bridging is not supported....

@pepsinio @iMicknl : would you be able to comment on the matter of esp32 passthrough for the Loctek Motion keypads using ESPHOME esp32_e5b.yaml ?

I am not having much success....Should keypad control going through ESP32 between keypad and EQ5 control box work at all ?

THere is a section in the code that indicate that ESP32 KEypad_uart gets used but I am not familiar enough with the coding to make sense of it fully :
image

@Scoff123
Copy link
Author

So the keypad is definitely sending the commands correctly the the ESP board. Are you able to view debug logging (logger.log) or print the debug messages (after changing the baud_rate from zero in the ESPHome config yaml) to determine if the ESP is actually receiving these sent keypad commands?

@IamMattM
Copy link

IamMattM commented May 26, 2023

@Scoff123 : THanks for the pointer and enabling Baud= 9600 (from 0)
I can see the messages when pressing keypad being decoded correctly (except for Preset4 not yet implemented)

[12:49:39][C][mdns:109]: Hostname: esp32-flexispot-eq5
[12:49:39][C][ota:093]: Over-The-Air Updates:
[12:49:39][C][ota:094]: Address: esp32-flexispot-eq5.local:3232
[12:49:39][C][ota:097]: Using Password.
[12:49:39][C][api:138]: API Server:
[12:49:40][C][api:139]: Address: esp32-flexispot-eq5.local:6053
[12:49:40][C][api:141]: Using noise encryption: YES
[12:49:40][C][wifi_signal.sensor:009]: WiFi Signal 'WiFi Signal'
[12:49:40][C][wifi_signal.sensor:009]: Device Class: 'signal_strength'
[12:49:40][C][wifi_signal.sensor:009]: State Class: 'measurement'
[12:49:40][C][wifi_signal.sensor:009]: Unit of Measurement: 'dBm'
[12:49:40][C][wifi_signal.sensor:009]: Accuracy Decimals: 0
[12:49:50][D][sensor:094]: 'Desk command': Sending state 3.00000 with 0 decimals of accuracy
[12:49:50][D][switch:012]: 'Preset 1' Turning ON.
[12:49:50][D][main:243]: Executing Preset 1 command
[12:49:50][D][main:746]: Executing Empty command
[12:49:50][D][main:322]: Executing screen timer command
[12:49:50][D][switch:012]: 'Virtual Screen' Turning ON.
[12:49:50][D][sensor:094]: 'Desk command': Sending state 8.00000 with 0 decimals of accuracy
[12:49:54][D][sensor:094]: 'Desk command': Sending state 4.00000 with 0 decimals of accuracy
[12:49:54][D][switch:012]: 'Preset 2' Turning ON.
[12:49:54][D][main:308]: Executing Preset 2 command
[12:49:54][D][main:746]: Executing Empty command
[12:49:54][D][script:077]: Script 'screen_timer' restarting (mode: restart)
[12:49:55][D][main:322]: Executing screen timer command
[12:49:55][D][switch:012]: 'Virtual Screen' Turning ON.
[12:49:55][D][sensor:094]: 'Desk command': Sending state 8.00000 with 0 decimals of accuracy
[12:49:56][D][sensor:094]: 'Uptime': Sending state 32.44800 s with 0 decimals of accuracy
[12:50:01][D][sensor:094]: 'Desk command': Sending state 5.00000 with 0 decimals of accuracy
[12:50:01][D][switch:012]: 'Preset 3' Turning ON.
[12:50:01][D][main:373]: Executing Preset 3 command
[12:50:01][D][main:746]: Executing Empty command
[12:50:01][D][script:077]: Script 'screen_timer' restarting (mode: restart)
[12:50:02][D][main:322]: Executing screen timer command
[12:50:02][D][switch:012]: 'Virtual Screen' Turning ON.
[12:50:02][D][sensor:094]: 'Desk command': Sending state 8.00000 with 0 decimals of accuracy
[12:50:03][D][sensor:094]: 'WiFi Signal': Sending state -46.00000 dBm with 0 decimals of accuracy
[12:50:09][D][sensor:094]: 'Desk command': Sending state 6.00000 with 0 decimals of accuracy
[12:50:09][D][switch:012]: 'M' Turning ON.
[12:50:09][D][main:438]: Executing Preset 3 command
[12:50:09][D][main:746]: Executing Empty command
[12:50:10][D][script:077]: Script 'screen_timer' restarting (mode: restart)
[12:50:10][D][main:322]: Executing screen timer command
[12:50:10][D][switch:012]: 'Virtual Screen' Turning ON.
[12:50:10][D][sensor:094]: 'Desk command': Sending state 8.00000 with 0 decimals of accuracy

@IamMattM
Copy link

And it actually worked once for Preset1 and Preset2 (moving feet from keypad) at some point but is now no longer working although the commands are always being decoded correctly by ESP32.

@IamMattM
Copy link

IamMattM commented May 26, 2023

When pressing the "up" toggle on the HA integration page I get the following messages and the feet move up:

[13:00:47][D][switch:012]: 'Virtual Screen' Turning ON.
[13:00:52][D][switch:012]: 'Up' Turning ON.
[13:00:52][D][switch:055]: 'Up': Sending state ON
[13:00:52][D][uart.switch:020]: 'Up': Sending data...
[13:00:52][D][switch:055]: 'Up': Sending state OFF
[13:00:52][D][sensor:094]: 'Desk Height': Sending state 62.10000 cm with 1 decimals of accuracy
[13:00:53][D][script:077]: Script 'screen_timer' restarting (mode: restart)
[13:00:53][D][main:322]: Executing screen timer command
[13:00:53][D][switch:012]: 'Virtual Screen' Turning ON.
[13:00:53][D][sensor:094]: 'Desk Height': Sending state 62.20000 cm with 1 decimals of accuracy
[13:00:53][D][script:077]: Script 'screen_timer' restarting (mode: restart)
[13:00:53][D][main:322]: Executing screen timer command
[13:00:53][D][switch:012]: 'Virtual Screen' Turning ON.
[13:00:53][D][sensor:094]: 'Desk Height': Sending state 62.30000 cm with 1 decimals of accuracy
[13:00:53][D][script:077]: Script 'screen_timer' restarting (mode: restart)
[13:00:53][D][main:322]: Executing screen timer command
[13:00:53][D][switch:012]: 'Virtual Screen' Turning ON.
[13:00:53][D][sensor:094]: 'Desk Height': Sending state 62.40000 cm with 1 decimals of accuracy
[13:00:53][D][script:077]: Script 'screen_timer' restarting (mode: restart)
[13:00:53][D][main:322]: Executing screen timer command
[13:00:54][D][switch:012]: 'Virtual Screen' Turning ON.
[13:00:54][D][sensor:094]: 'Desk Height': Sending state 62.50000 cm with 1 decimals of accuracy
[13:00:54][D][script:077]: Script 'screen_timer' restarting (mode: restart)
[13:00:54][D][main:322]: Executing screen timer command
[13:00:54][D][switch:012]: 'Virtual Screen' Turning ON.
[13:00:54][D][sensor:094]: 'Desk Height': Sending state 62.70000 cm with 1 decimals of accuracy
[13:00:54][D][script:077]: Script 'screen_timer' restarting (mode: restart)
[13:00:54][D][main:322]: Executing screen timer command
[13:00:54][D][switch:012]: 'Virtual Screen' Turning ON.
[13:00:54][D][sensor:094]: 'Desk Height': Sending state 62.80000 cm with 1 decimals of accuracy
[13:00:54][D][script:077]: Script 'screen_timer' restarting (mode: restart)
[13:00:54][D][main:322]: Executing screen timer command
[13:00:54][D][switch:012]: 'Virtual Screen' Turning ON.
[13:00:55][D][sensor:094]: 'Desk Height': Sending state 63.40000 cm with 1 decimals of accuracy
[13:00:55][D][script:077]: Script 'screen_timer' restarting (mode: restart)
[13:00:55][D][main:322]: Executing screen timer command
[13:00:55][D][switch:012]: 'Virtual Screen' Turning ON.
[13:00:55][D][sensor:094]: 'Desk Height': Sending state 63.60000 cm with 1 decimals of accuracy
[13:00:55][D][script:077]: Script 'screen_timer' restarting (mode: restart)
[13:00:55][D][main:322]: Executing screen timer command
[13:00:55][D][switch:012]: 'Virtual Screen' Turning ON.
[13:00:55][D][sensor:094]: 'Desk Height': Sending state 63.70000 cm with 1 decimals of accuracy
[13:00:55][D][script:077]: Script 'screen_timer' restarting (mode: restart)
[13:00:55][D][main:322]: Executing screen timer command
[13:00:55][D][switch:012]: 'Virtual Screen' Turning ON.
[13:00:56][D][sensor:094]: 'Desk Height': Sending state 64.20000 cm with 1 decimals of accuracy

@IamMattM
Copy link

IamMattM commented May 26, 2023

When pressing the "up" arrow on the keypad I only get to see the following messages and there is no movement in the feet.
SCope says command from keypad is:
[ 0x9b, 0x06, 0x02, 0x01, 0x00, 0xfc, 0xa0, 0x9d]

[13:03:02][D][sensor:094]: 'Desk command': Sending state 1.00000 with 0 decimals of accuracy
[13:03:02][D][sensor:094]: 'Desk command': Sending state 8.00000 with 0 decimals of accuracy

@IamMattM
Copy link

IamMattM commented May 26, 2023

Enabling the logger baud rate to 9600 has definitely helped in revealing what might be going on...

@Scoff123
Copy link
Author

Ok great that's really helpful, we are narrowing the issue down at least. So:

  1. Keypad commands are being sent to the ESP board, and are successfully received and decoded by ESPHome.

  2. PROBLEM ESPHome is not transmitting commands which originate from the keypad, onto the controller.

  3. Home Assistant commands are being sent to the ESP board successfully.

  4. HA commands are successfully being transmitted onto the controller and processed correctly.

Hopefully someone with a bit more ESPHome knowledge can maybe identify what could be going on here with the onward transmission logic of the 'keypad received' commands?

@IamMattM
Copy link

IamMattM commented May 26, 2023

An update:

I memorised Preset 1+2+3 using the standard setup (no ESP32 man-in-the-middle) and once using the ESP32 back in the path between keypad and eq5, all of those Presets 1+2+3 are working from the keypad !!

The UP/DOWN key control do not work but then again it does not look like the code interprets those commands correctly as "Up" and "Down" -

This has been done without first triggering any controls from the HA integration just to be sure....

So DEskCommand1(up) and DeskCommand2(down) don't seem to have ever done anything from the keypad....THe other ones have.

And on many occasions now that I am playing with the keypad preset keys, there are occurences where the keypad shows "rST" and I have to lower the feet all the way down using HA (since the down key does nothing from keypad)....

Getting there but it is a bit flaky at present.

I also need to find out why I do not seem to have the "STOP" button on HA ....

@Scoff123
Copy link
Author

I've enabled the debug logging to hopefully see what is and isn't happening. Desk currently set at my Preset 2 height of 79.0cm.

Testing Controls in Home Assistant without touching physical keypad

Desk Height shows correctly on keypad as 79.0cm, and also in Home Assistant under desk height sensor. Keypad lit up. 'Screen' sensor shows status 'on'. Keypad remains lit up. Logging shows just output of WiFi Signal and Uptime.
image

Test 1) Click Cover Up arrow - desk starts moving repeatedly in minute increments every second or so. I had to toggle the virtual screen to OFF in order to stop the behaviour after the height go to 88.3cm (due to not having a STOP button!). This spammed the log output with:
image

This seemed to crash my ESPHome webpage, so I closed the log output, and eventually could open it again, however the same spamming is still occurring, but the desk is not moving, and I have not executed any further commands since the virtual screen toggle. Not sure it's worth going any further just yet with other controls. ESPHome addon probably grinds to a halt due to the logging filling up the log so quickly.

I then disabled the logging again and reflashed the ESP, opened up the output screen again and back to normal, no spamming, nothing other than WiFi signal and Uptime. So I tried the Cover Up arrow again now, and the desk raised up constantly as expected, all the way to 126cm at the top. The output looked ok, although a lot of output for each cm of travel seemingly, but worked as expected - keypad numbers increased correctly as did height sensor in HA:
image

So as mentioned, the debug logging being enabled really interferes with the operations, which is a pain...

@Scoff123
Copy link
Author

just to follow on, leaving the debug logging disabled,

Test 2) Click Cover Down arrow - the desk moved continuously down to the minimum height, showing 70.7cm on the keypad and in HA - so working correctly and as expected - regular ESPHome output shows a block message for each cm of travel

image

I have noticed with tests 1 and 2, that the desk doesn't seem to come to a gradual stop like it does using the desk keypad normally without the ESPHome bridge. It's not a harsh stop, just not a gradual stop if that makes sense. But other than this, the Cover UP and DOWN works as expected, provided the Debug logging is disabled. The keypad does remain lit throughout constantly though, so the 12 second timeout doesn't seem to work for some reason, whether you interact with a control in HA or do nothing.

If I can figure out the keypad timeout issue, then I can move onto the remaining controls like Pre-sets as there is some strange behaviour there, even with the Debug logging disabled...

@IamMattM
Copy link

I have just tried out the HA "Up" (= minimum up motion only , not the cover.open arrow one you seem to have tried and failed to turn the keypad off) and for that switch , the keypad lights up and correctly goes down after exactly 12secs.

@Scoff123
Copy link
Author

Would you mind capturing the standard ESPHome log output when you activate the HA "UP" up to and including when your keypad lights turn off please? Here is my output - the desk does go up an increment, but the keypad is always permanently lit up and doesn't go out either after the 12 seconds. Oddly my keypad an home assistant height sensor showed 70.2 before i clicked the UP button in HA, and after the desk moved up slightly, the display and HA show 69.8?? The desk definitely moved in an upwards direction.

image

@IamMattM
Copy link

IamMattM commented Jul 14, 2023

@Scoff123

Sure. Here you go:

image
...
...
image

A video showing the keypad lit up and going off
https://drive.google.com/file/d/1WDnLPL4D1To_5fZ1KKZOlAPtqH1-ggYe/view?usp=drive_link

@Scoff123
Copy link
Author

@IamMattM Thanks very much for capturing and posting that. I can see the same output in my ESPHome log window when i execute the same scenario, so it looks like the execution of the code is working correctly at least.

With the factory setup of just EQ5 and Keypad, the initial press of any keypad button triggers a WAKE of the keypad screen and button illumination. After the factory set timeout period with no button presses, the keypad screen and illumination turns off.

Upon plugging my ESP device between EQ5 and Keypad, the keypad immediately WAKES and illuminates, and will NOT turn off regardless of interaction. The only way to shut it off is to unplug the unit. So to me that indicates either my EQ5 is receiving a PERMANENT CONTINUOUS WAKE command from plugging my ESP device in the middle, and the default Keypad timeout is no longer able to kick in, as the EQ5 thinks there is constant interaction.
The ESP board could be receiving a TURN OFF KEYPAD command after the factory timeout, from the EQ5, but is failing to process this correctly and in turn switch off the keypad illumination.

Any ideas how I can identify where the issue lies? I'm going to revert to the original GPIO pin assignments in the repo, just so that my ESP config is identical to the known working one that you are using.

@Scoff123
Copy link
Author

According to the README on this repo,

Execute a command

The control box only accepts commands when the 'screen is active'. To activate the screen, PIN 20 needs to be set to HIGH for about 1 second. The screen gets disabled automatically again after some amount of time receiving no commands.

Command list

Command name Start Length Type Payload Checksum End
Wake Up 9b 06 02 00 00 6c a1 9d

so how can I determine if GPIO20 is permanently being held high - as this would seem to cause the behaviour I am seeing?

@Scoff123
Copy link
Author

Scoff123 commented Jul 23, 2023

I've started over with a brand new ESP32 board (NodeMCU Devkit V1), new cat5 wiring and new solder joins with dupont connectors for ease of disconnecting/testing.
I've flashed the new board and using the original GPIO designations. I'm now seeing some different behaviour to before - no more strange toggling but I don't know if it's progress or not :/

First of all, my keypad remains lit up as soon as I plug the ESP board inline. The screen doesn't timeout after 12 seconds. If I wait for 12 seconds, then toggle the Empty Command from Home Assistant, the keypad turns off. If i then press a key on the keypad, it lights up, but then doesn't turn off again. I have to wait 12 seconds, issue the Empty Command from HA and only then does the screen turn off. If I try to issue the Empty Command from HA before waiting 12 seconds after an interaction, nothing happens and the screen remains on.

I note there is some commented code under the Virtual Screen section in the yaml here:

- platform: gpio
    name: "Virtual Screen"
    id: "virtual_screen"
    pin:
      number: GPIO23
      mode: OUTPUT
    restore_mode: ALWAYS_ON # Changed since required for keypad control and would otherwise need HA access to enable the virtual_screen
    internal: false

I'm wondering if this is causing the behaviour I am seeing? Although this should only affect the state at bootup

@Scoff123
Copy link
Author

20230723_161842
20230723_161851

@Scoff123
Copy link
Author

Also getting a couple of new error messages on the LCD, which I haven't had before - one is ASr - which some googling reveals means that the controller needs to be reset. The other one I cannot find anything for, which is -OL
20230723_175600
20230723_175422

@IamMattM
Copy link

IamMattM commented Jul 24, 2023

Just checking the obvious as you seem to have a lot of strange behaviours compared to @deveritt-uk and myself

You are using the short ethernet cable and you are connecting the correct ethernet lead to the expected port ? (keypad on the left hand port when viewed like the capture below:

Uploading image.png…

@Scoff123
Copy link
Author

Well, I hope it's nothing obvious, as I've checked it all over several times on this latest build with the brand new esp32 board! I've connected things exactly as per the wiring diagram, and have the keypad and controller the correct way around.

HA is showing the desk height at 10 metres, which would be an impressive feat (!) So something has got messed up.

Screenshot_20230723_175524_Home Assistant

Plugging the keypad back into the controller for factory setup now also shows rst, so I'm going to reset the controller and key the factory setup back to normal before carrying on. It's starting to feel like there just be something different in my EQ5 controller compared with both your controller and @deveritt-uk - actually @deveritt-uk would you mind confirming the exact model of controller that your EQ5 is using please? If we all have the same keypad, then the controller would surely be expecting the same uart messages from the keypad, and giving the same messages back to the keypad, regardless of differences in the controllers internals?

@Scoff123
Copy link
Author

I've reset the desk in factory setup, by holding the DOWN arrow on the keypad until the desk got to the lowest height it can go to (62.0cm), and kept it held for around 5 seconds, until the desk moved up and back down very slightly while showing ASr, and this reset the desk so that at least in factory setup things were working correctly again. With the desk reset, I powered it off, and reconnected my ESPboard inline, before turning power back on. No more error messages on the keypad LCD, and it shows the correct current height of 79.0cm on both the keypad and in HA.

The problem, however, is the same as when I first tested - after powering the ESP board up, and having NO interaction with either HA or the keypad, the keypad remains lit up and does not turn off after the timeout.

This is what my ESP device shows in HA upon plugging it in, and WITHOUT interacting with anything:

Logbook
24 July 2023
flexispot-eq5 Empty command turned off
18:16:46 - 7 minutes ago
flexispot-eq5 Down turned off
18:16:46 - 7 minutes ago
flexispot-eq5 Up turned off
18:16:46 - 7 minutes ago
flexispot-eq5 Virtual Screen turned on
18:16:46 - 7 minutes ago
flexispot-eq5 M turned off
18:16:46 - 7 minutes ago
flexispot-eq5 Preset 4 turned off
18:16:46 - 7 minutes ago
flexispot-eq5 Preset 3 turned off
18:16:46 - 7 minutes ago
flexispot-eq5 Preset 2 turned off
18:16:46 - 7 minutes ago
flexispot-eq5 Preset 1 turned off
18:16:46 - 7 minutes ago
flexispot-eq5 Keypad locked turned off
18:16:46 - 7 minutes ago
flexispot-eq5 Desk was opened
18:16:46 - 7 minutes ago
flexispot-eq5 Screen turned on
18:16:46 - 7 minutes ago
flexispot-eq5 Firmware turned off
18:16:45 - 7 minutes ago
image

So it seems that the Empty Command, although being sent, is not turning off the screen after initial power up. I don't know if this would be the ESP board not correctly sending the Empty Command to the EQ5, which should in turn turn the keypad lighting off?

I'm running ESPHome 2023.7.0 if it makes any difference to how the header files are being handled - what version are you running @IamMattM @deveritt-uk ?

@IamMattM
Copy link

IamMattM commented Jul 25, 2023

I currently am running with Firmware: 2023.6.5
image

Intesrestingly there is an update that I am told is available 2023.7.0 but it seems to have some issues somewhere in the yaml file so will need to be looked at if going through update...

image

@Scoff123
Copy link
Author

@IamMattM The switch.template config in the yaml will need to be updated slightly for the latest ESPHome version, in order to prevent that warning. I changed the yaml for the 'Keypad locked' section to the following:

switch:
  - platform: template
    name: "Keypad locked"
    icon: mdi:key
    id: "keypad_switch"
    internal: false
    restore_mode: RESTORE_DEFAULT_OFF
    assumed_state: false
    optimistic: true

This uses restore_mode instead of restore_state and I chose the RESTORE_DEFAULT_OFF option as if this seemed to make sense for the keypad lock function, as if the correct state cant be determined then defaulting to off makes sense.

If you do update I would be keen to know if your desk is still fully functional, so if you could post back that would be helpful.

@Scoff123
Copy link
Author

I've edited the desk_keypad_eq5.h and desk_height_sensor_eq5.h files to print the actual UART bytes in Hex format, so I can at least try and see what's going on between the 2 devices with the ESP board plugged in the middle.
As soon as I plug the board in-between the keypad and control box, the ESP log spams a constant stream of:

[11:32:48][D][UART:085]: Received data from Desk UART: 9B
[11:32:48][D][UART:085]: Received data from Desk UART: 04
[11:32:48][D][UART:085]: Received data from Desk UART: 11
[11:32:48][D][UART:085]: Received data from Desk UART: 7C
[11:32:48][D][UART:085]: Received data from Desk UART: C3
[11:32:48][D][UART:085]: Received data from Desk UART: 9D
[11:32:48][D][UART:025]: Received data from Keypad UART: 9B
[11:32:48][D][UART:025]: Received data from Keypad UART: 06
[11:32:48][D][UART:025]: Received data from Keypad UART: 02
[11:32:48][D][UART:025]: Received data from Keypad UART: 00
[11:32:48][D][UART:025]: Received data from Keypad UART: 00
[11:32:48][D][UART:025]: Received data from Keypad UART: 6C
[11:32:48][D][UART:025]: Received data from Keypad UART: A1
[11:32:48][D][UART:025]: Received data from Keypad UART: 9D
[11:32:48][D][UART:085]: Received data from Desk UART: 9B
[11:32:48][D][UART:085]: Received data from Desk UART: 04
[11:32:48][D][UART:085]: Received data from Desk UART: 11
[11:32:48][D][UART:085]: Received data from Desk UART: 7C
[11:32:48][D][UART:085]: Received data from Desk UART: C3
[11:32:48][D][UART:085]: Received data from Desk UART: 9D
[11:32:48][D][UART:025]: Received data from Keypad UART: 9B
[11:32:48][D][UART:025]: Received data from Keypad UART: 06
[11:32:48][D][UART:025]: Received data from Keypad UART: 02
[11:32:48][D][UART:025]: Received data from Keypad UART: 00
[11:32:48][D][UART:025]: Received data from Keypad UART: 00
[11:32:48][D][UART:025]: Received data from Keypad UART: 6C
[11:32:48][D][UART:025]: Received data from Keypad UART: A1
[11:32:48][D][UART:025]: Received data from Keypad UART: 9D
[11:32:48][D][UART:085]: Received data from Desk UART: 9B
[11:32:48][D][UART:085]: Received data from Desk UART: 04
[11:32:48][D][UART:085]: Received data from Desk UART: 11
[11:32:48][D][UART:085]: Received data from Desk UART: 7C
[11:32:48][D][UART:085]: Received data from Desk UART: C3
[11:32:48][D][UART:085]: Received data from Desk UART: 9D
[11:32:48][D][UART:025]: Received data from Keypad UART: 9B
[11:32:48][D][UART:025]: Received data from Keypad UART: 06
[11:32:48][D][UART:025]: Received data from Keypad UART: 02
[11:32:48][D][UART:025]: Received data from Keypad UART: 00
[11:32:48][D][UART:025]: Received data from Keypad UART: 00
[11:32:48][D][UART:025]: Received data from Keypad UART: 6C
[11:32:48][D][UART:025]: Received data from Keypad UART: A1
[11:32:48][D][UART:025]: Received data from Keypad UART: 9D
[11:32:48][D][UART:085]: Received data from Desk UART: 9B
[11:32:48][D][UART:085]: Received data from Desk UART: 04
[11:32:48][D][UART:085]: Received data from Desk UART: 11
[11:32:48][D][UART:085]: Received data from Desk UART: 7C
[11:32:48][D][UART:085]: Received data from Desk UART: C3
[11:32:48][D][UART:085]: Received data from Desk UART: 9D

so it appears the keypad is sending the 'Empty Command' string continuously, which I believe is correct, however I don't understand what is being received from the EQ5? And subsequently why the keypad is being kept 'alive' and illuminated

@IamMattM
Copy link

IamMattM commented Jul 26, 2023

The EQ5 box should really be sending the payload 0x000000 when at target height and after receiving the empty command.

I don't see that in your log above.

image

image

image

Your log seems to suggest that your EQ5 box sends the unknown message type 0x11 which is different to what I witnessed on my EQ% box, and could well explain why the keypad never switches off...

image

image

@IamMattM
Copy link

I did the full motor rST and the preset registration withouth the ESP32 in my setup - I wonder if having those presets registered in the EQ5 box could lead to those unknown message type 0x11 to go away allowing the box to send only 0x12 message types with payload 0x000000 which seems to eventually allow the keypad to turn off.

@Scoff123
Copy link
Author

Thanks for the info, it looks like I'm going to have to do some more digging into the signals being sent from the EQ5 controller to the esp32. I've done the motor reset, and also saved a height to each of the 4 presets, before connecting the esp32 board, but after connecting it, im still getting the same uart output bytes from the Control box and the keypad is staying lit up with zero interactions.

I'll see if i can revise the .h files so that the esp log output prints the bytes in a string on each line, rather than each byte on a separate line.

@Scoff123
Copy link
Author

Scoff123 commented Jul 26, 2023

Looking at the readme, it shows:

image

and this ties in with the bytes I'm getting spammed with from the keypad. I thought it was an 'empty command' as per the ESPHome yaml:

 - platform: uart
    name: "Empty command"
    id: switch_empty
    data: [0x9b, 0x06, 0x02, 0x00, 0x00, 0x6c, 0xa1, 0x9d]
    uart_id: desk_uart
    internal: false

I suppose this is just a naming thing, however I have no idea why my keypad would be constantly sending this wake command to the controller? As if a button was stuck down on the keypad. Is this likely this is the keypad actually sending this command, or the ESP just 'thinks' this command is being received, and so forwards it to the control box?

[18:23:29][I][desk_keypad:035]: Received data from Keypad UART: 9b 6 2 0 0 6c a1 9d
[18:23:29][I][desk_keypad:035]: Received data from Keypad UART: 9b 6 2 0 0 6c a1 9d
[18:23:29][I][desk_keypad:035]: Received data from Keypad UART: 9b 6 2 0 0 6c a1 9d

or could it be that the controller isn't sending the expected 0x000000 message which would normally stop the wake command from running continuously - or the controller is sending this but the ESP isn't interpreting it correctly.

@Scoff123
Copy link
Author

I found reference to the hex code that I am receiving from the CONTROLLER repeatedly, which is:

[13:03:58][D][UART:088]: Received data from Desk UART: 9b 04 11 7c c3 9d

within a different repo here: https://github.com/Dude88/loctek_IOT_box/blob/main/arduino.ino

image

although I'm not sure exactly what this if referring to in terms of command or functionality.

@Scoff123
Copy link
Author

@IamMattM - Out of curiosity - if you unplug your physical keypad from your ESP bridge, and leave just the EQ5 motor controller connected, can you still use HA to control the desk as expected, with no unusual behaviour from not having the keypad connected?

@Scoff123
Copy link
Author

I've spent too much time on this to give up, so figured I would delve into some more in depth testing. After taking the keypad apart, I can see it has a board model of RF355, which is nothing like any of the keypad models mentioned in this report, and I can't find any mention of that model board anywhere online. Interestingly there is some sort of RF hardware on the board for some reason, and i can also see the buzzer - presumably for the alarm function:
20230729_203252
20230729_203306
20230729_203336
20230730_110738
20230729_203326

So with the keypad plugged straight into thr EQ5 control box, I could check the voltage on each of the 10 pins of the board connector. 8 of them are for the ethernet and 2 slightly larger gauge for the USB port.

@Scoff123
Copy link
Author

Keypad circuit board connector
10 Grey = GND
9 Orange = 29v

8 yellow = 5.13v
7 Blue = GND
6 Black = 5.13v - changes during tx/rx
5 Green = 1.837v changes during tx/rx
4 Red = 0v Goes to 5v for 10s after button press, then back to 0v when keypad turns off
3 Purple = 0v
2 White = 5.11v
1 Brown = 5.10v

@IamMattM
Copy link

4 Red - seems to suggest the keypad drives the "screen" input into the ESP32 high on a keypad key press and otherwise idles back to a low state.

I could have been wrong back then when I thought I had witnessed actually the opposite on my system where the "screen" output from the keypad was idling high :
May 23rd: "PIN20 being an always idling +5V line might be the one most at risk of damaging GPIO22 in the table above."

Might be worth testing with the "inverted: true" property for GPIO22=screen.
Could it be that although the keypad sends the empty command, that empty command is never accepted by the EQ5 because the "virtual_screen" is not active ?

In one of your previous post you said that manually sending the "empty" command through HA did the trick and placed the keypad into off mode after 12s.
That action would have ignore the "screen" GPIO22 input and go ahead and drive out the required state for "virtual_screen" and command.

I am not in a position to try out anything as I am not home for a couple of weeks.

But it might be worth checking if the "screen" input is considered active as a high or low. THey might have changed the polarity in the keypad schematic/fw and th ESP32 might need to match that.

@Scoff123
Copy link
Author

Thanks, I've been doing a lot of testing and checking after fiddling with the header files in order to log all of the UART communications as a string. It's certainly looking like there is some difference between our setup, either schematic/fw like you suggest - given we have slightly difference EQ5 control box models, including the difference in the board layout and ST chip.

The good news is that I am finally making progress after battling away with it. I now have more functionality that I have had to date.

First of all, I have left all connections on the ESP board the same as the wiring diagram in this thread, EXCEPT for the GREEN ethernet cable on pin 6 of the keystone jacks - I have simply connected these together, so that they are a straight through connection between the keypad and controller, and they bypass the ESP board.

I have also specified that GPIO22, for sensing when the keypad screen is lit up/active, is an INPUT - this is an optional configuration of the ESPHome pin schema, however I don't know what the pin is defaulting to when NOT specifying this, so my screen sensor yaml is now:

binary_sensor:
  - platform: gpio
    name: "Screen"
    id: "screen"
    pin:
      number: GPIO22
      mode: input
    internal: false
    on_press:
      then:
        - switch.turn_on: virtual_screen
    on_release:
      then:
        - switch.turn_off: virtual_screen

Now, when I connect my ESPboard in between Keypad and EQ5, the keypad lights up initially, the same as if you turn power on to the desk normally. I can see that GPIO22 is reading 4.76v. Looking in HA, I can see the screen sensor is showing as ON, and Virtual Screen is also showing as ON. I am also seeing the desk height being correctly reported as 62.0cm.

After 10 seconds, the keypad lights now TURN OFF correctly, and GPIO22 voltage drops to 0v. HA shows the screen sensor turns OFF and also Virtual Screen turns OFF.

Recording.2023-07-31.122633.mp4
Screenshot 2023-07-31 122702

HA also correctly tracks the desk height, when I alter the height of the desk from the physical keypad up and down buttons.

I figured this is half the battle, although it's only really using the ESP board as a 'Read-only' device, rather than being able to send commands to the box - as if it was the physical keypad. But happy to even have this much working finally!
However, there is one command that I CAN send from HA, which is the Virtual Screen toggle - if I click this in HA, it turns Virtual Screen ON, turns Screen ON and also lights up the physical keypad. It stays lit for 10 seconds, at which point everything turns off correctly again. The same actually happens if in HA I click any of the 4 Preset buttons - no action is taken, just the keypad lights up and the screen sensors turn to ON for 10 seconds, before turning OFF.

So the above is happening with just the RX2/GPIO16 pin on the board 'tapping into' the blue/white ethernet cable on pins 5 of the RJ45 connectors/keystone jacks. This must just be sensing the wake command communication from the keypad to the EQ5. Or it's simply just reading the GPIO22 pin as HIGH, and there is no UART detection happening due to only having one half of a UART pair of pins connected.

So progress at last. No I just need to figure out if it's going to be possible to transmit the various commands from the ESP, If I can incorporate the GREEN pin6 keystone cables. Currently they are connected together, so the keypad is communicating over UART directly with the EQ5.

@Scoff123
Copy link
Author

Scoff123 commented Aug 7, 2023

If I disconnect the 2 green ethernet pin 6 wires from each other, and have the green wire which connects to pin 6 of the EQ5 keystone jack connected to my ESP Boards GPIO17/TX2, and leave the keypads keystone pin 6 green wire disconnected from everything, I can successfully SEND messages from HA to the EQ5, and it behaves accordingly, either Presets, Up, Down etc.
This does mean however that the physical keypad is no longer lit up and no longer works and responds to any physical button presses - as the wake command can no longer get for keypad to EQ5.

This seems to indicate that having the ESP board in the middle is breaking this communication between the keypad and the eq5, even with the keypad ethernet pin 6 green wire connected to GPIO3/RX0. The commands received on RX0 seem to be sending indefinitely out via the TX2 pin to the EQ5, rather than just sending once, and therefore the EQ5 is keeping the original red wire (ethernet Blue wire pin 4) HIGH at 5v indefinitely.

Reconnect the two green ethernet pin 6 wires back together again, and the keypad behaves correctly again, but I obviously can't send any commands from the ESP anymore.

Desk Height is working correctly, and is being received from the EQ5 onto GPIO16/RX2.

I wonder if the voltage on this green ethernet pin 6 wire is causing an issue? The voltage idles at 4.94v. When the keypad is pressed in standard setup with no ESP involved, the voltage drops to 3.88v for the time that the keypad stays lit up, and then when the keypad turns off, the voltage returns to 4.94v. This means that when involving the ESP board in between, GPIO3/RX0 is constantly reading HIGH, rather than dropping LOW - I don't know if this would have any bearing on the UART communication or the way that the ESP handles it, if it is expecting a drop from HIGH to LOW, or an increase from LOW to HIGH during communication?

@iMicknl Do you have any idea based on your research with the UART communication, if this could be causing an issue?

@Scoff123
Copy link
Author

I gave myself a quick crash course in logic analyzers and bought a cheap USB one online and installed Sigrok Pulseview. I used an ethernet break out board to hook up a passthrough setup for the keypad and controller, so that I could tap into the TX and RX lines in the default setup and check what is being sent and received between my keypad version and control box version.

An example of the keypad wake/empty command that is sent when pressing any button the the keypad:

image

keypad wake

correct 79 3 height

so you can see that the button press triggers the control box to send the current Height to the keypad just ONCE at the very start (highlighted in the second picture, 79.3cm in this case), and then the control box seems to send a follow up signal out to the keypad, much shorter

start of wake command

before the Wake / Empty command is then received by the control box, and then a constant cycle of TX / RX continues for the duration of the ~10 seconds that the screen stays lit up. Each RX is the Wake / Empty command, but the TX message seems to alter between longer strings like this:

image

and a mix of long/short or short/long strings like this:

image

image

at the end of the ~10 second screen wake time, a different RX message is received after the constant Wake / Empty messages for the past 10 seconds:

image

image

and then the screen turns off.

Will update shortly with further findings

@Scoff123
Copy link
Author

it seems that last RX command was a rogue value, as I've captured several more transmissions, and they all end with a final Wake / Empty command. After the final Wake / Empty command has been sent from the Keypad after 10 seconds, the Control box seems to send 2 final TX communications:

endofwake

endofwake2

and the Keypad lights turn off.

Now if I can just work out why, when the ESP board is involved, these Wake / Empty commands continue to transmit contiuously, and don't stop after 10 seconds, I can get the keypad to turn off like it should.

After speaking with @deveritt-uk it seems he has an identical control box and keypad to myself, and his keypad also stays lit up, so there must be something 'slightly' different with our combination compared with other models of control box posted here (e.g @IamMattM ), which seems to turn the keypad off correctly after around 10 seconds. I'm still wondering if it's due to the idling voltage of 5v for ethernet pin6, which is effectively stays HIGH at all times, as it only drops to around 3.88v (no ESP involved) during the screen wake time, then back up to 5v when screen goes off.

I'd be keen to know what your voltage does on this ethernet pin6 @IamMattM if you have a chance to check at idle and during screen wake?

@david-romero
Copy link

Thank you so much @IamMattM!

My flexispot desk is working like a charm! Thanks for your effort and for sharing!

Captura de pantalla 2023-08-31 a las 8 44 00

The diagram was very easy to follow and to wire! Even for someone with no experience in soldering!

Copy and paste your code and the desk is working with HA! 😄 😄 😄 😄 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants