2020年3月31日火曜日

ロボットブログラミングについて

あまプロではArduinoを使ってロボットブログラミングを行う場合が有ります。

生徒が既成品を買うて来て、作り方等を教える場合も有りますが、日本橋で部品を購入して独自のロボットで行う場合も有ります。
独自というても、ArduinoとDCモータ2個とモータドライバ超音波距離センサの組み合わせなんですけど、色々と嵌まる所が有ったのであメログ。
 
Arduinoだけなら角型乾電池(9V)のみで動くんですが、モータを回すとなると電圧が足らなくなるので単3乾電池(1.5V)が2個要ります。
Arduinoと角型乾電池、モータ2個と単3乾電池2個、それらをつなぐモータドライバ
簡単にはこんな仕組みです。

Arduinoは5Vと3.3Vの電圧を出力する事が出来ますが、今回はArduino自体を角型乾電池(9V)で動かそうとしてるので、モータ2個を回すにはどうしても電圧不足になります…無理に動かすとArduinoやモータドライバが不安定になり最悪壊れてまいます。
なもんで、ドライバを介して単3乾電池2個の電圧でモータを回します。
もう一つ超音波距離センサを動かすにも電圧が要るのですが、これはArduinoの5Vで動作し、Arduinoが不安定になる事も有りませんでした。
その他、ギアボックスやキャタピラやブレードボードやビニール線や電池ボックス等々…全部で日本橋で7000円(税込)で買えました。

工具は半田ごてセットとニッパとラジオペンチとネジドライバ(モータドライバとはちゃうよ) 合わせて2000円くらいかな?百均ならもうちょい安く揃えられるかも。

これらを駆使して、頑張ってロボットを組み立てます。

では次、いよいよプログラミング。
ArduinoはC言語みたいなのでプログラミング出来るんですが…正直子供向けのプログラミング教室には敷居が高過ぎます。
なもんで、Scratchに慣れた子どもにはBlocklyDuinoでプログラミングしてもらいます。
こちらScratchの様に予め用意されたブロックを組み合わせるだけで、Arduinoのコードを生成してくれる優れ物です。
日本語やにほんごにも対応してくれますので、これとArduinoIDEが有れば簡単なロボットプログラミングは出来てしまいます。
固有のライブラリをインクルードするとかは(今の所)無理なので、その場合は直接ArduinoIDEでコーディングするしかないんかな?

距離を測る場合は、標準のBlocklyDuinoでは出来ないんですが、設定画面で機能追加する事で距離センサのブロックが追加されます。
他にもサーボとかイーサネットの機能追加ブロックも有るみたいです(使た事ないけど)。

モータドライバを介して前進後進や右回転左回転をするにはドライバの各端子に接続したピンをオンオフ(Hight/Low)して制御します。
動力用電源端子1つと制御用電源端子1つとGND1つとモータ用入力端子4つとモータ用出力端子2つ…モータは2個でモータ用入力は一つ共有なんで…計15端子!
ビニール線を同じ色にすると、訳解らんくらいゴチャゴチャになります。
始めから一気に完成を目指すんやなくて、モータ1つずつ動かすと良ぇと考えます。

今回のロボットは右輪を右モータ、左輪を左モータで動かします。
どの端子をオンにしてどの端子をオフにしたらモータがどちらに回るかはデータシートに載ってます。
しかし、前進後進の度にピンを個別にオンオフしてたらコードも見難くなるので、前進後進停止右回転左回転は関数化して、都度呼び出す様にすると良ぇでしょう。
例えばこんな感じ。
ここで嵌りポイント
関数名を大文字にするとコンパイルエラーになりました。
良く解らんけど、諦めて関数名は小文字にしてます。

もう一つ嵌まりポイント
ピンのオンオフを切り替えたら、即モータが回ってロボットが動…きません。
0.5秒程待つくらいが丁度良ぇみたい。

もう一つハマりポイント
距離センサは超音波で距離を測ります。
モータ選りかは高速に結果を出すけど、それでもCPUの処理速度に比べたら遅いです。
loopの中で制御の度に距離を取得すると、結果取得に間に合わず不正確な距離を返すみたいです。
繰り返しの中では、毎回センサから距離を取得するのではなく、一度距離を取得したら変数に保存しておき変数の距離を参照する様に実装しました。

もう一つハマりポイント
UbuntuのarduinoIDEは偶にUSBでArduinoを接続しても認識せぇへん時が有ります。
そんな時は、ツールのシリアルポートのチェックを付けると良いです。

そんなハマりポイントを何とか解決して、BlocklyDuinoが生成してくれたコードからこちら。

int kyori;

int Sonic_Time_out = 3000;

long Sonic_Timing(){
  digitalWrite(12, LOW);
  delayMicroseconds(2);
  digitalWrite(12, HIGH);
  delayMicroseconds(10);
  digitalWrite(12, LOW);
  long duration = pulseIn(13,HIGH,Sonic_Time_out);
  if ( duration == 0 ){
    duration = Sonic_Time_out;
    digitalWrite(0, HIGH);
    delay(25);
    digitalWrite(0 ,LOW);
    delay(225);
  }
  return duration;
}

void foward() {
  digitalWrite(5, HIGH);
  digitalWrite(6, LOW);
  digitalWrite(7, HIGH);
  digitalWrite(8, HIGH);
  digitalWrite(9, LOW);
  digitalWrite(10, HIGH);
}

void right() {
  digitalWrite(5, HIGH);
  digitalWrite(6, HIGH);
  digitalWrite(7, LOW);
  digitalWrite(8, HIGH);
  digitalWrite(9, LOW);
  digitalWrite(10, HIGH);
}

void stop() {
  digitalWrite(5, LOW);
  digitalWrite(10, LOW);
}

void left() {
  digitalWrite(5, HIGH);
  digitalWrite(6, LOW);
  digitalWrite(7, HIGH);
  digitalWrite(8, LOW);
  digitalWrite(9, HIGH);
  digitalWrite(10, HIGH);
}

void back() {
  digitalWrite(5, HIGH);
  digitalWrite(6, HIGH);
  digitalWrite(7, LOW);
  digitalWrite(8, LOW);
  digitalWrite(9, HIGH);
  digitalWrite(10, HIGH);
}

void setup()
{
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, INPUT);
  pinMode(0, OUTPUT);
  digitalWrite(11, HIGH);
  pinMode(2, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
}


void loop()
{
  kyori = Sonic_Timing()/29/2;
  if (kyori > 20) {
    foward();
    delay(500);

  } else if (kyori > 10) {
    stop();
    delay(500);
  } else {
    digitalWrite(2, HIGH);
    if (kyori % 2 == 0) {
      right();

    } else {
      left();

    }
    delay(1000);
    back();
    delay(500);
    digitalWrite(2, LOW);

  }

}
これをArduinoIDEへコピペしてArduinoへアップロードするだけです。

センサで距離を測って、20cmより離れてたら前進して、20cm〜10cmの場合は停止して、それより近くなったら方向転換して戻らせてみました。
ちょっと動かしただけで、直ぐに線が外れて動かへん様になるし、ソースは100行以上あるしで、全然子ども向けではないけど…。
大人なロボットプログラミング入門には良ぇんちゃうかな?

2020年3月22日日曜日

LibreOfficeの参照について

あまプロではLibreOfficeを使って表を作る事が有ります。
先日、リブレオフィスのCalcで表計算をしてた時に、数式のコピペではまったのであメログ。

Calcでセルの値を他のセルでも参照したい場合は、数式を使います。
例えば下記の様に左のセルの1を右のセルでも表示したい場合には、右のセルで=B2と入力すれば左のセルの値が右のセルにも表示されます。
例では1にしたけど1とか漢字でも何でも可能
これ便利やねんけど、他のセルでも1を参照したい場合には一手間要ります。
=B2を他のセルへコピペすれば簡単かと思いきや、コピペするとこんな感じに
=B2をコピペしたのに=A4になる
参照が相対的に計算されてずれてまうのね。そう、ずれるんです。
一行上に貼り付けると=B1
一列左に貼り付けると=A2     =B2     一列右に貼り付けると=C2
一行下に貼り付けると=B3
これCalcでは相対参照(デフォルト)って呼びます。
2つ左のセルの参照をコピーしたので、貼り付けたセルでも2つ左のセルを参照します。
便利な時にはめっちゃ便利やねんけど、不便な時にはめっちゃ不便。
ローカル変数みたいにコピーした参照を使いたい時には良ぇけど、グローバル変数(例えば消費税とか)みたいに参照したい時に使えない。

その問題を回避するには絶対参照と呼ばれる方法を使います。
相対参照との違いは、
  • 相対参照は基準となるセルからの参照
    基準となるセルが変われば参照先も変わる
    二列二行目やとB2
  • 絶対参照はシート全体のからの参照
    基準となるセルが変わっても参照先は同じ
    二列二行目やと$B$2
こんな感じ。頭に$を付けるだけ
で、相対参照と絶対参照の切り替えは、手打ちで$を付けても良ぇけど、ショートカットが便利。
古い公式にはShift+F4と載ってて、新しい公式には載ってへんけど、バージョン6.3ではF4で切替可能です。

F4押下の度に相対参照(B2)->行列絶対参照($B$2)->行絶対参照(B$2)->列絶対参照($B2)を切り替えます。
解り易く色分けして並べてみるとこんな感じ。
B2が参照先のセルね。
 それらを色んな所にコピペしてみるとこんな感じ。
青字の行列絶対参照は何処にコピペしてもB2を参照する
その参照結果はこんな感じ。
青字の行列絶対参照は何処にコピペしても1を表示する
消費税とか重力とか定時とか…シート内のどのセルからも決まったセルを参照したい場合には絶対参照を使いましょ。

今回使たリブレはこちら。
早く来い来い6.4

2020年3月17日火曜日

LibreOfficeのフォントの色を変更できない

あまプロではLibreOfficeで表を作る事が有ります。
リブレオフィスのフォントの色ではまったのであメログ。

Ubuntu19.10版のリブレでは
こんな感じで、フォントの色を指定しただけでは文字色を変更出来ません。
ツール > オプション > アクセシビリティの
システム設定のフォント色を画面表示に使用
のチェックを外さなければフォントの色選りシステム設定が優先されてしまいます。

何故かデフォで「システム設定のフォント色を画面表示に使用」が有効になっているのと
「システム設定のフォント色を画面表示に使用」が有効の為に反映されない「フォントの色」が有効になっているのが変なのですが…ちょっと不親切です(-.- )