Drake is the name of the computer I am developing. However, this blog covers all aspects of embedded hardware and software, and explains various projects in detail. Feedback is greatly appreciated.
woensdag 2 december 2009
Adding a segment: the middle vertical bar
My first idea for a segment to add is the middle vertical bar. This will not be split in two, but instead will be the whole length. This makes some letters better (B, D, |) and other characters possible ($, +, T, M, W, w, m, x, X). As you can see, there is still a lot of room for improvement.
dinsdag 1 december 2009
7 segment font
I've been playing with fonts for a while, and I've always wondered about the least number of bits that is needed to display a character set. One option is to use a 7 segment display, as shown in this picture. Sadly, it doesn't handle all characters, and a lot of them are messed up. On wikipedia there is a 14 segment display, which does handle most characters correctly, but 14 bits seems a bit excessive. I'll see if I can find some alternatives that use less segments, but still produce acceptable results. If you have ideas, please let me know.
zondag 15 november 2009
GTA-316 blue screen fix
I recently got a GTA-316 digital photo frame (I know, about three years later than most people) and after installing my first set of JPG images it turned out that it had crashed, because the first JPG was not in a format it liked. This problem was permanent: when you turned the device on, it would immediately load the picture, try to display it, and fail. All it would show was a blue screen (see figure 1), and none of the buttons would work anymore (not even the one that turns it off). Basically it turned into a paper weight. I was planning to use the LCD screen for my own purposes, but I was not going to let a software error like this get the better of me either. I fixed the problem, and here is how I did it.
First I opened the GTA-316. This is relatively simple, there are four screws (two hidden behind the battery panel). Figure 2 shows you how to access these screws. You'll need a very small screwdriver to unscrew them, but it is easy. I had to use a magnet to find the screws afterwards, so be prepared to store them somewhere safe. It is best to remember how you take things apart, so you can put it back together more easily later.
Once open, lay out the components as shown in figure 3. You can detach the front panel and the plexiglass completely, the front panel holds a microphone, but this is rather loose. Now you need to follow the following steps:
1. Use a large pointy metal object and scrape a few times along the address lines of the EEPROM inside the GTA-316 (see picture) to remove any coating.
2. Connect the USB of the computer to the GTA-316.
3. Press the "on" button of the GTA-316. This is marked in the picture with a red arrow.
4. Wait until the cute and compression distorted animation starts.
5. Press the large pointy metal object against the address lines of the EEPROM inside the GTA-316 (see picture) to short circuit them. Hold it there until the display shows an error message ("PICTURE FILE ERROR" or something like this). If this message does not appear, but instead the blue screen appears, read the next paragraph.
6. Remove the large pointy metal object.
7. Your computer should now recognize the GTA-316 as an unformatted USB drive.
8. Allow the computer to format the drive (this gets rid of your bad JPG files). If instead the computer shows the folder with the bad JPG files, delete them.
9. Use the "safely remove hardware" option of your computer.
10. Disconnect the GTA-316.
11. The GTA-316 should now be in working order. Make sure you follow the instructions and use the included conversion program (or hints on other websites) to ensure no bad JPG files make their way on the GTA-316.
In case the GTA-316 gives a blue screen instead of an error message you did not touch the correct lines. Sadly I was unable to find a data sheet of the particular chip, and I pressed the object randomly against the lines. Circled in figure 4 are is the area where most address lines are located, which gives you the highest chance of success. I had to do it four times myself. Make sure the pins are properly scraped and the metal object is not greasy. In case you get the blue screen, disconnect the USB and start again at step 1 in the paragraph above.
Warning/disclaimer: this procedure involves messing with hardware. It is unlike to cause problems, but I do not guarantee anything. Your results may vary. The GTA-316 might stop working forever. The computer attached using the USB might blow up. If the USB connection has issues, you might get an electric shock. In other words: do the following steps at your own risk.If this fix worked for you, or does not work for you, or if you have an easier way to fix it, please let me know. I welcome comments.
First I opened the GTA-316. This is relatively simple, there are four screws (two hidden behind the battery panel). Figure 2 shows you how to access these screws. You'll need a very small screwdriver to unscrew them, but it is easy. I had to use a magnet to find the screws afterwards, so be prepared to store them somewhere safe. It is best to remember how you take things apart, so you can put it back together more easily later.
Once open, lay out the components as shown in figure 3. You can detach the front panel and the plexiglass completely, the front panel holds a microphone, but this is rather loose. Now you need to follow the following steps:
1. Use a large pointy metal object and scrape a few times along the address lines of the EEPROM inside the GTA-316 (see picture) to remove any coating.
2. Connect the USB of the computer to the GTA-316.
3. Press the "on" button of the GTA-316. This is marked in the picture with a red arrow.
4. Wait until the cute and compression distorted animation starts.
5. Press the large pointy metal object against the address lines of the EEPROM inside the GTA-316 (see picture) to short circuit them. Hold it there until the display shows an error message ("PICTURE FILE ERROR" or something like this). If this message does not appear, but instead the blue screen appears, read the next paragraph.
6. Remove the large pointy metal object.
7. Your computer should now recognize the GTA-316 as an unformatted USB drive.
8. Allow the computer to format the drive (this gets rid of your bad JPG files). If instead the computer shows the folder with the bad JPG files, delete them.
9. Use the "safely remove hardware" option of your computer.
10. Disconnect the GTA-316.
11. The GTA-316 should now be in working order. Make sure you follow the instructions and use the included conversion program (or hints on other websites) to ensure no bad JPG files make their way on the GTA-316.
In case the GTA-316 gives a blue screen instead of an error message you did not touch the correct lines. Sadly I was unable to find a data sheet of the particular chip, and I pressed the object randomly against the lines. Circled in figure 4 are is the area where most address lines are located, which gives you the highest chance of success. I had to do it four times myself. Make sure the pins are properly scraped and the metal object is not greasy. In case you get the blue screen, disconnect the USB and start again at step 1 in the paragraph above.
zaterdag 4 juli 2009
More animations
I finally settled into my new place in Sunnyvale, so you can expect more posts here. I added some animations to the LED cube: a heart beat, an elevator, a cube drawing and a slow glow effect. Especially the glow effect is impressive (you can't see the LED blink) and only possible due to the way the cube was wired. Other effects are trickier, though, hopefully I can define one of the trickier ones tomorrow.
zondag 26 april 2009
Source code for LED cube control
The source code for the LED cube control is now available. Basically PORTB and PORTC of the PIC16F57 (which is actually a low end device) are used to control the output. I'm looping one bit through PORTB and one bit through PORTC to address all LED.
Fourth layer picture
zaterdag 25 april 2009
Fourth layer
The fourth layer is finished, but not attached yet. Hopefully that will happen tomorrow, together with my first animation. Video should be provided.
zondag 12 april 2009
Third layer
maandag 30 maart 2009
Pattern
I succeeded in creating a two part pattern loop. An issue was that blanking the image in between each shift caused the LED to be less bright. By adding a delay the impact of the blank could be reduced, however, initially there was too much delay and the pattern seemed to be blinking. The correct code is as follows:
PatternDelay
call Blank
movf p1,w
movwf PORTC
movf p1+1,w
movwf PORTB
call SmallDelay
call Blank
movf p2,w
movwf PORTC
movf p2+1,w
movwf PORTB
call SmallDelay
decfsz delay+1,f
goto PatternDelay
decfsz howlong,f
goto PatternDelay
retlw 0
Here the two patterns are in p1 and p2. As you can see it is relatively easy to extend to more patterns. The next step would be to write an application that can find the minimum sets needed to display a certain pattern.
zondag 29 maart 2009
Figures
Today I tried to create the first figure on the LED cube, an O. In order to do this I had to switch between two patterns, two dots at the bottom in the middle and at the top in the middle, and two dots to the left in the middle and at the right in the middle. The trick was ensuring that the screen is blank in between, because any transistion LED will seem lit as well. The code became:
Next step would be to have the delay loop automatically switch between two patterns... Although I might need more than two for complex figures. At 20 MHz it is completely invisible that such switching is taking place, except for the LED being slightly dimmer. Biggest problem is still that the bottom LED make it seem like the LED at the top are slightly lit. I might need to reduce their transparancy somehow.
Display
call Blank
movlw 96
movwf PORTC
movlw 6+96
movwf PORTB
call Blank
movlw 144
movwf PORTC
movlw 9+144
movwf PORTB
goto Display
Blank
movlw 240
movwf PORTC
clrf PORTB
retlw 0
Next step would be to have the delay loop automatically switch between two patterns... Although I might need more than two for complex figures. At 20 MHz it is completely invisible that such switching is taking place, except for the LED being slightly dimmer. Biggest problem is still that the bottom LED make it seem like the LED at the top are slightly lit. I might need to reduce their transparancy somehow.
zaterdag 28 maart 2009
Second layer of LED cube
maandag 23 maart 2009
LED cube problem
I woke up in the middle of the night (which usually doesn't happen) with the thought that my idea of reversing the polarity of the LED in the matrix to double the number of LED I can control wouldn't work. I drew a small version on a piece of paper, and indeed: it doesn't work. There is no combination of control signals that will allow me to turn on only one LED. It's fortunate that I discovered this now, instead of after soldering the next layer of LED. I can still control the cube with 16 lines, but I'll have to use a matrix of 8x8 divided in 4 4x4 segments rather than using two 4x4x2 segments. There will be a switching issue, but at 20 MHz this shouldn't create a big problem.
zondag 22 maart 2009
Processor board
After I cycled against and with the wind to Radioshack (the closest, but not the cheapest supplier of PCB in my area) I was able to start soldering together the board shown. It is the typical board I make, with a 6 pin ICSP for connecting the Pickit 2, a 8-12V power supply input using a 2.1mm jack (standard) and a 20 MHz resonator (not very accurate, but accuracy seems not very important in a LED cube. The speed is useful for making special effects, which I'll probably never write). As said I'm using the 16F57, mostly because I had one around and it has two full ports (PORTB and PORTC) that can be used to control the cube. PORTB will have to share bits with the ICSP, but that shouldn't be a problem. After soldering the board I tested it, and it didn't immediately work, but that was because I didn't realise the PIC16F57 is actually not a 16-series PIC, but a base model PIC. After switching the programming software to recognize base PIC, it all worked fine. My voltage meter is running out of power, so it was giving the clearly wrong voltage of 6.3V from USB and the 7805. I'll have to buy a new battery for it.
zaterdag 21 maart 2009
LED part 2
I know, progress is rather slow, but here is the next part, and basically the ground floor of the LED cube. I also added the required resistors. I didn't have a PCB so I couldn't hook it up yet, but I did decide on the PICmicro to use: the rather obscure PIC16F57 which happened to be in one of the boxes that I got for winning the Microchip Innovation competition. I need to check on it, but it has 28 pins so I'm pretty sure I can use two full PORT for outputting the data, which would reduce the requirement for quick switching between patterns. I already tried lighting one of the LED, and they burn rather brightly, and are visible from the side as well. I'm still not sure if the next layer should face up as well, but it is probably best if they do.
donderdag 12 maart 2009
LED part 1
The LED arrived, and they were nicer than I thought: they actually look transparent, which is much more useful for the cube idea. I started soldering them together, here are the first 8. I'll probably need to devise some plastic covering to ensure that the wires don't cross once I start bending the whole thing into a proper shape.
zaterdag 28 februari 2009
Places to order parts
In my previous post I referenced Futurlec as a place where you can order parts. Note that they are slow, but they are inexpensive and they have some very unique items. I really like their "LCD8X2", which is the smallest LCD display I have found so far that can still display 16 characters on two lines, and is controlled by a normal HD44780.
If I needs parts quickly, I usually go to Jameco, which is around the corner of my work place. They are more expensive, but they have very good service: you can just walk in, and walk out with your parts within 15 minutes. If you order them over the phone, they can even make them ready for pick up.
For the actual PIC microcontrollers I used to use Glitchbuster, but unfortunately they disappeared. I currently still have a large amount of them from winning the grand prize of the Microchip innovation competition but dread the moment that I would actually have to order more, as none of the websites I mentioned so far carry a good assortment. I might just order them directly of Microchip's website.
Finally, for all sorts of odds and ends, like soldering irons, solder, wirewrap wire, and various PCB, I tend to visit the local Radioshack. Do not buy parts here, as they are very expensive, and inferior in quality. Just look out for those things that will make your life better.
If I needs parts quickly, I usually go to Jameco, which is around the corner of my work place. They are more expensive, but they have very good service: you can just walk in, and walk out with your parts within 15 minutes. If you order them over the phone, they can even make them ready for pick up.
For the actual PIC microcontrollers I used to use Glitchbuster, but unfortunately they disappeared. I currently still have a large amount of them from winning the grand prize of the Microchip innovation competition but dread the moment that I would actually have to order more, as none of the websites I mentioned so far carry a good assortment. I might just order them directly of Microchip's website.
Finally, for all sorts of odds and ends, like soldering irons, solder, wirewrap wire, and various PCB, I tend to visit the local Radioshack. Do not buy parts here, as they are very expensive, and inferior in quality. Just look out for those things that will make your life better.
3D LED cube
Of course I will be continuing with the ZX-jen project, but I'm also working on a display consisting of 4x4x4 LED. I ordered 10mm big LED and will soon put them together. Using a grid with two LED (opposite polarity) per crossing you can control 72 LED with 12 lines, but I think it is wiser to control two groups of 32 LED with 8 lines each, for a total of 16 lines. This way the control of each group can be done with a single PORT, allowing all LED to change at the same time without intermediate values, which could cause the display to blink LED that should remain off. This could still happen, but is a lot less likely with the new configuration. I'll write more once the LED have come in, I used Futurlec for the order, which is notoriously slow, but has nice products for an inexpensive price.
dinsdag 17 februari 2009
MIDI module
At some point I found this box, and decided to turn it into a MIDI module. MIDI is a bit obsolete nowadays, but I still have a keyboard and an pseudo-analog synthesizer that use it, so I thought to create something. So far it can play Beethoven, but it can't record yet. This is something I'll still need to work on, but after my recent experience with the GPS module, this should be a lot easier.
At least it looks nice, though a few lights would of course make it more interesting.
At least it looks nice, though a few lights would of course make it more interesting.
zondag 15 februari 2009
Acey Ducey working
"Soon" was a bit later than I thought. The first thing that became troublesome was the encoding of strings as {length,character,character,character,...}. Parsing strings like that requires making sure the length is always kept correct, and given the large number of different parse routines for skipping digits, skipping characters, skipping whitespace and various other tokens the length rarely was correct. Instead of hunting down this error I thought it was more robust to change the encoding of strings as {character,character,character,...,0} which is the usual way strings are encoded in C. This means that 0 can no longer be used as a character, but since this was not something you could input on a keyboard anyway it wasn't very relevant. Of course, changing the code this way was not entirely insignificant, but fortunately everything was structured well enough so the switch was done in an hour or so.
The next issue that I ran into was the keyboard input. The keyboard handling is currently done without an interrupt, disabling and enabling the keyboard using the clock line whenever character input is required. This worked well. However, I also want to check for the "Esc" key during program execution, so the user can interrupt the program if so desired. In order to do this I occasionally release control of the clock line and look if a character comes in. If it does, I read it and checked whether it was "Esc". This worked well, however, if keyboard input happens for a normal reason during execution (in this case, to enter the bet of the player) the last scan code ("Enter key released") will be stalled due to the clock line being pulled low, and will appear as the next character. The routine checking for "Esc" finds this scan code, and assumes that the user entered something and will wait for input, but obviously the user just released the "Enter" key and no characters are forthcoming. This means the program seems to hang. I fixed it by having two versions of the getKeyboard routine (using a status bit), one in case I do want to wait until input takes place, and one which will return after the first scancode has been recognized.
But after that, the Acey Ducey game from the classic computer games website started working. Of course, there were some bugs in this BASIC program, and some minor conversions that were needed, but in general it works, as you can see from the screen shot. Typical conversions include adding % to indicate that the variables are integers, adding LET in front of assignment statements, using RND(number) instead of number*RND(1) and splitting the PRINT part of an INPUT statement, as well as a PRINT statement that prints both constants and variables. Finally some of the constant strings needed to be shortened in order to fit the screen.
I'm happy that the game is running, but obviously I don't want to enter it over and over again. I therefore will have to devise a way to store the program somewhere, and retrieve it. There are two ways: I can add an additional 24LC512 chip and compress and store the code in there, or I can use the upper part of the current 24LC512 for storage. Currently a program can use lines 1-2047, storing it at the top would reduce this. Of course, an alternative would be to use an SD card for storage, allowing easy exchange with a PC as well. Or a serial interface/USB interface for storing it in a PC.
Apart from this a lot will need to happen with the code. String handling. Array handling. Negative number input. Fortunately it is using much less than 3K so far, of the 4K that is available. So a lot of features are still possible, although I might have to divert from usual BASIC syntax in certain cases. For arrays I'm tempted to use square brackets, for example, to distinguish them from functions. For strings I'll probably resort to the ZX-81 method of treating them as arrays to begin with. And it is likely an array like DIM A%(10) will have element A%[1] overlap with variable B%, as the RAM of a PICmicro is, after all, tiny (less than 400 bytes, of which many are used for processing).
The next issue that I ran into was the keyboard input. The keyboard handling is currently done without an interrupt, disabling and enabling the keyboard using the clock line whenever character input is required. This worked well. However, I also want to check for the "Esc" key during program execution, so the user can interrupt the program if so desired. In order to do this I occasionally release control of the clock line and look if a character comes in. If it does, I read it and checked whether it was "Esc". This worked well, however, if keyboard input happens for a normal reason during execution (in this case, to enter the bet of the player) the last scan code ("Enter key released") will be stalled due to the clock line being pulled low, and will appear as the next character. The routine checking for "Esc" finds this scan code, and assumes that the user entered something and will wait for input, but obviously the user just released the "Enter" key and no characters are forthcoming. This means the program seems to hang. I fixed it by having two versions of the getKeyboard routine (using a status bit), one in case I do want to wait until input takes place, and one which will return after the first scancode has been recognized.
But after that, the Acey Ducey game from the classic computer games website started working. Of course, there were some bugs in this BASIC program, and some minor conversions that were needed, but in general it works, as you can see from the screen shot. Typical conversions include adding % to indicate that the variables are integers, adding LET in front of assignment statements, using RND(number) instead of number*RND(1) and splitting the PRINT part of an INPUT statement, as well as a PRINT statement that prints both constants and variables. Finally some of the constant strings needed to be shortened in order to fit the screen.
I'm happy that the game is running, but obviously I don't want to enter it over and over again. I therefore will have to devise a way to store the program somewhere, and retrieve it. There are two ways: I can add an additional 24LC512 chip and compress and store the code in there, or I can use the upper part of the current 24LC512 for storage. Currently a program can use lines 1-2047, storing it at the top would reduce this. Of course, an alternative would be to use an SD card for storage, allowing easy exchange with a PC as well. Or a serial interface/USB interface for storing it in a PC.
Apart from this a lot will need to happen with the code. String handling. Array handling. Negative number input. Fortunately it is using much less than 3K so far, of the 4K that is available. So a lot of features are still possible, although I might have to divert from usual BASIC syntax in certain cases. For arrays I'm tempted to use square brackets, for example, to distinguish them from functions. For strings I'll probably resort to the ZX-81 method of treating them as arrays to begin with. And it is likely an array like DIM A%(10) will have element A%[1] overlap with variable B%, as the RAM of a PICmicro is, after all, tiny (less than 400 bytes, of which many are used for processing).
vrijdag 13 februari 2009
Partial LIST
Partial LIST now works. You can specify a line number, and it will only show the code from that line number. I also limited the length of the list displayed, as there is no way to control this otherwise. I then started implementing one of the examples again, and discovered that the 9 was not handled correctly, which I fixed. Soon the first game will be working...
maandag 9 februari 2009
Subtract
And now subtract works in expressions. Again only a few minutes of coding, but by coding a few minutes a day, I slowly get to where I want to be. The next step will be more attention to the user interface, as showing the entire listing is unacceptable. LIST 10-100 and such commands need to be understood and functioning, or there needs to be a delay between moving back to the top of the next page.
zondag 8 februari 2009
RND
As I'm trying to get the programs at the classic basic games webpage to run on the ZX-jen I needed the RND() function. Unlike the old RND() functions, which return floating point numbers, which would require me to add floating point or at least fixed point methods to my code, I decided to create an integer version of RND() in which the parameter indicates the limit to be returned. So if RND(14) is called, it returns a random number between 0 and 13. It actually accepts an expression between the parenthesis, although since the PICmicro has only 8 depths of recursion it could go wrong at some point. Soon I will be able to show you the first program running under the ZX-jen.
Upon attempting to enter the first program I discovered that I need to implement the - operation, as well as some form of delay, because the screen is small and often scrolls over before everything is displayed. Of course, I can code the delay manually, but then GOSUB suddenly becomes important.
Upon attempting to enter the first program I discovered that I need to implement the - operation, as well as some form of delay, because the screen is small and often scrolls over before everything is displayed. Of course, I can code the delay manually, but then GOSUB suddenly becomes important.
donderdag 5 februari 2009
INPUT
I'm pretty sure you'll believe that INPUT now works without me showing a screen shot. INPUT accepts only a variable name (and an integer variable only, even) and causes a ? to be displayed, after which the user can enter a number. The number gets converted and can then be used for processing. It was relatively easy, although I had to distinguish i-nput from i-f. There was one bug: as you know I disable the keyboard while the program is executing, in order to avoid characters getting lost (I know, an interrupt routine to gather keystrokes would work, but that is just postponing the problem, makes the code more complicated to debug, and doesn't use the hardware to its fullest extent, as a keyboard has a built in 15 character buffer). When I called the getSentence() code I forgot to enable the keyboard. So it seemed the system just froze. Easily found, and easily fixed.
Now all I need is an random function and some other easy mathematics and I can start porting simple BASIC games. At that point it will probably become useful to write an inport/export feature that allows me to store the written programs. Of course, I could just take the memory chip out and insert another one, preserving the code that way, but that seems rather involved and expensive. An interface to a PC or SD card might be better.
Now all I need is an random function and some other easy mathematics and I can start porting simple BASIC games. At that point it will probably become useful to write an inport/export feature that allows me to store the written programs. Of course, I could just take the memory chip out and insert another one, preserving the code that way, but that seems rather involved and expensive. An interface to a PC or SD card might be better.
zondag 1 februari 2009
IF...THEN
Instead of FOR...NEXT I thought IF...THEN might be a much better option. As shown, IF...THEN now works. It can do comparisons <, =, >, <>, <=, >=, and, as a bonus, == (same as =, obviously). As my parser only checks for positive cases and not for negative cases, you can also write IF...GOTO. Because this work was done during the weekend, and therefore during the day, you can even see me taking the picture in the reflection of the television as well as my messy desk on the background. I discovered several things still need to improve: number printing should leave out leading zeroes, and it should handle negative numbers, as these might show up soon. Regardless, this introduces the important concept of flow control into the system which means it might actually start doing something useful in the near future.
vrijdag 30 januari 2009
Source code for alphabet applications
On the PIClist someone asked about an example for controlling a LED display to show characters. I referred to my clock at the time, but I wrote a simpler application for a children's night light which also contained an alphabet. If you click on this link, it will lead you to the source code, which includes the character set. The usual copyright notice, found elsewhere in this blog, applies.
donderdag 29 januari 2009
Addition!
As you can see from this screen shot, addition now works. In fact, I now have a CMRreadexpression routine that reads an expression, parses it and executes it. It can differentiate between variable names and numbers, as well as handle the + symbol. It can be easily extended to handle other operations as well, though parentheses will be another hurdle, if I am going to implement those at all. Making it a separate function will make it very easy to include it in the next challenge, the FOR instruction. So hopefully I will be able to say things like:
FOR a%=b%+1 TO 0 STEP -1
...
NEXT a%
In the screen shot you can see additional debug statements that identify the operator ('+') but this will be removed soon, probably. Despite what the screen shot seems to imply, the print bug of virtual semicolons has not been fixed: I just added a few spaces to the end of the line.
FOR a%=b%+1 TO 0 STEP -1
...
NEXT a%
In the screen shot you can see additional debug statements that identify the operator ('+') but this will be removed soon, probably. Despite what the screen shot seems to imply, the print bug of virtual semicolons has not been fixed: I just added a few spaces to the end of the line.
maandag 26 januari 2009
Slow ZX-jen progress
Another short program, demonstrating progress in the handling of variables. You can now assign integer variables with let, and assign them a number (other operations will be implemented in the future) and print them, either with ; (means no newline will print) or without. The output contains the usual debug statements, l for 'let' and p for 'print'. As you can see there is still a slight bug in the print command where it doesn't check the length of the read sentence, and thereby it assumes that line 40 ends with a ;. It used to, in the past, but it was erased. Unfortunately, this was not yet realised by the program. This will need to be fixed. But lots of things need to be fixed still. At least it seems like it is doing something.
I decreased the size of the image here. If you want to see a blown up version of the screen shot, look at the previous post. It will show approximately how the screen is built. Also, thank you for the comment on that post... I always enjoy comments.
I decreased the size of the image here. If you want to see a blown up version of the screen shot, look at the previous post. It will show approximately how the screen is built. Also, thank you for the comment on that post... I always enjoy comments.
zondag 25 januari 2009
ZX-jen screen shot
Here is a screenshot from the "ZX-jen" project, or the Drake-TV mentioned earlier in this blog. The cursor is '>' and the screen continues at the top after it ends at the bottom, instead of scrolling. The square block is the cursor and indicates the current position. Before that is the executing of the program, which is:
10 print "Hello world!"
20 let a%=3
As you can see the result of the execution is:
pHello world!
l%
The "Hello world!" is the actual output, the "p" and "l" are debug indicators: they are the first letter of the command being executed, so "print" and "let". The % sign is the type of variable being read, in this case an integer, which indicates that the let statement was correctly interpreted. The only other command that is currently available is "goto". The "Esc" key can be used to interrupt a program. The next step will be to allow printing of a%, although for that to happen the assignment should actually store the value in memory. After this various simple operations, like + and - should be implemented. After this I will consider the "for" and "next" statements.
As you can see the system supports "run" and "list" commands, but also "new" to wipe the memory. The program is stored in an external 24LC512, so even if the power fails the program will be available. Program lines can be entered by just preceding something with a line number, and deleted by providing a line number with no data. Overwriting is possible too.
10 print "Hello world!"
20 let a%=3
As you can see the result of the execution is:
pHello world!
l%
The "Hello world!" is the actual output, the "p" and "l" are debug indicators: they are the first letter of the command being executed, so "print" and "let". The % sign is the type of variable being read, in this case an integer, which indicates that the let statement was correctly interpreted. The only other command that is currently available is "goto". The "Esc" key can be used to interrupt a program. The next step will be to allow printing of a%, although for that to happen the assignment should actually store the value in memory. After this various simple operations, like + and - should be implemented. After this I will consider the "for" and "next" statements.
As you can see the system supports "run" and "list" commands, but also "new" to wipe the memory. The program is stored in an external 24LC512, so even if the power fails the program will be available. Program lines can be entered by just preceding something with a line number, and deleted by providing a line number with no data. Overwriting is possible too.
zaterdag 24 januari 2009
Debugging the clock
Most likely due to the fact that I took pictures of it for this blog, one of the many wires connecting the LED had broken. This is the disadvantage of wirewrap wire: it breaks easily. After looking at the clock, I discovered that last vertical line failed completely, and the vertical line 7 before that. So using my own schematic it was clear that the D0 line from the PIC16F877A had failed, but not immediately: going from the 7th row of LED to the 14th row. So it was easy to locate the wire that was loose and resolder it. The clock works now, again.
In other words: glad I documented things in this blog. Otherwise I wouldn't have had the schematic. Of course, if I hadn't documented it, it probably wouldn't have broken either...
In other words: glad I documented things in this blog. Otherwise I wouldn't have had the schematic. Of course, if I hadn't documented it, it probably wouldn't have broken either...
maandag 19 januari 2009
LED clock source code
The source code of the LED clock is not very tidy, but it does the job. It first contains the definition of the hands of the clock, for one quarter. These are given by move up and move right markers, two bits at a time. I also added tables for mapping X coordinates and multiplying a number with 5, which, together with a bit shift, is convenient for also multiplying with 10. Then there are the routines for drawing digits. Digits have been optimized for the least amount of LED needed to display them, as displaying fewer LED allows brighter LED. The "second hand" is actually a single LED that moves in a square around the clock, and its table defines that movement. Initialization is as usual, with the A/D converter for reading the temperature.
The drawing routine has a memory bank that retains the image, which is rebuilt every time a display is made. For this rebuilding separate routines exist, one to display a single pixel, ones that draw entire digits, and ones that draw hands. A cursor keeps track of where things are currently being drawn. There is a separate set of routines to allow a scroll text on the clock, which is used to announce birthdays (not completely implemented yet) and a help text (which currently randomly enables itself). Then there are routines to display the temperature graph over the last 15 minutes, 15 hours and 15 days. Each LED position is 2 degrees Celcius. Not very accurate, but still interesting to see. Actually displaying things is done by "RefreshDisplay" which draws all the LED that are on. It skips LED that are off, to ensure that the remaining ones are brighter (this means that a display with more LED on will have these LED dim a bit).
Then there are routines to handle the two buttons, which are used to navigate through the different menus and submenus, including the setting of the alarm time and the alarm count down options. Updating the clock is also done this way. I also started on a teddy bear mode where it would display certain animals as pictures, but this has not completed yet.
The drawing routine has a memory bank that retains the image, which is rebuilt every time a display is made. For this rebuilding separate routines exist, one to display a single pixel, ones that draw entire digits, and ones that draw hands. A cursor keeps track of where things are currently being drawn. There is a separate set of routines to allow a scroll text on the clock, which is used to announce birthdays (not completely implemented yet) and a help text (which currently randomly enables itself). Then there are routines to display the temperature graph over the last 15 minutes, 15 hours and 15 days. Each LED position is 2 degrees Celcius. Not very accurate, but still interesting to see. Actually displaying things is done by "RefreshDisplay" which draws all the LED that are on. It skips LED that are off, to ensure that the remaining ones are brighter (this means that a display with more LED on will have these LED dim a bit).
Then there are routines to handle the two buttons, which are used to navigate through the different menus and submenus, including the setting of the alarm time and the alarm count down options. Updating the clock is also done this way. I also started on a teddy bear mode where it would display certain animals as pictures, but this has not completed yet.
zondag 18 januari 2009
Powering the LED of the clock
Obviously the hardest part of the clock was all the LED. For a display of 21x15 you already have 315 LED that need to be powered, and even the large 16F877A has only 40 pins. The first step to simplify things is to group the LED in groups of 7, with a shared cathode. At that point you can select a group of LED by setting the cathode to 0V, and light a specific LED by setting its anode to 5V. LED burn very brightly at 5V, but can handle this only for a short duration of time (the so-called duty interval). For the LED I used the duty interval was 1/16th, but because of the amount of LED I stayed well below that. To select a group of LED I used the 74LS154, which demultiplexes a 4-bit input into 16 separate lines that can be individually pulled low. Attaching these to each of the cathodes would allow the control of 16 groups of LED. As they are grouped in groups of 7, this meant approximately 1/3rd of the LED could be controlled this way. Using 3 74LS154 the entire board could be controlled (in the schematic not all LED are drawn, one has to imagine the missing LED in between). To make things easy the 74LS154 allows you to individually select which 74LS154 is active at a given time, so with only 7 lines you can control all cathodes, and with 7 additional lines all anodes. With 45 cathodes, this means the duty cycle is, at best, 1/45th. However, it turned out that the drain on the 74LS154 is not high enough to power 7 LED at the same time, and it has to be split in 2 groups (one of 3 LED, one of 4 LED). This means the duty cycle became 1/90th. It turns out that even at 1/90th the LED burn quite brightly and are well visible.
The anodes could obviously be powered directly from the PIC16F877A, as it can output 25mA per line. However, it can only output 100mA in total, and it is therefore recommend to add the 74LS125 buffer chip, which can output 35mA per line. Do not forget to add the 0.1uF decoupling capacitors at every IC used: in this case there are 3 74LS154, 2 74LS125 and 1 16F877A that need decoupling. The result is a display that can be used for many purposes, but was used, in this case, for a clock. Alternatively the LED could be all put in a long line, making a scroll text display.
The anodes could obviously be powered directly from the PIC16F877A, as it can output 25mA per line. However, it can only output 100mA in total, and it is therefore recommend to add the 74LS125 buffer chip, which can output 35mA per line. Do not forget to add the 0.1uF decoupling capacitors at every IC used: in this case there are 3 74LS154, 2 74LS125 and 1 16F877A that need decoupling. The result is a display that can be used for many purposes, but was used, in this case, for a clock. Alternatively the LED could be all put in a long line, making a scroll text display.
zaterdag 17 januari 2009
Temperature measurement for clock
The reason why I added a thermometer to the clock was because I had an LM335 lying around, which I bought at a website that doesn't exist anymore. It was relatively easy to connect (as you can see from the schematic). The resistor is pretty lenient, as the whole system needs to be calibrated on the PIC microcontroller that is attached. Unfortunately this also means that the system is very sensitive to the voltage that is applied: I currently have 6V attached to the system, which is not enough to properly prime the 7805 I use for power (a minimum of 6.6V is needed) which means that attaching a higher voltage source (like a 9V adapter) causes the temperature display to behave erratically. This can, of course, be easily avoided by just having enough power. Still, it is likely that for each different 7805 it has to be adjusted separately. This can be done externally by hooking up a 10K potentiometer to the ADJ pin of the LM335, however, since this was a one-off implementation I decided to just leave it the way it is.
donderdag 15 januari 2009
And here is the backside of the clock. As you can see, I took a few days wiring up all the LED on the front. It was a bit tedious, but also fun to see the result. I tested each line I added separately with a test program, to make sure everything worked well before continuing.
The wire used is actually wirewrap wire. It is very thin, and therefore has a higher resistance, but if you keep them relatively short this will not affect the circuit. They place themselves easily, but unfortunately will break if you move them too often. Easiest is to cut them to the correct length first, then strip them with pliers, then solder two spots together on the board and then push the end into the existing solder. This way you get a pretty solid connection to anywhere.
dinsdag 13 januari 2009
Clock
Another interesting project I completed last year was a clock, that uses 5x7 segment displays in a 21x15 configuration to form a display, on which a clock is displayed. The clock also measures temperature, keeps graphs over time and has a scroll text explaining its function. It is controlled by two buttons. On the picture you can see the normal display, with the clock set to approximately 5:30 PM (the LED in the corner indicates the PM). It also shows the current temperature in Celcius as well as the date (13th). The clock uses a PIC16F877A, mostly because of the large number of outputs that is needed to control all the LED. Most time was the soldering of all these connections, I'll include a picture of the back later, which shows how this was done. There are some IC to ensure proper power to the LED (although it is still lacking, occasionally). It uses the DS1307 for the time. The DS1302 with capacitor would've been better, but unfortunately I had none available, so I used the DS1307 with a separate battery.
Labels:
Clock,
DS1307,
LED,
PIC16F877A,
Thermometer
zondag 11 januari 2009
Current project: Drake-TV
My current project is Drake-TV, a new version of the Drake that is hooked up to a PS/2 keyboard and the television, and works on a 9V adapter. It contains the various circuits described on these pages: the power supply (using a 7805), the video output (this time using a 16F688 instead of the 16F628A), the main processor (the 16F690) and the "external" memory EEPROM (24LC512). The audio has not been connected yet, but will undoubtedly be connected in the future.
Labels:
EEPROM,
PIC16F628A,
PIC16F688,
PIC16F690,
power supply,
video
Abonneren op:
Posts (Atom)