cancel
Showing results for 
Search instead for 
Did you mean: 

Code Examples

MotooTanaka
Esteemed Contributor

KXSC7_S.jpg

近年まれにみる大型ゴールデンウィークも今日で終わりということで、

明日からの社会復帰にそなえたリハビリも兼ねて秋月で買ってきたアナログ出力の加速度センサをTSoCで動かしてみました。

センサ (KXSC7-2050 モジュール)

http://akizukidenshi.com/catalog/g/gK-07243/

写真ではジャンパ線が飛び回っていますが、3端子レギュレータで KitProg からの 5V を 3.3V に落とす以外では、

センサのモード設定用が殆どでした。

Schematic

schematic.JPG

取り合えず出力を TeraTerm で見てみると

000-TeraTerm-log.JPG

こんな感じで、ちょっと面白くありません。

そこでシリアルプロットというソフトにつないで表示させてみると

シリアルプロット

https://hackaday.io/project/5334-serialplot-realtime-plotting-software

001-Serial-plot.JPG

x, y, z それぞれ頂点と底辺に来るように基板を動かしてみたところ、

だいたい、1g で 900 くらい、-1g で 400 くらいの数字に読めているようでした。

センサの出力がアナログなので、ADCで受けてやると下記の様に50行程度で書けてしまうというプログラムの書きやすいセンサでした。

※これでリハビリになったのかは、疑問ですが・・・

main.c

===================

#include "project.h"

#include "stdio.h"

char str[128] ; /* print buffer */

void print(char *str)

{

    UART_UartPutString(str) ;

}

void init_hardware(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */

  

    UART_Start() ;

    ADC_Start() ;

}

void splash(void)

{

    sprintf(str, "KXSC7 Test Program (%s %s)\n", __DATE__, __TIME__) ;

    print(str) ;

}

void measure(int16_t *x, int16_t *y, int16_t *z)

{

    ADC_StartConvert() ;

    ADC_IsEndConversion(ADC_WAIT_FOR_RESULT) ;

    *x = ADC_GetResult16(0) ;

    *y = ADC_GetResult16(1) ;

    *z = ADC_GetResult16(2) ;

}

int main(void)

{

    int16_t x, y, z ;

  

    init_hardware() ;

  

    splash() ;

  

    print("    X,     Y,     Z\n") ;

    for(;;)

    {

        measure(&x, &y, &z) ;

        sprintf(str, "%5d, %5d, %5d\n", x, y, z) ;

        print(str) ;

        CyDelay(100) ;

    }

}

===================

moto

0 Likes
1 Reply
MotooTanaka
Esteemed Contributor

値が900から、400では分かりにくい! とのご指摘をいただきました。

確かにそうだよね〜、と、それでは机に水平に置いた状態の Z を1.0 g,

裏返して置いた状態を -1.0 として一次関数補間をさせて見ました。

serial-plot.JPG

これなら、読取り値が殆ど実際のGの値になりますね。

センサ自体も±2g 対応なので、センサを動かしたときに

1g以上の値が出ているのもグッドです。

回路は比較的単純なのに、ブレッドボード上で長めのジャンパを使って接続していると

最初の写真の様に煩雑な感じになってしまったので、知人にお願いして基板を作ってもらいました。

IMG_3590_SS.jpg

さっぱりして良い感じですね。(^_^)V

main.c

==================

#include "project.h"

#include "stdio.h"

int16_t pos_1_g = 980 ;     /* read value at  1.0 g */

int16_t neg_1_g = 425 ;     /* read value at -1.0 g */

float   ramp    = 0.0036 ;

float   offset  = -2.5315 ;

char str[128] ; /* print buffer */

void print(char *str)

{

    UART_UartPutString(str) ;

}

void cal_ramp_and_offset(int16_t pos_1_g, int16_t neg_1_g, float *ramp, float *offset)

{

    if (pos_1_g == neg_1_g) {

        return ;

    }

    *ramp = 2.0 / (float)(pos_1_g - neg_1_g) ;

    *offset = -1.0 - (float)(*ramp) * neg_1_g ;

}

void init_hardware(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */

   

    UART_Start() ;

    ADC_Start() ;

}

void splash(void)

{

    sprintf(str, "KXSC7 Test Program (%s %s)\n", __DATE__, __TIME__) ;

    print(str) ;

}

float calc_g(int16_t value)

{

    float g ;

    g = ramp * (float)value + offset ;

    return( g ) ;

}

void measure(int16_t *x, int16_t *y, int16_t *z)

{

    ADC_StartConvert() ;

    ADC_IsEndConversion(ADC_WAIT_FOR_RESULT) ;

    *x = ADC_GetResult16(0) ;

    *y = ADC_GetResult16(1) ;

    *z = ADC_GetResult16(2) ;

}

void print_float(float value)

{

    char *format = "%d.%04d" ;

    if (value < 0.0) {

        value *= -1.0 ;

        format = "-%d.%04d" ;

    }

    sprintf(str, format, (int)value, (int)(value * 10000) % 10000) ;

    print(str) ;

}

int main(void)

{

    int16_t x, y, z ;

   

    init_hardware() ;

   

    splash() ;

       

    print("    X,     Y,     Z\n") ;

    for(;;) {       

        measure(&x, &y, &z) ;

        print_float(calc_g(x)) ;

        print(", ") ;

        print_float(calc_g(y)) ;

        print(", ") ;

        print_float(calc_g(z)) ;

        print("\n") ;

        CyDelay(100) ;

    }

}

==================

配線図

schematic_2.JPG

moto

0 Likes