Sep 7, 2013

Mascot 719

Got a "new" Mascot power supply to my workbench

Click to enlarge

I didn't expect very much from it but actually it's quite accurate and good power supply after one modification and calibration. At the beginning analogue voltage meter had about 0.5-0.7V offset. That may even break things especially in low voltages (for ex. 4.0V instead of 3.3V).

Datasheet says that it have <1.0mV load regulation @ 15V output, <1.0mV line regulation @ 2A load current and ripple voltage should be under 0.3Vrms. Sense wires are also quite nice addition.

After some tests I opened it up and  found a few calibration potentiometers. None of them appeared to affect volt meters offset until I found a place of potentiometer that had been replaced with ordinary 81k ohm resistor (series with meters coil in voltage mode). That was quite easy to replace with a 100k potentiometer and now it seems to be bang on!

Click to enlarge
Considered also beefier components to zener regulator that seems to get really hot.
..but then thought that if it have worked that many years without any problems, it won't break anymore :) 

Before and after the mod:
Images before and after the calibration:
Click to enlarge
 Current reading seems to be OK.
Click to enlarge

Edit: One of the readers asked about PCB pictures. Download here

Jun 15, 2013

AVR I/O labels

Just a quick update - that's one hell of a handy "mod" to AVR micros! Not a new idea but makes your life easier.

Click to enlarge

Images can be found from http://www.blue17.elektroda.eu/mikrokontrolery-avr/1411 or by googling "ATmegaXX sticker".

Mar 28, 2013

Experimenting with AVR micros and VGA signal

Ever since I saw this (Craft by lft) MCU demo that won the Breakpoint 2008 Real Wild demo compo, I've been wanting to be able to do something similar. Well..it's still quite a long way to that kind of masterpiece but in this first part I'll clarify a little bit about the principles of generating the VGA-signal and also some "as simple as possible" code examples.

Basically the VGA signal consists of red, green and blue analog signals and H-sync & V-sync digital signals (5V). As you may guess, the voltage (0.0 - 0.7V) of each R/G/B wire tells the intensity of its colour. H-sync pulse is carried out after the end of each horizontal line and V-sync after each drawn screen.



























This is an illustrative view of one frame. Of course the real one would have 480 horizontal lines as this have only 11 for clarity. The easiest way to understand the picture is to think about old CRT (cathode ray tube) monitor. When the ray "hits" reactive material of display's inner surface, the area glows for a while. When this happens often enough (60Hz) we'll see steady image.

The beam draws the image quite much same way as you could write a letter (maybe slightly faster :) ). It starts the screen from upper left corner, writes the first line by going right, then H-sync signal tells that it's time to start the new line so the beam moves to the beginning of the next line and then start writing again. After reaching the end of the first frame, V-sync signal tells that it's time to start the new frame and all this starts again from the upper left corner of the screen. As the monitor draws 60 frames per second, there's 60 V-sync pulses and 31440 (60 frames * 524 lines) H-sync pulses per second. Because it takes some time to relocate the beam at the end of line or screen, there's "blanking areas" (bluish areas in the pic) where the beam is still going but it's actually outside of the visible area of the monitor. In these areas (front and back porch) R/G/B outputs have to be at 0 volts. It's common technique from old game consoles to use these blanking areas to generate audio and run other calculations when all the cpu time isn't going to generating of video signal.

After that you may realize that generating vga signal isn't so complicated as itself but the timing is everything! While the ray travels about 10 kilometers/second (6.2 miles/sec) there's no space for timing errors as we can see later.

The following figure shows all 5 signals relative to each other. Note that V-sync graph isn't in same scale as others.


24-bit image, 16.8M colours
6-bit image, 64 colours
Exact timing values can be found in here. The ideal clock speed for microcontroller would be 25.175MHz because with that clock speed every needed delay/timing would match exactly with N*clock cycle. But no worries. Monitors can stand fairly well small differences in timing values and frequencies so also other clock speeds can be used by calculating the closest possible delay times you can archieve with your particular clock frequency. The most important thing is that H-sync pulse and active video signals doesn't have any timing differences at all. Jitter in these causes wobbly and shaky image.
As you may deduce, the vertical resoluiton is always that same 480px in this display mode but the amount of horizontal pixels doesn't matter at all. For example if every R/G/B line is kept in same state whole active video sequence (25.4us) you'll get one pixel that is very wide. Or if rgb output values are changed every 0.254us, you'll get 100px wide image. Because of limitations of ATmegas processing speed we can't reach the full 640x480 resolution. The next reasonable step down is to draw every pixel twice as wide and every line also twice. Now we have 320x240 resolution. ATmegas should be fine with that.

These common ATmegas are 8-bit MCUs so it means that you are able to set only 8 output pins at once / simultaneously. This limits the max reasonable bit depth to 8-bit (256 colours). Because 3x 2-bit DACs would make only 64 colours and 3x 3-bit wouldn't fit in 8-bit limit, we could build 3x 2-bit DACs and then use the extra 2 pins to control the brightness of the colour so we get 256 colours. I used only 6-bits in my first experiment so there's 64 colours.


Click to enlarge

Assembly would be ideal language to write the vga code because you don't have to guess what C compiler is doing behind the scenes and you'd be able to optomize your code to run as fast as possible in every situation. I decided to save the ASM codes for a possible part 2 and made everything with C. I started by trying different techniques and ended up to use timer interrupt service that draws one line and H-sync every time when called. It also controls vertical amount of the lines and V-sync pulses.

My first working vga-code printed some "binary stripes" to screen. It simply counted from 0 (0b00000000) to 63 (0b00111111) and put the results in PORTC (3x 2-bit DACs connected to pins 0-5). Here it is presented as pseudocode (not any real programmin language or even fully working program, just easy to understand the idea):

// Timer interrupt service presented as pseudocode

ISR(timer1 interrupt routine){  // Runs every 31.8us
    line = line + 1;
    wait;  // Wait for 0.84us "front porch" after previous line
    turn HSYNC on; // 0 volts
    wait;  // Wait 3.8us (keeping the HSYNC active)
    turn HSYNC off; // 5 volts
    wait;  // Wait for 1.9us "back porch" before starting active video sequence

    if (run if line is 480 or less){  // If line is in visible area, run the code that produces the image.
        for(run 64 times by counting from 0 to 63){  // Counts from 0 to 63 in PORTC
            PORTC = value of for-loop variable;  // Set output
        }
        PORTC = 0; // Print black screen after the stripes (right side of screen)
    }
    else if (run if line is 492){
        turn VSYNC on; // 0 volts
    }
    else if (run if line is 494){
        turn VSYNC off; // 5 volts
    }
    else if(run if line is 524){ // One frame is complete, start another in next round.
        line = 0;
    }
}

Source files for ATMega32 @ 16MHz:

binary_stripes.c
vga_moving_palette.c

Fuse bits for ATMega 32:
-> High: 0xD9
-> Low: 0xFF

Fuse bit calculator: http://www.engbedded.com/fusecalc/


The code above should print stripes like that (slightly different colours but same principle). I had only 16MHz crystal so the horizontal resolution was quite poor. That was maybe the simplest vga program you can make. The next step could be adding some objects and specific colours. Simple square-shaped colour pattern might be quite easy to implement after understanding inner working of that first program.

In the second code example (colour pattern table) I used 8x8 array where all the colour values are stored (0bxxRRGGBB). For example:
0b00110000 = pure red 
0b00110011 = violet 
0b00000001 = dark blue
0b00111100 = yellow
And so on..

The square is made just by limiting upper and lower borders by testing that "if line is less or more than..." and same thing for left and right borders but at this time we'll modify the same for loop that made "binary stripes" in the first example to get the values from the array instead of just counting from 0 to 63.

At this point we got the first timing issue. When we are testing during active video sequence if it's time to change the row of the array, every last line of the specific pattern keeps going longer than others because processing takes some clock cycles more than normally (click the image to enlarge -> ). Of course it's possible to balance the delays with different tricks but it will be endless amount of work with C if the program grows bigger.

Since the whole 320x240 sized "display memory" won't fit in ATmegas RAM, we should manage to get the algorithm that uses blanking areas to prepare the incoming line beforehand and store only that to RAM at once. 




 
Ok. That was it for now. Let's see if I'll find some time to make part 2 with real-time calculated graphics, better optimized ASM-code and audio.

Feb 3, 2013

Sauna simulator

I've been asked to upload the video about that device so here it is now :)




















As the video tells, it have ATMega 1284p SMD 44-pin microcontroller, 35 SMD leds for the flames and embers, SD card and speaker for sound effects and NTC thermistor that detects the heat from lighter.

All the leds are controlled by PWM signal. Because the MCU have only couple of PWM lines, I used one 10-bit hardware PWM line for red leds (embers) and any of the yellow leds are driven by 3-bit software generated PWM. Unfortunately I'm not able to publish the source code or schematics about that because it was one of my school projects (so the next year students won't copy it). 



Got the replacement for my old and energy-hungry home server (Apple Power Mac G4). Raspberry Pi consumes only ~5 watts while my current server draws something like 60-80 watts. Both of them runs Debian linux well enough and the performance levels are about equal. 
At least it isn't too big if compared to 30 years old processor DIP package.

Raspberry Pi  vs  TS68000