Friday, December 30, 2011

Display issues - no more!

I found the solution for the ghost pixels!
It now looks as it suppose to and I'm a happy camper!

More about this later on...

Thursday, December 29, 2011

Visual Orgasm

Got the new display delivered by FedEX just now!

Plugged it in.
It works.
Looks a million times better than the last one!

There seems to have been some timing differences between the two so at the moment there's a lot of ghosting going on (this display is probably faster than the old) so I will need to tweak the code a little.

Starting of to be a great day!


Turns out it was the logic level converter that was the problem. The old display required +5V logic levels while the new one only require +3.3V, thus rendering the converter obsolete.
Even worse so - it kept a slight current residue on all pins and blurred the display.

I bypassed it and now it looks rather nice! :D


It seems I still got a bit of ghosting going on. Above each lit pixel is a dimly lit ghostpixel. I'm investigating this now and it is really bothering me. To be continued.

Tuesday, December 27, 2011

First decals!

Got the first test-prints of the playfield to decide what works and what doesn't, and I must say - it's looking GOOD!

There's a few minor tweaks that needs to be done. There's no white in the decal. At all. So I must either handpaint the inserts where white is needed or choose another textstyle that doesn't use white in it.
But I was prepared to that - the alternative was to have a solid decal and overlay the insert art. It could also work but doesn't give me the ultrasmooth playfield I'm aiming for.

I'm psyched - hopefully I'll have the game artwork during next week!

Monday, December 26, 2011

New Display

I just decided to give the LED displays another chance and ordered a Vishay-display with discrete LED's instead of LED-modules. Regarding to popular opinion these seem to work a lot better than PinLED's displays. All Vishay displays I found has been rather pricey, but the nice guys at PinballControllers suggested that I buy the display from Mouser instead, since their own stock ran out. Kudos!

Hopefully this display will meet my demands so that I can finally get the cabinet head together.
I can only hope, but one thing is certain - I will need a display!

Saturday, December 24, 2011

I heard you like pictures...

As the pinball design is becoming somewhat 100% (it will probably never be until it's printed) I thought you might like a little teaser image of the 2 GB large image file that is the playfield...

1) Lower left playfield.
This picture was taken at 7% zoom rate.
What we see here is a small piece of the left lower playfield with the in- and outlanes, slingshot, left ball lock etc. White areas will be cutout to create a little "boundary" of wood and allow for machinery and lights to protrude. It will also allow me to bolt down things without wrinkling the decal too much. The latter shouldn't be much of an issue as I intend to put a couple of layers lacquer on top of the playfield before assembling everything anyway.

The artwork's probably not as complete as I would like it to be, I'd like to have a little more small details that you see when your inspecting the playfield closely. I like that amount of detail in a game so presumably I'll try to get that into mine as well.

But I really think it's progressing nicely and feels kind of balanced. It might at the moment be a little un-orthodox compared to a classic pinball in terms of design, but it's my game. And my first at that - so I'll let it slide. ;)

But I'll probably at least try to color code the various parts that co-interact a bit more so it will be easier to distinguish various features from one another.

Next we have a picture of the main toy of the game - a big daddy, a.k.a Mr Bubbles!
He will if everything goes as planned have a rotating drill and a couple of Frankensteins monster-ish moves to go with that.

This piece was actually a lot large than I expected, so I had to do a little redesign in my design rather than chopping of his legs etc. But I like the size! It also allows me to insert machinery inside to make the drill rotate etc.

It has also got built in LED-lights which I intended to do, but this saves me the trouble. It will simply light green when he's active (i.e protecting a little sister), amber/yellow when searching (if a sister is targeted, or a shot is placed at big daddy directly) and finally red - hostile.

I hope to find more toys of equal quality - or maybe I'll attempt to do a couple of custom ones. I'd really like to have a splicer model as well - but they are almost just as large and I'm currently running out of room in the box!

Wednesday, December 21, 2011

How much wood would a woodchuck chuck...

Just sent blueprints to the factory to get a cost estimate and approval before it's going through the CNC machine. Turns out all carpenters/woodworker shops I've spoken to declined my design because it was to advanced for them. I guess the effects of a more computerized society is becoming increasingly evident among craftsmen as well...  I had to resort to having an expensive CNC cutout after all.

It turns out I need 148 holes drilled (not counting regular inserts) for lights and posts alone etc. Stuff really adds up after a while! On top of that all the inserts and special holes, ball-locks etc. 
Quite a beefy design in other words!

Anywho -
I'm a bit nervous that I've missed or entered a digit wrong somewhere, but it's been so long without any progress so I'm thinking I'll probably be able to fix/drill a single or some holes on my own in case of emergency.

Fingers crossed!

Saturday, December 10, 2011

The time of my life!

It has now been 8 days since my beautiful daughter was born!

Words can't describe my feelings. Incredible!

Wednesday, November 30, 2011

Still no tango

Mini-me has still not arrived! 

And not much has been done on the machine.
I've gathered soundclips and started to outline where and when the various soundclips are to play - but nothing solid yet.

Tuesday, November 8, 2011

A lot of stuff!

Just wanted to say that I'm about to be a father very soon! 
It will be awesome and I'm very much looking forward to it! 
Expected "delivery" is in one week but in reality could happen anytime now - or 4 weeks from now. Bought the baby bed today! :)

Man, the list of stuff to do on the machine just keeps growing. But I'm optimistic that I'll send the end of it. Some day! But as you can expect, I'll probably have to work in a slower pace than usual on my pinball machine - unless I change gear and push forward a little stronger.

I've kind of reached my goal before the baby arrives - to have an assembled and playable machine.
It is somewhat assembled and could be playable but I've decided to not do any more assembling of the playfield parts until the proper playfield is created, as it will just take a lot more time to disassemble the playfield first.

So here's a quick rundown on what's done and what's left:

Hardware - Cabinet is done, still need proper playfield "hinges".
Electronics - Some wiring is left to be done, but mostly I'm waiting for the playfield to be fixed.
Artwork - Cabinet and playfield art is done, awaits printing.
Playfield - Need to create a proper playfield. Inserts needs to be fixed and sanded.
Playfield parts - Ready for assembly, but there's no proper playfield to place them on yet.
Sound - Need to record/get sound samples to use.
Music - Will use the official soundtrack .
Video - DMD converter is written, so I can export any image file into a custom 16 color DMD format.
Rules - Most of the game rules are figured out, but not necessarily written down.
Programming - Core elements are there, actual gameplay is yet to be written.

I had a major setback in the DMD department where I returned my display because it didn't look quite alright. As you can see in several of the pictures the various modules were very unevenly lit, and the lines of the LED's were not as aligned as they can be. Due to, in my opinion, a highly disrespectful customer service returning the display only gave me half the money refunded and a big fat insult on top of that.

The major component that is left is obviously the actual playfield - where the routing of the wood is my worst enemy right now. I had an offer with CNC routing, but that would cost me almost 700$... Yikes! A little too much on the pricey side, if you ask me.

I'm quite confident I'll be able to pull out or find decent soundclips from the games, so that shouldn't be a problem. Neither will the programming be since I eat code for breakfast. ;)
Video shouldn't be too much of an hassle either since there's a lot of video material that can be used, it's simply a matter of DMD-fying the graphics. The converter already supports animated images for easy animation import/export.

The biggest struggle is trying to plan ahead.
Like Ben Heck said - when building a pinball machine you really must think several steps ahead, and in some cases "where will this part, that I will install in a couple of months, go"... I've done a few of those mistakes, like drilling holes where the flipperbuttons should be only to find out that I forgot to compensate for the side-guards size and position...

But HOPEFULLY I've managed to dodge most bullets - past, present and future such - and will end up with a truly epic game. The whole idea is to have a pinball machine that looks like it could be produced by real pinball makers in a real factory. At least, that's the plan!

Monday, October 31, 2011

New Theme!

The new theme has been decided and the artwork is nearly done. That's right. DONE!

It turned out supergreat and it actually took less than a week to finish the artwork for the entire cabinet and playfield. A lot of high quality material was available so things just kept rolling.

The theme?

It's really the perfect "replacement" for the original theme - the art deco is there, the decadence and all the major game elements could almost directly be translated into a Bioshock feature. I have a little more work to do on the playfield parts before sending it off to printing.

I'm psyched about the current design and can't wait to get the printed decals in my hand!

In case you're wondering -
The old theme was based on the early Fallout games! Also a setting very dear to me, but it was really hard  to find high resolution images to use and the color palette was mostly brown-isch. With Bioshock, I'm allowed to use blue, red, green, pink, purple etc without it getting weird. It all fits together really nicely. You'll see for yourselves soon enough!

(I won't publish any pictures of the playfield yet, but it will come soon! )

Saturday, October 15, 2011

...and re-assembled. Sort of.

Here's a few pictures for reference.
The head is not finished yet and is currently drying, so it's mounted upside down in the pictures...

Paint It Black

While I'm waiting for the new theme to settle in my mind, I've begun painting the cabinet and head. Does quite a difference on the appearance compared to bare wood.

1) Bare-wood cabinet

2) Putting the head together. A small door allows for easy access to the
display and speakers. A fan is also in place to draw out hot air. 

3) The assembled cabinet head. A fluorescent lamp is bolted in place
to keep the translite illuminated.

4) The painted cabinet and head. (Not finished yet)

There's a little retouching needed here and there, but at least the major parts are painted now.

Tuesday, October 4, 2011

Change of heart?

Hmm... I'm not so sure about the current theme after all.

I will have to check the pro's and con's of the various themes I've had in mind to see which comes up as winner this time.

Sunday, October 2, 2011

Image to DMD conversion

I've been working on converting regular image files to DMD images (well, my interpretation of them anyway) and just tested it out:

A) Converted RGB GIF to 16 color DMD. 

B) The original image for comparison.
(the format is RGB despite the black&white appearance)

Pretty neat, huh?

Basically I wrote a python program that loads images (animated GIF's preferably, but almost any image format works), converts them to monochrome and spits out a converted 16 color image in DMD format. Each frame of the animated image just adds another 4096 Bytes to the DMD file, meaning an animation results in a single DMD file.

I will probably have to do a little fine tuning to get the actual color conversion more precise. Right now it's simply dividing the 255 colors by 16. It could be better represented, I suppose.

In the example above, there's a lot of bleeding going on. That lies in the original file and has nothing to do with the conversion etc. The image was created very sloppily with a anti-aliased scaling of the original images. Nearest-neighbour scaling is preferred when working with so few pixels.

(There can hardly be anyone out there who can't guess the theme now, right?)

Friday, September 23, 2011

Easy speed

Probably the easiest speed gain I've every "hacked" together:

  if (sdCard_) return true;

By initalizing once and then returning true until rebooted, I gained an additional 26 Hz while streaming. This should be safe since the card is read-only and will not change size and/or require re-initialization during runtime... So now I'm counting 66 Hz and still loading animation data in the background.

Current speed (for 16 colors):
Loop 1 : Start to read,       7.354 ms
Loop 2 : Read 512 Bytes, 4.886 ms
Loop 3 : Read 512 Bytes, 4.879 ms
Loop 4 : Read 512 Bytes, 4.881 ms
Loop 5 : Read 512 Bytes, 4.880 ms
Loop 6 : Read 512 Bytes, 4.881 ms
Loop 7 : Read 512 Bytes, 4.879 ms
Loop 8 : Read 512 Bytes, 4.881 ms
Loop 9 : Read 512 Bytes and close, 4.881 ms

Actual video data is currently:
16 colors @   6 FPS   (Screen refresh is 66 Hz)
  8 colors @ 14 FPS   (Screen refresh is 96 Hz)

8 colors may be quite sufficient to create nice graphics, but of course - the more the merrier! I'm sure more can be done to improve the performance.
Stay tuned!

Wednesday, September 21, 2011

SD card - again

A little update -
It seems incremental updates DO work. That's good news!
I'm however quite stunned that the various parts of the reading take so much time...

Loop 1 : Starting...18.467 ms
Loop 2 : Read 512 Bytes, 16.303 ms
Loop 3 : Read 512 Bytes, 16.301 ms
Loop 4 : Read 512 Bytes, 16.309 ms
Loop 5 : Read 512 Bytes, 16.300 ms
Loop 6 : Read 512 Bytes, 16.304 ms
Loop 7 : Read 512 Bytes, 16.307 ms
Loop 8 : Read 512 Bytes, 16.303 ms
Loop 9 : Read 512 Bytes, 16.301 ms
Loop 10: Closing! 1.779 ms

Each loop requires a 10 ms SD.begin() call. So in practice, a data read is actually 'only' 6 ms.
So there's more to be done, but as I said - incremental updates are a good thing!



After a little tweaking I'm able to have a (somewhat) flickerfree loading in the background.
It runs at about 40 Hz and the video is loaded at between 5 and 10 fps depending on blocksize.

So, I can either A) limit the 110 Hz refresh to match the lower loading Hz, or B) Switch to fullscreen@40Hz when displaying video. Or probably C) only show animations on 2/3 of the display like newer Stern games. Or even D) depending on type of animation, load the frames in the background and display the animation when ready. This requires a maximum of 30 frames animation length since that's all the RAM I've got available.

All of the above assumes 16 color video. Smaller video size or fewer colors would contribute to a faster refreshrate.

Hopefully I can tweak the SD loading even more to bring up the refresh rate, since it also controls the brightness of the screen.

Tuesday, September 20, 2011

Those pesky SD cards...

I'm having slight progress with the SD-card reading programming.
I'm currently reading a full frame of animation 13 times per second. Time for some sloppy math!

Old code:   1 Byte @ 3.5 ms
New code:  1 Byte @ 0.01 ms

Unfortunately, this is too slow to be useful - but it is still a 350x improvement over the previous speed! IF it's possible to break down the reading over several frames this is not an issue. But I'm not sure how the SD-library responds to changes in the SPI-slaveselects during reading.

I could load one color-layer at a time (512 Bytes) directly into the drawbuffer during animations, which hopefully translates to around 6 ms per layer. That way the screen would still refresh fast enough to be considered flickerfree. It would only allow for videos with around 10 frames per second if all 16 colors are being used. There might be a FAT restriction on the number of files on the SD-card that prevents me from using this method however.

Another option could be to simply load a lot more data and "pause" the game during loading. 1 second of loading would load 23 frames of animation, and if playback speed is 15 fps it roughly sums up to 1.5 seconds of animation. But it's not really practical to pause the display and lights every now and then, and usually when the game allows a pause you'd often want more than 1.5 seconds of animation.

Naturally I'd prefer to read an entire frame (4096 Bytes) in one go, since this allows me to easily add text and tweak the screen before displaying. I guess I'll have to experiment a little to find out how to solve this!

It may be time for me to fix the slow 'digitalWrite' of the Chipkit after all, something which I've sort of avoided until now... because it's boring!

Saturday, September 17, 2011

Graphics revised - check!

Finally got around and rewrote the graphics library.
It is by no means finished (the text adding is a mess) and will be revised in a future update, but for now I'm quite happy with the results!

1) Test image with scrolling starfield and 'MULTIBALL!'-text.
Unfortunately, the colors of the picture are washed out - they are much more vibrant in reality.
Don't judge a pinball by the skills of the photographer! ;)

What we are looking at is 16+1 colors, double-buffered, Speedy-Gonzales-100Hz magnificence!

Basically, the double buffering is just two buffers that each take turns in rendering. This means I can keep drawing the frontbuffer, or drawbuffer, while the backbuffer gets built. i.e I can keep logic at 30Hz while still rendering a flickerfree 100 Hz. This of course allows me to download new animation frames in the background and render them when they're completely loaded. Awesome!

Oh, and did I say I'm completely rebuilding the frame EVERY frame now? By limiting the rebuilding to 30Hz I get even more rendering-hertz to play with! Just a reminder, the Arduino could barely keep up drawing 5+1 colors at 52 Hz with everything else going on...

I've also added a couple of convenience functions such as addText, addTextLarge, addRect, fadeIn, fadeOut, fadeDisplay etc to make the programming of the display a little friendlier. The fadeDisplay function is particularly useful to print text over finished animation a´la modern Stern-games by dimming the rest of the screen and then draw the text over it.

No 'addLine' function you say?
Plotting a line is harder than one might think, if you want a decent looking one!
Check this for reference! Don't worry, I will be adding one in the future - at the moment I only need vertical/horizontal.

Wednesday, September 14, 2011

SD card reading - check!

The SD card reading is now started. And somewhat finalized.
The library I'm using however does not impress.

At the moment it is reading around 1 byte per 3.5 ms, which is mighty slow...
It should be able to read at least a couple of hundred times faster than that!
So, it's 'back to the drawingboard' for me as far as the SD card goes...

Sunday, September 11, 2011

Motherboard revised

I did a little work on the motherboard, including adding the third soundboard, 3.3->5V converter and SD-card reader. Behold!

1) From left, going clockwise: Soundboards (2 sfx, 1 music), Arduino Mega2560, "display adapter" (3.3V to 5V converter),   Chipkit Max32 + MUX shield, SD/MMC card reader.
It has a certain "scrapyard challenge"-feel to it, but it will be hidden from view anyway. And - should it come to the point where it bothers me a whole lot, the schematics for all the boards I've used are open source and available online so I could easily order a circuitboard with all the components integrated.

Adding a second sound effects card really made a difference. I'd thought it would be more subtle but being able to have multiple effects playing alongside music really adds to the experience. This also means I can have longer spoken phrases during the game without losing music or effects while doing so.

Saturday, September 10, 2011

Colors revised

Just got the new MCU (Chipkit Max32) to function correctly with my display.
I had a lot of trouble getting it to work, even contacted the developers and we confirmed I was doing right (programming wise). But the problem was the lower operating voltage of the Chipkit.

It only took a logic level 3.3V <-> 5V converter and a whole lot of patience to get it working!

No pictures yet, but the difference is spectacular: 16+1 colors and no flickering!
The 4X CPU speed of the Chipkit really shines here, and as an additional bonus, it seems I'm able to update the columns at 20 MHz speed instead of 5MHz, another speed increase of 400% right out of the box! I'm using regular digitalWrites with hardware SPI, so I figure I could push the refreshrate up a notch if needed.

Now I can focus on getting the display system back on track, continue on the serial communication, SD card reading, etc...

But I'd still say -
Chipkit, you sure were worth the trouble!

Sunday, August 28, 2011

Paint it black

Got my fingers a little dirty and started working on a couple of the playfield toys. I have not yet decided if this particular one will be an animated one...

1) White, die-cast 1957 Chrysler 300C

2) Black undercoat (purposely not 100% covering)

3) Base layer, grey (purposely not 100% covering)

4) Added rust and painted interior

5) More rust and dirt wash
6) The final car - A broken down, war beaten 'Chrysalis Motors Highwayman'
I'm thinking you cannot have a hard time guessing the theme of the game now...

Monday, August 22, 2011

As David would have said - Ch-ch-ch-changes!

I've changed my mind... I will be using a SD card for animations.
It will also be used to store the highscore etc.  The built in EEPROM has a "very" limited write/erase cycle so I figure I'd keep the internal memorycards intact and store everything on external cards to minimize the risk of my pinball machine breaking down during a tournament or whatnot.

The Chipkit 512 KB flash storage means around 120 frames of animation. That data is probably best used as common animation that needs to be readily available and the SD-card ones will be mode-specific graphics. With SPI the datarate is fast enough, and I figure I could use the natural pauses in the game to load new animations into RAM. The current game logic was actually already prepared for this so it would mean minimal changes and/or interruptions in gameplay.

I've also got basic serial communication between master (Arduino) and slave (Chipkit) going on, so the host can send "playMusic", "playAnimation" etc commands to the slave which will then perform them. I will probably do at least one rewrite of that library as time progress to further streamline the communication, but at the moment it works fine. It is prepared for (and is currently) sending batch jobs of commands, but it's uncertain if the final version will send single commands right away or batch them together for sending at the end of the frame.  There are different benefits for both versions.

I've also refactored the code to work with two different boards:
Arduino - Switches, Solenoids, Game logic and SoundFX.
Chipkit - Display, Lights, SD card and Music

With the transition to the Chipkit, it unfortunately turned out that (most likely) the voltage difference from 5V to 3.3V does not allow the display to properly function. I've been in touch with the manufacturers of both the display and the Chipkit and we've come up with the same conclusion. So, I've ordered a 3.3->5V logic translator chip now which will hopefully solve the problem. Kind of a bummer, but it will be worth the extra effort for all the sweet improvements it offers.

The game logic ... Ah, the fun part!
The ruleset is shaping up quite nicely and as it seems to me - a nice adaptation of the original concept. When reading the rules I'm quite satisfied that the gameplay will be fun as well. I guess the hardest part will be actually finding sound and graphics for the game, but if all else fails, I will do them myself.

Wednesday, August 17, 2011

Max32 + Mega2560 = Superpin!

The main bottleneck at this moment is the RAM, as I said earlier. With the Mega2560 I got 8KB of RAM, which gives me around 1 display buffer with 8 colors (´a 4096 bytes). Sure, I could do some voodoo magic to get it working, but it will be very slow to perform any writing to the buffer. With all this extra overhead the 16MHz will running at 100% just to keep up. In order to fully support doublebuffering I would like to have three buffers. One buffer that is sent with SPI to the display straight away, and two that are alternated and built "behind the scenes".

I will be using BOTH boards, actually.

The Max32 will take care of the visuals (lights and display) and the Mega2560 will do solenoids, switches and game logic. Using all the available memory, this would give me around 800 KB to store data (ruleset and logic excluded) for animation - I could easily fit all the game animations there to eliminate the need for an external SD card.

The Max32 is also of more than 4x the MHz, 2x the flash and 16x the RAM!
With this extra card I've more than doubled the performance and the number of I/O pins, which will really come in handy!

1) Poor Man's Motherboard!

Sunday, August 14, 2011

Out of RAM

Ouch, Arduino. Ouch...

Time for plan B - Chipkit Max32

Those buffers...

I found out that I can improve the speed of the display rendering with about 50%.
It's quite simple really.

Currently I'm checking every frame, after every color, after pixel on/off...
But my machine will not feature 60 fps full motion video. Heck, even cinemas don't have that. You can easily see that this is a large overhead with largely redundant information.

By extracting the draw buffer (front) from the videolayer (back) I can keep drawing the frontbuffer "no questions asked" at about 1 ms per color. All the screen updates, such as text and images, happens in the backbuffer and when say a certain interval has passed the buffers are swapped. Rinse and repeat.

The beauty about this is that I remove all the heavy checks from the draw routine and can spread out the work of building a frame over a "lot" of time. Every clock cycle is crucial in this build since the Arduino is a single core, single process type of MCU.

A quick example (numbers are guesstimates, since I have not coded the backbuffer part yet):

Single frame: 18 ms (drawing) + 20 ms (building) = 38 ms, gives around 26 fps if the frame would be recreated every frame, such as during a video scene. This is very low and flickering is noticeable. Normal case is around 52 fps if the frame is created only once and drawn many times.

Single frame: 8 ms (drawing) + 2 ms (building) =   10 ms, gives around 100 fps if video was created at about 15 frames/sec. I could easily limit the drawing to 70 Hz to further free up resources without being noticeable for the player. Time that they however will feel with the game being more responsive.

I can't believe I've missed this -
I've done this a million times before in regular graphics programming...

Saturday, August 13, 2011

Shades of Sanity

SPI is a godsend. Everything's forgiven!

1) 8 + 1 colors at 18.868 ms, about 52 frames/sec.

The new code is approximately 2.5 x faster, which may not sound a lot - but that's what separates a boring or flickering display from a nice, crisp multicolor display. The main time thief is the "if ( *f++ >= lx)" part - the code runs at about 128 frames/sec with a fixed value instead of "b", so I figure it will be possible to further improve the code. For reference, old Williams games used 4+1 shades, newer Stern games use 16 shades.  Considering the hardware used, I'm quite satisfied with the current performance.

Feel free to look upon and possible improve the code:

void writeDisplay()
Write all shades in one go. (i.e around 2.3 ms per color)

register byte x,y,lx,b;
    register byte *f;

cli(); //Disable interrupts 

for (lx=1; lx < DISPLAY_MAX_BRIGHTNESS+1;lx++) //repeat for each color/shade
   f = &frame[0][0];

//row 1  -------------
bitClear(PORTF, 2);          //set 4th bit of PORTF to LOW          
for (x=0; x < 16; x++)   //send full 128 bit row using SPI
if ( *f++ >= lx) b  = B10000000; else b=0;
if ( *f++ >= lx) b |= B01000000;
if ( *f++ >= lx) b |= B00100000;
if ( *f++ >= lx) b |= B00010000;
if ( *f++ >= lx) b |= B00001000;
if ( *f++ >= lx) b |= B00000100;
if ( *f++ >= lx) b |= B00000010;
if ( *f++ >= lx) b |= B00000001;

   bitSet(PORTF, 2);            //set 4th bit of PORTF to HIGH //Column latch
      bitSet(PORTF, 4);          //set 5th bit of PORTF to HIGH (mark first row)  
bitClear(PORTF, 5);          //set 6th bit of PORTF to LOW     
        bitClear(PORTF, 3);          //set 4th bit of PORTF to LOW
        bitSet(PORTF, 3);            //set 4th bit of PORTF to HIGH      
bitSet(PORTF, 5);            //set 6th bit of PORTF to HIGH

//row 2-31      ------------
for (y=0; y < DISPLAY_MAX_ROWS-2; y++)

   bitClear(PORTF, 2);          //set 4th bit of PORTF to LOW          
for (x=0; x < 16; x++)   //send full 128 bit row using SPI
if ( *f++ >= lx) b  = B10000000; else b=0;
if ( *f++ >= lx) b |= B01000000;
if ( *f++ >= lx) b |= B00100000;
if ( *f++ >= lx) b |= B00010000;
if ( *f++ >= lx) b |= B00001000;
if ( *f++ >= lx) b |= B00000100;
if ( *f++ >= lx) b |= B00000010;
if ( *f++ >= lx) b |= B00000001;

  bitSet(PORTF, 2);            //set 4th bit of PORTF to HIGH //Column latch
    bitClear(PORTF, 4);          //set 5th bit of PORTF to LOW (the rest of the rows are not leading)
  bitClear(PORTF, 5);          //set 6th bit of PORTF to LOW    
       bitClear(PORTF, 3);          //set 4th bit of PORTF to LOW
      bitSet(PORTF, 3);            //set 4th bit of PORTF to HIGH
bitSet(PORTF, 5);            //set 6th bit of PORTF to HIGH
//row 32 ---------------
   bitClear(PORTF, 2);          //set 4th bit of PORTF to LOW          
for (x=0; x < 15; x++)   //send full 128 bit row using SPI
if ( *f++ >= lx) b  = B10000000; else b=0;
if ( *f++ >= lx) b |= B01000000;
if ( *f++ >= lx) b |= B00100000;
if ( *f++ >= lx) b |= B00010000;
if ( *f++ >= lx) b |= B00001000;
if ( *f++ >= lx) b |= B00000100;
if ( *f++ >= lx) b |= B00000010;
if ( *f++ >= lx) b |= B00000001;
if ( *f++ >= lx) b  = B10000000; else b=0;
if ( *f++ >= lx) b |= B01000000;
if ( *f++ >= lx) b |= B00100000;
if ( *f++ >= lx) b |= B00010000;
if ( *f++ >= lx) b |= B00001000;
if ( *f++ >= lx) b |= B00000100;
if ( *f++ >= lx) b |= B00000010;
if ( *f  >= lx) b |= B00000001;
  bitSet(PORTF, 2);            //set 4th bit of PORTF to HIGH //Column latch
      bitClear(PORTF, 4);          //set 5th bit of PORTF to LOW (the rest of the rows are not leading)
bitClear(PORTF, 5);          //set 6th bit of PORTF to LOW
        bitClear(PORTF, 3);          //set 4th bit of PORTF to LOW
        bitSet(PORTF, 3);            //set 4th bit of PORTF to HIGH
bitSet(PORTF, 5);            //set 6th bit of PORTF to HIGH
} //End of color/shade

sei(); //enable interrupts.

bitClear(PORTF, 5);          //set 6th bit of PORTF to LOW

Friday, August 12, 2011

The new code...

My code is now full of commands similar to this:

*b = ((*b   << 1) | (*p++ | layer)?1:0); 

My head hurts...

Wednesday, August 10, 2011

Something shady's going on...

Sat down a couple of hours and got started on a multicolor display-routine - only to find out it didn't work. At all...

After extensive troubleshooting of what I believed to be was faulty cables, I've redone all the cables except the powercables in the machine. Now everything is nice and pluggable/unpluggable in a easy manner.

The problem wasn't in the cables however, but the cabling still needed some work.
When I tried a different version of the digitalWriteFast it, for some peculiar reason, broke the pins I was using so I tried plugging the display into another set. The refresh rate of the screen was becoming rather slow and at that time I didn't connect that those pins were not "accelerated" by digitalWriteFast.
Also - the new library was approximately 1.5 x slower than the old. Doh.

So anyway - I reverted to the old library and the old pins and now my code could do its work properly.

1) Multicolor display. Four different reds and one black layer.
Here it's simply displaying f(y)=red, but any pixel can be any shade. 
At the moment it can display 5 different "colors" (4 red + 1 black). The code that enables different shades is quite slow since it needs to check for different values and also draw the screen multiple times, so with 4 colors I'm pushing 'the little MCU that could' beyond its comfort zone.

I will do further testing with SPI enabled since I need to get the time needed for each update to a lot less than it is currently taking. It is currently updating a full 4+1 color frame at 19 ms, which is "really slow". I hope to get this down to under 1 ms, if possible...

Saturday, August 6, 2011

A picture's worth...

You can see it in very crude motion including a crude pong-isch game on Youtube.

What you see above is a PinLED display driven directly via the Arduino microcontroller. I was going for a plasma screen first but they need a lot more power, four different voltages from -115VAC to 115VAC etc. The PinLED hooks up directly to +12VDC which is a much more convenient level. If you're also worried about the environment or electrical bill, the PinLED is also preferred as it stays under the RoHS law.

The current display code draws a frame of information, in which the designer/programmer (me) fills with data. The current supported commands are just 3-5x5 letters and numbers being printed at any x,y coordinate. The final code will of course feature animated images etc. It's actually supported already, I just need to find a tool (or code one myself) that converts regular images to byte arrays that can be used in the code. 

As always, the DMD pixels are just on/off so different shades are created by lighting the various pixels for a different amount of time. I've yet to find a suitable method for this but the idea is that the final version will feature "multicolor" images. 

At the moment that picture (and video) was taken it ran at about 5.5 ms, i.e approx. 180 Hz. The current code revision runs at about 0.5 ms meaning it's too fast for the refresh rate of the screen... Therefor I need to slow my code down to push the refresh rate below 200 Hz (the maximum). 

It's a good day for a programmer when the main problem with the code is that it runs too fast!

Monday, August 1, 2011

Code changes

I've experienced that the Arduino seem to be slow sometimes, especially when writing values. So I did a little research and tested stuff on my own - and the Arduino is not slow. But the code is.

For instance:

Using regular digitalWrites, 2500 on/off cycles:   35764 microseconds.
Using digitalWriteFast, 2500 on/off cycles:            2614 microseconds.

The old code is almost 14 (!) times slower than the new code! Damn...
Of course, there are caveats. It requires the pin number AND state to be static and known at compile time. Most of us do this all the time anyway (const, #define etc) so it's not a big deal.

The syntaxes are similar, if not identical, too.

Old: digitalWrite(PINNR, STATE);
New: digitalWriteFast(PINNR, STATE);

The static STATE can be avoided by simply doing something similar to:
if (someState) 
   digitalWriteFast(PINNR, HIGH);
  digitalWriteFast(PINNR, LOW);

So - If your are developing on Arduino, download the digitalWriteFast library before doing any coding! It's  A LOT faster and doesn't require that much planning ahead. I've already begun converting my code (and redesigning it along the way) to gain the juicy speedup.

The numbers where taken from the top of my head so I don't remember the two last digits of each value, but the magnitude of the values are correct. With a 14x speedup, the last two digits are indeed the least significant values. 


Improved the speaker system today with a nice AC/DC amplifier and it's loud... really loud. Finally I can wake the neighbors with my machine!

I've moved the amplifier from the cabinet to the head, and I've put the audio controls (tone, volume, power, headphones) on the back of the head. I don't want the controls to be sticking out from the head so this will be covered by a steel grill later on, so it won't be that easy to adjust, but still possible.
I've also plugged in the nice Stern 8-Ohm speakers and resoldered the passive mixer with thicker cables.

Basically I will be putting the display, speakers, amplifier and everything related to that inside the head and the rest of the hardware inside the cabinet. The head will of course be connected to, and receive its power from, the cabinet itself.

To sub, or not to sub.... that's the question.

Sunday, July 31, 2011

Cabinet head!

Finally got time to work on the cabinet head.

As I've mentioned earlier, the old cabinet head was far too tilted to be salvaged.
It also wasn't matching up nicely depth-wise with the cabinet - making it look a bit flimsy, kind of like a tiny head on a giant body. Not cool.

I've ordered a red LED-display (128x32, PinLED, same display as in Stern's international versions of Spiderman and Family Guy) so in a few days I'll hopefully have my machine drawing pretty pictures for me while it speaks! I was going for a plasma display at first, but as it turned out they needed either A) a lot of high voltage power, or B) a lot of money from the buyer. I also didn't find any red plasma screens, but I've read they're filterable to display red instead. Anyway - 
The PinLED display was in an acceptable price range and I'm a sucker for the red glow, so it was a no-brainer. Looking forward to hooking it up!

The speaker and display panel is prepared as well and the new head is looking rather nice, although it's still unfinished. I figure I can use magnets to keep the translite locked in place (this may change in the future) so that lightbulbs can be changed easily in-place. 

I will put a ventilation grill on the back and I hope to get good airflow with cold air being pushed into the cabinet from underneath and hot air being drawn out with a fan on the cabinet head. I'm not expecting a lot of heat anyway since it's all modern tech inside, but it won't hurt to have good ventilation!

Thursday, July 21, 2011

Behind the Scenes

It's been a while since the last post (almost a month!) but things are not standing still. The project has just come to the point where I need a little help. Since I'm making the pinball machine in my living room, there are limits on what can be done around people and pets. Such as working on metal.

I've also finalized the lights layout and the layout of the actual playfield and feel confident enough to do an attempt on a proper whitewood board. Therefor I need to have a new playfield properly routed by professional woodworkers (or find somewhere where I can properly work the wood with electric tools) so that I get nice, clean, cuts for the inserts etc.

I've stretched out to find good companies for printing the artwork for the machine and play field and found a great local company. Just hoping they find the time to aid me with this. The graphics are not 100% done, but hopefully they will be soon.

The ruleset is also taking form and a lot of the features are already decided. If I pull of the things I've planned, this will be one epic board!

So things are indeed moving along quite nicely, it's just happening behind the scenes at the moment.

Sunday, June 26, 2011

Oh, those legs!

Got tired of bending myself into unnatural positions when I was working on the pinball machine so I attached the legs. A bit prematurely, since I need to take them off again any time soon to sand+paint the cabinet...

But it's starting to look quite good, doesn't it?

1) Cabinet with legs attached. Note the fancy global illumination lamp on top of the cabinet...

Tuesday, June 21, 2011

Dot Matrix Display

This should come in handy when the time comes....
Interfacing a real pinball DMD with Arduino.

And another about making DMD friendly graphics...
DMD Graphics with Flash.

More pinball projects!

Just found out a couple of days ago that the Longhorn Engineer is also building a pinball machine. He's come a bit further in his building than I, so check it out at

There's also Ed's Junk, who's creating a pinball machine based on the old NBA Hangtime games.
Be sure to check out Ben Heck's pinball project as well at
And in case you missed it, Jeri Ellsworth is (was?) building a machine as well as other high-tech stuff I wouldn't dare trying to understand!

I'm pretty sure there's a lot more out that, let me know if you got a project going on - I would love to know about it. It always nice to see others honoring the past and show that pinball is just as great today as it ever was.


Sunday, June 19, 2011

Mixed feelings...

Got the two MP3 Triggers playing alongside nicely now, complete with stereo sound mixing independently from each other through the same speaker set. The circuit was almost insultingly easy to create but it took a little trial and error...

I got confused about GND and GBUF, and since I burned the first cheap amp I wasn't to keen on testing further. So a little research later, I bought a new cheap amp and soldered a couple of resistors here and there - and it just worked!

This is enough volume to keep it interesting for now, but I'll probably have to get a better amp later on.
For those who are interested, this page contains the circuit needed. Simple, eh?

I also got receiving status requests from the MP3 Triggers to work at 19200 baud using NewSoftSerial (now: SoftwareSerial). Couldn't get receiving to work at all at first, but I needed to get the latest beta-driver along with a couple of specific pins on the Arduino Mega2560 to get it running.

The timing got off sometimes causing the response to get lost somewhere in cyberspace, but that was rectified using a stand alone power-supply instead of the USB-only that I was using when testing. Wish I knew that a couple of hours earlier....

Still can't get multiple SoftwareSerials to recieve properly thou...

Advice are appreciated!

Wednesday, June 15, 2011

More cabinet work laid to rest!

Spent a few days mounting the coindoor, siderails and various other pieces on the cabinet. Starting to actually look like a pinball machine now!

1) Top view, start button, coindoor, plunger, skirt and working single ball feeding system.
It needs additional components to support multiple balls, which the final board will have.

2) Inside view of the coindoor, which will eventually take Swedish 5-kronor or simply any coin.
Also, the lever guide assembly which locks the lockdown bar can be seen at the top left. 

3) The mess. Everything looked so neat and tidy before
the big (BIG) power cables took over the place.
I also spent some time beginning on a wire harness, so now all solenoids are plug&play connected to the machine. Of course, once I find a decent solution for having the board in a vertical position while doing work on it, I will fix the wire harness to the board itself. Right now it's a bit messy.

I still fear the day when I need to unscrew EVERYTHING, clean it up, paint it and reassemble it again.

But it will be awesome!

Tuesday, June 7, 2011


Yes! Got software serial working with the MP3 Trigger v2.

Once again, it turns out I didn't read carefully enough...
First - the ini file must be named MP3TRIGR.INI, not mp3trigr.ini etc.
Second - The baud settings in the file needs to be "#BAUD 9600" and in my world the hash-mark is a comment, so I removed it to enable that feature.... I thought.
Third - The SoftwareSerial library differs from the original, since Write (send bytes) and Print (send characters) are two different functions in the hardware version, but one and the same in the software. I needed to add the output type as well to get it working.

But after a bit of reading and fumbling around I can now use the pins I want for communication.

Hopefully 9600 baud is fast enough to trigger the sounds during a running game.

Monday, June 6, 2011

A little reconstruction here, a little reconstruction there...

... and we got sound!

Well, at least sound from one unit. The other one hasn't been ordered yet.

I had quite a struggle getting stuff to work and selecting the correct serial settings for the MP3 Trigger v2. The problem began with the first serial port occupied by one of the power boards connections. I.e trigger a sound - trigger the solenoid. Not good.

I tried resorting to using software serial communication instead...

...but after a long troubleshooting it turns out that the baud setting was not changeable in the ini file as I believed it would be. Since the baud is fixed at 9600 for software communication I couldn't use the SoftwareSerial library for Arduino to create a custom pin for serial communication. But it worked itself out alright in the end since the Mega2560 has three additional hardware serial ports that I could use instead. 

To get more than line-out level audio I had to get a small amplifier. I figure for testing purposes, a simple 7$ circuit would suffice, correct? Yes, it did. But I won't wake the neighbors with this! 

1) Cheap audio amplifier. This was gathered from a cheap MP3 speaker set that was mercilessly butchered and brought back to life by the ATX PSU. The next question is how I should mix the two sound boards' output into one stereo channel that can be sent to the speaker set...
I also spent a lot of time rewiring and cleaning up the electrics inside the cabinet. Now I got dedicated connections that I can tap +3.3V, +5V, +12V and +48V out of. Also, I rewired the Arduino and the one (later two) MP3 Trigger I got to use the computer PSU instead of a dedicated PSU for Arduino. 

2) Top: +48VDC connections, fusebox, +12VDC connections
The other top: Switchboard, temporary speakers
Center: +48VDC power boards, ground-bridge, Arduino, sound board, (cheap) audio amplifier
Bottom: +48VDC PSU, PC ATX PSU, +3.3/+5/+12V power connectors, extension cord

More power, cleaner cabling.  I like.

Saturday, June 4, 2011

Milestone 1

There's magic in the air tonight!

First, an incredible day in Malmö with my wonderful girlfriend (who deserves lots of credit for putting up with me building a pinball machine in the living room). We visited an exhibit there about vegan food and had a great meal. Highly recommended!

After that I wired up both flippers and kicked the ball around with the new power boards. Worked absolutely perfect! I accidentally put my knuckles in front of the flippers at one point, so I can guarantee they pack a heavy punch! I also tried the table at approx. 10 degrees angle and there were no problems at all hitting the higher places with force, so my initial design with quite high ramps should be alright.

Now that I know everything works as intended I can focus on getting the reset of the board and functions in place!

Wednesday, June 1, 2011

We're in control!

It turns out me burning the Wonderboard wasn't really my fault. I had a faulty coil so the circuit shorted. Instead of the minimum 4Ω my coil was 0.004Ω....

Ok... I lied. It was my fault also. I need to have normally closed EOS installed, mine was normally open. That also caused the high resistance coil never to trigger and thus burning the coil when I applied the +48VDC current.

This is how it's supposed to look when done (or redone) correctly:

1) The redone flipper assembly. Note the normally closed EOS switch. I've also installed the capacitors now. The nice thing about this setup (the correct way etc) is that if the EOS switch breaks, the resistance of the coil gets locked in high resistance, which means that the coil shouldn't burn out.
2) A closeup of the connectors. I've decided to use 'hot-plugs' so disconnecting the solenoids will be quick and easy if they need repairs. It also makes it impossible to connect power in the wrong direction since the cables will have matching pairs.

I've tested the setup with a regular ATX-powersupply and the new power driver boards and it works like a charm! Will be receiving my ATX-connectors in a day or two so I can supply the driver boards with +48VDC instead... (Wish me luck!)

Also, I got my MP3 trigger today, yeah!
Now I just need to connect a powersource (buy a powerplug 'head' or drive it directly from Arduino's +3.3VDC) and get FAT16 microSD flash card and I'll be playing MP3's like there's no tomorrow!

Can't wait!