![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
cm279
Joined: 21 Nov 2010 Posts: 6
|
Reading inclinometer data |
Posted: Sun Nov 21, 2010 9:03 pm |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
gpsmikey
Joined: 16 Nov 2010 Posts: 588 Location: Kirkland, WA
|
|
Posted: Sun Nov 21, 2010 11:31 pm |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Mon Nov 22, 2010 8:56 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
pmuldoon
Joined: 26 Sep 2003 Posts: 218 Location: Northern Indiana
|
|
Posted: Mon Nov 22, 2010 11:15 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
cm279
Joined: 21 Nov 2010 Posts: 6
|
|
Posted: Tue Nov 23, 2010 7:08 pm |
|
|
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](images/smiles/icon_confused.gif) |
|
![](templates/subSilver/images/spacer.gif) |
cm279
Joined: 21 Nov 2010 Posts: 6
|
|
Posted: Tue Nov 23, 2010 7:23 pm |
|
|
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
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
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 |
|
![](templates/subSilver/images/spacer.gif) |
pmuldoon
Joined: 26 Sep 2003 Posts: 218 Location: Northern Indiana
|
|
Posted: Wed Nov 24, 2010 6:29 am |
|
|
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? |
|
![](templates/subSilver/images/spacer.gif) |
pmuldoon
Joined: 26 Sep 2003 Posts: 218 Location: Northern Indiana
|
|
Posted: Wed Nov 24, 2010 6:31 am |
|
|
also, flush your buffer before sending the "*P".
while(kbhit())getc();
You may have left over garbage in the uart. |
|
![](templates/subSilver/images/spacer.gif) |
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Wed Nov 24, 2010 12:31 pm |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|