[DIY] Controlo multimedia com Arduino

Iniciado por BrunoPT, 22 de Dezembro de 2012, 10:58

tópico anterior - próximo tópico

BrunoPT

Boas, eu sou um iniciante em arduino e quero partilhar com o resto da comunidade, é um controlador multimedia.
Este controlador mostra o artista e a musica que está a ouvir e tem botoes para avançar para a musica seguinte, voltar á musica anterior, play/pausa, stop e ligar/desligar backlight.

O código foi feito á pressa e pode ser melhorado, mas funciona bem.

Resultado Final:
http://img7.imageshack.us/img7/5865/img20121222124215.jpg

Material necessário:
LCD Keypad Shield
Arduino (Usei o Duemilanove)
PC Linux com Rhythmbox

Código em Python (parte no pc):
#! /usr/bin/env python

import os
import serial
from time import sleep

PORTA_SERIE = "/dev/ttyUSB3" #PORTA SERIE
MUSIC_PROG = "rhythmbox-client" #NOME DO PROGRAMA
PROXIMA = "next" #COMANDO PARA PROXIMA
ANTERIOR = "previous" #COMANDO PARA ANTERIOR
REPRODUZIRPAUSA = "play-pause" #COMANDO PLAY/PAUSE
class mainprogram():
   def __init__(self):
       
       try:
           ser = serial.Serial(PORTA_SERIE, 9600, timeout=1)
       except Exception as e:
           print e
       
       ser.write("1Bem Vindo"+chr(10)+chr(13))
       ser.write("2LCD = OK "+chr(10)+chr(13))
       lastsong = ""
       lastartist = ""
       #Procurar por comandos
       try:
           while True:
               comando = ser.readline()
               while comando[-1:] == chr(13) or comando[-1:] == chr(10):
                   comando = comando[:-1]
               #MUSICA
               if comando == "0": #STOP
                   self.execute(MUSIC_PROG, REPRODUZIRPAUSA)
                   self.execute(MUSIC_PROG, ANTERIOR)
                   ser.write("ACK" + chr(13) + chr(10))
               elif comando == "1": #REPRODUZIR / PAUSA
                   self.execute(MUSIC_PROG, REPRODUZIRPAUSA)
                   ser.write("ACK" + chr(13) + chr(10))
               elif comando == "2": #ANTERIOR
                   self.execute(MUSIC_PROG, ANTERIOR)
                   ser.write("ACK" + chr(13) + chr(10))
               elif comando == "3": #SEGINTE
                   self.execute(MUSIC_PROG, PROXIMA)
                   ser.write("ACK" + chr(13) + chr(10))
               else:
                   if not comando == "":
                       comando = ""
                   
                   aberto = self.esta_aberto("rhythmbox")
                   if aberto == True:
                       musica = self.nome_musica()
                       ser.write("2"+musica.replace(chr(10), "")+chr(10) + chr(13))
                           
                       artista = self.nome_artista()
                       
                       if artista.replace(chr(10), "") == "":
                           artista = "Prima REPRODUZIR";
                           
                       ser.write("1"+artista.replace(chr(10), "")+chr(10) + chr(13))
                           
                       
                   else:
                       ser.write("1Rep. Musica"+chr(10) + chr(13))
                       ser.write("2Nao iniciado"+chr(10)+chr(13))
                       
               sleep(0.1)
       except Exception as e:
           print e
           print "DISCONECTADO"
           pass

   def esta_aberto(self, prog):
       stdout_handle = os.popen("ps aux", "r")
       text = stdout_handle.read()
       if text.find(prog) > 0:
           return True
       else:
           return False

   def execute(self, program, action = ""):
       try:
           if not action == "":
               stdout_handle = os.popen(program + " --" +action, "r")
           else:
               stdout_handle = os.popen(program, "r")
       except Exception as e:
           print e
           pass
       
   def nome_musica(self):
       stdout_handle = os.popen(MUSIC_PROG + " --print-playing-format=%tt", "r")
       text = stdout_handle.read()
       return text
   
   def nome_artista(self):
       stdout_handle = os.popen(MUSIC_PROG + " --print-playing-format=%ta", "r")
       text = stdout_handle.read()
       return text
   
   def getcurrentsongtime(self):
       stdout_handle = os.popen(MUSIC_PROG + " --print-playing-format=%te/%td", "r")
       text = stdout_handle.read()
       return text
       

   

if __name__ == '__main__':
   mainprogram()


Código para o arduino:
#include <LiquidCrystal.h>   // incluir livraria LCD

#define BUTTON_ADC_PIN           A0  // A0 e o ADC dos botoes
#define LCD_BACKLIGHT_PIN        10  // Pin digital de backlight do lcd
#define RIGHT_10BIT_ADC           0  // direita
#define UP_10BIT_ADC            145  // cima
#define DOWN_10BIT_ADC          329  // baixo
#define LEFT_10BIT_ADC          505  // esquerda
#define SELECT_10BIT_ADC        741  // direirta

LiquidCrystal lcd( 8, 9, 4, 5, 6, 7 );   //Pinos para o meu shield 16x2 LCD shield. LCD: ( RS, E, LCD-D4, LCD-D5, LCD-D6, LCD-D7 )

int comando;
int bkstate;


void setup()
{
 Serial.begin(9600);
 pinMode( BUTTON_ADC_PIN, INPUT );         //tornar ADC em input
 digitalWrite( BUTTON_ADC_PIN, LOW );      //desligar pullup no A0
 digitalWrite( LCD_BACKLIGHT_PIN, HIGH );  //ligar backlight
 pinMode( LCD_BACKLIGHT_PIN, OUTPUT );     //backlight e output
 lcd.begin( 16, 2 );                       //O LCD e 16x2
 lcd.setCursor( 0, 0 );
 lcd.print( "A espera de" );
 lcd.setCursor( 0, 1 );
 lcd.print( "conexao" );
 bkstate = 1;
}

void loop()
{
 buttonHandler();
 serialReader();
}

void buttonHandler() //VERIFICADOR DE BOTOES
{
 unsigned int buttonVoltage;
 buttonVoltage = analogRead( BUTTON_ADC_PIN );
 if( buttonVoltage < ( RIGHT_10BIT_ADC + 10 ) )
 {
   //BT DIREITA
   Serial.println(3);
   while ( buttonVoltage < ( RIGHT_10BIT_ADC + 10 ) )
   {
     buttonVoltage = analogRead( BUTTON_ADC_PIN );
     delay(100);
   }
   return;
   return;
 }
 else if(   buttonVoltage >= ( UP_10BIT_ADC - 10 )
   && buttonVoltage <= ( UP_10BIT_ADC + 10 ) )
 {
   //BT CIMA
   Serial.println(1);
   while (buttonVoltage >= ( UP_10BIT_ADC - 10 )
   && buttonVoltage <= ( UP_10BIT_ADC + 10 ) )
   {
     buttonVoltage = analogRead( BUTTON_ADC_PIN );
     delay(100);
   }
   return;
 }
 else if(   buttonVoltage >= ( DOWN_10BIT_ADC - 10 )
   && buttonVoltage <= ( DOWN_10BIT_ADC + 10 ) )
 {
   //BT BAIXO
  Serial.println(0);
  while (buttonVoltage >= ( DOWN_10BIT_ADC - 10 )
   && buttonVoltage <= ( DOWN_10BIT_ADC + 10 ) )
   {
     buttonVoltage = analogRead( BUTTON_ADC_PIN );
     delay(100);
   }
  return;
 }
 else if(   buttonVoltage >= ( LEFT_10BIT_ADC - 10 )
   && buttonVoltage <= ( LEFT_10BIT_ADC + 10 ) )
 {
   //BT ESQUERDA
   Serial.println(2);
   while (buttonVoltage >= ( LEFT_10BIT_ADC - 10 )
   && buttonVoltage <= ( LEFT_10BIT_ADC + 10 ) )
   {
     buttonVoltage = analogRead( BUTTON_ADC_PIN );
     delay(100);
   }
   return;
 }
 else if(   buttonVoltage >= ( SELECT_10BIT_ADC - 10 )
   && buttonVoltage <= ( SELECT_10BIT_ADC + 10 ) )
 {
   //BOTAO DE BACKLIGHT 1 - ESQUERDA
   if (bkstate == 1)
   {
     digitalWrite( LCD_BACKLIGHT_PIN, LOW );
     bkstate=0;
   }
   else
   {
     digitalWrite( LCD_BACKLIGHT_PIN, HIGH );
     bkstate=1;
   }

   while (buttonVoltage >= ( SELECT_10BIT_ADC - 10 )
     && buttonVoltage <= ( SELECT_10BIT_ADC + 10 ) )
   {
     buttonVoltage = analogRead( BUTTON_ADC_PIN );
     delay(100);
   }
 }
}
void serialReader()
{
 boolean end = false;
 int makeSerialStringPosition;
 int inByte;
 char serialReadString[50] = "";
 char received[45] = "";
 const int terminatingChar = 13; //Terminar com CR

 inByte = Serial.read();
 makeSerialStringPosition=0;

 if (inByte > 0 && inByte != terminatingChar)
 { //Se o inByte nao estiver vazio (inByte > 0) e se nao for CR
   delay(100); //Dar tempo

   while (inByte != terminatingChar && Serial.available() > 0)
   { // Ler ate ao fim
     serialReadString[makeSerialStringPosition] = inByte; // guardar o byte no array
     makeSerialStringPosition++; //passar para o proximo valor no array
     //if (inByte > 0) Serial.println(inByte); // Debug
     inByte = Serial.read(); // Ler o proximo byte
   }
   if (inByte == terminatingChar) //SE ACABOU BEM
   {
     if (strncmp(serialReadString, "1", 1) == 0)
     {
       lcd.setCursor(0,0);
       lcd.print("                ");
       lcd.setCursor(0,0);
       for (int i = 1; i < makeSerialStringPosition - 1; i++)
       {
         received[i - 1] = serialReadString[i];
       }

       lcd.print(received);
     }

     if (strncmp(serialReadString, "2", 1) == 0)
     {
       lcd.setCursor(0,1);
       lcd.print("                ");
       lcd.setCursor(0,1);
       for (int i = 1; i < makeSerialStringPosition - 1; i++)
       {
         received[i - 1] = serialReadString[i];
       }

       lcd.print(received);
     }


   }

   serialReadString[makeSerialStringPosition] = 0; //REMOVER CARACTER DE TERMINACAO
 }
}




Nota: Com este codigo podem fazer o que quiserem com o arduino, basta alterarem o codigo do programa em Python.

Podem utilizar o codigo á vontade :)


Kriptolix

Cara, parabens, por esses dias estava pensando em um interface arduino pra transformar meu pc em um som na sala, mas acabei esbarrando no meu pouco conhecimento do assunto e no custo o shield e da tela lcd pra faze-lo (sem contar o receptor IR). Obrigado por compartilhar, quem sabe da um impulso no meu tao sonhado controlador arduino lcd IR no pc.
Ubuntu Linux 10.10

BrunoPT

Citação de: kriador online 24 de Dezembro de 2012, 23:42
Cara, parabens, por esses dias estava pensando em um interface arduino pra transformar meu pc em um som na sala, mas acabei esbarrando no meu pouco conhecimento do assunto e no custo o shield e da tela lcd pra faze-lo (sem contar o receptor IR). Obrigado por compartilhar, quem sabe da um impulso no meu tao sonhado controlador arduino lcd IR no pc.

Eu tambem vou fazer isso. Quando estou só a espera do modulo IR.

Kriptolix

Bruno, dependendo do nivel de dificuldade pra fazer em como fique o acabamento, eu acho que tem mercado pra isso, a soluçao da akasa que faz algo parecido custa em torno de 380 reais e é quase impossivel de achar pra comprar no brasil (so vi uma vez), mande noticias quando terminar e voce pode ter potenciais clientes :)
Ubuntu Linux 10.10

BrunoPT

basicamente so é necessario um modulo de IR ligado ao pc por porta serie usb, depois é so fazer um software para programar as teclas.

Tota

Citação de: BrunoPT online 28 de Dezembro de 2012, 12:19
basicamente so é necessario um modulo de IR ligado ao pc por porta serie usb, depois é so fazer um software para programar as teclas.

Ola,

Creio que nem precisa, pois um receptor ligado a usb pode ser controlado pelo pacote lirc

http://www.lirc.org/

[]'s