2018年8月15日 (水)

Arduinoで作ろう(21) 屈折走行するクルマ

20180815
 高校物理・波動分野の授業で「異なる媒質の境界で波が屈折するのは,媒質が異なると波の伝わる速さも異なるからだ」なんてことを教えますが,これを説明するための道具を作ってみました。
秋月電子で買ったフォトリフレクタLBR-127HLDを使って床で反射する赤外線LEDの光を見て,反射光が強い場合(白い床)はモーターを高速回転させ,反射光が弱い場合(黒い床)は低速回転させています。
モーターの回転数はArduinoのPWM出力でコントロールしています。

スケッチはこちら→ 20180815.ino

/* Arduino + フォトリフレクタLBR-127HLD で屈折するクルマ */

void setup() {
Serial.begin(9600);
}

void loop() {
int Rval = analogRead(A0); // 右のフォトリフレクタの出力0~5Vを10bitでAD変換(0~1023)
int Lval = analogRead(A1); // 左のフォトリフレクタの出力0~5Vを10bitでAD変換(0~1023)

Rval = map(Rval, 0, 1023, 150, 255); //右 0~1023の値を160~255の値にマッピング
Lval = map(Lval, 0, 1023, 150, 255); //左 0~1023の値を160~255の値にマッピング

Serial.print(Lval); Serial.print(" "); Serial.println(Rval);

analogWrite(5, Rval); //右モーターにPWM出力
analogWrite(6, Lval); //左モーターにPWM出力
}


| | コメント (0) | トラックバック (0)

2018年7月14日 (土)

Arduinoで作ろう(20) 3軸加速度センサKXR94-2050

Keypadshield_kxr942050

 秋月で買った3軸加速度センサモジュールKXR94-2050で加速度計を作ってみました。
このモジュールの6,7,8ピンにそれぞれx軸,y軸,z軸方向の加速度がアナログ電圧値で出力されるんだそうです。
電源が5Vだと,加速度0m/s^2で2.5Vが出力される仕様です。
しかし,正確に言うと「加速度」ではなくて「重力+慣性力」の大きさを測っているみたいです。センサを水平に静かに置いてみると,z軸には10bitでAD変換された値で700前後が出力されています。
「なんだ,ばねにおもりをぶら下げて,ばねの伸びを測ってるみたいだな」と思って調べてみたら,実際この小さなモジュールの中にばねが何本も入っているらしいです。よくそんな小さなばねが作れるもんですな。驚きました。

M05153

 で,Arduinoにつないで測定してみました。
センサを水平に置いたとき,鉛直方向(z軸方向)は,9.8m/s^2ですが,AD変換された値で700程度の出力がありました。x軸,y軸方向は500程度です。
ところが,この値が実に不安定で,電源を入れ直したり,センサを傾けて元の水平位置に戻したりするたびにz軸方向は680~705程度,x軸・y軸方向は500~525程度の幅で出力値が変化します。これでは物理実験に使えないなあ。電源が不安定なのかもしれないと考えて,いろいろな電源で試してみましたが改善は見られません。どうやら,このセンサはその程度のモノのようです。ちょっと期待してただけにガッカリです。

スケッチはこちら→ 20180714.ino

/* LCD KeyPad Shield 3軸加速度センサ KXR94-2050 */

#include <LiquidCrystal.h>
LiquidCrystal lcd( 8, 9, 4, 5, 6, 7);

void setup() {
lcd.begin(16, 2);
//Serial.begin(9600);
}

void loop() {
int Zdata = analogRead(A1);
int Ydata = analogRead(A2);
int Xdata = analogRead(A3);
lcd.setCursor(0, 0);
lcd.print("X:"); lcd.print(9.8 * (Xdata - 500) / (700 - 500));
//Serial.print("X:"); Serial.print(Xdata);
lcd.print(" Y:"); lcd.print(9.8 * (Ydata - 500) / (700 - 500)); lcd.print(" ");
//Serial.print(" Y:"); Serial.print(Ydata);
lcd.setCursor(0, 1);
lcd.print("Z:"); lcd.print(9.8 * (Zdata - 500) / (700 - 500));
//Serial.print(" Z:"); Serial.println(Zdata);
}

| | トラックバック (0)

2018年7月 7日 (土)

Arduinoで作ろう(19) LCDシールド を作ってみた

20180707_095224

1602lcd

 そういえば以前 秋月電子で買った16文字×2行のLCDがパーツ箱の肥やしになってるなあ と思って,これを同じく秋月のArduino用ユニバーサル基板に乗っけてLCDシールドにしてみました。

FritzingにSD1602Hのパーツがないので,別のLCDのパーツを使って描いてます。
LCDのピンの番号に注意してください。

スケッチはこんな感じでOKです。

/* 自作 LCD Shield Hello,World */

#include <LiquidCrystal.h>
LiquidCrystal lcd(10, 9, 8, 3, 2, 4, 7);

void setup() {
lcd.begin(16, 2);
}

void loop() {
lcd.setCursor(0, 0);
lcd.print("Hello,World!");
lcd.setCursor(0, 1);
lcd.print(millis() / 1000);
}


| | トラックバック (0)

2018年7月 6日 (金)

Arduinoで作ろう(18) LCD Keypad Shield を買ってみた

Arduinolcdkeypadforstore3_chop

AmazonでLCD キーパッド シールド を買ってみました。

Photo
 680円でこのクォリティなら,十分すぎます。ココココにあるPDFを見ると,Arduinoのどのピンが使われているのかが分かりますし,LCDはライブラリ LiquidCrystal.h で普通に使えます。

 今回は5つのタクトスイッチを使えるようにしてみました。
5つのタクトスイッチは,左図のように分圧回路を使ってA0ピンひとつだけで,どのスイッチが押されているか判定しようというものです。なかなか良くできてますよね。

このスケッチ「20180706_LCD_KeyPadShield_switch_Test.ino」を使って,5つのスイッチを順に押しながらA0の電位(10bitにAD変換された値)を調べてから,下のようなスケッチを書いてみました。

「20180706_LCD_KeyPadShield_switch_Test2.ino」

/* LCD KeyPad Shield A0のスイッチテスト2 */

#include <LiquidCrystal.h>
LiquidCrystal lcd( 8, 9, 4, 5, 6, 7);

void setup() {
lcd.begin(16, 2);
}

void loop() {
int ADCdata = analogRead(A0);
lcd.setCursor(0, 0);
if (ADCdata < 50) {
lcd.print("RIGHT ");
}
else if (ADCdata < 150) {
lcd.print("UP ");
}
else if (ADCdata < 350) {
lcd.print("DOWN ");
}
else if (ADCdata < 500) {
lcd.print("LEFT ");
}
else if (ADCdata < 750) {
lcd.print("SELECT");
}
else {
lcd.print("None ");
}

lcd.setCursor(0, 1);
lcd.print(ADCdata); lcd.print("/1023 ");
delay(500);
}


| | トラックバック (0)

2018年7月 1日 (日)

Arduinoで作ろう(17) MPL115A2で大気圧測定

Multifunctionshield_mpl115a2

 Multi Function Shield にI2C接続の大気圧センサ MPL115A2 をつないで大気圧計にしてみました。
前回LCDに表示させてたやつの7セグLED版です。

スケッチはこちら→ 20180701MPL115A2.ino

/* Multi_function_shield 大気圧センサ MPL115A2 */

#include <Wire.h>
#include <MPL115A2.h>
const int LAT = 4; // Latchピン
const int CLK = 7; // Clockピン
const int SDI = 8; // Serial Data In ピン
int pressure;
int Buffer[4] = {0}; //1~4桁 数字のバッファ

byte digit[10] = //7seg 点灯パターン
{
B00000011, // 数字 0
B10011111, // 1
B00100101, // 2
B00001101, // 3
B10011001, // 4
B01001001, // 5
B01000001, // 6
B00011011, // 7
B00000001, // 8
B00001001 // 9
};

const byte keta[4] =
{
B00010000, //1桁め
B00100000, //2桁め
B01000000, //3桁め
B10000000 //4桁め
};

void setup() {
pinMode(SDI, OUTPUT);
pinMode(CLK, OUTPUT);
pinMode(LAT, OUTPUT);
MPL115A2.begin();
//Serial.begin(9600);
}

void loop() {
pressure = MPL115A2.read();
//Serial.println(pressure);
Buffer[3] = int(pressure) / 1000;
Buffer[2] = (int(pressure) % 1000) / 100;
Buffer[1] = (int(pressure) % 100) / 10;
Buffer[0] = (int(pressure) % 100) % 10;
Disp();
}

void Disp() {
for (byte j = 0; j < 4; j++) {
digitalWrite(LAT, LOW);
shiftOut(SDI, CLK, LSBFIRST, digit[Buffer[j]]);
shiftOut(SDI, CLK, LSBFIRST, keta[j]); // 桁
digitalWrite(LAT, HIGH);
delay(4);
}
}

| | コメント (0) | トラックバック (0)

2018年6月30日 (土)

Arduinoで作ろう(16) HC-SR04 で距離の測定

Multifunctionshield_hcsr04_

 Multi function shieldに測距センサHC-SR04をつないで距離計を作ってみました。
前回はLCDに表示させてますが,今回は7セグLEDです。

このシールドは,どこに何の端子が出ているのか分かりにくいのですが,この回路図とか,Fritzingのパーツの絵を見ると分かりますよ。3×4列のピンヘッダのところにD5,D6,D9,A5と+5V,GNDのピンがあります。
そういえば,この基板上にジャンパピンが2つありますが,これの役割も上記の回路図を見ると確認できます。これ,結構重要な情報ですよね。


スケッチはこちら→ 20180701.ino


/*
Multi_function_shield
超音波センサ HC-SR04
*/

#include
const int LAT = 4; // Latchピン
const int CLK = 7; // Clockピン
const int SDI = 8; // Serial Data In ピン
const int trig = 5;
const int echo = 6;
int time;
float distance;
int Buffer[4] = {0}; //1~4桁 数字のバッファ

byte digit[10] = //7seg 点灯パターン
{
B00000011, // 数字 0
B10011111, // 1
B00100101, // 2
B00001101, // 3
B10011001, // 4
B01001001, // 5
B01000001, // 6
B00011011, // 7
B00000001, // 8
B00001001 // 9
};

const byte keta[4] =
{
B00010000, //1桁め
B00100000, //2桁め
B01000000, //3桁め
B10000000 //4桁め
};

void setup() {
pinMode(SDI, OUTPUT);
pinMode(CLK, OUTPUT);
pinMode(LAT, OUTPUT);
pinMode(trig, OUTPUT);
pinMode(echo, INPUT);
Serial.begin(9600);
}

void loop() {
digitalWrite(trig, LOW);
delayMicroseconds(1);
digitalWrite(trig, HIGH);
delayMicroseconds(11);
digitalWrite(trig, LOW);

time = pulseIn(echo, HIGH);
distance = (time / 2) * 0.0340 * 10;
Serial.println(distance / 10);

Buffer[3] = int(distance) / 1000;
Buffer[2] = (int(distance) % 1000) / 100;
Buffer[1] = (int(distance) % 100) / 10;
Buffer[0] = (int(distance) % 100) % 10;
Disp();
}

void Disp() {
for (byte j = 0; j < 4; j++) {
digitalWrite(LAT, LOW);
shiftOut(SDI, CLK, LSBFIRST, digit[Buffer[j]]);
if (j == 1) {
shiftOut(SDI, CLK, LSBFIRST, digit[Buffer[j]]&B11111110);
}
shiftOut(SDI, CLK, LSBFIRST, keta[j]); // 桁
digitalWrite(LAT, HIGH);
delay(4);
}
}

| | トラックバック (0)

2018年6月26日 (火)

Arduinoで作ろう(15) LM35DZの温度計

Multifunctionshieldlm35dz

 Multi Function Shieldに温度センサLM35DZを取りつけて,温度計にしてみました。
LM35DZのアナログデータ出力は,A4で読み取ります。
Arduinoの基準電圧は5.0Vではなくて,実測で4.88Vだったので, temp = ((4.88 * analogdata) / 1024)としました。これでセ氏温度になりますが,さらに10倍して小数点以下1桁まで表示できるようにしてみました。
shiftOut(SDI, CLK, LSBFIRST, digit[Buffer[j]]&B11111110); ってとこで,小数点のDpを点灯させています。

スケッチはこちら→ 20180626.ino

/* Multi_function_shield 温度センサ LM35DZ */

const int LAT = 4; // Latchピン
const int CLK = 7; // Clockピン
const int SDI = 8; // Serial Data In ピン
float analogdata, temp;
int Buffer[4] = {0}; //1~4桁 数字のバッファ
byte digit[10] = //7seg 点灯パターン
{
B00000011, // 数字 0
B10011111, // 1
B00100101, // 2
B00001101, // 3
B10011001, // 4
B01001001, // 5
B01000001, // 6
B00011011, // 7
B00000001, // 8
B00001001 // 9
};
const byte keta[4] =
{
B00010000, //1桁め
B00100000, //2桁め
B01000000, //3桁め
B10000000 //4桁め
};

void setup() {
pinMode(SDI, OUTPUT);
pinMode(CLK, OUTPUT);
pinMode(LAT, OUTPUT);
Serial.begin(9600);
}

void loop() {
analogdata = analogRead(A4);
temp = ((4.88 * analogdata) / 1024) * 1000;
Serial.print(analogdata);
Serial.println(temp);
Buffer[3] = int(temp) / 1000;
Buffer[2] = (int(temp) % 1000) / 100;
Buffer[1] = (int(temp) % 100) / 10;
Buffer[0] = (int(temp) % 100) % 10;
Disp();
}

void Disp() {
for (byte j = 0; j < 4; j++) {
digitalWrite(LAT, LOW);
shiftOut(SDI, CLK, LSBFIRST, digit[Buffer[j]]);
if (j == 1) {
shiftOut(SDI, CLK, LSBFIRST, digit[Buffer[j]]&B11111110); //小数点をつける
}
shiftOut(SDI, CLK, LSBFIRST, keta[j]); // 桁
digitalWrite(LAT, HIGH);
delay(4);
}
}

| | トラックバック (0)

2018年6月25日 (月)

Arduinoで作ろう(14) ラーメンタイマー

71udt2dw40l__sl1002_

 aitendoで買った Multi function Shieldで3分間ラーメンタイマーを作ってみました。
LCDに比べて7セグLEDを点けるのはちょっと面倒ですが,やっぱりなんだか魅力的ですよね。

ココに取説のPDFがあるし,ココにライブラリ,ココにサンプルスケッチがありますが,ライブラリを使わないでラーメンタイマーを作ってみましょう。
このシールドには,74HC595が2個ついていて,Latch,Clock,SDIはそれぞれ4,7,8ピンです。
0~9の7セグ(アノードコモン)点灯パターンの配列を作って,各桁に入れる数字のためのバッファ配列も作っておきます。
millis()を使って残り時間を計算し, shiftOutで7セグLEDに数字データを送ってやります。
3分立ったら「チャルメラ」の音楽が鳴るようになってます(^^)

スケッチはこちら→ 20180625.ino

/* Mult_function_shield ラーメンタイマー180秒 */

const int buz = 3; // Buzzerピン
const int LAT = 4; // Latchピン
const int CLK = 7; // Clockピン
const int SDI = 8; // Serial Data In ピン
const int time = 180;
int timer = time; //残り時間
int Buffer[4] = {0}; //1~4桁 数字のバッファ

const byte digit[10] = //7seg 点灯パターン
{
B00000011, // 数字 0
B10011111, // 1
B00100101, // 2
B00001101, // 3
B10011001, // 4
B01001001, // 5
B01000001, // 6
B00011011, // 7
B00000001, // 8
B00001001 // 9
};

const byte keta[4] =
{
B00010000, //1桁め
B00100000, //2桁め
B01000000, //3桁め
B10000000 //4桁め
};

void setup() {
pinMode(SDI, OUTPUT);
pinMode(CLK, OUTPUT);
pinMode(LAT, OUTPUT);
pinMode(buz, OUTPUT);
}

void loop() {
timer = time - millis() / 1000;
if (timer > 0) {
Buffer[3] = int(timer) / 1000;
Buffer[2] = (int(timer) % 1000) / 100;
Buffer[1] = (int(timer) % 100) / 10;
Buffer[0] = (int(timer) % 100) % 10;
Disp();
}
else if (timer == 0) {
digitalWrite(LAT, LOW);
shiftOut(SDI, CLK, LSBFIRST, 0b00000011); //数字 0
shiftOut(SDI, CLK, LSBFIRST, B00010000); //1桁目
digitalWrite(LAT, HIGH);
tone(buz, 392, 200); delay(200); //チャルメラ
tone(buz, 440, 200); delay(200);
tone(buz, 494, 800); delay(800);
tone(buz, 440, 200); delay(200);
tone(buz, 392, 200); delay(800);
tone(buz, 392, 200); delay(200);
tone(buz, 440, 200); delay(200);
tone(buz, 494, 200); delay(200);
tone(buz, 440, 200); delay(200);
tone(buz, 392, 200); delay(200);
tone(buz, 440, 1000); delay(1000);
}
else {
}
}

void Disp() {
for (byte j = 0; j < 4; j++) {
digitalWrite(LAT, LOW);
shiftOut(SDI, CLK, LSBFIRST, digit[Buffer[j]]);
shiftOut(SDI, CLK, LSBFIRST, keta[j]); // 桁
digitalWrite(LAT, HIGH);
delay(4);
}
}

| | トラックバック (0)

2018年6月17日 (日)

Arduinoで作ろう(13) 大気圧センサMPL115A2

Mpl115a2_

I2C接続の大気圧センサ MPL115A2 を使って大気圧計を作ってみました。
以前,秋月電子で買ったものですが,今はSPI接続のMPL115A1しか売ってないみたいです。売り切れたのかしら?

このセンサを使うのにとても便利なライブラリがArduinoで遊ぶページで公開されています。ありがたいことです。
このライブラリを使うと,MPL115A2.read() という関数で大気圧を取得できるようになります。

で,実際に動かしてみると,このセンサは精度がイマイチのようで,値が±2 hPa くらいでフラフラします。電源が不安定なのかもしれませんが・・・。
特に小数点以下がフラフラしてうるさいので,int で整数値にしてみました。

スケッチはこちら→ 20180617.ino

/* 気圧センサMPL115A2 (I2C接続) */

#include <Wire.h>
#include <MPL115A2.h>
#include <ST7032.h>
ST7032 lcd;

void setup () {
lcd.begin(16, 2);
lcd.setContrast(30);
MPL115A2.begin();
}

void loop () {
lcd.setCursor(0, 0);
lcd.print(int(MPL115A2.read())); lcd.print(" hPa");
delay(1000);
}

| | トラックバック (0)

2018年6月15日 (金)

Arduinoで作ろう(12) サーボモータを動かす

Arduino12

 Arduinoでサーボモータを動かしてみました。
ライブラリを使うとこんなに簡単に動かせるんですね。以前PICマイコンを使ってPWMでサーボモータを動かしたときは結構苦労した記憶があるので,拍子抜けです。
こんなにカンタンだと,人間が堕落するような気がするなー。

Arduinoは最大で12個のサーボモータをつなげるので,サーボ型変数を設定します。1台だけなのでservo1にしました。
VRの真ん中の端子の電位0~5Vをアナログ入力端子A0に入れてAD変換し,さらに0~180度の角度データにマッピングしてサーボモータに送るだけです。

スケッチはこちら→ 20180615.ino

/* サーボモータをVRでコントロール */

#include <Servo.h>

Servo servo1; //サーボ型の変数をservo1とする
int deg;

void setup() {
servo1.attach(11); //servo1は,デジタルピン11につなぐ
}

void loop() {
deg = analogRead(A0);
deg = map(deg, 0, 1023, 0, 180); //AD変換した電圧データを0~180度の角度データにマッピング
servo1.write(deg); //サーボモータに角度を送る
}

| | トラックバック (0)