İvme ölçerden veri okumak..seri iletişimle

Başlatan Ksenon, 04 Ocak 2011, 17:24:23

Ksenon

Arkadaşlar merhaba
ivme sensöründen okuduğum bilgileri bilgisayara aktarıp kullanmam gerekiyor .
Kullandığım ivme sensörü  H48C3 ..
Sorun şu ki 3 eksende okuduğum bilgiler , 123 123 126 şeklinde geliyor bilgisayara.
Halbuki sonuncusu yani Z ekseninin sürekli G ye maruz kaldığını düşünürsek aralarında yüksek farklar olmalı . Bu arada PC'ye gönderirken aynı zamanda 3 farklı led'i de g değerlerini gözlemleyebileyim diye yakıp söndürüyorum . Oradan çıkan sonuç z eksenin 1g civarlarında olduğu.
Şimdi h48c3 'ün driver kodlarını koyuyorum.
/* H48C 3-Axis Accelerometer
     +----------+
 CLK | o*     o | Vdd (+5v)                Onboard MCP3204 12-bit ADC is used
     |   +--+   |                          to read the VRef,X-,Y-, and Z-axis
 DIO [ o |  | o | CS\                      outputs from H48C. Ref. volt. from
     |   +--+   |                          from H48C is 1.65 V (3.3/2).
 Vss | o      o | 0G (free-fall indicate)  1) read ref. volt.
     +----------+                          2) then then output ch.
3) g-force for the channel is calculated with this formula:
   G =[(axis - vref)/4095] * (3.3/0.3663) or G = (axis - vref) x 0.0022

 To allow the display of fractional g-force in the integer system we multiply
 0.0022 by 100 -- this will allow us work with g-force in 0.01g units.
 In order to simplify BS1 program design and optimize code space, g-force is
 "bumped" to 1000ths for display with the Print_Val subroutine. */

//-----[ I/O Definitions ]-------------------------------------------------
#define Dio       PIN_C4
#define Clk       PIN_C3
#define CS        PIN_C5

//-----[ Constants ]-------------------------------------------------------
#define  XAxis    0               //adc channels
#define  YAxis    1
#define  ZAxis    2
#define  VRef     3

//#define  Cnt2Mv   0xCE4C       //12 bit count to millivolts 0.80586 with **
#define Cnt2Mv 0.80586
//#define GfCnv     0x3852      // 12 bit count to mG-force 0.22 with **
#define GfCnv     0.22

/*
//-----[ Variables ]-------------------------------------------------------
mVolts   VAR Word    ' temp variable for milli-volts
gForce   VAR Word    ' temp variable for acceleration
*/

signed int16 rvCount;  // Reference voltage counter - 12bit ADC result

int16 Get_H48C(char axis);

int16 Get_H48C(char axis)
{
int i;
signed int16 fark;
int   h48c_cmd;
int16 h48c_data;

h48c_cmd=0b11011000;   //vref command
//printf("%d %d \n",h48c_cmd.code,h48c_command.addr);

output_low(Clk);

output_low(CS);
for(i=0;i<5;i++) {
output_bit(Dio,shift_left(&h48c_cmd,1,0));
output_bit(Clk,1);
delay_us(5);
output_bit(Clk,0);
delay_us(5);
}

h48c_data=0;
/* reads 16 bits from pin A1, each bit is read on a low to high on pin A2 */
for(i=0; i<13; i++) {
output_bit(Clk,1);
delay_us(5);
output_bit(Clk,0);
shift_left(&h48c_data,2,input(Dio));
}
output_high(CS);
rvCount=h48c_data;

if (axis==XAxis) h48c_cmd=0b11000000; //x axis command
if (axis==YAxis) h48c_cmd=0b11001000; //y axis command
if (axis==ZAxis) h48c_cmd=0b11010000; //z axis command

output_low(CS);
for(i=0;i<5;i++) {
output_bit(Dio,shift_left(&h48c_cmd,1,0));
output_bit(Clk,1);
delay_us(5);
output_bit(Clk,0);
delay_us(5);
}

h48c_data=0;
for(i=0; i<13; i++) {
output_bit(Clk,1);
delay_us(5);
output_bit(Clk,0);
shift_left(&h48c_data,2,input(Dio));
}
output_high(CS);
//axCount=h48c_data;

fark=h48c_data-rvCount;

return(fark);
}


Ana program:
#include "C:\accelerometer\son.h"
#include <H48C3.c>
int16 x_fark,y_fark,Z_fark;
int x_gForce,y_gForce,z_gForce;
void main()
{

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

   // TODO: USER CODE!!

while(1)
   {
   
x_fark=Get_H48C(0);y_fark=Get_H48C(1);z_fark=Get_H48C(2);
if (x_fark>32767) x_gForce=-1*((65536-x_fark)*.0022);
else x_gForce= x_fark*.0022;

if (y_fark>32767) y_gForce=-1*((65536-y_fark)*.0022);
else y_gForce=y_fark*.0022;

if (z_fark>32767) z_gForce=-1*((65536-z_fark)*.0022);
else z_gForce= z_fark*.0022;

putc(x_gForce);
delay_ms(800);
putc(y_gForce);
delay_ms(800);
putc(z_gForce);
delay_ms(800);

if (x_gForce>0.2)
{output_high(pin_B7);
delay_ms(200);
}
else output_low(pin_B7);

if (y_gForce>0.2)
{output_high(pin_B6);
 delay_ms(200);
}
else output_low(pin_B6);

if (1,1>z_gForce>0.9)
{output_high(pin_B5);
 delay_ms(200);
}
else output_low(pin_B5);
}

}



Acaba nerede yanlışlık yapıyorum eksenlerden gelen bilgileri nasıl sağlıklı okuyabilirim???
Teşekkürler

iyildirim

Öncelikle doğru bir şekilde ilerlemek, debug yapabilmek için seri portla ilgili sıkıntının olmadığını doğrula.
putc(x_gForce);
		delay_ms(800);
		putc(y_gForce);

satırlarında kullandığın gibi x_gForce değerini atıyorum 12345 gibi bir değere set edip ana döngünden önce PC ye gönder ve bunu PC  gördüğünden emin ol.
Microchip derleyicilerini kullandığım için kullandığın bu derleyici hakkında bilgim yok ve emin değilim ama genel olarak bildiğim putc sadece tek bir karakter yollayabilir.  Standart C için; kullandığın şekilde değişken içeriğinin seri porta basılması sorunlu. puts kullanabilir yada sıralı veya döngü içerisinde değişkeni oluşturan byte ları tek tek gönderebilirsin.  Bundan emin olduktan sonra varsa başka sorunlara bakılabilir.

Ksenon

putc komutuyla örneğin 32 gönderdim . PC tarafındaki terminal programında HEX 20 yani 32 'yi gördüm. Seri iletişimde bir sorun yok gibi görünüyor.

Ksenon

#3
Bu arada 32 sayısını herhangi bir değişkene bağlamadan gönderdiğimde dediğim gibi sonuç doğru ancak; x_gForce 'u 32 yapıp gönderdiğimde  Hex 84 yani 132 sayısını aldım PC tarafında!! Ayrıca kodda da gözüküyodur ama x_gForce değeri float olarak tanımlanmıştı.

iyildirim

Test için değeri 255 den büyük bir sayı kullanmalısın.
x_gForce gördüğüm kadarı ile int tanımlı.
Eğer float değişken kullanacaksan, PC tarafında ne kadar yeteneklisin bilmiyorum ama float değişkeni direkt byte lar şeklinde gönderip bunları bir de PC de değerini bulmaya çalışmak yerine

printf("%7.4\r\n",  x_gForce) veya 

char outbuf[10];
sprintf(outbuf, "%7.4\r\n",  x_gForce);
puts(outbuf);
şeklinde kullanabilirsin.