News:

SMF for DIYStompboxes.com!

Main Menu

Multi Effects Pedal

Started by MstrKurt, November 20, 2013, 11:35:51 PM

Previous topic - Next topic

cloudscapes

Quote from: MstrKurt on December 23, 2013, 05:18:40 PM

I'm currently using the dsPIC33FJ32GP202: http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en530332
But I have a dsPIC33FJ128GP802 coming on the 27th: http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en532298

I don't know much about interrupts in PIC's but what about using __delay32_(x) ?

Yeah, you're not gonna get much delay time with the first chip you linked to. second one looks promising though, memory wise! good for 200-500ms delay depending on how you stretch your samplerate and bitdepth. otherwise, you can use one of these:
http://www.microchip.com/ParamChartSearch/chart.aspx?branchID=270221&mid=&lang=en
They're very easy to use and will give you ten times the ram. Downside is that they use a serial interface, meaning they'll use up a bit of processor time each sample read/write.

I'm not familiar with __delay32_(x), but I imagine it's a delay library where x in the number of milliseconds or nanoseconds? personally I wouldn't use that for the same reason I wouldn't use loops. while your pic is "waiting" for the delay to run out, it can't do anything. it's frozen. you can't send or receive memory to external ram, can't perform calculations, can't sample pots, etc. you'll still be able to build a delay with it, but you'll be limited in how high you can set your samplerate. it can be done, it just won't be efficient or flexible. once you get your delay working using a loop or wait delay, I'd look into adapting timers and interrupts to it afterwards.

a wait delay basically puts your processor on ice for a duration you enter. while it may "work" for the end product, you aren't using the processor to its full potential because it's on ice a percentage of the time. wasted cycles means lower samplerate for the audio.

a timer interrupt is like a kitchen timer that you set to ring every fraction of a second, nanosecond, whatever. when it rings, it runs whatever function you tell it to, whether it's to push audio from the adc to memory and to the dac, perform a math calculation, etc. this may be a bit advanced for you though, so maybe try it with the loop or delay32, even if you'll be limited. but for the sake of information, I like to run a few timers for my samplers/loopers:

-one timer that "rings" repeatedly every 10 milliseconds. too slow for audio samples, but fine for sampling control pots, updating display leds, and not audio-centric calculations
-another timer that rings every 23us, or 44,000 times a second. it does very little when it rings, just move audio through memory, a bit of arithmetic, and sample the main audio ADC/DAC. you don't have to sample a control pot 44,000 times a second because the hand controlling it can't move that fast, so its wasted resources. hence using multiple timers.

but yeah, maybe look at timers and interrupts after you get a basic functioning delay/sampler using techniques you're most comfortable with. I guarantee you'll want to look into it later, though.



~~~~~~~~~~~~~~~~~~~~~~
{DIY blog}
{www.dronecloud.org}

MstrKurt

Quote from: cloudscapes on December 23, 2013, 05:44:12 PM
Quote from: MstrKurt on December 23, 2013, 05:18:40 PM

I'm currently using the dsPIC33FJ32GP202: http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en530332
But I have a dsPIC33FJ128GP802 coming on the 27th: http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en532298

I don't know much about interrupts in PIC's but what about using __delay32_(x) ?

Yeah, you're not gonna get much delay time with the first chip you linked to. second one looks promising though, memory wise! good for 200-500ms delay depending on how you stretch your samplerate and bitdepth. otherwise, you can use one of these:
http://www.microchip.com/ParamChartSearch/chart.aspx?branchID=270221&mid=&lang=en
They're very easy to use and will give you ten times the ram. Downside is that they use a serial interface, meaning they'll use up a bit of processor time each sample read/write.

I'm not familiar with __delay32_(x), but I imagine it's a delay library where x in the number of milliseconds or nanoseconds? personally I wouldn't use that for the same reason I wouldn't use loops. while your pic is "waiting" for the delay to run out, it can't do anything. it's frozen. you can't send or receive memory to external ram, can't perform calculations, can't sample pots, etc. you'll still be able to build a delay with it, but you'll be limited in how high you can set your samplerate. it can be done, it just won't be efficient or flexible. once you get your delay working using a loop or wait delay, I'd look into adapting timers and interrupts to it afterwards.

a wait delay basically puts your processor on ice for a duration you enter. while it may "work" for the end product, you aren't using the processor to its full potential because it's on ice a percentage of the time. wasted cycles means lower samplerate for the audio.

a timer interrupt is like a kitchen timer that you set to ring every fraction of a second, nanosecond, whatever. when it rings, it runs whatever function you tell it to, whether it's to push audio from the adc to memory and to the dac, perform a math calculation, etc. this may be a bit advanced for you though, so maybe try it with the loop or delay32, even if you'll be limited. but for the sake of information, I like to run a few timers for my samplers/loopers:

-one timer that "rings" repeatedly every 10 milliseconds. too slow for audio samples, but fine for sampling control pots, updating display leds, and not audio-centric calculations
-another timer that rings every 23us, or 44,000 times a second. it does very little when it rings, just move audio through memory, a bit of arithmetic, and sample the main audio ADC/DAC. you don't have to sample a control pot 44,000 times a second because the hand controlling it can't move that fast, so its wasted resources. hence using multiple timers.

but yeah, maybe look at timers and interrupts after you get a basic functioning delay/sampler using techniques you're most comfortable with. I guarantee you'll want to look into it later, though.





That's the the exact memory module I had in mind if it did turn out I needed one.

Thanks a lot for taking your time to explain to me the reasoning behind needing timer interrupts! I'll do some research on how I can implement these.

I've created a form of Distortion thus far by just creating a clipping point e.g. if(input>value){ input = value;}
However there is a problem that I can't get a clean signal out, (I imagine this is because I have the output coming from a digital output and is sitting on 3.3V DC, or even because I'm not using a DAC at this stage, I will use the DAC when the new chip arrives)

cloudscapes

I forgot to mention a thing in my kitchen timer metaphor. While the processor is "waiting" for the timer to "ring", it can do other stuff. it's not frozen like it would be when using loops to wait, or a wait delay.
~~~~~~~~~~~~~~~~~~~~~~
{DIY blog}
{www.dronecloud.org}

potul

Hi MstrKurt,

Based on the pseudo code you entered, I think you need to research a little about delay lines. Delaying a signal is not simply waiting for some time and then output the signal. You need to store in memory all the signal that is received so that you can output it afterwards... This is why the more delay you need, the more memory is required.
This is the reason I told you that with such a PIC, delays are limited to some ms (depending on sampling rate), because the internal memory is small. Adding external memory gives you the ability to have longer delays.

In the project I sent you there is an implemented delay line you can use (with internal memory)

MstrKurt

Thanks for clearing that up Pottul :).

Would anyone know of an informative book on various types of audio effects including the background on how they are created / and how they became popular?.

Digital Larry

Here's pretty good reference for a bunch of DSP FX.  Not much on the history, but pretty informative otherwise.

http://www.cs.cf.ac.uk/Dave/CM0268/PDF/10_CM0268_Audio_FX.pdf
Digital Larry
Want to quickly design your own effects patches for the Spin FV-1 DSP chip?
https://github.com/HolyCityAudio/SpinCAD-Designer

MstrKurt

Thanks Digital Larry :)

The new chip (dsPIC33FJ128GP802) has arrived, I believe I have everything set up right but Im still hearing some sort of noise when I'm trying to get a clean signal through, and also the signal decays rather quickly to a rather blippy distortion.

Anyone know what could be causing this?.

slacker

How are you getting audio in and out of the chip? A schematic and a look at the code would be useful.

MstrKurt



Main Code:
/////////////////////////////////////////////////////////////////////////////////////////////////
// © 2012 Microchip Technology Inc.
//
// MICROCHIP SOFTWARE NOTICE AND DISCLAIMER:  You may use this software, and any
// derivatives created by any person or entity by or on your behalf, exclusively with
// Microchip?s products.  Microchip and its licensors retain all ownership and intellectual
// property rights in the accompanying software and in all derivatives here to.
//
// This software and any accompanying information is for suggestion only.  It does not
// modify Microchip?s standard warranty for its products.  You agree that you are solely
// responsible for testing the software and determining its suitability.  Microchip has
// no obligation to modify, test, certify, or support the software.
//
// THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF NON-INFRINGEMENT,
// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE, ITS INTERACTION
// WITH MICROCHIP?S PRODUCTS, COMBINATION WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION.
//
// IN NO EVENT, WILL MICROCHIP BE LIABLE, WHETHER IN CONTRACT, WARRANTY, TORT
// (INCLUDING NEGLIGENCE OR BREACH OF STATUTORY DUTY), STRICT LIABILITY, INDEMNITY,
// CONTRIBUTION, OR OTHERWISE, FOR ANY INDIRECT, SPECIAL, PUNITIVE, EXEMPLARY, INCIDENTAL
// OR CONSEQUENTIAL LOSS, DAMAGE, FOR COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
// SOFTWARE, HOWSOEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR
// THE DAMAGES ARE FORESEEABLE.  TO THE FULLEST EXTENT ALLOWABLE BY LAW, MICROCHIP'S TOTAL
// LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES,
// IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
//
// MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE TERMS.
//
// ****************************************************************************
// ****************************************************************************/
//
// ADDITIONAL NOTES:
// Code Tested on:
// 16-Bit 28-Pin Starter board with dsPIC33FJ128GP802 device
// **********************************************************************/

#include "p33fxxxx.h"
#include "dsp.h"
#include "adcdacDrv.h"

//Macros for Configuration Fuse Registers:
//Invoke macros to set up  device configuration fuse registers.
//The fuses will select the oscillator source, power-up timers, watch-dog
//timers etc. The macros are defined within the device
//header files. The configuration fuse registers reside in Flash memory.



// Internal FRC Oscillator
_FOSCSEL(FNOSC_FRC); // FRC Oscillator
_FOSC(FCKSM_CSECMD & OSCIOFNC_ON  & POSCMD_NONE);
  // Clock Switching is enabled and Fail Safe Clock Monitor is disabled
  // OSC2 Pin Function: OSC2 is Clock Output
  // Primary Oscillator Mode: Disabled

_FWDT(FWDTEN_OFF);                        // Watchdog Timer Enabled/disabled by user software
  // (LPRC can be disabled by clearing SWDTEN bit in RCON register


fractional input;



int main (void)
{
// Configure Oscillator to operate the device at 40MIPS
// Fosc= Fin*M/(N1*N2), Fcy=Fosc/2
// Fosc= 7.37M*43/(2*2)=79.22Mhz for ~40MIPS input clock
PLLFBD             = 41; // M=43
CLKDIVbits.PLLPOST = 0; // N1=2
CLKDIVbits.PLLPRE  = 0; // N2=2
OSCTUN             = 0; // Tune FRC oscillator, if FRC is used

// Disable Watch Dog Timer
RCONbits.SWDTEN=0;

// Clock switch to incorporate PLL
__builtin_write_OSCCONH(0x01);     // Initiate Clock Switch to
    // FRC with PLL (NOSC=0b001)
__builtin_write_OSCCONL(0x01);     // Start clock switching
while (OSCCONbits.COSC != 0b001);  // Wait for Clock switch to occur

// Wait for PLL to lock
while(OSCCONbits.LOCK!=1) {};

initAdc();    // Initialize the A/D converter to convert Channel 4
initDac();    // Initialize the D/A converter
initDma0();   // Initialize the DMA controller to buffer ADC data in conversion order
initTmr3();   // Initialize the Timer to generate sampling event for ADC

extern fractional BufferA[NUMSAMP]; // Ping pong buffer A
extern fractional BufferB[NUMSAMP]; // Ping pong buffer B
extern unsigned int DmaBuffer; // DMA flag
extern int flag; // Flag
int i;

            ;

TRISBbits.TRISB2 = 1;
TRISBbits.TRISB12 = 0;


  while (1)    // Loop Endlessly - Execution is interrupt driven
   {

      while(AD1CON1bits.DONE != 1)
      {

      }
      input = ADC1BUF0;
     
                   if(flag)
                  {
                    for(i = 0; i < NUMSAMP; i++)
                      {
                        while(DAC1STATbits.REMPTY != 1);// Wait for D/A conversion
                          if(DmaBuffer == 0)
                            DAC1RDAT = BufferA[i];     // Load the DAC buffer with data
                              else
                                DAC1RDAT = BufferB[i];  // Load the DAC buffer with data
                        }
                                    flag = 0;
                    }
               }

        DAC1RDAT = input;
           //  return 0;

     
  }


adcdacDrv.c:


/////////////////////////////////////////////////////////////////////////////////////////////////
// © 2012 Microchip Technology Inc.
//
// MICROCHIP SOFTWARE NOTICE AND DISCLAIMER:  You may use this software, and any
// derivatives created by any person or entity by or on your behalf, exclusively with
// Microchip?s products.  Microchip and its licensors retain all ownership and intellectual
// property rights in the accompanying software and in all derivatives here to.
//
// This software and any accompanying information is for suggestion only.  It does not
// modify Microchip?s standard warranty for its products.  You agree that you are solely
// responsible for testing the software and determining its suitability.  Microchip has
// no obligation to modify, test, certify, or support the software.
//
// THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF NON-INFRINGEMENT,
// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE, ITS INTERACTION
// WITH MICROCHIP?S PRODUCTS, COMBINATION WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION.
//
// IN NO EVENT, WILL MICROCHIP BE LIABLE, WHETHER IN CONTRACT, WARRANTY, TORT
// (INCLUDING NEGLIGENCE OR BREACH OF STATUTORY DUTY), STRICT LIABILITY, INDEMNITY,
// CONTRIBUTION, OR OTHERWISE, FOR ANY INDIRECT, SPECIAL, PUNITIVE, EXEMPLARY, INCIDENTAL
// OR CONSEQUENTIAL LOSS, DAMAGE, FOR COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
// SOFTWARE, HOWSOEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR
// THE DAMAGES ARE FORESEEABLE.  TO THE FULLEST EXTENT ALLOWABLE BY LAW, MICROCHIP'S TOTAL
// LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES,
// IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
//
// MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE TERMS.
//
// ****************************************************************************
// ****************************************************************************/

#include "p33fxxxx.h"
#include "dsp.h"
#include "adcdacDrv.h"

fractional BufferA[NUMSAMP] __attribute__((space(dma)));  // Ping-pong buffer A
fractional BufferB[NUMSAMP] __attribute__((space(dma)));  // Ping-pong buffer B

/*=============================================================================
initAdc() is used to configure A/D to convert channel 4 on Timer event.
It generates event to DMA on every sample/convert sequence.
=============================================================================*/
void initAdc(void)
{
AD1CON1bits.FORM  = 3; // Data Output Format: Signed Fraction (Q15 format)
AD1CON1bits.SSRC  = 2; // Sample Clock Source: GP Timer starts conversion
AD1CON1bits.ASAM  = 1; // ADC Sample Control: Sampling begins immediately after conversion
AD1CON1bits.AD12B = 1; // 12-bit ADC operation

AD1CON2bits.CHPS = 0; // Converts CH0

AD1CON3bits.ADRC = 0; // ADC Clock is derived from Systems Clock
AD1CON3bits.ADCS = 3; // ADC Conversion Clock Tad=Tcy*(ADCS+1)= (1/40M)*4 = 100ns
// ADC Conversion Time for 12-bit Tc=14*Tad = 1.4us

AD1CON1bits.ADDMABM = 1; // DMA buffers are built in conversion order mode
AD1CON2bits.SMPI    = 0; // SMPI must be 0


//AD1CHS0: A/D Input Select Register
AD1CHS0bits.CH0SA = 4; // MUXA +ve input selection (AN4) for CH0
AD1CHS0bits.CH0NA = 0; // MUXA -ve input selection (Vref-) for CH0
//AD1PCFGH/AD1PCFGL: Port Configuration Register
AD1PCFGL           = 0xFFFF;
AD1PCFGLbits.PCFG4 = 0;     // AN4 as Analog Input


IFS0bits.AD1IF   = 0; // Clear the A/D interrupt flag bit
IEC0bits.AD1IE   = 0; // Do Not Enable A/D interrupt
AD1CON1bits.ADON = 1; // Turn on the A/D converter
}

/*=============================================================================
initDac() is used to configure D/A.
=============================================================================*/
void initDac(void)
{
  /* Initiate DAC Clock */
  ACLKCONbits.SELACLK  = 0;  // FRC w/ Pll as Clock Source
  ACLKCONbits.AOSCMD   = 0;  // Auxiliary Oscillator Disabled
  ACLKCONbits.ASRCSEL  = 0;  // Auxiliary Oscillator is the Clock Source
  ACLKCONbits.APSTSCLR = 7;  // Fvco/1 = 158.2 MHz/1 = 158.2 MHz

  DAC1STATbits.ROEN = 1; // Right Channel DAC Output Enabled
  DAC1DFLT          = 0x8000; // DAC Default value is the midpoint

  // Sampling Rate Fs = DACCLK/256 = 103 kHz
  DAC1CONbits.DACFDIV = 7;   // DACCLK = ACLK/(DACFDIV - 1): 158.2 MHz/6 = 26.4 MHz

  DAC1CONbits.FORM    = 1;   // Data Format is signed integer
  DAC1CONbits.AMPON   = 0;   // Analog Output Amplifier is enabled during Sleep Mode/Stop-in Idle mode

  DAC1CONbits.DACEN   = 1;   // DAC1 Module Enabled
}

/*=======================================================================================
Timer 3 is setup to time-out every Ts secs. As a result, the module
will stop sampling and trigger a conversion on every Timer3 time-out Ts.
At that time, the conversion process starts and completes Tc=12*Tad periods later.
When the conversion completes, the module starts sampling again. However, since Timer3
is already on and counting, about (Ts-Tc)us later, Timer3 will expire again and trigger
next conversion.
=======================================================================================*/
void initTmr3()
{
TMR3          = 0x0000;   // Clear TMR3
PR3           = SAMPPRD;  // Load period value in PR3
IFS0bits.T3IF = 0;    // Clear Timer 3 Interrupt Flag
IEC0bits.T3IE = 0;    // Clear Timer 3 interrupt enable bit

T3CONbits.TON = 1;    // Enable Timer 3
}

/*=============================================================================
DMA0 configuration
Direction: Read from peripheral address 0-x300 (ADC1BUF0) and write to DMA RAM
AMODE: Register indirect with post increment
MODE: Continuous, Ping-Pong Mode
IRQ: ADC Interrupt
ADC stores results stored alternatively between BufferA[] and BufferB[]
=============================================================================*/
void initDma0(void)
{
DMA0CONbits.AMODE = 0; // Configure DMA for Register indirect with post increment
DMA0CONbits.MODE  = 2; // Configure DMA for Continuous Ping-Pong mode

DMA0PAD = (int)&ADC1BUF0;  // Peripheral Address Register: ADC buffer
DMA0CNT = (NUMSAMP-1);     // DMA Transfer Count is (NUMSAMP-1)

DMA0REQ =  13;             // ADC interrupt selected for DMA channel IRQ

DMA0STA = __builtin_dmaoffset(BufferA); // DMA RAM Start Address A
DMA0STB = __builtin_dmaoffset(BufferB); // DMA RAM Start Address B

IFS0bits.DMA0IF  = 0; // Clear the DMA interrupt flag bit
IEC0bits.DMA0IE  = 1; // Set the DMA interrupt enable bit

DMA0CONbits.CHEN = 1; // Enable DMA channel
}

/*=============================================================================
_DMA0Interrupt(): ISR name is chosen from the device linker script.
=============================================================================*/
unsigned int DmaBuffer = 0;
int flag = 0;

void __attribute__((interrupt, no_auto_psv)) _DMA0Interrupt(void)
{
DmaBuffer ^= 1;      // Ping-pong buffer select flag
flag       = 1;      // Ping-pong buffer full flag
IFS0bits.DMA0IF = 0; // Clear the DMA0 Interrupt Flag
}

/*=============================================================================
_DAC1RInterrupt(): ISR name is chosen from the device linker script.
=============================================================================*/
void __attribute__((interrupt, no_auto_psv)) _DAC1RInterrupt(void)
{
  IFS4bits.DAC1RIF = 0; // Clear Right Channel Interrupt Flag
}


addacDrv.h:

/////////////////////////////////////////////////////////////////////////////////////////////////
// © 2012 Microchip Technology Inc.
//
// MICROCHIP SOFTWARE NOTICE AND DISCLAIMER:  You may use this software, and any
// derivatives created by any person or entity by or on your behalf, exclusively with
// Microchip?s products.  Microchip and its licensors retain all ownership and intellectual
// property rights in the accompanying software and in all derivatives here to.
//
// This software and any accompanying information is for suggestion only.  It does not
// modify Microchip?s standard warranty for its products.  You agree that you are solely
// responsible for testing the software and determining its suitability.  Microchip has
// no obligation to modify, test, certify, or support the software.
//
// THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF NON-INFRINGEMENT,
// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE, ITS INTERACTION
// WITH MICROCHIP?S PRODUCTS, COMBINATION WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION.
//
// IN NO EVENT, WILL MICROCHIP BE LIABLE, WHETHER IN CONTRACT, WARRANTY, TORT
// (INCLUDING NEGLIGENCE OR BREACH OF STATUTORY DUTY), STRICT LIABILITY, INDEMNITY,
// CONTRIBUTION, OR OTHERWISE, FOR ANY INDIRECT, SPECIAL, PUNITIVE, EXEMPLARY, INCIDENTAL
// OR CONSEQUENTIAL LOSS, DAMAGE, FOR COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
// SOFTWARE, HOWSOEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR
// THE DAMAGES ARE FORESEEABLE.  TO THE FULLEST EXTENT ALLOWABLE BY LAW, MICROCHIP'S TOTAL
// LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES,
// IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
//
// MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE TERMS.
//
// ****************************************************************************
// ****************************************************************************

#ifndef __ADCDRV1_H__
#define __ADCDRV1_H__

// Sampling Control
#define Fosc 79227500     // Hz
#define Fcy (Fosc/2)     // Hz
#define Fs    103160       // Hz
#define SAMPPRD  (Fcy/Fs)-1   // Hz
#define NUMSAMP  256

// Functions
void initAdc(void);
void initDac(void);
void initTmr3(void);
void initDma0(void);

// Peripheral ISRs
void __attribute__((interrupt, no_auto_psv)) _DMA0Interrupt(void);
void __attribute__((interrupt, no_auto_psv)) _DAC1RInterrupt(void);
#endif









cloudscapes

You should buffer the guitar signal before it reaches the pic, which probably can't handle the impedance very well. Just an opamp buffer with gain pot is probably enough.

Another trick I use often is just to make a clipping led. If the adc sample value is greater than a bit under the max value (so if 10bit adc, 0-1023, if it's greater than 1000) light a led. otherwise, dark. it'll help you trim your gain well and ensure you have a proper signal before you start debugging the code. only takes a few minutes to set up if you know the code to set a pin high or low.
~~~~~~~~~~~~~~~~~~~~~~
{DIY blog}
{www.dronecloud.org}

MstrKurt

#30
So create  an op amp outside of the PIC to feed the signal to before reaching the PIC? is this to amplify the signal before reaching the PIC?.

Here is an audio preview of what It sounds like: It's quite loud so be warned. Also mind the bad playing and recording.

https://www.dropbox.com/s/w52cs7s31raoz3m/Not%20so%20Clean.mp3
Any advice is appreciated :)

cloudscapes

Quote from: MstrKurt on January 04, 2014, 01:05:07 PM
So create  an op amp outside of the PIC to feed the signal to before reaching the PIC? is this to amplify the signal before reaching the PIC?.

if it's straight from the guitar, yeah. just simple opamp buffer with gain pot.

the pic's ADCs are 12bit and with a default voltage reference extect voltages between 0 and 3.3v to be able to give you that full 12bit range. if it's just straight from the guitar, the ADCs are getting only a fraction of the voltage, so maybe only 2 or 3 usable bits and it'll sound pretty sputtery/crunchy. not saying that's the problem you had, but it certainly wouldn't help if it's guitar straight to pic.

careful not to overload the pic's ADC, voltage-wise. it can probably handle a bit more than 3.3v for a second, but I wouldn't push it. just make sure your buffer/gain doesn't go over that, regardless how you do it.

it might seem like a lot of work to get started  ;D but you do it once or twice and it gets easier afterwards.
~~~~~~~~~~~~~~~~~~~~~~
{DIY blog}
{www.dronecloud.org}

MstrKurt

Quote from: cloudscapes on January 04, 2014, 02:59:12 PM
Quote from: MstrKurt on January 04, 2014, 01:05:07 PM
So create  an op amp outside of the PIC to feed the signal to before reaching the PIC? is this to amplify the signal before reaching the PIC?.

if it's straight from the guitar, yeah. just simple opamp buffer with gain pot.

the pic's ADCs are 12bit and with a default voltage reference extect voltages between 0 and 3.3v to be able to give you that full 12bit range. if it's just straight from the guitar, the ADCs are getting only a fraction of the voltage, so maybe only 2 or 3 usable bits and it'll sound pretty sputtery/crunchy. not saying that's the problem you had, but it certainly wouldn't help if it's guitar straight to pic.

careful not to overload the pic's ADC, voltage-wise. it can probably handle a bit more than 3.3v for a second, but I wouldn't push it. just make sure your buffer/gain doesn't go over that, regardless how you do it.

it might seem like a lot of work to get started  ;D but you do it once or twice and it gets easier afterwards.

Fantastic information.

Thank you very much for that. I will make a standard buffer for the input and diff amp for the output when I get access to the lab on Tuesday.
Did you check out the sound I recorded to give an indication of what I'm getting?. Does it sound like the problem we've been discussing?.

slacker

#33
To add to what Etienne said, part of your problem is that the guitar signal swings above and below ground and the PIC can only read positive voltages, those above ground, so your current set up is only sampling half the waveform. That's where some of the distortion in your sound clip is coming from. To solve this you need to bias the input to half the PIC's supply voltage using something like shown below. So long as the total swing of the signal is less than the supply voltage you'll now sample the full wave form.



How are you powering the PIC? If you're powering it from the USB port via the programmer then you'll get a lot of noise in the signal, you need to power it from a separate voltage regulator. In my experience just having the programmer connected even if the PIC has it's own power adds a lot of noise, I disconnect the programmer once I've finished programming.

slacker

Quote from: cloudscapes on January 04, 2014, 10:30:04 AM
Another trick I use often is just to make a clipping led. If the adc sample value is greater than a bit under the max value (so if 10bit adc, 0-1023, if it's greater than 1000) light a led. otherwise, dark.

Nice idea I'll have to try that.

MstrKurt

Quote from: slacker on January 05, 2014, 01:45:09 PM
To add to what Etienne said, part of your problem is that the guitar signal swings above and below ground and the PIC can only read positive voltages, those above ground, so your current set up is only sampling half the waveform. That's where some of the distortion in your sound clip is coming from. To solve this you need to bias the input to half the PIC's supply voltage using something like shown below. So long as the total swing of the signal is less than the supply voltage you'll now sample the full wave form.



How are you powering the PIC? If you're powering it from the USB port via the programmer then you'll get a lot of noise in the signal, you need to power it from a separate voltage regulator. In my experience just having the programmer connected even if the PIC has it's own power adds a lot of noise, I disconnect the programmer once I've finished programming.

Thanks for your input, Slacker.

I'm powering it via a PICkit 3, however while I'm in the lab I power it directly from a DC power supply known as a Black Box with 3.3V.
Would powering the circuit from a 3V battery still require a regulator or should it be ok?.

MstrKurt

#36
Just a follow up question regarding the op amps:

I'm aware of how to design an op amp to a specific gain but only when I know the input voltage. Do guitars have a maximum output voltage(before hitting an amp), if so does it differ for each guitar?.

EDIT: Sorry, I re-read that a gain pot is needed. Apologies for not reading back beforehand.

slacker

Quote from: MstrKurt on January 05, 2014, 02:39:55 PM
Would powering the circuit from a 3V battery still require a regulator or should it be ok?.

Yeah you could probably use a 3 Volt battery without a regulator. You'll probably need a higher Voltage to power the opamps though, unless you find some that work at 3 Volts. The "standard" for guitar pedals is 9 Volts so I would use that to power the opamps and a 3.3 Volt regulator to power the PIC.

MstrKurt

The only Op Amp I could find at the lab is a 5V powered one, so I've got 2 separate supplies (3.3 and 5)
The weird thing is if I power the chip by a battery rather than my programmer I don't hear anything, and while my programmer is connected,
I still get the same original sound while the op amp is there.

Here is the Schematic:


Digital Larry

The input impedance of your circuit is about 50k ohms which is going to load a typical passive guitar pickup quite a bit.  I recommend a non inverting stage with a fixed gain of between 1 and 2 and the volume pot after it.  This will have a much higher input impedance.
Digital Larry
Want to quickly design your own effects patches for the Spin FV-1 DSP chip?
https://github.com/HolyCityAudio/SpinCAD-Designer