Subscribe via RSS
19Jun/1620

Commodore 64: Serial Interface to Arduino

So, in my previous post, I was heading towards building an archaic circuit to control trains with the User Port. This would've worked, had I spent a lot more time and built a very complex circuit. Instead I've now chosen a new path... let's hook the C64 up to an Arduino and do most of the work there. The C64 can be the display and input/output for controlling the trains.

Interfacing both components

The C64 User Port has both a 'parallel port' with 8 i/o pins and a serial port. I initially wanted to use the parallel pins, but came to the conclusion that I'd have to write my own language on both sides and deal with the data transfer timings and clock synchronisation. Instead, it'll be easier to use industry-standard RS-232!

I suppose this is a bit of a cop-out. I wanted to build something that was dated to the level of technology that existed back when these machines were in their prime... unfortunately my electronic knowledge isn't up to scratch... so getting to a variable 12v output wasn't overly easy. It also would not have been PWM. Due to all this, including the Arduino into the mix isn't such a bad idea. Plus, everyone I'd asked for help told me to do this... even sending me links to my own blog posts :)

DTE vs. DCE

Serial plugs have a single channel, with each end having one transmit (TX) and one receive (RX) pin. Each end will send data down the cable via the TX pin and expect to receive data on the RX pin. Standard serial cables are 'straight through', meaning that the TX pin is connected to the TX pin and likewise with RX. Doesn't quite make sense, does it? How are two separate devices meant to eachother if they are both transmitting down the same singular TX wire and hearing silence on the RX?

This all becomes clear once you realise that devices fit into two categories: DTE (data terminal equipment) and DCE (data circuit-terminating equipment, also known as data communication equipment.) In the end, these two devices boil down to one being the master (the DTE) and one being the slave (the DCE.)

Of course, you can purchase 'cross-over' cables for serial connections. These are known as null-modem cables and allow you to hook two DTEs together. Say, for example, you want to transfer a file from your PC to your Amiga, or somesuch!

In my previous serial project, when I connected the IBM receipt printer to the Arduino, I needed the Arduino to be the master, and so I hacked around until I had correctly configured it as a DTE. This time around we want the Arduino to be the DCE. Due to this, be careful to follow the pinouts and wiring from the serial port to the MAX232 in the circuits below!

Note: For further reading/wiring on RS-232, there's a good article at avr Programmers and another at Advantech.

C64 Serial Port

The User Port on the C64 also has serial connections. These are TTL and so need to be brought up to the RS-232 5v standard. The MAX232 IC will do this for us quite easily. We'll also use one at the other end for the Arduino.

UPDATED (2024): The CTS and RTS wires were incorrectly ordered on the original diagram. The following diagram is now correct, but I've decided to leave the comments at the bottom of this article which state otherwise.

The circuit is derived from 8bitfiles.net. This circuit was also correct in that the pins are wired up as DTE. This means that you could use it, as-is, to also hook to a modem or any other DCE device.

The MAX232 needs few extra components. Fortunately, these extra components are identical on both ends, so buy everything in duplicate! The capacitors are all 1.0uf electrolytic. I used 1k resisters on the LEDs so as not to draw too much current from the User Port.

Arduino Serial Port

This is nearly the same circuit as the C64 end. The funniest thing happened here... if you google enough 'arduino max232' you'll just loop back around to my post, from ages ago on interfacing an IBM printer to the Arduino. Just make sure you don't use that circuit! It's DTE, we need DCE as per below! I've left out the RTS/CTS as I don't intend on using any form of handshaking in this project. It's still in the circuit above for the C64 so that you can use the port for other purposes.

ARDUINO-RS232

As per usual, make sure you DO NOT apply 5v in the wrong direction... I did and it ruined a few caps and possibly the IC. Garbage then came through the serial port. If this ever happens, then throw out the components and start again; you'll never be able to trust them.

Also make sure that you use the 5v pin on the Arduino. AREF is NOT a valid voltage source.

Hooking it all together

Build both circuits above and give one a male and the other a female db-9 connector. The DCE device usually gets the female, so put this on the Arduino-side!

DSC03947 DSC03956 DSC03954

DSC03955 DSC03950

If you want to roll your own cable, then grab some grey IDC and two crimp-style plugs. Just make sure that you have pin 1 matched to pin 1. If you're splitting the cable, then paint a wire (or use a marker) to ensure that you get the orientation correct. It's really easy to confuse pin 1.

DSC03998 DSC04000 DSC04002

From above, you can see the pin numbering. I slid the second port all the way to the end, prior to crimping, to ensure that the numbers matched up. Using the red '#1 wire' on the cable worked wonders too.

Testing with Strike Terminal 2013 Final

Download Strike Term 2013 Final from here and then get it to your C64. I copied the D64 to my SD2IEC and loaded it up. Hit M and select User port. Hit b and switch it to 1200 Baud (or other baud, depending on what you've configured in the Arduino.)

DSC03976 DSC03978 DSC03957

DSC03958 DSC03964 DSC03965

Once ready, hit f5 and then hit enter on the default server. This'll start sending modem AT commands down the serial and they should start showing up at the other end. Either open the Arduino Serial Monitor... or edit the code to display it. I bought some 8x8 LED Matrices to render the data coming in.

DSC03963 DSC03971

There were no real caveats here... everything just worked! Press f3 to get to the terminal. Hit commodore+e for local echo and then commodore+i to 'send id'. You should now be able to type freely... everything will be sent down the wire.

DSC03983 DSC03984 DSC03985

DSC03986 DSC03987 DSC03988

At that point I only had one matrix... so the last char typed was displayed.

Writing C code to use the Serial Port

Nanoflite has written a 2400 baud User Port Serial Driver for cc65. I originally tried to use this at 1200 baud, as that's what I'd been using everywhere and heard it was the max the User Port was capable of. It turns out that this driver only supports 2400 baud! Download it and put the source somewhere.

Switch to the driver directory and compile it:

cl65 -t c64 --module -o c64-up2400.ser c64-up2400.s

Copy this to the folder that has your source file it. I slightly modified the example.

#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <serial.h>
#define DRIVERNAME  "c64-up2400.ser"

static const struct ser_params serialParams = {
    SER_BAUD_2400,      /* Baudrate */
    SER_BITS_8,         /* Number of data bits */
    SER_STOP_1,         /* Number of stop bits */
    SER_PAR_NONE,       /* Parity setting */
    SER_HS_NONE         /* Type of handshake to use */
};

int main (void)
{
  int xx;
  
  clrscr();
  puts("C64 serial ...");

  // Load driver
  ser_load_driver(DRIVERNAME);

  // Open port
  ser_open(&serialParams);

  // Enable serial
  ser_ioctl(1, NULL);

  for (xx = 0; xx < 10; xx++) {
	ser_put('C'); 
	ser_put('6'); 
	ser_put('4');
	ser_put('.');
	ser_put('.');
	ser_put('.');
  }
 
  return EXIT_SUCCESS;
}

Compile this:

cl65 -t c64 -O -o trainctl2 trainctl2.c

I then put it on the SD2IEC and loaded it via LOAD "0:TRAINCTL2",8 followed by a RUN.

DSC03993 DSC03989 DSC03991

DSC03992 DSC03994 DSC04003

Shit... worked... this is great! Next it's time to put a PWM throttle onto the Arduino and control it from the Commodore... I'll tinker with graphical programming in C also.

1Jun/160

Parallel Port: Digital to Analog

Most parallel ports on most computers (Amiga, C64, PC, etc...) have (at least) 8 true digital pins that one can interface with for either input or output. This can be extended using shift registers or multiplexers; I've written up an example of this here.

With a lot more pins at one's disposal, more items can be controlled; as long as what you want to control is in the digital realm. To control a standard DC motor, for example, you'll need to be in the analog world and we'll describe how to get there below.

Digital to Analog Converters

The basic principal is to use a number of digital inputs and map these to relevant resistance values on an output. If you had 4 pins available, then you could determine the maximum resistance you needed and divide by the number of pins. You'd then make sure that, as each pin was brought HIGH, that the resistance summed towards the final value that you required.

You can either use a bunch of resistors to do this, or an integrated DAC circuit.

R/2R Ladder

This circuit consists of a bunch of resisters in parallel/serial, using properties of such combinations to provide a stepped resistance output. This is known as an R/2R Ladder and is a popular method for converting digital signals to analog.

We're going to implement one using 10k/20k resistors and an LM358 opamp to buffer the output. This part of the circuit is borrowed from the 8-bit digital to analog converter circuit over at IKALOGIC.

Combining it into our Parallel Port Interface

The 8 outputs from the 595 need to be de-coupled from the LEDs and provided as the inputs to the resistor ladder.

Parallel-Port-with-D2A

As that we can send any value to the 595, you don't really need to be careful as to which end is the MSB, but do remind yourself of it as it'll become important when writing the software.

DSC03731 DSC03732 DSC03733

You should now be able to check the voltage on pins 1 or 2 to see the variance between 0 and 5v when you're switching the bits on and off.

DSC03740 DSC03745 DSC03746

To my surprise, the output voltage was nearly exactly double the byte value being output by both the Commodore 64 and the Windows Parallel Port.

Once the test breadboard produced the result I wanted, I confirmed it all by soldering it together on the PCB. Not the ugliest mess I've created, but not very far off! And... it works.

DSC03755 DSC03754 DSC03751

What's next?

Now that we have an analog interface, we can control a PWM throttle. To do this, we'll go back to the Arduino world and steal a motor controller. I've previously worked with H-Bridges before and will use a module to make this easy. Controlling direction will be easy also!

26May/160

Parallel Port: Shift Registers

Now that we've controlled a LED by a single pin on the Parallel Port, it's time to expand our abilities. The goal of this post is to describe the usage of Shift Registers and then consume a minimal amount of pins, 3 out of the 8 available, to control up to 64 outputs!

A Shift What?

So, you have 8 digital input/output pins on the Parallel Port. This isn't the greatest amount and it'd be really nice to extend the amount available. There are a few ways, but a popular method is to employ a shift register.

A shift register is an IC which takes a 'serial' input and then outputs this on it's output pins in 'parallel'. By 'serial', we mean that the IC accepts input data on one pin only. This data is provided by you, as either a '1' or a '0'. Once you've set the value on the input pin, you then toggle another pin, known as the 'clock' pin, to tell the IC that the data is ready to be consumed.

The shift register, once the clock pin is toggled to a '1' and then back to a '0', will look at the input pin and then copy this value into it's internal register. We're using a 74HC595 which has 8 internal registers and therefore 8 output pins. At this point, the IC shifts all values on it's 8 internal registers up one slot and then sets the very first internal slot to the value you've provided.

You can then provide 7 more values, toggling the clock pin between each, an the IC will shift them along it's internal registers. What you've now done is set an 8-bit value inside this IC. Once the IC contains the value you've requested, you toggle the 'latch' pin and the IC will shift these 8 values out to the 8 output pins. These are known as 'parallel' as there is a single pin for each value; as opposed to the input which is serial (or one-after-another) on a single pin.

So, we've used 3 pins/wires here to control 8 output pins... pretty neat hey? We've turned our original 8 Parallel Port pins into (8-3) + 8... 13!

But wait, there's more! There's an 'output' pin on the shift register that reports the 'shifted off' value. What can you do with this? Feed it into a neighbour shift register as the 'input'. Hook up the same clock/latch wires as the first register and then, when you shift the 9th bit into the first, the very first bit you shifted in will be shifted out of the first register and into the second.

This means that, with the same 3 wires, you now have 16 outputs! Of course, you can keep doing this. I can't find anywhere that mentions how many you can effectively chain up. Of course, as you add more, the time to toggle out the values increases and you need to make sure that your code/hardware has time to think about other things instead of spending it all talking to the shift registers.

Connecting it to our previous circuit

We only used one line of the parallel port in the previous circuit and therefore only controlled one LED. For this first shift register, we'll need 3 lines. First thing is to hook up three LEDs with matching resistors. We could just hook two other lines up direct to our new shift register, but I like being able to visualise the data (and troubleshoot issues!)

Parallel-Port with 74HC595With this circuit, you'll be able to use the sample code in the previous post to control the 3 LEDs.

Sending out a 1, 2 or 4 should switch them on individually. Sending any combination of these, by adding them together, will turn on the associated LEDs. For example, sending out the decimal value 3 will switch on the first and second LED. The value 5 will switch on the first and third LED. As the value makes it to the port, it is split into it's individual bits, which are then translated to the data pins.

Once these are working, we're going to splice in some opto-couplers. We don't want any untoward voltages getting back to the parallel port. Optocouplers contain an LED and an internal light sensor. When power is applied to the input, the LED lights and the light sensor receives the signal. This is then output to the secondary circuit. This effectively provides an 'air gap' between the two circuits.

From these couplers we can control our shift register(s). Hook the three outputs to the 74HC595 shift registers SERIAL, CLOCK and LATCH pins. Remember the order as they each play key roles (as per the description of how they work above.)

Once you're ready, check that the three input LEDs react accordingly to basic Parallel Port data. Note that you may get erroneous data coming out of the shift register from the get-go. Data coming off the Parallel Port during system boot cannot be controlled and may cause havoc. We'll do something about this in a later article.

Building this required a LED array... you could do it easier and get one of those bar-graph arrays. Wiring up all the individual LEDs gets a little tricky.

DSC03682 DSC03683 DSC03684

Controlling the data output

Based on the initial description of the shift register, we know that we have to control the 3 data lines in a special sequence. First thing we need is an 8-bit data value to send out. Once we have this we can send each data bit out via the SERIAL line; toggling the CLOCK signal in-between. Finally, toggling the LATCH should see our value displayed in a glorious binary LED representation!

I've used Windows and the Parallel Port code here to manually try and turn on LEDs. My wires are hooked up as D0:SERIAL, D1:CLOCK and D2:LATCH. I am going to send 00000001 as the value to ensure that all LEDs are turned off bar the first.

  1. Ensure that LATCH is low (red)
  2. Toggle D0 to RED, this is a '0' for the first bit of the serial value.
  3. Now toggle the CLOCK (D1) on and off 7 times.
  4. Toggle D0 to GREEN.
  5. Toggle the CLOCK on/off once more.
  6. Toggle D2 on and off...

If everything is hooked up, then you should now have one LED showing on the output of the 74HC595. It didn't quite work with this initial circuit... LEDs would light a little randomly.

DSC03685 DSC03691 DSC03693

Noise

Although the above circuit worked, it was not reliable! Every now and then one LED (or two) past the one I wanted to switch on would also switch on! Sure, my soldering was dodgy, let alone the wiring also being messy. Either way, noise was being introduced and the flipping of the serial and clock was jumbled, causing random output.

The solution to this was to put a 100nf capacitor across the +5v and gnd supplying the 74hc595. This cap should be put as close to the IC pins as possible. Once in place, this stabilised the data from the PC Parallel port.

References

- HowTo: Understand the 74HC595 (David Caffey)
- Gammon Forum: Using a 74HC595 output shift register as a port-expander
- protostack: Introduction to 74HC595 shift register – Controlling 16 LEDs

What's Next?

Next is a 12v throttle. I intend on using the described sample here. The only issue is that it wants a potentiometer to vary the output voltage. This is an analogue method; we'll convert it to digital by calculating 8 resistor values to imitate the throttle at 8 positions.

I'll write this up soon once I've completed the circuit.

22May/160

Parallel Port: Model Railways

Am sure this has been done 100 times before, but I've recently acquired two relic computers and I want them to control my trains. They both have ports consisting of 8 digital I/O pins and I'll utilise these to control a throttle, direction and points. I'll also use them to read sensors.

Having only 8 pins provides a nice challenge... but nothing a few shift registers cannot handle!

First step, LEDs

Let's get started very simply by switching a LED on and off. One might think that, as that LEDs are synonymous with digital electronics, that one can just hook it up to a digital pin and set the output to HIGH. One could... but the current draw would likely kill the 'controller' that the parallel port relies on!

Due to this, you must make sure that you provide sufficient safeguards to prevent damage to your delicate hardware. Once you trash a parallel port in a system (especially of this vintage), you cannot go back.

The trick we'll use is known as opto-coupling or opto-isolation. The goal is to use ICs that have both a LED and a light sensor inside them. When you trigger a HIGH state on the LED side, the light sensor is activated and the associated HIGH state is seen on the output side.

This effectively isolates the electrical circuits and prevents any unweildly voltages on the 'peripheral' side from trashing your valuable hardware.

Thanks to Ian Stedman, we can use the circuit he has provided to hook up LEDs and opto-couplers.

The Amiga port provides a lower current than most PC Parallel ports, so we'll use it as the lowest denominator when creating this circuit so that we can use this hardware across multiple platforms.

initial circuit

(Excuse the paint-brush infancy!)

A 74HC7404 Hex Inverter is used to 'sink' the current used by the LED or Opto-coupler. This IC is much more capable of handling the current and will link the GND wires together internally rather than sending the GND signal back through the parallel port to be linked inside the Amiga (or other device that you've plugged this in to.) This provides a secondary level of protection.

The circuit was built on a crappy prototype board; I seem to have misplaced my breadboard. I used ribbon cable and a standard DB-25 male printer port plug. I've left room for future expansion. I had some spare RGB leds, so the red light is showing that 5v is available and green indicates a 'LOW' output from D0 (or pin 2 of the parallel port.)

DSC03658 DSC03665 DSC03667

Controlling it via code

Thanking Ian again, he's provided us links to demonstration code to test out the circuit we've just created. Download the first sample here.

This sample provides a compiled version of 'Pario' which is a C program to test the parallel port on the Amiga. This code is for the console, so extract it and then run the PARIO/PARcode binary.

DSC03671 DSC03672 DSC03673

Excuse the quality of the photos... haven't learnt how to take screen captures on the Amiga and photographing an LCD TV isn't easy.

Either way, once the program is loaded you'll get a list of options... Press 1 then enter then set the ports to output. Then Press 2 and enter either FF or 00. This is a blanket 'all on' or 'all off' for the 8 data pins.

DSC03674

Doing this made my LED successfully light up and turn off! Winner!

Cross-platform: PC test on Windows 7

This wasn't fun. First I had to re-image my Lenovo X61 as it had a huge amount of spyware on it after lending it to a friend. Then I had to make LPT1 work. Device Manager indicated that all was swell, but the sample code from Code Project just didn't work. On reboot, the green LED would flicker, so I knew that the port was live and communicating.

I dug deeper and tried a second example, using TVicPort, but this also didn't work. I went into the BIOS and found the port disabled!?! Why did Windows tell me it was fine?

After enabling it, there was still no dice. I dug through the sample code and it all seemed to set the port into ECP mode. Was this the same as "bi-directional" which was the default setting in the BIOS? Had no clue.. so back into the BIOS where this could be changed to ECP. Had to be it!

DSC03675 DSC03678 DSC03679

And blam! It works. Hitting D0 on the first sample app works a treat!

Cross-platform: Making this work from the Commodore 64!

My User Port interface for the C64 arrived and I decided that using BASIC was going to provide a good challenge. I've also now coded the User Port in C.

With the hardware hooked up, I ran the following sample to control the LEDs. A thanks to Coronax for the initial example.

Originally the code was to test all values up to 255, or 11111111b. We only need to test the first three pins in our case, so going to 7 (or 111b) will iterate through the values as expected.

Line 20 sets the magical address 56579 to 11111111b. This means that all 8 pins are '1' or 'output'. 56577 is then the I/O for the port and setting a 0 or a 1 provides a digital LOW or HIGH respectively.

10 PRINT "USER PORT EXAMPLE"
20 POKE 56579, 255
30 FOR I = 0 TO 7
40 POKE 56577, I
50 FOR J = 1 TO 150: NEXT J
60 NEXT I
70 GOTO 30

Does it work? Yes... Check out more on coding the User Port here.

What's next?

Next is a shift register... with the ultimate goal being a minimal-pin-usage 12v throttle for the railway. Stay Tuned.

30Nov/155

ASP.NET 4.5 has not been registered on the Web Server

As a .net Developer, I have Visual Studio installed and this (usually) includes its own little version of IIS Express. This is all configured out of the box on install and just works.

After upgrading to Windows 10, I started getting this error:

ASP.NET 4.5 has not been registered on the Web server. You need to manually configure your Web server for ASP.NET 4.5 in order for your site to run correctly.

The usual trick is to go to command prompt, find your .NET Framework directory (somewhere near C:\Windows\Microsoft.NET\Framework\v4.0.30319) and then run aspnet_regiis there.

Unfortunately, on Windows 10, this doesn't work. It'll respond with:

Microsoft (R) ASP.NET RegIIS version 4.0.30319.0
Administration utility to install and uninstall ASP.NET on the local machine.
Copyright (C) Microsoft Corporation.  All rights reserved.
Start installing ASP.NET (4.0.30319.0).
This option is not supported on this version of the operating system.  Administrators should instead install/uninstall ASP.NET 4.5 with IIS8 using the "Turn Windows Features On/Off" dialog,  the Server Manager management tool, or the dism.exe command line tool.  For more details please see http://go.microsoft.com/fwlink/?LinkID=216771.
Finished installing ASP.NET (4.0.30319.0).

This all makes sense... you instead need to hit the start button, type "programs and features" into the search and then hit the first result that appears.

Once in the Programs and Features window, hit the "Turn Windows Features on or off" in the left pane.

Now scroll down through the tree and find:

  • Internet Information Services
    • World Wide Web Services
      • Application Development Features

...and then check all the relevant features you require. I chose .NET 3.5 and 4.6.

Let it do its work and then you should be back to happy-development-land in VS before you know it. If not, then it could actually be a bug in Visual Studio. Please check the following patches for your version of VS: VS2010, VS2012 or VS2013.

If you could only see .NET 4.6 (or have just updated to it...)

Then you need to patch Visual Studio as per the instructions here. Seems that upgrading to 4.6 won't let Visual Studio correctly see that 4.5 is installed.

28Oct/150

Buffalo E7 Kagayaki PC Mouse

On the way back from Shimoda to Tokyo, I happened upon a delight in the shopping magazines found in the a seat-pocket on the Odoriko. I'd actually already scoured Osaka and Tokyo for this delight, but all shop assistants (Yodobashi, Bic Camera, etc...) had never even seen the product.

Little did I expect to find it in, what we declare in Australia, as home-shopping dodgy magazines. But, there it was... and a friend in Japan managed to order it for me then and there on the train! It then arrived only a few days after I returned to Oz.

DSC09382 DSC09384 DSC09386

Under those delicious 'older gentleman' dark chocolate KitKats is a Buffalo USB Mouse. It's a standard form-factor with fantastic markings. Buffalo have taken the time and painted them in line with the E7 shinkansen.

DSC09393 DSC09391 DSC09392

Further than this, they've even put a serious amount of effort into the packaging.

The artwork on the outside of the box is a lightly water-coloured scene of the Shinkansen bolting somewhere north.

I love it that they've made the box out of plastic. The mouse is centrally on display, with all appendages neatly concealed in the base of the packaging.

DSC09394 DSC09396 DSC09397

Opening it felt like unfolding origami. The intricate design perfectly fit the coiled cable and documentation.

DSC09398 DSC09400 DSC09404

Once out, I found it to be smoother than I had expected. It has a very glossy finish and is slippery to the touch. Fortunately, the sides are covered in a rubber panel, which provides a nice level of grip.

DSC09405 DSC09407 DSC09408

The best part about this mouse is that the scroll wheel is legit. The wheel is clicky and can be pressed without rotating. I've used newer mouses in the past that had very light-touch wheels that even had momentum if you spun them too quickly. This wheel has the exact friction point I've been looking for.

24Jul/150

WCF Clients: Set credentials BEFORE you do anything else!

I've just lost hours of my time and, Microsoft, I'd love it back. I had HTTPS WCF services running from a web app on IIS and I needed to merge in a NET.TCP service as well. Web.config hell, I tell you, but it eventually worked.

I then tried to set the ASP.NET Membership Authentication 'required' on the push services (DuplexChannelFactory) via NET.TCP. Everything I read online said I needed a certificate, so I specified this on the server, using the server certificate as I already had HTTPS configured.

This all worked OK... but trying to specify the Username and Password on the channel factory for the generated Client was a nightmare!

It turns out that, long story short, you SHOULD NOT do anything to the generated client after instantiating it. Set the username and password immediately.

This will work:

WcfClient = new WcfClient (new InstanceContext(WcfCallback), "");
WcfClient.ChannelFactory.Credentials.UserName.UserName = "username";
WcfClient.ChannelFactory.Credentials.UserName.Password = "password";
WcfClient.InnerChannel.Opened += WcfClient_Opened;

This wont:

WcfClient = new WcfClient (new InstanceContext(WcfCallback), "");
WcfClient.InnerChannel.Opened += WcfClient_Opened;
WcfClient.ChannelFactory.Credentials.UserName.UserName = "username";
WcfClient.ChannelFactory.Credentials.UserName.Password = "password";

Adding events to the ChannelFactory worked OK, if done prior to the credential configuration. But as soon as you touch the InnerChannel it'll throw a read-only exception as follows:

InvalidOperationException was caught
Object is read-only.

Anyway, the re-ordering worked like a charm... just keep an eye on it!

8Jul/150

SqlDateTime vs DateTime (The battle of the Milliseconds)

This was a good one. I had stored a data row both locally in SQL CE 4.0 and then remotely via a WCF service to SQL Express 10.50.4000. I also then stored the 'most recent' date of the most recent local row in a local 'settings' table as an nvarchar. This was formatted as yyyy-MM-dd HH:ii:ss.fff. I'd then pull this date from the settings table and send it to the remote service that asked are there any records newer than this date?.

The remote service would usually repond with the correct answer, when there were newer rows. But, every so often, it would also respond with Yes! In fact there is! Here is the record with the date you just specified!. WTH? I sent the remote service the exact date and it responds with the same record, which is supposedly newer (no greater-than-or-equals here) when it is exactly the same? ... or is it?

It should not have returned this record. The date should have matched the check date I sent the service and the is there a record with a date greater than the check date should not have been true...

DateTime objects stored in MSSQL lose accuracy

Turns out that, in the land of the datetime data format in MSSQL, that the accuracy is not maintained.

MSSQL, with the datetime format, can only store milliseconds of ##0, ##3, ##7. There's a lot of posts on this splattered all over the web.

Be careful when storing a datetime as a string

So what was my issue? I was getting the datetime from my local record and storing this as a string in another table, called settings, which was a key-value-paired one-size-fits-all user-settings table.

I was formatting it to the correct SQL format, preserving the milliseconds. Of course, I could, in this case, store any 3-digit millisecond value I required.

When I then read that back as a datetime in C#, the value was rehydrated correctly.

When I then sent that to the server, the value was up to 2 milliseconds less/greater than the ACTUAL record in my local db and the remote db. Therefore the server would, every so often, return the record I had based my date off... because I was storing it as text more accurately than MSSQL was in the datetime format.

SqlDateTime to the rescue

C# has a data type known as SqlDateTime. If you grab your DateTime from any object, pipe it into the constructor of a new SqlDateTime and then grab the .Value on the other end, you'll wind up with the DateTime as it would be stored in the database!

Tada! You'll no longer have to worry about inaccurate milliseconds!

In fact, you should probably switch ALL DateTimes in your C# app to SqlDateTimes if you want to get rid of shitty little bugs that will only occur when you do something at an exact millisecond that CANNOT BE STORED IN MSSQL.

End Rant.

23Jun/150

My Pebble Time has arrived

I've always thought a smartwatch would be fun, but I've never really been keen on any of the models available. This stood true until I found out about the Pebble. The previous models were butt-ugly, but the kickstarter project for the Pebble Time took my fancy.

time-banner

I backed the project and received my Pebble Time last Thursday. The contents of the package were very simple: A manual/quickstart, a charging cable and the watch itself. The watch came pre-charged and I was ready to plug it in.

open-box

Initiating Connection

first-bootI enabled bluetooth on my phone and loaded up the Pebble App. It found the watch and then tried to update it's firmware. This managed to fail 3 times in a row... I held down a number of buttons on the watch but could not get it to reboot as per their recommendation. On the fourth attempt, the firmware updated.

I could now view the installed watchfaces and apps on my watch. Watchfaces are apps, but they get maximum screentime as they're the default app shown, displaying the time. Extra Apps can then be installed to do any number of tasks. The watch is effectively always connected to the world, as long as your phone is... and as long as you have battery... everywhere.

First Impressions

The battery life is intense. It lasts around 5 days without charging. It's warned me today that it's at 20%, but I thought I'd keep going to see how long it lasts. Last charge was Thursday evening. Better to deep-cycle the batteries, I suppose.

Off the shelf there is a remote to control music, an app to configure alarms (not tied in to any Android app), watchface selection and settings. The Music remote works great, although it tied in to 'Apollo' instead of Google Music... I have no music in Apollo.. will need to sort that out.

There's a whole plethora of watchfaces to install. Anything you can think of. I tried WeatherLand and IsoTime, two great designs. The former takes into account your location and the local weather and renders the background mountain scene accordingly! There's also the shadow clock, which is installed by default.

IMG 20150623 135216 IMG 20150623 135304 IMG 20150623 135457

I haven't installed any third-party Apps on the watch yet... I'll do that and report back here... but I have gone ahead and created my own custom Watchface!

Cloudpebble and Developing

Development for the watch couldn't be easier. Browse to Cloudpebble, create an account and you're already set to go. You can program in C++ or Javascript via their online IDE, which works extremely well. It can even allow you to emulate a watch via the web or directly upload your project to your own watch via your phone! The upload works via your phone's internet connection and then bluetooth... just enable Developer Mode in settings and you're off.

You can choose to develop an App or a Watchface. These are really the same thing, but a watchface will be categorised correctly and perform the correct actions on button-press events.

Mimicking My Old Arnette Watch

old-arnetteHere it is... it was a clunker and it contributed to a broken wrist. (Don't wear watches whilst playing sport!) This is the last remaining photo I have of this model and it is near-on impossible to find any reference to it on the internets.

As you can see, my watch bit the dust after a decade of punishment. I had loved the 'text mode' so much that I decided to emulate it on the Pebble Time. I used FontStruct to create a 30px high font that resembled the Arnette font. This then worked perfectly as a resource in cloudpebble and rendered pixel-for-pixel on the watch itself.

I then just had to write the logic to write out the text of the time. This was a little tricky, but nothing that couldn't be solved by a few arbitrary values and if clauses. The result speaks for itself! There was the odd bug or two to start with... but I've been testing the watchface out in the field and it's working great. I think I might add a battery meter on there and a few other doo-dads if possible. I'll then release it to the greater community.

Note that the old Arnette actually had a 'magic-a-ball' if you held down the top-right button. I hadn't known about this feature... 4 years in to owning the watch I accidently held down the button whilst trying to set the time and the friggen a-ball came up. It read back to me "YEAH SURE". Nice fortune! After that it became a great decision-maker whilst intoxicated. I might also program this into the watchface... will need to work out if I can commandeer the buttons whilst in 'watchface-mode'.

IMG 20150623 123045 IMG 20150623 123204 IMG 20150623 130328
IMG 20150623 130509 IMG 20150623 134455 IMG 20150623 141354

In the last shot you can see that I realised I'd had the colours the wrong way around... flipping them gave me goose-bumps... although the screen is 4x the DPI of the original watch, the result is so similar it's not funny. I love it!

Got any other ideas/development requests?

Feel free to leave a comment here and request something custom for this watch? Am happy to work with anyone who wants to design/develop something for this watch. It's a great platform and the only limit would be one's imagination!

28May/150

An insight into the workings of a Comment Bot

I get emails every now and then from this blog telling me that there's a new comment for approval. Most often than not, it's spam. It's also usually really shit spam. The context is wrong, the URLs are Russian and the text is crap. I have always wondered how it's generated and who would be the one posting the comments.

Regardless of the plugins I have enabled to stop spam (and it seems 10000s of comments are in fact stopped), some of the crap still gets through.

Today I received an email indicating a new comment. This one was different though... the contents seem to have been verbatim pasted, as opposed to 'customised' by the 'poster'.

{I have|I've} been {surfing|browsing} online more than {three|3|2|4} hours today, yet I never found any interesting article like yours.
{It's|It is} pretty worth enough for me. {In my opinion|Personally|In my view}, if all {webmasters|site owners|website owners|web owners} and bloggers made good content as you did, the {internet|net|web} will be {much more|a lot more} useful than ever before.
I {couldn't|could not} {resist|refrain from} commenting.

{Very well|Perfectly|Well|Exceptionally well} written!
{I will|I'll} {right away|immediately} {take hold of|grab|clutch|grasp|seize|snatch} your {rss|rss feed} as I {can not|can't} {in finding|find|to find} your {email|e-mail} subscription {link|hyperlink} or {newsletter|e-newsletter} service. Do {you have|you've} any?
{Please|Kindly} {allow|permit|let} me {realize|recognize|understand|recognise|know} {so that|in order that} I {may just|may|could} subscribe.
Thanks.
{It is|It's} {appropriate|perfect|the best} time to make some plans for the future and {it is|it's} time to be happy.
{I have|I've} read this post and if I could I {want to|wish to|desire to} suggest you {few|some} interesting things or {advice|suggestions|tips}.
{Perhaps|Maybe} you {could|can} write next articles referring to this article.

Woah... it seems that these comments really do get customised... I mean, they still have NOTHING to do with my blog and the URLs they point to have NOTHING to do with the guts of the comment, but the contents of the comments seem to be variable.

I assume the variability is to prevent the crap getting marked as spam. The English makes sense, to the point where each of the permutations actually sound like a native speaker.

I wonder if a bot chooses, at random, which word to use from each array, or if a human is doing it all. A human should, at least, know that the entire body has nothing to do with any post on this blog; but then again, the poster may not even speak English.

I am sure this {article|post|piece of writing|paragraph} has touched all the internet {users|people|viewers|visitors}, its really really {nice|pleasant|good|fastidious} {article|post|piece of writing|paragraph} on building up new
{blog|weblog|webpage|website|web site}.
Wow, this {article|post|piece of writing|paragraph} is {nice|pleasant|good|fastidious}, my {sister|younger sister} is analyzing {such|these|these kinds of} things, {so|thus|therefore} I am going to {tell|inform|let know|convey} her.
{Saved as a favorite|bookmarked!!}, {I really like|I like|I love} {your blog|your site|your web site|your website}!

Then again.. if you keep reading the dribble you'll see how crap it is and, even though some sentences flow, others just don't belong where they are.

Meh... either way, it was a very interesting insight into the workings of these bots/humans/drones posting shitty comments on the world of blogging.