Aqui no Arduino e Cia já vimos como utilizar o módulo encoder KY-040 com Arduino, no post Como usar um encoder rotativo com Arduino. Neste post vamos mostrar como você pode usar esse encoder rotativo com Raspberry Pi.

O módulo KY-40 é esse da imagem abaixo. Ele possui rotação contínua e um botão no eixo que permite que você faça por exemplo um sistema de navegação por menus e seleção de itens.

Encoder rotativo KY-040

No post do encoder com Arduino nós usamos esse botão central, mas hoje vamos usar apenas a função de seleção por rotação do eixo do encoder. De qualquer forma, é um botão tipo push-button, muito simples de usar.

Ligação do módulo KY-040 na Raspberry Pi Zero W

Nos nossos testes vamos utilizar o KY-040 juntamente com um display Oled 128×64 com comunicação I2C, que vai mostrar o valor de um contador.

A placa que vamos utilizar é a Raspberry Pi Zero W com header, que apesar de estar a um bom tempo no mercado e ser muito utilizada em projetos de IoT é a primeira vez que dá as caras aqui no blog.

O display Oled será conectados nos pinos 3 (SDA I2C) e 5 (SCL I2C) da GPIO, enquanto os pinos CLK e DT do módulo encoder serão conectados nos pinos 12 (GPIO 18) e 11 (GPIO 17), respectivamente. Confira a ligação na imagem abaixo:

Circuito Raspberry Pi Zero W com Encoder e display Oled I2C

A alimentação tanto do módulo como do display serão feitas pelo pino 3.3V da GPIO. Muita atenção com a ligação display Oled, pois em alguns modelos os pinos Vcc e GND estão invertidos, ok?

Biblioteca e programa encoder rotativo com Raspberry Pi

Para os próximos passos estou considerando que você está com a sua placa Raspberry Pi preparada e com o sistema operacional instalado e conectado na rede wifi.

Para instalação do SO (estamos usando o Raspbian), recomendo usar o Raspberry Pi Disk Imager, que mostro no post Raspberry Pi Disk Imager: um jeito fácil de instalar o Raspbian.

Primeiramente vamos atualizar o Raspbian utilizando os comandos abaixo:

sudo apt-get update
sudo apt-get upgrade

Essa atualização do sistema operacional pode demorar uns bons minutos, ok?

Antes de mais nada, precisamos habilitar a interface I2C da Raspberry Pi usando o raspi-config. Abra uma janela de terminal e digite:

sudo raspi-config

Na tela do raspi-config, navegue até a opção 5 (Interfacing Options), e depois habilite a interface I2C:

Raspi-config habilitar interface I2C Raspberry Pi

Instale a biblioteca do display Oled usando os comandos:

sudo apt install python3-dev python3-pip libfreetype6-dev libjpeg-dev build-essential libopenjp2-7 libtiff5
sudo -H pip3 install --upgrade luma.oled

Você vai precisar também da fonte Minecraftia-Regular.ttf que você encontra neste link. Esse arquivo com a extensão ttf (TrueType Font) precisa ficar na mesma pasta onde você vai colocar o programa em Python, ok?

Para o programa, use o editor de sua preferência e digite ou copie o código abaixo:

#Programa: Encoder Rotativo com Raspberry Pi Zero W
#Autor: Arduino e Cia

from luma.core.interface.serial import i2c
from luma.core.render import canvas
from luma.oled.device import ssd1306, ssd1325, ssd1331, sh1106
from time import sleep
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
from RPi import GPIO

#Pinos/GPIO de conexao com o modulo KY-040
clk = 18
dt = 17

GPIO.setmode(GPIO.BCM)
GPIO.setup(clk, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(dt, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

#Variaveis contador
counter = 0
clkLastState = GPIO.input(clk)

#Definicoes da interface I2C e display
serial = i2c(port=1, address=0x3C)
device = ssd1306(serial, rotate=0)

#Fontes
#font = ImageFont.load_default() #se vc deseja usar a fonte padrao
font1 = ImageFont.truetype('Minecraftia-Regular.ttf', 14)
font2 = ImageFont.truetype('Minecraftia-Regular.ttf', 13)
font3 = ImageFont.truetype('Minecraftia-Regular.ttf', 20)


#Tela inicial
with canvas(device) as draw:
    draw.rectangle(device.bounding_box, outline="white", fill="black")
    draw.rectangle((0,0,128,19), outline="white", fill="white")
    draw.text((7, 1), "Arduino e Cia", font=font1, fill="black")
    draw.text((32, 20), "Encoder", font=font2, fill="white")
    draw.text((57, 37), "0", font=font3, fill="white")
sleep(1)

try:
        while True:
                clkState = GPIO.input(clk)
                dtState = GPIO.input(dt)
                if clkState != clkLastState:
                        if dtState != clkState:
                                counter += 1
                        else:
                                counter -= 1
                        #mostra no terminal o valor do encoder
                        print (counter)
						#atualiza o display com as informacoes do encoder
                        with canvas(device) as draw:
                            draw.rectangle(device.bounding_box, outline="white", fill="black")
                            draw.rectangle((0,0,128,19), outline="white", fill="white")
                            draw.text((7, 1), "Arduino e Cia", font=font1, fill="black")
                            draw.text((32, 20), "Encoder", font=font2, fill="white")
                            draw.text((57, 37), str(counter), font=font3, fill="white")
                        sleep(.1)
                clkLastState = clkState
                sleep(0.01)
finally:
        GPIO.cleanup()

Salve o arquivo com o nome de encoder.py e execute o programa utilizando o comando

sudo python3 encoder.py

Ao executar o programa você verá no display Oled o valor gerado pelo encoder (começando por zero). Gire o eixo do encoder no sentido horário para aumentar o valor e no sentido antihorário para diminuir.

O display I2C que estou usando tem o endereço I2C 0x3C, e esse valor está especificado no programa na linha 26 (logo após address). Se você precisar checar o endereço do seu display, utilize o comando abaixo:

i2cdetect -y 1

Se as conexões do display estiverem corretas, ele vai gerar uma saída como essa abaixo:

I2Cdetect Raspbian

Gostou? Tem muito mais post usando Raspberry Pi aqui no Arduino e Cia!

Avalie este post!