昨日、一定の距離に近づくとカメラのシャッターが切れるという装置を作ったが、ふと思いついて、同じハードウェアで距離計が作れるな、と思った。なぜかというと、無駄にサーボを使っているからだ。
50センチ以下の距離が測れればいいな、というわけで、サーボの0度から180度まで割り付ける。
5センチ18度、というわけで、何かスマホいじりをしている次女に
「お~い、智香っ、智香。分度器を貸せ」
と言ったら、
「ん~?分度器?……ナイ。」
とニベもない。中学生のクセして、ないワケあるかいっ!!……と思ったが、ガミガミ言うのも面倒くさい。
針の長さがだいたい8cmだから、
tan18° = x ÷ 8cm、x = tan18° × 8cm ≒ 2.6cm。
円周上2.6cm刻みで目盛りをふればよろしい。……って、なにムダな計算しとるんだ俺は。
まあよい、それで、動かしてみるとこんなふうになかなか面白い。
で、まあ、定規をあてて測ると、だいたい合ってる。
しかし、デジタルで採れている値を、ムダにアナログに直すという、はっはっは。
スケッチはこんな具合。
// // rangemeter.ino // 超音波センサで測距して、サーボで作ったメーターで表示する。 // 27.6.7(日) 1015~ // 佐藤俊夫 // #include <Servo.h> Servo meter; const int SERVO = 8; const int TRIG = 9; const int ECHO = 10; const int SERVO_MIN = 0; const int SERVO_MAX = 180; const float RANGE_MIN = 0.0; const float RANGE_MAX = 50.0; void setup() { meter.attach(SERVO); meter.write(SERVO_MIN); pinMode(TRIG,OUTPUT); pinMode(ECHO,INPUT); } void loop() { float range = 0.0; delay(1000); range = ranging(); if(range <= RANGE_MAX){ indication(range); }else{ indication(RANGE_MAX); } } void indication(float range){ int deg = 0; deg = map(range, RANGE_MIN, RANGE_MAX, SERVO_MIN, SERVO_MAX); meter.write(deg); } float ranging(){ float time = 0.0, range = 0.0; digitalWrite(TRIG,LOW); delayMicroseconds(1); digitalWrite(TRIG,HIGH); delayMicroseconds(1); digitalWrite(TRIG,LOW); time = pulseIn(ECHO,HIGH); if (time > 0.0) { range = (time / 2.0) * 340.0 * 100.0 / 1000000.0; return(range); }else{ return(9999.0); } }