Quantcast
Viewing all articles
Browse latest Browse all 13

Creating a Spotify remote with an Arduino and LCD Shield

Image may be NSFW.
Clik here to view.
spotifyremote
This one is for the Spotify people. We’ve created a small project that makes use of the Arduino and LCD Keypad shield to create a Spotify remote control. This will show the current playing song as well as adding Play/Pause, Prev and Next functionality to it.

Check out the quick YouTube video at the bottom of this page.

The remote is made from a VB.NET application that listens on a select COM port for commands, it also broadcasts the current playing song via the COM port to the Arduino.

You could add a Bluetooth module to this (described in our previous article here) to make it completely wireless, which would be really cool.

So, what’s needed?

We’ll begin by creating the Arduino sketch. What we need to do is the following:

  1. Read the Serial Port and look for incoming characters that make up the current song.
  2. Listen for button presses and Serial.println() commands.
  3. Display the current song on the LCD (with Scrolling Text)

These three tasks are actually really simple to do; most of the hard work will be on the .NET application side that sends commands to Spotify. Take a look at the Arduino Sketch below:

The Arduino Sketch

#include <LiquidCrystal.h>

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
String inData;
String currentSong;
String lastSong;

typedef struct Timer  {
    unsigned long tStart;
    unsigned long tTimeout;
};

bool tCheck (struct Timer *timer ) {
    if (millis() > timer->tStart + timer->tTimeout) 
        return true;

    return false;    
}

void tRun (struct Timer *timer) {
    timer->tStart = millis();
}

//Tasks and their Schedules.
Timer t_updateLCD = {0, 3500}; //Run every 2 seconds.

void setup() {
   Serial.begin(9600);
   lcd.begin(16, 2);
}

void loop() {
  //Call the main menu.
  mainMenu();

 while (Serial.available() > 0) {
        char recieved = Serial.read();
        inData += recieved; 

        // Process message when new line character is recieved
        if (recieved == '\n') {
            Serial.print("Arduino Received: ");
            Serial.print(inData);
            currentSong = inData;
            inData = ""; // Clear recieved buffer
        }
    }

    //Update LCD.
    if (tCheck(&t_updateLCD)) {
          lcd.clear();
          lcd.setCursor(0,0);
          lcd.print("Playing:");
          lcd.setCursor(0,1);
          int index = 0;
          int len = (currentSong.length() - 2);
          for (int i=0; i<len;i++) {
            if (index == 16) {
              lcd.setCursor(0,1);
              lcd.print("                "); //Clear line
              index = 0; 
              delay(200);
            }
            lcd.setCursor(index,1); 
            lcd.print(currentSong[i]);
            delay(150);
            index++;
          }
          lastSong = currentSong;

      tRun(&t_updateLCD);
    }
}

void mainMenu() {
  int x = analogRead (0);
  lcd.setCursor(0,0);

  //Check analog values from LCD Keypad Shield
  if (x < 100) {
    //Right
    Serial.println("next|");
  } else if (x < 200) {
   //Up
   //Not assigned yet. Add commands here.
  } else if (x < 400){
   //Down
  } else if (x < 600){
    //Left
    Serial.println("prev|");
  } else if (x < 800){
    //Select
    Serial.println("pause|");
  }
  delay(50);
}

The Arduino refreshes the LCD Screen every 3500ms. This is optional but it seemed better that it was constantly scrolling instead of just static text; moving text seems less boring!

As far as the Arduino code is concerned; that’s all there is to it. We’ll now move over to Visual Studio and get started with the application we have put together. The actual Spotify control class is by a person named Steffest who released this back in 2009 – We can’t really give you much more than that, as there is no website for this code.

You can download the Project Code by clicking here. (it is also posted below)

The .NET Application

Imports System.IO
Imports System.IO.Ports
Imports System.Threading

Public Class Form1
    Dim currentSong As String
    Dim buffer As String
    Delegate Sub myMethodDelegate(ByVal [text] As String)
    Dim hdlD As New myMethodDelegate(AddressOf processCommand)
    Dim WithEvents SerialPort As New IO.Ports.SerialPort
    Dim p() As Process

    Private Sub Form1_Disposed(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Disposed
        If SerialPort.IsOpen() Then
            SerialPort.Close()
        End If
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ni.Visible = False
        GetSerialPortNames()
    End Sub

    Sub GetSerialPortNames()
        For Each sp As String In My.Computer.Ports.SerialPortNames
            lstPorts.Items.Add(sp)
        Next
    End Sub

    Sub SendSerialData(ByVal Port As String, ByVal data As String)
        If (SerialPort.IsOpen) Then
            SerialPort.Write(data)
        Else
            MsgBox("Not connected to Port.")
        End If
    End Sub

    Sub processCommand(ByVal myString As String)
        buffer = buffer + myString
        Dim str As String
        str = buffer
        If InStr(str, "|") Then
            Dim words As String() = str.Split(New Char() {"|"})
            buffer = ""
            Dim word As String
            For Each word In words
                If (word.Length > 0) Then
                    Dim Spotify As New spotify()
                    Select Case word
                        Case "prev"
                            Spotify.PlayPrev()
                            lstConsole.Items.Add("Play previous song.")
                        Case "next"
                            Spotify.PlayNext()
                            lstConsole.Items.Add("Play next song.")
                        Case "pause"
                            Spotify.PlayPause()
                            lstConsole.Items.Add("Spotify paused.")
                        Case Else
                            '  We received an Unknown command. Deal with it.
                            '  lstConsole.Items.Add("Received: " & word)
                    End Select
                End If
            Next
        End If

    End Sub

    Private Sub SerialPort_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort.DataReceived
        Dim str As String = SerialPort.ReadExisting()
        Invoke(hdlD, str)
    End Sub
    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Application.Exit()
        If SerialPort.IsOpen Then
            SerialPort.Close()
        End If
    End Sub
    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        checkSongStatus()
    End Sub

    Private Sub checkSongStatus()
        p = Process.GetProcessesByName("Spotify")
        If p.Count > 0 Then
            lblStatus.Text = "Spotify is running."
            Dim Spotify As New spotify()
            If Spotify.Nowplaying() <> currentSong Then
                currentSong = Spotify.Nowplaying()
                If currentSong = "" Or currentSong = "Paused." Then
                    lstConsole.Items.Add("Spotify Paused.")
                Else
                    lstConsole.Items.Add("Song changed to: " & currentSong)
                    If (SerialPort.IsOpen()) Then
                        SerialPort.Write(currentSong & vbCrLf)
                    End If
                End If
            End If
        Else
            lblStatus.Text = "Spotify is NOT running."
        End If
    End Sub
    Private Sub Form1_SizeChanged(ByVal sender As Object, ByVal e As System.EventArgs) _
 Handles MyBase.SizeChanged

        If Me.WindowState = FormWindowState.Minimized Then
            Me.WindowState = FormWindowState.Minimized
            Me.Visible = False
            Me.ni.Visible = True
        End If

    End Sub
    Private Sub ni_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
 Handles ni.Click

        Me.Visible = True
        Me.WindowState = FormWindowState.Normal
        Me.ni.Visible = False

    End Sub

    Private Sub btnConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConnect.Click
        If lstPorts.SelectedIndex <> -1 Then
            Try
                If SerialPort.IsOpen Then
                    SerialPort.Close()
                    btnConnect.Text = "Connect"
                Else
                    SerialPort.PortName = lstPorts.SelectedItem.ToString
                    SerialPort.BaudRate = 9600
                    SerialPort.DataBits = 8
                    SerialPort.Parity = Parity.None
                    SerialPort.StopBits = StopBits.One
                    SerialPort.Handshake = Handshake.None
                    SerialPort.Encoding = System.Text.Encoding.Default
                    SerialPort.Open()
                    btnConnect.Text = "Disconnect"
                End If
            Catch ex As Exception
                MsgBox(ex.Message)
            End Try
        Else
            MsgBox("Please choose a serial port", vbInformation, "Serial Port")
        End If
    End Sub
End Class

The application works by listening and sending information on the same COM port as the Arduino. The application listens for 3 commands (play/plause, prev, next) once these get detected they send the relevant command over to the Spotify application. Information about the current song is then sent to the COM port and received by the Arduino, which outputs this to the attached LCD screen.

Once the application is loaded and in use it should look like the below:

Image may be NSFW.
Clik here to view.
remote

As you can see, the only options you have is to select a COM port (this should be the Arduino’s COM port) and a Connect/Disconnect button. That’s it! – The console window at the bottom updates in realtime as to what is getting sent/received from the Arduino.

Check out the YouTube video of this in operation: (apologies for the quality, it’s the phone camera again!)

 

It’s actually quite fun to play around with; this would look great sat on the desk with an enclosure made for it.

That’s it for now, if you have any comments, questions or suggestions then please feel free to comment below or send us a message using the contact us page.

Have fun!


Viewing all articles
Browse latest Browse all 13

Trending Articles