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.

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.

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.

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...

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.

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.

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.

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.