※2024年1月でOMRON D6Fphは、販売中止となりました。他社で同等の微差圧センサあるかもしれませんのお探しください。
信州MAKERSでは、ロードバイク関連の開発は、2020年で終了となっております。理由は、ロードバイク関連の電子工作の読者が
非常に少ない点にあります。自転車乗りは、インドア趣味はしないということだと思います。私自身も、電子工作を始めてからロードバイク
はローラ台で踏むだけでサイクリングにほとんど行かなくなりました。
上写真のLCDの3つの数値はkmh単位で、下左がPITO管の風速、下中央が車速で右上が車速ー風速=相対大気速度=追い風が+、向い風-表示です。車速センサつけてないのでゼロで、風速が23kmhなので向い風-23kmhです。
●駆動デバイス
機能 | 種別 | 品名 | 接続方式 |
①表示 | LCD | ACM1602ni | i2c |
②風速センサ | 微差圧センサ | OMRON D6FPH 5050AD3-1 |
i2c |
③車速センサ | リードスイッチ | CatsEye転用 | デジタル入力 |
④データログ用 | μSDカード | spi | |
⑤パワーメーター 入力 |
SeatTube型 | パワー用 マイコン |
シリアル |
●CPU選定
3年前は、初心者だったので、LPC1768を使いました。
今回は処理速度が必要なので、Arduino ATMEGA328P8、16MHzでは重いので、mbed cortex で選びました。
更に、実使用なので、雨で破壊される可能性が高いので
壊れても惜しくない価格帯のCPUでないといけません。
サイズ | 処理速度 | 電力 | コスト | 採点 | |
LPC1768 | ×50×25 | ◎100MHz M3 | ×50mA | × 6000円 |
×大高 |
NUCLEO L432KC | ▲50×18 | ◎80MHz M4 |
▲20mA | △ 1500円 |
▲大 |
LPC11U35 | △40×20 | 〇50MHz M0 |
○10mA | 〇 850円 |
〇中 |
LPC1114FN28 | △36×16 | 〇50MHz M0 |
○10mA | ◎ 400円 |
◎小省安 |
Teensy 3.2 | ◎30×18 | ◎100MHz M4 |
▲30mA | ▲ 2500円 |
〇小速 |
Teensy3.2も魅力的なサイズなのですが、電力NGなので
LPC1114FN28も3年ぶりで使ってみました。
CPU単体ではUSBシリアルついてないので、USBシリアル
WRITER付が高いけど便利です。SwitchScienceさんで
ロングセラー品として販売してます。アマゾンにもあります。
●LPC1768プログラムからLPC1114FNへ変更
1stSTEP:LPC1114FNでシリアル最高速測定
=>~230400bpsまでOK、460800bpsはNG
2ndSTEP:LCD をドライブできるか?
秋月で買ったACM1602NIです。
i2cで高コントラストバックライト無でロードバイク向き。
3年前は、LPC1768用のライブラリだったが今回は、
LPC1114FNなので、相性のいいライブラリ探す。
mbed サンプルプログラム検索でQMC1602niで検索
一番簡単そうなプログラムがこれでした。takahiro maeda
https://os.mbed.com/users/maro/code/i2c_lcd_ACM1602NI/
これだけの行数で、見事にLCD動作できました。
変更したのは、main.cのi2cピン定義を(dp5,dp27)//sda,scl変更するだけで表示動作しました。
include “mbed.h”
DigitalOut myled(LED1); int main() { while(1) { |
3rdSTEPは、昔使っていたPgmで動くか試したら、動作しました。
ACM1602niのライブラリはこちらを使いました。
Takuo WATANABE /
https://os.mbed.com/users/takuo/code/ACM1602NI/
3rdSTEP:3年前の風速計プログラムが1114FNで動作するか?
i2cがLCDとD6FPHの2個ぶる下がっています。
3年前のソースを変更しました。LCP1768で動作させてましたが、
現在より丁寧に書いてます。ライブラリーは
ACM1602ni.h
SDFileSystem.hの 2個だけ使ってます。
微差圧センサのD6FPHのi2cドライブは3つの関数を書きました。
LPC1114FNでmain.cのi2c ピン番号変えてOKでした。
車速のピン割り込み関係とSDファイル関係をコメントアウトして
LCDと風速計の動作確認できまたプログラムです。
●風速の計算(ベルヌーイの定義通り)
http://www.gifu-nct.ac.jp/elcon/labo/fukunaga/edu/4d/keisoku_kikai2.pdf
気温から密度を求めて
風速=PITO係数x√(微差圧/密度) と簡単に計算できます。PITO管係数ですが、正確な風速計と合わせて0.9としました。だいたい、1~0.9程度で収まるみたいです。
校正用で精度がそこそこな風速計は、楽天で仕入れましたが、6千円~8千円です。
https://item.rakuten.co.jp/auc-ten-kou/40kg-1/
校正用風速計の備忘録
//実装接続プログラム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(p15);//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(PullDown); // Set the pin to Pull Down mode. in2.rise(&flip2); // 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++; } } |
●以後
車速センサをリードスイッチと磁石で作って、
ピン割り込みで車速が精度よくでるかデバッグします。
※2020年12月追記
風速計開発してから4年過ぎてますが、2019年に再度作り直したきり、ロードバイクへ定常的に取り付けてません、理由は、私があまりロードバイクに乗らないからです年間千kmも乗りませんし、冬場のローラー台トレーニングのほうが距離が多いくらいだからです。たまに乗ると風速計が欲しいと思うことが多々あるのですが、信州MAKERSの他のテーマが忙しくてなかなか風速計に手が回りません、もし、どうしても欲しいけど現状では、自作できないが将来的に自分で使ってみてから自作に挑戦してみたい方がいらしゃるなら、私の2019年版の風速計セットお貸しいたします。それでセンサとマイコンの学習などしてみるとお仕事、勉強の役にたちますので、お得な遊びになると思います。信州MAKERSでは、自作したい人を応援しますので、自作したい意思があるならお手伝いいたします。ご連絡はメールでお願いします。ich48397@wd5.so-net.ne.jp 信州MAKERS管理人です。
2019年の作品記事はこれです。