【祝】最長勤続日数! 勤続日数カウンターをつくった
新卒から2年と3ヶ月が経ち、友達の現職の勤続日数がこれまでで最長になったのでお祝いをしました。
勤続、過去最長記録をみんなに祝ってもらった。めっちゃ恥ずかしいことなんだけど、めっちゃ嬉しくて、少し泣いた。
— しらはま (@shirahama_x) 2018年7月20日
お陰様で楽しくやってます。#自作の勤続カウンター#高い完成度 #東大電気系の本気#まさかのリセット機能😂 pic.twitter.com/CcEE6JnoRx
せっかくなので、勤続日数カウンターについてちょっと紹介します。
はじまり
7月4日、ふれっしゅから「お祝いに何か用意する?」と言われて始まったこのプロジェクト。 はじめは盾を贈ろうという話になっていたのですが、盾に勤続日数を表示したくない?という話になり、最終的には勤続日数を表示し続けるカウンターを作ることになりました。 よく考えてみると、日数カウンターのデバイスって世の中で見たことない気がしますね。 7月20日に会う予定だったので、2週間しかなくて結構ギリギリでしたw
概要
仕様
- 開始日からの日数を計測する
- リセットボタンを長押しすると開始日を現在時刻にする
材料
- Arduino nano
- WaveShare E-Ink 電子ペーパーモジュール
- DS1307 I2C RTCモジュール
- MDF 4mm, 2.5mm
- ケミカルウッド 適量
- 塗料、プラ紙(?)
プログラム
ポイント1:電子ペーパー、回路
ディスプレイ選びのポイントとしては、明るいときにはきちんと表示が見え、暗いときにはあまり目立たないという点でした。普通の液晶パネルのように自分が発光するタイプだと夜明るくて邪魔なので、調光機能つけないといけません。その点、コントラストがはっきりしていて文字盤も読みやすく、自分が発光しない電子ペーパーはちょうど良かったです。おかげで部品点数も手間も減り、2週間という短納期を実現できました。 電子ペーパー、初めて使ったんですがやっぱり電源切っても表示されっぱなしというのは面白いですね。
また、この電子ペーパーモジュールのwikiページやデモコードなどが結構ちゃんとしていたので、パーツを買ったその日のうちにすぐに動かせたのもとても楽でした。
パーツはすべて秋葉原でぱぱっと買えるものを使いました。 モジュールを千石や秋月で買って、ユニバーサル基板にくっつけてあります。今思い出したけど、使ってないピンはんだ付けするの忘れてる気がする・・・・笑
ポイント2:筐体
初めて3DCADを使ってチュートリアル以外にまともにモノを作りました。 Fusion360ってすごい!
3DCNCを使って表面パネルを削り出し、他はレーザーカッターで切った板を重ねています。
ポイント3:塗装
塗装は完全に素人なので、秋葉原工作室さんに伺って教えてもらいました。
完全に初めてということを伝えると「段差があるから薄いプラ紙(?)を貼るといいよ」とか「缶スプレーで塗るといいんじゃないかな」といったアドバイスがもらえましたし、道具もその場にあるので、行ったその日のうちに塗装ができました!(感謝)
ポイント4:プログラム
プログラムはGitHubに公開しておきました。
機能としては開始時刻を記録して現在時刻との差分を表示するというだけなのですが、意外と面倒な点がいくつかありました。
フォント
今回はGoogle Fontsからいいフォントをひたすら探して、Ranchersというものを使いました。 inkscapeでピクセル単位でいい位置を探し、書き込んであります。 全部ぶん投げちゃったけど1日でいい感じに仕上げてくれたふれっしゅ、ありがとう!!!!笑
長押し検知・連打検知
チャタリング防止用に、50msごとにスイッチをポーリングしています。 ステートをOFF, ONのほかにLongOFF/LongONという2つを用意し、一定時間より長く同じステートにいたらLongOFF/LongONになるみたいな実装にしてあります。 そうすると、ON -> OFF -> ON -> OFFみたいにLongじゃないステートの行き来をカウントすれば連打検知が結構簡単に実装できるということに今回気づきました。 この辺がそのコードです。 普段からそういう実装する人的には自明かもしれないですが、自分的にちょっとうまく実装できた感あって嬉しくなったポイントですw
EEPROMの寿命検知
EEPROMの書き換え寿命が1万回程度なので、もし1万回リセットボタン押したらEEPROMが壊れて開始時刻が壊れてしまうかもしれません(押さないとは思うけど)。
ということで、データが壊れているか検知するためにCRCを計算することにしました(このへん)。
PyCRCというプログラムをつかって今回はCRCを求めています。
こんな感じの引数でpycrcについてくるpycrc.pyを実行すると、それっぽいCのコードが吐けます。
ちなみに気をつけるポイントは--xor-out=0xAAAA
を指定する部分です。これがないと、全部ゼロのデータのCRCの結果がゼロになってしまうので、EEPROMをゼロで初期化したときにデータがvalidになってしまいます。
$ ./pycrc.py --model crc-16 --algorithm tbl --std=c99 --crc-type=Type --xor-out=0xAAAA --generate h -o crc.h
デフォルトだと8bitずつ計算するので256 * 2byte = 512 byteの領域がメモリに必要です。これはマイコン的に厳しいので、省スペースにするために4bitずつ計算するようにしました(このへん)。
現在時刻の修正
今回はRTCモジュールのサンプルに従って、コンパイル時刻に現在時刻を設定するようにしました。 起動時にEEPROMに保存されているコンパイル時刻と定数として保持しているコンパイル時刻を比較し、異なっていたときだけ更新するようにしています。 まぁ書き込みには1分程度しかかからないので、おおよそうまくいったと思います。
RTCモジュールもArduino用のサンプルプログラムが提供されているので、それを利用するととても簡単に使うことができました。 ただCRCや日付計算のためにかなりコードを書き換えました。このディレクトリにあるものがサンプルコードを書き換えたライブラリになります。
メモリ削減
ATmega328はメモリが2KiBしかないので、プリントする文字列をそのまま定数で保持していくと苦しいことになります。そのため、基本的にすべてのSerialにプリントする文字列をコードと同じフラッシュメモリに入れています。
まとめ
市販の時計はすごい!!!!
渡して数秒でリセットボタンに気づいたしらはまは天才でした。 1000日経ってカンストする画面を見てもらえるのを楽しみにしています!٩( ’ω’ )وヨッシャ!
あと仕事とは別に適当な工作するの楽しいですね。 もう少しCADとか色塗りの技術をつけていきたいです。なんかオススメありますか。
Yubikey on Ubuntu 16.04
Ubuntuでyubikeyを使おうとするとChromeがエラーを吐く問題。
https://crbug.com/427966 が参考になった。
以下を/etc/udev/rules.d/50-security-key.rulesに書けば良いっぽい。
SUBSYSTEMS=="usb", ATTR{idVendor}=="1050", TAG+="uaccess", TAG+="udev-acl"
追記 (Apr 11, 2018)
こんな記事が出てた。 Using Your U2F YubiKey with Linux
$ cd /etc/udev/rules.d $ sudo curl -O https://raw.githubusercontent.com/Yubico/libu2f-host/master/70-u2f.rules $ sudo udevadm control --reload-rules && sudo udevadm trigger
meld as mergetool
meldをgitのマージツールとしてつかうときには、.gitconfigに少しだけ設定が必要。
[diff] tool = meld [merge] tool = meld [mergetool "meld"] cmd = meld $LOCAL $MERGED $REMOTE #keepBackup = false # if you don't like the backup file
コンフリクトした部分以外はgitがマージしてくれる。コンフリクトした部分はLOCALかREMOTEから取ってこよう。
TAのすすめ
この記事はeeic (東京大学工学部電気電子・電子情報工学科) Advent Calendar 2016の第7日目の記事になります。
目次
はじめに
なにがしかの要因によりタイトルだけ決まっていたこの記事ですが、みなさんが超有用記事を書く中 %%ただノロけ%% 雑多な記事をあげるのもなぁあと思ったので、今回は「僕がTAをやるにあたって気をつけていたこと」というテーマで適当に書き連ねてみようかと思います。基本的にTA側目線です。 いま実験なんかでこっそり「あのTAはクソ」とか言っているB2,3や、TAをやることになったB4~M2のみなさんに役に立てば幸いです。
大したこと書いてねえじゃねえかamiqはクソ!とかいって石を投げないでくださいね。泣いちゃいます。
amiq11とは
まず自己紹介します。僕は今年τ研を修士で卒業したamiq(あみきゅー)です。今は某IT企業で日々C++と戯れています。 TAのすすめを書くにあたって重要なのはTA歴だと思うので、やっていたTAを列挙してみます。
- B4夏: 1コマ G1G2G3(現I1I2I3)の最終発表
- B4冬: 1コマ オペレーティングシステムの演習
- M1夏: 週3・4週間 G1G2G3(現I1I2I3)
- M1冬: 1コマ オペレーティングシステムの演習
- M2夏: 週3・4週間 G1G2G3(現I1I2I3)
- M2冬: 週3・8週間 大規模ソフトウェア演習
- M2冬: 1コマ オペレーティングシステムの演習
TAのしごと
僕の場合は指導教官であるτ先生からお願いされてTAをしていました。 先生によってTAの扱いは異なると予想されますので、一例に過ぎないということを始めに注意しておきます。
- 見回って質問の応対
- 実際に教える内容の相談
- 授業用のリソースの準備
- スライドを作って説明
- レポートの採点
このうち、実際に学生から見える部分は1くらいかと思います。
特にM2のときにTAをした大規模ソフトウェア演習では、初めての授業ということもありかなり時間を取って授業のコンテンツを議論した記憶があります。 全体の授業の流れを決めた後は、TAと先生で担当を決め、実際にスライドを用意したり、実験用のgitlabやサーバーの設定等を行っていました。実験の前に意外と手間がかかっているわけですね。
考えていたこと・やったこと
TAから見た学生
特にg1g2g3課題で感じましたが、B3って本当に勉強し始めなんだなぁというのが率直な感想です。修士までの間で当然のように感じるようになったことが、学部3年生時点では全然わかってないということが多いです。例えば"%c"と"%s"の違いをきちんとわかっているか、writeとfwriteの違いは、とか、そういうレベルからどうなんだっけという感じの人が多い印象でした。ただ、みんなが情報系に進むわけでもないので、それ自体はしょうがないと思います。ただ、TAとの感覚の違いは大きい。当然のように感じていることが意外とできなくてギャップに驚きます。しかも、基本的にはわかっていないなら聞いてねというのがTAのスタンスなのですが、みんな黙々と作業をしていて質問もしてこない。うーん、わかってるの?なんなの?
実体(予想)
実際のところ、聞くタイミングがいまいちわからないという人が多いように感じました(逆にやたらとなれなれしく聞いてくる班もあったりしたような気はするけど)。自分で頑張って、ーんわからないという状況のまま1、2時間たっているという状況も多かったのではないでしょうか。
気を付けていたこと1:巡回
ということで、僕がTAをするときには、全部の班に1度以上声をかけるということを徹底していました。後ろを歩くだけでは何も質問してこなくても、「調子どう?」と一言かけるだけで「あ、いまちょっとここで悩んでるんですけど・・・」と質問してくれる人が多くいたので、これは効果があったかなと思います。また、進捗を正確に把握しやすいという利点もありました。
気を付けていたこと2:スライド
学術論文の発表スライドでは、スライドを相手に渡したりするわけでもないので、話す内容に重点を置いた構成にしていました。しかし、授業スライドではスライドだけを後から見返す可能性があります。そこで、授業スライドでは基本的に文字を多めに入れ、スライドだけを後で見返しても十分な情報が含まれているように注意をしていました。また、大規模ソフトウェア演習のスライドでは、ソフトウェア開発の小手先のテクニックというよりはより根幹になるような内容を取り入れようと、コンパイルやリンクの話、ライセンスの話などを取り入れてみました。自分が初心者だったときはこれが知りたかったんだよなーとかいうのを思い出しながらスライド書いていくのは楽しかったです。
気を付けていたこと3:最終発表
僕が担当した実験は発表があるものでした。そこで、発表の際により盛り上がことを期待して、みんなにリアルタイム投票とTwitterのハッシュタグを指示していました。リアルタイム投票のシステム、実は僕がまともに書いた初めてのjavascript/cssだったりします。バグがあったらごめんね。 また、最終レポートの採点にもこの最終発表の印象点は含まれていました、が、発表がすごく”おもしろかった”としても、レポートの内容がきちんとしたもののほうがよくなるように評価していた記憶があります。レポート、みんなきちんと書こうな。。。大規模ソフトウェアは逆にブログ記事が採点対象ということもあり、みんな気合いれて書いてくれていたので全員点数が高かったと思います。
しかししんどかった
TAとかいうのなんかクソしんどくないですか。週3で3時間ぐるぐる回りながらこの人は何が分からないのかとかいうの考えつつ、スライドを作って、しかも隔週の研究室の進捗報告で話す内容を確保するための研究をしないといけないとかいうの体力的にしんどかった。。 ので、ぜひ学生さんはTAをいたわってあげてください。。
おわりに
書くのおそくなってごめんなさい。 基本的に後輩に優しく丁寧に教えてあげるのがいいと思います。そうすればきっと後輩とも仲良くなれるし楽しいTAライフになるんじゃないでしょうか。
パワーポイントで図形を描くとデフォルトが水色の塗りつぶしになってしまいます。これを常に塗りつぶしなしに変えたいのですが、起動するたびにこの水色が出てきてしま...
Link: パワーポイントで図形を描くとデフォルトが水色の塗りつぶしになってしまいます。これを常に塗りつぶしなしに変えたいのですが、起動するたびにこの水色が出てきてしま...
毎回ダサい図形のフォーマットになってしまっていちいち設定するの面倒だなぁ、と思っていたら、簡単に設定を変えられた。もっと早く知っておくべきだった・・・・・
PowerPoint 2016では、デフォルトにしたい図形を右クリックして、「規定の図形に設定」を押せば次回以降図形を描画するときに同じスタイルを使ってくれるみたい。
OSがあまりにわからなかったからとりあえず自分でOSつくっちゃった話 (1st step)
はじめに
題名にあるとおり今までぼーっとふわふわーっと生きてきたらOSの授業があまりにわからなかった(他の授業はわかるとは言ってない)ので、「これはもう自分で作っちゃったほうが早いんじゃない?」と思ったので自分で作ってみました。
というとなんか強い人が凄いことをやったみたいになっていますがやったことは簡単に言うと①OS自作の本を購入②まねして実装の2つだけ。
もともとただの自己満足としてやってみようと思っていたのですが、せっかくやるならアピールしとこうってことで、OSの先生に話して、OSの授業で発表することになりました。
で、そうなるとさすがに本買って真似して実装しただけだと先生にも「え、それって本の写経しただけだよね?サルでも出来るよね?」って言われないにしても、思われちゃうので、最初は自分で拡張してみるつもりでした。
が、一応ちゃんと本を読んで理解しながら進めたはずなのに終わってみるとわかったようなわかってないようなモヤモヤ感がすごい・・・。結局何したんだかいまいちわからないという感じになりました。
「拡張とか言う前にこのモヤモヤ感をなんとかせねば!」ということで、拡張するのは将来の自分への課題として、どのような実装を行ったのかを適宜調べながらもう一度しっかりまとめ直そうということにしました。さすがにこれだけだと先生に「え、拡張するって言ったよね?結局大したことしてなくない?」って思われちゃうので、汎用OSではどんな実装がされてるかなど、今回作ったOSと比較しながらまとめようと思います。
結果的に授業でやったようなことを自分でしっかり調べてまとめるみたいな感じになるわけで、結局OSがわからなかったからOSつくってみたけどやっぱりよくわからないからOS真面目に勉強した話みたいになりました。
0 step 本選び
まずAmazonで調べたところ、OS自作でまずヒットした本は「30日でできる! OS自作入門」という本、コメントも多く評価も高いのでいい本なんだと思います。はじめはこれにしょうかと思っていたのですが、コメントをよむとどうやら本当に30日でやるには相当頑張らないといけないっぽい、また開発環境はwindowsに限られるっぽいということがわかりました。さすがにそんなに時間かけれないなぁという思いからこの本は保留にして他の本を探しました。
そこで見つけたのが、今回利用した本「12ステップで作る組込みOS自作入門」でした。コメント数はさっきの本よりは少ないのですがこちらも評価の高い本です。組み込みOSってなんなのかよくわかっていなかったのと、なんかマイコンボードを使うとかで、どうなんだろうと思っていたのですが、コメントの中でゼミで学部3年生にやらせていて朝9時から夕方8時くらいまで毎日作業ということで、実働10時間を6日間で完成させているというのがあって、割と短期間でできそうだと思ったのと、「なにより大学生や社会人1年目の方が読まれると信じられないくらいレベルアップできると思います。」というコメントを発見し”圧倒的成長学科”の自分としてはやらないわけにはいかないという気持ちになりました。
その後本屋にも行ってほかにもいくつかの本の中身を実際にみてみましたが、OSの授業の内容とも近いものとなると「12ステップで作る組込みOS自作入門」が最適と判断しこの本に従って開発を行うことにしました。
この本にはサポートページもあるのでそこも参照していただければどのようなものなのか解ると思います。
1st step 開発環境の構築
*やったこと*
gccやら、minicomやら、フラッシュROM書き込みツールやらのインストール
ただインストールするだけなんですが、いろいろと本との環境の違いやらで手こずりました。12ステップの中で一番手こずったとおもいます(´・ω・`)
そして、今回作成したファイルは次のとおりです。
main.c : 「Hello world!」を出力させる普通のCのプログラム
startup.s : アセンブラで書かれていてスタックポインタの設定とmain()の呼び出しなどを行っている。プログラムはこの中の_start:から実行される
vector.c : 割込みベクタの定義。start()から実行されるようにポインタを設定
lib.h lib.c : ライブラリ関数。今回はputsとputcだけ実装。
serial.h serial.c : シリアル通信を行うためのいろいろが書かれている。
defines.h : charやlongなど様々な型の定義。
ld.scr : リンカスクリプト。コンパイルして作成される実行形式ファイルのメモリ配置を定義している。
Makefile : ビルド方法のマニュアル的なもの。
*説明*
組み込みプログラムにおいて、プログラムの実行はstart.sの_startから始まる。_startではスタックポインタの設定を行い、main()にジャンプする。では、どのようにして、_startから処理を開始するのだろうか。多くのCPUには割り込みという機能がある。これはCPUがある処理をしている最中に「割込み」という指示が入ると、別の処理にはいるというもの。割込み時に行う処理を一般的に割込みハンドラと呼ぶ。割込みハンドラの処理が終了すると、CPUは中断していた処理を再開する。割込みを実現するには、割込み発生時にどのハンドラを実行するのかを設定する必要がある。これは大きく分けて2つの方法がある。
①割込み発生時には、特定のアドレスから実行する。
②割込み発生時には、どのアドレスから実行するか特定のアドレスに設定しておく
①の方法は、割込みハンドラを配置するアドレスをCPU側で決め打ちにしてしまい、割込みが発生したらそのアドレスに強制的に処理がとぶというもの。
②の方法は、割込みハンドラを配置するアドレスを特定のアドレスに記述しておくというもの。
この「ハンドラのアドレスを記述しておく特定のアドレス」を割込みベクタと呼び、この方法をベクタ割込み方式と呼ぶ。割込みが発生すると、CPUは割り込みベクタを参照してハンドラの配置場所を知り、そこに強制的に処理がとぶ。H8はベクタ割込み方式で、割込みベクタの種類に応じて、アドレスが0x000000~0x0000ffのメモリ上に配置されている。割込みの一つにリセットベクタがある。H8は、リセットが発生するとリセット・ベクタを参照してそこから動作を開始する。H8では、割込みベクタの先頭がリセット・ベクタになっている。vector.cでvectorsという配列を定義した。これが割込みベクタの設定である。
vector[0]にはstart()関数のアドレスが設定されている。これはstartup.sで定義されている_startのことである。
H8の割込みベクタは0x000000~0x0000ffというアドレス上にあるため、vectorsの内容は0x000000~0x0000ffのアドレスに配置する必要がある。これはld.scrで行っている。
作成したコードはここにあげてあります。基本的には本に書かれているもの、サポートページにあるものと同じですが、自分の中でわかりやすいようにコメントを追加してあります。
これでHello World!できました。
TumblrでjQueryつかって目次を自動生成する
はじめに
上のページを参考にしてやってみたところ、このスクリプトでは複数記事があった場合に対応できないのと、h1, h2タグの階層構造に対応していないことに気づいて、ちょっと不便だな、となった。ということで、改良したからメモ。
目次
やりかた
Step1: JQueryを使えるようにする
<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
上記コードをテーマのHTMLのヘッダかどっかに突っ込む。
Step2: JSのコードの追加
追加するコードは以下。これをテーマのヘッダかどこかに入れる。
function getLevel(tagName) { if (tagName.toLowerCase() == "h1") return 1; else if (tagName.toLowerCase() == "h2") return 2; else return -1; } $(function() { $(".toc").each(function() { var toc = $(this); var article = $(this).closest("article"); var article_id = article.attr("id"); var toc_id = "toc-" + article_id; var index_tree = $('<ul></ul>'); var current_node = index_tree; var prevLevel = 1; article.find("h1,h2:not(.post-title)").each(function(i) { var id = '' + article_id + '-chapter-' + i; $(this).attr('id', id); var level = getLevel($(this).get(0).tagName); var text = '<li><a href="#' + id + '">' + $(this).html() + '</a></li>'; if (level > prevLevel) { var new_node = $('<ul></ul>'); current_node.find("li:last").append(new_node); current_node = new_node; prevLevel = level; } else if (level < prevLevel) { current_node = current_node.parent().closest("ul"); prevLevel = level; } current_node.append(text); $(this).append('<span class="back-toc"><a href="#' + toc_id + '">↑</a></span>'); }); $(this).append(index_tree); $(this).attr('id', toc_id); }); }); $(function() { $('a[href^=#]').click(function() { var speed = 400; var href = $(this).attr("href"); var target = $(href == "#" || href == "" ? 'html' : href); var position = target.offset().top; $('body,html').animate({ scrollTop: position }, speed, 'swing'); return false; }); });
Step3: 本文に目次をつける
本文中の目次つけたいところにこれを置く。
<div class="toc"></div>