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 CCS Technical Support

Having trouble using PIC16F1828 to communicate with ADS1255.
Goto page 1, 2, 3, 4  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
olet96



Joined: 09 Jul 2014
Posts: 16

View user's profile Send private message

PostPosted: Wed Jul 09, 2014 2:45 pm     Reply with quote

The VDD on the PIC is 5 volts and the ADC SPI is 5 volt tolerant. As far as the data I was looking at in the serial monitor goes I was printing the result data not the result2 data and when I was referring to PIC data I just meant the data I was sending to the serial monitor from the PIC. Here is the full schematic and the serial monitor data for both result and result2 result is the DATA and result2 is the DATA2. Also here is the changed code I've been running.
Code:

do
   {
      write_command(ADS1255_WAKEUP); //issue the wakeup command
      //now wait for DRDY, and read the data
      result=read_data();

      //Now put the chip to sleep
      write_command(ADS1255_STANDBY);
      output_high(CS); //and deselect the chip
      //here you should have a signed int32 reading in 'result'
      double result2=result*0.000000149011;

      printf("DATA:%ld\n\r",result);
      printf("DATA2:%1.8f\n\r",result2);     
      delay_ms(500);     
   }
   while (TRUE);
}

Full Schematic
Serial monitor[/code]
temtronic



Joined: 01 Jul 2010
Posts: 9614
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Jul 09, 2014 3:34 pm     Reply with quote

SPI tolerant means the ADC will run with 5V on it's pins, it's the data to PIC than can be the problem.
Others who use SPI devices will know but I think SPI pins are ST types , needing 80% VDD to be a logic high. If so 80% of 5V is 4 volts, and your ADC can't output more than say 3.6V.
All this is from memory, I'd have to DL your PICs datasheet to confirm my thinking but it would explain the trouble.
I've never liked the mixed power supply levels for projects, either all 5V or all 3V, as it greatly simplifies 'operational details'.

jay
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jul 09, 2014 4:39 pm     Reply with quote

I don't like your trouble-shooting methodology. I don't like your display
of raw data in decimal. It conceals too much. For example,

If I convert the first 5 samples from your decimal values to hex, I get this:
Code:

FD20
D620
D920
F220
E120

That's disturbing. It looks like 12-bit signed data, left-justified in a 16-bit
word. Not what would I expect from a 24-bit signed output device.

I would get rid of the whole Wheatstone bridge/ strain gauge apparatus
and peg the differential inputs with 0v and 5v (Ain0 and Ain1), and then
reverse them (5v and 0v on Ain0 and Ain1). Then run some conversions
and make sure you're getting the correct 24-bit results for those input voltages.

I would get rid of the floating point math entirely, until I nailed down the
correct operation of the device.

Also you are doing stuff like this (below), where you are declaring a
variable in the middle of code. That might work in C++, but CCS doesn't
explicitly say you can do it. You should declare variables at the beginning
of a function in CCS. Read this description:
http://stackoverflow.com/questions/8474100/where-you-can-and-cannot-declare-new-variables-in-c
CCS is not specified as C99 compatible. So you can't (safely) put
variable declarations in the middle of a block.
Quote:
do
{
write_command(ADS1255_WAKEUP); //issue the wakeup command
//now wait for DRDY, and read the data
result=read_data();

//Now put the chip to sleep
write_command(ADS1255_STANDBY);
output_high(CS); //and deselect the chip
//here you should have a signed int32 reading in 'result'
double result2=result*0.000000149011;




This part below in main() is potentially a problem. Selfcal takes a
specified time (dependent upon PGA and data rate) to complete.
You can put in a fixed delay or you can poll DRDY to check for completion.
You don't have that in your code. According to the ads1255 data sheet,
Quote:
The standby mode shuts down all of the analog circuitry
and most of the digital features.

It's possible that you are prematurely halting the Selfcal process before
it completes. I mean, if all analog circuits are shut down, how can it
do the Selfcal process ? So this part of the code should be looked at.

With the default data rate of 30,000 and the default PGA of 1, and a
clkin of 7.68 MHz, the calibration delay is 417us. So, you might just
try a fixed delay of 500us after sending the Selfcal command.
Or make it 1 ms, to be safe.
Quote:

void main()
{
signed int32 result;
setup_oscillator(OSC_INTRC|OSC_8MHZ|OSC_PLL_ON); //Shouldn't be needed but here 'in case'

output_high(CS); //ensure chip select starts high
//wait for supply to fully stabilise
delay_ms(500);
write_command(ADS1255_SELFCAL);
//self calibrate
write_command(ADS1255_STANDBY);
output_high(CS); //and deselect


--------------------------------------------
*** Important ***

Re-reading this thread, I just caught Temtronics point about SPI interface
voltage levels. You said this:
Quote:
The VDD on the PIC is 5 volts

That's a fail with the 3.3v digital interface on the ADS chip. The ADS chip
puts out a 3.3v signal which goes to the MISO pin on the PIC. But the
PIC, running SPI hardware at a +5v Vdd, requires a Vih of +4v on the
MISO pin. So it's not going to work. This is likely the major problem with
your project. It's probably why your data looks funky.

One solution is to run the SPI in software mode. Add FORCE_SW to the
#use spi() statement. Then the MISO pin becomes a TTL input pin
with a Vih requirement of +2.0v, and it works fine with the 3.3v signal
coming from the ADS chip. The 5v signals going from the PIC to the
ADS chip are OK, because the ADS chip's SPI interface is 5v tolerant.
Ttelmah



Joined: 11 Mar 2010
Posts: 20018

View user's profile Send private message

PostPosted: Thu Jul 10, 2014 2:03 am     Reply with quote

Yes.

'5v tolerant', means a pin on a low voltage device, can stand being driven by a 5v device without damage. It does not mean it can drive an input on a 5v device....

However one thing not asked, is why you are running the PIC off 5v?.
The PIC you are using supports operation up to 32MHz off 2.5v or higher. Your interface would suddenly become easy, if the PIC is running at 3.3v as well....
There are 3.3v versions of the MAX232 (Max 3232), so the whole circuit only needs one supply.
olet96



Joined: 09 Jul 2014
Posts: 16

View user's profile Send private message

PostPosted: Thu Jul 10, 2014 9:42 am     Reply with quote

I have changed my PIC VDD to 3.3v and also eliminated the Wheatstone Bridge by removing R4 and R5 and soldered wires to the inputs of the chip. I then was able to apply 0v and +3.3v to AIN0 and AIN1. In the code I added a 1ms delay after SELFCAL and removed the declared variable in the do while all together and began printing RAW DATA directly after it was red from the ADC. I then ran the code and switched the inputs from 0v-3.3v, 3.3v-0v, and 0v-0v and noticed I was getting some kind of change in the data but it didn't seem consistent and also only the 4 LSBs seemed to change.

Code:

#include <SPI.h> //include processor definition and register names

#use SPI(MASTER, SPI1, MODE=1, BITS=24, baud=2000000, STREAM=ADS) //main data transfer is 24bits
/* Chip needs the following wiring.
PIC   ADS
C0    18    SCL
C1    16    Data in to PIC
C2    17    Data out from PIC
B7    15    Data ready signal from ADS - put this on any pin you want
A7    14    Chip select to ADS

The specified SPI baud rate supported by the chip, is to 550KHz to 2.4Mhz. You need to be inside this.
Hence specifying 2Mhz.
*/
#define DRDY PIN_A4 //see above
#define CS PIN_A5

void write_command(int8 val)
{
   //single command write, leaving the chip still selected
   output_low(CS); //select chip
   spi_xfer(ADS,val,1); //Issue the command
}

signed int32 read_data()
{
   int32 value=0;
   //read 24bit result from chip - page 34 on data sheet
   //First wait for DRDY to drop
   while (input(DRDY)) ;
   //get here when DRDY drops   
   write_command(ADS1255_RDATA); //Issue the read command
   //Now need to read 24bit result
   value=spi_xfer(ADS,0,24); //read 24bits
   //now need to convert 24bit signed to 32bit
   output_high(CS); //deselect chip after read
   printf("RAW DATA: 0x%08lx \n\r",value);
   if (BIT_TEST(value,23))
      value=value | 0xFF000000;
   else
      value=value & 0x007FFFFF;
     //value=value/0.00000014;
   return value;
   
}   

void write_regs(int8 reg_no, int8 num_bytes, int8 * data_ptr)
{
   //generic function to write to one or more registers on the ADS
   //Command to chip is 0101 reg_num 0000 num_bytes, then the bytes to send
   output_low(CS); //select chip
   reg_no&=0xF; //ensure reg_no is 15 max
   num_bytes&=0xF; //same for number of bytes
   spi_xfer(ADS, 0x50 | reg_no, 1); //send first byte
   spi_xfer(ADS, (num_bytes-1), 1); //number of bytes to write less one
   //Now send the data
   while (num_bytes)
   {
      spi_xfer(ADS, data_ptr[num_bytes--], 1); //send each byte
   }
   output_high(CS); //and deselect
}
 

int8 read_reg(int8 reg_no)
{
   int8 rval;
   //generic read function just for a single register
   output_low(CS); //select chip
   reg_no&=0xF; //ensure reg_no is 15 max   
   spi_xfer(ADS, 0x10 | reg_no, 1); //send first byte
   spi_xfer(ADS, 0, 1); //read one byte
   rval=spi_xfer(ADS,0,1); //Clock data back
   output_high(CS);
   return rval;
}
   
void main()
{  //double result2;
   signed int32 result;
   //setup_oscillator(OSC_INTRC|OSC_8MHZ|OSC_PLL_ON); //Shouldn't be needed but here 'in case'

   output_high(CS); //ensure chip select starts high
   //wait for supply to fully stabilise
   delay_ms(500);
   write_command(ADS1255_SELFCAL);
   delay_ms(1);
   //self calibrate
   write_command(ADS1255_STANDBY);
   output_high(CS); //and deselect
   
 
   
   //Now the chip is here in 'standby' mode, so to perform a conversion, you have to wake it,
   //then wait for DRDY, before issuing RDATA, and reading the reply.
   do
   {
      write_command(ADS1255_WAKEUP); //issue the wakeup command
      //now wait for DRDY, and read the data
      //delay_ms(1);
      result=read_data();

      //Now put the chip to sleep
      write_command(ADS1255_STANDBY);
      output_high(CS); //and deselect the chip
      //here you should have a signed int32 reading in 'result'
       //result2=result*0.000000149011;

      //printf("DATA:%lX\n\r",result);
      //printf("DATA2:%lX\n\r",result2);     
      delay_ms(500);     
   }
   while (TRUE);
}


here is some of the values I have been getting from the serial monitor.

Code:

AIN0 at 3.3V, AIN1 at 0v.       

                                                                                                                                                                                                             
     RAW DATA: 0x6700e2ff                                                                                                                                                                                           
     RAW DATA: 0x6700e7ff                                                                                                                                                                                         
     RAW DATA: 0x6700d5ff                                                                                                                                                                                         
     RAW DATA: 0x6700e3ff                                                                                                                                                                                         
     RAW DATA: 0x6700f5ff                                                                                                                                                                                         
     RAW DATA: 0x6700feff                                                                                                                                                                                         
     RAW DATA: 0x6700d3ff                                                                                                                                                                                         
     RAW DATA: 0x6700ccff                                                                                                                                                                                         
     RAW DATA: 0x6700f4ff                                                                                                                                                                                         
     RAW DATA: 0x6700eaff                                                                                                                                                                                         
     RAW DATA: 0x6700feff                                                                                                                                                                                         
     RAW DATA: 0x6700eeff                                                                                                                                                                                         
     RAW DATA: 0x6700d2ff                                                                                                                                                                                         
     RAW DATA: 0x6700f0ff                                                                                                                                                                                         
     RAW DATA: 0x6700d3ff                                                                                                                                                                                         
     RAW DATA: 0x6700f1ff                                                                                                                                                                                         
     RAW DATA: 0x6700cfff                                                                                                                                                                                         
     RAW DATA: 0x6700f6ff

AIN0 at 0V, AIN1 at 3.3V


     RAW DATA: 0x6700c7ab                                                                                                                                                                                         
     RAW DATA: 0x6700f0ab                                                                                                                                                                                         
     RAW DATA: 0x6700f9ab                                                                                                                                                                                         
     RAW DATA: 0x6700c7ab                                                                                                                                                                                         
     RAW DATA: 0x6700d5ab                                                                                                                                                                                         
     RAW DATA: 0x6700edab                                                                                                                                                                                         
     RAW DATA: 0x6700f7ab                                                                                                                                                                                         
     RAW DATA: 0x6700feab                                                                                                                                                                                         
     RAW DATA: 0x6700f6ab                                                                                                                                                                                         
     RAW DATA: 0x6700deab                                                                                                                                                                                         
     RAW DATA: 0x6700fbab                                                                                                                                                                                         
     RAW DATA: 0x6700d0ab                                                                                                                                                                                         
     RAW DATA: 0x6700d3ab                                                                                                                                                                                         
     RAW DATA: 0x6700eaab                                                                                                                                                                                         
     RAW DATA: 0x6700efab                                                                                                                                                                                         
     RAW DATA: 0x6700e4ab                                                                                                                                                                                         
     RAW DATA: 0x6700edab                                                                                                                                                                                         
     RAW DATA: 0x6700f4ab

AIN0 at 0v, AIN1 at 0v

     RAW DATA: 0x6700de00                                                                                                                                                                                         
     RAW DATA: 0x6700f100                                                                                                                                                                                         
     RAW DATA: 0x6700e100                                                                                                                                                                                         
     RAW DATA: 0x6700fa00                                                                                                                                                                                         
     RAW DATA: 0x6700f500                                                                                                                                                                                         
     RAW DATA: 0x6700f000                                                                                                                                                                                         
     RAW DATA: 0x6700f800                                                                                                                                                                                         
     RAW DATA: 0x6700f600                                                                                                                                                                                         
     RAW DATA: 0x6700fe00                                                                                                                                                                                         
     RAW DATA: 0x6700ef00                                                                                                                                                                                         
     RAW DATA: 0x6700e300                                                                                                                                                                                         
     RAW DATA: 0x6700e900                                                                                                                                                                                         
     RAW DATA: 0x6700f900                                                                                                                                                                                         
     RAW DATA: 0x6700ef00                                                                                                                                                                                         
     RAW DATA: 0x6700ea00                                                                                                                                                                                         
     RAW DATA: 0x6700fc00                                                                                                                                                                                         
     RAW DATA: 0x6700ed00                                                                                                                                                                                         
     RAW DATA: 0x6700f600


 
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jul 10, 2014 10:15 am     Reply with quote

Can you post your CCS compiler version ? The version is given at the
top of the .LST file. It will be a number such as 5.026, or 4.141, etc.
olet96



Joined: 09 Jul 2014
Posts: 16

View user's profile Send private message

PostPosted: Thu Jul 10, 2014 10:22 am     Reply with quote

Version 5.026
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jul 10, 2014 2:03 pm     Reply with quote

Some tests need to be done.

1. You need to check all the connections on the ADS1255. Make sure
the reference voltages are not reversed on the two pins.

2. Check if you're getting \DRDY pulses from the ADS1255. Use your
scope. The \DRDY should periodically have low level pulses. It should
not be sitting at a continuous high level.

3. A short test program needs to be written, to see we can write to
and read from the GPIO Control Register in the ADS1255. If we can
write bytes such as 0x55 and 0xAA and read them back, then we
can be pretty sure we're successfully talking to the chip.

4. I think the driver code needs some modifications. The ads1255
data sheet says there should be a 't6' delay of 50 tclkin periods after
you send the read data command, and before you start to read data.
With an 8MHz clock, this delay would be 50/8MHz = 6 usec. The driver
code needs to be carefully reviewed, to make sure these delays are
inserted at the correct locations.

5. The driver code needs to be cleaned up. This line is sending a byte
but it has the 'bits' parameter set to 1.
Quote:
spi_xfer(ADS,val,1);

It doesn't matter with hardware SPI, because the compiler always sends
a complete byte anyway (8 bits). If software SPI was used, it would
matter. All lines where 'bits' = 1 should be changed to 'bits' = 8, just
for completeness.

6. SCLK at 2 MHz is right at the high limit for a CLKIN of 8 MHz.
It would be better to reduce it somewhat. See if it helps.

-----------
I have a question. Do you still have any interest in this project ?
If you lost interest, then I don't want to continue it. Also, when is
the project due ? When does the ads1255 have to be working ?
demedeiros



Joined: 27 Dec 2013
Posts: 74

View user's profile Send private message

PostPosted: Thu Jul 10, 2014 8:00 pm     Reply with quote

Hi PCM, i'm also working on this project. We are still actively pursuing this project, and are trying to determine if the ADS1255 is the ADC that we will move forward with. We dont have a defined time line, but would like to have this particular portion working as soon as we can.

Thank you for all of your help. It has been tremendously helpful! Olet96 is working on the short test program you have mentioned. Hopefully we'll have a test program written up tomorrow at some point.

Thanks again for all of your help!!!
olet96



Joined: 09 Jul 2014
Posts: 16

View user's profile Send private message

PostPosted: Fri Jul 11, 2014 12:22 pm     Reply with quote

I pieced together the read and write register codes from Ttelmah's original code to right to and then read back from registers on the ADC. However when im sending 0x55 and 0xAA to register 0x04 (GPIO) im reading back a 0x54 and a 0xA9, but when I tried writing a 0x01 and a 0xF0 it returned a 0x01 and a 0xF0 so im not sure whats going on exactly.

herei s the code im using
Code:

void write_regs(int8 reg_no, int8 num_bytes, int8 * data_ptr)
{
   //generic function to write to one or more registers on the ADS
   //Command to chip is 0101 reg_num 0000 num_bytes, then the bytes to send
  // output_low(CS); //select chip
   reg_no&=0xF; //ensure reg_no is 15 max
   num_bytes&=0xF; //same for number of bytes
   spi_xfer(ADS, 0x50 | reg_no, 1); //send first byte
   spi_xfer(ADS, (num_bytes-1), 1); //number of bytes to write less one
   printf("Data Ptr: 0x%X \n\r", data_ptr[0]);
   spi_xfer(ADS, data_ptr[0], 1); //send each byte
   }

int8 read_reg(int8 reg_no)
{
   int8 rval;
   //generic read function just for a single register
   reg_no&=0xF; //ensure reg_no is 15 max   
   spi_xfer(ADS, 0x10 | reg_no, 1); //send first byte
   spi_xfer(ADS, 0, 1); //read one byte
   delay_us(10);
   rval=spi_xfer(ADS,0,1); //Clock data back 
   return rval;
}

void main()
{
int val;
int val2;
int8 Data1[1];
int8 Data2[1];

Data1[0] = 0x01;
Data2[0] = 0xF0;

  output_high(CS); //ensure chip select starts high
  delay_ms(100);
 
    while(TRUE){
    output_low(CS);
    write_regs(0x04, 1, Data1);
    val = read_reg(0x04);
    output_high(CS);
    delay_ms(10);
   
    output_low(CS);
    write_regs(0x04, 1, Data2);
    val2 = read_reg(0x04);
    output_high(CS);
    delay_ms(10);
   
    printf("Val: 0x%X \n\r", val);
    printf("Val2: 0x%X \n\r", val2);

    delay_ms(1000);}
   
     }
olet96



Joined: 09 Jul 2014
Posts: 16

View user's profile Send private message

PostPosted: Fri Jul 11, 2014 1:10 pm     Reply with quote

Out of curiosity I tried writing to a different register (0x03)DRATE and was able to write a 0x55 and a 0xAA and return a 0x55 and 0xAA. So my thought is that when I'm writing to register (0x04)GPIO I'm reading back the input values because according to the data sheet "Reading these bits will show the state of the corresponding digital I/O pin, whether if the pin is configured as an
input or output by DIR3-DIR0. When the digital I/O pin is configured as an output by the DIR bit, writing to the
corresponding DIO bit will set the output state. When the digital I/O pin is configured as an input by the DIR bit,
writing to the corresponding DIO bit will have no effect. When DO/CLKOUT is configured as an output and
CLKOUT is enabled (using CLK1, CLK0 bits in the ADCON register), writing to DIO0 will have no effect."
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Jul 11, 2014 1:22 pm     Reply with quote

I think you're right. That wasn't a good register to do a R/W test on.
Since it works with the DRATE register, I think the basic SPI
communication is working.

I think the next step is to carefully review the code that reads A/D data.
There must be a problem in it somewhere, possibly with the required
delay times, such as delay 't6' in the ads1255 data sheet.
olet96



Joined: 09 Jul 2014
Posts: 16

View user's profile Send private message

PostPosted: Fri Jul 11, 2014 2:26 pm     Reply with quote

So we discovered that the code was dropping off the last byte of data by using a logic analyzer to look at the SPI bus. We were able to read each of the three bytes of data individually ( 8 bits at a time) then put them together into our desired 32 bit number and it seems to work now we just have to work on converting our unsigned 32 bit number to a signed 32 bit number and get it all to work with the strain gauge.


Here is the code we used
Code:

{
   unsigned int8 value=0;
   unsigned int8 value2=0;
   unsigned int8 value3=0;
   unsigned int32 Data = 0;
 
     //read 24bit result from chip - page 34 on data sheet
   //First wait for DRDY to drop
   while (input(DRDY)) ;
   //get here when DRDY drops   
   //write_command(ADS1255_RDATA); //Issue the read command
   spi_xfer(ADS, ADS1255_RDATA);
   delay_us(10);
   //Now need to read 24bit result
   value=spi_xfer(ADS,0,8); //read 8bits
   value2=spi_xfer(ADS,0,8); //read 8bits
   value3=spi_xfer(ADS,0,8); //read 8bits
   //now need to convert 24bit signed to 32bit
   output_high(CS); //deselect chip after read
   printf("RAW DATA: 0x%lX \n\r",value);
   printf("RAW DATA2: 0x%lX \n\r",value2);
   printf("RAW DATA3: 0x%lX \n\n\n\n\r",value3);
   Data = value;
   Data = Data<<8 | value2;
   Data = Data<<8 | value3;
   printf("Data is: 0x%lX:\n\n\n\n\n\r", Data);
   return value;
}


Thanks again for all of your help. It has been extremely helpful!!!!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Jul 11, 2014 2:55 pm     Reply with quote

That's good. For the record, can you post some of the 24 bit values
that you are reading now ? (in hex format). It's so we can compare it
to the previous bad data that you posted.
olet96



Joined: 09 Jul 2014
Posts: 16

View user's profile Send private message

PostPosted: Fri Jul 11, 2014 11:52 pm     Reply with quote

Sorry I just noticed your reply and im no longer at the shop until Monday morning however I will be sure to post some of the data then.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2, 3, 4  Next
Page 1 of 4

 
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