分岐点

進路選択に迷い迷走している私ですが、いつまでもこの状態でいる訳にもいかないので閲覧数2,000回を超えた今、自分のココロの中についても描いていけたらなと思います。

私は豊橋技科大を推薦受験⇒一般受験し落ちました(勉強不足+書類選考のみで経験を活かせなかった)。専攻科を滑り止めに受け(専門科目免除なし)合格していたのでプラス2年間同じ高専にお世話になる予定です。

3年時からモノ作りや教育(布教)に目覚めてモノコトイノベーションやコンテスト出展や高専ロボコン参加などをしてきた私は2年半の間に多くの事を経験しました。同時に広がった世界に対してどう向き合えばいいのか分からなくて収束のための時間というものを探す形で進学を選んだのだと思います。

ここで私の「計画性」について考えてみたいと思います。研究室優先配属の手続きを忘れていたことやロボコン+卓球+進路関係+現実逃避による時間不足など色々やらかして来ました。しかし、私の考えとして「やってみないと分からない」ものは「とりあえずやる」というものがあります。特に最近はこの傾向が強いがために、マイナス面で言えば予定や締切の管理ミスやタクス過密による精神不安定が生じております。ですが私はもう少しこのままで格闘する事を考えています。ちょっとしたミスや不便感を培った技術で解消したり、自分の経験を他の人がより簡単に得られるような発信をしたりする事が今の自分になんとかできる事だと思っています。自分の軸がより尖ったものとなるよう努めてまいります。

分身ロボもどき #IT_Party

友人の頑張りにより本州最西端でITパーティーが開かれました🎊

connpass.commargaritan.hatenablog.com

最近オリィ研究所にはまっている私はRaspberry Pi を用いた自作分身ロボットについてお話させていただきました。

ロボコン部署紹介.pptx - Google ドライブ

今回のブログでは実演に用いた分身ロボットの作り方を中心に書いていきたいと思います。早速ですが、Raspberry Piを遠隔操作するために「TeamViewer」というアプリを導入します。ラズパイ関係なく簡単にPCの遠隔操作が可能になるのでおすすめです。

iot-plus.net

次に回路・ハード周りを構築していきます。

基本的には周南ロボコンの時に参考にした「ZeroBot」と同じ構成です。

https://cdn.hackaday.io/images/6417841519894620814.png

https://hackaday.io/project/25092/instructionsd

電源周りは面倒なのでモータードライバーに単3電池4つを直列に繋ぎ

モータードライバーはBanggoodから輸入いたしました。

http://デュアルチャンネルL298N DCモータドライバボードPWMスピードデュアルHブリッジステッパモジュール モジュール基板 from エレクトロニクス on banggood.com https://banggood.app.link/GYGmJW1vv2

ブレッドボードやジャンパーピンで回路を繋ぎ

タミヤ製品を使いながら適当にハードを完成させます。

 

そしてロボット駆動用のGUIを作ります。

Tkinter を使い4つのボタンを配置。

電卓のレイアウトを作成する - Narito Blog

そしてそれぞれ呼び出す関数を定義し

GPIOピンを直接制御します。

Raspberry Pi のGPIOをPythonから利用する - Qiita

こちらが最終的なプログラムです。

github.com

最後にストリーミング。

Raspberry Piと動画モニタアプリMotionで、晩ご飯作成風景を家庭内ストリーミング配信する - Qiita

今回はぎりぎりのスケジュールでしたので、ラズパイのストリーミング配信をラズパイ上で表示させるという頭の悪そうな事をしています。ここはぜひより良い方法を探して教えて下さいますようお願いしておきます。


f:id:massiro-myaon:20191218203617j:image

そんなこんなで現時点の分身ロボットの出来上がりでございます!発表本番でも自宅にロボットを置いた状態で発表会場から動かすということができ、喜んでいただけたようなので良かったです(本当は会場に分身を置いて自宅から参加したかったw)!

分身として使う為の音声周りの機能追加やハードのデザイン向上などやるべき事はまだまだありますが、マイペースにやってまいります🍵

2進数アドベントケーキ🍰

Fusion360主催の #クリスマスオーナメントコンペ2019 に出品しました。
今年はアドベントカレンダーが流行ったので、私はクリスマスケーキを
模した2進数アドベントカレンダーの製作に取り組みました。


2進数アドベントケーキ🍰


もともとArduino Nano用の箱型ケースは設計・製作していたのでLEDが
通る穴をあけた蓋を付けるだけなのですがクリームが覆われているような
形を意識しました。まあモデリング技術でいえばほかの参加者に到底およ
ばないので、実際に造形してコンセプト通りに動くようにしていきます。

とりあえず蓋をSTLに変換して出力。その間に出力ピンの対応を確認。
正しくは抵抗を挟んで電流等を調整する必要がありますがそのような
隙間もないので今回は直刺しでいきます。

f:id:massiro-myaon:20191208115853j:plain

プログラムは配列を活用しながら計算・出力していきます。
2進数⇒10進数の変換は忘れかけていましたがこちらのサイトに救われました。

C言語入門 - 10進数を2進数に変換 - サンプルプログラム - Webkaru

int day=17;
int value[5];
int anode[]={11,8,5,2,0};
int casode[]={1,4,7,10};

void setup() {
  //Serial.begin(9600);
  pinMode(0, OUTPUT); //2^0
  pinMode(1, OUTPUT); //GND
  pinMode(2, OUTPUT); //2^1
  pinMode(4, OUTPUT); //GND
  pinMode(5, OUTPUT); //2^2
  pinMode(7, OUTPUT); //GND
  pinMode(8, OUTPUT); //2^3
  pinMode(10, OUTPUT); //GND
  pinMode(11, OUTPUT); //2^4
  for(int p=0;p<4;p++){
    digitalWrite(casode[p], LOW);
  }
}

/* 10進数-->2進数変換関数 */
void ChangeFunc(
unsigned long int DecimalNumber, /* 10進数[in] */
char* BinaryString) /* 2進数文字列化[out] */
{
  int i,k;

  for(i = 0, k = 4; k >= 0; i++, k--)
  {
    if((DecimalNumber >> i) & 1)BinaryString[k] = '1';
    else BinaryString[k] = '0';
  }
  BinaryString[i] = '\0';
}

void loop() {
  int i;
  char BinaryString[5]; /* 2進数文字列化 */
  
  ChangeFunc(
  day, /* 10進数[in] */
  BinaryString); /* 2進数文字列化[out] */
  /* シリアルポートに文字列を出力 */
  /*Serial.print(day, DEC);
  Serial.print("\n");
  Serial.print(BinaryString);
  Serial.print("\n");
  */

  for(int i=0;i<5;i++){
    if(BinaryString[i]=='1'){
      digitalWrite(anode[i], HIGH);
    }
    else digitalWrite(anode[i], LOW);
  }
  delay(86400000UL);
  day = day-1;
  while(day<=0){
    for(int s=0;s<5;s++){
      digitalWrite(anode[s], HIGH);
    }
    delay(1000);
    for(int n=0;n<5;n++){
      digitalWrite(anode[n], LOW);
    }
    delay(1000);
  }
}

シリアルポートを確認用に使っていましたがRX/TXのピンを出力に使って
いるためコメントアウトしています。
カレンダーと言いながら、カウントダウンになってしまいましたが
クリスマスまで問題なく動いてくれると信じて常設しておきます🎅

追伸:応募方法ミスってました。悲しみながらデータ共有の用意を致しましたので
是非皆さん作ってみてください😭
https://a360.co/2rfe0O2

周南ロボコン参戦

昨年まで運営を務めていた周南ロボコンですが、今年は参加者側に挑戦しました。 今年の競技についてはパワーアップした周南ロボコンのWebサイトを見てみて下さい! http://www.tokuyama.ac.jp/robocon/2019/index.html

ロボット概要

1台目のロボットは塩ビパイプを登るロボットです。 糸を巻いていくロボットが主流でしたが、糸の先におもりをつけてパイプの中に入れておくことで、 タイヤで昇っていくロボットの重さを軽くするという斬新なアイデアで高速昇降しているチームもありました。 私はArduino互換のESP32(IoT Expressで検索)を用いてスマホから昇降用のモーターとピン球の保持・排出用のサーボを制御しました。

www.mgo-tec.com

開発途中にフラッシュ削除が必要になったりしましたが、SNSのおかげで何とかなりました。

ESP8266/ESP32環境向上委員会公開グループ | Facebook

ESP32 が動作しない(Rebootを繰り返す)時の対処 | くまぱんだ日記

2台目のロボットはピン球を箱に向けて落としていくロボットです。展開制限がないのでガイドを垂らしていくロボットが多かったです。 私はとにかく「ロボット視点の映像を見ながら遠隔操縦する」ことに捕らわれていたので、Zerobotの情報をもとにRaspberry Pi Zero Wを使って足回りのみのロボットを作りました!ただ、ボールの受け取り場所も排出機構もない上に、操縦も難しかったので、2試合目はピン球落とせる箱を付けて有線で出ましたw

hackaday.io

反省点

反省点としては大きく2つ。
1つは「有線で勝負できるロボットを作ってから無線・自動に挑もう」ということ。
無線操作をRaspberry PiArduinoそれぞれで実現するという当初の目的は叶いましたが、ハードウェアの設計としては競技に全く適しておらず、悲しい結果に終わりました(´;ω;`) 案外有線⇔無線の切り替えは楽なので、先に機能的なロボットの設計を頑張りましょう!!
2つ目は「オープンソースに頼りすぎない」ということ。 両ロボットともネットから拾ってきた情報をもとに製作しました。 難しめの制御を短期間で導入するという意味ではよい選択だったと思いますが、実際の競技に適した形で改良しようとしたときに、結局サンプルの理解・修正に時間を取られてしまいます。また、オープンソースに頼るという事は大げさに言えば「既に世の中あるものしか作れない」という事でもあるので、研究等においては致命的だなとか考えたりしました。

まとめ

初めて参加者として周南ロボコンに出れたことは新鮮でしたが、体育館で高専祭を迎えるのはそろそろやめたいですねw というわけで来年は今年の学びを生かしてロボットを別の場所から操縦できるようにしたいと思います(反省してない)。 これができるようになれば全国の高専生に参加してもらえるようになり、活動の幅も広がると思うので応援よろしくお願いします!!

Maker Faire 京都

Maker Faire に初めて参加しました!

ものづくりのあらゆる分野が集まっていて楽しかったです。

今回はその一部を紹介したいと思います。

 

1)技科大の木製時計

これまでの金属時計の重さが気になり製作したそうです。

着脱部分を磁石+フックで実現していました。

 

2)ベゼリー

Raspberry Piを使ったコミュニケーションロボット。

現在販売中ですが、活用事例を模索中みたい。

 

3)不思議な楽器

機械の近くで手を動かしてみると...

何故か手の動きに合わせて音楽が流れます...不思議

 

4)組み紐自動作成機

3DプリンターArduinoを使って組み紐が自動で作られていました。

 

5)OriHime拡張ツール

出展者のお母さんがOriHimeで参加してました。

M5stackを使って今誰がOriHimeを使ってるか確認できるようです。

 

こういう場所にくると製作意欲が湧くので定期的に行きたいですね!

地方でも取り組みが広がるよう努力します。

3Dプリンター入門

学校で3Dプリンター自体は何度も使っていましたが

遂にMy 3Dプリンターを手に入れました。

ja.aliexpress.com

私が購入したとき(2019/7)は21,640円でした。

組み立ては大変でしたが、動画もあったので何とかなります。


TEVO Tarantula PRO - Detailed Assembly & Calibrations

スライサーには「KISSlicerr64」を使いました。

私が使っている設定を共有しておくので参考にしてみてください。

kisslicer_win64.zip - Google ドライブ

 

今のところPLA(白)とABS(黒)を使いましたが問題なく造形出来ました。

ABSの時は保温のために、ゴミ袋で覆ってから造形しています。

f:id:massiro-myaon:20190922235408j:plain

1家に1台の時代もそう遠くないかも知れませんね笑 

 

2021/02/26 追記

新規に買ったABSの設定温度がベッド(80~100)ノズル(190~230)だったので

ベッド(80→90)ノズル(235→226)に設定変更。

また、造形終了時に Printer G-code の Postfix の設定で「G1 X0 Y235 F3000」が行われていた(テーブルを前に出してくれる)ものの、そのせいで断熱用ビニール袋を突き破ってしまうことが多々あったので「G1 X0 Y200 F3000」に変更した。

指紋認証入門

私のいる高専ではICカードを使った認証をよく使っていて私もPasoriで遊んでみたりしていました。
blackuma.hatenablog.com

ただしこれにはデメリットもあり、例えば出席管理でICカードを使う場合は他の人に託してしまえるのでよく「監視しておく人」というのが設けられます。

せっかく自動化・効率化の技術を使うのに、一時的に生産性が著しく低い人間が生まれてしまうというのは私のプライドが許しませんでした。

他の認証を考えた時、生体認証しか思いつかなかった私は、Ali Express で指紋認証モジュールを約2000円で購入しました。(生体認証のデメリットは調べてない...)
ja.aliexpress.com

海外の文献は充実していたので基本的な認証動作はすぐにできました。
How to work with Fingerprint scanner using Arduino nano — Steemit

これだけでも十分使えますが、出席管理を想定して誰がいないかを表示できるようにステップ3.2を編集します。

#include <Adafruit_Fingerprint.h>

#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);

Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);

// 127個の1の配列
int List[127];

void setup()  
{
  int i;
  for (i = 0; i < 127; i++ ) {
    List[i] = 1;
  }
  
  Serial.begin(9600);
  while (!Serial);  // For Yun/Leo/Micro/Zero/...
  delay(100);
  Serial.println("\n\nAdafruit finger detect test");

  // set the data rate for the sensor serial port
  finger.begin(57600);
  
  if (finger.verifyPassword()) {
    Serial.println("Found fingerprint sensor!");
  } else {
    Serial.println("Did not find fingerprint sensor :(");
    while (1) { delay(1); }
  }

  finger.getTemplateCount();
  Serial.print("Sensor contains "); Serial.print(finger.templateCount); Serial.println(" templates");
  Serial.println("Waiting for valid finger...");
}

void loop()                  
{
  if(Serial.available()>0)
  {
    switch(Serial.read())
    {
      case 'a': //データが'a'であれば次を実行する
        int i;
        for (i = 0; i < 127; i = i + 1) {
          if (List[i]==1){
            Serial.print(i+1);Serial.print(" ");
          }
        }
        break; 
      default:
        break;
    }
  }
  getFingerprintIDez();
  delay(50);            
}

uint8_t getFingerprintID() {
  uint8_t p = finger.getImage();
  switch (p) {
    case FINGERPRINT_OK:
      Serial.println("Image taken");
      break;
    case FINGERPRINT_NOFINGER:
      Serial.println("No finger detected");
      return p;
    case FINGERPRINT_PACKETRECIEVEERR:
      Serial.println("Communication error");
      return p;
    case FINGERPRINT_IMAGEFAIL:
      Serial.println("Imaging error");
      return p;
    default:
      Serial.println("Unknown error");
      return p;
  }

  // OK success!

  p = finger.image2Tz();
  switch (p) {
    case FINGERPRINT_OK:
      Serial.println("Image converted");
      break;
    case FINGERPRINT_IMAGEMESS:
      Serial.println("Image too messy");
      return p;
    case FINGERPRINT_PACKETRECIEVEERR:
      Serial.println("Communication error");
      return p;
    case FINGERPRINT_FEATUREFAIL:
      Serial.println("Could not find fingerprint features");
      return p;
    case FINGERPRINT_INVALIDIMAGE:
      Serial.println("Could not find fingerprint features");
      return p;
    default:
      Serial.println("Unknown error");
      return p;
  }
  
  // OK converted!
  p = finger.fingerFastSearch();
  if (p == FINGERPRINT_OK) {
    Serial.println("Found a print match!");
  } else if (p == FINGERPRINT_PACKETRECIEVEERR) {
    Serial.println("Communication error");
    return p;
  } else if (p == FINGERPRINT_NOTFOUND) {
    Serial.println("Did not find a match");
    return p;
  } else {
    Serial.println("Unknown error");
    return p;
  }   
  
  // found a match!
  Serial.print("Found ID #"); Serial.print(finger.fingerID); 
  Serial.print(" with confidence of "); Serial.println(finger.confidence); 

  return finger.fingerID;
}

// returns -1 if failed, otherwise returns ID #
int getFingerprintIDez() {
  uint8_t p = finger.getImage();
  if (p != FINGERPRINT_OK)  return -1;

  p = finger.image2Tz();
  if (p != FINGERPRINT_OK)  return -1;

  p = finger.fingerFastSearch();
  if (p != FINGERPRINT_OK)  return -1;
  
  // found a match!
  Serial.print("Found ID #"); Serial.print(finger.fingerID); 
  Serial.print(" with confidence of "); Serial.println(finger.confidence);
  List[finger.fingerID-1] = 0;
  return finger.fingerID; 
}

ステップ3.1に「from 1 to 127」とあったから127個の配列にしていますが128でも登録&認証できたのでたぶん無限に増やせます。

シリアル通信で"a"を送信してやると配列が表示されるようになっていて、認証が済んだ番号の配列は次から表示されなくなります。

番号と人との対応表を作ったうえで、127の所をすべて登録人数に置き換えてやると出席管理ツールの出来上がりです。