|
|
View previous topic :: View next topic |
Author |
Message |
olet96
Joined: 09 Jul 2014 Posts: 16
|
|
Posted: Thu Jul 10, 2014 10:22 am |
|
|
Version 5.026 |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jul 10, 2014 2:03 pm |
|
|
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: 71
|
|
Posted: Thu Jul 10, 2014 8:00 pm |
|
|
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
|
|
Posted: Fri Jul 11, 2014 12:22 pm |
|
|
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
|
|
Posted: Fri Jul 11, 2014 1:10 pm |
|
|
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
|
|
Posted: Fri Jul 11, 2014 1:22 pm |
|
|
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
|
|
Posted: Fri Jul 11, 2014 2:26 pm |
|
|
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
|
|
Posted: Fri Jul 11, 2014 2:55 pm |
|
|
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
|
|
Posted: Fri Jul 11, 2014 11:52 pm |
|
|
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. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Sat Jul 12, 2014 12:37 am |
|
|
Changing the last bit of a byte, suggests SPI reading on the wrong clock edge. However that it only does it when multi-byte transfers are used suggests the code is doing something very odd.
Try something very minor. Change the number of bits specified for the maximum transfer in the #USE SPI, to 32, rather than 24.
This is the 'maximum' that can be performed in a single transfer, and I'm wondering if the compiler gets in a twist with this being the odd '3 byte' size.
I've used multi byte transfers successfully with the #use syntax, without any problems but have always tended to set the transfer up to transfer an 'even byte' number of bits, and then used the lesser numbers in the actual transfer command.
Best Wishes |
|
|
demedeiros
Joined: 27 Dec 2013 Posts: 71
|
|
Posted: Mon Jul 14, 2014 5:52 am |
|
|
Ttelmah,
During testing it appeared that the program was dropping the last byte, not bit. For example, on our logic analyzer, we would see the following three bytes:
Code: | 0xB7 0x02 0x0C //These are made up values
|
When plotting "value" before conversion to 32bit signed, only the following would print:
You can see how the last byte (0x0C) has not been printed.
I am not sure if this is an issue with printf or how we are printing the value?
Hopefully that clears it up. Olet96 will post some actual values later on this morning.
Thanks to the both of you for the phenomenal help! |
|
|
olet96
Joined: 09 Jul 2014 Posts: 16
|
|
Posted: Mon Jul 14, 2014 7:51 am |
|
|
Here is some of the data we are getting from the PIC with 2.5v on the input of the ADC.
Code: |
Data is: 0x00BFB9F7:
Data is: 0x00BFB804:
Data is: 0x00BFB8B2:
Data is: 0x00BFB7AE:
Data is: 0x00BFBAB6:
Data is: 0x00BFB81E:
Data is: 0x00BFBA4C:
Data is: 0x00BFB9BF:
Data is: 0x00BFB70C:
Data is: 0x00BFB972:
Data is: 0x00BFB908:
Data is: 0x00BFB866:
Data is: 0x00BFB886:
Data is: 0x00BFB82E:
Data is: 0x00BFB8FD:
Data is: 0x00BFB8CC:
Data is: 0x00BFB833:
Data is: 0x00BFB8AF:
Data is: 0x00BFB898:
Data is: 0x00BFB92B:
Data is: 0x00BFB89A:
Data is: 0x00BFB9B2:
Data is: 0x00BFB84A:
Data is: 0x00BFB84A:
Data is: 0x00BFB889:
Data is: 0x00BFB804:
Data is: 0x00BFB947:
Data is: 0x00BFB830:
Data is: 0x00BFB8EB:
Data is: 0x00BFBAA8:
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Mon Jul 14, 2014 8:58 am |
|
|
All -ve....
You convert by looking at the 24th bit. If it's set, then you put 0xFF into the top byte. So the signed 32bit hex value (for the first number) is 0xFFBFB9F7. This was the extra code that I had. This gives (in decimal) -4212233. Almost exactly 1/2 scale -ve. Which 'input of the ADC'?. Remember it is the differential voltage it measures.
What have you got the gain set to?.
If this is '1', then it reads +/-5v, so if you have +2.5v on the -ve input, and 0v on the +ve input, then -ve 4194304, would be the expected reading. 17929 counts different, which is just 1/100th volt.
Looks a sensible reading if the voltages are set like this. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
olet96
Joined: 09 Jul 2014 Posts: 16
|
|
Posted: Tue Jul 15, 2014 3:39 pm |
|
|
So yesterday I had been trying to get the 24 complementary 2's converted to a signed 32 bit number and had noticed while looking at the RAW DATA that I wasn't getting what I expected to in hex with the 24 bit number I was getting from the ADC so today I tried doing a test and wrote to the register (0x01) MUX register and then set it to (0x88) which sets both inputs of the ADC to AINCOM which in this case we have tied to ground. However in doing this I noticed the RAW DATA would never go to (0x000000) demedeiros had recommended that I try changing the DRATE(0x03) register from the default 30,000SPS. So I tried setting it to 1,000SPS and noticed RAW DATA was closer to (0x000000) so I changed it to another data rate 100SPS just to see if it would change anything and RAW DATA jumped back up so at this point I'm pretty confused I have the code writing and reading back from registers so I believe its working I'm just unsure why I'm getting the results I am. I figure it would be best to make sure the ADC is functioning properly before I attempt to go any further with the conversions.
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
delay_us(1);
spi_xfer(ADS, (num_bytes-1), 1); //number of bytes to write less one
delay_us(1);
spi_xfer(ADS, data_ptr[0], 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, 2); //read one byte
delay_us(10);
rval=spi_xfer(ADS,0,1); //Clock data back
output_high(CS);
return rval;
}
void main()
{
int8 Setup1[1];
int8 Setup2[1];
int MUX_settings = 0;
int DRATE_settings = 0;
signed int32 result;
Setup1[0] = 0x88;
Setup2[0] = 0xA1;
//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_regs(0x01, 1, Setup1);
delay_us(10);
write_regs(0x03, 1, Setup2);
delay_us(10);
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;
MUX_settings = read_reg(0x01);
printf("MUX Settings is: 0x%X \n\r", MUX_settings);
delay_ms(1);
DRATE_settings = read_reg(0x03);
printf("DRATE Settings is: 0x%X \n\r", DRATE_settings);
printf("DATA:%ld\n\r",result);
delay_ms(500);
}
while (TRUE);
}
|
|
|
|
|
|
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
|