Saturday, February 8, 2014

Adding 16x2 LCD and Rotary Encoder

As mentioned in my previous post, I got the remaining parts I needed for my grooveshark radio project: LCD, rotary encoder and hifi USB audio DAC.

First step was to get the LCD and rotary encoder to work with Arduino. For that purpose I made a board following the schematic on the next picture:


This is how the board looked like:


The two black things in the bottom are connectors for the cables that go to the arduino.

You can get instructions on how to use the LCD here: http://arduino.cc/es/Tutorial/LiquidCrystal
And regarding the rotary encoder, I used this library: http://www.pjrc.com/teensy/td_libs_Encoder.html

Works like a charm!!!

And this is the previous Arduino code modified to use both the LCD and the rotary encoder (the linino side remains unchanged):

#include <Encoder.h>
#include <LiquidCrystal.h>
#include <FileIO.h>

#define    GENRE_NONE             0
#define    GENRE_ROCK             12
#define    GENRE_BLUES            230
#define    GENRE_ELECTRONICA      67
#define    GENRE_CLASSICROCK      3529
#define    GENRE_INDIE            136
#define    GENRE_METAL            17


int stations[] = { GENRE_NONE,
    GENRE_ROCK,
    GENRE_BLUES,
    GENRE_ELECTRONICA,
    GENRE_CLASSICROCK,
    GENRE_INDIE,
    GENRE_METAL };


String stations_str[] = { "None",
    "Rock",
    "Blues",
    "Electronica",
    "Classic Rock",
    "Indie",
    "Metal" };
    
int genres;
int val = 0;
int enc_val = 0;
int prevVal = 0;
Process radio_process;
String label_song, label_artist;



LiquidCrystal lcd(13, 12, 11, 10, 9, 8);
Encoder knob(2,4);
int knob_sw = 3;

void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);

  // Print a message to the LCD.
  lcd.print("Grooveshark!!");

  pinMode(knob_sw, INPUT);
  digitalWrite(knob_sw, HIGH);

  genres = sizeof(stations)/sizeof(int);
  Serial.begin(9600);
  Bridge.begin();

  start_radio(val);  

}

void loop() {
  long knob_value = knob.read();

  if(knob_value > 0) {
    enc_val++;
    if(enc_val>=genres) enc_val = genres - 1;
  }
  else {
    if(knob_value < 0) {
      enc_val--;
      if(enc_val<0) enc_val = 0;      
    }
  }
  
  int sw_value = digitalRead(knob_sw);  
  
  Serial.println(sw_value);
  if(!sw_value){
    val = enc_val;
  }
  
  if(knob_value!=0 || !sw_value) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Radio:");
    lcd.setCursor(0, 1);
    if(enc_val == val) {  
      lcd.print("-");
    }
    else {  
      lcd.print(" ");
    }

    lcd.print(stations_str[enc_val]);
  }
  knob.write(0);

  
  if(val != prevVal) {
    String text;
    text = "Value: ";
    text += val;

    start_radio(val);
    
    prevVal = val;
  } 
  
  char labelbuffer_song[256];
  char labelbuffer_artist[256];
  Bridge.get("songName", labelbuffer_song, 256); 

  if (String(labelbuffer_song).length() > 0 && label_song != String(labelbuffer_song)){
    lcd.clear();
    label_song = String(labelbuffer_song);
    
    lcd.setCursor(0, 1);
    lcd.print(label_song);
    Bridge.get("songArtist", labelbuffer_artist, 256);
    label_artist = String(labelbuffer_artist);
    
    lcd.setCursor(0, 0);
    lcd.print(label_artist);
    
  }
  
}

void start_radio(int val) {
    String parameter = "";
    radio_process.close();
    Process killer;
    killer.begin("killall");
    killer.addParameter("mpg123");
    killer.run();
    if(stations[val] != 0) {
      radio_process.begin("python");
      radio_process.addParameter("/root/examples-pygrooveshark/radio_mpg123.py");
      parameter+= stations[val];
      radio_process.addParameter(parameter);
      radio_process.runAsynchronously();
    }
    else {
      radio_process.begin("echo");
      radio_process.addParameter("Do Nothing!!!");
      radio_process.runAsynchronously();
    }
}


Moving the rotary encoder I can move through the radio genres and by pressing the rotary encoder shaft I can select it.

What is next? improve both the UI and the python script to add playlists, user favourites and popular songs.

No comments:

Post a Comment