CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Read multiple channels MCP3424

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Comiter



Joined: 26 May 2010
Posts: 2

View user's profile Send private message

Read multiple channels MCP3424
PostPosted: Sun Oct 10, 2010 3:02 pm     Reply with quote

Hi all!
I'm trying to read from different channels on a microchip MCP3424 ADC.
My problem are that I can't change between channels. When I read from only one channel (that is, compiles the SW with the other readings commented out), it works fine with different channels (only one at the time though). I've tried to read the channels in sequence, based on Timer1 interrupt, so that I read each channel once every 4th second, still the same result. The issue is that (when trying to read all channels) it reads the first value (the first time it enters the while loop) when the software runs, and that's it.

The code is found below:
Code:

#include <18F87J11.h>

#device adc=10
#FUSES NOWDT
//#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale // Ca hvert 2 sec.
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPROTECT                //Code not protected from reading           


#use delay(clock=8000830)
#use i2c(Master, scl=PIN_C3,sda=PIN_C4,slow) //#use i2c(i2c1,MASTER,SCL=Device_SCL, SDA=Device_SDA,FAST=400000, FORCE_HW)//#use i2c(master, sda=PIN_J1, scl=PIN_J0,SLOW)
#use rs232(baud=19200, Parity=N, bits=8, stop=1, UART2)

#define ADCRead 0xDB
#define ADCWrite 0xDA

struct Verdier
{
   float battSpenning;
   float lading_Sol;
   float lading_Vind;
   float stromforbruk;
   float alarmtimer;
   int1 LavSpenningAlarm,LightOn;   
   
   //Variabler for display navigering
   // Page 0 = Standard display
   // Page 1 =
   // Page 2 =
   // Page 3 =
   int pageNumber;
   
   int WebastoPaa;
   
   
}maaling;

int1 skrivLcd,kalkuler, LCDInit;


#int_RTCC
void  RTCC_isr(void)
{
//   output_toggle(PIN_B6);
   RTCISRTeller1++;
   RTCISRTeller2++;
   
   if(RTCISRTeller1 > 3){
      RTCISRTeller1 =0;
      skrivLCD = 1;
   }
   
   if(RTCISRTeller2>200){
      RTCISRTeller2 = 0;
      LCDInit = 1;
   }
   
   kalkuler = 1;

}


float ReadADC(int channel){
   int8 HighBuffer,LowBuffer,Config,ack=0;
   signed int16 value=0;
            
   switch(channel){
      case 1:   i2c_start();
            ack = i2c_write(ADCWrite);  // Adress factory set at 1101 = 0xD
            if(ack)
               printf("Feil!!");   
            i2c_write(0x8B); //16bit mode, Gain = 8, one shot samplemode   
            i2c_stop();   
            delay_ms(5);// Wait for conversion to be finnished in oneshot mode
            i2c_start();
            i2c_write(ADCRead); //Set Read/Write to 1 for read
            HighBuffer = i2c_read(1);
            LowBuffer = i2c_read(1);
            Config = i2c_read(1);
            printf("Config: %x\n\r",Config);
            while((Config&0x80)==1){Config = i2c_read(1);}; // Wait for finnish
            i2c_stop();            // When conversion finnished
            delay_ms(5);
            i2c_start();         // Read new value
            i2c_write(ADCRead); //Set Read/Write to 1 for read
            HighBuffer = i2c_read(1);
            LowBuffer = i2c_read(1);
            Config = i2c_read(0);
            i2c_stop();   
            delay_ms(5);
            Value = make16(HighBuffer,LowBuffer);
            return (float) Value;
            break;

      case 2:   i2c_start();
            i2c_write(ADCWrite);  // Adress factory set at 1101 = 0xD
            i2c_write(0xAB); //16bit mode, Gain = 8, one shot samplemode   
            i2c_stop();   
            delay_ms(5);
            i2c_start();   
            i2c_write(ADCRead); //Set Read/Write to 1 for read
            HighBuffer = i2c_read(1);
            LowBuffer = i2c_read(1);
            Config = i2c_read(1);
            printf("Config: %x\n\r",Config);
            while((Config&0x80)==1){Config = i2c_read(1);}; // Wait for finnish
            i2c_stop();            // When conversion finnished
            delay_ms(5);
            i2c_start();         // Read new value
            i2c_write(ADCRead); //Set Read/Write to 1 for read
            HighBuffer = i2c_read(1);
            LowBuffer = i2c_read(1);
            Config = i2c_read(0);
            i2c_stop();   
            delay_ms(5);
            Value = make16(HighBuffer,LowBuffer);
            return (float) Value;
            break;

      case 3:   i2c_start();
            i2c_write(ADCWrite);  // Adress factory set at 1101 = 0xD
            i2c_write(0xCB); //16bit mode, Gain = 8, one shot samplemode   
            i2c_stop();   
            delay_ms(5);
            i2c_start();   
            i2c_write(ADCRead); //Set Read/Write to 1 for read
            HighBuffer = i2c_read(1);
            LowBuffer = i2c_read(1);
            Config = i2c_read(1);
            printf("Config: %x\n\r",Config);
            while((Config&0x80)==1){Config = i2c_read(1);}; // Wait for finnish
            i2c_stop();            // When conversion finnished
            delay_ms(5);
            i2c_start();         // Read new value
            i2c_write(ADCRead); //Set Read/Write to 1 for read
            HighBuffer = i2c_read(1);
            LowBuffer = i2c_read(1);
            Config = i2c_read(0);
            i2c_stop();
            delay_ms(5);
            Value = make16(HighBuffer,LowBuffer);
            return (float) Value;

            break;

      case 4:   i2c_start();
            i2c_write(ADCWrite);  // Adress factory set at 1101 = 0xD
            ack=i2c_write(0xE8); //16bit mode, Gain = 1, one shot samplemode   
            i2c_stop();
            delay_ms(5);
            i2c_start();   
            i2c_write(ADCRead); //Set Read/Write to 1 for read
            HighBuffer = i2c_read(1);
            LowBuffer = i2c_read(1);
            Config = i2c_read(1);
            printf("Config: %x\n\r",Config);
            while((Config&0x80)==1){Config = i2c_read(1);}; // Wait for finnish
            i2c_stop();            // When conversion finnished
            delay_ms(5);
            i2c_start();         // Read new value
            i2c_write(ADCRead); //Set Read/Write to 1 for read
            HighBuffer = i2c_read(1);
            LowBuffer = i2c_read(1);
            Config = i2c_read(0);
            i2c_stop();
            delay_ms(5);
            
            Value = make16(HighBuffer,LowBuffer);
            return (float) Value;
            break;

      default: break;      
            
   }
   
}   


void lesLadingSol(struct Verdier *maaling){
   maaling->lading_Sol = ReadADC(1);
   maaling->lading_Sol = maaling->lading_Sol*0.0000078125;
   maaling->lading_Sol = maaling->lading_Sol/0.00375;
//   sol = spenning/0.00375;   
}

void lesForbruk(struct Verdier *maaling){
   maaling->stromforbruk = ReadADC(2);
   maaling->stromforbruk = maaling->stromforbruk*0.0000078125;
   maaling->stromforbruk = maaling->stromforbruk/0.00375;
//   forbruk = spenning/0.00375;
   
}

void lesLadingVind(struct Verdier *maaling){
   maaling->lading_Vind = ReadADC(3);
   maaling->lading_Vind = maaling->lading_Vind*0.0000078125;
   maaling->lading_Vind = maaling->lading_Vind/0.00375;
//   vind = spenning/0.00375;
}   

void LesBatteriSpenning(struct Verdier *maaling ){
   maaling->battSpenning = ReadADC(4);
   maaling->battSpenning = maaling->battSpenning*0.0000625;
   maaling->battSpenning = maaling->battSpenning*-7.83;
//   batteri = spenning*-7.83;
}   


void main()
{

   setup_oscillator(OSC_8MHZ|OSC_NORMAL|OSC_IDLE_MODE|OSC_PLL_OFF);
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_CLOCK_INTERNAL|ADC_TAD_MUL_2);
   setup_psp(PMP_DISABLED);
//   setup_spi(SPI_SS_DISABLED);
//   setup_spi2(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_32);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
   setup_timer_2(T2_DIV_BY_16,255,16);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_timer_4(T4_DISABLED,0,1);
   setup_comparator(FALSE);// This device COMP currently not supported by the PICWizard
   enable_interrupts(INT_RTCC);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(INT_TIMER2);
   enable_interrupts(INT_RDA);
   enable_interrupts(INT_RDA2);
   enable_interrupts(GLOBAL);
   i2cscan();
   //General call to latch in address on adc.   
    i2c_start();
   i2c_write(0x00);   
   i2c_write(0x04);     
   i2c_stop();

   lcd_init();
   initVars(&maaling);
 
    BackLightControl(On);
 
    Delay_ms(2000);
 
    BackLightControl(Off);
    
    setup_wdt(WDT_OFF);


   while(1){
      BackLightControl(On);
      if(kalkuler){
         kalkuler = 0;
         lesLadingSol(&maaling);
         lesForbruk(&maaling);
         lesLadingVind(&maaling);
         LesBatteriSpenning(&maaling);

         //batteriAlarm(&maaling);
         output_toggle(PIN_B6);
         
      }
      
      if(LCDInit){
         LCDInit = 0;
         lcd_init();
         lcd_gotoxy(1,1);
         printf(lcd_putc,"Batterisp:   %f V",maaling.BattSpenning);
         lcd_gotoxy(1,2);
         printf(lcd_putc,"Forbruk:     %f A",maaling.stromforbruk);
         lcd_gotoxy(1,3);
         printf(lcd_putc,"Lading Sol:  %f A",maaling.lading_Sol);
         lcd_gotoxy(1,4);
         printf(lcd_putc,"Lading Vind: %f A",maaling.lading_Vind);         
      }   
      
      if(skrivLCD){
         skrivLCD = 0;
         lcd_gotoxy(1,1);
         printf(lcd_putc,"Batterisp:   %f V",maaling.BattSpenning);
         lcd_gotoxy(1,2);
         printf(lcd_putc,"Forbruk:     %f A",maaling.stromforbruk);
         lcd_gotoxy(1,3);
         printf(lcd_putc,"Lading Sol:  %f A",maaling.lading_Sol);
         lcd_gotoxy(1,4);
         printf(lcd_putc,"Lading Vind: %f A",maaling.lading_Vind);
         printf("BatteriSp:%f V\n\r",maaling.BattSpenning);
         printf("Strømforbruk:%f A\n\r",maaling.stromforbruk);
         printf("Lading Sol:%f A\n\r",maaling.lading_Sol);
         printf("Lading Vind:%f A\n\n\r",maaling.lading_Vind);

      }
   
   }   

}

Any help are appreciated.

- Comiter
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Oct 10, 2010 5:56 pm     Reply with quote

The MCP3424 data sheet says this, on the upper left side of page 19:
Quote:

When the Master finds the RDY bit is cleared, it can send a
not-acknowledge (NAK) bit and a stop bit to exit the current
read operation and send a new read command for the latest
conversion data.

Your code is missing the part shown above in bold. You need to fix this
in all 4 cases, by adding the line shown in bold below to each case.
Quote:

case 1: i2c_start();
ack = i2c_write(ADCWrite); // Adress factory set at 1101 = 0xD
if(ack)
printf("Feil!!");
i2c_write(0x8B); //16bit mode, Gain = 8, one shot samplemode
i2c_stop();
delay_ms(5);// Wait for conversion to be finnished in oneshot mode
i2c_start();
i2c_write(ADCRead); //Set Read/Write to 1 for read
HighBuffer = i2c_read(1);
LowBuffer = i2c_read(1);
Config = i2c_read(1);
printf("Config: %x\n\r",Config);
while((Config&0x80)==1){Config = i2c_read(1);};
Config = i2c_read(0); // Send a NACK to exit read operation
i2c_stop(); // When conversion finnished

delay_ms(5);

i2c_start(); // Read new value
i2c_write(ADCRead); //Set Read/Write to 1 for read
HighBuffer = i2c_read(1);
LowBuffer = i2c_read(1);
Config = i2c_read(0);
i2c_stop();
delay_ms(5);
Value = make16(HighBuffer,LowBuffer);
return (float) Value;
break;


Also, the test in the statement below isn't correct:
Quote:

while((Config&0x80)==1){Config = i2c_read(1);};

If you do a bitwise AND on 'Config' and 0x80, you will get either 0x80
or 0x00. Neither of those results will ever be equal to 1. So as written,
your test will always fail and will drop out of the loop on the first pass.
You need to change it to this:
Code:
while(Config&0x80){Config = i2c_read(1);};

Now the test will be evaluated for True/False, and it will behave the way
that you want. You need to fix this in all 4 cases, also.

There might be other problems but I didn't look at it any more than this.
Comiter



Joined: 26 May 2010
Posts: 2

View user's profile Send private message

PostPosted: Mon Oct 11, 2010 12:25 am     Reply with quote

Hi PCM programmer,
thank you very much for the swift reply!

I knew it was something in the datasheet I've missed! I'll do the changes you pointed out when I arrive back from work.

Also, I'll try to tidy up the code a bit, and remove all the delays (as these were added to investigate if there were timing issues going on).

- Comiter
khwoo



Joined: 26 May 2009
Posts: 12

View user's profile Send private message

MCP3424 read 18 bits and send to PIC24HJ128GP206
PostPosted: Wed Oct 19, 2011 8:37 pm     Reply with quote

I saw the previous reply on the above topic.

And now I am doing the same thing which is
- to issue address/commend to MCP3424
- how the 18 bit data is read from MCP3424 to PIC24HJ128GP206

Same device - MCP3424 but PIC not the same.

Hope to get some guide on modifying the code above.

Thank you
khwoo



Joined: 26 May 2009
Posts: 12

View user's profile Send private message

Re: Read multiple channels MCP3424
PostPosted: Sun Oct 23, 2011 7:13 pm     Reply with quote

Can the above code be applicable to PIC24HJ128GP206?

Does the above code allow MCP3424 to read 18 bits through 4 channels / Microchip PIC store the data in the registers?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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