mrubyでLEDを点滅させる
2014/2/20追記
下記はRSTRING_PTR()を誤った使い方をしています。mrb_valueにRSTRING_PTR()マクロを使った場合に取り出した文字列は終端がNULLとは限りませんのでご注意
Arduino互換機 chipKIT Max32でmrubyを動かす - kyabの日記でchipKIT Max32でのmruby動作に成功したわけですが、次にLEDを光らせてみました。
コードは以下のとおりです。
mruby_led(C側)。前のコードとほぼ同じですが、ruby側から呼び出せるdigitalWrite()とdelay()を実装して、mrubyに登録してます。
#define CHANGE_HEAP_SIZE(size) __asm__ volatile ("\t.globl _min_heap_size\n\t.equ _min_heap_size, " #size "\n") #include <mrbconf.h> #include <mruby.h> #include <mruby/irep.h> #include <mruby/string.h> #include <mruby/value.h> extern const char code[]; //print function mrb_value cputs(mrb_state *mrb, mrb_value self){ mrb_value val; mrb_get_args(mrb, "S", &val); Serial.println(RSTRING_PTR(val)); return mrb_nil_value(); } //digitalWrite function mrb_value cdigitalWrite(mrb_state *mrb, mrb_value self){ mrb_int pin; mrb_int val; mrb_get_args(mrb, "ii", &pin, &val); digitalWrite(pin, val); return mrb_nil_value(); } //delay function mrb_value cdelay(mrb_state *mrb, mrb_value self){ mrb_int val; mrb_get_args(mrb,"i", &val); delay(val); return mrb_nil_value(); } void setup(){ CHANGE_HEAP_SIZE(102400); //100kb Serial.begin(9600); pinMode(7, OUTPUT); //set pin7 as OUTPUT //init mruby mrb_state *mrb = mrb_open(); //register c functions mrb_define_method(mrb, mrb->object_class, "cputs", cputs, ARGS_REQ(1)); mrb_define_method(mrb, mrb->object_class, "cdigitalWrite", cdigitalWrite, ARGS_REQ(2)); mrb_define_method(mrb, mrb->object_class, "cdelay", cdelay, ARGS_REQ(1)); //load bytecode and execute mrb_load_irep( mrb, code); //check exception if (mrb->exc){ Serial.println("exceptin occured in ruby code!"); } } void loop(){ Serial.println("loop() called"); delay(1000); }
code.rb(mruby側)。500ミリ秒毎に7番ピンの出力をHIGHとLOWで切り替えてるだけです。
HIGH = 1 LOW = 0 cputs "mruby code started" loop do cdigitalWrite(7, HIGH); cdelay(500); cdigitalWrite(7, LOW); cdelay(500); end
う〜ん、rubyであることを活かしたコードにしたいんですが、何も浮かばなかったw
参考にしたサイト:
http://www.dzeta.jp/tech/index.cgi?mruby+API%A5%AC%A5%A4%A5%C9
手探りでおぼえるmruby その1:クラスを定義する、メソッドを定義する - エンジニアのソフトウェア的愛情