Subscribe via RSS
27Sep/200

Smushing JSON into submission!

I don't even know how to describe this operation on JSON. The basic idea is that we want to deserialise a stream into something legible, without creating a class for each item in an array. json2csharp believes that each item should be an array since it sees them all as individually named classes. Let me prove it! Here's a chunk'o'data:

{
    "trainCount":122,
    "requestTimestamp":1601124556789,
    "responseTimestamp":1601128156789,
    "nextUrl":"https://junatkartalla-cal-prod.herokuapp.com/trains/1601128156789",
    "trains":{
        "8":{
			"id":"8",
			"from":"LR",
			"to":"HKI",
			"title":"IC8",
			"latitude":60.172097,
			"longitude":24.941249,
			"speed":0,
			"direction":0,
			"category":"IC",
			"status":"1",
			"delta":60,
			"trainType":"LONGDISTANCE",
			"updated":1601127783841,
			"action":"deleted"
        },
        "9":{
			"id":"9",
			"from":"HKI",
			"to":"LR",
			"title":"S9",
			"latitude":60.571148,
			"longitude":25.199523,
			"speed":0,
			"direction":0,
			"category":"S",
			"status":"1",
			"delta":60,
			"trainType":"LONGDISTANCE",
			"updated":1601128143878,
			"action":"modified"
        }
    }
}

So, if you slam that JSON into json2csharp, you'll get the following:

    public class 8    {
        public string id { get; set; } 
        public string from { get; set; } 
        public string to { get; set; } 
        public string title { get; set; } 
        public double latitude { get; set; } 
        public double longitude { get; set; } 
        public int speed { get; set; } 
        public int direction { get; set; } 
        public string category { get; set; } 
        public string status { get; set; } 
        public int delta { get; set; } 
        public string trainType { get; set; } 
        public long updated { get; set; } 
        public string action { get; set; } 
    }

    public class 9    {
        public string id { get; set; } 
        public string from { get; set; } 
        public string to { get; set; } 
        public string title { get; set; } 
        public double latitude { get; set; } 
        public double longitude { get; set; } 
        public int speed { get; set; } 
        public int direction { get; set; } 
        public string category { get; set; } 
        public string status { get; set; } 
        public int delta { get; set; } 
        public string trainType { get; set; } 
        public long updated { get; set; } 
        public string action { get; set; } 
    }

    public class Trains    {
        public 8 8 { get; set; } 
        public 9 9 { get; set; } 
    }

    public class Root    {
        public int trainCount { get; set; } 
        public long requestTimestamp { get; set; } 
        public long responseTimestamp { get; set; } 
        public string nextUrl { get; set; } 
        public Trains trains { get; set; } 
    }

So, that's actually uncompilable code. Is uncompilable a word? Dunno... this is actually the first time that json2csharp has failed me! No matter the options selected on the site, the output was always bad code... json2csharp doesn't work with ALL json! So, what to do? Well, we actually need to mangle this JSON into submission. The best bet would be to move that train id/number into the array object as a parameter, rather than having it as the dictionary key. We have two methods to do this...

Using jQuery MAP Function

If you are pulling JSON from a hosted browser, then you can run JS in the browsers console and produce cleaner JSON. In this case, you want to use jQuery's MAP function to rewrite each array object:

json_data.trains = $.map(json_data.trains, function (data, idx) { return data; });

If you feed the JSON at the top of this post into that function, you'll get the following:

{
	"trainCount": 122,
	"requestTimestamp": 1601124556789,
	"responseTimestamp": 1601128156789,
	"nextUrl": "https://junatkartalla-cal-prod.herokuapp.com/trains/1601128156789",
	"trains": [{
		"id": "8",
		"from": "LR",
		"to": "HKI",
		"title": "IC8",
		"latitude": 60.172097,
		"longitude": 24.941249,
		"speed": 0,
		"direction": 0,
		"category": "IC",
		"status": "1",
		"delta": 60,
		"trainType": "LONGDISTANCE",
		"updated": 1601127783841,
		"action": "deleted"
	}, {
		"id": "9",
		"from": "HKI",
		"to": "LR",
		"title": "S9",
		"latitude": 60.571148,
		"longitude": 25.199523,
		"speed": 0,
		"direction": 0,
		"category": "S",
		"status": "1",
		"delta": 60,
		"trainType": "LONGDISTANCE",
		"updated": 1601128143878,
		"action": "modified"
	}]
}

Very nice.

Using C# Regex

I've never thoroughly learnt Regex and it still makes me sad. One day I'll sit down and go through a course. For now, googlin' works nicely to find an example for this scenario. Effectively we want to remove the "NUM": and just leave the curly braces. We then also need to remove a curly brace at the end.

            var data = (new System.Net.WebClient()).DownloadString(nextUrl);
            data = new Regex("\"([0-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9])\":").Replace(data, "");
            data = data.Replace("\"trains\":{", "\"trains\":[");
            data = data.Replace("}}}", "}]}");

So, the first line downloads the data. The second uses Regex to find anything in double-quotes that's a number from 0-9. I actually wanted 0-9999, but it seems you need to match each character 1-by-1, so I gave it options with | (pipe) up to 99999. From there, the third line turns the trains object into an array and the final line closes that array with a square bracket instead of the existing curly brace.

Final C# Class Output

With either of the methods above, you end up with cleaned JSON. From here, slapping that back in json2csharp gets you the following:

    public class Train    {
        public string id { get; set; } 
        public string from { get; set; } 
        public string to { get; set; } 
        public string title { get; set; } 
        public double latitude { get; set; } 
        public double longitude { get; set; } 
        public int speed { get; set; } 
        public int direction { get; set; } 
        public string category { get; set; } 
        public string status { get; set; } 
        public int delta { get; set; } 
        public string trainType { get; set; } 
        public object updated { get; set; } 
        public string action { get; set; } 
    }

    public class Root    {
        public int trainCount { get; set; } 
        public long requestTimestamp { get; set; } 
        public long responseTimestamp { get; set; } 
        public string nextUrl { get; set; } 
        public List<Train> trains { get; set; } 
    }

Thank you json2charp, that's exactly the reusability that I was looking for!

26Sep/202

Repairing Atari 2600 Original Wireless Controllers

So, I've recently been repairing a large selection of Atari paraphenalia and, included in the container-load, was an official Atari-branded CX-42 wireless controller kit! The setup is pretty awesome; the base unit has a power input and then an output to go to the console. This means it doesn't need a separate power adapter as it chains into the power for your Atari. It then has the two controller plugs which you simply insert into the left and right controller ports on your console. Finally, the joysticks are more-or-less standard one-button Atari joysticks with extra 4cm bases to contain a 9v battery and radio circuitry.

DSC00668

DSC00674 DSC00671 DSC00698

Of course, this came to me due to being unhealthy. One of the controllers wouldn't go left! I'd usually associate this to cable failure, but... well... they don't really get much abuse in this scenario! They needed a good clean anyway, so the tear-down and diagnosis begun.

Is it the controller? (Hard way!)

So, just because I'd previously torn 100s of these apart, I went straight to the controller to check the internal switches. The construction of these is relatively simple, until you try to separate the joystick circuit board from the actual joystick... so many screws and springs fly everywhere. Regardless, once the unit was open, all switches were tested and found to be functional. I didn't think of taking a photo at the time, so you'll just have to imagine.

Is it the controller? (Easy way!)

After a little googlin', I stumbled across this hint stating that you could 'hear' the controllers using an FM radio. Hah, of course you can... It seems that they use frequencies down around ~40mhz, but somehow you can hear this at ~100mhz on your FM radio. So, what to do? Find an FM radio first. Fortunately I had some on the shelf thanks to wanting to listen to tapes a few months back.

On Windows 10, you'll find there's no more sndrec32. Instead you need to browse over here and Voice Recorder. Yey for anti-monopolistic effort! Anyway, I managed to record the following:

What you'll hear above is: Static -> radio station -> static -> radio station -> static -> weak carrier signal! -> misc. tuning -> STRONG CARRIER SIGNAL! -> 5 presses of the fire button -> ~7 full rotations of the joystick -> 6 presses of the fire button (the last one is longer) -> static. Totally random! But it's a great way to test.

As you can hear above, I started just above ~102mhz FM and scrolled down until I found the carrier signal. Note that I had difficulty originally finding the signal as it's not that strong. Make sure you hold the joystick against whatever FM receiver you're using.

Once the carrier signal was found, I then fine-tuned it until the signal was the strongest and began mashing buttons. Of course, just because LEFT is transmitting something, doesn't mean it's transmitting the correct signal! But hey, we can now check the base to see if there's any obvious issue.

Is it the base unit?

The circuitry inside this unit is, thankfully, quite easy to trace and diagnose. The unit consists of two individual circuits, decoding each controller independently. This is actually a life-saver, thanks to one of the joysticks being 100% functional! With my multimeter in-hand, I went ahead reviewing the circuit and measuring signals along the way. Doing this for both joysticks and both circuits meant that it was straight-forward to determine where the signal started going funny!

DSC00648

Starting from the output, there are two hex-inverter chips on each side. All 6 inverters (2chips x 3inverters) on each side are used and these flip the signal before sending it out to the controller port. The left button was seeing a twitch in the voltage, but not enough to flip the inverter to full +5v. The input was meant to drag to ground, sending the full signal out, but it wasn't happening.

Tracing the signal back, there is an OKI MSM4015RS IC and, for the life of me, I still can't find a datasheet online. I thought this would be a show-stopper, but after testing the signals on this IC for both joysticks when the fire button was pressed, it turns out they're both reporting the same values.

I therefore traced the value back up towards the output and found that the output after the first inverter wasn't being dragged low enough. It was 0.6v on the working joystick and 0.7v on the failing joystick. The output of the inverter is tied to ground with a green-cap and tied high with a 4.7k resistor.

The resistor checked out, but I had no way to test the capacitor with my multimeter. Instead, I swapped the capacitor from joystick one's side to joystick two's. Surprisingly, this now saw joystick one's LEFT button working and joystick two's was now faulty. Nice!

Replacing all green-caps

You'll find three different-valued sets of green-caps on this board: 10x 183k100v (18nf), 10x 223k100v (or 2A223K) (22nf) and 6x 104k100v (100nf). I went ahead and purchased a full set of them from Jaycar with the goal to replace every one of them.

DSC00677

Who knows how close another is to frying?

DSC00696

The aftermath... (did I say only the green-caps? Ooops.. I didn't discriminate and took out the electros as well.)

DSC00701

Removing and replacing was easy enough. I really recommend Goot-Wick desoldering braid for cleaning up the PCB whilst you're doing things like this.

Now up doesn't work?

Hah, seems that enough plugging-and-un-plugging of the controller output cables from the main board caused one pin to fail. Thanks to standard technology, there were plenty of these plugs in my junk box, although not with the same pin count...

DSC00687

So I borrowed an internal connector from a three-pin plug and soldered it in. Worked perfectly!

A minor note on the usage of these wireless controllers

With the wireless base unit powered-on and fully-connected to your Atari, it'll send spurious/erratic/totally-crazy signals to the console on the joystick cable of any joystick that is turned off! There is therefore a correct sequence for powering everything up... Turn the joysticks on first and then the base unit. Note that the base unit doesn't have a power switch, so I'd recommend always turning it off at the wall. I suppose you could then leave the Atari power switch on, as you'll be using the wall switch as the power cable is chained through the wireless controller receiver. Just make sure that both controllers are powered on BEFORE you turn on the wall switch!

When I was first diagnosing this kit, I thought all was pointless after seeing the random signals coming out of the base unit. I was very happy to see the signals settle once the joysticks were powered up!

Testing

This unit worked splendidly with 2600-series consoles and games.

DSC00708

Even 2600 games in a 7800 console. What didn't work was the built-in asteroids for/on the 7800.

DSC00712

For some reason, the down and fire buttons won't work. Of course, a standard 1-button Atari 2600 joystick works fine on 7800-Asteroids, but this unit doesn't. I did a little digging and found that the pins aren't brought straight to ground... instead they hover around 150-250 ohms... I wonder if that's enough to not send through a proper button press? Also, they seem to 'repeat'... the multimeter actually goes pretty damn crazy when a button is pressed, beeping on and off as the resistance floats near-zero. As mentioned above, each output is tied high by a 4.7k resistor and low by a 22nf green-cap capacitor. I assume the cap is there to de-bounce the incoming signal, but maybe it's not big enough to trigger a single press for the 7800? I don't want to modify this unit as it's very original, so I'll just suggest that if anyone else wants to use this on a 7800 then they should tinker with the pull-down capacitors on the output lines.

Again, they worked 100% perfectly with all 2600-series equipment I tested.

Battery Cover

One was missing, so I used my Creality CR6-SE to bring a replacement. It didn't turn out toooooo bad. Works well when there's a battery inside... falls out when there's no battery!

DSC00715 DSC00716 DSC00718

DSC00722

Filed under: Retro 2 Comments
16Sep/204

I’m not original…

In fact, my new best friend is over 16 years old!

DSC00644

I ... thiiiiink ... he's half deaf... might be time to replace his ears.

12Sep/200

EZIO + OS9 + Hypercard (Or Just Windows)

The EZIO Board is a serial-based I/O module that can connect to both Windows and Macintosh machines. Actually, it can connect to anything that speaks RS-232. One of these came up on eBay recently and I couldn't resist. I saw the Macintosh serial port and decided to give it a go. It's really similar to an Arduino, but from a few decades before the Arduino was even a dream. If I'd known about these back in the early 2000s then I would've definitely had a very nice automated model railway. But alas, I only happen to find one now thanks to eBay!

DSC00616

The unit has 10 digital output lines, 10 digital input lines, 8 analog-to-digital lines and two PWM lines. You then get 4 +5v terminals and 4 GND terminals. There's a PIC microcontroller in the middle running the show and a MAX232 for the RS-232 comms. The unit has a DC-rectifier, so you can feed it 5-15v either AC or DC. The 5-15v is literally the operating recommendations of the 7805 voltage regulator on-board.

There's a whole lot of code on the old site (yeah, you have to use web archive to get to it), but it's mainly for Director!? and Macintosh. Hilariously, the Macintosh example uses Hypercard! Before booting up the Power Mac, I instead wrote a quick bit of C# to test out the unit.

ezio-test-app

The shot above uses dotnet-ncurses, allowing the console to act like a canvas. It's really nice to be able to draw text to specific areas, rather than scrolling the screen. Anyway, the basic idea is that you can control the digital out and then everything else is read in. Interestingly, floating pins show some very random values... so if you're using this device, make sure you tie everything to ground or use pull-up resistors where appropriate.

Of course, the whole reason I bought this was due to the Macintosh serial port. I wasn't overly-energetic, so I tried a virtual Macintosh first...

ezio-basiliskii

After installing Hypercard, the app came up, but the performance once it started trying to interact with the serial port was terrible. It also just didn't work, so I gave up and booted up the Power Mac.

DSC00618

Yup, works a charm. Hypercard is pretty clunky, but I'm sure you could do a lot with it. I'll have to dig out the railway track and control a train!

5Sep/200

Philips CDI 450 – Laser Replacement

The Philips CD-i (Compact Disc-Interactive) brand/tech was released back in 1990 to add a level of interactivity to CD-ROM based entertainment. Philips, from 1990 through to 1998, produced and released multiple devices for both the home and educational markets based on this technology. One of those models was the CDI 450 and I just happened to stumble across one a long time back at a Belgian flea market. It's been in a box for quite a while and I've only just gotten around to looking at it... The driving factors were: #1 COVID lockdown is driving me crazy and #2 there's a version of The 7th Guest for this unit!

DSC00507

The unit came with the power supply, a controller with it's face missing and, randomly, a game CD in the drive.

DSC00513 DSC00510 DSC00509

The controller was obviously useless, so I went to GAME OVER? in Amsterdam and picked up the cheapest controller I could find.

DSC00586

There's the standard rule of 'sunk cost' where you don't spend large amounts of money on something that could be dead. I then returned to Australia and the unit has been in the box since. Only recently did I turn it on...

DSC00519 DSC00523 DSC00524

DSC00532

Cool! It works! My French is rusty, so I wanted to try and get other games working. No matter what I tried, the unit would not read CDRs. Every google search I tried lead me to believe that the laser was gone, or going, so I scoured eBay for a replacement. It turns out that searching for VAM-1201 will give you shops in China that have the exact 'new old stock' component that I needed! I ordered one, expecting it to take years, instead having it arrive in just under two weeks!

DSC00537

Popping open the CDI was easy enough. There are four screws in the unit. Two are in the CD bay and two are in the 'optional module area' to the left. Open the CD lid and then remove the plastic shell to the left. It has two clips that need to be pushed in. Woah, what's this? My unit has the Digital Video Cartridge!

DSC00538 DSC00540 DSC00542

With the screws out, you'll now find the RF shield in the way... remove this evenly, prying it up from each corner and making sure there are no wires in the way.

DSC00544

Mine had a lovely amount of discolouration... maybe from the rain that was falling in the flea market in Belgium? Fortunately the motherboard looked pristine.

DSC00547

The Laser aparatus consists of the laser unit and drive motor in a plastic housing, attached to a metal plate via rubber suspension joints. This whole component is held in place by the two screws from the main case and two plastic lugs along the top frame. Gently lift the whole lot, evenly pulling it up. The top two lugs are quite tight, to make sure to ease the unit vertically away from them until it's free. Once done, don't lift too high as you'll first need to disconnect the data ribbon cable and power cables underneath.

DSC00549

Once done, you then need to remove the laser unit from the metal plate. It's held there by four rubber spacers. Note that these are old now, so be very gentle when sliding them out laterally from the slots in the laser housing. I managed to break one when doing so, but fortunately this didn't impact the ability of the unit.

DSC00560

Once you've slotted the new laser on the housing, place it back into the main unit. This is as simple as lining up the lugs at the top, holding the unit at 45-degrees whilst doing so. Note that the wired cable might be longer than the original... just place the wires somewhere in the spacing to the bottom-right. Also make sure the wires don't get pinched when you place the RF shielding back in!

From here? We test...

DSC00562 DSC00563 DSC00564

DSC00565

DSC00567 DSC00569 DSC00571

DSC00572 DSC00573 DSC00574

And the icing on the cake:

DSC00582

A perfect game to test out the DVC! It worked very very nicely.

Filed under: Retro No Comments
1Sep/200

Atari 2600 Jr – Reset/Select Switch Repairs

I'd recently come across an Atari 2600 Jr with faulty select and reset buttons. Turns out that the mylar strip that conducts the button presses to the motherboard is toast. It doesn't conduct anything at all and I can't work out exactly where the break is.

DSC00424

To test if the button area even works, you can insert wires as above and check for continuity. In this case, they did, so I considered the following options to repair them.

Silver Conductive Pen

This nearly worked, but I couldn't get the paste to set correctly. The pen is from Jaycar and the basic idea is to draw a line where you want the circuit and let it set. I drew some pretty bad lines on the plastic film, but my first attempt seems to have failed as I drew the tracks too thickly. The 'ink' only becomes conductive once it's totally dry and I'm blaming winter and the fact that I don't have an incandescent bulb in the house anymore.

DSC00428 DSC00431 DSC00432

The next attempts were seemingly too thin. It also seems that you can't 'restart' a trace... the joint isn't conductive? Finally, the resistance seen down the track is totally erratic... but that may also be due to wet ink.

Threaded Wire

I punched a few holes in the mylar and threaded copper wire through. It was a little too stiff but, once in-place, seemed to work quite well! The main issue with this method is that, at either end of the plastic strip, adhering the wire to the conductive trace is difficult. Of course, at the motherboard end you can just jam the wires in the socket!

DSC00436

At the button end, you need to slip it in under the top-layer of plastic. I didn't feel confident that I could keep a valid joint and therefore didn't pursue this technique.

Microswitches

Prior to opening and testing the methods above, I was always intending on just replacing whole plastic strip with microswitches. There's a nice plastic base behind the push buttons and one could easily drill in some switches. This would also give a nice tactile experience to what is (from the factory) a really awful and mushy button press.

DSC00444

I went ahead and drilled holes slightly smaller than the switches. From here, I gouged out the rest of the required space as I wanted a tight fit. Of course, I was imagining things thinking that I tight fit would be enough to hold the switches in place... a hard button-press would probably send them into the case.

DSC00449 DSC00451 DSC00458

Therefore I glued a strip of plastic (yeah, it's a cable-tie) along the back of the holes as a backing plate for the switches. This worked perfectly! I probably should've soldered the wiring first, but it was easy enough once the switches were in position!

DSC00467

Once it was all back together, it turns out that the buttons were pressed in 100% of the time. To fix this, I had to drill out a section of the plastic where the button meets the switch. This worked nicely. I then decided to remove the rubber as the press was being overly-softened by it. I'd recommend you test it both ways to see which feels the best... you can also try mounting the rubber on the actual case to make sure the alignment is correct.

DSC00481 DSC00478 DSC00486

From here, I just soldered the wiring up to a standard pin-header which fit snugly into the socket on the motherboard.

DSC00487

Testing began and the switches performed perfectly!

Filed under: Retro No Comments