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

spi with SCA100T problem

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



Joined: 15 Aug 2012
Posts: 6

View user's profile Send private message

spi with SCA100T problem
PostPosted: Wed Jan 02, 2013 9:06 am     Reply with quote

Hi Everybody,

I am new user of CCS. I am trying to use SCA100T tilt sensor with SPI mode. But I couldn't get stable x and y angles.

SCA100T SPI interface document
http://www.muratamems.fi/sites/default/files/documents/tn15_spi_interface_specification.pdf

SCA100T datasheet
http://www.muratamems.fi/sites/default/files/documents/sca100t_inclinometer_datasheet_8261800b2_0.pdf

There is my code.
Code:

#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay (clock=20000000)
#include <stdio.h>
#include <math.h>
#include <lcd.c>
#include <stdlib.h>

// SPI modes.
#define SPI_MODE_0_0 0x4000
#define SPI_MODE_0_1 0x0000
#define SPI_MODE_1_0 0x0010
#define SPI_MODE_1_1 0x4010

// SCA100T pins.
#define SCA100T_CS  PIN_B0   // Chip select pin

//  SCA100T commands.
#define RWTR 0x08
#define MEAS 0x00
#define RDAX  0x10
#define RDAY  0x11

void spi_delay(int8 n){
while(n--);
}

void spi_start(void){
output_low(SCA100T_CS);
spi_delay(10);
}

void spi_stop(){
output_high(SCA100T_CS);
spi_delay(10);
}

void spi_writebyte(int8 data){
spi_start();
spi_write(data);
spi_stop();   
}

void spi_init(){
spi_start();
spi_writebyte(MEAS);
spi_stop();
}


void main()
{
   int8 msb_x,msb_y,lsb_x,lsb_y;
   int16 angle_x,angle_y;

   set_tris_A(0xFF); 
   set_tris_B(0x00);
   set_tris_C(0x91);
   set_tris_D(0x03);
   set_tris_E(0xFF);
   
   setup_spi(SPI_MASTER | SPI_MODE_0_0 | SPI_CLK_DIV_64);
   
   spi_init();
   
   lcd_init();
   printf(lcd_putc, "\f");      // Clear the LCD.
   printf(lcd_putc, "TILT ANGLE");
   delay_ms(2000);   
   
   while(1)
   {
   msb_x=0;
   lsb_x=0;
   angle_x=0;
   msb_y=0;
   lsb_y=0;
   angle_y=0;
   
   output_low(SCA100T_CS);   
   spi_write(RDAX);
   msb_x = spi_read(RDAX);
   lsb_x = spi_read(RDAX);
   angle_x = make16(msb_x, lsb_x);
   angle_x=angle_x & 0x07ff;
   output_high(SCA100T_CS);     
   
   printf(lcd_putc, "\f");    // Clear the LCD.
   printf(lcd_putc,"\fTILT_X:%lu",angle_x);
   delay_ms(3000);

   output_low(SCA100T_CS);   
   spi_write(RDAY);
   msb_y = spi_read(RDAY);
   lsb_y = spi_read(RDAY);
   angle_y = make16(msb_y, lsb_y);
   angle_y=angle_y & 0x07ff;
   output_high(SCA100T_CS);     
   
   printf(lcd_putc, "\f");    // Clear the LCD.
   printf(lcd_putc,"\fTILT_Y:%lu",angle_y);
   delay_ms(3000);
   }

}
temtronic



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

View user's profile Send private message

PostPosted: Wed Jan 02, 2013 10:17 am     Reply with quote

hmm...
'stable'

How 'stable' is the platform the sensor is on?
.ie: solid block of steel or just 'on the bench'?


Your program only reads once every 6 seconds.
.. I'd be reading/displaying data more often.


hth
jay
alkkla2000



Joined: 15 Aug 2012
Posts: 6

View user's profile Send private message

PostPosted: Wed Jan 02, 2013 3:14 pm     Reply with quote

temtronic wrote:
hmm...
'stable'

How 'stable' is the platform the sensor is on?
.ie: solid block of steel or just 'on the bench'?


Your program only reads once every 6 seconds.
.. I'd be reading/displaying data more often.


hth
jay


Dear temtronic,

I think stable means that, If I don't move(touch) the sensor, the sensor data doesn't change should not be a much changes. But on the code, I am getting different data(for exam, 26, 265,743,...) for each 6 seconds. 6 second is for tracing data changes. Of course, I will change the second. I think, I don't adjust read_spi time? But I am new user of CCS and I am student. I don't understand where is the problem. I will be very appreciate if somebody help me?

Regards
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jan 03, 2013 3:23 pm     Reply with quote

Did you buy a board with the SCA100T, or did you design and build
the board ? If you bought it, post a link to the website for the board.
If you built it, post a schematic of the board. Also, did you follow the
directions for a stable power supply and bypass caps on the SCA100T
as given in this appnote ?
http://www.muratamems.fi/sites/default/files/documents/tn5_supply_voltage_regulation.pdf
alkkla2000



Joined: 15 Aug 2012
Posts: 6

View user's profile Send private message

PostPosted: Fri Jan 04, 2013 3:39 am     Reply with quote

PCM programmer wrote:
Did you buy a board with the SCA100T, or did you design and build
the board ? If you bought it, post a link to the website for the board.
If you built it, post a schematic of the board. Also, did you follow the
directions for a stable power supply and bypass caps on the SCA100T
as given in this appnote ?
http://www.muratamems.fi/sites/default/files/documents/tn5_supply_voltage_regulation.pdf



Dear PCM Programmer,

I built my own circuit. I used AP1512A-33 adjustable DC-DC converter, and I have adjusted 5V for output. I added my circuit schema below link. I will be so appreciate if you/someone help me.

Regards
Andac
http://i45.tinypic.com/13z8weo.jpg
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Fri Jan 04, 2013 3:51 am     Reply with quote

You need to swap the SPI data signals.

The PIC is the master, the SCA100T is the slave. MISO (Master In Slave Out) from the SCA100T should go to SDI (Serial Data In, RC4) on the PIC. MOSI (Master Out Slave In) should go to SDO (Serial Data Out, RC5).

As you have wired it, both devices have their inputs floating. This means the PIC will read noise instead of real data. The outputs clash as they drive each other :-( This may not have caused any damage.

RF Developer
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri Jan 04, 2013 4:00 am     Reply with quote

Code:
// SPI modes.
#define SPI_MODE_0_0 0x4000
#define SPI_MODE_0_1 0x0000
#define SPI_MODE_1_0 0x0010
#define SPI_MODE_1_1 0x4010
Where did this list come from?
The hard coded values are dangerous because when you change to another processor or compiler version the values may be wrong.

I suggest you use the following code:
Code:
// SPI Mode | MOTOROLA | MICROCHIP | CCS                          | Clock line idle | Data clocked in at
//----------------------------------------------------------------|-----------------|-------------------
//          | CPOL CPHA|  CKP CKE  |                              |                 |
//    0     |  0    0  |   0   1   | SPI_L_TO_H | SPI_XMIT_L_TO_H | low             | low to high edge
//    1     |  0    1  |   0   0   | SPI_L_TO_H                   | low             | high to low edge
//    2     |  1    0  |   1   1   | SPI_H_TO_L                   | high            | high to low edge
//    3     |  1    1  |   1   0   | SPI_H_TO_L | SPI_XMIT_L_TO_H | high            | low to high edge
#define SPI_MODE_0  (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1  (SPI_L_TO_H)
#define SPI_MODE_2  (SPI_H_TO_L)
#define SPI_MODE_3  (SPI_H_TO_L | SPI_XMIT_L_TO_H)


// Example:
setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_64 );
alkkla2000



Joined: 15 Aug 2012
Posts: 6

View user's profile Send private message

PostPosted: Fri Jan 04, 2013 9:18 am     Reply with quote

Dear RF Developer,

Thank you for your correction. Also, I have connected according to your advice.

My connection is:
RC3------SCK
RC4------MISO
RC5------MOSI
RB0------CSB

But it is same. I can not get stable values.

Dear Ckielstra,

Thank you for your suggestion. I correct my code for your suggestion.
And I add RS232 connection and get angle values. I have added code and angle values below.
So I still have unstable x and y angle values. Please help me. I will be so appreciate...

My code is:
Code:

#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay (clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, stream=PIC)
#include <stdio.h>
#include <math.h>
#include <lcd.c>
#include <stdlib.h>

// SPI Mode | MOTOROLA | MICROCHIP | CCS                          | Clock line idle | Data clocked in at
//----------------------------------------------------------------|-----------------|-------------------
//          | CPOL CPHA|  CKP CKE  |                              |                 |
//    0     |  0    0  |   0   1   | SPI_L_TO_H | SPI_XMIT_L_TO_H | low             | low to high edge
//    1     |  0    1  |   0   0   | SPI_L_TO_H                   | low             | high to low edge
//    2     |  1    0  |   1   1   | SPI_H_TO_L                   | high            | high to low edge
//    3     |  1    1  |   1   0   | SPI_H_TO_L | SPI_XMIT_L_TO_H | high            | low to high edge
#define SPI_MODE_0  (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1  (SPI_L_TO_H)
#define SPI_MODE_2  (SPI_H_TO_L)
#define SPI_MODE_3  (SPI_H_TO_L | SPI_XMIT_L_TO_H)

// SCA100T pins.
#define SCA100T_CS  PIN_B0   // Chip select pin

//  SCA100T commands.
#define RWTR 0x08
#define MEAS 0x00
#define RDAX  0x10
#define RDAY  0x11

void spi_delay(int8 n){
while(n--);
}
void spi_start(void){
output_low(SCA100T_CS);
spi_delay(10);
}

void spi_stop(){
output_high(SCA100T_CS);
spi_delay(10);
}

void spi_writebyte(int8 data){
spi_start();
spi_write(data);
spi_stop();   
}

void spi_init(){
spi_start();
spi_writebyte(MEAS);
spi_stop();
}


void main()
{
   int8 msb_x,msb_y,lsb_x,lsb_y;
   int16 angle_x,angle_y;


   set_tris_A(0xFF); 
   set_tris_B(0x00);
   set_tris_C(0x91);
   set_tris_D(0x03);
   set_tris_E(0xFF);
   
   output_high(SCA100T_CS);
   setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_64 );
//   setup_spi(SPI_MASTER | SPI_MODE_0_0 | SPI_CLK_DIV_64);
   
   spi_init();
   
   lcd_init();
   printf(lcd_putc, "\f");      // Clear the LCD.
   printf(lcd_putc, "TILT ANGLE");
   delay_ms(3000);   

   printf("angle_x,angle_y\n\r");
   
   while(1)
   {

   msb_x=0;
   lsb_x=0;
   angle_x=0;
   msb_y=0;
   lsb_y=0;
   angle_y=0;
   
   output_low(SCA100T_CS);   
   spi_write(0x10);
   
   msb_x = spi_read(0x10);
   lsb_x = spi_read(0x10);
   output_high(SCA100T_CS);
   angle_x = make16(msb_x, lsb_x);
   angle_x=angle_x & 0x07ff;
   
   
   output_low(SCA100T_CS);   
   spi_write(0x11);
   
   msb_y = spi_read(0x11);
   lsb_y = spi_read(0x11);
   output_high(SCA100T_CS);
   angle_y = make16(msb_y, lsb_y);
   angle_y=angle_y & 0x07ff;
   
   printf(lcd_putc, "\f");    // Clear the LCD.
   printf(lcd_putc,"\fT_X:%lu",angle_x);
   printf(lcd_putc,"\nT_Y:%lu",angle_y);
   printf("%lu      %lu\n\r"angle_x,angle_y);
   delay_ms(2000);

   }
}

reading angle values via RS 232:
Code:
angle_x   angle_y
706       482
706       194
994       322
1506     1218
866       354
1922     1346
546      1666
706      1378
98       1538
1122      290
258      1506
1858     1890
1634      994
130      1954
1826     1026
1730      994
994       610
1346      386
1250      450
Ttelmah



Joined: 11 Mar 2010
Posts: 19388

View user's profile Send private message

PostPosted: Fri Jan 04, 2013 12:18 pm     Reply with quote

Several comments:
First, getting a really smooth analog supply from a switch mode inverter, is 'not easy'. You would be much better off, using the switcher to give something like (say) 7vDC, and then using a linear regulator to generate the supply for the circuit. I'd not be at all surprised to find you have significant HF noise on your supply.
Then you need to be really careful with your ground layout. Either use a ground plane (and even then be very careful to not have the actual placement of parts so that digital circuits draw power 'past' analog circuits on the plane), or use very careful connections back to a _single_ point at the supply.
Then consider having the supply at the inclinometer chip, fed _back_ to the Vref pin on the PIC, and run the PIC analog code using Vref, rather than Vdd. The chip's output is ratiometric to it's supply, so if the PIC's ADC is run from the same point, you have a better chance of success.

Best Wishes
temtronic



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

View user's profile Send private message

PostPosted: Fri Jan 04, 2013 12:35 pm     Reply with quote

everything T says and...

try a test using battery only power, see what results you get for 5-10 minutes

also

what are the connections between the sensor and the PIC? Same PCB ? unshielded cabling, individual wires ? What kind of decoupling ( caps,low pass filters,chokes ,???) What 'noise' generators are nearby? Cellphones, Wifi, welders,fishtank heaters,??????

I have LM35s all over the house here and get rock steady data 24/7 for the past 10 years
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Jan 04, 2013 2:23 pm     Reply with quote

There are several things wrong with your SPI code.

1. You are giving spi_read() a non-zero parameter. The SCA100T data
sheet doesn't show this. It shows that you should use a parameter of
0x00. This bug in your code probably doesn't affect the output, but you
should at least follow the data sheet. Change your X-coordinate code to this:
Quote:

spi_write(0x10);
msb_x = spi_read(0x00);
lsb_x = spi_read(0x00);

Change the Y code to this:
Quote:

spi_write(0x11);
msb_y = spi_read(0x00);
lsb_y = spi_read(0x00);


2. The SCA100T data sheet clearly says you need a minimum delay
of 150 us between SPI operations, which you don't have. You need to
add the delay statement shown below in bold. (To be extra safe you
could make it be longer, such as 200 us):
Quote:

output_low(SCA100T_CS);
spi_write(0x10);

msb_x = spi_read(0x00);
lsb_x = spi_read(0x00);
output_high(SCA100T_CS);
angle_x = make16(msb_x, lsb_x);
angle_x=angle_x & 0x07ff;

delay_us(150);

output_low(SCA100T_CS);
spi_write(0x11);

msb_y = spi_read(0x00);
lsb_y = spi_read(0x00);
output_high(SCA100T_CS);


3. You are mis-interpreting the output data. You are treating the data
as if it's right-justified in a 16-bit word. But the SCA100T data sheet
shows that it's left justified. So with your mask of 0x7FF, you are
looking at only the bottom 6 bits (shifted left by 5 bits), which would
certainly fluctuate more than the whole 11-bit value, since those are the
LSB bits.

Since the SCA100T outputs 11-bits of data, you need to right-shift it
by 5 bits to make it be right-justified. See the lines shown in bold below:
Quote:

output_low(SCA100T_CS);
spi_write(0x10);

msb_x = spi_read(0x00);
lsb_x = spi_read(0x00);
output_high(SCA100T_CS);
angle_x = make16(msb_x, lsb_x);

angle_x >>= 5; // Right-justify the output word.
// angle_x=angle_x & 0x07ff;

delay_us(150);

output_low(SCA100T_CS);
spi_write(0x11);

msb_y = spi_read(0x00);
lsb_y = spi_read(0x00);
output_high(SCA100T_CS);
angle_y = make16(msb_y, lsb_y);

angle_y >>= 5; // Right-justify the output word.
// angle_y=angle_y & 0x07ff;


Even after you do all of this, the output will still probably fluctuate
somewhat. You can look at averaging algorithms in the forum archives.
Sherpa Doug was always promoting his Olympic Scoring algorithm.
Other people have posted their smoothing functions as well.


Also, in your schematic you have mis-labeled the PIC's RC4 and RC5
signals. This is in the lower right corner of your schematic. RC4 is SDI
so it must be MISO. RC5 is SDO, so it must be MOSI.
alkkla2000



Joined: 15 Aug 2012
Posts: 6

View user's profile Send private message

PostPosted: Mon Jan 07, 2013 1:48 am     Reply with quote

Dear Temtronic and Ttelmah,

Thank you for your suggestion. I am using breadboard, and I will consider your suggestion.

Dear PCM programmer,

Thank you so much for your correction of my code. I control the datasheet again and I realized my mistakes. I couldn't see delay time. Thank you so much for your remark.

And I don't exactly know what is right & left justified. I need to read some documents. Thank you for your all information again. I am so appreciate for your help. Data is fluctuating and I will look averaging algorithms.

Regards
Ttelmah



Joined: 11 Mar 2010
Posts: 19388

View user's profile Send private message

PostPosted: Mon Jan 07, 2013 2:11 am     Reply with quote

Ouch.
Switch mode inverter on breadboard. Read the data sheet for the inverter. Look particularly at their comments about board layout. Can a breadboard do this?...
Probably at least 50% of the problem.
Go to a linear regulator, and apply the code fixes from PCM programmer, and you have a good chance things will change. Smile

Best Wishes
alkkla2000



Joined: 15 Aug 2012
Posts: 6

View user's profile Send private message

PostPosted: Mon Jan 07, 2013 2:39 am     Reply with quote

Dear Ttelmah,

I agree with you. I will do my layout board. And I thank you again for all suggestion.

Regards
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