4040B 12-stage binary ripple counter and R-2R resistor network - Page 1
Forum section: electronics / beginners

author: dentaku
author_rank: Frequent Contributor
timestamp: November 29, 2014, 12:39:24 am
content: I was watching Allan W2AEW's video on R-2R resister networks and saw he was getting a ramp wave out of it using an up counter and an MCU.https://www.youtube.com/watch?feature=player_detailpage&v=AulX1OM7RwEI realized that the old 4040B 12-Stage Binary Ripple Counter outputs what looks like exactly the same thing so I simulated it to check this out.Using the simulated Word Generator I can reproduce exactly the same thing as the video but with a 4040B it's kinda jagged in places.Question?Is this because the 4040B ripple counter is slow and the bits don't flip exactly at the same time (propagation delay) while the word generator is almost perfect?

author: Circlotron
author_rank: Super Contributor
timestamp: November 29, 2014, 12:47:46 am
content: Probably 1K and 2K are a bit too low resistance and not allowing the 4040 outputs to swing fully rail to rail. I have used 100K and 200K with good results you will probably find though that there will still be a glitch halfway up the ramp because of propagation delay.If you put 12 bits wide of D flip-flop on the output of the 4040 and have it trigger on the rising edge but the 4040 on the falling edge you will probably get perfect results, only limited by how accurate the resistors are.

author: Andy Watson
author_rank: Super Contributor
timestamp: November 29, 2014, 12:51:15 am
content: The outputs of the 4040 are not perfect highs or lows. As the output voltage nears the supply rail, or ground, the output behaves more like a resistor of something like 500 ohms - depending on supply voltage.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: November 29, 2014, 01:17:28 am
content: The clue is in the name - Ripple counter. You really want a synchronous counter.But more than 8 bits with a resistor DAC is futile as there are too many error sources.12 bits is a total non-starter - even if you got that accuracy from the outputs, 0.01% resistors are expensive.

author: dentaku
author_rank: Frequent Contributor
timestamp: November 29, 2014, 01:19:35 am
content: Quote from: Circlotron on November 29, 2014, 12:47:46 amNice. I multiplied all the resistors by 100 and it's great now

author: dentaku
author_rank: Frequent Contributor
timestamp: November 29, 2014, 01:25:25 am
content: Quote from: mikeselectricstuff on November 29, 2014, 01:17:28 amIt's easy in a simulation but I was going to test it in real life with only 4 bits to start because I don't own that many good resistors.In fact I wanted to do this to get bleepy low bit sounds anyway

author: IconicPCB
author_rank: Super Contributor
timestamp: November 29, 2014, 06:42:11 am
content: Absolute resistor accuracy is not important so long as the mismatch is very low.A bunch of Rs matched to a value will do the job nicely.

author: f5r5e5d
author_rank: Frequent Contributor
timestamp: November 29, 2014, 06:51:07 am
content: if its the waveform you want then just make a .wav and play it out of a audio DAC from soundcard, DAP or burn a discwon't do DC, audio outs are mostly AC coupled, many audio DAC default to digital AC high pass filter toobut for dynamic accuracy its hard to match the linearity and resolution of audio DAC at the cost, availability

author: tggzzz
author_rank: Super Contributor
timestamp: November 29, 2014, 09:39:43 am
content: Quote from: dentaku on November 29, 2014, 12:39:24 amIf you think about it, that question contains the answer to the question.If it is a transient glitch then any effect would be transient, i.e. only occur when the outputs change. In which case slowing down the clock would make the effect less visible.

author: atferrari
author_rank: Frequent Contributor
timestamp: November 29, 2014, 12:46:46 pm
content: 10K and 20 K resistors were invented exactly for that.Add or parallel them and away you go.For any further testing you could build R2R (8 or 16 bits) in very small and dense block. I did and never had to sweat the details again.

author: magetoo
author_rank: Frequent Contributor
timestamp: November 29, 2014, 12:59:27 pm
content: Quote from: dentaku on November 29, 2014, 01:25:25 amFun fact; this kind of thing, binary counters in discrete logic and DACs, is how 70's "string machines" (string synths) worked.You'd have a "top octave generator" that gave you 12 square waves spaced around an octave, then divide those by two for each octave further down, and then add octaves up just like you have done to get ramp waveforms.QuoteAs someone who started out in the 8-bit era, I feel the need to point out that jagged edges on ramp waveforms had nothing to do with the sound in that particular period. :-)But then perhaps that's not what you're going for anyway.(Most of the "8-bit sound" is just squarewaves and PWM. The 6581 SID, which is what I grew up with, had something like 20-bit counters for the ramp and triangle waveforms IIRC.)

author: dentaku
author_rank: Frequent Contributor
timestamp: November 29, 2014, 04:20:47 pm
content: Quote from: magetoo on November 29, 2014, 12:59:27 pmSquare waves are just too easyI'm always looking at different way to make sounds and this looked interesting compared to all the OTA and opamp based stuff I've been experimenting with lately (unstable VCOs and exponential converters can get tedious).My favorite type of synths are mostly digital with analog filters. I've never had any preference for this purely analog stuff.I'm just messing with really low-fi noisemaker type stuff, not serious VCOs for a modular synth or anything like that.Maybe I can use and up/down counter and make a 4 bit triangle too.

author: tggzzz
author_rank: Super Contributor
timestamp: November 29, 2014, 06:30:07 pm
content: Quote from: dentaku on November 29, 2014, 04:20:47 pmOr add a sine lookup table and get a sinewave. Google "DDS" or "direct digital synthesis". There are many commercial chips that do exactly this; see Analog Devices for starters.If you then add a fancy way of changing the phase increment over time, you can simulate just about any modulated RF signal.HP (and others I presume) did just that in the late 80s, and the resulting instrument was classed as a "munition" requiring US export licences. Yup, I was an arms importer

author: Zero999
author_rank: Super Contributor
timestamp: November 29, 2014, 06:39:24 pm
content: If you design a counter which will count up and down alternately then it'll give you a triangle wave.

author: magetoo
author_rank: Frequent Contributor
timestamp: November 29, 2014, 06:58:10 pm
content: Quote from: dentaku on November 29, 2014, 04:20:47 pmCool! I've been reading a bit about synth circuits myself and come to pretty much the same conclusion. Too much work for someone who isn't a purist to be all analog. But there are some neat things I'll have to try. Some day. :-)QuoteOr with a strictly up counter, make it one bit wider than you need and the top bit is an up/down flag. (And then you could invert the output based on this signal somehow.)

author: dentaku
author_rank: Frequent Contributor
timestamp: November 29, 2014, 08:57:40 pm
content: Quote from: tggzzz on November 29, 2014, 06:30:07 pmThis all started because of a video I watched by Bil Herd about DDS.http://hackaday.com/2014/11/24/direct-digital-synthesis-dds-explained-by-bil-herd/I'm just keeping it oldschool and was wondering what I could do with the old 4000 series chips I have instead of using microcontrollers and such.

author: edavid
author_rank: Super Contributor
timestamp: November 29, 2014, 09:09:30 pm
content: Quote from: mikeselectricstuff on November 29, 2014, 01:17:28 amIn real life, yes, but it seems unlikely that that is the problem in the simulation, with a clock rate of 250Hz. I like the output resistance theory much better.Anyway, the whole point of using a simulator is that you can do experiments in a few seconds:1. Reduce the clock rate by 10X and see what happens2. Increase the resistor values by 10X and see what happens

author: dentaku
author_rank: Frequent Contributor
timestamp: November 29, 2014, 09:43:52 pm
content: Quote from: edavid on November 29, 2014, 09:09:30 pmYup, that's what I ended up doing and it fixed the jaggedness.

author: SeanB
author_rank: Super Contributor
timestamp: November 30, 2014, 06:30:26 am
content: Simplest and cheapest way to get matched resistors is to buy a strip of SMD resistors of either the R or 2R value, about 4 times the number of stages, still in the carrier tape. As Dave showed, you will find out that those made at the same time on the same machine will tend to be well matched for value, though they will all be at some nominal value. Then you simply make your board with the resistors in parallel or series to get the 2 values needed.

author: dentaku
author_rank: Frequent Contributor
timestamp: February 10, 2015, 01:41:42 am
content: I'm bringing this old past back because yesterday I built a 4bit R-2R out of some 100k resistor arrays and since I finally got an Arduino I decided to do the experiment with an up counter and an R-2R to create a ramp wave again.I first tested the R-2R with a 4040 counter and it looks nice when clocked at 10kHzbut when I connect my Arduino UNO to the same R-2R (running a simple counting up sketch) I get a spikey looking result.Does the output of the Arduino maybe need to be buffered somehow?4040 It looks greathttp://1drv.ms/1FrKArNArduino, looks not so great on the exact same R-2Rhttp://1drv.ms/1CNw1Au

author: dannyf
author_rank: Super Contributor
timestamp: February 10, 2015, 02:09:38 am
content: QuoteLikely due to loading - the output impedance on those pins isn't materially smaller than the 1k resistance.I would use a part with more current capability, like the HC equivalents.

author: dannyf
author_rank: Super Contributor
timestamp: February 10, 2015, 02:11:29 am
content: QuoteBecause the pin operations on an arduino are not atomic?It can be easily resolved, however.

author: dentaku
author_rank: Frequent Contributor
timestamp: February 10, 2015, 02:59:17 am
content: Quote from: dannyf on February 10, 2015, 02:11:29 amWhat do you mean by atomic?

author: edavid
author_rank: Super Contributor
timestamp: February 10, 2015, 03:22:33 am
content: Depending on which port pins you use, and how you write to them, they won't all change at the same time, causing glitches.So yes, adding a latch (e.g. 74HC373) would be a good way to solve the problem.

author: magetoo
author_rank: Frequent Contributor
timestamp: February 10, 2015, 10:56:21 am
content: Atomic just means "indivisible".In programming lingo, an atomic operation is one that is guaranteed not to be interrupted (it can either complete successfully or fail, but will never be "half done").If setting the pins isn't an atomic operation, then things like an interrupt handler can come in and leave things in an in-between state while it is being processed. And that might cause glitches.

author: tggzzz
author_rank: Super Contributor
timestamp: February 10, 2015, 11:14:10 am
content: Quote from: dentaku on February 10, 2015, 02:59:17 amBeing "atomic" is neither necessary nor sufficient - it is irrelevant.What matters is that the outputs all switch at the same time.You can never get perfection in that respect, so there will always be glitches as one signal changes slightly before another. Such glitches are minimised by ensuring equal and low loading, driving from a single device, and using a single clock to latch all outputs simultaneously.

author: dannyf
author_rank: Super Contributor
timestamp: February 10, 2015, 11:41:57 am
content: QuoteIf you arduino's pin operation functions, they are pin-oriented, meaning that they operate on one pin at a time. Say that you are outputing 0b0111 on the four pins and you want to go to 0b1000 next. As you can only write one pin at a time, you may set the msb first, making the output to be 0b1111, and then clear the lowest three pins, outputing 0b1011, then 0b1001 and then 0b1000.The right approach is to work on the port so that all the state changes on the pins take place at the same time.

author: dentaku
author_rank: Frequent Contributor
timestamp: February 10, 2015, 01:09:29 pm
content: Quote from: dannyf on February 10, 2015, 11:41:57 amOK. I have never used a microcontroller until recently so I was keeping it simple using a sketch I found that outputs on digital pins 2,3,4,5 and uses delayMicroseconds to se the frequency.void setup(){pinMode(2,OUTPUT);pinMode(3,OUTPUT);pinMode(4,OUTPUT);pinMode(5,OUTPUT);}void loop(){for(int i=0;i<14;i++) // increment automatically{int a=i%2; // calculate LSBint b=i/2 %2;int c=i/4 %2;int d=i/8 %2;digitalWrite(5,d); //write MSBdigitalWrite(4,c);digitalWrite(3,b);digitalWrite(2,a); // write LSBdelayMicroseconds(100); // wait for x us}}

author: dannyf
author_rank: Super Contributor
timestamp: February 10, 2015, 01:43:00 pm
content: That wouldn't be atomic.If the pins are on the same port, you can use a shadow variable to form the desired value and then export it to the port data register.Something like this:Code:sDAC_PORT = ((i&0x08)?(1<<5):0) | //form the msb on PORT.5((i&0x04)?(1<<6):0) | //form the 2nd msb on PORT.6((i&0x02)?(1<<2):0) | //form the 3rd msb on PORT.2((i&0x01)?(1<<4):0); //form the lsb on PORT.4DAC_PORT = sDAC_PORT; //export the shadow variableWith this approach, the pin changes will be synchronized.It obviously gets slightly trickier when the port is also driving other devices.

author: dentaku
author_rank: Frequent Contributor
timestamp: February 10, 2015, 01:47:18 pm
content: OK, I did some more research and if I count on PORTB (I could have used D but I decided to use B) it works fine with no spikyness using this code and using pins 8,9,10 and 11.Code:void setup (){DDRB = 255; //pinMode (8, OUTPUT); pinMode (9, OUTOUT)...}void loop (){PORTB ++;delayMicroseconds (100);}I guess I'm going to have to do some more reading and see if I can do this without tying up ALL of PORTB just to count to 16 because I'm assuming just changing toDDRB = 255toDDRB = 15doesn't free up pins 12 and 13 even though I don't need them just to count to 16.EDIT... I see you posted while I was still typing my last message