tetris11

joined 2 years ago
MODERATOR OF
[–] tetris11@feddit.uk 3 points 1 hour ago

it's like they're unable to drive due to a broken gearbox

[–] tetris11@feddit.uk 1 points 2 hours ago

By saying he has private beliefs, perhaps he is saying that he doesn't believe in abortion personally yet doesn't want to project his personal views onto others across the country.

I like him for saying this. I have my own less-than-enlightened cagey views on some hot topics, but I try not to let them oppress people and ultimately believe in the freedoms of all people to choose their own path through life

[–] tetris11@feddit.uk 2 points 5 hours ago

As long as the relationship is consensual, then that's.... that's fine

[–] tetris11@feddit.uk 3 points 5 hours ago

Plastic, yes, bad.

But a chinese lantern made of thin metal and paper, released on a wet winter day? I can't see that doing harm.

[–] tetris11@feddit.uk 2 points 5 hours ago

Renaissance Festival

I've always wanted to go to one of these, not only to see jousting but also to eat a big ole chunk of meat off the bone like Homer does in the Iliad, but it seems like something only the US does, despite not having any medieval history whatsoever!

[–] tetris11@feddit.uk 2 points 5 hours ago* (last edited 5 hours ago)

One of my radiators was leaking slightly from the valve^[I overtightened it because I thought tighter is better, but it looks like I warped the olive], so I thought I would take it off and have another go with a fresh olive. Other than the usual fun of water leaking everywhere ^[despite draining, and bleeding, and getting soot onto nice tea towels], one problem immediately arose: I can't get the olive off. So I order an Olive Tool / Brass Puller, whilst the radiator lies on the floor for a day^[I'm wearing ski socks and christmas sweaters to overcome the lack of heating].

The tool arrives, I use the 15mm attachment on the small side and it slides the olive off of that side no problem. I use the 22mm attachment on the big side and.... it's 1mm too big? Wait, what?

It turns out I was a ruddy fool for expecting my radiator to conform to modern sizes. One side uses 15mm, the other side uses the 1/2" patriotic standard:

So I'm waiting a few days now for this somewhat harder to find tool to arrive, whilst the weather ticks ever colder and wetter, and I question the existence of my hybrid radiator -- the confused love child of two worlds.

I feel like I say this every week, but, I hate plumbing.

[–] tetris11@feddit.uk 1 points 5 hours ago

As someone who is primarily nocturnal, I don't pity you - all your good habits go out of the window as soon as your body is desynced with the general population

[–] tetris11@feddit.uk 1 points 5 hours ago

It's heartbreaking watching your parents grow old. Strength to you for keeping your spirits high

[–] tetris11@feddit.uk 2 points 6 hours ago

So many ways to interpret this

[–] tetris11@feddit.uk 2 points 16 hours ago* (last edited 16 hours ago) (1 children)

oh okay good to know I'm at least not alone in this experience

Edit: To do it myself, I'd have to implement the JTAG protocol on the GPIO's directly using arduino or esp libraries, which is not something I would relish doing. Perhaps in MicroPython, but that has limited libraries and it would be a lot of trial and error.... and ultimately, I just want to run a JTAG debugger on an ARM core I found, not re-invent a new JTAG debugger

[–] tetris11@feddit.uk 20 points 16 hours ago

For anyone wondering "what the heck, this comic is from the 60's no?"

https://en.wikipedia.org/wiki/Nancy_(comic_strip)

2026 to present

Caroline Cash took over the strip from January 1, 2026.[32] Writing for Prospect, Frank M Young describes Cash's first month on the strip as "vibrant, authentic, edgy" and that "her Nancy teeters between crowd-pleasing and shocking."[33] In a June 2026 storyline, Fritzi says she is bisexual,[34] and starts dating Phil Fumble's cousin Phylis Fumble.[35]

So like Dennis the Menace it's had a few artists, and Cash is the current one

[–] tetris11@feddit.uk 7 points 17 hours ago

All I do, is sit down at the typewriter, and start hittin' the keys. Getting them in the right order, that's the trick. That's the trick.

 
 

Why did the Peasants have to be so demanding?

 

There's a Victorian chapel in one of the hospitals at GOSH, designed by the same guy who did Westminster.

Marvel of engineering, but built around miasma theory (need lots of light and aerated sections to keep bad air at bay) which fell out favour when germ theory came into being (sterilise everything, and you're fine), so the big spaces became impractical.

By then the chapel was Grade II listed, so they couldn't knock it down. So they smashed everything around it, underfitted it and moved it down, and then rebuilt the hospital around it.

 

cross-posted from: https://feddit.uk/post/56789745

DeviceI had this cheap chinese radio MIABOO M20, which had a ton of cool features: portable, bluetooth, aux, and radio. But the speaker wasn't great (mono), and the battery didn't last very long

So I took it apart (beer, force, pliers) with great effort since there's not a single screwhole anywhere on it as it was all glued together

Components:

  • Speaker
  • Battery (no markings, but big and blue cyclinder, looks like a 18650 Li-ion)
  • Main board
    • 2-pin JST speaker connection and another 2-pin JST (2.4mm pitch)
    • SD card slot
    • MCU, unknown 18140
    • 18-pin FPC connector to the LED board
  • LED board
    • 54 Lights:
      • 4x5 grid of different coloured LEDs
      • 4 digits with colon and a dot
      • 4 bottom lights
    • 4 buttons
    • 18-pin FPC connector

LED Board

Front

7 sets of something that appear to feed into everything else. My guess with the 54 LED lights is that it's probably a 7x8 grid, and this is the "7" part.

Some markings on the board:

  • Q are where the transistors are
  • 2A I think are fuses?
  • 104 and 102 are common resistors, with R names etched into the board
  • O are the test contacts on the board -- little circles of metal for me to test with a multimeter

     [O2]             [O14]

       Q5    Q4      Q7     Q6     Q8    Q10     Q9
    | 2A|  | 2A|  | 2A|  | 2A|  | 2A|  | 2A|  | 2A|
    |104|  |104|  |104|  |104|  |104|  |104|  |104|
    |102|  |102|  |102|  |102|  |102|  |102|  |102|
   R41 [O4] [O5]       [O7] R42  [O8]   [O9]   [O10]
   R47      R40   [O6]      R50   R44  R46    R45         [O12]
            R48     R43    [O15]  R51  R52    R53
  [O1] [O3]         R49                       [O18]
                                                       [O13]
                                                
      |  02  04  06  08 10  12  14  16  18|     [O16]         
      |01  03  05  07 09  11  13  15  17  | [O17]          [O11]
      | F P C - C O N N E C T O R - P I N | 

So the 18 pins of the FFC cable (flat flexible cable?) are shown in the above FPC connector.

I used a multimeter in continuity mode to trace each pin to each of the contacts, and wrote down when it beeped. I then changed the numbering of the O contacts in the above schema so that each O number corresponds to an FPC pin (e.g. FPC Pin 18 traces a path to O18 on the board)

Back

  • Back has all the lights, see the video

Investigating the Board

So I hooked the 18-pin 0.5mm pitch ribbon cable into a 0.5mm FPC breakout board (5 quid, ebay), and then stuck each pin into a GPIO on my Raspberry Pi for testing.

Charlieplexing

I've talked about charlieplexing in a previous post, but the main gist is that pairs of pins, 1 high and 1 low is what drives a single LED. I assumed this was the case with this LED board, but when I tested every single pair against every other pair, I got nothing. Not a blip.

Broken lights?

At first I thought I'd somehow botched the board when I was taking it apart, and was worried that the LEDs were simply broken. I didn't know what to do, but after reading a bit I found out that a multimeter is the perfect tool for this because it has something known as Diode Mode which lets you literally put one probe on side of a diode, and another probe on the other side, and then it shoots a little tiny current through it.

At first I thought this was just mumbo jumbo, but thought I would give it a go, and - OH MY GOD IT WORKS! - each LED I tested this way sparkled light at me.

So I knew the board was working! I just have to figure out how to use the pins to get the signals down there.

Actual broken lights

Okay, so in my excitement in this discovery of Diode Mode on a multimeter, I then packed it away and got out my USB-to-TTL chip which also has VCC and Ground contacts.

For some reason I thought I would just double check an LED again using the 5v from the USB and the Ground on an LED, and.... nothing happened. Wondering what happened, I tried the 3v3 from the USB and the Ground on the LED, and.... (-PEW-) I smelled something burning.

I saw a little puff of smoke rising out of a blown LED, and wondering what happened, I stupidly did again on another LED, and another puff of smoking.

Oh dear

So what happened? Well it turns out that circuits have resistors and fuses for a reason, and that if you run an unrestricted current across a sensitive diode, it's probably going to blow up.

🫢

The reason why the multimeter is the better tool here, is because it gives a teeny tiny 1-2mA between the probes, and a USB can give 1000 times amount. Yeah....

Live and learn.

:

Multiplexing the PinsSo charlieplexing from the previous section did not work, meaning that the board probably isn't completely GPIO driven, but might actually have some dedicated pins for power and ground.

Which one's though?

Not really knowing what I was doing, I connected the LED board back to the main board via the FFC ribbon and powered on the main board. A few lights lit up (yes, this would have been an easier test earlier with the lights), and then I started measuring the voltage difference between each of the O pads.

spoiler O Pad voltage matrix

O\O 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
1
2 2.9
3 -0.3 -3.2
4 .14-.17 -2.8 .4
5 .14-.17 -2.8 .4 0
6 .14-.17 -2.8 .4 0 -.002
7 .14-.17 -2.8 .4 0 0 .001
8 .14-.17 -2.8 .4 0 0 .001 -.001
9 .14-.17 -2.8 .4 0 0 .001 -.001 0
10 .14-.17 -2.8 .4 0 0 .001 -.001 0 -.001
11 0.05 -1.2 1.9 1.5 .7 .3 -.05 .3 .3 .3
12 .8-1.1 -1.7-2.0 1.1-1.4 .3-.6 .7-1.0 .3-.7 .4-.6 .7-1.0 .7-1.1 .3-.6 -.3-0
13 .45 -2.4 1.1 .7 .7 .3 .7 .7 .7 .6 0 .4-.7
14 .97 -1.5 1.6 .8 .4 .4 .4 .4 .4 .4 .65 .5-.8 .3
15 .49 -2.4 .3 .3 .3 -.04 .3 .3 .3 .3 .06 0-.4 .74 -.8
16 .5 -2.3 .8 .02 .01 .4 .4 .4 .02 .4 -.3 .1-.4 -.3 -.3 -.8
17 .4 -2.4 .3 -.05 .7 .3 .7 .7 .7 .3 0 .4-.6 0 0 0 .8
18 .3-.7 -2.1--2.5 .6-1.0 -.04 -.05 -.05 -.05 -.05 -.05 -0.04 -.77 .3-.6 -.7 -.8 -.4 .4 0
:::

Great..... what does any of this tell us?

Well there's a pretty high chance that the 2.9V that I got when I put the red probe on 1 and the black probe on 2, gave the highest the positive voltage across the board is the main power line (Pin 1).

There's also a pretty high chance that the -3.2V I got when I put the red probe on 2 and the black probe on 3 is the main ground line (Pin 2). So I think the board operates at roughly 3.3 V, and the first two pins are power pins.

Okay, and does this work?

I moved Pins 1 and 2 in my initial setup on the Raspberry Pi to the 3v3 Pin and to the ground, and yep, things started lighting up!

I assumed that the rest of the lights were charlieplexed, and so I did pair testing on the other 16 pins, and I started getting individual LED's to light up!

Using this information I started to write a little driver and will start using this for my halloween projects!

 
 
 

I found a vape pen on the ground already half smashed so I couldn't identify what it was sadly, other than it being pink.

After taking it apart (pliers, force, beer) I looked at the chips under a magnifying glass, and saw it had a SC8F073 MCU^[yeah no idea. Had to look it up. Says it might a UART interface I can dick around with, but not seeing anything], and also had this little ribbon display whose only markings I could see are "12-25 WC294F".

Charlieplexing

It's a 6 pin cable going towards 18 LEDs, so in theory has more than enough (6*5 = 30) configurations to light up each LED.

Turns out because these are what I like to call "Cheap and Cheerful Chinese Chips", they cannot be arsed to put in the required resistors to allow such addressing to take place, so they make use of something called "charlieplexing" which works as follows:

  1. Only a single pair of anode/cathode pins needed to light up an LED (1 high, 1 low, all others in "high impedance" (i.e. disconnected))
  2. Since multiple LEDs might share an overlapping pin, you can't have multiple pairs of pins active at the same time, as this will cause spillover to other LEDs
  3. To show the number "3" , made up of 5 LEDs, you have to cycle through those 5 pairs of pins whilst impeding all others, very very fast to give the illusion of the number "3".

I used a USB to TTL chip from my laptop with Dupont connectors going into an FPC breakout chip (both roughly 5 quid from online retailers), and hooked the display ribbon into it, and got to testing pairs. I got the following (High Low) pair diagram

    |  32  |       65         53
    |  34  |    56    64   43    52
    |  35  |       54         42    
    |  36  |    61    63   45    51
    |  41  |       62         46      26

You might notice:

  • The battery (far left) has multiple pin mappings
  • The percent symbol (far right) has just one, despite the percent one arguably having a large use case by being paired with numbers...
  • There's no common pin grouping for each digit. Digit 1 is a mix of 5/6 high and Digit 2 is a mix of 4/5 high. So I feel like they could have done better.

Anyway after some dicking around, I put this little python "driver" to work and now it can do arbitrary numbers

Code

import json
import time
from pathlib import Path
from typing import Iterable
from gpiozero import InputDevice, OutputDevice


GPIO_PINS = (13, 19, 26, 16, 20, 21)
##FFCB_PINS = (1, 3, 5, 2, 4, 6)       # Physical FFC interface
DISP_PINS = (6, 4, 2, 5, 3, 1)       # Display pin numbers

Mapping = dict[str, dict[str, list[int]]] # Type


class PinMap:
    """Load display segment definitions and map them to display pins."""

    def __init__(self, gpio_pins: Iterable[int] = GPIO_PINS,
                 display_pins: Iterable[int] = DISP_PINS,
                 segment_file: str | Path = "out_segments.json"):
        self.gpio_to_display = dict(zip(gpio_pins, display_pins))
        self.display_to_gpio = {display: gpio
                                for gpio, display in self.gpio_to_display.items()}
        self.segments = self._load_segments(segment_file)

    def _load_segments(self, filename: str | Path) -> Mapping:
        with open(filename, encoding="utf-8") as file:
            raw_segments = json.load(file)

        segments: Mapping = {}

        for name, pairs in raw_segments.items():
            display_name, _, part = name.partition(".")
            part = part or "main"
            display_pairs = [[self.gpio_to_display[gpio] for gpio in pair]
                             for pair in pairs]
            # Preserve the original behaviour: use the first pair.
            segments.setdefault(display_name, {})[part] = display_pairs[0]

        return segments

    def to_gpio_pairs(self, display_pairs: Iterable[tuple[int, int]]) -> list[tuple[int, int]]:
        return [(self.display_to_gpio[anode],
                 self.display_to_gpio[cathode])
                for anode, cathode in display_pairs]


class CharlieplexDisplay:
    """Drive a Charlieplexed display using gpiozero."""

    def __init__(self, pin_map: PinMap, gpio_pins: Iterable[int] = GPIO_PINS):
        self.pin_map = pin_map
        self.gpio_pins = tuple(gpio_pins)
        self.devices: dict[int, InputDevice | OutputDevice] = {}

    def __enter__(self) -> "CharlieplexDisplay":
        self.high_impedance()
        return self

    def __exit__(self, exc_type, exc_value, traceback) -> None:
        self.close()

    def _close_devices(self) -> None:
        for device in self.devices.values():
            device.close()
        self.devices.clear()

    def high_impedance(self) -> None:
        """Release all GPIO pins and configure them as floating inputs."""
        self._close_devices()
        self.devices = {pin: InputDevice(pin, pull_up=None, active_state=True)
                        for pin in self.gpio_pins}

    def close(self) -> None:
        self._close_devices()

    def drive_pair(self, anode: int, cathode: int) -> None:
        """Drive one LED: anode HIGH, cathode LOW, all others floating."""
        valid_pins = set(self.gpio_pins)
        if anode == cathode:
            raise ValueError("Anode and cathode must be different")

        if anode not in valid_pins or cathode not in valid_pins:
            raise ValueError(
                f"Pins must be in {sorted(valid_pins)}; "
                f"got {anode}, {cathode}"
            )
        self.high_impedance()
        # Replace the two input devices with outputs.
        self.devices[anode].close()
        self.devices[cathode].close()
        self.devices[anode] = OutputDevice(anode, initial_value=False)
        self.devices[cathode] = OutputDevice(cathode, initial_value=False)
        # Set sink first, then source.
        self.devices[cathode].off()
        self.devices[anode].on()

    def light_single_pair(self, anode: int, cathode: int, duration: float = 1) -> bool:
        """Light one LED for duration seconds."""
        try:
            self.drive_pair(anode, cathode)
            time.sleep(duration)
            return True
        except Exception as exc:
            print(f"Error lighting {anode} -> {cathode}: {exc}")
            return False
        finally:
            self.high_impedance()

    def light_pairs_multi(self, display_pairs: Iterable[tuple[int, int]], loops: int,
                          on_time: float, off_time: float) -> bool:
        """Multiplex a sequence of display-pin LED pairs."""
        gpio_pairs=self.pin_map.to_gpio_pairs(display_pairs)
        if not gpio_pairs:
            return False

        try:
            for _ in range(loops):
                for anode, cathode in gpio_pairs:
                    self.light_single_pair(anode, cathode, on_time)
                    time.sleep(off_time)
            return True

        except Exception as exc:
            print(f"Error in display: {exc}")
            return False

        finally:
            self.high_impedance()



def make_number(display: CharlieplexDisplay, leds: dict, value: int, loops: int = 100,
                show_percent: bool = False, show_battery: bool = False) -> bool:
    if not 0 <= value <= 199:
        print("Value must be between 0 and 199")
        return False
    digits = f"{value:3d}"
    pairs: list[tuple[int, int]] = []
    for index, digit in enumerate(digits, start=1):
        pairs.extend(leds[f"dig{index}"][digit])
    if show_percent:pairs.extend(leds["percent"])
    if show_battery:pairs.extend(leds["battery"])
    return display.light_pairs_multi(pairs, loops=loops, on_time=1e-4, off_time=0)

pin_map = PinMap()
dp = pin_map.segments


# Make the LED mappings a bit more legible?
DIGITS = {
    " ": (),                               "0": ("tm", "tr", "tl", "br", "bm", "bl"),
    "1": ("br", "tr"),                     "2": ("tm", "tr", "bl", "bm", "cm"),
    "3": ("tm", "tr", "bm", "br", "cm"),   "4": ("tl", "cm", "tr", "br"),
    "5": ("tm", "br", "bm", "tl", "cm"),   "6": ("tl", "cm", "tm", "br", "bm", "bl"),
    "7": ("tm", "br", "tr"),               "8": ("cm", "tr", "tl", "tm", "br", "bm", "bl"),
    "9": ("cm", "tl", "tm", "tr", "br", "bm"),
}

SEGMENT_NAMES = {
    "tm": "top.middle",   "tr": "top.right",     "tl": "top.left",  "cm": "center.middle",
    "br": "bottom.right", "bm": "bottom.middle", "bl": "bottom.left",
}

def make_digit_map(display: dict) -> dict[str, list[tuple[int, int]]]:
    def segment(name: str) -> tuple[int, int]:
        return display[SEGMENT_NAMES[name]]
    return {digit: [segment(name) for name in names]
            for digit, names in DIGITS.items()}

leds = {
    "battery": [dp["battery"]["main"]],
    "percent": [dp["percent"]["main"]],
    "dig1": {
        " ": [], "0": [], ## Empty arrays we can add in
        "1": [dp["dig1"]["bottom"], dp["dig1"]["top"]],
    },
    "dig2": make_digit_map(dp["dig2"]),
    "dig3": make_digit_map(dp["dig3"]),
}

# display = CharlieplexDisplay(pin_map)
# print(leds["dig2"]["3"])
# print(display.light_pairs_multi(leds["dig2"]["3"], 100, 1e-3, 1e-3))

with CharlieplexDisplay(pin_map) as display:
    value = 199 ## the literal max value
    while value > 0:
        make_number(display, leds, value,
                    loops=3, show_percent=True, show_battery=False)
        value -= 1
    ## And then add the battery display at zero
    make_number(display, leds, 0,
                loops=300, show_percent=False, show_battery=True)

 
 
121
Bye, Tasha! (feddit.uk)
submitted 1 week ago* (last edited 1 week ago) by tetris11@feddit.uk to c/tenforward@lemmy.world
 

https://en.wikipedia.org/wiki/Symbiosis_(Star_Trek:_The_Next_Generation)

"Symbiosis" was filmed after "Skin of Evil", which featured the death of Tasha Yar, making this the final filmed episode with Denise Crosby as Yar until she reappeared in "Yesterday's Enterprise". Towards the end of the episode, as Picard and Crusher leave the cargo bay, Crosby can be seen waving goodbye to the camera behind them (timestamp 42:15, she is clearly visible above Patrick Stewart's left shoulder as the bay doors close). LeVar Burton later used behind the scenes footage from this episode in a feature on his show Reading Rainbow, in the episode "The Bionic Bunny Show"

 

https://en.wikipedia.org/wiki/Patrick_Stewart#Relationships_and_children

In his autobiography, Stewart said that he and Jennifer Hetrick had an affair during Stewart's marriage to Falconer, causing a breakdown in their marriage. He said that he and Hetrick dated during parts of the run of Star Trek: The Next Generation and were engaged during the filming of Qpid, although they never married.

Oh Patrick... you dawg

view more: next ›