esphome lights with multiple outputs

I have some weird DIY lights fixtures at home that are controlled over wifi. When I first build them, they used a micropython firmware that speaks MQTT. I added code so they get auto-discovered by home-assistant, but never bothered to fully implement and debug it. One side-effect was that I had to restart the lights as soon as the MQTT connection broke, e.g. when restarting the home-assistant container or network outages. So after I learned about esphome, it was kinda clear that I should just scrap my own python code and write a .yaml file for esphome instead.

For most of the LED-Dimmers that was simple. There is a PCA9685 component in upstream esphome, as well as a BME280 sensor that most of my boards have as well. Sprinkle in a few GPIOs for LEDs and buttons and we were done.

There was only one light fixture I did not migrate until today: my ceiling light. The PCB was bodged and not documented. It has four powerful LEDs that need cooling, so one GPIO controls the fan. Which itself is attached to a low-side-buck-converter.

Schematic of a low-side-buck-converter.

Taken from https://electronics.stackexchange.com/questions/330471/low-side-n-mosfet-buck-converter

And to make things even more complicated, the four main LEDs all should be set to the same brightness. So multiple float-output need to be set at the same time. Unfortunately the esphome light component only allows one output. The solution for that is to add lambda code into the .yaml file.

light:
  - platform: monochromatic
    icon: "mdi:ceiling-light"
    name: "Deckenlampe"
    output: 'pwm0_dummy'
    gamma_correct: 1.0 # use 1.0 so we can get the 'real' brightnes by using the get_brightness() call
    id: "mlight"
    # we can get away with not implementing the 'on_turn_off' state, since we always turn on in the on_state call
    on_turn_off:
      - lambda: |-
          id(light09).turn_off().perform();
          id(light11).turn_off().perform();
          id(light13).turn_off().perform();
          id(light15).turn_off().perform();
          float fan_v = 0;
          id(fan_pwm).set_level(fan_v);
          id(fan_speed_sensor).publish_state(fan_v * 100); // show 0..100% value
    on_state:
      - lambda: |-
          // remote_values holds the values reported to the frontend.
          // we cannot use current_values since that is about to update in the on_state change call
          float br = id(mlight).remote_values.get_brightness();
          //ESP_LOGD("main", "===== got brightness %f", br);
          id(light09).turn_on().set_brightness(br).perform();
          id(light11).turn_on().set_brightness(br).perform();
          id(light13).turn_on().set_brightness(br).perform();
          id(light15).turn_on().set_brightness(br).perform();
          // now the fan control
          // these values were checked experimentally, there is no deeper meaning
          // with 80% there is some air movement, but the fans are not to loud
          // and 51% does turn the fans on just slightly
          float fan_v = 0;
          if (br > 0.5) {
            fan_v = 0.51; //130/255
          }
          if (br > 0.9) {
            fan_v = 0.8;  //200/255
          }
          id(fan_pwm).set_level(fan_v);
          id(fan_speed_sensor).publish_state(fan_v * 100); // show 0..100% value

The mlight entity is the only light that is exposed to the user. It has a 1.0 gamma, so its output brightness is the same as the setpoint the user selects in the home-assistant interface. It is mapped to a unused output and only serves as the dummy for controlling the 4 real outputs.

Because esphome adds a transition by default, the trick is to copy the remote_values.get_brightness() value over to the other lights. Then do a lookup for the the fan speed and publish it as template sensor. If you use current_values instead, the lights will always lag behind the actual commanded setpoint, because the on_change handler is executed at the beginning of the transition.

Fixing “108.08” error on a lexmark C546dtn printer

The printer that I have been using for quite some time recently stopped working. The display indicated that the error is “108.08”.

A quick search got me the service-manual for this printer. This is a really great document. It has all the instructions needed to diagnose and fix an error. Detailed disassemly instructions can also be found.

Service instructions for the 108.xx error

I did all of that, but instead of replacing the printhead I just cleaned it. Over the time dust does accumulate on the windows where the laser light exits the printhead. After disassembly I could clearly see that the windows were cloudy; colorful toner could als be spoted on the windows. My solution was to use a kimtech wipe without any water/solvent to clean the lenses.

The manual actually says to clean those windows, but its on another page/section not directly related to that error.

Illustration how paper and light are routed through the printer

Fix broken pins on QFP Package

That is how my new HW-0.30-mini Quadcopter Flightcontrol looked prior to the repair:

broken pins

Since a few of the Pads already were delaminated I decided to do a repair instead of soldering in a new CPU. For a repair I would need to get rid of the expoxy mold to directly acces the pins of the leadframe. Initially I was thinking of using a ‘dreml’ tool to remove the exoxy, but watching the Uncaging Microchips talk at 31C3 taught me that using a CO2-Laser will also work.

Those pictures were taken during the laser-removal:

 

After lasering, all left to do was attach new wires. I did use a microscope for that. For scale, the wire running on top of the CPU has a 0.3mm diameter.

I ran some quick tests with the software to make sure the repair worked. Then a blob of hotmelt was applied to secure and protect the repaired pins:

HW-0.30-mini fixed

 

Backstory: I am also responsible for breaking the pins. I did solder the CPU at 31C3 without proper lighting using borrowed equipment. The temperature on the soldering iron was set to 450°C, I failed to check that. This lead to some major fuckup. Since I wanted to work with the board, the decision was made to simply cut of the broken pins. At the time I didnt need them.