Arduino(アルドゥイーノ)始めます -3ページ目

I2C通信を勉強したいです 2

Kです。
I2C通信の勉強のため、I2C接続のキャラクタLCDをWireライブラリで動かす実験をしてみました。


PDFにサンプルスケッチがあるので、これを前回の記事と同じように一バイトずつ送信してみました
http://akizukidenshi.com/download/ds/xiamen/AQM1602_rev2.pdf

このLCDのスレーブアドレスはArduinoの場合0x3Eになるようです。
>・スレーブアドレスは0x7C(7bitアドレス)です。「アドレス0111110+0(RW)」
>(READが不可なので、RWは常に0になります)Arduino表現では0x3Eになります。)
・・・と書いてあるのですがよくわかっていません・・・

サンプルスケッチを見ると、初期化のためには
0x00をつけて0x38,0x39,0x14,0x73,0x52,0x6C,0x38,0x01,0x0Cを書き込み、
文字表示は0x40をつけて書き込み、
しているようだったので一つ一つ書き込んでみると、

--
#include
char moji[] ="TEST";

void setup() {
Wire.begin();
delay(40);
Wire.beginTransmission(0x3E);
Wire.write(0x00);
Wire.write(0x39);
Wire.endTransmission();

delay(40);
Wire.beginTransmission(0x3E);
Wire.write(0x00);
Wire.write(0x14);
Wire.endTransmission();

delay(40);
Wire.beginTransmission(0x3E);
Wire.write(0x00);
Wire.write(0x73);
Wire.endTransmission();

delay(40);
Wire.beginTransmission(0x3E);
Wire.write(0x00);
Wire.write(0x52);
Wire.endTransmission();

delay(40);
Wire.beginTransmission(0x3E);
Wire.write(0x00);
Wire.write(0x6C);
Wire.endTransmission();

delay(40);
Wire.beginTransmission(0x3E);
Wire.write(0x00);
Wire.write(0x38);
Wire.endTransmission();

delay(40);
Wire.beginTransmission(0x3E);
Wire.write(0x00);
Wire.write(0x0C);
Wire.endTransmission();
}

void loop() {

{
Wire.beginTransmission(0x3E);
Wire.write(0x40);
Wire.write(moji[0]);
Wire.endTransmission();
delay(1);
}

{
Wire.beginTransmission(0x3E);
Wire.write(0x40);
Wire.write(moji[1]);
Wire.endTransmission();
delay(1);
}

{
Wire.beginTransmission(0x3E);
Wire.write(0x40);
Wire.write(moji[2]);
Wire.endTransmission();
delay(1);
}

{
Wire.beginTransmission(0x3E);
Wire.write(0x40);
Wire.write(moji[3]);
Wire.endTransmission();
delay(1);
}
while(1){}
}
--

ちゃんと液晶にTEST と表示されました。
(Arduinoのリセットボタンを押すとTESTTESTと初期化されずに文字列が追加されるのが謎ですが…)
なんとなーくI2C通信の流れがわかってきたような気がします。
それと、関数を使ってスケッチを綺麗にする大事さもわかってきました。

I2C通信を勉強したいです

Arduinoの作例を探しているとI2C通信がよく出てきますが、
実はI2C通信について何もよくわかっていないので勉強をしたいです。

I2C通信についてはここここに解説がありました。


1親機がスタートを宣言して
2通信相手のスレーブアドレスを指定
3親側からの書き込みか、親が読み込みかを指定
4子機から返事をして通信スタート
51バイトごとに通信して、最後に親からストップ信号




という流れでよいでしょうか?Sさん…!

https://www.arduino.cc/en/Tutorial/MasterWriter
ArduinoのWireライブラリで簡単にI2C通信ができるようです。

親側スケッチ
#include

void setup() {
Wire.begin(); // ()だと親。()内に数字入れると子機のアドレスになる
}

byte x = 0;

void loop() {
Wire.beginTransmission(8); // transmit to device #8子機(8)と通信開始
Wire.write("x is "); // sends five bytes 文字送信(5文字)
Wire.write(x); // sends one byte 数字送信
Wire.endTransmission(); // stop transmitting STOP信号送信

x++;//1ループごとに送る数字が1増える
delay(500);
}


子機側スケッチ
#include

void setup() {
Wire.begin(8); // join i2c bus with address #8 スレーブアドレス8として設定
Wire.onReceive(receiveEvent); // register event 親機から通信来たらこの関数を開始
Serial.begin(9600); // start serial for output シリアルモニタ表示用
}

void loop() {
delay(100);
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) {
while (1 < Wire.available()) { // loop through all but the last 親機から最後以外は文字が送られてくるので文字列として受信?
char c = Wire.read(); // receive byte as a character 一文字ずつ受信
Serial.print(c); // print the character 一文字ずつシリアルモニタに表示
}
int x = Wire.read(); // receive byte as an integer 最後の数字を受信
Serial.println(x); // print the integer 数字をシリアルモニタに表示
}

こういうことでしょうか?Sさん!


子機側のシリアルモニタにこのように表示されていきます。


まだ"while (1 < Wire.available())"の仕組みがあまりよくわかりません・・・

Arduino IDEの標準機能で簡単なグラフを表示する

Kです
Arduino IDE 1.6.6にはシリアルプロッタという機能がついています。

Processingを使ってグラフを表示しようと思っていたのですが、
この機能を使えば簡単にグラフ表示をさせることができます。

使い方はスケッチ例のBasic→AnalogReadSerialのように、
数値をSerial.printlnするだけです。

ArduinoIDEのツール→シリアルプロッタを開くと、グラフが表示されます。





複数の値を表示させたい場合は、
下のように改行前にスペースで区切ると複数表示が可能とのことです。

Serial.print(sensorValue);
Serial.print(" ");
Serial.println(sensorValue1);

回路設計ツールfritzingについて

fritzingはこんな図を作ることができるツールだ。




部品ライブラリから部品を配置して配線すると回路図やプリント基板を自動で作成してくれる。
fritzingはココからダウロードできる。

メニューからファイル-サンプルを開くから Aruduino のスケッチがを開くことができる。

Processingについて

前のブログで紹介したProcessingについて。
映像の13分頃から2Dのパーティクルの紹介がある。
画像やアニメーションを用いた視覚的な表現やインタラクティブな表現を簡単なプログラミングで作成できるらしい。
単純な直線、円などの描画もできそう。Processing基礎最速入門 がわかりやすいかも。
趣味でも使われているしアーティスト、デザイナー、建築家、研究者らが利用するそうだ。

Arduinoスケッチ例でProcessing をつかう時 メモ

Kです。
Arduino のスケッチ例04.Communication→DimmerなどではProcessing ソフトを使用します。

Processing を使用するスケッチ例では
/* Processing code for this example~から始まり*/で終わる部分をProcessingのスケッチとして使います。
例:した画像黒枠部をProcessingのスケッチとして使用


最初にArduinoにスケッチを書き込んでからProcessingのスケッチを実行します。
COMポートが使用中になってしまうためです。

また、Processing用スケッチのCOMポート設定も変更する必要があります。

println(Serial.list());
でProcessingが認識するCOMポートを見ることができます。
下画像でCOM4がArduinoの場合、

port = new Serial(this, Serial.list()[0], 9600);

port = new Serial(this, Serial.list()[2], 9600);
へ変更すると使用できるようになります。

Processingを使用すると、Arduinoからデータを送ってグラフ等が書けるようです。
検索すると作例もたくさん出てきますが、
私の環境ではintの数値をシリアル送信する作例は値が動かずうまく動きませんでした。
文字列として送ったり、highByte() lowByte()を使用して1バイトずつ送信するスケッチでは動いているようです。
まだあまり理解できていないのでビットについて勉強したいと思います・・・。

UbuntuマシンにArduino IDEを入れてみました

Kです。
メインPCのSSDを変更中でWindowsがつかえないので、
いらないノートPCに入れていたUbuntuにArduino IDEをインストールしてみました。

1、UbuntuソフトウェアセンターでArduino IDEと検索

2、インストールをクリックして、パスワード(PC起動時に入力するもの)を入力


これでインストールが完了しました。思ったより簡単でした。
(環境によりつまずくこともあるようです)

起動はデスクトップ左のランチャーにArduinoアイコンが出ているのでクリック


初回起動時に下のようなメッセージが出てきたのでAddにしておきました。
(詳細不明ですすみません)




COMポートは下画像のように"ttyACM0"などになっていればOKのようです。


サンプルスケッチのAnalogInOutを書き込んでみると


ちゃんと動作できていました!


Ubuntuはwindowsとかなり違うところが多く、
さらにうちの環境だとWifiが頻繁に切れるのであまり使ってないのですが
初めてPCを触った時のようなワクワク感がありますね・・・!

そのうちラズベリーパイも触ってみたいです。

サーボモーターを使ってみた

サーボモーターを使ってみた。

Sです。
メニューのファイル-スケッチの例から,



#include <Servo.h>

Servo myservo; // create servo object to control a servo

int potpin = 0; // analog pin used to connect the potentiometer
int val; // variable to read the value from the analog pin

void setup() {
myservo.attach(9); // attaches the servo on pin 9 to the servo object
}

void loop() {
val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)
val = map(val, 0, 1023, 0, 180); // scale it to use it with the servo (value between 0 and 180)
myservo.write(val); // sets the servo position according to the scaled value
delay(15); // waits for the servo to get there
}

接続は以下の通り。一番下の部品は10kΩボリュームだ。

Hardware Required 10k ohm potentiometer

http://www.arduino.cc/en/Tutorial/Knob



モーターシールドをつかってみました

Arduino モーターシールドを試してみました。

つかったもの
Arduino - ArduinoMotorShieldR3
モーターフェーダー

モーターでよかったのですが下の記事が楽しそうだったのでモーターフェーダを使用してみました。
元は音響用のボリュームにつかわれているものらしいです。
高かった・・・
Slide Pot モーターフェーダを手軽に利用できるリニアアクチュエータとして使う | メモとか倉庫とか(仮)

モーターシールドの使い方とスケッチは下の記事を参考にしました。
Motorシールドを用いたDCモータの制御方法 (Arduino) - Qoosky

今回使ったモーターフェーダはDC10V駆動でした。
家に10VがなかったのでDC9VのACアダプタを使っています。

モーターフェーダは可変抵抗としての機能もあるので、
抵抗値を図ることで大体の場所がわかります。
今回は一番端っこに行くとモーターをブレーキ、2秒待って反対側に移動、としました。

--スケッチ--
void setup() {
Serial.begin(9600);
// モーターAの制御用ピン設定
pinMode(12, OUTPUT); // 回転方向 (HIGH/LOW)
pinMode(9, OUTPUT); // ブレーキ (HIGH/LOW)
pinMode(3, OUTPUT); // PWMによるスピード制御 (0-255)
}

void loop() {

int vr = analogRead(A2); //A2にボリューム部の2ピンを接続。1=5V,0=GND

// モーターA: 正転
digitalWrite(12, HIGH);
digitalWrite(9, LOW);
while(vr > 0){ //一番端っこ(抵抗値がMAX)に行くまで正転
vr = analogRead(A2);
analogWrite(3, 120);
Serial.println(vr);
}
digitalWrite(9, HIGH); //端っこに行ったらブレーキ
// 2秒間上記設定で回転
delay(2000);


// モーターA: 逆転
digitalWrite(12, LOW);
digitalWrite(9, LOW);
while(vr <1023){ //一番端っこ(抵抗値が0側。電圧が高くなるほう)に行くまで逆転
vr = analogRead(A2);
analogWrite(3, 120);
Serial.println(vr);
}
digitalWrite(9, HIGH); //端っこに行ったらブレーキ
// 2秒間上記設定で回転

delay(2000);
}
--スケッチ--


端っこに行くとモーターをブレーキ、2秒待って反対側に移動・・を繰り返しています。




・・・ここまでやって使い道が思いつかなかったので、
LM35をつなげて物理的に表示する温度計とか思いつきました…。



以下たまに勝手に振り切れるスケッチ(範囲指定あたりが間違っている気もします)
-- --
void setup() {
Serial.begin(9600);
// モーターAの制御用ピン設定
pinMode(12, OUTPUT); // 回転方向 (HIGH/LOW)
pinMode(9, OUTPUT); // ブレーキ (HIGH/LOW)
pinMode(3, OUTPUT); // PWMによるスピード制御 (0-255)
}

void loop() {

int vr = analogRead(A2);
int lm35 = analogRead(A3); //LM35をanalogread
int temp = map(lm35, 0, 1023, 0, 5000); //analogread 0-1023を0-5000(mV)に変換
temp = constrain(temp,200,300);//200-300のみ採用 200mV(20度)以下と300mV以上は切捨て

int a = map(temp, 200, 300, 0, 1023); //200~300mV(温度) を 0~1023(フェーダの位置)にする

int b = max(a,vr); //温度とVR位置のどちらか大きいほう、小さいほうを出して
int c = min(a, vr); //
int d = b - c ; //差があまりなければモーターうごかさないようにした。
if(d <50){
Serial.print(temp);
Serial.print(",");
Serial.print(a);
Serial.print(",");
Serial.println(vr);
}else{
// モーターA: フルスピード正転
digitalWrite(12, HIGH);
digitalWrite(9, LOW);
while(vr > a){
vr = analogRead(A2);
analogWrite(3, 80);
Serial.print(temp);
Serial.print(",");
Serial.print(a);
Serial.print(",");
Serial.println(vr);
}

// モーターA: フルスピード逆転
digitalWrite(12, LOW);
digitalWrite(9, LOW);
while(vr < a){
vr = analogRead(A2);
analogWrite(3, 80);
Serial.print(temp);
Serial.print(",");
Serial.print(a);
Serial.print(",");
Serial.println(vr);
}
}
digitalWrite(9, HIGH);
// 2秒間上記設定で回転

delay(2000);
}
--おわり--

超音波距離計 HC-SR04をつかう

Kです。

超音波距離計 HC-SR04を試してみました。

**使用したもの
Arduino Uno
HC-SR04
LCDシールド


**接続**
HC-SR04とLCDシールドを装着したArduino
・Vccを5V
・TrigをD13
・EchoをD12
・GNDをGND

LCDシールドとの接続はオスメスのジャンパワイヤを使用します。
私はオスメスのリボンケーブルを裂いて使っています。
アマゾンで売っているものは海外から送られてきますが安く購入できました。

**スケッチ**
Simple Arduino and HC-SR04 Example - 3にLCDシールド表示を追加しました。
またLCDシールドのSELECTボタンで測定を開始するようにしています。

--以下スケッチ--
/*
HC-SR04 Ping distance sensor]
VCC to arduino 5v GND to arduino GND
Echo to Arduino pin 13 Trig to Arduino pin 12
Red POS to Arduino pin 11
Green POS to Arduino pin 10
560 ohm resistor to both LED NEG and GRD power rail
More info at: http://goo.gl/kJ8Gl
Original code improvements to the Ping sketch sourced from Trollmaker.com
Some code and wiring inspired by http://en.wikiversity.org/wiki/User:Dstaub/robotcar
*/

#define trigPin 13
#define echoPin 12
#include "LiquidCrystal.h"
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

int lcd_key = 0;
int adc_key_in = 0;

#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5

//LCDシールドのボタン
//http://www.dfrobot.com/wiki/index.php/LCD_KeyPad_Shield_For_Arduino_SKU:_DFR0009
int read_LCD_buttons(){ // read the buttons
adc_key_in = analogRead(0); // read the value from the sensor

// my buttons when read are centered at these valies: 0, 144, 329, 504, 741
// we add approx 50 to those values and check to see if we are close
// We make this the 1st option for speed reasons since it will be the most likely result

if (adc_key_in > 1000) return btnNONE;

// For V1.1 us this threshold
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 250) return btnUP;
if (adc_key_in < 450) return btnDOWN;
if (adc_key_in < 650) return btnLEFT;
if (adc_key_in < 850) return btnSELECT;

// For V1.0 comment the other threshold and use the one below:
/*
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 195) return btnUP;
if (adc_key_in < 380) return btnDOWN;
if (adc_key_in < 555) return btnLEFT;
if (adc_key_in < 790) return btnSELECT;
*/

return btnNONE; // when all others fail, return this.
}
//ボタン//

void setup() {
Serial.begin (9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);

lcd.begin(16, 2);
lcd.setCursor(0,0);
lcd.print("HC-SR04 TEST");
lcd.setCursor(0,1);
lcd.print("PUSH SELECT");
}

void loop() {
lcd_key = read_LCD_buttons();

if(lcd_key==btnSELECT){
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Distance =");


long duration, distance;
digitalWrite(trigPin, LOW); // Added this line
delayMicroseconds(2); // Added this line
digitalWrite(trigPin, HIGH);
// delayMicroseconds(1000); - Removed this line
delayMicroseconds(10); // Added this line
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration/2) / 29.1; //"29.1"=超音波が1cm進むのに必要な時間(us)
if (distance < 4) { // This is where the LED On/Off happens
// digitalWrite(led,HIGH); // When the Red condition is met, the Green LED should turn off
// digitalWrite(led2,LOW);
}
else {
//digitalWrite(led,LOW);
//digitalWrite(led2,HIGH);
}
if (distance >= 200 || distance <= 0){
Serial.println("Out of range");
lcd.setCursor(0,1);
lcd.print("Out of range");
}
else {
Serial.print(distance);
Serial.println(" cm");
lcd.setCursor(0,1);
lcd.print(distance);
lcd.setCursor(5,1);
lcd.print("cm");
}
}
delay(500);
}
--スケッチ終わり--


接続するとこのようになります。

LCDシールドのSELECTボタンを押すと距離が測定できます。





パソコンを置く場所の寸法計測に役立った・・・かな?