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

Reading inclinometer data

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



Joined: 21 Nov 2010
Posts: 6

View user's profile Send private message

Reading inclinometer data
PostPosted: Sun Nov 21, 2010 9:03 pm     Reply with quote

Hey folks, I have a 2-axis serial inclinometer sensor which I'm using for an angle measuring tool to read the angle data and display on an LCD display, similar to some of the new smart phone applications which can do this.

Looking at the datasheet for interfacing with the inclinometer, I'm not sure how to go about receiving the data sent to the PIC.
the datasheet is here :
http://www.leveldevelopments.com/PDF_Documents/LCP-45_Instructions.pdf

I have the TTL TX pin of the inclinometer connected to the PIC usart RX pin and the TTL RX pin connected to usart TX.

Using getc(..... and given the nature of the data output from the inclinometer as shown in the datasheet would it be possible to store bytes 1-5 in an array eg. Values[5] with bytes 1,2 (representing X angle data) 3,4 (representing Y angle data) and byte 5 signifying end of data.

Its hard to explain but easy to see in the datasheet at the bottom (HEX Output Format)
As long as the end result is the X and Y values stored as variables in the program I'd be very pleased.

Feel a bit bad asking such an odd question, just implementing this is proving to be difficult. Thanks in advance if anyone can help out
gpsmikey



Joined: 16 Nov 2010
Posts: 588
Location: Kirkland, WA

View user's profile Send private message

PostPosted: Sun Nov 21, 2010 11:31 pm     Reply with quote

One thing I see looking at the hex format is that while they say that 0x0A is used for the end of data, it looks like for small positive angles on the Y axis, it is also possible to get a 0x0A. I had been going to suggest setting a flag that data was complete when you see the 0x0A, however, if indeed you can get that with the conditions listed, sooner or later, it will bite you (Murphy watches over these things :-) ). Normally, you would have an index into the array you were putting the data in that incremented for each byte you received (with limit checking to make sure you don't run off the end of the array). When you see the 0x0a, you set a "valid" flag then reset the pointer to the start of the array. Anyway, that would be the way I would approach the problem. When you use the data, you could clear the "valid" flag and wait for the next time it became "valid again to indicate new data available.

mikey
_________________
mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Mon Nov 22, 2010 8:56 am     Reply with quote

To start in an easy way:
1- use the device in its default configuration, 9600 baud, 8N1, ASCII output format, continuous output.
2- in your hardware you need the device connected in the usart as you did.
3- in your code, use #INT_RDA and store the incoming characters in a buffer.
4- Inside the INT, to synchronize and store, use something like this:
Code:

#define BUFFER_SIZE 16
BYTE buffer[BUFFER_SIZE];

#int_rda
void serial_isr() {
int t;
 
   t=getc();
   if(t=='X')                   // begining of string
     { store_string=true;
        next_in=0;
     }
 
   if(store_string)   
     {buffer[next_in]=getc();
       next_in++;
       if(next_in>=BUFFER_SIZE )   // Buffer full !!
         {store_string=false;}
     }
}


When the buffer is full, the first task in main should be: disable_interrupts(INT_RDA) in order to get time
to show the received values in the LCD.
4- do a delay in order to refresh the display once a second.
5- after this, enable the INT_RDA interrupt again in order to get new data.
6- ......

Hope this help
pmuldoon



Joined: 26 Sep 2003
Posts: 218
Location: Northern Indiana

View user's profile Send private message

PostPosted: Mon Nov 22, 2010 11:15 am     Reply with quote

I would send the command *P to get a 5-byte response from the device when I needed it, putting it into an array as you said.

If I'm reading the datasheet correctly, worst case your data coming back could be:
0x000000000d
0x0000000d0d
0x000d00000d
0x000d000d0d

It is possible that even when the data is continuous, that the transmitter has a pause between data sets that could be identified by checking a timer value between INT_RDA's.
cm279



Joined: 21 Nov 2010
Posts: 6

View user's profile Send private message

PostPosted: Tue Nov 23, 2010 7:08 pm     Reply with quote

Been attempting to implement some of the ideas suggested here for a couple days.

The latter idea of using the hex data requested with *P has showin limited results.
The code I came up with is below although it really is just a test to see what I'm gettin back (which isnt much at all)

Code:
#include "16F690.h"
#device ADC=10
#fuses XT,NOPROTECT,NOWDT,INTRC,BROWNOUT,HS
#use delay(clock=4000000, INTERNAL)
#use rs232(baud=9600, xmit=PIN_B7, rcv=PIN_B5, ERRORS)
#include "flex_lcd.c"


int buffer[5];
int next_in;
int1 store_string;

void main()
{
lcd_init();                     // Initialise LCD
delay_ms(500);
puts("*9600B");
puts("*HE");

while(TRUE)
{
next_in=0;
store_string=1;
puts("*P");
   if((store_string==1)&&kbhit())
   {
   buffer[next_in]=getc();
    next_in++;
             if(next_in>=4 )   // Buffer full !!
            {
         store_string=0;
         }
   }
delay_ms(100);
lcd_putc("\fO/P: ");
printf(lcd_putc,"%u %u\n%u %u %u ",buffer[0],buffer[1],buffer[2],buffer[3],buffer[4]);     
}
}


On the LCD display i get the response:

O/P: 192 247
253 143 186


when i tilt the sensor in the X direction by around 30degrees or more the value changes instantly to 128. Tilting in the Y direction changes no values

I would expect to see a little different results to this
can you spot any errors in the code? I'm wondering if there are problems with the rs232 on either the sensor or the pic Confused
cm279



Joined: 21 Nov 2010
Posts: 6

View user's profile Send private message

PostPosted: Tue Nov 23, 2010 7:23 pm     Reply with quote

Had some much more varying results by simply using
Code:

puts("*P");
   if(kbhit()){
   buffer[0]=getc();
   buffer[1]=getc();
   buffer[2]=getc();
   buffer[3]=getc();
   buffer[4]=getc();
   }



buffer[0] changes alot with varying Y axis, looks linear Very Happy

buffer[1] is fixed at 10 ??? (the datasheet says byte 5 is always 0x0A??)

buffer[2] now reads 128 when tilted in the positive x direction and 192 when tilted in the negative x direction

buffer[3] changes alot with varying X axis, looks linear Very Happy

buffer[4] now reads 64 when tilted in the positive y direction and 0 when tilted in the negative y direction

So results are more promising, need some playing around with (figures represent the angle value x 10)

Just can't figure out why the value 10 is the second byte sent
pmuldoon



Joined: 26 Sep 2003
Posts: 218
Location: Northern Indiana

View user's profile Send private message

PostPosted: Wed Nov 24, 2010 6:29 am     Reply with quote

it sounds like you're not in sync with the data.
byte 5 MUST be 0x0a (10 decimal).

Code:
if(next_in>=4 )   // Buffer full !!

isn't that line only giving you 4 bytes of data?
What are you doing with the 5th byte?
Wouldn't it still be in the UART buffer when you come back around?
So you'd probably get a 0x0a that rotates thru the byte positions?
pmuldoon



Joined: 26 Sep 2003
Posts: 218
Location: Northern Indiana

View user's profile Send private message

PostPosted: Wed Nov 24, 2010 6:31 am     Reply with quote

also, flush your buffer before sending the "*P".

while(kbhit())getc();

You may have left over garbage in the uart.
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Wed Nov 24, 2010 12:31 pm     Reply with quote

You decide to run the device in this mode, as I told you it is not the easiest way to start.

Byte 5 0x0A = Line feed or newline, this is a EOM delimiter in the output string, hence it MUST be a constant.

Trying to interpret every single byte received and guessing its meaning it is not the way to decode. It is needed to do
a little math to convert the data output in a readable values:

Code:

long X_angle, Y_angle;
int8  X_sign, Y_sign;
char xsign, ysign;
int8 buffer[4];

void main()
{
   .........
   .........
   X_sign = (buffer[0]&0x40);
   Y_sign = (buffer[3]&0x40);
 
   if(X_sign) {xsign = '-';}
   else {xsign = '+';}
 
   if(Y_sign) {ysign = '-';}
   else {ysign = '+';}
   
   X_angle = make16(buffer[0],buffer[1]);
   Y_angle = make16(buffer[2],buffer[3]);

   lcd_putc("\fO/P: ");
   printf(lcd_putc,"X:%c%ld  Y:%c%ld\n", xsign, X_angle/10, ysign, Y_angle/10);

Not tested.

If you want to avoid this, just run the device in its default mode and you will get a full string of plain text that can be easily redirected.

Humberto
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