Since PONG was such a snap (heh) - why not do BREAK OUT for the PIC12F1840? Same hardware as the PONG game (you will have to turn the paddle sideways for left to right, instead of up to down). A lot of the infrastructure for the PONG game remains - just change the position / orientation of the paddle, change the graphics, and change the game play. Yeah, that's _all_ that needs to be done. Sure.
I've just started this today - I have the title screen changed and the paddle orientation complete. Working on the game play now. Nothing worth releasing the software yet. If you want to see what is basically in the guts of this game, go take a look at the PONG post HERE and check out the source code links.
The title screen, field, paddle and ball are done. Scoring and life counting is done. Wall collision and paddle collision detects are implemented. Loss of a life if you miss the ball is implemented. Video timings are (mostly) at spec. All I need to do now is put in the bricks!
I'm going to take the opportunity to try a new timing scheme I have been thinking about. Instead of timing the video lines throughout the code, I am going to let a TIMER0 interrupt service routine generate the video signals (except for actual data). This should be interesting.
It's possible to use the timer0 interrupt to time the video signals - for the most part I am getting a clean signal with no jitters - but some of the tweaking is AWFUL. I think what I actually have is a hybrid between using the ISR and the manual timing. More work to be done!
Using the timer0 interrupt has been fully implemented. Everything is working as before, but now all of the nasty 'Timing Fudge' (usually a bunch of NOPs) has been removed from the code. I can change the graphics now without having to go through and tweak each of the individual lines. This is _really_ nice. And the screen is rock solid.
As an experiment, I wired up their 8-pin part to a ICSP header and connected it to a PICKIT2. Well, it's not a 12F629 - in fact, the PICKIT2 reads back an ID of '0', which I think means the device isn't responding back properly. Anyone out there know what Microchip device has an ID of '0', if any?
So it's not a Microchip PIC - probably. It could be some other micro, or a specialty part as I said before. BUT, the important thing is that a PIC12F629 _can_ work in the design. And that gives me 20 individual LEDs on an 8-pin PIC with no additional hardware. And that makes me _really_ happy. Just think of the upgraded 'Iron Man Chest Arc Reactor' I can build now!
Okay, I revisited the Chinese Meteor Lights with 18 LEDs that has an 8 pin device controlling the LEDs. At first it was thought that the device was an 8-pin micro of some sort, maybe a PIC12F629. After removing their part and replacing it with a PIC12F629 and trying some programming - I deemed that the original part was not a standard 8-pin micro and probably some type of specialty part, a-la the UCS1212.
Well, a blog reader informed that yes, indeed, you should be able to do this design with an 8-pin PIC12F629. You just need to tristate the GPIO pins to the LEDs you do not want lit.
After years of working as a validation engineer on new silicon, I am not hesitant to go back and rerun tests if questions are posed. No ego here. Thank God for that. Sometimes you are right - sometimes you are wrong. And sometimes, when you are wrong, it means the situation is actually better.
So - it turns out that I did the tests I ran before _did_ tristate the unwanted GPIOs, but I was still seeing multiple LEDs being lit - albeit that only the target LED was fully bright, and the rest were semi-bright, looking quite like leakage of some sort.
It turns out that I did my testing with the PICKIT2 still connected to the design. The PICKIT2 allows you to program the PIC12F629 while assembled in the design. Nice. But the PICKIT2 connects to GPIO0, 1, & 3 and can mess things up - which I found out when I disconnected the PICKIT2 and the meteor light started behaving as expected / desired.
So - yes, it is some sort of 8-pin micro. Yes, you can replicate the design using a PIC12F629. So - have at it!
That tune. It's. Stuck. In. My. Head...
A new update soon. I have a couple of bugs to squash.
I split out all of the NTSC stuff into it's own module - NTSC_Interface.INC and NTSC_Interface.ASM. Hopefully this makes for easier implementation of NTSC video in your projects. I also have ODD/EVEN fields implemented and the timings are _really_ tweaked to try to meet spec. The big LCD TV is working better (VSync locks now, data is clean, but there's a weird shifting of the line data), and everything else I have thrown at it works great, including my Sony LCD goggles.
In order to get the large LCD TV working, I've had to implement odd/even fields to the video generation. So - long story short - there's a lot of CRAP information out there on what the video signal is supposed to look like. I'm surprised I've had anything working, with the BAD information that I have been working from.
Happy ending? I'm close to getting absolutely correct video implemented, and it's all thanks to this webpage:
Who knew there were SIX pulses in the midst of the vertical synchronization phase for NTSC video, not FIVE as some as said. And who would have thought it would make such a difference to the video quality! One must NOT mix up the timings for PAL/SECAM and NTSC, or bad things will happen.
You're welcome. Merry Christmas.
Version 4.01 of PONG is now released. It has COMPUTER mode for player 2. Just press and hold the PLAYER 1 BUTTON while powering up. A large 'C' should be in the upper right corner of the screen.
Also note - the player 1 joystick handling has been modified for the Tandy joystick (see pics below). The original code is still in the source, just commented out.
I crammed my second PONG board into an old Tandy joystick. Well, 'crammed' isn't really true, because there's plenty of room for the board, cables and Audio/Video jacks. Now the batteries? Those may post a problem. I'm just powering it from the PICKIT3 at the moment.
Top view. Looks like a normal Tandy joystick.
The front side, with the big red button that is original to the
Tandy joystick. Cheesy.
The right side, showing the ICSP header for programming the PIC. I use this to power the device - at least until I figure
out what I am going to do for the batteries.
An upper view where you can see the joystick,
big red button, and the A/V connectors.
A view of the inside. The bottom is on the left, the top is on
the right. In the bottom, the A/V connectors are on the lower
left. The micro board is on the upper right. The top has the
original joystick and button that came with the device.
Another view of the inside.
The top is on the left, the bottom on the right.
Close up of the micro board. 1 PIC, 6 resistors.
I need to add a capacitor.
This PONG post has surpassed the Dual Die Emulator post in the number of views. Thank you all very much. And thanks again to Hack-A-Day for the link from their website.
I've built another PONG board, one that is to be battery powered and self-contained in an old Tandy joystick. And after an hour of soldering, I programmed the part and - it works! So the first one wasn't a complete fluke. This should give hope to anyone else out there who is building this project.
I'm programming in a mode for making player 2 a computer player. When I finish, I'll post the code for anyone who is interested.
I've been working on BREAK OUT and there's lots of lines with fixed, single pixels and I was having a heck of a time getting everything lined up and the video signal timings correct. I was tweaking my signal timing routine and adding NOPs all over the place and spending a LOT of time getting things right that would just break when I added code or changed the graphics.
So I finally broke down and started experimenting with using a interrupt service routine to control the video signal, with the timings based on TIMER0. It turned out great, so this morning a did a major overhaul of PONG and turned over control of all of the video signal timing to a TIMER0 ISR.
Oh my, I should have done this in the first place.
All of the 'Timing Fudge' comments with the associated NOPs are gone. You won't find stray NOPs anywhere except for placing pixels on a line - no more peppering the code with NOPs to get the sync width or line width correct. It is _so_ clean and rock solid now, and so easy to change and maintain, that it almost has me in tears to think of how much time I have spending pushing 250ns slices around in the code.
Since it's a major change, PONG has been bumped up to V4.00.
I've started a new game for the PIC12F1840 - BREAK OUT. The new post is HERE if you are interested.
Ah, damn. There's always another bug.
While filming the V3.06 demo, I noticed that the ball would sometimes hit the upper sideline and not bounce off at an angle - it would just continue to follow the sideline until hit with a paddle, and then take off following the sideline to the other paddle, ad nauseum. Yeah, it bugged me, and I fixed it in my sleep last night. I was able to come into the lab this morning, go directly to the problem in the code and fix it. Nice. Weird, but nice.
Also, the _DEBUG_ option is set to FALSE, so there's no VSYNC flag pulse being generated on GPIO2.
And some timing fixes. And I added a blank and then two white lines after the Copyright, because it looks good.
As you may know, the preliminary work on video from the PIC led to creating of a PONG game. Well, that game has led to a LOT of work done on the NTSC interface. And as part of that work, I split out all of the NTSC stuff into it's own module -
NTSC_Interface.INC and NTSC_Interface.ASM. Hopefully this makes for
easier implementation of NTSC video in your projects. I also have
ODD/EVEN fields implemented and the timings are _really_ tweaked to try
to meet spec. The big LCD TV is working better (VSync locks now, data is
clean, but there's a weird shifting of the line data), and everything
else I have thrown at it works great, including my Sony LCD goggles.
I am including the full PONG game so you can see how the NTSC_Interface module was integrated into the game itself - and hopefully it will be a learning example so you can implement NTSC video into your own PIC project.
We have a bouncing ball! I am updating the video buffer during the vertical sync.
Data retrieval from the EEPROM is working now. It also simplifies the code quite a bit. I put a monochrome (1 bit - black or white) 32x32 picture of my son in the EEPROM and this is how it looks. Nice! Pixelicious, but nice!
It's been a while since I worked on this project. I guess it's time to clean it up and finish it. So, here are the details:
I had an old mixer/amplifier board taken out of something that had broken (it was a Fukuda DVD/Tuner/Amplifier combo, and the power supply went kaput). It has a TM2313 mixer chip, which has an I2C interface, 3 selectable input, and 4 channel output. So, instead of letting it sit around and do nothing, I decided to make my own Mixer/Amplifier interface, using a PIC12F1840 as the microcontroller.
Success! I have three thumbsticks (each with their own PIC12F1840) communicating over the same One-Wire interface to another PIC12F1840, which is displaying the thumbstick information on an I2C LCD.
Bus-backoff is working well, speed was dropped a bit (now only 50 reports per second per stick), and collisions are unusual. The important thing is making sure no incorrect or corrupted data is reported.
I only have three thumbsticks connected, because I didn't want to waste my precious perf board on a fourth.
I love it when things work.
Well, it's working. I need to clean up the code a bit. But - it's working! BTW: The red dongle to the top is the PICKIT3 programmer for the PIC12F1840. The umbilical going to the lower-right is the connection for my analyzer (USBee ZX). And the LCD is a 2x16 character with an I2C interface. Yes, I'm bit-banging two pins on the PIC to emulate an I2C interface. Right now, the code consumes 717 words of PIC memory, out of 4096 words. I'm going to shrink that a bit. There's an I2C interface module, a LCD interface module, the One-Wire interface module, and the small bit of main code.
Idle - thumbstick (button) unpressed and the thumbstick centered.
The thumbstick (button) pressed.
Y-Axis (Up-Down) fully DOWN.
Y-Axis (Up-Down) fully UP.
X-Axis (Left-Right) fully LEFT.
X-Axis (Left-Right) fully RIGHT.
Back to the idle state.
I've been working on the code and I found a minor hardware issue - the X-Axis was reversed. So I fixed that and updated the schematic (below). Added a few notes, too.
The code is pretty much done on the transmitter side - I need to work on the receiver now. Maybe just a PIC with an attached I2C LCD to display the info. That should be entertaining.
Each report from the device contains 3 bytes - the first byte is the identifier, plus the button information. High nibble is always 'D' (B'1101'), next nibble is the device address in bits 3-2, and finally the button state information in bit 0. The next two bytes are the X-Axis and Y-Axis information. Reports are only made if a state change to the button, X-Axis or Y-Axis is detected. Reports consume 400us on the bus, and there is always 5ms between reports - to allow for other devices (up to 4 total) to get on the bus and report. That means that there will be a maximum of 200 reports per second - is that a good enough response time? I've also implemented a crude bus-backoff algorithm just in case some other device is already using the bus to report.
That's it for now - more as progress is made.
Here's a little module I whipped up. It's a PIC12F1840 interfaced to a PS1 thumbstick. It has a 1-wire interface to whatever wants to use the joystick information. There are two axis - x and y - and a pushbutton (press the thumbstick). Each module can have a unique address (2 bits), so you can have up to 4 modules on a system. The device information is encoded in the packet sent to the host.
I'm still working on the code. I am using a variant of the 40khz IR transmitter - I am going to bump up the speed - and the same work will need to be done on the 40khz IR receiver code on the host.