Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
7
Help us understand the problem. What is going on with this article?
@eielh

Haskellでarduino(主にfrp-arduino)

More than 3 years have passed since last update.

arduinoで遊ぶのになるべく高級言語を使いたい。
Haskellでarduinoを扱うためのライブラリはHaskell Wikiにまとまっている。

arduinoを扱うのに好きな言語を使うにはFirmata protocolがよく利用されてるようです。
arduinoにFirmataでおしゃべりできるようになるにファームウェアをいれてシリアルポートでFirmataでおしゃべりしてarduino操作します。

このfirmata用のHaskellライブラリにはhArduinoがあります。

また、firmataから派生したものとして独自に進化したのがhaskinoっぽいです。

そして、Haskellでファームウェアを生成できるライブラリのfrp-arduinoがあります。
名前の通り、arduinoでFunctinal Reactive Programming可能にするようです。

Firmataを利用するとMacなり、ラズパイなりなにかとシリアル通信していないといけないし、かといってC言語っぽい言語も書きたくないので、frp-arduinoで遊んで見ることにしました。

公開されてる 0.1.0.3 のfrp-arduinoはghc 7.10.3だとうまくビルドできませんでした。githubのmasterは対処がしてあったので、stack.yamlのpackagesにgitリポジトリを指定して利用しました。

stack.yaml
packages:
- '.'
- location:
    git: git@github.com:frp-arduino/frp-arduino
    commit: cf463a0f9a1f9a36d1d760994adccd74c4e82123

Lチカのサンプルコードはこんな風になっています。

import Arduino.Uno

main = compileProgram $ do

    digitalOutput pin13 =: clock ~> toggle

このプログラムを実行するとpin13がチカチカするmain.cが生成されます。C言語ファイルが生成されます。
あとはこのmain.cをコンパイルして、arduinoにアップロードします。

OS Xでのアップロード手順

arduino用の実行ファイルをつくるためにコンパイラなどなどをインストールします。

$ brew tap osx-cross/avr
$ brew install avr-libc

arudinoと通信するmakeファイルが簡単につくれるarduino-mkをインストールします。

$ brew tap sudar/arduino-mk
$ brew install arduino-mk

このarduino-mkがpyserialを使うようなので好みの方法でいれます。

$ easy_install -U pyserial

あとは適当にMakefileをかきます。

NO_CORE = Yes

BOARD_TAG = uno
MCU = atmega328p
F_CPU = 16000000L

AVRDUDE_ARD_PROGRAMMER = arduino
AVRDUDE_ARD_BAUDRATE = 115200

include /usr/local/opt/arduino-mk/Arduino.mk

make uploadを実行すればarduinoにインストールできます。

遊んだコードなど

pinを指定すればLチカできる関数は以下の感じです。

blickBasic pin = digitalOutput pin =: clock ~> toggle

チカチカ速度を調整するにはclock = every 10000となってるので

blinkSpeed pin speed = digitalOutput pin =: every speed ~> toggle

で変えることができました

点灯しっぱなしにしたいなら

eternalHigh pin = digitalOutput pin =: clock ~> mapS (const bitHigh)

なのでできました。clockが来るたびにbitHighになるようにしてるだけです。

uartを使うとシリアルポートからアウトプットができました。

接続するとカウントアップする処理とかかいてみました。

import           Arduino.Uno

main = do
  compileProgram $ do
    uart =: clock ~> foldpS (\_ state -> state + 1) 0
       ~> mapSMany formatDelta
       ~> flattenS

formatDelta :: Expression Word -> [Expression [Byte]]
formatDelta delta = [ formatString "delta: "
                    , formatNumber delta
                    , formatString "\r\n"
                    ]

感想

ハードウェアとFPRって相性いいと思います。

グローバルな変数をつくる方法がわからない。

試した時のコード

eiel/frp-arduino-sample

LTしたときの資料

参考

7
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
7
Help us understand the problem. What is going on with this article?