ランダムの種?
random()関数は
乱数を発生させる(戻り値を返す)のだが,スケッチが開始されるたびに
同じ順序で乱数を発させてしまう。
つまり,3つ目の数字が「5」であれば必ず3つ目が「5」になる。これでは具合が悪い。
randomSeed()関数を使うと異なる乱数を発生させることができる。
randomSeed(1)とrandomSeed(2)は全く別の乱数になるのだ。
が,やはり()内の数字が同じであればスケッチが開始されるたびに同じ順序の乱数になってしまう。
()内の数字がスケッチ開始ごとに異なればいいのだ。理屈としては。
さて,どうしよう。
PCのプログラムでは,ボタンが押されるまで数字をカウントアップさせるといい。
PCの処理速度は人間にとって高速すぎるので同じ数字を狙うことは不可能だからだ。
random()関数の例では,次のようになっている。
void setup(){
// 省略 randomSeed(analogRead(0)); }
A0ピンに何もつないでいなければ,analogRead(0)の戻り値は不定になる。※1
なので,スケッチが開始されるたびに異なる乱数になるという訳だ。
-------------------------------------------------------
※1 テスターの測定端子(赤,黒)をつながないでおくと値が定まらないのと同じこと。
乱数は本当に乱数か? ランダム関数
擬似乱数か真の乱数かを説明したいのではない。
乱数とは規則性のない数字の羅列だ。よく引き合いに出されるのがサイコロの目。
乱数がイメージしているものとあっているかLEDを使って試してみよう。
まずはランダム関数の説明。reference\index.htmlを開こう。
Syntax
random(max)
random(min, max)
Parameters
min - lower bound of the random value, inclusive (optional)
max - upper bound of the random value, exclusive
Returns
a random number between min and max-1 (long)
min~max -1までの乱数を発生させる。min省略時は0~max -1
例:
// print a random number from 10 to 19 randNumber = random(10, 20);
スケッチで使う関数を調べる
大切なことを忘れていた!!
スケッチで使う関数や制御文などをどうやって調べるかだ。
インストールしたreference\index.htmlに一覧がある。
これは前にもちょっと説明したがまったく解説してなかった。
ブログで何回か使った関数 digitalRead() をクリックすると以下のような説明が現れる。
digitalRead()
Description
Reads the value from a specified digital pin, either HIGH or LOW .
Syntax
digitalRead(pin)
Parameters
pin: the number of the digital pin you want to read (int)
Returns
Example
~
関数の場合,
Description : 関数の説明
Syntax : 書式。digitalRead(pin) のように記述する
Parameters : 引数(ひきすう)。関数に入れる(渡す)値。pinはint型(整数型。改めて説明します)
Returns : 戻り値。HIGH or LOW .を返す
Exampleが続く
「Arduinoスケッチの言語」をもう一度読み返してください。
http://ameblo.jp/empsgs/entry-11513491109.html
main()関数はどこに?
マイクロコンピュータをのソースコード(Arduinoのスケッチですね)をC言語で書いていたり,
C/C++,javaの勉強した人にとって,Arduinoにmain()関数がないことが不思議ではないだろうか。
実は,Arduinoをインストールしたhardware\arduinoにmain.cppがある。
中身はこんな感じ,
#include <Arduino.h>
int main(void)
{
init();
#if defined(USBCON)
USBDevice.attach();
#endif
setup();
for (;;) {
loop();
if (serialEventRun) serialEventRun();
}
return 0;
}
setup()とloop()はここで呼び出されている訳だ。
冒頭のinit()はwiring.c実装され,タイマ,A/D変換,シリアルなどマイクロコンピュータの
初期化をしている。
-------------------------------------------------------------------------
「main()関数がないことが不思議ではないだろうか」と書いたが,Windows開発環境では
main()関数は明示的に記述しない。
なので,コマンドラインとか,特殊な環境? でのソースコートなければmain()関数を知らない
だろうと思う。どうだろうか。
暗くなると光るLED CdSを使う Answer 2
Arduinoで組んでみた。
スケッチは,
int led = 9; // LEDのアノード(anode)は9pin int CdS = 2; // CdSの片側は2pin // the setup routine runs once when you press reset: void setup() { // initialize the digital pin pinMode(led, OUTPUT); // LEDは出力 pinMode(CdS, INPUT); // CdSは出力 } // the loop routine runs over and over again forever: void loop() { int CdS_State = digitalRead(CdS); if(CdS_State == LOW){ // CdSが暗い場合。つまり3V未満 digitalWrite(led, HIGH); // 点灯 } // CdSが明るい場合 else{ // 消灯 digitalWrite(led, LOW); } } 前にも書いたとおり,明るい場所でLEDが消灯するまでVR01をまわして, 指などでCdSのセンサ面を覆ってみる。
------------------------------------------------------
前出の分圧の式 Vin=5V×VR01抵抗値÷(CdS抵抗値+VR01抵抗値)
は比の計算のほうが分りやすいだろうか。
5V : Vin = CdS(Ω) + VR01(Ω) : VR01(Ω)
暗くなるとCdSの抵抗が高くなるため,Vinは低くなる傾向になることがわかる。
暗くなると光るLED CdSを使う Answer
HIGHかLOWの境界は3Vなので,
http://www.arduino.cc/en/Reference/Constants のHIGHの説明
the microcontroller will report HIGH if a voltage of 3 volts or more is present at the pin.
暗いときは3V未満,明るい時に3V以上になるように回路を組めばいい。
抵抗の分圧を使おう。分圧については自分で調べください。
CdSは暗抵抗1MΩ,明抵抗10~20kΩなので,CdS 1MΩで確実に3V未満になるようにすれば
すればよい。CdSは個体差があるのでVR01で調整するのが良いだろう。
さて,そのVR01の抵抗値をどうするかだ。考え方は,
・D2の電圧 Vin=5V×VR01抵抗値÷(CdS抵抗値+VR01抵抗値)
・CdS暗抵抗1MΩ(10の6乗Ω),Vin < 3Vなので,3V = 5V×VR01抵抗値÷(1E6+VR01抵抗値)
・VR01抵抗値は1.5MΩ。薄暗くなったら点灯とすると1MΩ未満だろうか
・明るい場所で消灯するまでVR01をまわして調整
うまくゆくだろうか。
暗くなると光るLED CdSを使う
暗くなると街灯が光る。
日没時間にかかわらず暗くなると点灯するのは,光に反応するセンサを使っているからだ。
CdSと呼ばれる光センサが使われている(らしい)。
CdSは暗いときに抵抗が大きく,光か当たると抵抗が低くなるセンサだ。
メーカーH.P.より引用
http://www.macron.com.hk/photoresistor_mi.htm
この性質を利用して暗くなるとLED点灯ができる。
以前のブログを参照していただきたい。
「ボタンを押すと何が起こるのか? 」
http://ameblo.jp/empsgs/theme-10068903649.html
「アナログ変換 電圧の読み方 ついでに関数電卓」
http://ameblo.jp/empsgs/entry-11517941616.html
CdSは暗抵抗1MΩ,明抵抗10~20kΩとする。どうすればよいか? 回答は次回に。
今後の予定
前回からだいぶ時間が空いてしまった。
その間に,ARDUINO 1.0.5にアップグレードされた。バグフィックスとライブラリの追加など。
さて,今後の予定を思いついたままにピックアップする。
・Arduinoのランダム関数について
・PWM (pulse width modulation) パルス幅変調のおさらい
・D/A変換。専用IC MCP4922を使って
・Arduinoの三角関数の使い方
光の制御もやりたい。
以上はArduinoとは直接関係ないかも。
・回路シュミレータ LTspice IVの使い方
・フィルタについて
・PWMから作った方形波を正弦波にする
・発振回路
フリップフロップ 記憶する回路
追記 2016.04.30
http://www.toyosakiaki.com/disco/archive/?SMCL-296
ほんとは論理演算から説明したかったのだが,行きかがり上フリップフロップの説明。
フリップフロップ回路とは状態を記憶する回路のこと。RSとはリセット,セットを意味する。
今回 Arduinoは電源としてしか使ってません。(スケッチしていないということ)

ボタン1を押すとLEDが点灯する。離しても点灯のまま。
ボタン2を押すとLEDが消灯して離しても消灯しつづける。
点灯状態でボタン1を何回押しても変化なしなのだ。

回路は以下の通り。IC はTC4044を使った。74HC279もほとんど同じ動作をします。
点線の中はフリップフロップの仕組み。

テーマ,デジタル入出力の「ボタンを押すと何が起こるのか?」で説明をしたが,
http://ameblo.jp/empsgs/theme-10068903649.html
(プルアップの説明も思い出してください)
あれは押したら1,離したら0だった。その時の状態しか読み込まない。なのでLEDを点灯させ
続けるにはボタンを押し続けなければならない。
キーワード:論理演算, AND, OR, NAND, NOR, NOT, XOR
オペアンプ よくやる失敗
Q1 ゲイン(増幅率)を5にしたのにVinが1Vのとき出力が5Vにならない。
A1 ほとんどのオペアンプは電源電圧の7割程度の出力しかできない。
出力フルスイングのOPアンプを使う。単電源の場合も同じ。
キーワード:出力フルスイング,Rail to Rail
Q2 出力が3.7Vで変わらない。
A2 R2がつながっていない。振切れていのだがQ1の通り出力フルスイングでないOPアンプでは
電源電圧の7割り程度なのでこのような結果になる。
Q3 出力が安定しない。
A3 バイパスコンデンサのつけ忘れ。
電源にノイズがのっている。レギュレータの発振,電源反転IC(チャージポンプ)のノイズ。
やはり,バイパスコンデンサを見直すこと。
※外来ノイズ除去OPアンプがあるそうだ。LMV8xx,LMP2021,OPAx188
Q4 出力しない。出力がぜんぜん正しくない。
A4 電源入れ忘れ(よくやる)。
1回路入りと2回路入りを間違える。ピン数が同じだから。
Q5 OPアンプが熱い。
A5 「熱い」はかっこいいの意味ではない。触れないほど温度が熱くなること。
動作電源電圧を超えている。V- V+間が最大16V(±8Vということ)なのに±12V電源使っているとか。
データシートの絶対最大定格を確認する。
±の電源が逆など。だから,部品実装する前に電源を確認すること。
オペアンプの逆挿し。何でやるかねぇ。
