ししちにじゅうはち 4x7=28

よんたったー https://twitter.com/keita44_f4

回路図CAD+プリント基板CADな感想

某人が雑にブログをさくさく書くのやってるの、よいので真似しよう。
軽い気持ちでネットに知識を保存して、世界をちょっとだけよくするのよい。

CR-5000

  • 図研
  • 多くの企業で採用されている実績のある回路・基板CAD
  • 日本語おk、なはず
  • 強い
    • けど高いのでまだ使ったことない

Eagle

  • CadSoft
  • 100x80mmや部品数・レイヤーに制限ありまでは無料
  • 英語
  • 有料になると急に5〜20万と本気を出してくる
    • 回路図・基板・自動配線の3つのうちたくさん買うほど高額
    • えげつない
  • 強い
    • 老舗なのか、他フリーCADはEagle形式をインポートできるのを強みに言う

Design Spark PCB

  • RS compornents関係
    • RSの部品Noをつけた部品リストを出せる機能がある
    • 国内のPCB試作メーカにすぐに見積もり・発注が出せる機能とかある
  • 完全無償で商用利用もおk
  • 英語
  • Eagleのデータをインポートできる
  • 移動とか基本が普通CAD系の操作感で使いやすい

KiCAD

  • OSSな回路・基板CAD
    • ライブラリはGithubで公開、プルリクも受け付けてる
  • 完全無償で商用利用もおk
  • 日本語化バイナリが存在する
  • Eagleのデータをインポートできる
  • 普通のCAD系とちょっと基本操作が違ったのが違和感あった

というわけでDesign Spark PCB使って回路の勉強してる。

ヌードルメーカーで家二郎

この記事はNoodleMaker Advent Calendar 2014 20日目の記事です。

各所で話している通り、


こんな目に会いました。

本気には本気で返す

というわけで家二郎を作ることになりました。
今回はフィリップスのヌードルメーカーで家二郎ができることを報告します。

機材・材料

  • 機材
    • フィリップスヌードルメーカー
    • 一口IHコンロ
    • 鍋4つ
      • スープ大鍋
      • 麺茹で大鍋(フライパンで代用)
      • 油加熱小鍋
      • カエシ鍋
    • レンチンできる大きめのタッパー(ヤサイ茹で用)
  • 材料(約5人分)
    • スープ(約鍋1杯、丼10杯分くらい?)
      • げんこつ(豚の骨)1本約300g
      • 玉ねぎ 1個
      • キャベツの芯 1個
      • ネギの青い部分 1個
      • にんにく 1欠片
      • 生姜 1欠片
    • カエシ
      • 醤油 300ml
      • みりん 80ml
      • 豚肩ロース 800g
      • キャベツ 半玉
      • もやし 3袋
      • にんにく 1欠片〜
      • 豚背脂 500g

スープ

下茹で

ハンマーなどで割ったげんごつを30分ほど煮ます。
自分はビニール袋に入れてアパートの塀にぶつけて割りました。

30分茹でたら洗って肉や血合いを取ります。

本茹で

野菜・チャーシュー・背油とげんこつを一緒にしてアクを取りながら約4〜8時間ほど煮ます。




野菜・チャーシュー・背脂は2時間ほどで取り出します
玉ねぎは醤油をかけて食べました。

8時間後

こんな感じに乳化した状態になります。

カエシ

材料を混ぜて加熱。
みりんのアルコールを飛ばして置いておきます。

チャーシュー(スープ・カエシと平行)

茹でる

前述、スープと一緒に2時間ほど煮ます

スープに漬ける

前述のカエシに食べる30分ほど前から漬けて置きます。
時々ひっくり返すこと。

切る

うまい

油(スープと平行)

下茹で

前述、スープと一緒に2時間ほど煮ます

本茹で

食べる前に小鍋に入れて包丁でザクザク細かく切ります。
その後、軽く沸騰するまで火にかけて、火から下ろします。
あとは余熱でいい感じにとろけます。

ヤサイ

キャベツは一口サイズほどに切ります。
もやしと一緒にタッパーに入れてレンジ500Wで約1分半チンします。

水に塩・重曹を溶かしておく。
小麦粉をヌードルメーカー(2.5mm各麺)にセットする。
8分でヌードルメーカーをスタートさせる。
水はじっくり少しずつ1分ほどかけて入れる。
麺は1人前ずつでカットする。

湯で時間は約4分〜5分です。

ニンニク

みじん切り

できあがり

カエシ1:スープ4:油1くらいで丼に入れる。
茹で上がった麺を入れる。
野菜・ニンニク・チャーシューを盛る。
アブラ増しの場合はさらにアブラを上からかける。
カラメの場合はさらにカエシを上からかける。



まとめ

  • フィリップスのヌードルメーカーで家二郎はできる
  • 一口コンロのIHでも頑張れば家二郎はできる
  • mzpギルティ

SML with マイコンボード

この記事はML Advent Calendar 2014 14日目の記事です。

最近は、お仕事でマイコンボードプログラミングを書いています。
現在はBeagle Bone Black(以下BBB)をいじっています。
ところでこのマイコンボードはArmでフルのLinuxを動かすことができます。
さらにこんなコメントが。

!!!!

もちろんBBBは各種GPIOやLEDをLinuxファイルシステムとして提供してくれています。
つまりファイルの読み書きさえできて、Arm対応の言語なら何でもマイコン操作ができるはずです。
そこで今回はMltonによるマイコンボードプログラミングを紹介します。

環境

  • Beagle Bone Black (Rev C)
    • Ubuntu 14.10 utopicをインストール済み
    • apt-getでMltonのインストール済み

Beagle Bone BlackのGPIOの操作方法

  • 以下のサイトを参考にしました
    • shellからの操作がとても参考になる。
    • ピン番号についての一覧エクセル/PDFも便利。

http://www.si-linux.co.jp/techinfo/index.php?BeagleBoneBlack

# echo 60 > /sys/class/gpio/export             # 60番GPIOを使用
                                               # 新しいディレクトリgpio60ができる
# echo out > /sys/class/gpio/gpio60/direction  # outputに指定
# echo 0 > /sys/class/gpio/gpio60/value        # HIGH出力
# echo 1 > /sys/class/gpio/gpio60/value        # LOW出力

SMLによるGPIOモジュールの例(Arduino風)

上記シェルコマンドの動作をそのまま落とし込むだけです。
100行以下の小さなお試しプログラムです。

(* DIGITAL_GPIO.sig *)
signature DIGITAL_GPIO =
sig
  type pin = int
  datatype mode = OUTPUT | INPUT (* | INPUT_PULLUP *)
  datatype value = HIGH | LOW
  val pinMode : pin * mode -> unit
  val digitalWrite : pin * value -> unit
  (* 省略 val digitalRead : pin -> value *)
end
(* DigitalGPIO.sml *)
structure DigitalGPIO : DIGITAL_GPIO =
struct
  type pin = int

  datatype mode = OUTPUT | INPUT

  datatype value = HIGH | LOW

  val path = "/sys/class/gpio"

  fun startPin pin =
      let
        val path = path ^ "/export"
        val outs = TextIO.openOut path
        val () = TextIO.output (outs, Int.toString pin)
        val () = TextIO.closeOut outs
      in
        ()
      end

  fun setMode (pin, mode) =
      let
        val path = path ^ "/gpio" ^ Int.toString pin ^ "/direction"
        val modeString = case mode of
                             OUTPUT => "out"
                           | INPUT => "in"

        val outs = TextIO.openOut path
        val () = TextIO.output (outs, modeString)
        val () = TextIO.closeOut outs
      in
        ()
      end handle IO.Io error => ()

  fun pinMode (pin, mode) =
      let
        val () = startPin pin
        val () = setMode (pin, mode)
      in
        ()
      end

  fun digitalWrite (pin, value) =
      let
        val path = path ^ "/gpio" ^ Int.toString pin ^ "/value"
        val v = case value of
                    HIGH => "1"
                  | LOW => "0"

        val outs = TextIO.openOut path
        val () = TextIO.output (outs, v)
        val () = TextIO.closeOut outs
      in
        ()
      end
end
(* Main.sml *)
structure Main
          : sig
            val main : unit -> unit
          end
=
struct
  fun init () = DigitalGPIO.pinMode (60, DigitalGPIO.OUTPUT)

  fun loop () =
      let
        val () = DigitalGPIO.digitalWrite (60, DigitalGPIO.HIGH)
        val () = OS.Process.sleep (Time.fromReal 0.5)
        val () = DigitalGPIO.digitalWrite (60, DigitalGPIO.LOW)
        val () = OS.Process.sleep (Time.fromReal 0.5)
      in
        loop ()
      end

  fun main () = (init (); loop ())
end

val () = Main.main ()

できたプログラムをBBB上で実行すると、P9-12番ピン - GND間に繋いだLEDが1秒周期でチカチカします。
やったね!

setMode関数でIo例外を握りつぶしています。
実行初回だけdirectionファイルがビジー状態のエラーがでるためです。
もしかするとexport設定後のdirectionファイルへのアクセスが早過ぎる?
この辺はまだ調査中です。

まとめ

列挙型と代数的データ型

今日はなごやかJava第1回 - connpassに行って来ました。
そこで@bleisさんによるJavaC#(とF#)の比較の話の中で列挙型(と代数的データ型)について話題に上がりました。
SML好きな自分が最近C++を書いてて同じように2つの違いについて思ったことがあったので、ここに書いておきます。

列挙型

  • (おそらく)有限数状態を表すために作られた
    • int等でもプログラマが管理すれば同様の機能は実現できる
    • 状態の意味を名前付けしたり、状態数の制限を付加できる
  • C/C++Javaなどで使える*1
  • ラベルのみを持つ
  • 使用例
// C++

// 定義
enum Janken {
  Gu,
  Choki,
  Pa
};

// 使用
int walkLength(Janken hand)
{
  switch(hand) {
    Gu:    return 3 // グリコ
    Choki: return 6 // チョコレート
    Pa:    return 6 // パイナップル
  }
}

代数的データ型

  • 数学の直和が理論の元になっている
    • 集合A,Bに対して2つの直和A+Bは A+B = { a_label(x) | x∈A } ∪ { b_label(x) | x∈B }
    • つまり、どちらの集合から来たかラベルが付いた和集合
  • HaskellOCamlやSMLやScalaで使える
  • 型推論が効く
    • 強力なパターンマッチが使える
  • 列挙型と違い、ラベルだけでなくデータも持てる
    • そもそも列挙ではなく、複数の型を直和した別な型をつくる概念
    • Cでいう共用体(union)にラベルが付いている、ほうが正しく表していると思う
  • 暗黙の型変換は存在しない
  • 使用例
(* SML *)

(* 定義 *)
datatype janken =
    Gu
  | Choki
  | Pa
  | LocalRule of string * int

(* 使用 *)
fun walkLength hand = (* 型推論結果: fn: janken -> int *)
  case hand of
      Gu    => 3
    | Choki => 6
    | Pa    => 6
    | LocalRule (name, n) => n (* "グリコノオマケ"、など *)

まとめ

  • 2つの生まれ元は違えど、使いたい目的はたいてい同じ「ケース分け」
    • しかし、代数的データ型のほうが強い
  • 個人的には代数的データ型がサクッと使いたいんです!!
    • C++で代数的データ型を探して絶望したのよ…
    • もちろんクラスを駆使すればC++/Javaで同様のことはできる*2
    • もっと多くの言語に流行れ、でも原理的な問題で実装難しそう

*1:Cでは実体はただのint、C++では型や値を指定できるものの暗黙の変換とかがあってやっかいこの上ない

*2:そんなにがんばりたくない

Emacsのバッファ移動に便利なショートカットキー

問題点

C-xoでバッファ移動はできるけどバッファを3分割以上してると移動がめんどくなってきますよね。
自分は5画面(メイン1つ、サブ2つ、grep-find対象、grep-find結果)があるのでC-xoでは対処できなくなってきました。
そこでバッファをもっと便利に移動する設定を紹介。

よくある設定

Shift+カーソルキーでバッファが移動できるようになります。
めっちゃ便利!
しかし使っているとシフトを押すのがだるくなってきました。

(windmove-default-keybindings)
(setq windmove-wrap-around t)

今回の設定

そこでシフトすらいらないように設定。
そもそもEmacsではfbpn使うからカーソルキーなんて使わないって人におすすめ。
カーソルキーは全部バッファ移動に割り当ててしまいましょう.

(global-set-key (kbd "<left>") 'windmove-left)
(global-set-key (kbd "<right>") 'windmove-right)
(global-set-key (kbd "<up>") 'windmove-up)
(global-set-key (kbd "<down>") 'windmove-down)

やっぱりカーソルキーはほしい

手をカーソルキーまで移動するのもめんどいので、C-c+hjklを追加
手を移動させるのはとても面倒なことですよね。

;;; C-x oの代わりのバッファ移動
(global-set-key "\C-cl" 'windmove-right)
(global-set-key "\C-ch" 'windmove-left)
(global-set-key "\C-cj" 'windmove-down)
(global-set-key "\C-ck" 'windmove-up)

まとめ

今はこのC-c+vi操作が気に入っています。
まじ便利

C言語で非アスキー文字を使う方法

諸事情でArduinoを使っています。
さらにArduino ROBOTO LCDを組み合わせています。
さてこのLCDアスキー文字を表示できますが、実はアスキー外にも文字が定義されています。
その中で-9(unsignedだと247)*1を含んだ文字列を表示する方法で困ったのでまとめます。

無理やりキャストする

できるけどさっぱりクールじゃない。
コードも読みづらいです。

char* s = "a";
char[0] = (char)(-9);

16進数を使う

にあるように16進数の\xNNNNで指定できます。
ただしchar1文字しか使わないならN2文字で区切る必要があります。

char* s = "\xf7";

8進数を使う

なかなか使う機会がないけど\NNNで8進が使えましたね!

char* s = "\367";

まとめ

C難しい

*1:-9は上付き丸に割り当てており、℃を二文字使って表せる

俺がgithubを使うにあたってgitを理解しようとした話3

そもそもなんでgitを理解せねば、というかこんなトラブルをことが起きてしまったのか、というお話。

何をしようとしていたか

https://github.com/smlsharp/smlsharp:githubのSML#レポジトリ]のバージョンが1.1.0だったので1.2.0と2.0.0にアップデートしようとしてました。

理想はこんな感じ。

何をやらかしたか

バージョン1.2.0のアップデートは素直にいき、githubへ反映できました。
しかしその次が問題。
間違えて2.0.0の変更を1.1.0にかけてしまい、手元のmasterがリモートのmaster(oring/master)と別ブランチ状態に。
詳細は、いらないファイルを消し忘れたり、README.mdを消してしまったりをして、何度かやり直してパニックになっているうちに、こんな間違ったpush状態に陥っていました。

解決法

解決方法はいろいろありますが、今回は手元のmasterをresetしてv1.2.0に指し直してから、2.0.0をコミットしました。*1
図とコマンドは下記。
ちなみにこの時の自分ではどうしていいかわからずに*2、mzpさんとbleisさんにご指導を仰ぎました。
結果としてgitについていろいろ知ることになりました。

$ git reset --hard v1.2.0   # masterのHEADとファイル内容をv1.2.0へセット


あとはv2.0.0をコミットしなおせば目的のコミットツリーのできあがり。
ちゃんちゃん。

反省

  • gitはコマンドのコピペじゃなくて中身を理解してつかう
    • たいていは痛い目を見てから覚える
  • git reset --hardはファイル内容も書き換えるので慎重に
  • rebase -iでHEADが指してるコミットは消せないっぽい
    • gitのコミットはrebase等で消しても見えなくなるだけで、タグ・ブランチなどで差されていないとそのうちGCされて本当に消えるらしい

*1:わけもわからずmzpの言うとおりにしたらうまくいった、mzpすごいなー!

*2:rebase -i HEAD^^で間違ったv2.0.0を消そうとして消せなくて悩んでました。今思うと、masterのHEADが指してるところを消せるわけがないですね。