【風速計2019】Speedセンサはリードスイッチ式自作<ネオジが決め手>

風速計は、車速Speedセンサと比較しなければ意味がないです。サイコンは、GPSかANTセンサで車速を測定してますが、そこから情報を風速計に送受信するのが大変な作業になります。
 単純なリードスイッチ式のSpeedセンサを作ったほうが簡単で確実なので、昔買ってあったリードスイッチを取り出して車速が得られるか実験してみました。

●リードスイッチ
基本的な解説は、OMRONにあります。
秋月で昔買っておいた中国製リードスイッチを部品箱から探し出して使いました。プラスチックケースに入ってます

リードスイッチSP3-1A16-3A

0.3mmの薄い両面基板に半田付け固定しました。厚い基板だとフォークの曲面に沿わないので、この基板をの裏にゴム系両面テープを使ってフォークに接着しました。
0.3mm厚 極薄両面ガラス・ユニバーサル基板

●スポークのマグネットを補強
CATSEYEのスポーク用マグネットでは、3cm距離では、スイッチングしなかったので、昨年買っておいた、ネオジ角磁石を重ねたら、スイッチングできるようになりました。ネオジは、専門店のマグファインが種類が多くて便利です。マグファインのNSC0025を使いました。


 

●信号チェック
リードスイッチの矩形波形をデジタル入力するのですが、チャタリングが問題になります。矩形波形を見てから対策を考えることにしました。マイコン側のピンはプルアップでピンから10Ωの抵抗を入れてセンサと接続してあります。プルアップからGNDにFall波形をみると
チャタリングが激しく発生してました。

これでは、まずいので、Rise波形をみると
綺麗に立ち上がっているので、Riseで割り込みをいれることにしました。

●Speedセンサプログラム
単純なセンサなので、ライブラリは必要無しで、ピン割り込みとタイマーを使うだけです。
LPC1114FNのピン配置図を仕様書とmbed 

●mbedプログラム 備忘録
①リードスイッチは、LPC1114FN28のdp26に10KΩ抵抗を介して
接続。割り込みポート 定義
InterruptIn  in2(dp26);
②割り込み定義は、
in2.mode(PullUp);
in2.risec(&flip2);
③割り込み時の関数はflip2()で1回転の周期t2_periodと周波数t2_frequencyを計算して、タイマーt2をリセット。

④車速kmhの計算は、700x23c換算
Wheel_speed=t2_freq*0.11644;//2.096/18;
全ソース(LCDと風速と車速のみSDカード未だ)

//実装接続プログラム2016/10/16 rev.1.0
//単一プログラムでライブラリー化せず
// ********************Wind meter*****************************
// Target LPC1768
// 1)ACM1602NI (I2C text LCD library)
// Takuo WATANABE (wtakuo)
// http://mbed.org/users/takuo/code/ACM1602NI/
// 2)SD FIle read/write
// Junichi Katsu “超お手軽マイコンmbed入門”P60~
//example writing to SD card, sford
// 3)Frequency Counter x2ch
// Neel Shah
//https://developer.mbed.org/users/Neel/code/Frequency_counter/
// 4)OMRON D6F-PH5050 I2C diff pressure meter
// Kunihiko Matsuhashi
//*************************************************************
//————————————Header ———————————–#include “mbed.h”
#include “ACM1602NI.h”
#include “SDFileSystem.h”
#define D6F_ADDR 0xD8 //I2Cアドレス定義
I2C i2c1(dp5,dp27);
//DigitalOut led1(LED1);
//DigitalOut led2(LED2);
//DigitalOut pinout(p19);
ACM1602NI lcd(dp5, dp27);//I2C LCD
//SDFileSystem sd(p5, p6, p7, p8, “sd”); // the pinout on the mbed Cool Components workshop board
Serial pc(USBTX, USBRX);//USB serial
//InterruptIn in1(p16); //Wind sensor
InterruptIn in2(dp26);//Wheel encoder
//Timer t1;//for Wind sensor
Timer t2;//for Wheel encoder
//————————-const 定義————————————//
float t1_period = 0; // This is the period between interrupts in microseconds
float t1_freq = 0;
float t2_period = 0; // This is the period between interrupts in microseconds
float t2_freq = 0;
float Wind_speed=0;
float Wheel_speed=0;
float pitos=0;
float mitudo=0;
float tmpr=20;
float Cof=0.9;
int wtime=500;
static const char d6f_config[5]={0x00,0xD0,0x40,0x18,0x06};
static const char d6f_comp_read[4]={0x00,0xD0,0x51,0x2c};//差圧データx51hを指定
static const char d6f_temp_read[4]={0x00,0xD0,0x61,0x2c};//温度テータx61hを指定
static const char d6f_mem_read[1]={0x07};//リードレジスタx07hから読む
static const char d6f_init[2]={0x0B,0x00};//初期化レジスタx0Bhをx00でリセット
//—————————————————————————–
//初期化関数//uint8_t d6fph_strt(void) {
uint8_t error;//D6F-PHのレジスタ通信データを宣言・初期化する

error=i2c1.write(D6F_ADDR,d6f_init,2);
return(error);
}

//差圧読み込み関数//
float read_pressure(void) {
char error;
char rdata[2];
uint16_t raw_diff_pa;
float diff_pa;
error=i2c1.write(D6F_ADDR,d6f_config,5);
wait_us(33000);
error=i2c1.write(D6F_ADDR,d6f_comp_read,4);
error=i2c1.write(D6F_ADDR,d6f_mem_read,1,true);
error=i2c1.read(0xD9,rdata,2);
if (error){
return(error);
}
raw_diff_pa=(rdata[0]<<8)+rdata[1];
diff_pa=((float)raw_diff_pa-1024)/60-500;
return(diff_pa);
}
//温度読み取り関数//
float read_d6f_temp(void) {
char error;
char rdata[2];
uint16_t raw_ref_temp;
float ref_temp;

i2c1.write(D6F_ADDR,d6f_config,5);
wait_us(33000);
error=i2c1.write(D6F_ADDR,d6f_temp_read,4);
error=i2c1.write(D6F_ADDR,d6f_mem_read,1,true);
error=i2c1.read(0xD9,rdata,2);
if(error){
return(error);
}
raw_ref_temp=(rdata[0]<<8)+rdata[1];
ref_temp=((float)raw_ref_temp-10214)/37.39;
return(ref_temp);
}

//cout関数
/*void flip1(void)//TIMER WIND
{
led1=!led1;
pinout=!pinout;
t1_period = t1.read_us(); // Get time since last interrupt
//pc.printf(“t1_read_us=%5.1f\n”,t1_period);
t1_freq = (1/t1_period)*1000000; // Convert period (in us) to frequency (Hz)
t1.reset(); // Reset timer and wait for next interrupt
}
*/
//——————————-
void flip2(void)//TIMER WHEEL
{
// led2=!led2;
t2_period = t2.read_us(); // Get time since last interrupt
t2_freq = (1/t2_period)*1000000; // Convert period (in us) to frequency (Hz)
t2.reset(); // Reset timer and wait for next interrupt
}
//関数定義終わり—————————//

//————————-main—————————
// データ読みこみ毎にLEDが点滅する

int main() {
float prs;
int i=0;
prs=0;
/*
mkdir(“/sd/mydir”, 0777);
in1.mode(PullDown); // Set the pin to Pull Down mode.
in1.rise(&flip1); // Set up the interrupt for rising edge
*/
in2.mode(PullUp); // Speed SensorSet the pin to Pull Down mode.
in2.rise(&flip2); //Speed Sensor Set up the interrupt for rising edge
//t1.start(); // start the timer1
t2.start(); //start the timer 2
/*FILE *fp = fopen(“/sd/mydir/sdtest.csv”, “w”);
fprintf(fp,”Wind speed ,Pressure,temp,Wheelspeed,wtime%d\n”,wtime);
fclose(fp);
*/

while(1){
wait_ms(wtime);

//Wind_speed=t1_freq*0.0577;
//if(t2_freq<0.31 or t2_freq>20) t2_freq=0;
//

Wheel_speed=t2_freq*0.11644;//2.096/18;

d6fph_strt();
prs=read_pressure();//差圧データ読んで代入////
tmpr=read_d6f_temp();//温度データ読んで代入//
mitudo=353/(273+tmpr);
pitos=Cof*sqrt(2*prs/mitudo);
lcd.locate(0,0);
lcd.printf(“Pito:Bike:<%2.1f>\r\n”,Wheel_speed-pitos);
lcd.locate(0,1);
lcd.printf(“%2.1f,%2.1f\r\n”,pitos,Wheel_speed);
//lcd.printf(“\r\n”);
pc.printf(“Pitos=%3.1f,tmp=%2.1f,pa=%2.1f\r\n”,pitos,tmpr,prs);

//fp=fopen(“/sd/mydir/sdtest.csv”, “a”);
//fprintf(fp,”%2.1f,%2.1f,%2.1f\n”,pitos,tmpr,Wheel_speed);
//fclose(fp);
i++;
}
}

●動作確認
上記プログラムをLPC1114FN28に書き込んで前輪を回してみます。PITO管は結線をはずしてあるので出ません。<12.5>kmhでそれらしき値がでてます。

 

●以後
SDカードを残してセンサ動作とLCDがOKとなりましたので
実装基板を製作開始します。SDカードは、風速計は100msecより遅いサンプリングですので、そんなに問題にならないだろうと思います。PITO管をどう固定するかが課題として残ってます。

 

 

 

 

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です