距離計の補正のため、直線移動するための装置作成。
http://qiita.com/7of9/items/93257105e64bb4724fa7
にて用意した物を使って移動距離を測定してみた。
code v0.2
3000msecごとに300msecの間、DCモーターを駆動する。
ただし、3000msecごとに動くと測定が難しいので、3回ごとに駆動するようにした。
#include <ESP8266WiFi.h>
#include <stdint.h>
/*
* v0.2 2016 Sep. 3
* - execute for every [kCount_interval] times
* + add [kCount_interval]
* - include <stdint.h>
* v0.1 2016 Jul. 11
* - handle relay pin
* - add loop()
* - add setup()
*/
static const int kRelayPin = 14;
static const int kCount_interval = 3;
void setup() {
WiFi.disconnect();
Serial.begin(115200);
pinMode(kRelayPin, OUTPUT);
digitalWrite(kRelayPin, LOW);
}
void loop() {
char szbuf[] = "hello";
static int8_t cnt = 0;
Serial.println(szbuf);
if (cnt == 0) {
digitalWrite(kRelayPin, HIGH);
delay(300); // msec
digitalWrite(kRelayPin, LOW);
}
cnt++;
if (cnt >= kCount_interval) {
cnt =0;
}
delay(3000);
}
測定の様子
- レール(R-01)を3つ使用
- だいたい9秒ごとに移動するので、移動した時に定規で移動距離を見る
- レール単体では移動時にレールが動くのでバイスを重しとした
測定結果
R-01の連結部分を通る/通らない場合で測定値が変わる。
なお、測定者の技能により、読み取り誤差は2mm程度あるだろう。
連結部分を通らない場合
idx | 移動距離 (cm) |
---|---|
1 | 10.8 |
2 | 11.3 |
3 | 11.3 |
4 | 11.8 |
5 | 11.3 |
6 | 11.2 |
7 | 11.3 |
連結部分を通る場合
idx | 移動距離 (cm) |
---|---|
1 | 9.5 |
2 | 8.6 |
3 | 8.8 |
4 | 8.8 |
5 | 9.0 |
6 | 10.0 |
7 | 9.2 |
結果
2cm近い誤差がある。
距離計の補正に使うには誤差が大きすぎる。
誤差要因
- DCモーターのトルク関連
- delay(300)がそもそも300msecを保証しない
- ESP8266内部のOSによって誤差が生じる
アナログエンジニアさんの教え
測定中にふと思い出した教え。
データーの写し間違いや異常があった時には、消しゴムで消さずに横線を引いて元のデータの脇に書き添える。間違いデータと思ったものが、真実でありかつ次の実験計画に影響を及ぼすことがある。筆記用具は鉛筆でなく、簡単には消せないボールペンだ。
code v0.3 > delay()の時刻測定
delay(300);
の誤差を見るため、前後にミリ秒の表示を追加した。
#include <ESP8266WiFi.h>
#include <stdint.h>
/*
* v0.3 2016 Sep. 3
* - measure time for delay(300);
* v0.2 2016 Sep. 3
* - execute for every [kCount_interval] times
* + add [kCount_interval]
* - include <stdint.h>
* v0.1 2016 Jul. 11
* - handle relay pin
* - add loop()
* - add setup()
*/
static const int kRelayPin = 14;
static const int kCount_interval = 3;
void setup() {
WiFi.disconnect();
Serial.begin(115200);
pinMode(kRelayPin, OUTPUT);
digitalWrite(kRelayPin, LOW);
}
void loop() {
char szbuf[] = "hello";
static int8_t cnt = 0;
unsigned long mils;
Serial.println(szbuf);
if (cnt == 0) {
mils = millis();
Serial.println(mils);
digitalWrite(kRelayPin, HIGH);
delay(300); // msec
digitalWrite(kRelayPin, LOW);
mils = millis();
Serial.println(mils);
}
cnt++;
if (cnt >= kCount_interval) {
cnt =0;
}
delay(3000);
}
結果
hello
hello
hello
55758
56058
hello
hello
hello
65058
65358
hello
hello
hello
74358
74658
hello
delay(300);
ではミリ秒オーダーの誤差はないのか。