Arduino controlled Digital Potentiometer

#9

I think what is confusing me is that the wiper pin isnt even mentioned in the setup or anything of the original code and that it just works being randomly called “i” in the loop. also, there is a random “working” variable? byte? that, if it has a value greater than 127 then stuff happens and I’m just like “AHHHHHH how am i meant to know what it’s set at??? its not been declared before, whats the script???” and then theres another where for some reason a byte is shifted to the left and i cant find a comment saying why

0 Likes

#10

dude you are such a legend i cannot thank you enough for all your help. reading your stuff now and it seems so simple xD

1 Like

#11

One of the problems with this approach is that the loop method runs over and over as quickly as it can. You won’t be able to press a button and release it quickly enough to only register once. The loop will run LOTS of times in the fraction of a second you have either button pressed.

A simple way to work around this is to delay for a while whenever you detect that a button has been pressed. After you update the resistance value with the spi_out method, you could add these lines of code:

if (inc || dec) {
    delay(500);
}

That’ll give you to half a second to release the button before it registers again. Holding it down will increase or decrease the resistance by 10 every half a second. Something like holding down a key on the keyboard… :slight_smile:

1 Like

#12

awesome, thanks again, this is very informative!
let’s say thew wiper is at position 250, adding 10 would bring it to 260. In my mind i see this like an analogue clock, where the actual value would be 260-255=5, could i then make it jump from position 250 to position 5 with one increase push? i think that would be cool as i’m hoping to use this to control the input Power of a primary coil of a slayer exciter circuit (once i figure out how to make a 5v one) and it would be cool to see it jump from low power to high power and from high to low like that lol

0 Likes

#13

That’s a simple change. The code I wrote will “cap” the resistance at the top/bottom of the range of values.

if (resistance > 255) {
    resistance = 255;
}
if (resistance < 0) {
    resistance = 0;
}

To have it “wrap around”, you’d use this instead:

if (resistance > 255) {
    resistance = resistance - 255;
}
if (resistance < 0) {
    resistance = resistance + 255;
}

Simple! :smiley:

1 Like

#14

thanks!

right so now, Im getting an error saying " ‘pbInc’ was not declared in this scope " and i’m assuming it will say the same thing for pbDec

0 Likes

#15

Could you post your entire source code?

Please use the “</>” button to format it as code.

1 Like

#16

sure, I will in a sec as i think i was brain-farting.
i didnt add in the #include “Button” etc… lol

0 Likes

#17

<#include <SPI.h>

#include <Button.h>

#define PUSHBUTTON_PIN_7
#define PUSHBUTTON_PIN_8

Button Rup(PUSHBUTTON_PIN_8)
Button Rdn(PUSHBUTTON_PIN_7)

void setup() {
Rup.init();
}

void setup() {
Rdn.init();
}

int CS_signal = 2; // Chip Select signal onsul pin 2 of Arduino
int CLK_signal = 4; // Clock signal on pin 4 of Arduino
int MOSI_signal = 5; // MOSI signal on pin 5 of Arduino
byte cmd_byte2 = B00010001 ; // Command byte
int Ri = 100; // Setting up the initial value

Button Rup = 8; // pin 8 (red button) will increase resistance
Button Rdn = 7; // pin 7 (blue button) will decrease resistance

void initialize() { // send the command byte of value 100 (initial value)
spi_out(CS_signal, cmd_byte2, Ri);
}

void spi_out(int CS, byte cmd_byte, byte data_byte){ // we need this function to send command byte and data byte to the chip

digitalWrite (CS, LOW);                                                 // to start the transmission, the chip select must be low
spi_transfer(cmd_byte); // invio il COMMAND BYTE
delay(2);
spi_transfer(data_byte); // invio il DATA BYTE
delay(2);
digitalWrite(CS, HIGH);                                                 // to stop the transmission, the chip select must be high

}

void spi_transfer(byte working) {
for(int i = 1; i <= 8; i++) { // Set up a loop of 8 iterations (8 bits in a byte)
if (working > 127) {
digitalWrite (MOSI_signal,HIGH) ; // If the MSB is a 1 then set MOSI high
} else {
digitalWrite (MOSI_signal, LOW) ; } // If the MSB is a 0 then set MOSI low

digitalWrite (CLK_signal,HIGH) ;                                        // Pulse the CLK_signal high
working = working << 1 ;                                                // Bit-shift the working byte
digitalWrite(CLK_signal,LOW) ;                                          // Pulse the CLK_signal low
}

}

void setup() {
pinMode (CS_signal, OUTPUT);
pinMode (CLK_signal, OUTPUT);
pinMode (MOSI_signal, OUTPUT);

initialize();

Serial.begin(9600);                                                     // setting the serial speed
Serial.println("ready!");

}

void loop() {

bool Rup = pushButton.read();
bool Rdn = pushButton.read();

if (Rup) {
  Ri += 10;
}

if (Rdn) {
  Ri -= 10;
}

if (Ri > 255) {
  Ri = Ri - 255;
}

if (Ri < 255) {
  Ri = Ri + 255;
}
}
0 Likes

#18

ok i have probably tried to change too many things now

i tried #define “button” but it said that doesn’t exist

what i’m noticing from the “button” example code, is that i havent told it to read for the button? i’m not sure sorry i got kinda lost lol

0 Likes

#19

No worries, I’ve got the code and I’m going to list the issues and then the complete corrected code (I hope)…

1 Like

#20

OK, formatted correctly, that’s the following:

<#include <SPI.h>

#include <Button.h>

#define PUSHBUTTON_PIN_7
#define PUSHBUTTON_PIN_8

Button Rup(PUSHBUTTON_PIN_8)
Button Rdn(PUSHBUTTON_PIN_7)

void setup() {
Rup.init();
}

void setup() {
Rdn.init();
}

int CS_signal = 2; // Chip Select signal onsul pin 2 of Arduino
int CLK_signal = 4; // Clock signal on pin 4 of Arduino
int MOSI_signal = 5; // MOSI signal on pin 5 of Arduino
byte cmd_byte2 = B00010001 ; // Command byte
int Ri = 100; // Setting up the initial value

Button Rup = 8; // pin 8 (red button) will increase resistance
Button Rdn = 7; // pin 7 (blue button) will decrease resistance

void initialize() { // send the command byte of value 100 (initial value)
spi_out(CS_signal, cmd_byte2, Ri);
}

void spi_out(int CS, byte cmd_byte, byte data_byte){ // we need this function to send command byte and data byte to the chip

digitalWrite (CS, LOW);                                                 // to start the transmission, the chip select must be low
spi_transfer(cmd_byte); // invio il COMMAND BYTE
delay(2);
spi_transfer(data_byte); // invio il DATA BYTE
delay(2);
digitalWrite(CS, HIGH);                                                 // to stop the transmission, the chip select must be high
}

void spi_transfer(byte working) {
for(int i = 1; i <= 8; i++) { // Set up a loop of 8 iterations (8 bits in a byte)
if (working > 127) {
digitalWrite (MOSI_signal,HIGH) ; // If the MSB is a 1 then set MOSI high
} else {
digitalWrite (MOSI_signal, LOW) ; } // If the MSB is a 0 then set MOSI low

digitalWrite (CLK_signal,HIGH) ;                                        // Pulse the CLK_signal high
working = working << 1 ;                                                // Bit-shift the working byte
digitalWrite(CLK_signal,LOW) ;                                          // Pulse the CLK_signal low
}
}

void setup() {
pinMode (CS_signal, OUTPUT);
pinMode (CLK_signal, OUTPUT);
pinMode (MOSI_signal, OUTPUT);

initialize();

Serial.begin(9600);                                                     // setting the serial speed
Serial.println("ready!");
}

void loop() {

bool Rup = pushButton.read();
bool Rdn = pushButton.read();

if (Rup) {
Ri += 10;
}

if (Rdn) {
Ri -= 10;
}

if (Ri > 255) {
Ri = Ri - 255;
}

if (Ri < 255) {
Ri = Ri + 255;
}
}

Now to the problems:

  1. Line 1 should not start with the less than symbol.
  2. #define can’t have no value so #define PUSHBUTTON_PIN_7 should be #define PUSHBUTTON_PIN_7 7
  3. You have three setup methods. You can only have one.
  4. You seem to have gotten confused by defining rup and rdn twice. I’ve rearranged all variable declarations at the top
  5. You names your buttons the same as the result of reading the button.
  6. You didn’t update the potentiometer in the loop.
  7. You didn’t add the delay after updating the pot (to avoid it spinning wildly whilst pressing the button)

The edited version follows (note that I’ve not tested the code or even tried to compile it - there’s more than likely still an issue in there somewhere!)

#include <SPI.h>
#include <Button.h>

#define PUSHBUTTON_PIN_7 7
#define PUSHBUTTON_PIN_8 8

int CS_signal = 2; // Chip Select signal onsul pin 2 of Arduino
int CLK_signal = 4; // Clock signal on pin 4 of Arduino
int MOSI_signal = 5; // MOSI signal on pin 5 of Arduino
byte cmd_byte2 = B00010001 ; // Command byte
int Ri = 100; // Setting up the initial value

Button btnRup(PUSHBUTTON_PIN_8); // pin 8 (red button) will increase resistance
Button btnRdn(PUSHBUTTON_PIN_7); // pin 7 (blue button) will decrease resistance

void setup() {
    pinMode (CS_signal, OUTPUT);
    pinMode (CLK_signal, OUTPUT);
    pinMode (MOSI_signal, OUTPUT);

    btnRup.init();
    btnRdn.init();
    initialize();

    Serial.begin(9600);                                                     // setting the serial speed
    Serial.println("ready!");
}

void initialize() {
     // send the command byte of value 100 (initial value)
    spi_out(CS_signal, cmd_byte2, Ri);
}

void spi_out(int CS, byte cmd_byte, byte data_byte){ // we need this function to send command byte and data byte to the chip
    digitalWrite (CS, LOW);                                                 // to start the transmission, the chip select must be low
    spi_transfer(cmd_byte); // invio il COMMAND BYTE
    delay(2);
    spi_transfer(data_byte); // invio il DATA BYTE
    delay(2);
    digitalWrite(CS, HIGH);                                                 // to stop the transmission, the chip select must be high
}

void spi_transfer(byte working) {
    for(int i = 1; i <= 8; i++) { // Set up a loop of 8 iterations (8 bits in a byte)
        if (working > 127) {
            digitalWrite (MOSI_signal,HIGH) ; // If the MSB is a 1 then set MOSI high
        } else {
            digitalWrite (MOSI_signal, LOW) ;
        } // If the MSB is a 0 then set MOSI low

        digitalWrite (CLK_signal,HIGH) ;                                        // Pulse the CLK_signal high
        working = working << 1 ;                                                // Bit-shift the working byte
        digitalWrite(CLK_signal,LOW) ;                                          // Pulse the CLK_signal low
    }
}


void loop() {
    bool Rup = btnRup.read();
    bool Rdn = btnRdn.read();

    if (Rup) {
        Ri += 10;
    }

    if (Rdn) {
        Ri -= 10;
    }

    if (Ri > 255) {
        Ri = Ri - 255;
    }

    if (Ri < 255) {
        Ri = Ri + 255;
    }

    spi_out(CS_signal, cmd_byte2, Ri);

    if (inc || dec) {
        delay(500);
    }
}
1 Like

#21

Would be great to know if it worked. :slight_smile:

1 Like

#22

sorry unfortunately I had reached my “13 replies max on first day” or something so have been unable to respond until now

unfortunately it didn’t work, it says the #include <button.h> doesn’t exist lol

0 Likes

#23

That’s a common problem caused by copying the code from the site rather than using the button to download the ZIP file that has all the additional required files. Once you’ve got the ZIP, extract all the files to the folder where your current .ino file is and that should resolve it.

I’ve downloaded the required files and opened the code in Arduino IDE to check that it compiles and I had to fix two things so here’s the complete code that at least compiles:

#include <SPI.h>
#include "Button.h"

#define PUSHBUTTON_PIN_7 7
#define PUSHBUTTON_PIN_8 8

int CS_signal = 2; // Chip Select signal onsul pin 2 of Arduino
int CLK_signal = 4; // Clock signal on pin 4 of Arduino
int MOSI_signal = 5; // MOSI signal on pin 5 of Arduino
byte cmd_byte2 = B00010001 ; // Command byte
int Ri = 100; // Setting up the initial value

Button btnRup(PUSHBUTTON_PIN_8); // pin 8 (red button) will increase resistance
Button btnRdn(PUSHBUTTON_PIN_7); // pin 7 (blue button) will decrease resistance

void setup() {
    pinMode (CS_signal, OUTPUT);
    pinMode (CLK_signal, OUTPUT);
    pinMode (MOSI_signal, OUTPUT);

    btnRup.init();
    btnRdn.init();
    initialize();

    Serial.begin(9600);                                                     // setting the serial speed
    Serial.println("ready!");
}

void initialize() {
        // send the command byte of value 100 (initial value)
    spi_out(CS_signal, cmd_byte2, Ri);
}

void spi_out(int CS, byte cmd_byte, byte data_byte){ // we need this function to send command byte and data byte to the chip
    digitalWrite (CS, LOW);                                                 // to start the transmission, the chip select must be low
    spi_transfer(cmd_byte); // invio il COMMAND BYTE
    delay(2);
    spi_transfer(data_byte); // invio il DATA BYTE
    delay(2);
    digitalWrite(CS, HIGH);                                                 // to stop the transmission, the chip select must be high
}

void spi_transfer(byte working) {
    for(int i = 1; i <= 8; i++) { // Set up a loop of 8 iterations (8 bits in a byte)
        if (working > 127) {
            digitalWrite (MOSI_signal,HIGH) ; // If the MSB is a 1 then set MOSI high
        } else {
            digitalWrite (MOSI_signal, LOW) ;
        } // If the MSB is a 0 then set MOSI low

        digitalWrite (CLK_signal,HIGH) ;                                        // Pulse the CLK_signal high
        working = working << 1 ;                                                // Bit-shift the working byte
        digitalWrite(CLK_signal,LOW) ;                                          // Pulse the CLK_signal low
    }
}


void loop() {
    bool Rup = btnRup.read();
    bool Rdn = btnRdn.read();

    if (Rup) {
        Ri += 10;
    }

    if (Rdn) {
        Ri -= 10;
    }

    if (Ri > 255) {
        Ri = Ri - 255;
    }

    if (Ri < 255) {
        Ri = Ri + 255;
    }

    spi_out(CS_signal, cmd_byte2, Ri);

    if (Rup || Rdn) {
        delay(500);
    }
}
1 Like

#24

apparantly “button” does not name a type…for button 7… after 3 other times “button” has been mentioned/

sorry i seem to be having issues as i got the same error message for trying to respond earlier, apparantly i’m talking too much so I’m gonna try and put all problems and questions in 1 post incase i cant respond for a few hours again.

  1. where do i find these files? am i likey to need more? what was the clue i missed that would have implied i need to do that?

2)does the command byte always have to be B00010001 ? why B17? does it not matter?

  1. #define PUSHBUTTON_PIN_7 7” does it have to be written like that? i didnt find that in the library. am i looking in the wrong place?

  2. am i right in guessing that one of the changes was that there were multiple setup loops? i vaguely remember something about only being able to have 1 setup loop, if there is a limit on the number of set up loops, is there a limit to how big the setup loop can be?

  3. What’s “working”, why does it get bithsifted?

  4. how do you troubleshoot? is it just from aquired knowledge or do you maybe also use resources i havent found that can translate what the code says into what the code means? or the error messages etc?

  5. what would you say is the most efficient way for me to get better at programming arduino? is it really just a case of “read the examples and guess” or are there like actual tutorials available to give you a better understanding of arduino and programming?

thanks man!

1 Like

#25

also, how come neither the digipot control code nor the LED button example codes require the #include <SPI.h> or the #include “button.h”?

0 Likes

#26

Sorry for the delay, I went for a walk along the sea front after dinner with my family.

I can see how that might be confusing. The first mention of button in the #include "Button.h" tells the compiler to include the contents of the file named Button.h which is a header file that defines the things available in Button.cpp. You include this file so that you can define a Button class and invoke methods like read() on instances of the button.

The #define PUSHBUTTON_PIN_7 7 tells the compiler to define a label called PUSHBUTTON_PIN_7 and assign it the value 7. I would personally have named it something like RUP_BTN_PIN so that the pin number could change without changing the label. It’s common to given constants all caps names to make it clear that they can’t be changed in the code later.

The Button btnRup(PUSHBUTTON_PIN_7) line declares an instance of a Button class and names it btnRup.

So yeah, lots of mentions of “button” eh. :slight_smile:

You get the files from the Code tab of Circuito if you download the ZIP file. Here’s a screenshot:

This I don’t know. I assumed this was something to do with the digital potentiometer code you have.

As I mentioned above, it’s not the style I’d use. I might even have been lazy enough to skip the define statements and just specified the pin number in the button declaration like this:

Button btnRup(8);
Button btnRdn(7);

The parameter working is passed to the method to do the SPI communications. If you want to read more about bit shifting, this is a good Stack Overflow answer: https://stackoverflow.com/a/141873/39722

It’s a mixture of both. With experience you acquire knowledge of what things mean and you know (or assume) to work. You then focus on what you don’t know for certain. An approach that has worked well for me is to reduce complexity and remove “links” in the “chain”. So in this case I’d comment the code related to the potentiometer (“pot”) and just serial print the Ri value whenever a button is pressed. That way you can determine that the buttons are working. Then you move onto the next thing - controlling the pot. Even the biggest systems are made up of small programs.

There are a lot of different learning styles. You may know what works for you, or you may need to find out. Some people like to learn from books, others prefer a real life tutor who they can ask questions of, and others prefer videos or online courses. I’ve watched probably over 100 hours of YouTube videos to learn more about Arduino (and other controllers like the MSP430, ESP8266, ESP32) and I guess it helps that I’ve been programming since 1984 - you know, when we all had dinosaurs as pets. :joy:

SPI is a communication protocol. I assume the digipot needs it. You could comment the line and see what fails - one way to see for certain what needs it. hehe

Good luck and don’t give up. I know it can be frustrating at times, but the joy of getting your creation to [finally] work is priceless. :robot:

1 Like

#27

Oops, I just noticed I didn’t answer your question about the setup and loop functions. You can only have one of each, but their size is only limited by the memory available in the Arduino.

1 Like

#28

dude this is amazing. honestly man, thank you so much for taking the time to help a random dum-dum online like this!

I’m gonna get to work on this now, will let you know how i get on.

1 Like