Monday, September 6, 2021

LTC2645--PWM to Voltage--Embedded C--PWM DAC for Waveform Generation

Note: if you want to download the gerber for this post's MSOP .5mm to PDIP adapter board, you can get it from PCBWay's Project Page, here

OK on to the post:

Hmm...again: 10K audio from an Atmel 328.  Possible?

It can be done using a lookup table and GPIO with parallel resistor ladder DACs, or via its on board PWM

This post covers a variation of the PWM idea but it sounds kinda crappy.

The idea: for the last few weeks I have been working on an audio waveform generator based on an Atmel 328P  and Embedded C.

That's an 8 bit microcontroller with no DMA or I2S, and so far I've found it too slow to produce high fidelity audio--low frequencies can be produced easily, but anything above about 300hz exhibits varying degrees of distortion. 

But I read (here for instance) that you can use an 8 bit Atmel Microcontroller's PWM to get up to about 8K at output by varying a PWM signal's duty cycle then turning the PWM signal back into an acceptable analog voltage using a  low pass filter.

Fine, but let's have additional fun--let's see if we can use a PWM DAC, such as an LTC2645, instead of the filter. 

What is a PWM DAC?  To understand that, you need to have a basic idea how PWM works--a good description is here.

For the PWM to DAC IC, pulse width modulated signal(s) go in, and based on the signal's duty cycle, the chip produces one or more analog voltages at its output(s). 

PWM ICs have many applications in electronics, you see them frequently in power supplies for instance.  I am not sure how often PWM to voltage is used in DiWhy audio, but what the heck, I can't see why this wouldn't work, let's try it!

Sample and Hold: I got a few LTC2645's; its datasheet looks straightforward, and the IC replaces the various filter RC components, potentially making the entire audio generation circuit's footprint small and simple. 

But one problem for a DIY maker is that the LTC2645 is tiny--MSOP, 16 pins, 5mm between pins: 

The LTC2645 compared to a U.S. Nickel. For our friends abroad, a nickel is 21mm across.   

That's really, really small.

What to do? I reached out to my sponsor, PCBWAY, for help, and I designed a simple 16 pin 5mm MSOP to PDIP breakout board. Then, I uploaded the gerber. Happily I got 5x PCBs from PCBWAY within a few days (!!) along with a stencil they created for the project and got to work.  

Overall fab for 5mm MSOP's wasn't easy due to its extremely small size, but with some patience I got it working using the same hot air/SMD stencil process you can read about in the post here.  

If you want to play along at home, please download the files and gerbers for this adapter board from PCBWAY's Project pages, the gerber is here.

Next, on to some almost useless but slightly entertaining bench photos:

Not looking too bad....each board can accommodate two MSOP chips, but for sanity I just populated one half. That gives me a bit more room to tape down the PCB for fabrication.

Oops, this chip got installed upside down, oh well!

Pin time....

No photo but: After soldering the pins, I used a dremel tool to saw each board in half, and was left with 2 dusty BoB's. 


In need of some tidying up, but ready to go....


After a quick clean with flux remover, I was ready to test....




....with things not looking too bad under the microscope.


Wiring up the LTC2645 (datasheet is here) was easy; there is no programming needed, just hook up your PWM source one or more inputs, apply logic, power and ground, and use its output(s) to get a smooth uinpolar analog signal.

The LTC2645 accommodates four PWM inputs to four analog outputs. Make sure your incoming square wave is about 1Khz-5khz for the 12 bit chip; I used 3V P/P with a 1.5V offset.  Decoupling Cap for me was .2uF, but .1uF should work.

VDD for the LTC2645 is 5V; filter cap is .1uF


I wired it up using my trusty Radioshack development widget and an UNO R3:


OK, for test code here are some examples for waveform creation using PWM. These were all taken off the Internet; I modified each file slightly, but not much.  

The programs below were compiled and uploaded to the processor using my usual Atmel Studio 7/Atmel Ice combination. I used an Uno R3 development board.  Pin PB1 (For Arduino-ites: that's Arduino pin 9) was used as the PWM output for the top code example, while pin PD3 (which translates to Ardunio Pin 3) was used in the 10K example at the bottom of the post.

When compiled and the PWM was connected to the 2645, it produced a decent if gritty 3K triangle wave:

/*
 * LTC2645-func-gen  main.c
 * adapted code for 328P and LTC2645 from      *https://gist.github.com/Wollw/2425784
 * Created: 9/6/2021 9:46:56 AM
 * Author : audioDIWHY
 */ 

#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdbool.h>
#include <util/delay.h>
 

int main (void) {

/*set outputs */

 
DDRB |= _BV(PB1); 
        /*arduino PIN9--timer 1 PWM on 9,10 (PB1,2) */
DDRB |= _BV(PB2);  

    /*3.4K pwm using timer 1 */
    TCCR1A |= _BV(COM1A1) | _BV(WGM10);
    TCCR1B |= _BV(CS10) | _BV(WGM12);

 
  

  uint8_t pwm = 0x00;
  bool up = true;
  for(;;) 
        {
        /*3.4K tri */

OCR1A = pwm; 
pwm += up ? 1 : -1;
if (pwm == 0x84)up = false;
else if (pwm == 0x00)up = true;
   
}

}





And this short main.c file produced a 5K or 12K ramp (which looked and sounded pretty ratty).

/*adapted from webpage:
https://withinspecifications.30ohm.com/2014/02/20/Fast-PWM-on-    AtMega328 */

#include <avr/io.h>
#include <util/delay.h>

int main(void)
{

  

    DDRD |= _BV(PD3); 

/*arduino Pin 3 timer 2 PWM AVR PIN PD3*/
    

/* Set up the 250KHz output */
TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
TCCR2B = _BV(WGM22) | _BV(CS20);
OCR2A = 63;
OCR2B = 0;
 

/* Make the 250KHz rolling */
while (1) {
_delay_us(5);
if ( OCR2B < 63 )
OCR2B += 5; 

/* OCR2B += 2 is about 5K ramp.  5 is                                about 12K ramp. higher is more speed but crappier looking                                    waveform. */
else
OCR2B = 0;
}
}




 
Hey--it works....

So what's the verdict? After a morning or so working on this, sadly, this still isn't the audio frequency solution I needed.  

The LTC2645 is an interesting chip, but it's expensive (about $10USD for one 12 bit chip) and I am not sure you gain that much using it and not an RC filter.  

Maybe for certain applications where you want to turn four different PWM signals to voltages with output speeds up to 5K this chip would help. But that's an unusual requirement. 

Overall I guess we will see; the jury's still out.....

OK, enough PWM for now. Time to stop working, it's a 3 day weekend.

See ya' around....hoping your duty cycle is not too long....

No comments:

Post a Comment

Building a Moog T904B Inspired High Pass Filter--Using an SMD hotplate--Works!

Readers: If you'd like to build the project featured in today's post, please go to PCBWAY's Community pages--gerber file (main b...