Skip to content

mobileoverlord/firmata

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

43 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Firmata

This package implements the Firmata protocol in Elixir.

Firmata is a MIDI-based protocol for communicating with microcontrollers.

Feature Completeness

Implemented

  • Parser
  • Handshake
    • Retreiving Version
    • Retreiving Firmware
    • Retreiving Pin Capabilities
    • Retreiving Analog Pin Mapping
  • Toggle Analog Channel Reporting
  • Set Pin Mode
  • Digital Write

Planned

  • Digital Read

Usage Example

defmodule App do
  require Serial
  use Firmata.Protocol.Modes
  alias Firmata.Board, as: Board

  @high 1
  @low 0

  def start_link(tty, baudrate, opts \\ []) do
    GenServer.start_link(__MODULE__, [tty, baudrate], opts)
  end

  def init([tty, baudrate]) do
    {:ok, serial} = Serial.start_link
    {:ok, board} = Board.start_link
    Serial.open(serial, tty)
    Serial.set_speed(serial, baudrate)
    Serial.connect(serial)
    {:ok, {board, serial}}
  end

  # Forward data over serial port to Firmata

  def handle_info({:elixir_serial, _serial, data}, {board, _} = state) do
    send(board, {:serial, data})
    {:noreply, state}
  end

  # Send data over serial port when Firmata asks us to

  def handle_info({:firmata, {:send_data, data}}, {_, serial} = state) do
    Serial.send_data(serial, data)
    {:noreply, state}
  end

  # Handle application-level messages from Firmata to design the app

  def handle_info({:firmata, {:version, major, minor}}, state) do
    IO.puts "Firmware Version: v#{major}.#{minor}"
    {:noreply, state}
  end

  def handle_info({:firmata, {:firmware_name, name}}, state) do
    IO.puts "Firmware Name: #{name}"
    {:noreply, state}
  end

  def handle_info({:firmata, {:pin_map, _pin_map}}, {board, _} = state) do
    IO.puts "Ready"

    Board.set_pin_mode(board, 13, @output)
    Board.digital_write(board, 13, @high)
    Board.report_analog_channel(board, 3, @high)

    spawn(fn->
      :timer.sleep 1000
      Board.report_analog_channel(board, 3, @low)
    end)

    {:noreply, state}
  end

  def handle_info({:firmata, {:analog_read, 3, value}}, state) do
    IO.inspect "analog channel 3 reports value: #{value}"
    {:noreply, state}
  end
end

{:ok, _ard} = App.start_link "/dev/cu.usbmodem1421", 57600

Installation

If available in Hex, the package can be installed as:

  1. Add firmata to your list of dependencies in mix.exs:

    def deps do [{:firmata, "~> 0.0.1"}] end

  2. Ensure firmata is started before your application:

    def application do [applications: [:firmata]] end

About

Firmata protocol in Elixir

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Elixir 100.0%