Sunday, October 31, 2021

Dirty Digital LFO--DONE!

Holy smokes (not literally--no smoke yet) this one was a lot of work.  




But it's finished; much improved from its thru hole build predecessor, and I am extremely happy with the results.

Left: Earlier Prototype of the Current Prototype....

Update 12-17-21: I created then posted a quick audio clip of the DDLFO. Go here.  About the demo: You can  use LFOs for most anything that needs modulation...but I wanted to show some of the odd  LF waveforms you can get from this strange device without a lot of  obfuscatory fanciness. So--The demo uses 2 Dirty DLFO's modulating each other with the lube out of one of the LFO's feeding a single VCO. That's it. I used a bit of multitracking and added reverb as as to not completely destroy your speakers, but this was the  simplest way I could think of to show you how a DDLFO module "sounds". 

There have been many previous posts about the D-DLFO up until now:

  • Leaving Arduino Sketch for Pure C: here (it was arguably easier to build a module of this complexity using embedded C vs. Arduino Sketch).
  • Minimal AVR board: here
  • Earlier DLFO prototype with simpler buffering (and less features): here and here.
  • Adding waveform reset via external interrupt: here.
  • Fabricating and troubleshooting the SMD "pots board" for the build: here.

Also I want to thank my faithful sponsor PCBWAY for helping me realize the Dirty Digital LFO in its various incarnations. 

This was a tough fab, using 0804 SMD parts and intricate stencils. It's an advanced project. Their support and quick turnaround for the prototype boards was extremely helpful, so please help me continue to improve this blog and check them out.

Getting Dirty: Overall I am really happy I hung in there and rebuilt the original Dirty DLFO module to do more. 

The waveforms you can create with it go from normal tri/sine/ramp/saw to bizarre. Check out a few scope shots. That's the wonder of DIWHY I guess, you end up with things that can be--different?



Generous lube makes the signal analog like....

Portamento turns tri into a sloppy sine. Good enough.

My stock portfolio?

Hebrew from an LFO? Oy!!

Swan Lake?

More Cowbell!

the path not taken?

Using the Dirty Digital LFO: The module has two outputs: "Lube" and "Out", the former is the output  through a portamento subcircuit.  

The lube gets rid of the some of the digital grit which may or may not be what you want. 

There are 3 ways to change the frequency: the frequency pot at the top right, a slow/fast switch, and a 0-5V CV in. This is standard LFO stuff. You can set the output bias offset with the OFFSET pot (if I had more room I would have made the outoput voltage controlled, but enough features already right?) the WOMBO input mixes CV to the DAC out (see below); finally the CV bias in adds DC offset to the incoming CV in case a boost is needed.

What is a "WOMBO"?  I had to call it something....some of the strangeness you see in the scope shots is due to blasting CV in parallel into the DAC buffer output. We are not mixing the additional signal into the negative feedback side of the output op amp buffer, we are mixing it into what is normally used to set the bias offset (often tied to ground), here, treated as a mixer.  

I got this idea working on a friends' Ken Stone Dual Wasp Mixer, and thought it would be interesting feature to add to an LFO....it turned out to be the case. 

I had no idea what to call this input, so I chose 5 letters at random: "WOMBO".  There you go!

The PCB is wired for +/- 15V but should work on  +/-12V no problem; the PCB board I laid out accommodates a Euro power connector. 

As it's coded, the board supports 6 waveforms plus Sample and Hold:

  • Tri
  • Ramp
  • Square
  • Saw
  • Random 1 and 2 (CV controls frequency, or, CV controls frequency and randomness)
  • S/H (reset input, when it goes positive creates a sample of whatever is at the CV in and puts it at the output jack).

There is also a "Riley reset".  Hello? See previous posts here and here. This didn't work at first, after about 3 hours at the bench I realized that I had wired the interrupt to D1, but coded it for D0. Gotta love dumb mistakes. 

Since this interrupt starts the waveform over, you can get further complexity, such as turning a triangle into a saw, doing psuedo duty cycling of the square wave, and so on. Thanks to Max, Dave and the guys at BAM for insisting that I put this in.  It was a really good suggestion.

On to this post's useless bench build photos:






   

Showering off: Overall, this experience was AudioDIwhy at its best (for me anyway...)  

After hours of enjoyable and peaceful C coding, fantastically frustrating hours fixing and debugging the circuit, and much time spent swearing, soldering, wiring and having dumb bench fun, I ended up with a voltage controlled LFO that may be like nothing else out there--perhaps anywhere--if you have an LFO that can display psuedo hebrew-like characters on your scope, lmk--I didn't have one; now I do.

I feel I've come a long way since I was perf boarding dumb little op amp circuits and seeing if they smoked. So in spite of my psychiatrist girlfriend wondering about me and if everything is OK upstairs, I carry on--and perhaps this is a good thing. 

This was a pretty tough build, but if you are up for a challenge, you can get all the schems, files, gerbers, PDFs etc., from my github (here) as well as my sponsor PCBway's project page, here. Let me know if you come up with anything fun.

Here, now, I am happy.  Rock on!!!


Saturday, October 16, 2021

Dirty Digital LFO Rebuild: SMD Analog Board--Troubleshooting Audio Op Amps

 Hello Again! 

A few posts ago I got an LFO working based on Atmel 328P and some Embedded C Code. The module (post here) works, but uses four--count 'em four--thru hole PCBs, electrical tape, plenty of "temporary" fixes, and a heapin' helpin' of elbow grease.  

I know from previous experience that these butt sloppy modules stop working, or worse.  

I can do better!

OK, let's build this module again but this time with higher quality.  

I will also add "BOWAL" features (creating bias offsets at the inverting op amp inputs) adding much needed craziness to the module's incoming and outgoing signals--for more BOWAL see the previous post here.

The SMD board and solder mask for today's build is courtesy this blog's sponsor PCBWAY.  Please check them out and help support future geeky posts....

Wham BAM! The new design is already back from PCBWAY. that was fast!!!!

I mostly chose 0804 SMD parts for this build, smaller than I've used before. Then I built the "analog" board using the same stencil and hot air process you can read about here.

I make front panels from PCB blanks, even before a newdesign tests working, to make troubleshooting somewhat easier. 





OK with all the components soldered in it was time to test.  

Did the analog board work first time? Nope. The input and output buffers passed nothing through to the PCB mounted jacks. However the portamento sub-circuit worked the first time....it was time to troubleshoot!  

I'll post the schematic once the build is finished......


Make sure you have a steady platform from which to probe, solder and fix.

This design  used six op amps stages for signal conditioning. Analog signals can swing rail to rail, but our 328P microcontroller only likes to see 0 to 5V.  

How do we make sure nothing blows up? 

Op amps! 

I'd be surprised if anyone following this blog doesn't already know a lot about this component, but just in case, a series of posts about how op amps work and their primary applications begins here.

These fundamental ICs are a miracle when they work, but can drive you crazy when they don't; for a beginner they can be difficult to troubleshoot. 

So.....Here are some tips I've picked up from other techs that I used to get the analog board's op amp stages fully functional:

  • First--As always, don't guess! Don't shotgun! Don't brute force. Instead follow the wisdom of El Shango: follow your schematic and isolate the problem logically.  
  • BTW I get my kicks on Shango066. please fix things the way he does--divide and conquer.  
OK back to troubleshooting:
  • Using a scope or DVM, check that the op amp has the correct voltages at its VCC and VSS pins. If it doesn't, it won't work. Doh.
  • Check that the op amp isn't wired up backwards (so, V- rail goes to V+ etc., chip was installed upside down, etc.). That can fry your op amp in a heartbeat.  
  • If you wire up op amp power pins wrong, even if the op amp doesn't smoke, you may want to replace the op amp...I know one tech who says you should do that every time you reverse power any linear IC, including an op amp.
  • Draw a simplified mini-layout of the signal flow in and out of the stage under test, then check the signal flow carefully with a continuity tester.  
  • Check for continuity to the actual pins of the IC, not just its pad.
  • For audio troubleshooting, consider using a ProbeMeUpScotty to follow your signal path to where audio stops--where the audio quits may be where your problem begins. 
  • If you are sending the op amp DC, use a scope or DVM to see where the problem starts in the same manner.
  • Isolate each op amp stage from the rest of your circuit. I usually remove a resistor or cap between op amp stages or between an op amp stage's I/O and the rest of the circuit to do this. 
  • SMD tip: removing and reattaching small SMD resistors and capacitors has turned out (for me anyway) to be easier than dealing with thru hole removal/replacement. You need a steady hand, fine gauge solder, a magnifying glass, a fine tipped soldering iron, and of course a pair of zircon encrusted tweezers, but with the right tools it's easy and forgiving, even with really small parts.
  • Once you're sure you've electrically isolated the op amp stage under test, apply a known good test signal at the op amp stage's input (inverting or non inverting, depending on your basic design). 
  • You should see your buffered output at the op amps output pin pad--use a scope.  
  • If you don't see a decent output (0V at output, output is slammed against V+ or V- rail, output has severe oscillations, horrible distortion etc.) then you know the op amp stage under test has a problem and needs more attention. 
  • Check and double check the parts in the stage's feedback loop and surrounding I/O for issues. Wrong value? Short? Open? Design mistake?
  • You often can't scope the inputs of an op amp because they are virtual grounds. Damn! But you can sometimes use a neat trick to see what works and what doesn't.
  • Here is an example of this--in this case, used to troubleshoot an inverting op amp stage:
Wire up a clip lead to a resistor blow a test signal through it.  Now, touch the other end of the resistor to the inverting input of the op amp stage under test. If you now see your expected output (inverted of course) on your scope, you know the op amp chip itself is OK and its inverting feedback loop is OK too. You have further isolated the issue to the signal feeding the op amp stage under test.
  • Once you've fully isolated the issue look carefully for cold or bad solder joints, shorts, opens, a wildly incorrect part value, a stupid mistake in your design, and so on. It's almost always an easy fix but only once the problem is isolated.  

In my case, I found 2 problems: a resistor that was shorted (I flowed too much solder below it) and an inverting op amp input that wasn't fully soldered down (probably too little solder paste). 

At the end of it, I had a working analog board.  The "minimalist" Atmel board design for this module is almost unchanged, so hopefully the rest of this build will go smoothly....and its code is already written and works. Yeh!

BTW, I may have hit upon the analog input buffer circuit fragment that I'll use in many future designs. I use this fragment to feed analog signals to analog to digital converters (ADC's); it's simple, has a reasonably low parts count, and gives me good control over many parameters that need to be adjusted before the signal is fed into our MPU's ADC.

Here it is:

Oops should read "limits overall voltage to ADC".  

This sub-circuit has the ability to limit the overall buffer voltage output (Zener), each gain stage (R1-R4), the output impedance (R5, R6 plus next stage's load characteristics), the bias offset (R7, pot), as well as attenuate the incoming signal's overall amplitude ("Level").  

This is the fragment I am using for the post's analog board ADC input conditioning. How will it perform? Next post I will marry this analog "Pots" board to the MCU. Update--done! Works!! go here. See you then I hope! Stay safe, tune in and turn on. 

Saturday, October 2, 2021

Embedded C--Riley Reset Revisited--Interrupt Your DIY Digital Synth Module's Logic with Almost Any Signal!

We continue on our Embedded C Atmel MCU adventure.....

Quick one this time as I build my way to an improved Dirty Digital LFO. I don't want to forget what I've done so far so perhaps this post is mostly for me?


One of my favorite dev boards for Atmel Embedded C programming is the Arduino Uno R3. To get the background on Interrupts for this board, using Embedded C, you may want to read the previous post here.  

Interrupts are key in many digital audio projects, in the case of the "dirty digital LFO" I created a waveform reset to zero buffer PCB using a 3904 transistor and a few resistors--post for that is here.  

I am now rebuilding the ddlfo using a lookup table, and I also want to make it so an incoming square wave or pulse signal resets the LFO's output frequency to zero, and finally have that work in parallel with a frequency counter (post here).

But--can we get the existing DDFO reset circuit to work with what is essentially very different code?  Yes. That's one of the major advantages of embedded C; you get something to work, then drop code and hardware fragments from old projects into new ones. Modularity is a primary reason I made the switch from a highly abstracted programming language to Embedded C for my AudioDiWHY projects.


Get down to it: The inverter/buffer circuit and PCB shown above is covered in the post here. Lots of ways to do this, but since my sponsor, PCBWAY, sent me a few 3904 buffer PCBs and I've only used one to date, I might as well use what I already have on hand.  

To make this work I created a very simple gate to trigger on a breadboard using a single .001 cap and a 47K resistor; trial and error indicated that this worked best for my modular rig. The output resistor R5 for the buffer is set at 1K, not 22K as in the original DDLFO design. For proof of concept I am using an MCP4911 DAC, which I like due to its simplicity.  

To make the 4911 DAC go, I used existing MCP4921.c and .h code from my github page, here, and modified it slightly to accommodate 10 bits at output vs. the 4921's 12 bit output. the core "wave reader" code was written from scratch.

I will post this code including the 4911 driver file when I have this "wavewalker" LFO working--should be pretty soon?

The last thing to do was put it on the bench to test:

....using this code fragment before the "main loop":

/**********INTERRUPT ********/


ISR (INT1_vect)

{

       

x = 0;

_delay_ms(5);// "Riley Reset", incoming interrupt resets LFO wavefrm to zero


}

    

/**************************/


/**********Set up Riley reset timer************/

EIMSK |= 1<<INT1;  /* enable external interrupt 1 (D2 pin on Uno R3) */

EICRA |= 1<<ISC11; /* interrupt on edge (trig)  */

//EICRA |= ~(1 << ISC10); /* interrupt on low (trig) */

EICRA |= 1 << ISC10; /* interrupt on high (trig) */

sei(); /* enable interrupts */


This worked. The wavewalker design, so far, starts at cell 0 of a 200 cell uint_16 array and steps through the array sequentially; there is a pause between each read. This delay() sets the overall frequency--longer pauses mean a slower frequency at output.  

So--to perform a waveform reset is pretty simple, you tell the system to start reading at cell [0] each time an interrupt is seen.  

On the bench it works, but I see an occasional need to better debounce the interrupt signal. For the LFO "wavewalker" design to date: what you see above seems good enough. 

I need to next tweak the frequency counter (post here) to multiply it by 15 or 30 (how I arrived at these  constants will be covered in a future post), then create another lookup table match the observed incoming frequency to the delay between array reads. That should allow BPM to frequency conversion for the LFO.  

This will hopefully make more sense when I post the wavewalker design, which I hope to have working sometime this month. I am now going to pull apart the breadboard dookie you see above to further tweak the frequency counter subcircuit, so what you see blogged today is all I have for the interrupt portion of the design, at least for now. 

Stay tuned.

JTAG to SWD Converter

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