|
|
View previous topic :: View next topic |
Author |
Message |
Kamputty Guest
|
strange i2c issues... |
Posted: Tue Oct 31, 2006 5:16 pm |
|
|
Hi all,
Well, my capturing sound from a mic project is coming along. But I've come across a strange issue...not being an electronics person, I think it's something there, but who knows!
~ setup ~
#1. To capture the sound, I purchased a "Super Snooper Big Ears" kit. Has a speaker, volume control, and a headphone jack. It works.
#2. I've connected the headphone jack to my breadboard going to a LN386N-1.
Code: |
Pin 1 = open
Pin 2 = Ground
Pin 3 = Positive from headphone jack, 10k res to ground
Pin 4 = Ground
Pin 5 = To A1 on pic18f4520
Pin 6 = +5
Pin 7 = open
Pin 8 = open
|
#3. I'm using a Max517 DAC for D/A convertion
Code: |
Pin 1 = + output to headphone jack
Pin 2 = Ground
Pin 3 = SCL, plus 1k res to +5
Pin 4 = SDA, plus 1k res to +5
Pin 5 = ground
Pin 6 = ground
Pin 7 = open
Pin 8 = +5 |
#4. Now, if I just poll A1 (forget about the max517 for a sec), I can see the ADC values move as I make noise etc. It keeps on polling
#5. If I uncomment the i2c lines within the same loop, the system polls, but at times (many) the system restarts with code #15
#6. ooops, here's the test code
Code: |
#include <18F4520.h>
#device *=16 adc=8
#case
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES HS //20mhz mode
//#fuses INTRC_IO // internal 8mhz osc
#FUSES NOPROTECT //Code not protected from reading
#FUSES BROWNOUT //Reset when brownout detected
#FUSES BORV25 //Brownout reset at 2.5V
#FUSES NOPUT //No Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES NOPBADEN //PORTB pins are configured as analog input channels on RESET
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#FUSES LPT1OSC //Timer1 configured for low-power operation
#FUSES MCLR //Master Clear pin enabled
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#use delay(clock=20000000)
#use rs232(baud=115200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#use standard_io(A)
#use standard_io(B)
#use standard_io(C)
#use standard_io(D)
#use standard_io(E)
#define I2C_SCL PIN_C4
#define I2C_SDA PIN_C5
#define DAC_ADDRESS 0b0101100 // 010=factory, 11=517 setting, 0=ad0 grd, 0=ad1 gnd
#use i2c(master, sda=I2C_SDA, scl=I2C_SCL)
void test1()
{
unsigned int8 adc=1;
// set_adc_channel(0); // use a0
set_adc_channel(1); // use a1
delay_ms(100); // delay alittle for the adc to change
i2c_stop();
while(1)
{
adc=read_adc();
i2c_start(); // start
i2c_write(DAC_ADDRESS); // address of DAC
i2c_write(0b00000000); // command
i2c_write(adc); // value
i2c_stop(); // end
printf("adc=%u \r", adc);
}
}
void main()
{
// system setup
setup_adc_ports(AN0_TO_AN1|VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL|ADC_TAD_MUL_0);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
setup_low_volt_detect(FALSE);
enable_interrupts(GLOBAL);
printf("Mic test1 [%d]\r\n", restart_cause());
test1();
}
|
Any thoughts? Advice?
~Kam (^8* |
|
|
Ttelmah Guest
|
|
Posted: Wed Nov 01, 2006 3:06 am |
|
|
Obvious question. How is MCLR connected?.
Code 15, is 'MCLR from run'. The most likely reason for this to occur, is noise on the MCLR line, or on the supply rail itself. The obvious difference 'beyond' the act of writing to the DAC, is that this implies significant current will be drawn by the LM386, as it starts reproducing the sound. I'd suspect supply decoupling, or not enough pull up on the MCLR pin.
Best Wishes |
|
|
kam
Joined: 15 Jul 2005 Posts: 59
|
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Wed Nov 01, 2006 12:12 pm |
|
|
Can you find the schematic in a digital form and post it so we can explain what's going on and suggest a fix?
In the photo, all I see is one decoupling cap on the voltage regulator... and from what I can see it looks as though it is on the input side. Probably a pretty good indication that it is a decoupling problem.
John |
|
|
kam
Joined: 15 Jul 2005 Posts: 59
|
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Wed Nov 01, 2006 12:54 pm |
|
|
I'd try a large Cap on the output side of the regulator. Try a 1uF if that doesn't work try a 10uF... etc.
You may also want to try removing the BROWNOUT fuse from your code?
If you need more direction on the CAP issue post again with questions and they'll get answered.
John |
|
|
kam
Joined: 15 Jul 2005 Posts: 59
|
|
Posted: Wed Nov 01, 2006 1:04 pm |
|
|
John,
Yes, I will need help where to place the cap. Is this something on the Proto Board, or on my breadboard etc?
I uncommented the BROWNOUT fuse, it did help, but it still crashes...I'll attach a logic probe on the i2c side to see what's happening on that end...
Thanks!
~Kam (^8* |
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Wed Nov 01, 2006 1:20 pm |
|
|
OK.
We're trying to decide whether a part that you've added is causing a problem with dropping Vcc too low when it's working. The problem is, is that here isn't enough 'reserve' power available on the downstream side of the regulator (that little thingy with the heatsink on it.) So, if you add a big cap between Vcc and Gnd on your breadboard, it should help. It looks as though Vcc is 28, 29, or 30 and Gnd is 24, 25, 26, or 27. If you're using a polarized cap ensure that you get the polarity right.
If that doesn't work there are still a couple of other options.
BTW, every important part... PIC, 386, DAC, etc., should have a 0.1uF cap located as close to the supply pin as possible. Google 'power supply decoupling' and read about the importance. This is the most common cause of problems for those unfamiliar basic electronics.
John |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Nov 01, 2006 1:29 pm |
|
|
Quote: | enable_interrupts(GLOBAL); |
Why do you have interrupts enabled when you have no interrupt
service routine and you're not using interrupts ? |
|
|
Konrad
Joined: 15 Sep 2003 Posts: 34
|
|
|
kam
Joined: 15 Jul 2005 Posts: 59
|
|
Posted: Wed Nov 01, 2006 5:27 pm |
|
|
PCM programmer wrote: | Quote: | enable_interrupts(GLOBAL); |
Why do you have interrupts enabled when you have no interrupt
service routine and you're not using interrupts ? |
I had RTC...removed code but forgot to remove enable line... |
|
|
kam
Joined: 15 Jul 2005 Posts: 59
|
|
Posted: Wed Nov 01, 2006 5:51 pm |
|
|
Okay, here's the latest....
#1. I've added a 1uf 50v cap between gound and +5v
#2. I've removed some dead code (enable_int, setup_spi...)
#3. I've added the missing connection between max517 pin7 and +5v
Still no sound, it is alittle more stable, but still crashes.
Here's what I've found so far via debugging
#1. I can read the A/D just fine
#2. When I interact with the max, thats when the crash happens
#3. Using a logic analyizer, checked out the timing, I'm not to fast nor slow in communicating with the Max
Here is my layout (fixed?) for the max
Code: |
Pin 1 = Output to speaker
Pin 2 = Ground
Pin 3 = SCL plus 1k res to ground
Pin 4 = SDA plus 1k res to ground
Pin 5 = Ground
Pin 6 = Ground
Pin 7 = +5v
Pin 8 = +5v
|
Pic side
Code: |
#1. Added 1uf 50v cap between Ground and +5v
#2. Using C4 as SCL
#3. Using C5 as SDA
#4. Using CCS's i2c code, no custom bit banging routines
|
Here is my latest test code
Code: |
#include <18F4520.h>
#device *=16 adc=8
#case
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES HS //20mhz mode
//#fuses INTRC_IO // internal 8mhz osc
#FUSES NOPROTECT //Code not protected from reading
#FUSES BROWNOUT //Reset when brownout detected
#FUSES BORV25 //Brownout reset at 2.5V
#FUSES NOPUT //No Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES NOPBADEN //PORTB pins are configured as analog input channels on RESET
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#FUSES LPT1OSC //Timer1 configured for low-power operation
#FUSES MCLR //Master Clear pin enabled
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#use delay(clock=20000000)
#use rs232(baud=115200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#use standard_io(A)
#use standard_io(B)
#use standard_io(C)
#use standard_io(D)
#use standard_io(E)
#define I2C_SCL PIN_C4
#define I2C_SDA PIN_C5
#define DAC_ADDRESS 0b0101100 // 010=factory, 11=517 setting, 0=ad0 grd, 0=ad1 gnd
#use i2c(master, sda=I2C_SDA, scl=I2C_SCL)
#define NO 0
#define YES 1
void waitForButton()
{
printf("\r\n\r\nWaiting for keypress...");
while(input(PIN_B6));
printf("PRESSED\r\n");
}
void test1(int8 channel, int1 doI2C)
{
unsigned int8 adc=0;
output_low(PIN_B7);
set_adc_channel(channel);
delay_ms(100); // delay alittle for the adc to change
printf("\r\nChannel [%d]\r\n", channel);
// output_high(I2C_SCL);
// output_high(I2C_SDA);
if(doI2C)
{
i2c_stop();
}
waitForButton();
output_high(PIN_B7);
output_low(PIN_B7);
output_high(PIN_B7);
output_low(PIN_B7);
while(1)
{
adc=read_adc();
if(doI2C)
{
output_high(PIN_B7);
i2c_start(); // start
output_low(PIN_B7);
output_high(PIN_B7);
i2c_write(DAC_ADDRESS); // address of DAC
output_low(PIN_B7);
output_high(PIN_B7);
i2c_write(0b00000000); // command
output_low(PIN_B7);
output_high(PIN_B7);
i2c_write(adc); // value
output_low(PIN_B7);
output_high(PIN_B7);
i2c_stop(); // end
output_low(PIN_B7);
printf("Doing i2c adc=%u \r", adc);
}
else
{
printf("adc=%u \r", adc);
}
output_high(PIN_B7);
output_low(PIN_B7);
output_high(PIN_B7);
output_low(PIN_B7);
}
}
void main()
{
// system setup
setup_adc_ports(AN0_TO_AN1|VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL|ADC_TAD_MUL_0);
setup_psp(PSP_DISABLED);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
setup_low_volt_detect(FALSE);
printf("\r\n\r\nMic test1 [%d]\r\n", restart_cause());
test1(1, YES);
}
|
You'll ask why I'm playing with B7...I use that as a flag with the analyizer
Just so you have a complete understanding of my setup...
Let me ask a question about power for a sec. I have 2 power supplies that are used...actually 3, the 3rd being a wall wart for the Proto board.
Power supply #1 provides 5v
Power supply #2 provides 9v
Power supply #3 provides 5v (wall wart)
I have a breadboard that has 3 banana plugs, 1 BLACK and 2 RED. I have the 5v on one RED, and the 9v on the other RED, and BOTH grounds on the SAME BLACK. My understanding is that that's okay.
Well, there it is.
~Kam (^8* |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Nov 01, 2006 7:07 pm |
|
|
Quote: | Pin 3 = SCL plus 1k res to ground
Pin 4 = SDA plus 1k res to ground |
i2c requires pull-ups, not pull-downs.
Also, 1K is below the spec for the minimum resistance.
For a 5v circuit, the minimum is about 1.6K.
You could use 2.2K or 4.7K. |
|
|
kam
Joined: 15 Jul 2005 Posts: 59
|
|
Posted: Wed Nov 01, 2006 7:12 pm |
|
|
PCM programmer wrote: | Quote: | Pin 3 = SCL plus 1k res to ground
Pin 4 = SDA plus 1k res to ground |
i2c requires pull-ups, not pull-downs.
Also, 1K is below the spec for the minimum resistance.
For a 5v circuit, the minimum is about 1.6K.
You could use 2.2K or 4.7K. |
Typo on my end, they are 1k to +5v. I'll change them to 2.2k and see... |
|
|
kam
Joined: 15 Jul 2005 Posts: 59
|
|
Posted: Wed Nov 01, 2006 7:44 pm |
|
|
Well, the 2.2k did make it *more* stable, but I can still make it still crashes (reboots with error #15). Still no sound...
When I remove the read_adc, and just use a random adc, it does not crash, but no sounds either!
~Kam (^8* |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|