# OLED
[![Hex version](https://img.shields.io/hexpm/v/oled.svg "Hex version")](https://hex.pm/packages/oled)
OLED is a library to manage the monochrome OLED screen based (for now) on chip SSD1306 connected by SPI or I2C.
The idea is to support other similar chips also.
![Sample](images/sample.jpeg)
## Features
Graphic primitives
- [x] Points
- [x] Lines
- [x] Rects
- [ ] Circles
- [ ] Polygons
- [ ] Filled Rects
- [ ] Filled Circles
- [ ] Filled Polygons
- [ ] Text rendering
- [x] Scenic driver
<p align="center">
<br>
<br>
<img src="images/scenic_preview.gif"><br>
Scenic driver with dithering enabled
<br>
</p>
## Basic Setup
*1. edit your mix.exs*
```elixir
def deps do
[
{:oled, "~> 0.1.0"}
]
end
```
*2. create a display module*
```elixir
defmodule MyApp.MyDisplay do
use OLED.Display, app: :my_app
end
```
*3. add the configuration*
```elixir
config :my_app, MyApp.MyDisplay,
device: "spidev0.0",
driver: :ssd1306,
type: :spi,
width: 128,
height: 64,
rst_pin: 25,
dc_pin: 24
```
*4. add your application's supervision tree*
```elixir
defmodule MyApp.Application do
use Application
def start(_type, _args) do
import Supervisor.Spec, warn: false
children = [
# Add this line
MyApp.MyDisplay
]
opts = [strategy: :one_for_one, name: MyApp.Supervisor]
Supervisor.start_link(children, opts)
end
end
```
*5. use it*
```elixir
# Draw something
MyApp.MyDisplay.rect(0, 0, 127, 63)
MyApp.MyDisplay.line(0, 0, 127, 63)
MyApp.MyDisplay.line(0, 63, 127, 0)
# Display it!
MyApp.MyDisplay.display()
```
## Displays configuration
```elixir
config :my_app, MyApp.MyDisplay,
device: "spidev0.0", # Device (i.e.: `spidev0.0`, `i2c-1`, ...)
driver: :ssd1306, # Driver. (Only SSD1306 for now)
type: :spi, # Connection type: `:spi` or `:i2c`
width: 128, # Display Width
height: 64, # Display Height
rst_pin: 25, # Reset GPIO pin (SPI only)
dc_pin: 24 # DC GPIO pin (SPI only)
address: 0x3C # DC GPIO pin (I2C only)
```
## Scenic Driver
OLED is compatible with [Scenic](https://github.com/boydm/scenic) thanks to [rpi_fb_capture](https://github.com/fhunleth/rpi_fb_capture).
*1. Add the dependencies*
```elixir
def deps do
[
{:oled, "~> 0.1.0"},
{:scenic, "~> 0.10"},
{:scenic_driver_nerves_rpi, "~> 0.10", targets: @all_targets},
{:rpi_fb_capture, "~> 0.3.0"}
]
end
```
*2. Configure the driver*
Passing the configuration for the display...
```elixir
config :my_app, :viewport, %{
name: :main_viewport,
default_scene: {MyApp.Scene.Default, nil},
size: {128, 64},
opts: [scale: 1.0],
drivers: [
%{
module: OLED.Scenic.Driver,
opts: [
display: [
driver: :ssd1306,
type: :i2c,
device: "i2c-1",
address: 60,
width: 128,
height: 32
],
dithering: :sierra
]
}
]
}
```
... or the display module if you have one (Check the Basic Setup):
```elixir
config :my_app, :viewport, %{
name: :main_viewport,
default_scene: {MyApp.Scene.Default, nil},
size: {128, 64},
opts: [scale: 1.0],
drivers: [
%{
module: OLED.Scenic.Driver,
opts: [
display: MyApp.MyDisplay,
dithering: :sierra
]
}
]
}
```
## Thanks
Special thanks to [@nerves-training](https://github.com/nerves-training) where I've seen for the first time approach of use `rp_fb_capture` in [scenic_driver_oled_bonnet](https://github.com/nerves-training/scenic_driver_oled_bonnet) to implement a Scenic driver.