Author Topic: Displaying Volume control on LCD using Digital potentiometer and Arduino  (Read 3112 times)

0 Members and 1 Guest are viewing this topic.

Offline radhikaTopic starter

  • Regular Contributor
  • *
  • Posts: 105
  • Country: in
Hello,
I am working on project which is speaker and where I am using digital potentiometer to change the volume. This varying of volume will display on LCD and decrease or increase of volume take place via button (up for Increase button and down for decrease button). The display show the number of volume i.e (0, 16, 32, 48, 64, 80, 96, 112, 128), also it diplay "Min Volume" when reached to 16 and "Max Volume" when reached to 128. Here is the code:
Code: [Select]
/*
MCP4018T103E connected to  arduino Board
  CS >>> D10
  SCLK >> D13
  DI  >>> D11
  PA0 TO VCC
  PBO TO GND
  PW0 TO led with resistor 100ohm .
*/
#include <SPI.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 9, 5, 4, 3, 2);  //RS = 12, E = 9,

byte address = 0x11;
const int CS= 10;
int i=0;
int vol = 0;

const int DOWN_BUTTON_PIN = 1;
const int UP_BUTTON_PIN = 0;

volatile boolean up = false;
volatile boolean down = false;

long time = 0;
long debounce = 200;

void setup()
{
 lcd.clear();
  lcd.begin(16, 2);  //LCD have 16 column and 2 rows
  lcd.setCursor(1,0);  //LCD cursor set at 1st clomn and 0 rows
  pinMode(UP_BUTTON_PIN, INPUT_PULLUP);  //button
  pinMode(DOWN_BUTTON_PIN, INPUT_PULLUP);
 
  pinMode (CS, OUTPUT);
  SPI.begin();
  // adjust high and low resistance of potentiometer
  // adjust Highest Resistance .
   digitalPotWrite(0); //0
   delay(1000);
 
      // adjust  wiper in the  Mid point  .
   digitalPotWrite(64); //64
   delay(1000);

   // adjust Lowest Resistance .
   digitalPotWrite(128); //128
   delay(1000);
}

void loop()
{
  checkIfDownButtonIsPressed(digitalRead(DOWN_BUTTON_PIN));
  checkIfUpButtonIsPressed(digitalRead(UP_BUTTON_PIN));
 
  if (up || down)
  {  // Slow the up/down menus a bit
    delay(1000);
  }
 
    for (i = 0; i <= 127; i=i+16)
    {
       if (up) {   //UP Button Logics
       up = false;
       i = i + 16;
      vol = digitalPotWrite(i);
      lcd.setCursor(1,0); //Column 1 and Row 0
      lcd.print("Volume:  vol");
      if ( i == 127)
      {
      lcd.setCursor(1,1);
      lcd.print(" MAX VOLUME ");
      delay(10);
      }
       }
    }
    delay(500);
    for (i = 128; i > 0; i= i-16)
    {
       if (down) { //DOWN Button Logics
       down = false;
       i = i - 16;
      vol = digitalPotWrite(i);
      lcd.setCursor(1,0); //Column 1 and Row 0
      lcd.print("Volume:  vol");
      if ( i == 16)
      {
      lcd.setCursor(1,1);
      lcd.print(" MIN VOLUME ");
      delay(10);
      }
    }
}

void checkIfDownButtonIsPressed(int newState)
{
  static int lastDownButtonState = 0;
 
  checkButton(down, lastDownButtonState, newState);
}

void checkIfUpButtonIsPressed(int newState)
{
  static int lastUpButtonState = 0;
 
  checkButton(up, lastUpButtonState, newState);
}

void checkButton(volatile boolean &output, int &oldState, int newState) {
  if (oldState != newState) {
    if (newState == 1) {
      output = true;
    }
    delay(50);
  }
  oldState = newState;
}

int digitalPotWrite(int value)
{
  digitalWrite(CS, LOW);
  SPI.transfer(address);
  SPI.transfer(value);
  digitalWrite(CS, HIGH);
}

Problem I am facing :
1st : Code show error of digitalPotWrite is not in the scope.
2nd: LCD just glow and doesn't show anything in LCD.

Please help, I am new here. Please enlighten me from your knowldge.
 

Offline HB9EVI

  • Frequent Contributor
  • **
  • Posts: 722
  • Country: ch
Re: Displaying Volume control on LCD using Digital potentiometer and Arduino
« Reply #1 on: September 23, 2018, 08:37:25 am »
If you declare a function, it has to be placed above the code, where the function is going to be used, otherwise it's - like it says - out of scope.

I don't know the arduino lcd functions so good, so far the code seems ok to me, but I can be wrong; except from a code problem, it could be wired in a wrong way
 
The following users thanked this post: radhika

Offline radhikaTopic starter

  • Regular Contributor
  • *
  • Posts: 105
  • Country: in
Re: Displaying Volume control on LCD using Digital potentiometer and Arduino
« Reply #2 on: September 23, 2018, 09:27:50 am »
You mean
int digitalPotWrite(int value)
{
  digitalWrite(CS, LOW);
  SPI.transfer(address);
  SPI.transfer(value);
  digitalWrite(CS, HIGH);
}
would be declare above the funtion usage?
 

Offline radhikaTopic starter

  • Regular Contributor
  • *
  • Posts: 105
  • Country: in
Re: Displaying Volume control on LCD using Digital potentiometer and Arduino
« Reply #3 on: September 23, 2018, 09:52:30 am »
If you declare a function, it has to be placed above the code, where the function is going to be used, otherwise it's - like it says - out of scope.

I don't know the arduino lcd functions so good, so far the code seems ok to me, but I can be wrong; except from a code problem, it could be wired in a wrong way

Hi, you are right. It solve my problem.
But, as according to code when I simulate it. It diplay something different on LCD. Can you help me what to improve in it? Please see the below picture.
https://postimg.cc/mcTZrMmJ
 

Offline sokoloff

  • Super Contributor
  • ***
  • Posts: 1799
  • Country: us
Re: Displaying Volume control on LCD using Digital potentiometer and Arduino
« Reply #4 on: September 23, 2018, 03:35:34 pm »
I'd be inclined to something like this (untested, of course):

In your first version, you got the digitalPotWrite was not in scope because you had unbalanced braces. You were missing a brace logically between line 93 and 94.
The Arduino environment is excessively lax (IMO) about allowing you to call functions before declaring or defining them. In my code below, I've tried to define functions before calling them, but you can get away without that in most cases in Arduino environment.

The LCD not displaying was a result of confusion around the for loops in the loop function. I don't know what the original intent of the for loop was around the up or down button handling. It just wasn't correct (nor is a loop needed there).

Code: [Select]
/*
MCP4018T103E connected to  arduino Board
  CS >>> D10
  SCLK >> D13
  DI  >>> D11
  PA0 TO VCC
  PBO TO GND
  PW0 TO led with resistor 100ohm .
*/
#include <SPI.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 9, 5, 4, 3, 2);  //RS = 12, E = 9,

byte address = 0x11;
const int CS= 10;
int g_volume = 0;

const int DOWN_BUTTON_PIN = 1;
const int UP_BUTTON_PIN = 0;

volatile boolean up = false;
volatile boolean down = false;

long time = 0;
long debounce = 200;


void updateLCDScreen(int volume) {
  lcd.clear();            // If you don't do this, the MIN/MAX volume will remain (like the OFF of the other program)
  lcd.setCursor(1,0);     //Column 1 and Row 0
  lcd.print("Volume: ");
  lcd.print(volume);
  if (volume == 128)
  {
    lcd.setCursor(1,1);
    lcd.print(" MAX VOLUME ");
  }
  if (volume == 16)             // What about 0 volume?
  {
    lcd.setCursor(1,1);
    lcd.print(" MIN VOLUME ");
  }
}

void digitalPotWrite(int value)
{
  digitalWrite(CS, LOW);
  SPI.transfer(address);
  SPI.transfer(value);
  digitalWrite(CS, HIGH);
}


void checkButton(volatile boolean &output, int &oldState, int newState) {
  if (oldState != newState) {
    if (newState == 1) {
      output = true;
    }
    delay(50);
  }
  oldState = newState;
}

void checkIfDownButtonIsPressed(int newState)
{
  static int lastDownButtonState = 0;
 
  checkButton(down, lastDownButtonState, newState);
}

void checkIfUpButtonIsPressed(int newState)
{
  static int lastUpButtonState = 0;
 
  checkButton(up, lastUpButtonState, newState);
}

void setup()
{
  lcd.clear();
  lcd.begin(16, 2);  //LCD have 16 column and 2 rows
  lcd.setCursor(1,0);  //LCD cursor set at 1st clomn and 0 rows
  pinMode(UP_BUTTON_PIN, INPUT_PULLUP);  //button
  pinMode(DOWN_BUTTON_PIN, INPUT_PULLUP);
 
  pinMode (CS, OUTPUT);
  SPI.begin();
  // adjust high and low resistance of potentiometer
  // adjust Highest Resistance .
   digitalPotWrite(0); //0
   delay(1000);
 
   // adjust  wiper in the  Mid point  .
   digitalPotWrite(64); //64
   delay(1000);

   // adjust Lowest Resistance .
   digitalPotWrite(128); //128
   delay(1000);
}

void loop()
{
  static int old_volume = -1;
 
  // Check the buttons. This code looks good (and familiar... ;) )
  checkIfDownButtonIsPressed(digitalRead(DOWN_BUTTON_PIN));
  checkIfUpButtonIsPressed(digitalRead(UP_BUTTON_PIN));

  // Now, handle the up/down buttons.
  if (up) {   //UP Button Logics
    up = false;
    g_volume += 16;
  }
  if (down) { //DOWN Button Logics
    down = false;
    g_volume -= 16;
  }
 
  // Range check the volume
  // This is a helpful function, though you could use two if statements as well
  g_volume = constrain(g_volume, 0, 128);
 
  // Only update the LCD and pot if the volume changed from previous time
  if (old_volume != g_volume)
  {
    updateLCDScreen(g_volume);
    digitalPotWrite(g_volume);
    old_volume = g_volume;
   
    // Slow the up/down menus a bit
    delay(1000);
  }
}
 
The following users thanked this post: radhika

Offline sokoloff

  • Super Contributor
  • ***
  • Posts: 1799
  • Country: us
Re: Displaying Volume control on LCD using Digital potentiometer and Arduino
« Reply #5 on: September 23, 2018, 03:41:48 pm »
Also, if you tell the LCD to display "Volume: vol" that's exactly what you'll get.
You need to tell it first to display the string "Volume: " and then a second call to display the value of the variable. (see lines 31 & 32 below):

Code: [Select]
  lcd.print("Volume: ");
  lcd.print(volume);

digitalWritePot didn't return any value originally, so vol was going to be set to some undefined value.
Go into your Arduino preferences and make sure that Compiler Warnings is set to "All"
Then get in the habit of understanding every red warning message that the compiler gives you.
At the "Default" setting for compiler warnings, you didn't get a warning on that function, which didn't help you at all. (Fixing just that wouldn't have been a complete fix, but it would have perhaps given you a clue that something was wrong there anyway.)
 
The following users thanked this post: radhika

Offline sokoloff

  • Super Contributor
  • ***
  • Posts: 1799
  • Country: us
Re: Displaying Volume control on LCD using Digital potentiometer and Arduino
« Reply #6 on: September 23, 2018, 03:46:07 pm »
I also have to admit a small amount of concern (and I don't mean to be the least bit disrespectful here) that if these are homework assignments, that I might be providing somewhat too much help.

If these are homework, please be sure to study carefully the differences between your code and mine (assuming mine works correctly) and figure out why they are different. If you don't understand, come back here and ask, don't just submit the answer and get a good mark on the homework.

Related, if you'd prefer that I (and other EEVBlog posters) take more time and lead you to the answer rather than posting working code, I can also do that. That might be frustrating in terms of timezone and limited availability at times.

While your immediate goal is probably to submit working homework, I (and you) should be much more focused on you learning how to debug and fix the inevitable errors in code that every programmer makes. I don't want to short-circuit that (pun intended).
 
The following users thanked this post: radhika

Offline radhikaTopic starter

  • Regular Contributor
  • *
  • Posts: 105
  • Country: in
Re: Displaying Volume control on LCD using Digital potentiometer and Arduino
« Reply #7 on: September 23, 2018, 04:54:26 pm »
Hi, Thanks for reply:) I am so much grateful
According to this code
void updateLCDScreen(int volume) {
  lcd.clear();            // If you don't do this, the MIN/MAX volume will remain (like the OFF of the other program)
  lcd.setCursor(1,0);     //Column 1 and Row 0
  lcd.print("Volume: ");
  lcd.print(volume);
  if (volume == 128)
  {
    lcd.setCursor(1,1);
    lcd.print(" MAX VOLUME ");
  }
where is written that volume varry from 0 to 128. Isn't we missing that for loop where it increase the volume and reach to 128. Is this g_volume = constrain(g_volume, 0, 128);  doing the same function and if yes, then where it declare it is use for g_volume.

Please guide me to the right track.

haaha.. and yes the code seems similar to you because you once answered my question on menuitem and this logic of button works so well. Thank you so much for this :)
 

Offline radhikaTopic starter

  • Regular Contributor
  • *
  • Posts: 105
  • Country: in
Re: Displaying Volume control on LCD using Digital potentiometer and Arduino
« Reply #8 on: September 23, 2018, 04:56:53 pm »

Go into your Arduino preferences and make sure that Compiler Warnings is set to "All"


Done :) Thanks :)
 

Offline radhikaTopic starter

  • Regular Contributor
  • *
  • Posts: 105
  • Country: in
Re: Displaying Volume control on LCD using Digital potentiometer and Arduino
« Reply #9 on: September 23, 2018, 05:04:16 pm »
I also have to admit a small amount of concern (and I don't mean to be the least bit disrespectful here) that if these are homework assignments, that I might be providing somewhat too much help.

If these are homework, please be sure to study carefully the differences between your code and mine (assuming mine works correctly) and figure out why they are different. If you don't understand, come back here and ask, don't just submit the answer and get a good mark on the homework.

Related, if you'd prefer that I (and other EEVBlog posters) take more time and lead you to the answer rather than posting working code, I can also do that. That might be frustrating in terms of timezone and limited availability at times.

While your immediate goal is probably to submit working homework, I (and you) should be much more focused on you learning how to debug and fix the inevitable errors in code that every programmer makes. I don't want to short-circuit that (pun intended).

Thank you so much for allowing me to ask the differenced of normal coding and your professional one:)
Yes, It's not homework or college assignment. It's my own project on which I am working from the last 6-7 months. I done my code for PIC microcontroller. But, before going to PIC I am using Arduino to check my circuit. I learnt Arduino and tried to code but I am still not reaching to good coder :palm:
Can you suggest me some good material where I learn from and I wanna code like you, So fast, short and accurate without even compiling :) 
 

Offline radhikaTopic starter

  • Regular Contributor
  • *
  • Posts: 105
  • Country: in
Re: Displaying Volume control on LCD using Digital potentiometer and Arduino
« Reply #10 on: September 23, 2018, 05:33:07 pm »
Why it's not displaying anything :(
https://postimg.cc/yJX2dsBn
 

Offline sokoloff

  • Super Contributor
  • ***
  • Posts: 1799
  • Country: us
Re: Displaying Volume control on LCD using Digital potentiometer and Arduino
« Reply #11 on: September 23, 2018, 06:00:09 pm »
Is this g_volume = constrain(g_volume, 0, 128);  doing the same function and if yes, then where it declare it is use for g_volume.

Please guide me to the right track.
Yes. constrain is an Arduino library function.

Doc is here: https://www.arduino.cc/reference/en/language/functions/math/constrain/
 

Offline sokoloff

  • Super Contributor
  • ***
  • Posts: 1799
  • Country: us
Re: Displaying Volume control on LCD using Digital potentiometer and Arduino
« Reply #12 on: September 23, 2018, 06:03:54 pm »
Why it's not displaying anything :(
https://postimg.cc/yJX2dsBn
I'd add something in setup then to just test that the simulator and wiring is all correct.

Perhaps change the LCD setup code to something like this:

Code: [Select]
  lcd.clear();
  lcd.begin(16, 2);  //LCD have 16 column and 2 rows
  lcd.setCursor(1,0);  //LCD cursor set at 1st clomn and 0 rows
  lcd.print("Testing");
  lcd.setCursor(1,1);
  lcd.print("1..2..3..");
  delay(10000);
 

Offline sokoloff

  • Super Contributor
  • ***
  • Posts: 1799
  • Country: us
Re: Displaying Volume control on LCD using Digital potentiometer and Arduino
« Reply #13 on: September 23, 2018, 06:09:20 pm »
I am using Arduino to check my circuit. I learnt Arduino and tried to code but I am still not reaching to good coder :palm:
Can you suggest me some good material where I learn from and I wanna code like you, So fast, short and accurate without even compiling :)
Well, I do compile it; I just can't test or simulate your peripherals, so that I have to just reason about and try to write correct code.

How to get better at coding?
Do a lot of it. Struggle through the difficulties. Really work at it, then when you're stuck, ask for help.

Read other people's code. Find some open source projects, look at the outcome, think about how they probably did things, then read the code and see if you can figure it all out. Lots of open source software is low quality (like lots of closed source software), but some of it is excellent quality.

Read some books. I love Steve McConnell's Code Complete and Steve Macguire's Writing Solid Code. I don't know that reading those books is the first thing I'd recommend though; I tend to learn more by doing and struggling personally, then once I have a reasonably good background, then read the books.

But mostly, it's do a lot of it...
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf