goo blog サービス終了のお知らせ 

もんく [とある南端港街の住人になった人]

スペインかポルトガルの港町に住みたい
日本→インドネシア→台湾→マレーシア→日本
since Oct. 2004

サーボの使用を断念すべきか?

2020-05-06 14:50:19 | ABCのAはArduinoのA
今週はサーボが届いていたのでサーボの制御をやってみた。(と、昨日書いた。)

が、断念した方が良いような気がしている。理由は2つ。

小さな理由
起動時に勝手に動く。電源をOFFからONにした時、最初のattach(ピン番号, 最小値, 最大値)の時に動く。
ライブラリを改造すれば良いのかと思って見たがわからなかった。
なので回避する手段はリレーでこの瞬間だけPWM信号線をカットする事か?

大きな理由
サーボは自分の位置を把握する手段が無い。だから脱調してしまった時に自ら暴走を止める事ができない。プログラムもそれを検知できない。サーボが動かす相手は重い物なのでこれはとても危険だ。


そう書いているうちに1つ対策を思いついた。
簡単に言うと、同じ位置への移動命令を何回も繰り返す事。
脱調を始めると位置が遠くまでズレるか回転してしまうので命令を出した後にすぐに停止命令を出す。停止命令の後に再度同じ場所への移動命令を出す。これを何回も繰り返す、と言うわけ。これが可能な事なのかわからないが、何回もテストして脱調が無くなるかを確認してみる事にする。

これは元の対策前プログラム。



これが対策した部分。

AI デバイスがもう届いた

2019-08-19 13:43:19 | ABCのAはArduinoのA
最近Aliexpressの配送がとても速い。
前はちゃんと1ヶ月かかっていたのに前回も今回も10日ほどで到着。
こう言う事されるとAmazonも勝てないかもしれないな。ビックリだよ。



そうそう、その前に、ビザ更新で配偶者との結婚証明書が必要になったらしい。前回までは不要で、この会社に入った最初の時には必要だった。もう要らないと思って用意していなかったので日本の母に送ってくれるよう頼んだ。(3ヶ月以内の戸籍謄本が必要。領事館で翻訳してもらう。もし6ヶ月以内の物を持っていれば結婚証明書の代わりに家族証明書と言うのを作ってはもらえるそう。領事館さん、丁寧に案内いただいてありがとう。)










と言うわけで、パッケージを開けてみた。思ったより小さい。
通販で買う物は必ずいつも到着してみると小さいなと感じる。期待が大き過ぎるからか? いや、実際にももちろんArduino Unoよりかなり小さいし、NodeMCU互換機よりも小さい。その中にカメラとスピーカーとSDカードスロットと液晶とバッテリー、全部入っているし、CPUの速度も速いそうだから驚き。

M5stickVにUSBで電源を入れてみると、早速顔認識していた。だからと言ってそれ以上何かできるかと言うとわからないが。デモなんだろう。まあいい。

さてこれから何かやってみるのだけど、もう1つ買ったSDカードがまだ来ていない。そっちもすぐに来るはず。

プログラミングの学び方は

2019-06-04 14:14:57 | ABCのAはArduinoのA
MicroPythonの実質第1号プログラムができた。

ここに来るまで約1週間。やっとまともに動いたと言うところ。



昨日も書いたように、サンプルプログラムがわかりにくいので引っかかる。ただその前にも引っかかるところは別にある。プログラミングに入る前の「作法」がよそ者にはわからないって事。


MicroPythonをどうやってコントローラに入れたら良いのか? ネットで調べる。いろいろ書いてあって、このコマンドラインで動くツールを使えとなっている。コマンド? Windowsに付いてるので良いの? 調べる。TeraTermが良いとか、他のターミナルソフトが良いとか書いてある。いったいどれが標準的なやつなんだ? 標準的なのでないとネットで調べてやってみる時に違って混乱するかもしれないし。と、xxと言う会社が出してるこの無料ツールだとコマンド無しでも簡単とか? じゃそれいただき。あれ? また調べる。実はコッチのツールの方がもっと簡単。よし、乗り換え。....何だ、早く言ってくれよ。今までの知識全部クリア。

さてさて、これでできるはず。何?ライブラリ入れろって? ここからダウンロードして、あれ?セットアップのプログラム付いてるけど、これ使う前にパソコンにPython入ってないと動かないじゃん! 調べる。なんだ、セットアップなんか必要なくてただコピーして入れとけば良いだけかよ。作業フォルダに入れると勝手に使えるようになるのか? あれ、使えない? 調べる。なるほど、コントローラの中にコピーしておかないといけないのか。どうやって? 調べる。(ずっと前のところに危うく戻りそうになる。) が、なるほど簡単な方法があるじゃないか! よしこれでOK。

サンプルプログラムを動かして本当にここまでのやり方で良かったか検証してみよう。ええっと、サンプルプログラムはと.. おいおい、そんな部品買ってないよ。普通に売ってない部品だし! 仕方ない、ネットで簡単なプログラムが無いか見てみよう。あった、このパーツならArduinoを最初に初心者セットで買った時についてきたはず。じゃ、これ動かしてみる。まあ、何となく動く。ソリャだれかが先にやったのコピーしてるんだから動かなかったらおかしい。

と言うような感じでどうにかここまで来た。

だんだんわかって来たのは、よほど新奇な事をやるのでない限り、自分でプログラムをゼロから考えて書いていてはいけないと言う事。多分先人もそうやっていると思うけれど、他人の組んだプログラムをコピーして要らないところを削って取っておいて使うのが良いよう。短いプログラムでもゼロから書くのはとても大変。まず初心者は「,」とか「:」をうっかり忘れる。変数の綴りを間違える。その上に文法もちゃんと間違える。ちょっとした事でもどう間違っているのか理解するのが大変だ。それに実行中のプログラムを途中で止めるだけでわからないメッセージが出てきていちいち調べないといけないから面倒臭いと言ったらない。

と言うわけで、極力考えない事にしておまじないは全部コピーで済ます。それでスピード上げて行こうぜ。


最後になってしまったけれど、これで何をやったかと言うと、部屋の温湿度をAmbientと言うインターネット上のサービスに送ってリアルタイムで更新されるグラフで見えるようにした。温湿度なのはたまたまセンサーがあったから。

スピードメーター、インストール完了。

2019-05-09 21:51:22 | ABCのAはArduinoのA
今日やっとスピードメーターのインストール完了。
少し間違いがあって修正はしてけれどこれでどうにか動いている。

大きな間違いは浮動小数点の扱い。
誰かのブログに書いてあったのをそのまま使ったのでなぜダメなのかわからなかったけれど面倒なので最も簡単な方法で修正。

それと同じような計算を関数にせずコピペしたからその時に変数を書き換えるのを数ヶ所忘れていた事。

(この記事には前があるので初めての方は探してみてください。)
↓ちゃんと整形されていない。

#include
#include

#include

// For the Adafruit shield, these are the default.
#define TFT_RST 8
#define TFT_DC 9
#define TFT_CS 10
#define sclk 13
#define mosi 11

// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);

//Analog pin numbers
int If = 0; //Infeed
int G1 = 1; //1u G
int G2 = 2; //2u G
int C2 = 3; //2D Cooling
int G3 = 4; //3u G
int C3 = 5; //3D Cooling

// Gear ratio
const float gIf = 3.2; //Gear set spec 1:3.2
const float gG1 = 3.2; //Gear set spec 1:3.2
const float gG2 = 3.2; //Gear set spec 1:3.2
const float gC2 = 3.2; //Pulley 30:96 =1:3.2
const float gG3 = 3.2; //Gear set spec 1:3.2
const float gC3 = 3.2; //Pulley 30:96 =1:3.2

// Constant for calculation
const float a = 226.08;

// Constant for analog value translation to voltage
const float uV = 0.004883; //=5V/1024

// Speed
float sIf = 0;
float sG1 = 0;
float sG2 = 0;
float sC2 = 0;
float sG3 = 0;
float sC3 = 0;

void setup() {
// TFT
tft.begin();
tft.fillScreen(ILI9341_BLACK);
tft.setRotation(3); //Landscape screen

// for serial output (Comment out when running)
Serial.begin(9600);

}

void loop() {
// 5V = 50Hz -> Voltage x 10 = Freq
// Pole = 4
// rpm(motor) = (120 x Freq)/p = 30 x Freq
// rpm(roll) = rpm(motor) / GearRatio
// Speed = rpm(roll) x π x diameter
// diameter = 0.24[m]
// Speed = (226.08 x Voltage) / GearRatio

// Voltage reading
sIf = a * (analogRead(If)*uV) / gIf;
sG1 = a * (analogRead(G1)*uV) / gG1;
sG2 = a * (analogRead(G2)*uV) / gG2;
sC2 = a * (analogRead(C2)*uV) / gC2;
sG3 = a * (analogRead(G3)*uV) / gG3;
sC3 = a * (analogRead(C3)*uV) / gC3;


//for debug only (Comment out when actual running)
//Serial.print ("Infeed :");
//Serial.println (sIf);
//Serial.print ("1u Groll :");
//Serial.println (sG1);
//Serial.print ("2u Groll :");
//Serial.println (sG2);
//Serial.print ("2D Cool :");
//Serial.println (sC2);
//Serial.print ("3u Groll :");
//Serial.println (sG3);
//Serial.print ("3D Cool :");
//Serial.println (sC3);


//for display TFT
tft.fillScreen(ILI9341_BLACK); //screen reset with black color
tft.setCursor(0, 0);
tft.setTextColor(ILI9341_RED); //text color (adjust)
tft.setTextSize(2); //text size (adjust)
tft.println ("Roll SPEED METER"); //Display title
tft.println (" ");
tft.setTextSize(3); //text size

tft.setTextColor(ILI9341_BLUE); //text color
tft.print ("Infeed :");
if (sIf > 500 || sIf < 0){
tft.println ("ERR");
}else{
tft.println (sIf);
//Serial.print("sIf"); //debug
//Serial.println (sIf); //debug
}
tft.setTextSize(1); //gap size
tft.println (" ");

tft.setTextColor(ILI9341_WHITE); //text color
tft.setTextSize(3); //text size
tft.print ("1u Groll :");
if (sG1 > 500 || sG1 < 0){
tft.println ("ERR");
}else{
tft.println (sG1);
//Serial.print("sG1"); //debug
//Serial.println (sG1); //debug
}
tft.setTextSize(1); //gap size
tft.println (" ");

tft.setTextColor(ILI9341_BLUE); //text color
tft.setTextSize(3); //text size
tft.print ("2u Groll :");
if (sG2 > 500 || sG2 < 0){
tft.println ("ERR");
}else{
tft.println (sG2);
//Serial.print("sG2"); //debug
//Serial.println (sG2); //debug

}
tft.setTextSize(1); //gap size
tft.println (" ");

tft.setTextSize(3); //text size
tft.print ("2D Cool :");
if (sC2 > 500 || sC2 < 0){
tft.println ("ERR");
}else{
tft.println (sC2);
//Serial.print("sC2"); //debug
//Serial.println (sC2); //debug
}
tft.setTextSize(1); //gap size
tft.println (" ");

tft.setTextColor(ILI9341_WHITE); //text color
tft.setTextSize(3); //text size
tft.print ("3u Groll :");
if (sG3 > 500 || sG3 < 0){
tft.println ("ERR");
}else{
tft.println (sG3);
//Serial.print("sG3"); //debug
//Serial.println (sG3); //debug
}
tft.setTextSize(1); //gap size
tft.println (" ");

tft.setTextSize(3); //text size
tft.print ("3D Cool :");
if (sC3 > 500 || sC3 < 0){
tft.println ("ERR");
}else{
tft.println (sC3);
//Serial.print("sC3"); //debug
//Serial.println (sC3); //debug
}

delay (500); //checking interval 100=0.1sec

}

スピードメーター完成(のはず)(修正あり)

2019-04-09 22:28:34 | ABCのAはArduinoのA
スピードメーターはたぶん完成したと思われる。実機に取り付けていないのだけれど、入力の値を擬似的に設定してみるとスピードを表示できた。

昨日までこのTFT、動かせないんじゃないかと思っていたが、動いた。何をやったかと言うと、裏面のJ1と言うジャンパをハンダでショートさせて正式に5V仕様に変更しただけ。

これを買った時の商品説明には5Vでも3.3Vでも動くと書いてあった。なので最初はロジックレベルコンバータで3.3Vで動かしてみたがダメだった。レベルダウンせずに5Vでもやってみたがそれもダメ。と言うのが昨日まで。

今朝再度ネット検索すると面白いサイトを見つけた。マニュアル集みたいな英語サイトで、いろいろ丁寧に説明が書いてあった。が、この5Vジャンパ以外別に間違った事はしていないのもわかった。なので半信半疑でハンダブリッジをやってみた。

LCDwiki


あっ、動いた!

ってわけ。これでダメなら実はコントローラがILI9341って買いてあったけれど実はデタラメじゃないかと疑おうとしていたのだった。

スケッチはこんな感じ。
前にも書いた通り、誰かがメンテナンスできるように初歩的な書き方しかしていない。


#include
#include

#include

// For the Adafruit shield, these are the default.
#define TFT_RST 8
#define TFT_DC 9
#define TFT_CS 10
#define sclk 13 //要らないかも。スタディしながら書いてたのが残ってた。
#define mosi 11 //これも不要。

//おまじない。↓
// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);


//Analog pin numbers アナログピンの番号指定。
int If = 0; //Infeed
int G1 = 1; //1u G
int G2 = 2; //2u G
int C2 = 3; //2D Cooling
int G3 = 4; //3u G
int C3 = 5; //3D Cooling

// Gear ratio ギヤがあるのでギヤ比
const float gIf = 3.2; //Gear set spec 1:3.2
const float gG1 = 3.2; //Gear set spec 1:3.2
const float gG2 = 3.2; //Gear set spec 1:3.2
const float gC2 = 3.2; //Pulley 30:96 =1:3.2
const float gG3 = 3.2; //Gear set spec 1:3.2
const float gC3 = 3.2; //Pulley 30:96 =1:3.2

//スケッチ内で計算しなくて良いように定数をまとめた
// Constant for calculation
const float a = 226.08;

// Speed スピードの変数指定 単位はm/min
float sIf = 0;
float sG1 = 0;
float sG2 = 0;
float sC2 = 0;
float sG3 = 0;
float sC3 = 0;

void setup() {
// TFT おまじない
tft.begin();
tft.fillScreen(ILI9341_BLACK); //全面黒で塗り潰し
tft.setRotation(3); //Landscape screen //画面の向き指定

// for serial output (Comment out when running) デバッグ用
//Serial.begin(9600);

}

void loop() {
//後から見る人への解説
// 5V = 50Hz -> Voltage x 10 = Freq
// Pole = 4
// rpm(motor) = (120 x Freq)/p = 30 x Freq
// rpm(roll) = rpm(motor) / GearRatio
// Speed = rpm(roll) x π x diameter
// diameter = 0.24[m]
// Speed = (226.08 x Voltage) / GearRatio

// Voltage reading アナログ電圧読み込み
sIf = a * analogRead(If) / gIf;
sG1 = a * analogRead(G1) / gG1;
sG2 = a * analogRead(If) / gG2;
sC2 = a * analogRead(G1) / gC2;
sG3 = a * analogRead(If) / gG3;
sC3 = a * analogRead(G1) / gC3;

// Voltage reading debug onpy (comment out while run) デモ用
// Input voltage simulation
//sIf = a * 0.01 / gIf;
//sG1 = a * 1.00 / gG1;
//sG2 = a * 2.00 / gG2;
//sC2 = a * 3.00 / gC2;
//sG3 = a * 4.00 / gG3;
//sC3 = a * 5.00 / gC3;


//Debug only (comment out when run) デモ用
//sIf = a * 1 / gIf; //If=1V
//sG1 = a * 2 / gG1; //G1=2V
//sG2 = a * 3 / gG2; //G2=3V
//sC2 = a * 4 / gC2; //C2=4V
//sG3 = a * 5 / gG3; //G3=5V (Max voltage value)
//sC3 = a * 6 / gC3; //C3=6V (impossible)

//for debug only (Comment out when actual running) デバッグ用
//Serial.print ("Infeed :");
//Serial.println (sIf);
//Serial.print ("1u Groll :");
//Serial.println (sG1);
//Serial.print ("2u Groll :");
//Serial.println (sG2);
//Serial.print ("2D Cool :");
//Serial.println (sC2);
//Serial.print ("3u Groll :");
//Serial.println (sG3);
//Serial.print ("3D Cool :");
//Serial.println (sC3);


//for display TFT ここからTFT表示

//最初に画面上にタイトルを表示
tft.fillScreen(ILI9341_BLACK); //screen reset with black color
tft.setCursor(0, 0);
tft.setTextColor(ILI9341_RED); //text color (adjust)
tft.setTextSize(2); //text size (adjust)
tft.println ("Roll SPEED METER"); //Display title
tft.println (" ");
tft.setTextSize(3); //text size

//ここから下が各スピードの表示

tft.setTextColor(ILI9341_BLUE); //text color
tft.print ("(回転物1) :");
if (sIf > 500 || sIf < 0){ //値が変な時はエラー表示
tft.println ("ERR");
}else{
tft.println (sIf);
}
tft.setTextSize(1); //gap size
tft.println (" ");

tft.setTextColor(ILI9341_WHITE); //text color
tft.setTextSize(3); //text size
tft.print ("(回転物2) :");
if (sG1 > 500 || sG1 < 0){
tft.println ("ERR");
}else{
tft.println (sG1);
}
tft.setTextSize(1); //gap size
tft.println (" ");

tft.setTextColor(ILI9341_BLUE); //text color
tft.setTextSize(3); //text size
tft.print ("(回転物3) :");
if (sG2 > 500 || sG2 < 0){
tft.println ("ERR");
}else{
tft.println (sG2);
}
tft.setTextSize(1); //gap size
tft.println (" ");

tft.setTextSize(3); //text size
tft.print ("(回転物4) :");
if (sC2 > 500 || sC2 < 0){
tft.println ("ERR");
}else{
tft.println (sC2);
}
tft.setTextSize(1); //gap size
tft.println (" ");

tft.setTextColor(ILI9341_WHITE); //text color
tft.setTextSize(3); //text size
tft.print ("(回転物5) :");
if (sG3 > 500 || sG3 < 0){
tft.println ("ERR");
}else{
tft.println (sG3);
}
tft.setTextSize(1); //gap size
tft.println (" ");

tft.setTextSize(3); //text size
tft.print ("(回転物6) :");
if (sC3 > 500 || sC3 < 0){
tft.println ("ERR");
}else{
tft.println (sC3);
}

delay (200); //checking interval 100=0.1sec

}


前提条件として、これはYokogawaのインバータの多機能アナログ出力をアナログ入力する事を想定。出力のタイプは回転数 (回転数をDC電圧に読み替えて出力している)。アナログ最大出力はデフォルトで10Vなのでゲインを50%に設定して最大出力が5Vになるようにする。






修正 2019/04/10

上記のスケッチに間違いがあるので下記のように修正します。

変数uVの追加


アナログ読込値を電圧に変換する。


アナログ値が直に電圧の値になっていると思い込んでスケッチを書いてしまったが、そんなわけはないので電圧値に変換するように式を変更した。


機械が便利になっても使わないわけ

2019-04-03 23:18:51 | ABCのAはArduinoのA
趣味のプロジェクト発進と1月30日に書いていた後、たまにスケッチ (プログラム) も書いていた、他の仕事をしながら。

それが昨日と今日にかけて完成っぽくなってきた。なぜ「っぽく」かと言うとまだハードウェアが無いから。いつもやりかただと、ハードウェアを用意してからスケッチなのだけど、まあ、簡単な物になる予定だし。なのでスケッチも簡単。

と言うか、超簡単にしとかないと後で誰が見るかわからないから必然的にそうなるべきなのだ。あまり効率を求めて配列とかいろいろテクニック使うより実用とメンテナンス性を重視。処理スピードは求めないし、壮大なプログラムでもない。


ところで、この趣味のプロジェクト、作っても使われない可能性が高い。と、前回も書いたっけ?

と言うのは、これとは別に材料の特性を使う前に知るための物を作ったのだけれど、昨日書いたように使われていなかった。直接の原因が今日はっきりわかって、それは測定用のある小さな機械が壊れたからと、もう1つは表示用のPCが壊れたからだった。

両方いっぺんに壊れるはずないのでどっちかがダメになって何かして両方壊してしまったらしい。まあ、何か壊れるのはあり得るから良いとして、それを報告しないまま何もしていないと言うのが、新しい物を置いても使われないだろうと思う根拠だ。


日本から新たに来たマネージャーがそれを知らないわけは無いのだけれど、騒ぎもせず放っておくと言うのは簡単に言って重要と思っていない証拠だろう。

その理由は想像が付く。日本ではそんな事やってないでも生産できているから。じゃ、なぜできているかは半分は日本の機械の方が完全自動機で少し方式も違うからあまり細かくやらなくても機械がやってくれると言う事。もう半分はたぶん偶然できているのがその理由。

偶然となぜ言えるかと言うと、前に開発の人が来てテストした時に、なぜ同じにやって違ってしまうかがわからなかった時にわかった。日本で偶然機械がカバーしてくれてた事が何か彼らには分からなかったのだ。あの時言われた通りに日本式でやっていたら工程の管理なんてできていなかったはず。

そんな事もだいたい分からないと言うか、わかろうとしないわけで、不具合が出た時だけ騒ぐのでただ単に日本方式でやりたがる。


そう言うわけで、スピードメーターを作っていて、これがあればもしかしたらある問題の真相が判明するかも知れないし、もっと作業も簡単になるかもと思うわけだけれど、まあ、使わないだろうなと思っている。

でも、作る自分にとっては良いのだ。自分の勉強になるから。今のところそれ以外に目的は無い。

TFTでスクロールするグラフを表示したい

2018-09-01 23:59:59 | ABCのAはArduinoのA


ありそうで意外と無いのがこのようなスクロールして時系列で表示するグラフの描き方。もっとポピュラーなものかと思っていたが、そうでもなたった。

スクロールしないのは多くある。スクロールしないものは、グラフのプロットが右端まで行くと全体を消してまだ左端からプロットが始まると言うタイプ。でもそれでは読み難い。左端に戻った時にそれ以前との関連がわからなくなる。

なのでスクロールは必須だ。

今日1日そのスケッチの描き方を探してみたが、見つかったのは結局上のYoutube動画のみ。

でもこの機能が自由に使えればかなり使途は広がるはず。なのでもう少し探す事にしよう。

透過濃度計プロジェクト 1話完結 (追加)

2018-08-14 23:28:21 | ABCのAはArduinoのA
久しぶりに作ってみた。透過濃度計。


透過濃度計と言うのは、LEDのライトとCdSを使ってその間に来るフィルム状の物の濃さを測る物。フィルムの色が濃くて光が通らないとCdSの抵抗値が上がり、反対に薄いと抵抗値が下がる。Arduinoのアナログピンで受けるときは濃いと電圧が上がり、薄いと下がる。きれで時間の経過とともに濃さが違って来るかどうかをモニターする。


仕組みは簡単。


CdSは直列に5個接続されていて大きなフィルムの幅方向の平均を取る感じになっている。(生産機械に取り付けているので写真はなし。) 写真は無いがCdSの取り付けステーだけは外注してお金をかけた。他のパーツは全部安い。

出力をどうして確認するかろ言うと、今回はシリアル通信でPCに送って表示する事にした。LCDを買ってグラフ表示しようかと当初は思っていたのだけれどど、これがなかなか情報が少なくて調べ難かった。何かちょっと面倒らしい。

なので、安易な方法としてPCの画面にプロットする事にした。
候補は以下。
1) Arduino IDEのシリアルプロット機能。
これは便利だけれどXY軸のメモリが自分で変えられない。なので止めた。

2) 国産のあるソフト。
英語表記にならないから止めた。使うのは日本人では無いので日本語表記では困る。良いソフトだったが残念ながら使えない。

2) SerialPlot
(最初書いた時とリンクのURLを変更している。)
なかなか良いのでこれを使うことにした。
ちょっと最初、設定をどうするかわからなかったけれど、わかってみると難しくもない。

Arduinoでシリアル通信をONにし、シリアルプリントでPCのデータを送る。データ型は今回はfloatで小数点以下2桁に制限。どうせ人間が見るからそれ以上は要らない。またArsuinoから送られて来るのはASCIIコードだそうなので、SerialPlotではそう言う設定もできる。


アナログ値を読んで認識されるのは0〜1023の整数値だそうなので、それを電圧値に計算で求め、その計算結果をPC上のSerialPlotで受けてグラフ表示する。

スケッチ....わざわざ書かなくても良い位簡単。プロットへの出力をなぜ電圧にしているかと言うと、将来別の方法で読む事になった場合、値が大きく違ってしまうから。今回のこれの前はデータロガーでやっていたのでそれに合わせていると言う事もあり。

下にスケッチを追加しておいた。時間待ちのところなど素人丸出しの組み方だけれど、用は足りる。変数T1はグルーバル変数にする必要は無いが、最初にそう書いてしまったのでそのまま。値を電圧に変換するところの計算式に数字がそのまま入っていてカッコ悪いが1回しか使わないし、まあ良い事にしよう。ちなみに値は1ビット変化した時の電圧に相当。つまり5V÷1024の値。(0〜1023のステップ数)

あ、まずい! 0.00489じゃなくて0.00488だ。細かい事は気にしない気にしない。

データの取得とプロットは6秒置き。これはプロセス上そんなに頻繁に見ないければならないほど値が変わるとは思っていないため。それにデータを見て対処するのは人間の仕事なので1分に1回の取得でも間に合う位。ただ、あまり間を開けると作業員が動いてるかフリーズしてるかわからないので1分に10回にしている。

2.4インチTFT液晶を買ってみた その3

2018-04-29 17:12:38 | ABCのAはArduinoのA
早速、温度センサーの読み取りスケッチをミックスしてみた。以前にSD18B20を9個使って作ったシステムがあるのでそれをほぼそのまま書き込んだ。が、まだ実際のセンサーがArduinoに接続されていないので-127℃表示になっている。接続すれば多分このままで動くんじゃないかと思う。

以前のセンサーはもう機械に付いているが、それの場所を移動してこの液晶に交換しようか?

スケッチはこちら。

----------------------------------------------

//Temp. checking with DS18B20 sensors + 2.4inch TFT

//DB12B20 Library 温度センサーのライブラリ
#include
#include

//2.4 TFT Library
#include // Core graphics library
#include // Hardware-specific library

//2.4 TFT section
// The control pins for the LCD can be assigned to any digital or
// analog pins...but we'll use the analog pins as this allows us to
// double up the pins with the touch screen (see the TFT paint example).
#define LCD_CS A3 // Chip Select goes to Analog 3
#define LCD_CD A2 // Command/Data goes to Analog 2
#define LCD_WR A1 // LCD Write goes to Analog 1
#define LCD_RD A0 // LCD Read goes to Analog 0

#define LCD_RESET A4 // Can alternately just connect to Arduino's reset pin

// Assign human-readable names to some common 16-bit color values:
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF

Adafruit_TFTLCD_ILI9342 tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
// If using the shield, all control and data lines are fixed, and
// a simpler declaration can optionally be used:
// Adafruit_TFTLCD tft;


//DB18B20 section 液晶シールドで使っていないピンが0番と1番しかない。
#define ONE_WIRE_BUS 1 //Sensor pin No. (Yellow wire)
#define SENSER_BIT 9 //Sensing resolution setting

//SD18B20 Lib. special command 温度センサーのおまじない。
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

//SD18B20 each sensor ID (fill up manually) センサー変更したら書き換えせよ。
DeviceAddress sens1D1Z = { 0x28, 0xFF, 0x4A, 0xDE, 0x93, 0x16, 0x5, 0xBD };
DeviceAddress sens1D2Z = { 0x28, 0xFF, 0x89, 0x28, 0x94, 0x16, 0x5, 0xD3 };
DeviceAddress sens2D1Z = { 0x28, 0xFF, 0xC7, 0xE0, 0x93, 0x16, 0x5, 0xC7 };
DeviceAddress sens2D2Z = { 0x28, 0xFF, 0xFF, 0x40, 0x8C, 0x16, 0x3, 0x1C };
DeviceAddress sens3D1Z = { 0x28, 0xFF, 0x2C, 0x8E, 0xA1, 0x16, 0x4, 0x27 };
DeviceAddress sens3D2Z = { 0x28, 0xFF, 0x95, 0xE7, 0xA1, 0x16, 0x3, 0x1B };
DeviceAddress sens4D1Z = { 0x28, 0xFF, 0x89, 0xE3, 0xA1, 0x16, 0x3, 0x48 };
DeviceAddress sens4D2Z = { 0x28, 0xFF, 0x42, 0x91, 0xA1, 0x16, 0x4, 0x36 };
DeviceAddress sens4D3Z = { 0x28, 0xFF, 0xCC, 0x93, 0xA1, 0x16, 0x4, 0x58 };

// Gloval valiables for temp. 温度の値を書き込む変数の定義。
float temp1D1Z;
float temp1D2Z;
float temp2D1Z;
float temp2D2Z;
float temp3D1Z;
float temp3D2Z;
float temp4D1Z;
float temp4D2Z;
float temp4D3Z;


void setup(void) {

//2.4 TFT section (initialize)
tft.reset();
tft.begin();

//SD18B20 section (initialize) センサーの初期化。
sensors.setResolution(SENSER_BIT);
sensors.begin();


}

void loop(void) {

sensors.requestTemperatures(); //Temp. reading request 温度読み取り命令

//inserting Temp. value into valiables 温度の値を変数に入れる。
temp1D1Z = sensors.getTempC(sens1D1Z);
temp1D2Z = sensors.getTempC(sens1D2Z);
temp2D1Z = sensors.getTempC(sens2D1Z);
temp2D2Z = sensors.getTempC(sens2D2Z);
temp3D1Z = sensors.getTempC(sens3D1Z);
temp3D2Z = sensors.getTempC(sens3D2Z);
temp4D1Z = sensors.getTempC(sens4D1Z);
temp4D2Z = sensors.getTempC(sens4D2Z);
temp4D3Z = sensors.getTempC(sens4D3Z);

uint8_t rotation=1; //Set LCD direction 0,1,2,3
tft.setRotation(rotation);

testText(); //Text drawing function

delay(10000); //Drawing interval
tft.fillScreen(BLUE);
delay(1000);

}


unsigned long testText() {
tft.fillScreen(BLACK); //Fill screen with color first

tft.setCursor(0, 0); //Set origin point

tft.setTextSize(2); //Text size
tft.setTextColor(RED); //Text color
tft.println("TEMP. CHECK"); //output

tft.setTextSize(1);
tft.println();

tft.setTextSize(3);
tft.setTextColor(WHITE);
tft.print(" 1D1Z ");
tft.println(String(temp1D1Z, 1)); //Limit No. of digit

tft.print(" 1D2Z ");
tft.println(String(temp1D2Z, 1)); //小数点以下を1桁にした。

tft.println();

tft.setTextColor(GREEN);
tft.print(" 2D1Z ");
tft.println(String(temp2D1Z, 1));

tft.print(" 2D2Z ");
tft.println(String(temp2D2Z, 1));

tft.println();

tft.setTextColor(WHITE);
tft.print(" 3D1Z ");
tft.println(String(temp3D1Z, 1));

tft.print(" 3D2Z ");
tft.println(String(temp3D2Z, 1));

tft.println();

tft.setTextColor(GREEN);
tft.print(" 4D1Z ");
tft.println(String(temp4D1Z, 1));

tft.print(" 4D2Z ");
tft.println(String(temp4D2Z, 1));

tft.print(" 4D3Z ");
tft.println(String(temp4D3Z, 1));

}


つづく

2.4インチTFT液晶を買ってみた その2

2018-04-29 14:28:11 | ABCのAはArduinoのA
ライブラリを使うとプログラムの中にライブラリローカルのコマンドが出てくるので使い方を探らないといけないが、液晶表示パネルがタッチスクリーンになっていてしかもSDカードスロットまで付いていると言う複雑なデバイスだと面倒だ。

でも使いたい機能は表示だけだし、表示するものだって文字だけで良い。なのでサンプルスケッチを良く見て極力シンプルなスケッチにする事にする。

その練習用スケッチはこれ。
(IDEにコピーするとちゃんとした表示になります。)

----------------------------------------------


// IMPORTANT: Adafruit_TFTLCD LIBRARY MUST BE SPECIFICALLY
// CONFIGURED FOR EITHER THE TFT SHIELD OR THE BREAKOUT BOARD.
// SEE RELEVANT COMMENTS IN Adafruit_TFTLCD.h FOR SETUP.

#include // Core graphics library
#include // Hardware-specific library

// The control pins for the LCD can be assigned to any digital or
// analog pins...but we'll use the analog pins as this allows us to
// double up the pins with the touch screen (see the TFT paint example).
#define LCD_CS A3 // Chip Select goes to Analog 3
#define LCD_CD A2 // Command/Data goes to Analog 2
#define LCD_WR A1 // LCD Write goes to Analog 1
#define LCD_RD A0 // LCD Read goes to Analog 0

#define LCD_RESET A4 // Can alternately just connect to Arduino's reset pin

//ここから上はサンプルスケッチから変えてない。
//どのピンを何に使っているか知らないし考える必要が無さそうだから。

// Assign human-readable names to some common 16-bit color values:
//色はカラーコード調べるのが面倒だからサンプルのままにした。

#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF

Adafruit_TFTLCD_ILI9342 tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
// If using the shield, all control and data lines are fixed, and
// a simpler declaration can optionally be used:
// Adafruit_TFTLCD tft;
//この上、何だかわからないのでそのままにした。おまじないだろう。


//サンプルではPC側シリアルにいろいろ出力があったが、
//要らない感じだったのでそこは全部削除した。
//なので下記のように非常にシンプルになった。
void setup(void) {

tft.reset();
tft.begin();

}


//loopの中はもともと簡単だったけれど、時々画面の向きを変える命令が入っていた。
//向きは一定のつもりなので削除した。
//uinit8_tと言うのを始めて知ったがintとかと同じ類らしい。放って置く。
//画面の向きはデフォルトが0で横長、1は縦、2と3はそれぞれの逆向き。

void loop(void) {

uint8_t rotation=1; //Set LCD direction 0,1,2,3
tft.setRotation(rotation);

testText(); //Text drawing function 文字表示のサブルーチンみたいなの。

delay(10000); //Drawing interval

tft.fillScreen(BLUE); //画面更新がわかるように青画面を1秒入れた。
delay(1000);

}


ここからが実際の画面表示のルーチン。

unsigned long testText() {
tft.fillScreen(BLACK); //Fill screen with color firstまず全面黒にする。

tft.setCursor(0, 0); //Set origin point原点を指定。

tft.setTextSize(2); //文字サイズ。1行目はサイズ2。
tft.setTextColor(RED); //文字色を赤にする。
tft.print("TEMP. CHECK"); //表示
tft.println(); //空白を表示。(前行をtft.printlnにすれば要らない。消し忘れ。)

tft.setTextSize(1); //最少の空白行を入れている。
tft.println();

tft.setTextSize(3); //ここから後は文字サイズ3になる。
tft.setTextColor(WHITE); //ここから後は文字色は白になる。
tft.print(" AAA1 ");
tft.println(86.3);

tft.print(" AAA2 ");
tft.println(88.2);

tft.println();

tft.setTextColor(GREEN); //ここから後は緑文字。サイズは変えない。
tft.print(" BBB1 ");
tft.println(65.4);

tft.print(" BBB2 ");
tft.println(63.2);

tft.println();

tft.setTextColor(WHITE); //白文字に戻る。
tft.print(" CCC1 ");
tft.println(84.7);

tft.print(" CCC2 ");
tft.println(87.9);

tft.println();

tft.setTextColor(GREEN); //緑文字に戻る。
tft.print(" DDD1 ");
tft.println(87.4);

tft.print(" DDD2 ");
tft.println(83.7);

tft.print(" DDD3 ");
tft.println(88.4);

}



----------------------------------------------

このスケッチを書きながらいろいろ試してみた。

まず、文字の大きさはどの位が良いか?
これは見た目でサイズ3に決定。サイズ3でどれだけの文字数が入るかのテストもしてみた。



13x13なのでサイズ3で十分とわかる。必要な行数は最低9行だから。

一応出来上がり予想画面はこうなった。
左に計測点の名前、と言うか記号で、その右に温度の数値が出る。今のところ未だセンサーは無いので数値はスケッチ上に直接数値を書いてある。



計測は数十秒毎か1分毎でも構わないので表示の更新は緩慢。いつ変わったかわかりにくいので更新前にブルースクリーンが1秒程度出るようにした。それでフリーズせずに動いているとわかると言う意味もある。




この後は温度センサーのところに入るつもり。
前に作った温度センサーのスケッチとミックスするだけのはず。
つづく

2.4インチTFT液晶を買ってみた

2018-04-28 22:18:34 | ABCのAはArduinoのA
Arduinoで新しいプロジェクトを始めたいと思っていrので液晶表示器を買ってみた。

プロジェクト始める前にちょっと考えた。前回まではシールドってのをあまり意識して来なかったのだけど、使うべきかなと。ちょっとした物だとシールドじゃなくてパーツで買ったら安いのだけれど、少し複雑になるとハンダ付けしないといけなくなって、その部分で信頼性も落ちるしデバッグが大変になる。なので出来るだけ止めよう。そして回路組むのとプログラミングに集中すべきだなと。

さて、前置きが長くなってしまったが、2.4インチ液晶、これもシールドでUnoにポン付けできる。ハンダ付けしないでこうしてゲームみたいなデモが表示できてしまった。

が、これができたのは先人のおかげです。簡単じゃなかったところを先人がいろいろやってくれたおかげです。
なので、お世話になったサイトを先に紹介します。

ArduinoUNO用のTFTシールド
こちらを読めば買ってきた2.4インチがどんなものであろうとも使えるようになるかもしれません。必見です。

そしてこの下のURLからスケッチをもらって液晶ドライバーの特定をします。
いろいろあって何が当たるかわからないそうです。
LCD_ID_readreg


今回かったのは ILI9342 でした。

なので次にお世話になったのはこちら。英語サイトですが、難しくはありません。

Arduino Uno TFT 2.4" ILI9342


あとはここに書いてある通りにライブラリをダウンロードすればOK。
Ili9342 ライブラリ
Touch-Screen-Library
GFX library (これはIDEのライブラリの管理からインストールできる)

デモスケッチはili9342ライブラリの中に3つあるのでどれかを動かしてみる。それが最初の写真。動作確認まで完了。


さて、そこまでは良いけれど、この液晶パネルの実用性の無さは要検討。
それもここでちゃんと言ってくれている。
Arduino互換機花ざかり その2

そんなの買う前に調べとけ、と言われそうだけれど、調べました。今回はこれで良いのです。

なぜなら、必要なピンはたったの1本だから。と言うのは、温度センサーを作るつもりなのだ。でも、温度を測定するポイントは1カ所じゃなく、何と10カ所と多い。でもピン1本で良いのは例の DS18B20 を使う予定だから。

Arduino+複数温度センサー3つ(0m、10m、15m)



ところで、液晶表示のためのスケッチの書き方を探さないと。
つづく

作業ミス撲滅システム その2

2017-09-22 20:37:59 | ABCのAはArduinoのA
作業ミス撲滅システムこれでだいたい終わりにしようと思う。

まあ、後はArduinoへのノイズを考慮して設置する事、PLCからの24V入力(PLCからインジケーターLEDへの入力)線を配線してやれば良いだろう。




スケッチは以下の通り。
前回のスケッチからの変更点は切替スイッチの接点が余っていたのでLEDのテストモードを設けた事。

入力と出力の点数が各14点と決まっているのでサブルーチンと配列でも使って比較するようにすればもう少しスマートになるかと思うけれども、どうせ2つのケースしかないのでこのままにしてしまう。



//INPUT
const int NiIU = 13; //NUW input
const int NiI3 = 12; //N3u input
const int NiI4 = 11; //N4u input
const int NiIW = 10; //NWd input
const int BrI1 = 9; //B1u input
const int BrI2 = 8; //B2u input
const int BrI3 = 7; //B3u input
const int BrI4 = 6; //B4u input
const int HiI2 = 5; //HD2uIN input
const int HoI2 = 4; //HD2uOUT input
const int HiI3 = 3; //HD3uIN input
const int HoI3 = 2; //HD3uOUT input
const int HiI4 = 14; //HD4uIN input
const int HoI4 = 15; //HD4uOUT input

//OUTPUT
const int NiLU = 22; //NUW output
const int NiL3 = 24; //N3u output
const int NiL4 = 26; //N4u output
const int NiLW = 28; //NWd output
const int BrL1 = 30; //B1u output
const int BrL2 = 32; //B2u output
const int BrL3 = 34; //B3u output
const int BrL4 = 36; //B4u output
const int HiL2 = 38; //HD2uIN output
const int HoL2 = 40; //HD2uOUT output
const int HiL3 = 42; //HD3uIN output
const int HoL3 = 44; //HD3uOUT output
const int HiL4 = 46; //HD4uIN output
const int HoL4 = 48; //HD4uOUT output

//SELECT SW
const int NOprd = 20; //Switch input NO PRODUCTION
const int KK105 = 19; //Switch input Prod K
const int SS590 = 18; //Switch input Prod S
const int TESTL = 21; //Switch input LED Test Mode

//Variables
int Prod = 0;


void setup() {

//Debug
// Serial.begin(9600);

pinMode(NiIU, INPUT);
pinMode(NiI3, INPUT);
pinMode(NiI4, INPUT);
pinMode(NiIW, INPUT);
pinMode(BrI1, INPUT);
pinMode(BrI2, INPUT);
pinMode(BrI3, INPUT);
pinMode(BrI4, INPUT);
pinMode(HiI2, INPUT);
pinMode(HoI2, INPUT);
pinMode(HiI3, INPUT);
pinMode(HoI3, INPUT);
pinMode(HiI4, INPUT);
pinMode(HoI4, INPUT);

pinMode(NiLU, OUTPUT);
pinMode(NiL3, OUTPUT);
pinMode(NiL4, OUTPUT);
pinMode(NiLW, OUTPUT);
pinMode(BrL1, OUTPUT);
pinMode(BrL2, OUTPUT);
pinMode(BrL3, OUTPUT);
pinMode(BrL4, OUTPUT);
pinMode(HiL2, OUTPUT);
pinMode(HoL2, OUTPUT);
pinMode(HiL3, OUTPUT);
pinMode(HoL3, OUTPUT);
pinMode(HiL4, OUTPUT);
pinMode(HoL4, OUTPUT);

pinMode(NOprd, INPUT);
pinMode(KK105, INPUT);
pinMode(SS590, INPUT);

}

void loop() {

Prod = 0;  //スイッチのステータスをこれに入れる

//Rotary SW checking

int OFF = digitalRead(NOprd); //No production (Rotary SW home)
int KJ1 = digitalRead(KK105);
int SR5 = digitalRead(SS590);
int TES = digitalRead(TESTL); //Next product

//Debug
// Serial.print(" OFF= ");
// Serial.println(OFF);
// Serial.print("KJ1= ");
// Serial.println(KJ1);
// Serial.print("SR5= ");
// Serial.println(SR5);
// Serial.print(" TES= ");
// Serial.println(TES);

//Machine setting checking
//設定を切り替えスイッチで確認している
//スイッチはどこか1つしかONにしないので順番に接点確認しているだけ
//つまりONがどこか2つの接点で重なる事を想定しないない

if (OFF == HIGH){
Prod = 0;  //スイッチのステータス、この場合はゼロ
OFF = LOW;
}else{    //これはそうでない時何もするなと言う事だが、必要かどうか?
}

if (KJ1 == HIGH){
Prod = 1;
KJ1 = LOW;
}else{
}

if (SR5 == HIGH){
Prod = 2;
SR5 = LOW;
}else{
}

if (TES == HIGH){
Prod = 3; //Not specified product name
TES = LOW;
}else{
}

//Debug
// Serial.print(" Prod= ");
// Serial.println(Prod);
// Serial.println(" ");

//Operation checking (each Product)
//ここからスイッチのステータス毎のプログラムが動く

switch (Prod){

//OFF case

case 0:

// Serial.println("OFF");

delay(1000);
digitalWrite(NiLU, LOW);
digitalWrite(NiL3, LOW);
digitalWrite(NiL4, LOW);
digitalWrite(NiLW, LOW);
digitalWrite(BrL1, LOW);
digitalWrite(BrL2, LOW);
digitalWrite(BrL3, LOW);
digitalWrite(BrL4, LOW);
digitalWrite(HiL2, LOW);
digitalWrite(HoL2, LOW);
digitalWrite(HiL3, LOW);
digitalWrite(HoL3, LOW);
digitalWrite(HiL4, LOW);
digitalWrite(HoL4, LOW);

break;

//KK105 case
case 1:

// Serial.println("KK105");

if (digitalRead(NiIU) == HIGH){ //この設定ではここがONなら正常
digitalWrite(NiLU, LOW);
}else{
digitalWrite(NiLU, HIGH); //WARNING
}

if (digitalRead(NiI3) == HIGH){
digitalWrite(NiL3, LOW);
}else{
digitalWrite(NiL3, HIGH); //WARNING
}

if (digitalRead(NiI4) == LOW){ //この設定ではここがOFFなら正常
digitalWrite(NiL4, LOW);
}else{
digitalWrite(NiL4, HIGH); //WARNING
}

if (digitalRead(NiIW) == HIGH){
digitalWrite(NiLW, LOW);
}else{
digitalWrite(NiLW, HIGH); //WARNING
}

if (digitalRead(BrI1) == LOW){
digitalWrite(BrL1, LOW);
}else{
digitalWrite(BrL1, HIGH); //WARNING
}

if (digitalRead(BrI2) == HIGH){
digitalWrite(BrL2, LOW);
}else{
digitalWrite(BrL2, HIGH); //WARNING
}

if (digitalRead(BrI3) == LOW){
digitalWrite(BrL3, LOW);
}else{
digitalWrite(BrL3, HIGH); //WARNING
}

if (digitalRead(BrI4) == LOW){
digitalWrite(BrL4, LOW);
}else{
digitalWrite(BrL4, HIGH); //WARNING
}

if (digitalRead(HiI2) == LOW){
digitalWrite(HiL2, LOW);
}else{
digitalWrite(HiL2, HIGH); //WARNING
}

if (digitalRead(HoI2) == HIGH){
digitalWrite(HoL2, LOW);
}else{
digitalWrite(HoL2, HIGH); //WARNING
}

if (digitalRead(HiI3) == HIGH){
digitalWrite(HiL3, LOW);
}else{
digitalWrite(HiL3, HIGH); //WARNING
}

if (digitalRead(HoI3) == HIGH){
digitalWrite(HoL3, LOW);
}else{
digitalWrite(HoL3, HIGH); //WARNING
}

if (digitalRead(HiI4) == LOW){
digitalWrite(HiL4, LOW);
}else{
digitalWrite(HiL4, HIGH); //WARNING
}

if (digitalRead(HoI4) == LOW){
digitalWrite(HoL4, LOW);
}else{
digitalWrite(HoL4, HIGH); //WARNING
}

break;

//SS590 case
case 2:

// Serial.println("SS590");

if (digitalRead(NiIU) == HIGH){
digitalWrite(NiLU, LOW);
}else{
digitalWrite(NiLU, HIGH); //WARNING
}

if (digitalRead(NiI3) == HIGH){
digitalWrite(NiL3, LOW);
}else{
digitalWrite(NiL3, HIGH); //WARNING
}

if (digitalRead(NiI4) == LOW){
digitalWrite(NiL4, LOW);
}else{
digitalWrite(NiL4, HIGH); //WARNING
}

if (digitalRead(NiIW) == HIGH){
digitalWrite(NiLW, LOW);
}else{
digitalWrite(NiLW, HIGH); //WARNING
}

if (digitalRead(BrI1) == HIGH){
digitalWrite(BrL1, LOW);
}else{
digitalWrite(BrL1, HIGH); //WARNING
}

if (digitalRead(BrI2) == HIGH){
digitalWrite(BrL2, LOW);
}else{
digitalWrite(BrL2, HIGH); //WARNING
}

if (digitalRead(BrI3) == LOW){
digitalWrite(BrL3, LOW);
}else{
digitalWrite(BrL3, HIGH); //WARNING
}

if (digitalRead(BrI4) == HIGH){
digitalWrite(BrL4, LOW);
}else{
digitalWrite(BrL4, HIGH); //WARNING
}

if (digitalRead(HiI2) == LOW){
digitalWrite(HiL2, LOW);
}else{
digitalWrite(HiL2, HIGH); //WARNING
}

if (digitalRead(HoI2) == HIGH){
digitalWrite(HoL2, LOW);
}else{
digitalWrite(HoL2, HIGH); //WARNING
}

if (digitalRead(HiI3) == HIGH){
digitalWrite(HiL3, LOW);
}else{
digitalWrite(HiL3, HIGH); //WARNING
}

if (digitalRead(HoI3) == HIGH){
digitalWrite(HoL3, LOW);
}else{
digitalWrite(HoL3, HIGH); //WARNING
}

if (digitalRead(HiI4) == LOW){
digitalWrite(HiL4, LOW);
}else{
digitalWrite(HiL4, HIGH); //WARNING
}

if (digitalRead(HoI4) == LOW){
digitalWrite(HoL4, LOW);
}else{
digitalWrite(HoL4, HIGH); //WARNING
}

break;


//TEST MODE 全部光らせるだけ
case 3:

// Serial.println("TEST MODE");

digitalWrite(NiLU, HIGH);
digitalWrite(NiL3, HIGH);
digitalWrite(NiL4, HIGH);
digitalWrite(NiLW, HIGH);
digitalWrite(BrL1, HIGH);
digitalWrite(BrL2, HIGH);
digitalWrite(BrL3, HIGH);
digitalWrite(BrL4, HIGH);
digitalWrite(HiL2, HIGH);
digitalWrite(HoL2, HIGH);
digitalWrite(HiL3, HIGH);
digitalWrite(HoL3, HIGH);
digitalWrite(HiL4, HIGH);
digitalWrite(HoL4, HIGH);

delay(1000);

digitalWrite(NiLU, LOW);
digitalWrite(NiL3, LOW);
digitalWrite(NiL4, LOW);
digitalWrite(NiLW, LOW);
digitalWrite(BrL1, LOW);
digitalWrite(BrL2, LOW);
digitalWrite(BrL3, LOW);
digitalWrite(BrL4, LOW);
digitalWrite(HiL2, LOW);
digitalWrite(HoL2, LOW);
digitalWrite(HiL3, LOW);
digitalWrite(HoL3, LOW);
digitalWrite(HiL4, LOW);
digitalWrite(HoL4, LOW);


break;

}
delay(1000);

}

作業ミス撲滅システム その1 (追加あり)

2017-09-03 21:23:35 | ABCのAはArduinoのA
今日はとても簡単なので簡単な回路図のみ。

大型機械を複数人数で同時に操作する。しかも時々操作が違うので怖い。下手すると間違ってもわからない。なので簡単に全体の操作がわかるような物を考えた。

当初は実際に操作する部分にLEDを光らせようとか、操作間違いをLCDに表示しようかと思ったが、止めた。LCDだと情報量は多くなるけれど文字を読まないといけないと言う問題がある。なので作るのも簡単な中央操作パネルに間違いがあればLEDを光らせるような物にした。


入力は機械のPLCが24Vで操作した部位のLEDを光らせるのでそれを入力にする。スケッチはそれが正しいか間違いかを判断して間違いであれば黄色いLEDを光らせる。入力出力ともに14点あるので今回はAruduinoはUNOでなくてMEGAにした。もちろん中国製互換機。

LEDの入出力以外に切替スイッチを付ける。ポジションはOFF(生産なしモード)、製品1モード、製品2モードの3つ。(買ったスイッチにはもう1つ接点があるので将来追加も可能。)

ブレッドボード上ではテストOK。接点が多くてスケッチが大変だけれどやっている事は簡単。
この件、そのうちまた。



追加
スケッチの要点 (全部ではないのでご注意ください)

定義するインプットとアウトプット多数。



中央やや上にロータリースイッチのピン番号を定義。



最初にロータリースイッチを確認して後にどの設定で動作するかを決めている。
"switch case"を使っている。
各caseの最後にbreakが必須。



最初のcase 1 は何もしないモード。



case 2 と 3 は各入力を判断して間違っている場合だけ出力側のLEDを点灯させる。

スピードメーターその後6

2017-08-20 21:37:58 | ABCのAはArduinoのA
調べてみたらスピードメーターを作りたいと言い始めたのは何と1年も前だった。今まで何やってたんだと言うところ。その間、時々やっては中止、やっては中止となっていた。

さて、今回もちょっとやってみている。

今回は超簡単なレシピになっている。超簡単だけれども、なぜか簡単な方が上手く行く。割込みも何も手の込んだ事はやってない。


アイデアとしては単にパルスとパルスの間の時間計測。その計測値から回転物の回転数を計算し、予めわかっている周長を掛けて周速(回転物の外周のスピード)を計算しているだけ。パルスは1回転あたり1回出ると言う想定。

センサーは以前、1年前から考えていた赤外線式ライントレースセンサー。子供がロボットに使うもので赤外線を出す発光部とそれを受ける受光部のペアになっているもの。



//Time checking
unsigned long time_m = 0;   //時間計測するための変数1
unsigned long time_n = 0;   //時間計測するための変数2
unsigned long time_length = 0; //上記2つの差の時間

//Signal checking
int sig01 = 4;   //センサーからの入力(デジタル)

//Speed calculation
const float circm = 0.7536; //外周長:Φ0.24mxπ
int rpm = 0; //回転数
int sp = 0; //スピード(周速)


void setup() {

pinMode(sig01, INPUT);
Serial.begin(9600); //後でLCDに変更したいと思っている
}



void loop() {

//Sensor pulse checking nは前回ONになった時の時刻
time_n = time_m;


if (digitalRead(sig01) == HIGH) { //入力がONになったら時刻計測
time_m = micros(); //Time signal turn ON mに入れる
delayMicroseconds(20); //Chattering proof チャタリング防止(効くかわからない)
time_length = time_m - time_n;

//Speed calculation
rpm = 60E6 / time_length; //回転数=60秒÷パルス間隔時間
sp = rpm * circm; //回転数からスピードを計算

//Serial output for debug
Serial.print("n= ");
Serial.println(time_n);
Serial.print("m= ");
Serial.println(time_m);
Serial.print("Cycle time = ");
Serial.print(time_length);
Serial.println("ms ");
Serial.print(" RPM = ");
Serial.println(rpm);
Serial.print(" SPEED = ");
Serial.print(sp);
Serial.println(" m/min");

while (digitalRead(sig01) == HIGH) {} //Do nothing while stay ON
}

}


※1 チャタリング防止のところはセンサーの種類によるし、やってみないとわからないので適当に調整する事が必要。
※2 回転数を計算するときに小数点以下を切り捨てるために整数型の変数rpmに入れている。
四捨五入するほどの事もないし、計算が速くなった方がメリットがあるから。
※3 上記と同じ意味で変数sp、スピードも整数型にしている。
※4 最後の"while (digitalRead(sig01)...{}"は、信号がONであり続ける間は何もしないと言う意味。ONである間にloop(){...の中を回してしまうと同じONで何回もカウントしてしまうのでOFFになってから回すようにしている。





シリアルへの出力の結果は下記。

time_n= 945672
time_m= 1112620
n= 945672
m= 1112620
Cycle time = 166948ms
RPM = 359
SPEED = 270 m/min

time_n= 1112620
time_m= 1610788
n= 1112620
m= 1610788
Cycle time = 498168ms
RPM = 120
SPEED = 90 m/min

time_n= 1610788
time_m= 1787184
n= 1610788
m= 1787184
Cycle time = 176396ms
RPM = 340
SPEED = 256 m/min


計算は合っているみたいだ。
一番最初はtime_nがゼロだからいい加減になってしまうけれど、まあ最初だけなので良い事にする。計測値はどんどん更新されてしまうわけだし。

また、このスケッチの特徴はパルスが入って来ないと計測値が更新されないと言う事。つまり回転物が止まると出力が無くなる。これもまあ良しとしよう。止まっている時に計測値は必要ないので。

気になるのは、micros()が無限に時間計測しないと言う事。いつかはリセットしてゼロになると思うのでもしかするとtime_lengthの計算がマイナスになってしまう。でもそこにはプラスの値しか入らないので計算値が変になるだろう。が、それもたまになので良いことにしよう。
mがnより大きかったら計算するみたいにしても良いかと思うけれども、たまに来るそれのために毎回チェックしなくてもたまに変な値が出る方がマシかもしれない。どうせ自分で使うわけだし。



さて、今後残る問題は、これをどう表示するかと言う事。
LCDに数字で書くのが簡単なのだけれど、グラフにして表示した方が実用的にはズレがわかって良いようにも思う。が、それをすると(1)グラフィック表示のできる液晶を使うか(2)PCを1台占有してシリアルで信号を送り続ける、あたりを考えないといけない。

どちらもちょっと面倒臭い。コストの問題もある。

グラフを諦めてLED数個でやると言うのもある。なぜならスピード計測が必要な回転物がいくつかあるので、時間で変化するのでなくてそれらの相対的な変化を見ると言うのも目的にかなっているから。

なのでできれば1個のArduinoで数か所同時に計測できれば良いのだけれど、そうするともうちょっと凝ったスケッチにしないといけないだろうし、複数LEDの出力をどうするか考えないといけなくなる。ピンが足りなくなる可能性もある。

となると1個で1計測で並べるのが一番良いかもしれない。パーツ代が安い(センサーはRM5、LCDがRM10、ArduinoUno互換がRM15 合計760円)のでそれもできる。ちょっと考えよう。

オシロスコープ届いたぜ

2017-06-05 22:34:39 | ABCのAはArduinoのA
オシロスコープが、結局オーダーした直後に示されていたのと同じ日程で届いた。途中FedExが1日遅れを通知してきたのに、結局元に戻ったスケジュールで来た。オーダーから何とたった5日で中国からマレーシアへ来たのだった。速い速いFedExさん。エコノミー便なのに。

箱はちょっと潰れていた。メーカー箱にラップをかけてその上から荷造り用テープでミイラになるまで巻いてあった。メーカー箱と外装の間に何のクッションもないから潰れて当然だ。でもまあ、メーカー箱の中が良く出来ていてクッションも分厚いので問題無い。壊れたりしてはいなかった。よかった。

さて、中身の確認。書かれている物はちゃんと全部あった。よしよし。が、これには元からマニュアルは入っていないらしい。それらしきものが何も無い。もしかして、CDROMの中なのか?多分そうだと思う。とすれば、今、家で読めないじゃんか! 困るじゃん! 明日会社でパソコンに突っ込んでコピーしないと。

そうだ、メーカーサイト探してダウンロードしよう。あるある、ダウンロードページ。と喜んだのもつかの間、ダウンロードできない。なぜなら、ユーザー登録の画面にユーザー名、パスワード、もう一回パスワード、メールアドレスと必要な項目を書いて登録ボタンを押す.......押す....押す........押す、けど反応無し。ダメだ。iPadのSafariはダメなのかと思ってスマホのChrome、これもダメ。

あきらめる、今日は。寝る。もう11時になるし。


そう、も1つ誤算。電源ケーブルのプラグがマレーシア式でもなく、日本やアメリカタイプでもない、Oタイプと言う平たい角が3本ばらばらの角度で出ているものだった。幸いにも中国行った時の変換器があるが、もうちょっと汎用的なのは無かったのか?