KISS Tindies: A Wire Form Practice Project

After I built a very simple copper wire body for a Tindie blinky, I wanted to advance my copper wire forming technique with practice making something a little more complex. Looking on my workbench of stuff, the most obvious candidate for a follow-up project are the KISS Tindies given out at Hackaday Superconference 2018. They were the demonstration objects in a workshop on pad printing – people were invited to apply red to these circuit boards and take them home. Not everyone took theirs home, so extras were distributed to other interested Supercon attendees like myself.

KISS Tindies

So I could create some copper wire bodies for the band. It wouldn’t make sense to give the same dog bodies to these heads – these call for some stylized human-like poses. I thought I would have to dig deep into my meager artistic skills to draw a guitar-playing puppy, but it turns out art already existed for these heads. (It’s possible these PCB heads were actually made from the art – I don’t have the history here.)

KISS Tindies reference art

Unlike the puppy, though, there wasn’t an obvious way for me to separate these shapes into a “front” and “back” for the two voltage planes. I thought I might try to make fully three-dimensional bodies but a few tests indicate I don’t yet have enough skills as a copper wire sculptor to pull it off.

Scaling my ambitions back down to match my current skill level means the next project will take a slight step backwards in functionality: they will be flat figures, and the body won’t be a functioning circuit. The focus of this exercise is to practice wire forming on a flat plane.

(Cross-posted to Hackaday.io)

Onshape is Free For Makers, But They’re Less Eager To Say So Now

onshape_logo_mediumWhen I first discovered Onshape over two years ago, it was a novelty to see a capable CAD system run completely within my web browser. The technologies that made Onshape possible were still evolving at the time: on the client-side, web browsers had immature WebGL implementation that sometimes didn’t work, or worked unacceptably slowly. And on the server side, Onshape is an active participant in evolving AWS to work for them.

Now WebGL is a mature part of every popular web browser, including those at the heart of inexpensive Chromebooks. I’m old enough that the phrase “CAD Workstation” conjured up computer systems that cost as much as a car. With Onshape, a Chromebook can be a CAD workstation! Not a great one to be sure, but more than enough for curious learners to get started. (This page has more details on Onshape performance.)

This is why, when I started Sawppy the Rover, I switched from Fusion 360 to Onshape. Because I wanted Sawppy to be accessible to everyone, not just those who have a computer capable of Fusion 360. And I have continued to do so, not realizing another aspect of Onshape evolution had occurred.

This came up on my radar because of my super simple wire straightener project. I’ve shared simple tools before, but this one caught more attention than most thanks to a referral from Twitter (and another). I was surprised to see feedback in the theme of “I don’t have an Onshape account” and was surprised people felt it was a barrier.

When I first started using Onshape, their sign-on screen would direct people to a page where people could sign up for an account. On this screen, a free plan for makers and hobbyists was prominently displayed.

That has been removed, hence the confusion.

The free plan still exists, but it’s no longer on their “CAD Pricing” table and not mentioned in their “How to Compare Onshape Plans” guide. From the FAQ I inferred that it’s not even possible to sign up for a free plan directly, one would have to start a trial for the Professional plan, decline to pay, and be downgraded to the free plan. (I can’t test this hypothesis myself since I already have an established account on the free plan.)

I personally find this disappointing, but I’m not surprised. Onshape is a business and businesses have to be profitable or they’ll disappear. I’m a little afraid this might mean they’re working to phase out the free plan, but even in that case I hope they offer a subscription tier that’s priced reasonably for hobbyists on tight budgets.

LEGO 41611: BrickHeadz Marty McFly and Doc Brown

Today will be a little holiday break from the usual fare… it’s time to play with LEGO bricks!

I count Back to the Future as one of my favorite movie series, a fact known to most of my friends. So it’s no surprise that I had been gifted a Back to the Future themed LEGO set. Kit #41611 from their “BrickHeadz” line of caricature figurines represented our stars Doc Brown and Marty McFly. This is my first BrickHeadz set and I was very curious to see how they would come together.

Our heroes are depicted as they were at the beginning of the first movie, when Doc demonstrated time machine operation for the first time in the parking lot of Puente Hills Twin Pines Mall. Marty is in his puffy 1985 jacket holding a VHS camcorder, and Doc is wearing his white lab coat with radiation symbol on the back and holding the car’s remote control.

These kits minimize appearance of LEGO studs, using a lot of smooth pieces to create the desired appearance. This is especially apparent in the face and hair. Marty had many smoothly curved pieces, whereas Doc had a much more random jumble of pieces to represent his wild Einstein-like hair.

When I poured all the pieces out on the table, I wondered about a few pieces that were brightly colored in a way that did not match the color theme of the character. As I followed instructions, I learned these pieces would not be visible when properly assembled. Hence these oddly colored pieces were designed to be a visual indication if assembly should go wrong. Here’s a partially complete Marty, the bright pink and bright green pieces sit inside the body and head, invisible when properly assembled.

LEGO 41611 1 partial Marty

Once Marty was complete, it was time for Doc. Again, the bright pink, yellow, and green pieces would not be visible when properly assembled.

LEGO 41611 2 Marty done time for Doc

And here is Doc and Marty, ready for their adventures through time. It’s very generous of LEGO to give a few extra small pieces that are easy to lose. Assembling both of them consumed approximately 30-45 minutes, and I enjoyed every minute of it.

LEGO 41611 3 Doc and Marty

 

A Copper Wire Body For Tindie

With the wire spool ready to go, it’s time to tackle a simple starter learning project. For the subject I turned to the simple Tindie blinky badge. The badge itself is a soldering exercise, and now it will also serve as a freeform circuit exercise: I will give the Tindie puppy a copper wire body!

Tindie copper body 4 with tail

There will be two loops of wire, one will be electrically connected to battery positive, other loop will be connected to battery negative. There are two existing positions for LEDs on the badge, and I will be adding a third LED to give Tindie puppy a flashy tail. Each LED will bridge the two loops of wire for power.

The Tindie logo was printed up, scaled so printed head matches circuit board size. Then I start tracing out curves as nominees for positive and negative loops.

Tindie copper body 1 planning

Once I had a plan, three segments of wire formed the positive loop, which has Tindie’s two left legs and most of the body.

Tindie copper body 2 front

The negative loop has Tindie’s two right legs and some duplication of body curvature. I had to make sure it reached back far enough for the tail LED to get power. The two loops also formed a battery holder between them. It was important for the battery to be in the body if I wanted Tindie to sit on paws, because if I used the default battery holder in the head our puppy would topple over from being too top-heavy. And the natural place to put a battery in the body is in the chest, as heart of the machine.

Tindie copper body 3 front and back

Some soldering work later, Tindie is standing on paws of a shiny copper wire body, complete with blinky tail. Since the two loops of wire are only held together by leads of the three blinking LEDs, it is rather fragile. For future projects I need to find additional ways to brace positive and negative loops without short circuiting them. Either more electronic components or non-conductive structure.

(Cross-posted to Hackaday.io)

Copper Wire Spool Holder With Straightener

Now that I’m warmed up to make circuit sculptures, it’s time for more practice. And for that practice, I’ll need wire and lots of it. Most of the projects I’ve seen are built from straight rods of brass that I could procure from the local hobby shop. However, I personally prefer the color of copper (though it will suffer from oxidation) and I can get copper wire fairly inexpensively in a large spool. But of course, that wire would need straightening.

Thus the next project: A holder for a spool of wire that includes a straightener. For reference on straightener, I looked at CNC wire bending machines of both the DIY variety and an industrial offering, both of which featured similar wire straightening mechanisms. Then I tried to replicate my own using my stock of cheap 608 bearings and metal 8mm shafts left from my Sawppy rover project.

Version 1 was a very simple base that laid out the five shafts in the arrangement I wanted. I neglected to consider wire behavior so they ended up getting caught under the bearing.

Wire straightener 1

Version 2 addressed that issue by raising its working surface so wire would not get under bearings. However, a 3D printer has problem holding precise tolerances and so shaft holes had to be drilled out before the shafts would fit. This changed position enough that final bearing spacing didn’t work well.

Wire straightener 2

Version 3 attempted to eliminate variability of shaft position by eliminating the shafts entirely – have bearings sit on 3D-printed posts. Unfortunately position errors were even worse!

Wire straightener 3

After stopping and thinking about the problem, I thought perhaps I’m over-complicating the device. As an introduction, I’m only dealing with 18 AWG wire. This is fairly easy to bend so perhaps I don’t even need bearings – simple shapes might be enough. Hence version 4 replicated the round (but not rolling) surfaces in a wave.

Wire straightener 4

Version 5 tried to improve by having a second stage with different spacing. This is an improvement. A mild one, but an improvement nonetheless.

Wire straightener 5

Version 6 integrated version 5 into a spool holder.

Wire straightener 6

Since I’m not using bearings, friction is quite high. It would not be acceptable if I were trying to build a CNC wire bending machine (a potential future project) but for manual use it’ll do for now. Using a pair of pliers, I can grab and pull on the end to give me wire straight enough for the next few projects.

Onshape CAD file is publicly available here. Adjust dimensions to fit your 3D printer’s characteristics, then export to STL for printing.

UPDATE: Onshape has a free subscription tier for makers, even though it isn’t as prominently advertised as it used to be.

(This page has also been posted to Hackaday.io)

Freeform Fun with Salvaged SMD LEDs

There’s a freeform circuit contest going on at Hackaday right now. I’m not eligible to enter, but I can still have fun on my own. I haven’t had any experience creating freeform circuit sculptures and now is as good as time as any to play around for a bit.

Where should I start? The sensible thing is to start simple with a few large through-hole light-emitting diodes (LEDs), but I didn’t do that. I decided to start higher up on the difficulty scale because of a few other events. The first is that I learned to salvage surface mount devices (SMD) from circuit boards with a cheap hot air gun originally designed for paint stripping. I had pulled a few SMD LEDs from a retired landline telephone and they were sitting in a jar.

The second is the arrival of a fine soldering iron tip (*). I had ordered it in anticipation for trying to repair a damaged ESP32 module. I thought I should practice using these new tips on something expendable before tackling an actual project, and a freeform exercise with salvaged SMD LED seems like a great opportunity to do so.

As a beginner at free form soldering, and a beginner at SMD soldering, the results were predictably terrible. I will win no prizes for fine workmanship here! But everyone has to start somewhere, and there will be many opportunities for practice in the future.

7 survivors light

It’s just a simple circuit with seven LEDs in parallel, on the lead of their shared current-limiting resistor. Not visible here is another aspect of learning to work with surface mount components: they are really, really small. I had actually salvaged nine LEDs. Two of the nine LEDs have flown off somewhere in my workshop and didn’t make it to the final product.

9 salvaged LEDs

For comparison, here is the “I ❤ SMD” soldering kit that was my gentle introduction to surface mount soldering. The LED in that soldering kit were significantly larger and easier to manipulate than those I salvaged from an obsolete landline telephone.

SMD intro size comparison

Moral of the story: for future projects practicing SMD assembly, be sure to have spare components on hand to replace those that fly off into space.


(*) Disclosure: As an Amazon Associate I earn from qualifying purchases.

Royal Purple Lissajous CRT

I brought my laser Lissajous curve machine (that degraded into a not-Lessajous curve machine) to our SGVTech meet, but it was not the only one there. [Emily] brought her salvaged CRT that she intends to turn into a Lissajous machine as well. Since I had brought my amplifier with me for my machine, it was easy to disconnect my contraption and connect to hers instead. Now, the stereo amp will be driving the CRT’s horizontal and vertical deflection coils instead of speakers. Unlike the last time we hooked this amp up to a CRT in this manner, we now have LRWave to control left and right audio channels independently.

Violet Lissajous back

This CRT was originally a black and white unit. To add some visual interest, [Emily] has coated it with Krylon Royal Purple Stained Glass Paint. I think the change is subtle but effective at communicating this is something special.

Another change for this experiment: we’ve switched platforms from Android to running LRWave on an old MacBook Pro. We’ve had recurring problems with random pops and crackles in output waveform, and since it’s a problem shared with the native signal generation app across three different Android devices, I suspect the root cause is somewhere within Android OS. Hence switching to MacOS as a change of pace to see if it also has the cracks and pops heard when running on LRWave. Or in the case of a CRT, seen on-screen as a sporadic scrambling of the curve. The switch was a good move. We had no unexpected noises for the rest of the night.

Violet Lissajous front

We got some very pretty curves, far better than what I got out of my laser LED and speaker apparatus. And unlike the speakers, a CRT deflection coil does not degrade as we send different wave forms through it. We had smooth curves throughout the entire test session, it did not degrade into squiggly abstract modern art.

Violet Lissajous closeup

Observations from the night:

  • LRWave can generate a more consistent signal running on MacOS than on Android.
  • Laser + mirrors + speakers are indeed accessible at lower cost and lower voltage, but speakers suffer damage when forced to reproduce arbitrary wave forms. Further evolution of my idea would require finding a different actuator to replace speakers.
  • CRTs can produce beautiful Lissajous curves, far smoother than any pixel-based flat panel display can. Furthermore, their deflection coils seem to suffer no damage from arbitrary wave forms pushed through them.
  • When a salvaged raster CRT like this unit is run at low speeds, there is a visible gap in the line that [Emily] credits to the beam occasionally cutting out for vertical blanking interval. Its effect can be mitigated by running at high speeds, or be used as intentional visual effect at low speeds.

[Emily] plans to spray a matte coating to reduce distracting reflections. I look forward to future progress on this project.

Laser Lissajous at SGVTech

The main reason I wanted a less delicate and more portable form for my laser Lissajous project is that I wanted to bring it to show-and-tell at SGVTech meetup. I got it printed and assembled a half our before the meet. I verified it could make a basic Lissajous curve and then it was time to go.

It was an interesting piece of novelty for show-and-tell. The laser was difficult to see against the ceiling of the space, so I ended up tilting the contraption on its side so the laser is projected sideways onto a taped-up sheet of white paper serving as screen.

I started the night with sine waves that produced decent Lissajous curves. Then we started playing around. LRWave allowed us to feed different wave forms in – triangular, sawtooth, and square waves. Each produced their own wild patterns, but after a while we noticed some changes in the system. Reverting back to sine waves no longer reverted to soothing sounds and smooth curves. Looking over the apparatus, we found that a speaker has rattled itself loose. Tightening fasteners back down did get us some of the curvature back, but could not eliminate all the extraneous vibrations affecting the curve. Something else is degrading. Either the hot glue holding mirrors to the speaker, or the coil inside the speakers.

By the end of the night, between all the potential variables of speaker degradation, glue adhesion failure, mirror flex, and extraneous vibration in the system, the laser curves stopped being Lissajous curves and started becoming wild abstract modern art. It had come full circle: I started this with a 3D-printed stand that was a tribute to Frank Gehry. By the end of the night, the laser projection started resembling Frank Gehry sketches.

Decayed Lissajous laser curve

3D-Printed Laser Lissjous Apparatus

Copper wires and helping hands are fine for my laser Lissajous rough draft, but it’s fragile and nearly impossible to take elsewhere. It’s time to design and 3D-print a more rigid and portable version of my cheap & cheery laser light show.

The fundamental task is not difficult: note the final arrangement of components in my rough draft, put them into Onshape, and create a housing for those parts with the help of Onshape in-context modeling. However, the geometry requirements of mirror and laser placement resulted in quite an awkward layout of components involved.

I looked at component layout in 3D space inside Onshape and spent a few hours trying to find a good way to package them all together. After a few fruitless hours trying to create something that I find pleasing to my existing sense of aesthetics, I decided to take this opportunity and go in a different direction instead: I’m going to channel my inner Frank Gehry for packaging these components.

Lissajous bracket 2 wireframe

This is my take on a wild asymmetric shape that still serves all the requirements of the project, much as how Gehry architecture have many features that seem wild at first glance. Their jarring exterior masks the fact it still creates the interior volume and structural support necessary for the building. For me, this was a fun way to experiment with contour and curvature tools available in Onshape and difficult to represent in OpenSCAD.

Lissajous bracket 2

When assembled, my apparatus can create fairly decent Lissajous curves. Not as nice as those [Emily] and I created on a CRT, but a lot more easily reproducible by anyone with access to a laser pointer, a pair of speakers, and some mirrors. It also allows me to take it around for show-and-tell with other makers.

Helping Hands For Laser Lissajous Rough Draft

With small plastic mirrors now installed on salvaged laptop speakers, it’s time to put them to work. With their far smaller size, I could place the mirrors much closer together. This is important because if they were too far, beam deflected from the first mirror would spread out in a wider arc than that the size of the second mirror. This was a problem with the initial proof of concept rig, especially when I explored maximum deflection which ended up burning up a speaker. Now, these compact speakers allow mirrors to be only about 15mm apart.

These speakers were again powered by the same thrift-store stereo amp, but keeping in mind the lessons from the last round, I’m more careful about the amp’s output volume. The next challenge was to find ways to hold all the components involved as I experiment with direction, angle, and orientation. Since I only had two hands and there were three components (two speakers and a laser) I needed to summon help.

The laser was taped to a stiff strand of copper wire which I could bend at will to aim the laser. For the speakers, I had two sets of helping hands which typically help me solder electronics together but today they are mirror holders. Their alligator clips hold nice and strong to mounting brackets formerly used to secure these speakers inside a laptop chassis. Together they helped me determine an arrangement that would produce the results I sought. Now I could take what I’ve learned and make it more permanent with a 3D-printed chassis.

Dell Inpsiron speaker Lissajous first draft with helping hands

Installing Mirrors On Laptop Speakers

I set out to use mirrors attached to speakers to deflect a laser beam into Lissajous figures. After I’ve destroyed (and taken apart) a speaker to prove the concept worked, I need replacement speakers to move forward. Searching through my parts bin for replacement speakers, I found another pair salvaged off an obsolete Dell Inspiron 6400 laptop. Given the track record so far, I do not expect these speakers to last long, but the journey should be fun.

Dell Inspiron 15 speakers

The proof of concept used blue painter’s tape. This time I’m going for a little more permanence with mirrors hot-glued to the speaker surface. Since these speakers are tiny, I need to cut my stock of plastic mirrors down to size. The first cut using scissors immediately signaled no-go: the plastic is brittle sending cracks along the cut.

Plastic mirrors too brittle cracks when cut

So instead of cutting with scissors, we’ll cut a shallow groove into the surface with a knife, then applying pressure with a pair of pliers to make it break along the groove. This technique also works for real glass mirrors as well, but glass would require a diamond-tipped cutter to form the groove and probably something other than pliers to apply force.

Plastic mirror score and break

I broke the plastic mirror into little octagons, which are close enough to a circle for today’s fabrication exercise. Trying to attach them, though, found another problem with plastic mirrors: heat deformation. I put some hot glue directly on the back of my first octagon mirror, and watched it deform from heat. Oops.

Plastic mirror damaged by heat

I switched to putting glue on the speaker first, then waiting a few seconds for the glue to cool. Before the glue solidifies, I apply the mirror. Success! I now have two small speakers with small plastic mirrors attached to them. Next up: lasers.

Mirrors installed on Dell Inspiron 15 speakers

Burnt Speaker Teardown

There was a casualty of my laser+speaker Lissajous proof of concept: while exploring the limits of how far I could push a speaker, I went too far and burned one up. It was an unfortunate but expected part of playing with using components outside of their designed purposes. And now the dead speaker has one final role to play: as a dissection subject so we can see what’s inside. This is a irreversibly destructive process because speakers are not built to be disassembled and repaired. Once I plunged the blade into the speaker surround, I am committed.

Cut speaker surround

Once the surround was cut, I could access and cut the suspension underneath. After they were both cut I could lift the cone. Several problems were immediately visible. The voice coil that should have been attached to the bottom of the cone has separated, leaving a ring of charred material and a single thin strand of magnet wire. Emphasis on single: there should have been two wires for the coil! Also, lifting the cone released a strong odor of burnt insulation.

Speaker cone lifted

Since that thin strand of magnet wire is our only connection to the voice coil carcass still buried within its narrow slot, the only thing to do is to tug on it (gently) to unwind the coil. As wires were pulled, they occasionally brought up flakes of burnt speaker with them. Eventually, enough of the obstacles were removed that the charred remains of the voice coil could be recovered. It’s a pretty sorry sight and a fitting company to the smell.

Speaker voice coil recovered

I originally had the ambition of creating my own voice coil actuator out of the damaged chassis, by winding magnet wire around a 3D-printed replacement cone. But that’s before I saw how narrow the slot was. I could not make anything to fit in that slot, so the re-purposing plan was abandoned. We’ll just keep the big chunk of magnet because magnets are always fun. (Keep away from credit cards, though.)

The magnet assembly was held on to the speaker chassis by four big rivet-like structures. A drill press was summoned to remove the bulk of the metal. It was novel to see metal shavings align themselves to the magnetic field.

Speaker on drill press

After the majority of the rivet were removed, the chassis was placed in a vice and the magnet assembly was pried loose from the chassis.

Speaker magnet pried loose

This still left four protrusions to cut flush, and the tedious task of cleanup – the metal chips really wanted to stay with the magnet! But by the end of the night I have a hefty speaker magnet assembly.

Laser+Speaker Lissajous Proof of Concept

With LRWave 1.0 complete, I could focus on the mechanical bits of a Lissajous machine driven by that web app. The goal is to build a more accessible Lissajous machine that does not have the risk presented by high voltages involved in driving a CRT. It will not look as good as a CRT, but that’s the tradeoff:

  • High voltage electron beam in a CRT replaced by far lower voltage LED laser diode.
  • CRT deflection yokes replaced by audio speakers.

The proof of concept rig is driven by the same thrift store amplifier used in the successful CRT Lissajous curve demo. This time it will be driving speakers, which is what it was designed for, instead of CRT deflection yokes. The speakers came from the same source as that CRT: a Sony KP-53S35 rear projection television we took apart for parts so we could embark on projects like this.

Hypothesis: If we attach a mirror to a speaker, then point a laser beam at that mirror, the reflected beam will be displaced by the movement of that speaker. By using two speakers and adjusting beam path through them, we can direct a laser beam among two orthogonal axis X and Y via stereo audio waveform generated by LRWave.

For the initial test, mirrors were taped directly on speaker cones and arranged so laser beam is projected to the ceiling. This produced a satisfactory Lissajous curve. Then the mirror configuration were changed to test another hypothesis: instead of direct attachment to speaker cone, tape the mirror so it sits between the fixed speaker frame and the moving speaker cone. This was expected to provide greater beam deflection, which it did in the pictured test rig. However, the resulting Lissajous curves were distorted due to flex by the plastic mirrors and not-very-secure tape.

RPTV Speakers and masking tape

Experimenting with maximum deflection range, I pushed the speakers too far and burned one up. For a brief few seconds the laser beams were visible, reflected by the smoke of an overloaded speaker coil.

  1. I could see the laser beams, cool!
  2. Um… why am I able to see the laser beams?
  3. [sniff sniff]
  4. Oh no, the magic smoke is escaping!

The Lissajous curve collapsed into a flat line as one deflection axis stopped deflecting, and that ended experimentation for the day.

LRWave 1.0 Complete

The (mostly cosmetic) fine tuning have been done and the LRWave web app is sitting at a good state to declare version 1.0 complete. Now I can move onward to the hardware components of my laser Lissajous project.

LRWaveV1.0

Some tidbits worthy of note are:

  • MDC Web theme colors can be applied via CSS styles as per documentation. What’s (currently) missing from the documentation is the requirement I also have to add @import "@material/theme/mdc-theme"; to my style sheet. In the absence of that import directive, the theme CSS styles have no effect, causing me to bang my forehead against a non-respnsive brick wall. Now the following visual elements finally worked as designed:
    • App has a dark background, because I’m building this for a laser Lissajous curve project and I expect to use this app mostly in the dark.
    • The column titles “Left” and “Right” now has theme colors.
    • The waveform drop-down box options are now visible and not white-on-white. (Change is not visible in screenshot.)
  • Web Audio API implementation in Chrome would cause audible pops when pausing or resuming playback. This is true even if I write code to fade volume. (Fade out to zero upon pause, fade in from zero upon resume.) Since this fade code added complexity to my app but failing to eliminate the audible pops, I did not commit fade code to my app.
  • The browser tab favicon now works… I am not sure why but next item might be related:
  • I’ve added an instance of the icon to my app’s background. Now there’s a little app icon at top center of app background. Perhaps this change helped kicked the browser favicon code into action?
  • Responsive layout is much improved – the app was always fine in portrait mode in a compact phone resolution, but now it no longer looks embarrassing on larger displays.
  • Added support for Safari browser. (Safari uses webkitAudioContext while other browsers use AudioContext.)
  • Wrote up a README.md for the project.

The whole project was done via Cloud 9 IDE. My AWS cost for this experiment was a grand total of $0.43.

LRWave EC2 Cost

Github project: https://github.com/Roger-random/lrwave

Published live version: https://roger-random.github.io/lrwave/

LRWave Core Functions Complete

After a few hours of JavaScript coding, all the core functionality I set out to implement is running. At least, at a basic level. (This link will go to the live version of LRWave, which should continue to improve as I learn.)

  • Two-channel (left and right) function generator
  • Frequency adjustment
    • User can type in anything from 0 to 24 kHz
    • Buttons to adjust frequency up/down in 1Hz steps.
  • Waveform selection available in Web Audio API
    • Sine
    • Square
    • Sawtooth
    • Triangle
  • Gain adjustment
    • User can type in anything from 0% to 100%
  • Play/pause button.

LRWave on Nexus 5

Since I hate web pages that start playing some sound upon load without user interaction, I don’t start playing sound until the user has pushed the play button. It turns out I have accidentally followed the guidance from Google, which will not allow pages using Web Audio API to play sound before user input. I don’t always agree with Google, but I’m glad we’re aligned here.

The JavaScript portion of this project have been relatively easy. I found Web Audio API to be straightforward to use in my simple little function generation app. There are some refinements to be made: there are audible pops as settings are updated. Right now I perform those updates immediately, but they should ramp from old to new value in order to avoid abrupt changes. Everything else dealing with user interface are standard event handler code.

What I found challenging is the aesthetics side of things. Proper HTML layout is still a struggle for me, but I know projects like this will eventual lead to mastery (or at least competence) with responsive web layout. In the meantime, my app looks fine on a phone in portrait orientation but things start to get weird quickly as browser window size grows.

Individual components in MDC Web have worked well so far, with the exception of the slider control. I tried to use it for gain but it didn’t behave as I expected so, after a half an hour scratching my head, I set it aside for later. Another difficulty was MDC theming. I wanted the background to be black and I haven’t found my mistake when trying to do it within MDC theming module.

On the web browser interaction side, I designed an icon and added a reference in the header. Google Chrome recognizes it enough to use the icon on the recently opened sites window, but it doesn’t use the icon on the browser tab and I don’t understand why.

Lots of learning so far, but more learning plus refinement ahead…

Building A MDC Web App With Only The Parts I Need

Material Design logoOne criticism of using Materialize CSS is that we were pulling down the entire library and all of its resources for our project, whether we are using them or not. Aside from the obvious inefficient use of bandwidth, it also presented a challenge when we wanted SGVHAK Rover to be usable independently without an internet connection. This meant we had to make a copy of the entire library in our project to serve locally.

To avoid this problem, MDC Web (Material Design Components for Web) is designed so projects could pull in features piecemeal. Now each web app only has to download the parts they needed. The reason this isn’t typically done is because of another inefficiency: there is overhead per HTTP transaction so we can’t have MDC web components come down in tiny little individual pieces – the overhead would easily wipe out any space savings.

To avoid that problem, MDC Web uses webpack to bundle all the individual pieces into a consolidated file that only requires a single HTTP download transaction. So instead of a HTML file demanding tens to hundreds of individual CSS and JavaScript files, we have a single HTML file, that loads a single bundled CSS file, and a single bundled JavaScript file. These bundles are standalone pieces that can be served by any web server independent of MDC Web webpack infrastructure. Maybe even copied to a rover.

I was looking forward to this functionality and was happy to see it was covered in Section 5 of the Getting Started guide. After putting in the configuration required, it was a matter of typing npm run build to generate my compact representation. I copied the generated bundle.css and bundle.js files and my index.html to a separate directory for the next test.

When I served up my Getting Started project via the development server npm start, Chrome developer console showed that the simple button required downloading 462KB of support files. That’s roughly the same order of magnitude as what it would take to download Materialize and all supporting information, and I was eager to see improvement.

I then went to the separate directory with the built bundles. To ensure that I’m indeed free from npm and webpack, I served these bundle files using an entirely different infrastructure: Python 3’s development web server. The environment variables $PORT and $IP were already set for a Cloud 9 environment and were reused:

python3 -m http.server $PORT --bind $IP

In the browser developer console, I could see that these files – and only these files – were downloaded. They added up to 32KB which was larger than I had hoped for in such a simple example, but maybe there’s room for further optimization. In any case, that’s definitely a tremendous improvement over 462KB.

Using Cloud 9 To Explore Web Development

I’ve started going through the Getting Started guide for Google’s Material Design Components for Web (MDC Web). This is a prerequisite for Material tutorials and I’ve already run into one problem traced to an out-of-date installation of Node.js. Given that I’m learning a new piece of software, I’m sure I’ll run into more problems that require modifying my computer. As mistakes are likely due to my learning status, I’m wary of potentially messing up my main Ubuntu environment.

What I need right now is an enclosed sandbox for experimentation, and I’ve already set up virtual machines I could use for this purpose. But since this is a web-based project, I decided to go all-in on the web world and try doing it online with a web-based development environment: Cloud 9.

Cloud 9 logo colorI’ve played with Cloud 9 before, back when it was a startup with big dreams. It has since been acquired by Amazon and folded into the wide portfolio of Amazone Web Services (AWS). As far as I knew Cloud 9 has always run on AWS behind the scenes, but now a user is exposed to the underlying mechanisms. It means we now have better control over the virtual machines we’re running, which is mostly good. It also means users have to pay for those virtual machine resources, which is fairly inexpensive (I expect to pay less than $1 for this experiment) but isn’t as good as the “Free” it used to be. The saddest part is that it’s no longer “point-click-go” simple to get started. Getting Cloud 9 properly setup means climbing the learning curve for managing AWS security and permissions, which can be substantial.

Access Permissions

AWS has an entire document focused on authorization and access control for Cloud 9. For someone like myself, who just want to play with Cloud 9 but also want to safely partition it off from the rest of my AWS account, the easiest thing to do is to create a new user account within my AWS dashboard. This account can be assigned a predefined access policy called AWSCloud9User, and that’ll be enough to get started. When logged in to this dedicated account I can be confident mistakes won’t accidentally damage anything else I have in AWS.

Network Permissions

With the power of fine-grained virtual machine control comes the responsibility of configuring it to act the way we want. When I last used Cloud 9, launching a piece of web hosting software on my VM meant it was immediately accessible from the internet. That meant I could bring it up on another browser window at my desk to see how it looks. However, this is no longer the default behavior.

When running my VM in the form of an Amazon EC2 instance like now, it has its own network firewall settings to deal with. Not only that, the VM is in its own private network (Amazon VPC) which has its own network firewall settings. Both of these firewalls must be configured to allow external access if I’m to host web content (as when exploring MDC Web) and wish to see it on my own machine.

There’s a lot of documentation online for using Cloud 9. The specific configuration settings that need to be changed are found under “Previewing Running Applications” in section “Share a Running Application over the Internet

First Step In Material Design Adventure Foiled By Ubuntu’s Default Old NodeJS

With the decision to tackle a new web-based software project, the next decision is what web-based UI framework to build the app in. My last web-based software project was to build an UI for SGVHAK rover at the beginning of the year. In the fast-paced world of front-end web development, that’s ancient history.

The rover UI project used Materialize CSS library to create an interface that follows Google’s Material Design guidelines. At the time, Google offered web developers a library called “Material Design Lite” but with the caveat they’re revamping the entire web development experience. There was little point in climbing the learning curve for a deprecated library like MDL. As Materialize CSS was close to using Bootstrap, a known quantity, the choice was appropriate for the situation.

Now, at the end of the year, we have Google’s promised revamp in the form of Material Design Components for Web. I am still a fan of Material so my signal generator utility project LRWave will be my learning project to use Google’s new library.

Diving right into the Getting Started Guide during a local coding meetup, I got as far as the end of “Step 1” executing npm start when I ran into my first error :

ERROR in ./app.scss
    Module build failed: SyntaxError: Unexpected token {
        at exports.runInThisContext (vm.js:53:16)
        at Module._compile (module.js:374:25)
        at Object.Module._extensions..js (module.js:417:10)
        at Module.load (module.js:344:32)
        at Function.Module._load (module.js:301:12)
        at Module.require (module.js:354:17)
        at require (internal/module.js:12:17)

[…]

webpack error

Since app.scss was only three lines for Step 1, it was trivial to verify there’s no typo to account for an unexpected “{“. A web search for this error message implicated an out-of-date installation of NodeJS, which triggered a memory from when I first started experimenting with NodeJS on my installation of Ubuntu 16.04. When trying to run node at the command line, a fresh install of Ubuntu 16.04 would tell the user:

The program 'node' is currently not installed. You can install it by typing:
sudo apt install nodejs-legacy

That suffix “legacy” is a pretty good hint this thing is old. Running node --version returned v4.2.6. Checking the Node JS website, today’s LTS is v10.14.2 and latest is 11.4.0. So yes, 4.2.6 is super old! Fortunately there’s a pointer to a more updated set of binaries maintained by Nodesource that plays well with Ubuntu’s built-in package management system. Following those directions automatically uninstalled legacy binaries and replaced them with up-to-date versions.

Once I’m running on non-ancient binaries, I could continue following MDC Web’s Getting Started guide on my computer. But this experience motivated me to look into a different option…

New Project: LRWave

LRWave Logo 128And now we switch gears to address something that came up earlier. During my successful collaboration session with [Emily] to draw Lissajous curves on an old CRT, one of the deflection coils was driven by a stereo amplifier based on signals from an app running on my phone. What I had wanted to try was to drive both deflection axis from the amplifier using different signals sent to the left and right stereo channels. Unfortunately, the simple tone generator app I had use doesn’t allow independent channel control. Well, somebody should write an app to do this, and the best way to make sure the app does what I want is to write it myself. Thus formed a convenient excuse for me to dive back into the software world for my next project.

In this day and age, the easiest way to distribute a piece of code is to make it a web app of some flavor. The basic way is to create a sound file (MP3 or similar) on the server with the desired wave form, and download to the browser for playback. But this is pretty clunky. It would be great if there’s a way to generate and manipulate audio wave forms using JavaScript running on the browser, no server-side code required.

I started with the HTML5 <audio> tag, which would allow implementing the “basic way” above of playing a sound clip generated on the server but not the preferred path. For the more advanced approach to work, there would need to be a browser-side API that are supported by modern browsers. Which implies a W3C standard of some sort. I started dreaming up technical terms that might let me find such an API, and after a few searches with fancy words like “frequency generation API” I found the much simpler named Web Audio API. Double-checking on the “Can I Use” reference site, we can see it’s widely implemented enough to be interesting.

Since it’s a simple utility, it has a simple utilitarian name of “LRWave.” Just something to generate different wave forms to be sent out to left and right channels. Following the simplicity of the app, its logo is two instances of the Google Material speaker icon facing left and right. In between them are two different waves from a public domain SVG file signifying the intent that it sends different waves to each speaker.

Sony KP-53S35 Signal Board “A” Components

Here are the prizes rewarded for an afternoon spent desoldering parts from a Sony KP-53S35’s signal board “A”.

Signal board A top before

The most visually striking component were the shiny metal boxes in the corner. This is where signal from the TV antenna enters into the system. RF F-Type connectors on the back panel is connected to these modules via their RCA type connector. Since this TV tuned in to analog TV broadcast signals that have long since been retired, I doubt these parts are good for any functional purpose anymore. But they are still shiny and likely to end up in a nonfunctional sculpture project.

Near these modules on the signal board was this circuit board “P”. It was the only module installed as a plug-in card, which caught our eye. Why would Sony design an easily removable module? There were two candidate explanations: (1) easy replacement because it was expected to fail frequently, or (2) easy replacement because it is something to be swapped out. Since the module worked flawlessly for 21 years, it’s probably the latter. A web search for the two main ICs on board found that the Philips TDA8315T is a NTSC decoder, which confirmed hypothesis #2: this “P” board is designed to be easily swapped for a TV to support other broadcast standards.

The RCA jacks are simple and quite likely to find use in another project.

Miscellaneous ICs and other modules were removed mostly as practice. I may look up their identifiers to see if anything is useful, but some of the parts (like the chips with Sony logo on top) are going to be proprietary and not expected to be worth the effort to figure out what they do.

The largest surface mount chip – which I used as hot air SMD removal practice – was labeled BH3856FS and is an audio processing chip handling volume and tone control. Looking at the flip side of the circuit board, we can see it has a large supporting cast of components clustered near it. It might be fun to see if I can power it up for a simple “Hello World” circuit, but returning it to full operation is dependent on the next item:

What’s far more interesting is nearby: the TDA7262 is a stereo audio amplifier with 20W per channel. This might be powerful enough to drive deflection coils to create Lissajous curves. The possibility was enough to make me spent the time and effort to remove its heat sinks gently and also recover all nearby components that might support it. I think it would be a lot of fun to get this guy back up and running in a CRT Lissajous curve project. Either with or without its former partner, the BH3856FS audio chip above.