Skip to content

Instantly share code, notes, and snippets.

@mnishiguchi
Last active November 21, 2021 00:01
Show Gist options
  • Save mnishiguchi/7acf189376a4c5ffa184c39372cafbf4 to your computer and use it in GitHub Desktop.
Save mnishiguchi/7acf189376a4c5ffa184c39372cafbf4 to your computer and use it in GitHub Desktop.
Inky pHAT name badge example in Elixir

Inky pHAT name badge example

About

Inky pHAT is an electronic paper (ePaper / eInk / EPD) display for Raspberry Pi.

Let's do something similar to Pimoroni's Inky pHAT name badge example in Elixir. Here is Pimoroni's Python code.

This Youtube video Raspberry Pi, eInk and Nerves with Livebook by Underjord introduces you the basics of Inky on Nerves firmware.

Dependencies

Add these Elixir packages to your list of dependencies in mix.exs:

def deps do
  [
    {:chisel, "~> 0.2.0", targets: @all_targets},
    {:inky, git: "git@github.com:mnishiguchi/inky.git", branch: "mnishiguchi/ssd1608", targets: @all_targets},
  ]
end

Start Inky server

display_type = IO.gets("Display type") |> String.trim() |> String.to_existing_atom()
accent = IO.gets("Accent") |> String.trim() |> String.to_existing_atom()

# Start an Inky server
{:ok, inky_pid} = Inky.start_link(display_type, accent)

# Inspect the internal state of the Inky server
:sys.get_state(inky_pid)

Load BDF fonts

font_name = IO.gets("Font") |> String.trim()
fonts_dir = "/data/fonts" |> tap(&File.mkdir_p/1)
font_path = Path.join([fonts_dir, "#{font_name}.bdf"])

font_url =
  "https://raw.githubusercontent.com/olikraus/u8g2/master/tools/font/bdf/#{font_name}.bdf"

if File.exists?(font_path) do
  IO.puts("Already exists #{font_path}")
else
  {:ok, {{_, 200, _}, _headers, body}} = :httpc.request(font_url)
  IO.puts("Downloaded font #{font_name}")
  File.write(font_path, List.to_string(body))
end

IO.puts("Loading font #{font_path}")
{:ok, chisel_font} = Chisel.Font.load(font_path)

Print pixels on Inky

person_name = IO.gets("Name") |> String.trim()

print_badge_fun = fn ->
  Inky.set_pixels(
    inky_pid,
    fn _x, y, _w, h, _pixels ->
      name_field_top = div(h, 2)
      name_field_bottom = trunc(h * 0.9)

      cond do
        y < name_field_top -> :black
        y < name_field_bottom -> :white
        true -> :black
      end
    end,
    push: :skip
  )
end

print_text_fun = fn text, {x, y}, color, opts ->
  put_pixel_fun = fn x, y -> Inky.set_pixels(inky_pid, %{{x, y} => color}, push: :skip) end
  Chisel.Renderer.draw_text(text, x, y, chisel_font, put_pixel_fun, opts)
end

print_badge_fun.()
print_text_fun.("Hello!", {24, 1}, :white, size_x: 4, size_y: 3)
print_text_fun.("My name is", {24, 36}, :white, size_x: 2, size_y: 2)
print_text_fun.(person_name, {24, 72}, :black, size_x: 3, size_y: 3)

# Push the pixels in bulk
Inky.set_pixels(inky_pid, %{}, push: :await)
@mnishiguchi
Copy link
Author

mnishiguchi commented Nov 13, 2021

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment