Tuesday, February 28, 2023

DIY emulation in 2023

Intro

I've been told this is currently the 2020s, and so it's time for my decennial post on how to emulate classic games.  I've been chasing the high of modded original Xboxes running XBMC and a collection of emulators since 2006.  The main selling point of that setup was how slick the interface was.  Just turn it on and do everything with the controller on a UI that was clearly designed for a TV.  The main downside was having a huge Xbox in your living room, and having to use wired controllers.

Last decade's solution was a Raspberry Pi running RetroPie, which worked ok, but the interface was never that great and it struggled with N64.

Separately, the Roku I use to watch Plex, Netflix, and other media is starting to show its age, and I wouldn't mind something more open source.

My plan was to buy a mini PC, put linux on it, maybe some HTPC distro, and use that for both media and emulation.

I'll skip over the saga and say that the media playback didn't work out.  I had assumed there would just be native clients for Netflix and others available, but there isn't.  There are the web versions, and maybe something could be done with launching the web versions seemlessly, but it just didn't feel like it'd ever have the slick UI I wanted.

Incidentally, around this time I got an Nvidia Shield donated to me and discovered SmartTubeNext, which is a Youtube player which skips ads, including portions of the videos about sponsors themselves.  That greatly reduced my desire for media playback on the mini PC.  I've also been very happy with pairing the Shield with an Xbox controller to play game via Steam Link on my Desktop PC.

So what did I end up with?

The focus then was just emulation, from N64 and older.  First, I bought this Mini PC for $200.  Note there are a ton of these around this price point, and they all have similar specs.  I sort of regret buying this one because it has a very loud fan, despite the fact that the listing claimed it was silent when I bought it (and later removed that claim), and because this one doesn't support any sort of Wake On LAN or boot on power restore, so there is no way to for me to turn it on remotely, and I can't leave it on 24/7 because of how absurd the fan is.

I also bought this IR USB dongle for $20.  I intended on setting it all up manually, but ended up just installing the FLIRC program from the repos and liking it a lot.  I set up buttons on my remote to map to Alt+F4 (close program), ESC, and a custom shortcut I set up to show the desktop.  Between those and the obvious stuff like arrow keys and enter, I found it pretty easy to use with a remote.  The only things I have on the desktop are Steam and RetroArch, as well as a few useful tools, including a shortcut to power off.

I was using my Logitech Harmony 300 remote until some of the button finally started to give out.  I replaced that with this remote I got for $40, which I like quite a bit.

I also have this wireless N64 controller that I got for $40, and which you can use with actual N64s or via a USB dongle on a PC.

And I found this amazing archive of every ROM ever on Internet Archive.  I got all the N64 and older ROMs from the systems I wanted, and filtered the sets down to the games I had heard of.

I installed Xubuntu on there, although I'm keeping my eye on KDE's Plasma Bigscreen, which looks very promising for what I want to do, but right now is only available on ARM hardware.

So overall I'm happy with this set up.  I have to get up to turn it on, but after that I can control everything with the remote and controller.  I've been playing a lot of N64 games on it, and they generally work well.  Goldeneye's sound stutters, but I googled what to tweak in the setting to get the best performance out of it, and that was enough to play through the campaign.  Mario 64 I'm about halfway through and it's been flawless.

Monday, January 2, 2023

Friday, December 9, 2022

Finding the B-21's hangar location from the stars in its press image

 https://twitter.com/johnmcelhone8/status/1600683623250030593

Saturday, October 8, 2022

QR codes Share

https://typefully.com/DanHollick/qr-codes-T7tLlNi

Second, the mask - what's that? Well, QR readers work best when there are the same amount of white and black areas. But the data might not play ball so a mask is used to even things out. When a mask is applied to the code anything that falls under the dark part of the mask is inverted. A white area becomes black and black area becomes white.

There are 8 standard patterns which are applied one by one. The pattern that achieves the best result is used and that info is stored so the reader can unapply the mask.

the 8 possible QR code masks

 

Thursday, September 15, 2022

Here’s Why Car Wheels Are So Flat These Days

 https://www.theautopian.com/heres-why-car-wheels-are-so-flat-these-days-and-no-its-not-just-aerodynamics-and-styling/

At first, rack and pinion gears were being applied to existing suspension designs but since the tire forces were being “amplified” by the large kingpin offset and scrub radius in those old designs, they were too much for the driver to take and were ripping the steering wheel out of their hands. Something had to be done and since there will always be potholes and braking forces, the only thing that the engineers could do to reduce the forces coming back through the steering system was to reduce the size of the kingpin offset and scrub radius. This meant the lower ball joints had to move outboard, the brakes had to move outboard and all the dominoes started to fall which spelled the end of deep dish wheels.

Saturday, August 27, 2022

Why No Roman Industrial Revolution?

https://acoup.blog/2022/08/26/collections-why-no-roman-industrial-revolution/

Eventually in the 1800s, these engines get small enough and fuel efficient enough to be able to move their own fuel over water or rails, collapsing the prohibitive transportation costs that defined pre-industrial economies and in the process breaking the tyranny of the wagon equation, decisively transforming warfare in ways that would not be fully appreciated until 1914.

But the technology could not jump straight to railroads and steam ships because the first steam engines were nowhere near that powerful or efficient: creating steam engines that could drive trains and ships (and thus could move themselves) requires decades of development where existing technology and economic needs created very valuable niches for the technology at each stage. It is particularly remarkable here how much of these conditions are unique to Britain: it has to be coal, coal has to have massive economic demand (to create the demand for pumping water out of coal mines) and then there needs to be massive demand for spinning (so you need a huge textile export industry fueled both by domestic wool production and the cotton spoils of empire) and a device to manage the conversion of rotational energy into spun thread. I’ve left this bit out for space, but you also need a major incentive for the design of pressure-cylinders (which, in the event, was the demand for better siege cannon) because of how that dovetails with developing better cylinders for steam engines.

Monday, July 18, 2022

Is it getting hotter?

I wanted to see what actual data said about how much hotter it has gotten in my area during my lifetime.  I know climate change is going on at a global level, but I just cared about my area, is it actually getting noticeably warmer, or is it just my imagination?

Before we go any further I should stress I'm not trying to prove or disprove climate change, or do any sort of serious climate science here.  I'm just trying to answer the question: Is it actually noticeably hotter here in the Philly area now than it was when I was a kid?

I've seen graphs of average temperature over time for cities before, but I feel like they tend to use average temperature over the year.  Which, I'm sure is a more important data point for climate science, but again, I only care about if I feel hotter here.  I don't really care about days that would have been 50F and now are 60F.  I decided the right metric to use for me is how many days over 90F per year do we see?  Is that number going up?

I won't turn this into a huge post.  I grabbed data from the NOAA here, in a CSV for the Philly airport from 1980 to 2021, which roughly matches the time I've been alive.  I threw that into a database and queried the count of days per year over 80F and over 90F, and graphed both, with trend lines.

graph of days over 80F in Philadelphia

graph of days over 90F in Philadelphia

Before I put the trendline on there, I have to admit I thought the 90F version didn't show any increase.  But then I noticed how few years had less than 20 days over 90F recently vs the 80s.  We haven't had a year with less than 10 days over 90F since 2014.

The over 80F version is a bit harder to read, but I feel like it shows the upward trend better, particularly if you focus on the 100 days line.  In the 80s there were a few years with more than 100 days over 80F. In the 90s it was about half the years.  In the 2000s it was most, and then in the 2010s it was all but 2, which barely snuck in under the line.

For fun I also looked for number of days where it never went above 30F.  Note this isn't just the daily low, this is the warmest it got on any given day, or in other words, days where it never got above freezing.  Spoiler alert, it's also getting less cold.

graph of days under 30F in Philadelphia

I did also pull the lows and looked at those,  they showed similar trends.  The 1980s had an average of 25 days below 20F, the 2010s had an average of 13 days, and 2021 had exactly 1.  The one graph I will post from the lows is this one of the number of days where the low is over 70F.  In other words, days where it never goes below 70F, even over night.  If you're looking to cool your house by opening the windows over night and closing them during the day when it heats up, it's going to be pretty tough to do if it's not going below 70F at all (which probably means it's still over 80F when you're going to bed).

 

graph of days with a low over 70F in Philadelphia

I was actually surprised at how clear the trend was in the data, and in every single version of the data I could think of to look at.  There wasn't a single dimension I looked at that didn't show this trend.  Turns out it is hotter now than when I was a kid.  Not a fan.

Tuesday, July 12, 2022

Mouse Heaven or Mouse Hell?

 https://www.sciencehistory.org/distillations/mouse-heaven-or-mouse-hell

Officially, the colony was called the Mortality-Inhibiting Environment for Mice. Unofficially, it was called mouse heaven.

Biologist John Calhoun built the colony at the National Institute of Mental Health in Maryland in 1968. It was a large pen—a 4½-foot cube—with everything a mouse could ever desire: plenty of food and water; a perfect climate; reams of paper to make cozy nests; and 256 separate apartments, accessible via mesh tubes bolted to the walls. Calhoun also screened the mice to eliminate disease. Free from predators and other worries, a mouse could theoretically live to an extraordinarily old age there, without a single worry.

But the thing is, this wasn’t Calhoun’s first rodent utopia. This was the 25th iteration. And by this point he knew how quickly mouse heaven could deteriorate into mouse hell.

Saturday, June 25, 2022

Converting numbers stored as decimal to binary encoded decimal values in PostgreSQL, or how I fixed my smart water meter reader

Intro

In my previous post about reading my smart water meter in Home Assistant, I left you on a cliff hanger.  You don't really need to go back and read that post if you haven't already.  Just know that I'm reading my smart water meter using a USB SDR dongle and a tool called rtlamr, (and a wrapper for that tool called rtlamr2mqtt).  While I seemed to be able to read the meter, and the ID matched the one printed on the label, there was a drift between the two readings.

Also know that you really don't need to read this post.  Of everything I've written for this blog, this may be the most absurd self indulgent post yet.  I can guarantee you, that no one will find the contents of this post useful.


Figuring out the offset

My initial readings from the SDR were 157815, while the physical meter read 268770.  I had a suspicion that the SDR would have to be multiplied by 10, because the physical meter had an odometer style dial for all the digits down to the 10s digit.  The 1s digit was a permanent 0, and then there was a clock style dial, which I assumed was the 1s digit.

water meter, showing the dials

I just sort of assumed that the SDR version of this number would also have a resolution of the 10s digit, but I hoped it was better.  It was also possible it was much worse.  The water company bills me by the 1000s of gallon.  If I understood the meter, that would be the white dials.  It was entirely possible the SDR was only broadcasting that number.  I also wasn't sure what kind of time lag there would be between usage and the SDR reading changing.  I was getting readings pretty constantly, about once a minute, maybe more, but those readings didn't seem to change when I was actually using water.

After the first night I could see the SDR meter updating about once an hour.  Not ideal, if I was going to use this to help detect leaks, but still better than nothing.

I would wait until a time when we hadn't used much water, and then record the physical meter.  If the SDR didn't update for at least an hour before and after the time I read the physical meter, then I assumed that SDR reading corresponded to the physical reading I had.  My plan was to do that about once a day for a while and then try to find the offset.  I figured with just two pairs, I should be able to find the equation of the line through those points and that ought to be enough to convert between the two.  That is, as long as the SDR was increasing in a linear way.

After a day I had these two readings.  With both I verified that the SDR reading hadn't changed for a while around the time they were taken, both around 3pm.

6/2: 268815.4    157825
6/3: 268864.5    157830

Solving that line gave me this formula to convert the SDR reading to the physical reading: physical = 9.82 * SDR - 1281026.1.  Looking at the multiplier of 9.82 I realized that confirmed my suspicion that the SDR reading was for 10 gallons, and that the factor should just be 10, the only reason it wasn't was the error in the SDR value, since that was only accurate to 10 gallons.  I simply used 10x and found the offset and that gave me the slightly updated formula of: physical = 10 * SDR - 1309434.

And with that, I was pretty much done...


Discrepancies

6/3 was a Friday, so I didn't get a chance to get a good reading over the weekend, but come Monday I took another reading to confirm my formula worked.  On the afternoon of 6/6 I read the physical meter at 269214.8, and the SDR reading was 157985.  Plugging the SDR value into my formula gave: 10 * 157985 - 1309434 = 270416.  Which is 1201.2 gallons too high.

Now this was damn peculiar.  I wouldn't have been surprised to see some error, but 1200 gallons was way too much.  The fact that it was close to 1000 made me suspicious that perhaps I had read something wrong.  Luckily I had taken pictures of each physical meter reading.  I double and triple checked everything, but got the same results.

I went back and looked at the graph of SDR readings.  There was a clear jump at about 11:30am that day.  The previous change was at 3am and the SDR value at that time was 157849, then at 11:30 that changed to 157952.  Note that just looking at the last two digits the value went from 49 to 52.  Those are 10s of gallons so 30 gallons used.  That seemed plausible, albeit still a bit high.  I began to wonder if the first 4 digits of the SDR number were actually something else, basically two independent numbers just concatenated together.  I tried subtracting 1000 from the readings after the jump, and that helped, but they were still off by a lot.

spreadsheet of SDR and actual meter readings

After a week of this I began to lose hope that I'd be able to correct this issue.  I tried fitting any curve to these numbers, even though it really didn't make any sense why the meter would go up in a non-linear fashion.  I started to rationalize that at least the SDR did seem to increase when we used water, and stay the same when we didn't.  At the very least, I could do something with that.


Stumbling Block

You may remember from my first post, that my first stumbling block was reading the default scm meter type, instead of the r900 type I actually had.  It turns out this was also my second stumbling block.

I began to be more sure that A. I was not making any mistakes with these readings, and B. this was a common enough water meter that someone else must have also had this issue.  After a lot of searching, and just reading through every issue on the github project that mentioned the R900 meter, I finally found this issue.

github issue suggesting to use r900bcd if r900 produces odd results

That was it.  Turns out there was another r900 type, called r900bcd (binary coded decimal).  I had seen this type, but figured if I was able to read my meter using the r900 type that meant that was what I had.  I never thought that the r900bcd type would also be able to read my meter, but produce different outputs.

Sure enough I changed the type to r900bcd, relaunched the program, and the readings matched the physical meter exactly (up to the 10s digit).  This was both a huge relief and super annoying that I wasted so much time on what was essentially the same problem I already had.

Either way, I was happy to have accurate water usage data, to within 10 gallons and approximately an hour.  I could definitely use that to detect leaks while we were away or asleep.  But now I had a new problem.  I had already collected a week's worth of priceless data.  What was I to do with these data points, which through no fault of their own, had been encoded incorrectly?

Well, if you'd like a snack now is the time to get one, because this is the part where the blog post gets good.  If you're somewhat annoyed at having read a 1000 word essay, which was essentially a preamble to the actual purpose of this post, please remember that you were warned earlier.


Binary Coded Decimal

"What is Binary Coded Decimal (BCD)" you almost certainly do not ask yourself?  Well it's a system where instead of just converting a full number into binary, you instead take each individual decimal digit and convert it into binary.  4 binary digits let you express all the numbers from 0 to 9, so you can represent each decimal digit with 4 binary digits.  Why would we do that?  It does have some advantages when expressing numbers which could grow quite large, and we don't want to lose any precision.  Dates and times are a good example.  We could (and often do) convert a time into just the number of seconds since X, and then store that as a big binary number, but using BCD lets us encode each digit in a date exactly.

graphic explaing BCD vs binary


Converting decimal numbers into BCD

Now I have these values which seem all over the place, but are actually just numbers which were converted from binary to decimal, when they should have been converted from BCD into decimal.  No information has been lost, I simply need to figure out how to correct the encodings of these numbers.  Though, it took me a while to even wrap my head around what set of operations I wanted to perform.

After thinking it through for a while, and doing some trial and error with online calculators, I figured it out.  I had to convert my decimal values back into (normal) binary.  I had to then break that binary number up into groups of 4 digits each.  And then, convert each of those groups of 4 binary digits back into a decimal number.  Finally, I could just concat those decimal digits into my correct value.

From about a week I didn't have that much data to correct.  I could have very easily written a little script to iterate over each value and convert it for me.  I didn't need to do this in SQL, and in fact I wasn't even sure I could do this in SQL.  But I was pretty sure SQL could convert decimal to binary and back again, and that (plus a bunch of string manipulation) was really all I needed.

 

The Query

So without further ado, here is the monstrosity of a SQL query I wrote to convert values which had been incorrectly converted from BCD to decimal as if they were simple binary numbers.


I'll attempt to walk you through it, but if you don't know SQL you might as well just skip ahead.  I start with a subquery, as I like to do.  This subquery is just trying to convert the numbers from decimal back to binary.  This is the part doing work:

select right((state::int / 10)::bit(32)::varchar, 20) as binary_num

First it has to divide by 10, then convert to binary, then cast as a string and just take the last 20 digits (4 bits * 5 decimal digits = 20 bits in BCD).  Now that I have that BCD string, all I have to do is split it up into groups of 4 bits.  Each
SUBSTRING(binary_num, 1, 4)::bit(4)::int::varchar

Is grabbing one group of 4 bits, converting it from a string to a binary number, then to a decimal digit, and then back to a string.  And then I just concat those together, convert that back to an int so that I can multiply that by 10, and that is my corrected value.

With that I had a bunch of lines of the ids that had to change and the values they had to change to.  Now, despite having written that query, I can never remember how to write an insert or update that uses a subquery off the top of my head.  Instead I just copied the results of the select into Sublime, and used my favorite text editor feature of all time, multi-line cursor.  I just wrote an update statement for each line all at once and ran those few hundred statements together in a transaction.

 

Result

And with that, all was right.  I had my priceless data, and could admire my graphs to my heart's content.  I'll leave you with this graph of the original vs the corrected data for your viewing pleasure.

a graph of actual water meter readings vs sdr readings