LoginSignup
4
3

More than 5 years have passed since last update.

Raspberry PiでErlang使ってADコンバータでアナログ値取得してみた

Last updated at Posted at 2016-03-13

モチベーション

関数型言語ってどんなもの?と思い戦闘機本を勉強中
で、Rapberry Pi使って何か面白いことできないかなと考え中

Raspberry PiとErlangでアナログ値取得

手始めに講談社ブルーバックス「Raspberry Piで学ぶ電子工作」6章のSPI通信によるADコンバータを用いたアナログ値取得を、Erlangで書いてみた。
上記の本には電子回路(フォトレジスタ、ADコンバータ、LEDなど)の構成、Pythonのコードと、その説明が書かれているのでそれと照らし合わせていただければ。

print.erl
-module(print).
-compile(export_all).

-define(SPICLK, "11"). %% GPIOピン番号
-define(SPIMOSI, "10").
-define(SPIMISO, "9").
-define(SPICS, "8").
-define(LED, "25").

main() ->
 io:format("initializing...~n"),
 pi_gpio:set_pin_direction(?SPICLK, "out"),
 pi_gpio:set_pin_direction(?SPIMOSI, "out"),
 pi_gpio:set_pin_direction(?SPIMISO, "in"),
 pi_gpio:set_pin_direction(?SPICS, "out"),
 pi_gpio:set_pin_direction(?LED, "out"),
 mainloop().

mainloop() ->
 Val = readadc(0),
 io:format("~w~n", [Val]),
 case Val > 2500 of %% 取得値が一定値以上でLED点灯
  true -> pi_gpio:set_pin_value(?LED, "1");
  false -> pi_gpio:set_pin_value(?LED, "0")
 end,
 timer:sleep(500), 
 mainloop().

readadc(Adcnum) ->
 pi_gpio:set_pin_value(?SPICS, "1"),
 pi_gpio:set_pin_value(?SPICLK, "0"),
 pi_gpio:set_pin_value(?SPICS, "0"),
 ComOut = (Adcnum bor 16#18) bsl 3, %% スタートビット+シングルエンドビットとのor, 左3ビットシフト
 loop1(ComOut, 5), %% 5ビット送信
 Adcout = 0,
 loop2(Adcout, 13). %% 13ビット読み込み


loop1(ComO, 0) -> ok;

loop1(ComO, N) ->
 case ComO band 16#80 of %% 8ビット目が1?
  16#80 -> pi_gpio:set_pin_value(?SPIMOSI, "1");
  16#0 -> pi_gpio:set_pin_value(?SPIMOSI, "0")
 end,
 ComO1 = ComO bsl 1,
 %%io:format("loop1:clockpin:High,Low~n"),
 pi_gpio:set_pin_value(?SPICLK, "1"),
 pi_gpio:set_pin_value(?SPICLK, "0"),
 loop1(ComO1, N-1).


loop2(AdcO, 0) ->
 pi_gpio:set_pin_value(?SPICS, "1"),
 %%io:format("cspin:High~n"),
 AdcO;

loop2(AdcO, K) ->
 %%io:format("loop2:clockpin:High,Low~n"),
 pi_gpio:set_pin_value(?SPICLK, "1"),
 pi_gpio:set_pin_value(?SPICLK, "0"),
 AdcO1 = AdcO bsl 1,
 H = pi_gpio:get_pin_value(?SPIMISO), %% GPIO9番ピンから値を読み込む
 %%io:format("misopin value: ~w~n", [H]),
 case K < 13 andalso H =:= 1 of %% 値が1?
  true ->
   %%io:format("adcout bor 0x1~n"),
   AdcO2 = AdcO1 bor 16#1;
  false ->
   %%io:format("adcout bor 0x0~n"),
   AdcO2 = AdcO1
 end,
 loop2(AdcO2, K-1).

%% ctrl-g
%% i
%% c
%% pi_gpio:release_pin("11"),
%% pi_gpio:release_pin("10"),
%% pi_gpio:release_pin("9"),
%% pi_gpio:release_pin("8"),
%% pi_gpio:release_pin("25").

Raspberry PiへのErlangインストール、GPIO制御

Raspberry PiへのErlangのインストール、GPIO制御は下記を参照して、ちょっとだけ修正
Raspberry Pi and Erlang - Part1
Raspberry Pi and Erlang - Part2

pi_gpio
-module(pi_gpio).

-compile(export_all).

-define(GPIO_PATH, "/sys/class/gpio/").
-define(GPIO, "gpio").

reserve_pin(Pin) ->
   ExportFile = string:concat(?GPIO_PATH, "export"),
   file:write_file(ExportFile, Pin, [append]).

release_pin(Pin) ->
   UnexportFile = string:concat(?GPIO_PATH, "unexport"),
   file:write_file(UnexportFile, Pin, [append]).

set_pin_direction(Pin, Direction) ->
   reserve_pin(Pin),
   file:write_file(direction_file(Pin), Direction, [append]).

set_pin_value(Pin, Value) ->
   file:write_file(value_file(Pin), Value, [append]).

get_pin_value(Pin) ->
   {ok, Value} = file:read_file(value_file(Pin)),
   {H, _} = string:to_integer(binary_to_list(Value)),
   H.

direction_file(Pin) ->
   string:concat(pin_path(Pin), "direction").

value_file(Pin) ->
   string:concat(pin_path(Pin), "value").

pin_path(Pin) ->
   PinFolder = string:concat(string:concat(?GPIO, Pin), "/"),
   string:concat(?GPIO_PATH, PinFolder).

実行

構成は上記のブルーバックスを参照ください。
2016-03-13142139.jpg

実行後、フォトレジスタに指を近づけて暗くすると、出力値が2500を切ってLEDが消灯、再び指を離すとLED点灯。。。
ScreenShot 2016-03-13at22231PM.jpg

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3