PCDisplay
Github: https://github.com/lucasoshiro/pcdisplay
Este projeto trata-se de um display LCD acoplado ao gabinete de meu computador, mostrando as seguintes informações:
- Uso de CPU
- Uso de RAM
- Velocidade de download/upload
- Temperatura do processador
- Data e hora
- Hostname e versão do sistema operacional
- Título e artista da faixa em execução
O hardware foi feito com um Arduino Nano junto do display em si. No repositório está contido o código host, feito em Ruby, que centraliza as informações do computador e as fornece para o Arduino, e o código guest, usado pelo Arduino para controlar o display.
Fluxo
+-----+ +---------+ Requisição +------------+ |Botão| --------> | Arduino | ----------------> | PC | +-----+ | (guest) | | (host) | | | <---------------- | | +---------+ Dados +------------+ | | | V +---------+ | Display | +---------+
As requisições têm o formato REQUISIÇÃO <argumentoss>
, com cada argumento
separado por espaço. O argumento também pode vir entre aspas, podendo ser
escapado da mesma forma que no bash. As respostas são enviadas no formato
REQUISIÇÃO <dados>
, com o mesmo nome da requisição.
PCDisplay Host
O PCDisplay host é executado no computador e envia os dados ao Arduino. Ele é composto pelos seguintes arquivos:
-
arduino_serial.rb
: contém a classe Arduino, que abstrai a biblioteca SerialPort, para facilitar a comunicação com o Arduino; -
serial_server.rb
: biblioteca que permite a criação de um servidor capaz de processar uma requisição feita pelo Arduino, e enviar os dados requeridos, com sintaxe semelhante ao framework Sinatra; -
pc.rb
: contém a classe SingletonPC
, que centraliza as diversas leituras do computador, provendo sempre de forma rápida os dados. Cada “leitor” é executado em uma thread diferente, atualizando os dados do singletonPC
conforme os dados são obtidos; -
main.rb
: neste arquivo são definidas os callbacks para cada requisição, no seguinte formato:
request 'REQUISIÇÃO' do
dado = algum_processamento
"REQUISIÇÃO #{dado}"
end
Ou seja, o fluxo é o seguinte:
+-------+ Requisição +------------+ +--------+ | | -------------> |SerialServer| ---> | | |Arduino| +------------+ |callback| | | <--------------------------------- | | +-------+ Dados +--------+ ^ | +------------+ +--------+ | | <----- | Player | | PC | +--------+ | | +------------+ <----- +--------+ ^ ^ ^ ^ ^ | Rede | | | | | | +--------+ +-----+ | +---+ | +----+ | CPU | | |RAM| | |Hora| +-----+ | +---+ | +----+ | | +--------+ +-----------+ |Hostname| |Temperatura| +--------+ +-----------+
PCDisplay Guest
O PCDisplay Guest é executado no Arduino, e ele funciona como uma máquina de estados:
+---------+ +------+ +-----+ | SYSINFO | ------> | TIME | -------> | CPU | +---------+ +------+ +-----+ ^ | | V +-------+ +-----+ +------+ +-----+ | MEDIA | <-- | NET | <--- | TEMP | <-- | RAM | +-------+ +-----+ +------+ +-----+
Cada estado tem uma função de atualização da tela associada, que lê as
informações contidas na struct global INFO
, e as mostra na tela.
O loop principal realiza um ciclo das seguintes ações:
-
Caso uma troca de estado esteja agendada, troca de estado, senão permanece no atual;
-
Envia uma requisição das listas de requisições;
-
Espera o resultado e atualiza a struct
INFO
com os dados vindos do computador. Caso exceda o limite de tempo, entende-se a conexão foi perdida e tenta-se conectar novamente; -
Mostra a informação na tela, executando-se a função associada ao estado.
O agendamento de uma troca de estado ocorre quando o botão é pressionado. Esse evento causa uma interrupção, ativando uma flag que indica que no próximo ciclo o estado deverá ser trocado.
Galeria
Update (10/2021)
Depois de algum tempo, o display tinha dado problema e eu resolvi trocar por um novo, gráfico, de 128x64 pixels. Nesse novo display é possível mostrar todas as informações em uma só tela, não é necessário mais usar a máquina de estados.
Quanto ao resto do código, permanece igual.