T-shirt project progress log

I have finished work for the year, so I now have some serious time over xmas to devote to my LED T-Shirt project.

I have my own playlist handling code set up - it’s a linked list, allowing me to add / move / remove things in the middle of the sequence whilst it is playing.

I also have a button hooked up (Will be mounted on my belt) - it will interrupt what is currently playing, play something else (In this case a Teletubby “Eh Oh!”” animation), and then resume with the normal sequence.

panel demo

I am only using 2 of the 3 connectors on the active-3 board, so that leaves me with 6 spare GPIO pins.

I will use 2 for an ATXRaspi (To allow me to cleanly power down with a button), plus 4 general purpose action buttons - I am planning on allowing the user to configure the purpose of these buttons via the UI on the phone.

Not totally sure about what to do for the phone UI yet, am currently leaning towards a REST API on the back end, so that the UI can be easily swapped out.

It’s currently all C#. I am not using the C# bindings, it’s just calling the led-image-viewer executable, waits for the process to end, and then calls it again to play the next animation.

1 Like

thanks for the update, looks cool
So you’re saying you’re not building this just for you, but for a bunch of end users you would sell to when it’s all good, working, and foolproof’ed?

Just for me at the moment, but if I do get it to a reasonable place I would consider open sourcing the whole thing (Including the CAD project). I am not looking to sell anything

gotcha, thanks for the info. Mine is explained on my blog, and the code is published, but it’s still a fair amount of work to build one. No one has so far.
To be honest, I also do not mind having the only one in the world :slight_smile:

One per continent only please :wink:

I made some progress on the CAD side - I now have the hole spacings for the thread inserts (The ones the magnets screw into) and have printed off a temporary frame to hold the panels. The panels fit inside so perfectly :slight_smile:

Now I just need to work out how to make a curved version of it, which is not gonna be easy. I am thinking of using Fusion360’s “sheet metal” functionality, which allows you to take a curved surface, flatten it out, perform operations on it (ie add the holes), and then re-bend it

Oh hell yes!

The sheet metal modelling technique worked!!

  • Start with a solid that has a bend in it, which is bigger than it needs to be (So that you don’t need to calculate how big the curved part needs to be, you have plenty of extra material that can be trimmed away)
  • Convert it to a sheet metal part
  • “Unfold” it (Flatten the curved sheet metal part)
  • Do a combine operation - have it keep only parts that intersect with the flat version (That I screenshotted in my previous post)
  • “Refold” it (Makes it curved again, keeping the changes that you made to it while it was flat)

Fusion360_6cRgd8U6DJ

So yeah - it seems you can design the geometry as a flat part (So it’s easy to work with as everything is on a flat plane, plus all the dimensions are accurate), and then convert it to a curved version

Is there any interest in me open sourcing this CAD project?

There’s a free version of Fusion360, so anyone could use it to create themselves a frame.

To a certain degree, I can make it so that you can configure it without needing to know CAD.

F360 has a “User parameters” feature whereby you just edit a table (Like editing a spreadhseet) and it updates the design for you.

There is only so much that could be done via parameters though.

The design as it stands is intended for two panels (1x2). I could probably include a variant for 3 though (1x3). Trying to make it work for eg 2x2 etc may well be problematic

It would also be problematic to allow for different hole spacing patterns - as it stands, it is geared for the style in the below pic - ie there are two different dimensions for x and y, where there is one in the middle on the x axis, and two symmetrical about the middle on the y axis. Trying to make it work for a fundamentally different style would be nigh on impossible

I spent an inordinate amount of time getting the sheet metal technique to actually retain dimensional accuracy of the hole placement when you re-bent it. For anyone trying to do the same thing, the trick is to extrute a 0.2mm flat part where the top face of the part will end up being the top most face of your part (eg the front of the bezel). Then you can extrude down, adding features, and when you re-bend, it will be accurate (ish(

Fusion360_vfVeVSEAtj

I have made some changes to the general design of the part. I did do a test print with it lying flat, but it was a shitload of supports, and was too weak along the layer lines (Plus a really rough surface where it will be next to my skin)

I am now playing with a version that is split into two parts and designed to be printed upright.

I made the screw mount holes conical, so they don’t need supports

This also has the following benefits:

  • You could conceivaby print a 3 panel mount (eg >300mm high) on a smaller printe, split into 3 parts
  • Multiple shorter prints - always safer
  • Less filament usage (Printing flat used as much material for the supports as the part itself

I may have to design some custom supports though, as those tree supports are a bit flimsy. I had to pause the print and hot-glue one of them in place :stuck_out_tongue:

The faces highlighted in blue in the picture below are where bars join the two halves. I will use heat-set thread inserts inserted into the frame itself.

I decided against using the thread inserts that are part of the panel, as @marcmerlin advised that these are weak as it is, so best not to have them be a structural part of the frame as well as holding the panel to the frame.

I have also built in strain relief for the power and ribbon cables (Middle bottom) so that I can zip-tie them secure.

1 Like

good job on the dedication. I had a good feeling it would not be trivial.
For the screw holes, whether you can use them depend on the specific panel. Some panels are better than others on that front. For others, you’re better off using the magnets as long as you can have some strong enough that it won’t pop out in the field.
thanks for keeping us updated on your project.

Surely, if you keep the magnets, the panel staying on is still reliant on the thread inserts that the magnets screw into.

Plus, then you have to glue magnets (Or pieces of metal) into the frame, and that glue joint could fail.

Plus, of course, as you note, the magnets could come apart.

So it seems to me that magnets have 3 potential points of failure, but just using the thread inserts has 1

I extended the cable retention the entire length of the mount, because for the bottom panel, you will need to secure the cables running to the top panel.

I also switched to regular supports instead of tree supports and allowed them to sit on top of the part, so now there’s even less support material

Update RE: the frame

I have realized that when you bend the panel, the spacing of the mounting holes changes.

The LEDs actually get further apart too.

The net result is, that when you screw the panel to the frame, it ripples, because the holes are too close together.

It’s pretty obvious when you realize it, but I am kind of kicking myself for not realizing sooner.

This kind of explains why I was having so many problems with the dimensional accuracy on refolding the sheet metal part. I knew it was changing the dimensions and was fighting against it, when in reality it was correct. Admittedly, it was getting the values way way out, but still, I got fixated on making sure that the length of the bent front surface matched my panel width of 240mm, when in reality it seems to need to be about 243mm

It’s back to the drawing board for a bit with the CAD - I am taking a two step approach:

  1. Add a multiplier factor variable to expand all the appropriate distances by a given factor
    The down-side of this method is that this value would need to vary depending on bend angle
  2. Work out how to model the whole part so it is automatic

I have iterated through values for (1) - doing a test print each time and found a value where the spacing is good and there is no longer any ripple

Now I have that figure, I will attempt (2), which will be easier at this point because I know what the correct result is and I can compare without having to print.

I am also kind of glad now that I initially bought two panels that turned out to be PWM which I cannot currently use - I am using these for fit tests, so I don’t have to worry about damaging my panels that work :wink:

I have been focussing on the web UI over the last few days.

When in the field, the Pi will be running a WiFi hotspot that my phone can connect to.

I am using Blazor Server, as this allows me to code entirely in C# (The front end is C# with HTML and CSS), and not need to worry about client / server comms - I can just pass C# objects between the back and front end. It also means that actions on the back end can push updates to the front end.

I have also managed to get a really nice dev env set up. I can code in VSCode on my desktop, set breakpoints, hit F5 and it automatically builds the code on my PC, rsyncs it across to the pi, runs the app, and attaches the debugger. Seeing as it’s all Blazor, I can even hit breakpoints in the web UI from within VSCode

So far I have the following pages:

  • Playlist
    Add items, set order, choose how many times they loop or how long they play etc.
  • Quick Media
    Allows configuring of my 4 physical buttons and what they do
    (eg play an item and then resume the playlist where it left off)
  • Library
    Shows all available media that has been imported
  • Import
    At the moment, I have not implemented upload - you just SFTP into the Pi and dump files into the incoming folder. You can then click Import, and it will convert it into a stream and put it into the library

chrome_I53C5XiUyi

I have also migrated to the C# bindings (using the version from the PR I made) rather than just running the led-image-viewer binary.

That way, I can re-use the matrix and canvas objects, and it’s a LOT more reponsive and way less glitchy.

Oh, and I settled on a name for the software

WearWare

I am back from spending some time with my family.

My aunt customized a t-shirt for me - the screen sits inside the shirt.

As it’s curved and inside the shirt, it blends in with my body pretty damned well

On the code side, I have pretty much completed a first pass of the UI - all MVP functionality is in place.

Still no real error handling though, which I think is gonna be quite the task.

I also have implemented a mock version that runs completely locally on my PC - it creates an extra page on the web server with buttons to click which simulate pressing of the GPIO buttons. What the screen would be playing is logged out to the console.

In this way, I can work on business logic and UI without the need to be running it on the Pi

Today I started work on the battery pack

I will be using 21700 5000mAh cells, and will probably need 6 (3S2P) or 8 (4S2P) of them.

I have some of these holders for the batteries

I am planning on having a number of segments clipped to my belt, with 2 batteries in parallel in each segment. There will be one head segment with an XT60E-F socket on it to output power:

Then I will need one tail segment with one end capped off, and 1 or 2 middle segments with a pass-through at each end.

Here is a model of what I have so far - this is a middle section. The green part will be printed in flexible TPU and joins one segment to the next, so the whole chain of segments can flex.

Fusion360_v2FUciTzeN

I may end up getting rid of the wires running down the middle - these are balance wires (For charging on a balance charger, or monitoring per-cell voltage), but I don’t think I need them as I have an 8 port 21700 charger, so I could just slide the clip off, remove the lid, and charge the cells in that.

Over the last few days I have been concentrating on the case for the Pi

I have managed to cram everything in to a relatively small space

On the right is power input. There’s an XT60 male at the back, and a button with an LED (Made of veroboard) at the front. ATX-like startup and shutdown (Press the button, the LED pulses until it shuts down, then LED goes out) is provided by a Petrockblock powerblock (Red component on the right).

On the left is the Pi Zero / Electrodragon active-3 driver board - both are mounted upside-down.
This allows me to have easy access to the Pi and SD card.

The light blue part is a header - it traps the mini-HDMI to HDMI adapter in place so it can’t wobble or come out, and also holds a panel-mount microSD socket.

At the front, there is a slot at the bottom is for the two ribbon cables, and an XT60 female on the right which provides power to the LED panels.

At the back are two more buttons to trigger quick media. Again, these are made of veroboard, sandwidched between two plates to allow easy mounting from the outside.

Unfortunately, I have had to go down to only two buttons, as GPIO 2 and 3 default to high and are causing problems. I may figure it out at some point, but two will do for now.

On the underside, I have belt clips

Here’s a section view - the 5A 7v BEC will be sitting underneat the Electrodragon board.

Here is a pic of a test print of the power section. As you can see, I have used JST-SM (One of the few connectors with male and female wire terminated connectors with clips) to join everything together for easy maintenance and disassembling. I need to shorten and tidy up the wires - everything is extra long at the moment for convenience

Got it all assembled and working.

At least one element of the project is now basically complete.

I did a rough estimate the other day - I think I have spent about 200 hours on the project so far…

I have implemented a Matrix Options system

It has DDLs for things which have limited options available (Along with names for them, so you don’t have to remember which number means what), and numeric inputs for things which are numbers etc.

There is a main options page where you can set all options - these serve as a default for your system

chrome_NROGgJM9Pk

On that main page is a checkbox to the left of each option. If it is checked, then only those options will appear on any page that lets you convert a stream.

In this way, you can avoid having a big long list of options when you go to convert a file to a stream, and only have the options listed that you regularly change for a given animation

chrome_69WFQNxxKb

If you set an option’s value on the global page, when you go into a page for stream conversion, you can override that value without changing affecting your global options. You can either type in a new value, or, if your global setting has overridden it from the library defaults, you can just delete the value, and it will apply the library default

Also note how it shows you the command-line args that would be generated for stream conversion using the options that you chose. If the option is library default, it removes it from the command-line

chrome_Gk0hEgVoOV

And of course, there’s form validation

chrome_aIZoDcyhBS

There’s also numerous layers of re-conversion.

When you first import from the incoming folder, it converts it with the specified options and puts the stream into the library.

You can then add any number of playlists, and if you add that item to a playlist, it will keep the options you used on import, but it also keeps it’s own copy of the original GIF. You can then re-convert the instance in that playlist independently of the library version - so eg you could have a “dim” or “bright” playlist for indoor/night-time or outdoor/day-time, but you would not need to keep separate dim/bright versions in the library.

You can also re-convert the version in the library to set a new default for that animation, and it won’t affect the instances in your playlists

It also seems perfectly happy re-converting a file while it is playing. I set up a playlist with only one file, and duration of that animation of 1s (So it’s reloading it from disk every 1s), and then re-converted it - it was perfectly happy, and playback did not seem to stutter at all. I had htop running and it looks like it just uses another core

Been spending most of my time working on the PR for the library lately, but in the background I have been getting the battery pack sorted.

I did a battery life test today - I used 6x 21700 50,000mAh cells in a 3S2P configuration, set up my typical animation set and let it run for 8 hours. It’s down to 3.5v / cell - well within the safe zone for this kind of cell. I’m, one happy bunny!

Today I finally assembled the whole thing for the first time in it’s final (Yeah right, who am I kidding) state.

I got some low profile IDC connectors - these are not as tall, as they lack strain relief, so I added some glue lined heat shrink to the ends of the cables (You can see “1” and “2” written on it).

The power connectors were too tall, so I chopped the plug off, trimmed the pins down and direct soldered plugs to the pins.

Then a whole bunch of cable management to make it all sit nice and flat

I designed a new style of battery pack that puts all 6 batteries in one box, and curves it to make it conform to my body more

Fusion360_85tOWvzLFG

End result:

The t-shirt hangs a bit, mainly due to the weight of the panel. It could sit a lot more flush with the body. I may have to get some straps and strap it to my chest

I am going to an event this Sat, am planning on wearing it. I am pretty terrified that it’s all going to crash and burn though

Oh, and I put the source code on GitHub

It’s the big night tonight, and I made a few last improvements.
Turning brightness down to 75% (Probably needed it anyway, was too bright), it saves a ton of power. I was able to go from 6 batteries to 4.

I also did a new battery pack design - this one features integrated voltage checkers, and a balance lead connection, so I can charge the batteries inside the case. It has a button to activate the voltage checkers, so it’s not draining power all the time.

I bevelled the edge of the frame, so the corners do not stick out so much, and added a strap loop at the top so I can support the weight with a strap around my kneck, making the t-shirt sag less, and giving me extra security in case the velcro comes loose

The end result looks a lot better IMHO