Aug 18, 2016

30 MHz DIY Signal Generator (part 1)

A year ago I started this simple, microcontroller based DIY signal generator project which was capable for approximately 60_kHz sampling rate. However, that ended up to be quite boring becase I need test signals with higher bandwidth in my projects and there's already couple of similar MCU based signal generator projects on the internet. One idea leaded to another, and now I have dual channel, 90_MS/s, 30_MHz, 16-bit self-made arbitrary waveform generator (AWG). This won't be a complete step-by-step tutorial to build a similar one, but I'll try to explain enough details to give a good overview about the system. Also, the HW design and source code will be released, if someone wants to build one or even develop it further!

Click to enlarge
The user interface (UI) is managed mostly by the Atmel ATmega microcontroller. The signal generation itself is done in FPGA, which controls also the LCD screen, and couple of other miscellaneous tasks. The digital signal goes from the FPGA to the high-performance DAC through the 2x 16-bit parallel bus, and the analog signal passes through the low-pass filter, to the high speed op-amp and output BNC connectors. The low-pass filter is needed to remove the unwanted alias frequencies.

Analog bandwidth__30 MHz
Sample rate90 MS/s
Channels2 (+one internal modulation gen. / ch.)
Voltage swing±8 V (±4 V to 50 Ω load)
WaveformsSine, Square, Triangle, Saw, Noise, Arbitrary__
ModulationFM, AM, PM, Frequency sweep
Others2.8" TFT touch screen,
3 rotary encoders,
10 MHz clock reference input (BNC),
2.5 PPM internal clock reference,
USB remote control & SW update

Click to enlarge
The first prototype was built by using a Lattice XO2 breakout board (~$25) and self-made ATmega328P development board. The DA converter was implemented with two 8-bit R2R ladder DACs. There was no LCD or control knobs attached yet, but all the commands was given via virtual COM port (FTDI FT232RL) to the MCU, which controls the FPGA via SPI bus.

Click to enlarge
The next step added the LCD screen, control knobs and a frontend low-pass filter & amplifier (TI_THS3001) testing board to the prototype. The DAC component (AD9747) was not tested in this prototype, because the breakout board just for that would have been quite expensive due to the price of the DAC IC (~$30). Instead of physical breakout board, the DAC and the analog front-end was simulated by using Agilent Advanced Design System, and the simulations ended up to match pretty well to real-world performance tests.

Click to enlarge

Download schematic:
PDF File (rev 1.0)
Proteus 7.7 Schematic file (rev 1.0)

As you may notice, there is no separate JTAG header for the FPGA, but there's a ISP header for flashing the ATmega MCU. After flashing the Chip45boot2 bootloader to the MCU, the ISP header isn't needed anymore. The Lattice XO2 breakout board has a FTDI FT2232H USB interface IC which is programmed to USB-JTAG bridge configuration. The same IC is utilized also in this design, but more of that, it has also a USB-UART bridge functionality, so both, the MCU and the FPGA can be programmed via the single USB connector. The USB-UART bridge also allows the debugging and remote control features for the MCU.

The schematic design of the front panel leds & knobs may look a bit strange at the beginning, but the idea was to use as few MCU pins as possible for controls. All of the signal wires are connected to ADC pins of the MCU, which switches these pins very rapidly between the input mode (reading the values of knobs) or the output mode (feeding current to the leds). Depending on the voltage value, the MCU deduces the position of the switches. More common way would have been to place an extra MCU to front panel PCB for knobs & leds and the communication would pass through I2C bus, but again, this solution was chosen to keep the design as simple as possible (and to try something new). As an after thought, it works quite ok after tuning the ADC treshold values, but in my next AWG project I'd use a separate MCU for controls.

As the XO2 FPGA has a quite nice clock manipulation features built-in, I used a temperature compensated crystal to provide an accurate clock reference for the signal generator core. However, if even that isn't accurate enough or the clock of the different devices needs to be synchronized, there's also a input BNC connector for the external 10 MHz clock reference, and the internal clock MUX of the FPGA selects the clock, that is selected from the UI menu.

To keep the design as simple as possible, there is no variable gain amplifier or even separate DAC for offset leveling. This compromises in the resolution of the AWG, since the smallest possible voltage step is 16_V_/_2^16_=_0.24_mV in any voltage or offset scale.

Click to enlarge

The design was fitted into 50 x 100 mm 2-layer PCB, which was ordered from ITead Studio. There was only one bug, which was easily corrected with a piece of copper wire, so I decided not to order a new revision. Also the 5 V linear regulator, next to the power connector was replaced with SMPS module, which gives a lot better efficiency. The front-end op-amps still have linear regulator for the best possible noise performance. Power rails of the DAC are well filtered and regulated with LDO regulators, so the switching noise wouldn't pass to the signal outputs.

Click to enlarge

The project box (Bahar BDA-40004-W200) was ordered from AliExpress, and modified for all the knobs, connectors, leds and the display. The layout was designed in 3D modelling software to make sure that everything fits nicely and the placement looks logical. Someone may like separate buttons, but I'm a fanboy of rotary encoders, so there's three of them! One controls the selected menu item, another the digit of the selected value and third knob controls the value of the selected menu item/digit.

Click to enlarge

All_the necessary pieces fitted into that project box. The main power supply is implemented by using IEC power connector with fuse holder & switch and 230 V to 2x15 V toroidal transformer. AC voltage goes to the PCB with fuses, MOVs (over-voltage protection), rectifier and bypass capacitors. +-21 VDC voltage passes to main PCB. The transformer with 2x 10-12 VAC outputs would be ideal, but I happened to have this 15 VAC model already, so it shall be good enough, althoug the output voltage is a bit high.

WARNING - Do not attempt construction of the power supply if you do not know how to wire mains equipment.

Well, that was quite broad description about the project. The Part 2 will include the PCB design files, source code, description about the program and performance measurements. Please, Tell me in the comments, what else you want to be included into Part 2!

Jun 20, 2016

Case mod: Fractal Design Define Nano S

Maybe not that much electronics related, but lately I've been doing this computer case mod project. Last years my computers have been in a ~105x40x25 cm closet with three Mobo & PSU mounts and four 120mm Noctua fans. Since my main computer is on 24/7 and I'm sleeping in the same room, the box is covered with sound absorbing material.

Click to enlarge

That's a good solution as long as I don't have to move the computer. But having a LAN Parties twice a year have been a bit problematic, since I have to disassemble the computer to the cardboard boxes and assemble it again at the party place. Also, the TV stand / Computer closet may not come along to my new apartment in the future, so its a good time to invest into a proper computer case. I already have some mATX cases and a huge full tower, but neither of them wouldn't fit into my needs. I've always liked the look of Fractal Design Define series cases, but they are just too big to fit nicely in my apartment, or to be carried around even twice a year. Lately Fractal Design released this very good looking Define Nano S case, which would be perfect unless it wouldn't support ITX motherboards (170x170 mm) only.

Click to enlarge

But wait, the Nano S case measures 203x330x400 mm so the ATX motherboard (305x244 mm) would fit into it after a bit of dremeling. Because the placement of the power supply was changed and the hole for motherboard's I/O connector had to be moved upwards a bit, the easiest way was to buy a 1.5 mm thick aluminium sheet and re-make whole back side of the case. The motherboard tray was taken off from a full ATX tower and cut down to fit into this chassis.

Click to enlarge
Maybe the worst thing in Fractal Design's Define cases are the overly bright blue PWR & HDD leds, which were replaced with dimmer green & orange leds. These won't illuminate the entire room at night. I have a 250 GB SSD for the operating system and 3 TB HDD for everything else. There's also a custom made HDD mount, which have a ~3 mm thick sheet of rubber between the HDD mount and the case. This absorbs very efficiently the constant humming noise of the 7200 RPM HDD. The plate on top of is sized so that the whole thing can be mounted easily to the 120 mm fan slot.

Click to enlarge
Although the new placement of the PSU won't allow big CPU coolers to be used, my Prolimatech Samuel 17 seems to manage with the Xeon E3-1230v3 CPU just fine (idle: 38°C, load: 65°C). There's a 120 mm CPU fan blowing towards the PSU, so the hot air goes out directly, through the PSU.

Until now, my backing up solution has been a bit fiddly, but now I decided to include a 3.5" hot-swap HDD mount in the back side of the case, so I can easily insert a HDD maybe twice a month, and put it somewhere else, so it's completely offline when not used.

There's also four timelapse videos about the modding process and the end result (end of the part 4):

Dec 13, 2015

Merry Christmas & Happy New Year 2016!

Click to enlarge

Year 2015 was quite busy so not many blog posts lately. However, I've been doing ATmega324P & Lattice XO2 FPGA based dual channel arbitrary function generator project with 90 MS/s sample rate and 30 MHz analog bandwidth. That should be out during 2016!  #NewYearsResolution
Click to enlarge

May 29, 2014

DIY USB soldering microscope

I've been looking for a decent and cheap USB microscope for SMT soldering. Many of these 50-100$ Chinese microscopes have quite poor working distance, resolution and image quality so I thought to try make one by myself.

A webcam should work quite nicely as a camera sensor because they should work almost everywhere without fiddling with drivers or viewing programs. Logitech C270 is quite inexpensive and it have 1280x920 resolution. A bit of googling also revealed that it doesn't have any too fancy autofocus features that could cause problems later. Estimating the delay between camera and monitor from internet reviews was quite hard but it seems to be in tolerable level.

The lens is maybe the most critical part of the system because it defines the working distance and the amount of light that gets to image sensor. I came across the 50mm F1.4 CCTV lens from which seemed to be quite good for this project. 50mm may not sound like much enough for proper zoom level but this 50mm is with 2/3" image sensor. If the sensor is smaller, also the effective focal length gets greater because of cropping factor. I estimated that it should correspond something like couple of hundreds millimeters focal length with C270's image sensor. Minimum focus distance of this lens is ~30cm. It's a bit too long but focusing range can be modified by moving the sensor closer or further away from lens. The lens have adjustment rings for aperture and focus so finding the best configuration shouldn't be too hard. The lens package contained a threaded macro adapter so now theres also complete lens mount for my camera casing.

Click to enlarge

After taking apart the webcam and checking that everything works as planned, I got small black plastic case from local electronics store, drilled coule of holes, glued macro adapter to it's place and installed 1/4" tripod threads to case.

3. 85x55x30mm WCAH2855 plastic case

Total: ~ 63€ / 86$

Image quality, depth of field and delay is certainly good enough for typical hobbyist-level SMT soldering but I found that I'm still using bare eye for soldering because it's just more handy unless parts are 0402's or smaller. For after inspection and troubleshooting this is very useful. And if not else, it's still quite nice toy!

Click to enlarge

I've_tried couple of softwares that are capable of showing webcam view. VLC had horrible delay, VirtualDub works fine but it doesn't allow real time effects like flipping the image horizontally and vertically (handy if the object is between you and camera as in the picure above). Open Broadcaster Software have also webcam input and it allows real time image flipping so I ended up using it in preview mode. Edit: VirtualDub manages also real time effects! See instructions in comments below.

*A few glitches in video are caused by recording software, not the camera itself.

Sep 7, 2013

Mascot 719

Got a "new" Mascot power supply to my workbench

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!

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

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.

Images can be found from 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.'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:


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

Fuse bit calculator:

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