Envelope detection via PIC ADC?

Started by Gurner, February 16, 2011, 10:04:31 AM

Previous topic - Next topic

Gurner

Has anyone considered this or done it?

What I mean is sample the incoming AC guitar signal at say 30khz (20 x 1.5Khz) to pull out the cycle 'peak' & then convert peak to RMS in the PIC.

The latest £1.00 16f18xx range of PICs can run at 40Mhz, so this ought to be a breeze for them?

(yes, I know a bog standard peak detect circuit into a PICADC pin is easier less taxing but much as a mountaineer wants to climb a mountain cos it's there blah blah)

Galego

Couldn't it be done with one of those sound to light circuits, but instead of lighting an led, setting a input pin high (or low) with a transistor?

Gurner

I'm sure you could, but such ICs typically have a whole heap of comparators internally....what I'm talking about here is sampling a guitar signal in real time to extract 'peak' on a per cycle basis (kind of a software comparator vs hardware comparator I guess).

Hides-His-Eyes

I think this is one of those "300 lines of code or 5 components" situations

I think you'd be better off using an efficient algorithm rather than trying to do it by brute force; perhaps something like this?

http://www.numerix-dsp.com/envelope.html

Gurner

Quote from: Hides-His-Eyes on February 16, 2011, 02:12:33 PM
I think this is one of those "300 lines of code or 5 components" situations

I think you'd be better off using an efficient algorithm rather than trying to do it by brute force; perhaps something like this?

http://www.numerix-dsp.com/envelope.html

I'm working on it right now...I reckon it'll be about 20-25 lines of code - fortunately even 300 lines of code doesn't take up any any space on my pcb (& for the intended app, I already have a PIC pretty much kicking its heels against the kerb) ...and it's space on my PCB I really need!

Hides-His-Eyes

I'd love to see what you come up with then! :)

Gurner

well I've got it working (15 lines of code in the end), but the peak detect readings are only presently stable/accurate up to 300hz of incoming audio signal - I've stumbled at getting my PIC timer 1setup to interrupt at a higher frequency, so once the audio gets above 300Hz, then there aren't enough sample 'slices'.

Should be able to sort this simple timer1 problem, but I need to sleep on it - a fresh pair of eyes tomorrow should help!

Hides-His-Eyes

I wish I know how to do this stuff... I've got coding experience, electronics experience, I've just never sprung the money for a PIC programmer.

Gurner

#8
Ok, an update....the short bit of code works very well - but I was using a sig gen (perfect sine wave)

However  a guitar signal is such more tricky (& retrospectively, somewhat obviously!) , there's a strong 2nd harmonic shortly after the pluck which 'zero crosses' too & therefore plays havoc with extracting the fundamental peak.

So what the code really needs to do is smooth/average out the extracted peaks (much like a LPF cap does in a peak detect circuit) ....needs a bit more work & will likely turn out to be 300 lines of code!

Quote from: Hides-His-Eyes on February 17, 2011, 05:29:52 AM
I've just never sprung the money for a PIC programmer.

FWIW there are PICKIT2 clones on ebay very cheap .... http://cgi.ebay.co.uk/Clone-Microchip-Development-Programmer-Mini-PICKIT-2-/230586542975?pt=UK_BOI_Electrical_Components_Supplies_ET&hash=item35b0076b7f

potul

You can check some envelope detector algorithms here:

http://www.musicdsp.org/archive.php?classid=0

I haven't tried any, so I can't recomend any...

Mat


potul

There is one in the link I put that looks simple enough. It is basically_

-Full Rectifying the signal (using the abs function in this case)
-Apply a LP filter to it.

You can specify release and attack time.

I think it is simple enough to be adapted to ASM for the PIC. (are you using ASM or C?)

Mat

Gurner

#11
I'm actually only using basic with the PIC (still just a learner really) - there are a lot of links on that page, which one was the one that you found?

Edit: Found it!

potul

select "all" and search for "envelope". You will find it.
With basic should even be simpler.

Mat

cpm

#13
my guess:

1) settle for an algorithm that gives the response you are looking for, with simple calculation: forget about arbitrary floating point opereations (stick to 8/16 bit simple math and lookup tables if needed)
2) program it as fast as possible: i'd go for ASM to save on cycles (this gives a higher sampling rate, or more headroom for calculations)
3) get the minimum sampling period you can achieve with your running code (working hard on 1 & 2)
4) RC filter the signal to match you sampling period, to avoid unwanted aliasing

I think the hardest to achieve is a good detection acuracy for attack, and a complex enough algorithm that will soften the output. You dont want ripple, do you?

also, take in mind that memory is very limited in pics, you cant sample a big lot of input and wiser methods are needed to track signal history.

this would be a fun project i'd like to try some time in the future.
my thinking would be a quick and dirty rectifier with "fast" envelope and use the pic to shape the final response for a more limited range. That way a 300hz sampling rate as the one you got may be good enough

Gurner

Thanks for your input, just one point.... the 300Hz I mentioned wasn't the sampling frequency....it was the frequency of the incoming signal I was sampling - I got a great steady peak detect value at that low incoming audio frequency - the peak detect value in the PIC it got jittery as I increased the frequency of the incoming audio signal above 300Hz. I know what's causing this - my sampling frequency is too low, but I'm having one helluva job getting the sampling frequency up with this darned new PIC I'm using!

BubbaFet

I just received a tube of PIC16F1827s. Man, does this microprocessor
have all the goods, or what? Yowzer!

I'm applauding your present course of action, as I am about to
begin investigation of this device for musical applications also, as
personal time allows. It's such a cool chip! I've been using Microchip
8-bit uPs in products since they first came out, 20 years ago. This chip is the
one that I've wished for a long time...


Gurner

#16
Got to agree about the new PIC16F182x range of chips (I'm using the PIC16f1828) - man, these ICs are full to the brim with cool features...& all that with an onboard 32Mhz internal Oscillator to boot (not 40Mhz as per my first post) - all this for £1! Steal of the century.

Every night I discover more & more - for example last night, I dabbled withusing the ADC -Vref & (internal +4.096V) +Vref....which gets me great resolution at lower signal swings (saving me an opamp stage)...& on it goes.

Gurner

Ok, I managed this in the end, but a coiuple of pointers....

1, Using Basic, it's not possible to use an interrupt routine at any decent frequency (too much overhead entering/exiting the interrupt routine).

2. You'll likely need to use the CCP module ...specifically the special event trigger. essentially, this can be set up to do the ADC aspect in the background (using hardware) at a high sampling frequency, leaving you free to massage the ADC results in your main loop.

My present simple code looks something like this...

Begin:
IF ADRESH >= PREVIOUS_SAMPLE THEN  ' ADRESH is the ADC register (present sample) - if it's equal to or bigger than the last sample keep it
previous_sample = ADRESH                    
else
previous_sample = previous_sample-1   ' if it's not bigger start decrementing (this is the pseudo cap dishcharge time)
endif
GOTO Begin


I intend revisiting this over the coming evenings, to  do full wave rectification of the incoming AC signal in software.

Galego

Quote from: Gurner on February 22, 2011, 04:06:02 AM
1, Using Basic, it's not possible to use an interrupt routine at any decent frequency (too much overhead entering/exiting the interrupt routine).

What do you mean by this?

I have made a tap tempo pic basic pro program that uses Timer2 interrupts and reads ADC from 3 pins, the interrupt routine runs at over 100khz, if I reduce the PR2 value.

What you have to be very careful in Basic, is to make sure that while the main section of your program is running, you shouldn't use complicated calculations, because they will most likely call a disable and enable to make sure the interrupt doesn't interfere with the calculations it needs to do.

So if you have something like A = ((B * C) + D) / E, decompose it into smaller pieces and use shift right/left when possible to prevent the interpreter from interfering with the interrupts.

Gurner

#19
Quote from: Galego on February 22, 2011, 06:05:19 PM
Quote from: Gurner on February 22, 2011, 04:06:02 AM
1, Using Basic, it's not possible to use an interrupt routine at any decent frequency (too much overhead entering/exiting the interrupt routine).

What do you mean by this?

Ok, I'll rephrase it.....

1, Using Basic, I wasn't able to get an interrupt routine going to allow any decent sample frequency, (ie where the ADC happens in the interrupt routine)

I was using Darrel Taylor's PICBasic interrupt routines & running the PIC at 8Mhz .....I had diffs, because by the time the interrupt entry & exit context savings had done their bit, there wasn't any decent length of time left to do much before the next interrupt would be due.

Now that may well becuase I suck at basic (& I'll freely admit, I'm not a programmer - a kludger would be a better description)....it may becuase of PICBAsic (or even the way the interrupts have been implemented within Picbasic) but I'd have to say the special event timer is a revelation...and certainly the way to go when you want high rates of sampling in the background going on  - basically it's taking ADC samples in hardware with no code overhead/intervention  - just basically go & read the contents of ADRESH  whenever you want your ADC reading - I'm running at 40khz - not the slighest stress on my main code.

while I'm here....I'm happy to report that I can now feed an AC signal into my PIC, and have the signal full wave rectified in software (ie guitar signal straight out of an opamp into a PIC analogue pin - no diodes or caps involved) ...and then the magnitude extracted thereafter  - this doesn't just save me a cap & two opamps and diodes, but allows variable discharge rates inside the PIC to suit....instant charge times - zero crossing detect etc.