Erlang

From eLinux.org
Revision as of 14:40, 28 January 2016 by Skvamme (talk | contribs) (Graphics)
Jump to: navigation, search

Erlang on Raspberry Pi, starting with a fresh Raspbian image (even Lite will do). Make sure you run raspi-config to enlarge the file system to fill your memory card. Erlang takes a couple of hours to compile (when you run "make").

sudo apt-get update
sudo apt-get install wget
sudo apt-get install libssl-dev
sudo apt-get install ncurses-dev
wget http://www.erlang.org/download/otp_src_18.2.1.tar.gz
tar -xzvf otp_src_18.2.1.tar.gz
cd otp_src_18.2.1/
./configure
make
sudo make install
cd ..
sudo rm -R otp_src_18.2.1/

If you don't want to install everything that comes with the standard Erlang package, you can save space and time just by putting a file with the name SKIP in every library you don't want/need in your raspberry pi. This is the applications I usually skip. Do this before you run ./configure and make.

touch lib/asn1/SKIP
touch lib/cosEvent/SKIP
touch lib/cosEventDomain/SKIP
touch lib/cosFileTransfer/SKIP
touch lib/cosNotification/SKIP
touch lib/cosProperty/SKIP
touch lib/cosTime/SKIP
touch lib/cosTransactions/SKIP
touch lib/diameter/SKIP
touch lib/eldap/SKIP
touch lib/ic/SKIP
touch lib/gs/SKIP
touch lib/megaco/SKIP
touch lib/orber/SKIP
touch lib/ose/SKIP
touch lib/otp_mibs/SKIP
touch lib/parsetools/SKIP
touch lib/percept/SKIP
touch lib/reltool/SKIP
touch lib/snmp/SKIP
touch lib/test_server/SKIP
touch lib/typer/SKIP
touch lib/webtool/SKIP
touch lib/wx/SKIP
touch lib/xmerl/SKIP

You start the interactive shell with erl and quit with Ctrl-g q. Read about Erlang at [1].

Graphics

Ex11_graphics

There is a very nice graphics library written in Erlang. It makes a perfect match if your application is written in Erlang and you are using a small screen where you don't want a window manager. The screen in the image is an Adafruit 5" 800x480. Erlang ex11 is writing directly to the screen (X11 server). Read about it here [2]

To help create new widgets there is a small program included to convert DXF-files to erlang ex11 drawing primitives. Download or draw your own graphics in a CAD system and save as DXF. Convert the DXF file with dxf2erl:start("filename.dxf"). from the erlang console.

Onewire

This is a simple owserver client. It can call dir and print a directory listing from a onewire network. First, you have to install owfs:

sudo apt-get install owfs

Configure owfs in /etc/owfs.conf

Then, save a file, onewire.erl with the following content:

-module(onewire).
-export([start/0,init/0,loop/1]). 

start() -> spawn_link(?MODULE,init,[]).

init() ->
	io:format("New process: ~p~n", [?MODULE]),
	inets:start(),
	{ok,Socket} = gen_tcp:connect("localhost", 4304, [binary, {packet, 0}]),
	Version = 0,
	Type = 10,
	Control_flags = 36,
	Size = 1024,
	Offset = 0,
	Raw = <<"/",0>>,
	Payload = size(Raw),
	ok = gen_tcp:send(Socket,<<Version:32,Payload:32,Type:32,Control_flags:32,Size:32,Offset:32,Raw/binary>>),
	loop(Socket).

loop(Socket) ->
	receive
		{tcp,Socket,Bin} -> Dir = get_directory(Bin),
			io:format("In ~p: Dir is: ~p~n",[?MODULE,Dir]),
			?MODULE:loop(Socket);
		{ow_dir,Raw,Pid} -> 
			Version = 0,
			Type = 10, % get
			Control_flags = 36,
			Size = 1024,
			Offset = 0,
			Payload = size(Raw),
			ok = gen_tcp:send(Socket,<<Version:32,Payload:32,Type:32,Control_flags:32,Size:32,Offset:32,Raw/binary>>),
			receive {tcp,Socket,Bin} -> Dir = get_directory(Bin), Pid ! {ow_dir,Dir} after 10000 -> ok end,
			?MODULE:loop(Socket);
		{tcp_closed,_} -> ok;
		Any -> io:format("~p got unknown msg: ~p~n",[?MODULE, Any]),
			?MODULE:loop(Socket)
	end.

%****************************************************************************************
% Function get_directory(Bin)
%****************************************************************************************
get_directory(Bin) ->
	get_dir(Bin,<<>>).
	
get_dir(<<>>,Dir) -> Dir;
get_dir(<<0,0,0,0,0,0,0,0, Return_value:32/signed-integer,Rest/binary>>,_Dir) when Return_value /= 0 -> 
	io:format("Return value is: ~p and Rest is: ~p~n",[Return_value,Rest]);
get_dir(<<_Version:32,_Payload:32,0:32,_Control_flags:32,Size:32,_Offset:32,Raw:Size/binary,0,Rest/binary>>,Dir) ->
	get_dir(Rest,<<Dir/binary,Raw/binary>>);
get_dir(<<_Version:32,Payload:32,Return_value:32,_Control_flags:32,_Size:32,_Offset:32,Raw:Payload/binary>>,Dir) ->
	io:format("Return value is: ~p and Raw is: ~p~n",[Return_value,Raw]),
	<<Dir/binary,Raw/binary>>.

Compile the file with: erlc onewire.erl Start an Erlang console with erl and type onewire:start(), and you should see a listing of your onewire network.

Another Erlang module can send this message to onewire: {ow_dir,<<"/",0>>,self()} and get back a directory listing.