Another year, another version of the led-o-blinker. This time I had to go wired to fit into the 40 minute deadline. Happy holidays!

]]>https://ncrmnt.org/?feed=rss2&p=316203162Simple IPv6 setup with OpenWRThttps://ncrmnt.org/?p=3147
https://ncrmnt.org/?p=3147#respondSun, 25 Nov 2018 14:26:17 +0000https://ncrmnt.org/?p=3147A while ago I was asked in comments about my OpenWRT IPv6 setup. So I decided to write a small note about it here in my blog. Sorry for missing some of the theory and the details – it’s meant for those who are in a hurry.

We all know that IPv4 addresses are running the hell out, IPv6 *SHOULD* be already used extensively, but many of our local providers just don’t bother themselves with it. And since in terms of setup IPv6 is way more complicated to properly set up compared to IPv4 a lot of sysadmins don’t bother themselves setting it up just because – ‘IPv4 will be ‘nough for our age, man’. As for me, I decided to set up some basic IPv6 in my LAN just to test things out, have an ability to test my own apps over IPv6, and, well, be prepared for the future, you know.

My server is running on a shelf at home, behind an OpenWRT router. I get my IPv4 address at the WAN interface with DHCP. Thankfully the age of PPTP/PPPoE is over at last (as is the age lanparties. I really miss ’em).

Since I didn’t have much time for setup I decided to do things as simple as possible. Waiting for my provider to offer IPv6 was not an option – I’d retire earlier, so I decided to use one of the transition mechanisms available. So, to make things short and simple, it’s either a miredo/teredo tunnel, or a thing called 6-to-4, that is pretty good, since the IPv6 range you’ll get is as static as your IPv4 address. Besides, you don’t need to find a tunnel broker – it will find one on its own (though you can’t choose which one, though), so it’s even easier.

In LUCI, once we’ve just flashed OpenWRT you normally have WAN, LAN interfaces, and a WAN6 interface. The setup looks like this:

This is the thing we’re going to tune. In my case it looked like this:

If you haven’t really touched DHCP and LAN settings with any super-complex setups, everything should “just work” and all you LAN clients will get their shiny IPv6 addreses once configure 6to4. But we’ll run into a huge problem here: Everything on the network that is IPv6-capable will be directly exposed to the Internet which is NOT a wise idea even if you’re running only linux. To fix this, we’ll add WAN6 to a new firewall zone:

And configure the zone in this way:

To test the setup you’ll need either a VPS with IPV6 enabled or use online tools like this one. Once done with the firewall, IPv6 address of the router will be directly accessible from outside, but none of the computers on our internal network. On the other hand, all computers inside our network will be able to use IPv6 sites with no problems. Well, that covers it. Looks simple enough.

This setup is very IPv4-like, and all the usual port-forwarding stuff stays the same for both IPv4 and IPv6, so you’ll have less to set up when you need to use port from the outside. In my case all http traffic goes through the router anyway, where it’s reverse-proxied via nginx.

Email server on the other hand is a totally different story. For it to work you have to get a reverse PTR entry in DNS. For IPv4 that was done by my ISP. This will not work with this IPv6 setup, and according to the manuals on the Internet you’ll have to install BIND (and have a dance setting it all up) for this to work. So for now I’ve disabled IPv6 in my email server for now.

P.S. For brutal folks with red eyes that need “no freakin’ graphical user interface”, and prefer to write dangerous spells in configuration files by hand only, here are the relevant spells and places where you need to put them:

]]>https://ncrmnt.org/?feed=rss2&p=314703147LineageOS + Magisk adventureshttps://ncrmnt.org/?p=2719
https://ncrmnt.org/?p=2719#respondSat, 09 Jun 2018 18:06:26 +0000https://ncrmnt.org/?p=2719I use LineageOS and Magisk root (A magic tool that help Android Pay and root access coexist). With Lineage you can receive updates every week on monday (for my Oneplus 5T) and so far they’ve been really stable. All was good until the last update of may bricked my cellphone. As it turned out Lineage build was perfectly fine, the bug was with Magisk (Once I removed it and flashed the update – everything worked, except for Magisk). In this blog post I’ll tell about Magisk’s epic fail, and will provide a link to fixed Magisk version that doesn’t turn your phone into a pumpkin brick.

The problem was dumb: Magisk patches boot.img, it detects the end of linux kernel and the start of dtb blob by a 32-bit magic number – 0xd00dfeed. And that sequence happened to be inside the compressed linux kernel (Ooops!). This turned out to be knownbug, and Magisk repository even has a Pull Request with a fix.But now (9th of June 2018) it’s not yet merged and we have no working Magisk build for Oneplus 5/5t. After less than an hour after the post went live, the fixes are merged. We should expect 16.5 soon.

So I had to roll up my sleeves, install Android SDK and compile Magisk with the so much needed fix applied. For those who want the binaries – I posted them at xda-developers. Magisk is marked as 16.4.1, versioncode set really low, so that you will be prompted by Magisk Manager to update to any available official version. Just don’t update until a fix is out, or your phone will instantly turn into a pumpkin brick.

]]>https://ncrmnt.org/?feed=rss2&p=271902719OnePlus 5T Dock with NFChttps://ncrmnt.org/?p=2684
https://ncrmnt.org/?p=2684#respondThu, 03 May 2018 14:49:53 +0000https://ncrmnt.org/?p=2684I recently got myself a OnePlus 5t cell phone. (Mostly because it’s fully supported by LineageOS which is IMO the best option you can get for your phone). Finally I got a few spare moments to design a nice 3-printed phone stand for it.

I used SolveSpace (as usual) to design it. Unlike most phone docks and stands that one could get back in the days when those were popular, this one is designed to fit the cellphone without removing it from the leather case.

The base is features a lead for the cable.

The base is also large enough so that you can open the leather case and the phone will not flip.

And the final touch – an NFC sticker. This way the phone will know that it’s docked.

]]>https://ncrmnt.org/?feed=rss2&p=268402684IPv6 supporthttps://ncrmnt.org/?p=2677
https://ncrmnt.org/?p=2677#commentsSun, 22 Apr 2018 16:42:34 +0000https://ncrmnt.org/?p=2677Okay, starting from right now my blog should be available via ipv6 as well.
]]>https://ncrmnt.org/?feed=rss2&p=267722677A DIY music player with web interfacehttps://ncrmnt.org/?p=2407
https://ncrmnt.org/?p=2407#respondSat, 20 Jan 2018 15:31:46 +0000https://ncrmnt.org/?p=2407This post covers my music player with web interface that I’ve added to my workshop (or, perhaps, I’d better call it “my lab”?) In this post I will walk through the messy details of making such a box and document all the tricky bits.

The idea

The idea is pretty simple. A linux-based SBC that is connected to the wireless network that provides web-based interface to control the playback. A USB sound card armed with a few amplifier modules are used to output the sound (since built-in sound devices are usually 2-channel only). A USB hard disk is used to store the music collection. Sounds good? Okay, let’s get started.

The part list

The whole BOM is something about ~40-50$. I can’t give you any precise calculations since I had almost everything gathering dust in the attic for a few years or so (completely ignoring economical turbulence), except the plastic enclosure.

Enclosure

This is the most difficult part of the build. But necessary, since we don’t want to end up with wireporn, do we? The box consists of 3 3d-printed floors assembled with M3 screws and a cover. They are 150x150mm and took about 10 hours to print each. It took me a few tries to make everything a tight fit. I’ll start with the bottom floor. The 3d-render of it looks like this:

And like this in real life (Or at least the first ‘green’ prototype looked like that).

It contains a 30mm fan (I wish I did go for a 120mm from the very beginning, that stuff is really noisy!), a USB-to-SATA bridge for the HDD hot-glued to sit in place. Wall-mounting holes included. I’ve printed a special bracket for the HDD so that it would be easier to plug it in and out without any disassembly.

The second floor houses the usb hub that contains a 12->5V DC-DC and the android TV stick. The nifty trick about those TV sticks is that due to simple schematics you can usually inject power via the USB host. And that’s precisely what my baseboard does. There are also holes in it for the uSD connector and the micro-usb port. The always-on port of the usb hub is also on the side of the box.

This is how it looks on the render:And like this in real life:

Finally, the topmost floor contains the sound card and the VMA2016 amplifier modules. The line-in and mic-in are wired on the side of the box, so that I can connect a mic and, say, a guitar (just in case my neighbors get drunk and go karaoke and I’d want to take my revenge on them)

Finally, that’s how it looks when I’ve assembled everything. I was to lazy paint the green plastic into something else, so I’ve printed everything in black.

On the bottom of the box there’s a special bracket to hold the dust filter. I tried a piece of common cloth for a start, but alas it with it the fan didn’t generate enough air flow to cool down the hard disk under a heavy load. Eventually I moved on to a 120mm fan at the very top.

I used widely available steel angle brackets for to mount the box to the wall that are attached using M3 screws.

And that’s how it looks when attached to the wall.

The software

Here’s the list of software that I’m currently using:

skyforge – gets you a customized debian rootfs in no time

groovebasin – A music player with web-interface, compatible with mpd clients, can be obtained from debian packages

alsamixer-webui – web interface for alsa sound mixer

nginx – serves as a reverse proxy and allows to switch between alsamixer and groovebasin web-ui.

aura – an embedded rpc library. A lua script called shard-ctl uses it to communicate with the hardware to turn on and off relays on the board

A few bash scripts and systemd units that control things like cooling and mounting root filesystem

WIFI & Time

The wifi is brought up using debian’s /etc/network/interfaces.d/ mechanism. Since the device lacks an RTC it’s a good idea to fix the date/time when the device starts up. Here’s my /etc/network/interfaces.d/wlan0

N.B. Remember to replace arvale.lab with the ntp server of your choice. I use a local openwrt router as a ntp server

Systemd units

The startup sequence is quite tricky. After debian’s usual services like ssh and network are up, we need to power on the usb<->sata bridge, wait till it’s detected by the system and mount the disk drive with the collection. Next we need to start the groovebasin service and power on the amplifier modules.

This is done by three unit files:

groove-mount (A bad name, but it’s what’s left of pre-systemd shell scripts. Right now it only turns on power at the start)

Finally, goes the groovebasin.service (The debian package lacked one, so I wrote one). Note the working-directory directive that points groovebasin to a directory where a relevant config.json is stored. It resides on the external hard disk.

groovebasin’s config.json

Nothing really fancy, mostly taken from the example. I removed the API keys directives, since you’ll need your own there.

/etc/asound.conf

Since most music contains only two channels we’ll need to do some upmixing using alsa. Apart from that, even with SoC sound devices disabled, usb sound card has the id 1, not 0 so groovebasin will not work out of the box.

The only thing I needed is put this script in /usr/local/bin and tell cron to run it every minute.

The web stuff

Basically we have 2 distinct web apps. Groovebasin (written in nodejs) and alsa-mixer (written in python). To make them both want to share the same port 80, I used nginx as a reverse proxy.

The OpenWRT sitting in my lab assigns this device the ‘iceshard.lab’ dns name, and I’ve also told it to route player.iceshard.lab and mixer.iceshard.lab request there as well. After, I added nginx on the player itself with these directives.

Auto-shutdown the amplifier modules

When there’s no music playing there’s a quiet white noise coming from the speakers. It’s barely noticeable and starting playback usually makes it even quieter. After I picked a decent power supply it was almost never heard (especially if I have my 3d printer printing or CNC milling something). But in complete silence it becomes annoying as hell and wastes power. So, I’ve made another bash script. It uses mpc to listen to events from groovebasin and polls groovebasin status. When nothing has been playing for over 120 seconds – it shuts down all amplifiers. If something started playing – it brings all the speakers back online.

Obligatory screenshots of the web ui

The desktop app and hotkeys

I used electron as a quick hack to create a nifty desktop app that sits in the tray and pops up when you press Win+A. It also brings up the mixer window as well, by pressing the icon in the tray. Electron is messy, memory hungry and ugly platform that I usually prefer to stay away from, but it this case it was the easiest way to get the job done.

More stuff

This post turned out to be huge as well as the project itself. It had taken a while to accomplish and document even in this simplest form. I’m sorry I didn’t document many things as detailed as they have deserved. If you want to build something like this yourself and help polish the instructions – pull requests at github are always welcome

Opensource

You can grab the scripts used to create the rootfs at this github repository. Skyforge will build the firmware, install the kernel debs and generate the initramfs and boot.scr. The result will be packaged in a tarball that you can extract onto an SD card (See linux-sunxi wiki for instructions on creating a bootable SD card)

All enclosure designs are created using solvespace and are up on my thingiverse

]]>https://ncrmnt.org/?feed=rss2&p=240702407Getting rid of wireporn in the bathroomhttps://ncrmnt.org/?p=2624
https://ncrmnt.org/?p=2624#respondMon, 08 Jan 2018 09:59:12 +0000https://ncrmnt.org/?p=2624I have three devices in my bathroom: electric razor, trimmer for my beard and an electric toothbrush. Each of them comes with its own power brick and compete for a single 220v outlet. As a result I caught myself multiple times when at as one item of these is completely out of charge. Or, worse, the power bricks end up in a huge mess-o-wires you have to untangle. (like, the one you see on the left side of the photo below). And, since I deal with this in the morning when I’m in a rush to get myself out to work it’s even more annoying. At some moment I decided to fix that. I didn’t want to add more 220v outlets, since:

a). It’s quite difficult in that particular case
b). I didn’t want to keep all power bricks plugged all the time any way – I never really trust cheap power bricks and for a reason!
c). The total length of the wires gathering dust would re
main intact
d). I needed a shelf for these anyway

Therefore, armed with a 3d-printer and aliexpress I decided to make it a bit different. The result you can see on the right half of the photo below. Build details follow.

Besides, if you liked this design, you can grab it on my thingiverse (link at the very bottom of this post).

The idea was simple, I wanted to power everything from a single (known good) power brick and minimize the wiring, gathering dust. A good shelf for all of these would be a good bonus. So I quickly came up with this concept, so I only had to nail some details.

First thing we need to be careful about – electric trimmers and razors often have NiCD power cells inside. Those are charged with constant current and the power brick itself provides the current limit. Therefore, if we plug it into a 3A DC-DC adjusted to the same voltage as we so on the power brick bad things will happen. Well, perhaps it won’t go kaboom like those li-ion cells, but will definitely melt the plastic. (Believe me, I checked it )

That’s why I got myself a bunch of DC-DC power modules with a user-configurable current limit. Those are dirt-cheap on aliexpress (if you don’t mind the wait), a little more pricey in local stores.

While those DC-DC’s were on their way from china, I started creating the shelf itself.

This particular one attaches to the wall (in place of a bathroom hook) with two screws. It also retains the bathroom hook functionality with this cap that cover it:

For this project I used once again solvespace, although I have already bumped into many places where the functionality of this program, in just NOT enough. Especially when it comes to adding artistic elements. Unfortunately, blender still sucks as a solid cad, although I really want to give it another try. Perhaps it will be best to do all the geometry-sensitive parts of the design in solvespace, while doing all the “artistic beautification” in blender. But, not this time.

It took a long time to print it, perhaps more than a day. Besides, when I finished designing all the parts of this project, DC-DC modules already arrived, so I only had to add the 2.5mm barrel jack sockets to them:

And secure them inside the box

Everything is assembled using M3 and M4 screws (excluding the mounting to the wall – use self-tapping screws here). I printed everything with SBS plastic, excluding those long ‘hands’ holding the trimmer and the razor. I used PLA for them for added durability.

Before actually connecting all the stuff to it, I had carefully inspected the stock power bricks and configured the DC-DC’s to give the same voltage and current as stated there.

I used common 2.5mm barrel jacks, that are very inexpensive. I had a similar jack on the trimmer, so didn’t have to cur the original cable. The one in the tooth-brush is a very similar barrel jack, but of a smaller diameter. I happened to find a spare one. The razor had a different type of plug, so I had to cut the cable from the original power brick. I’ll later add a 2.5mm jack there too, so that I can reassemble the original cable and take it along with me on a trip.

The obvious drawback of this assembly is that all the jacks are the same, so plugging a device in a wrong socket will be an epic fail. I worked it around by making the cabling as short as possible. This makes misconnecting hard, but possible.

However, if you take into account how often I’ll plug them in or out (hint: hardly ever) this should do for now.

For those eager to print themselves a similar shelf – head to my thingiverse.

]]>https://ncrmnt.org/?feed=rss2&p=262402624A Led-o-blinker for the New Yearhttps://ncrmnt.org/?p=2602
https://ncrmnt.org/?p=2602#respondThu, 28 Dec 2017 21:13:02 +0000https://ncrmnt.org/?p=2602Took about 40 minutes to make and voila, a led-o-blinker for the day we celebrated New Year at work. I used that glam PCB for android TV-sticks, an OpenWRT module and a little shitty code with Christmas magic inside.

]]>https://ncrmnt.org/?feed=rss2&p=260202602Cloning complex 2d shapes with inkscape, freecad and 3d-printerhttps://ncrmnt.org/?p=2593
https://ncrmnt.org/?p=2593#respondTue, 19 Dec 2017 11:06:45 +0000https://ncrmnt.org/?p=2593This small tutorial will cover how to clone complex 2d parts with a flatbed scanner, inkscape and freecad. You may use this for any complex shapes that are too tough to measure using calipers. This technique can also be used to reverse-engineer complex PCB shapes to aid in creating custom enclosures. As a small example I’ll clone part of my archery fingertab.

Okay, let’s move on. First we’ll need a piece of paper or cardboard and pencil and trace our shape. Or you can put the part directly under the scanner. It all depends on the color and material of the part and the desired results. I prefer to trace it to avoid scratching the scanner.

The next step is scan it. Preferably pick PNG for less compression artifacts and a relatively high DPI. I picked 300dpi, but it’s mostly a matter of taste and performance. If the cardboard or paper isn’t quite white (Like the one I took for this tutorial) play with contrast and brightness sliders to make it appear whiter. Here’s what I got after scanning and playing with sliders:

Now import (File->Import) this stuff to inkscape. For PNG the DPI should be saved in the file, but to make sure – you can draw a line, see how long it is in mm and compare it with the ‘real thing’ using calipers. The results should be a precise match unless you scanner software screwed up DPI setting somehow. If you need extra fine results you can calibrate your scanner using some part of known dimensions and calculating the scaling coefficient. But in my case it was already good enough out of the box.

Now we need to trace the bitmap into vector graphics. This procedure will give us precise path and remove all remaining noise. Select the image and click Path->Trace Bitmap. In the dialog we’ll see something like this:

I picked ‘Brightness Cutoff’ mode with a threshold of 0.6. Note the noise dots in the preview window! If your paper is dirty or you are using some non-white cardboard (like in my case, I picked it to show the speckles removal option in action) or if you scanner is dirty or scratched. Gladly inkscape can get rid of those. just navigate to Options tab and configure the ‘Suppress Speckles’ option. The size is dependent on the DPI and it may take a few tries. Note that for some reason this option has no effect on the preview window!

Once traced, we can get rid of the bitmap and fine-tune the traced result. This is what I got:

To remove artifacts along the lines click Path->Simplify. This will remove unneeded points that is also good in terms of performance for further steps. We can do simplification several times, but it has a nasty side-effect of rounding corners.

Almost done. Now navigate to Object->Fill and Stroke. In the ‘Fill’ tab we disable color filling, in the ‘Stroke’ tab we enable the contour. The Freecad manual recommends “Stroke width” parameter set to 0mm, but since we want to see at least something in inkscape now I’ve set it to 0.1mm:

Now every like is split in two. We need to remove the extra. At this point we can pick either the outer or the inner boundary. But before we can do this, we’ll have to click Path->Break Apart.

After cleaning up we’ll get a nice shape you see on the picture below. At this point we can go ahead with FreeCad export, or redraw some elements (e.g. circles and rectangles) by hand. Personally I decided to skip this part.

Now optionally set ‘Stroke Width’ to 0 and save as ‘Plain SVG’. Despite what FreeCad manual says I had no problems importing svg with 0.1mm outline.

We can exit inkscape now, the job is done. It’s freecad time now. Initially I wanted to use solvespace, but dxf import from inkscape (R12 and R14 formats alike) is termally broken: either (R12) sizes are screwed up (and solvespace lacks scaling tool) or there are terrible artifacts around the border (R14). Besides, if there are too many points solvespace refuses to work correctly with the layer considerable slows down. Hopefully it will be fixed in some later releases.

But while now we’ll have to use some ‘heavy artillery’ called FreeCAD. The latter allows to do way more than SolveSpace, but has very counter-intuitive (IMO) interface. Although, I guess, it’s more a matter of habit.

Create a new project in FreeCad and import our SVG as geometry. We’ll end up with something like this:
Pick the ‘Draft’ workbench, select all pieces of the puzzle and click ‘Draft->Upgrade’.
Now switch to ‘Part’ workbench. Select all once again and click ‘Part->Extrude’ and pick the desired thickness of the part. We’ll end up with something like this:
The only thing we’re missing – holes where they have to be. We have to select in turns the main part and the pieces we want to subtract from it and click ‘Part->Boolean->Cut’. After a few iterations we’ll end up with a model that we can finally export to STL:
And, finally, print!

The best part of it that we can easily scan some PCBs and other stuff and that will aid us in designing enclosures (mainly by saving time on the frustrating calipers measurement and re-printing the whole part when we made a single mistake)

]]>https://ncrmnt.org/?feed=rss2&p=259302593Verilog Simulators and ctesthttps://ncrmnt.org/?p=2557
https://ncrmnt.org/?p=2557#respondSat, 09 Dec 2017 11:04:24 +0000https://ncrmnt.org/?p=2557If you are someone with a software engineering background getting your hands dirty with hardware design, first thing you’d want to use – some kind of testing framework/runner for all the tests you write. If you are using myhdl you’ll already use all the stuff python offers for unit-testing.

But if you are using more conventional tools for a bigger project with a bunch of third-party libraries, chances are you are not happy with shitty bash/csh tools and instead of wasting the precious minutes of your life writing those you’d want to use something existing. After all, why reinvent the wheel?

In this post I will describe the troubles of integrating verilog simulators with existing test runners. Namely – ctest (that comes from cmake).

So, what’s the purpose of the test runner? Cpt. Obvious says it’s needed to run your tests (perhaps multi-threaded to speed things up), handle timeouts and generate nice and shiny reports in different formats that we can later integrate in, say, jenkins, post on cdash or print on soft paper for later usage.

Cool stuff, but how does a test (which is usually just a program) tell the runner that it is ‘passed’ or ‘failed’? Obviously via exit code. If it’s 0 – PASSED. Anything else – EPIC FAIL. Sounds simple.

So, if our test is a verilog testbench, the only thing we have to do is finish the simulation with a non-zero exit code. Sounds simple? Well, turns out it’s not.

The classic verilog $finish() takes no argument and always terminates with 0 exit code (unless we crashed the simulator… somehow).

Some simulators allow to supply an exit code, but some don’t.

$finish(1);

SystemVerilog adds a new $fatal() call that terminates the simulation with a non-zero exit code so we should be okay unless… we’re using a huge load of third-party libraries and behavioral models that just call $finish() if something went wrong. And the latter is almost always the case for a big project.

Solution here is utter and ugly hackery – but it works and with all this mess there’s little else we can do:

Write a result.txt file a non-zero exit code

Actually do the simulation.

Overwrite result.txt with zero exit code if we’re good

Wrap the actual simulation run in a shell script that runs the simulation and after it’s done – reads out our result.txt and passes the code to the shell.

This way if anything terminates the simulation prematurely due to some assert in the libraries – will still have a non-zero exit code.

Btw, you can generate the wrapper directly from cmake via configure_file.

Parallel test runs and bad patterns

So, we have lots of tests. And lots of cores on our PC. A natural solution would be running things in parallel. If we’re using ctest, the only thing we have to do – type ctest -jN, where N is the number of concurrent tests we want to run.

And ctest will do all the rest for us. There can be several instances of a simulation model running at the same time – all verilog simulator I know of allow this, including icarus verilog (which is my favorite!). That would’ve been easy in a perfect world, but in the reality there’s another pitfall:

Traditionally in verilog, different IP cores, libraries and etc. read and write their data/logs from one single directory: the directory where we’ve started the simulator. And as the project gets bigger the option “edit the models by hand” looks less and less neat.

Solution – run the model you’ve compiled&elaborated from DIFFERENT working directories. You can do it with WORKING_DIRECTORY argument to add_test().