Go Down

Topic: Adjusting delay with potentiometer (Read 5921 times) previous topic - next topic

Pedro147

Jan 10, 2015, 10:34 am Last Edit: Jan 14, 2015, 07:34 am by Pedro147
I have a circuit and some code that I am working on. It is a 7Seg controlled by a 74HC595 with two push buttons to increment/decrement the displayed numbers. I have incorporated a potentiometer to adjust the delay period in the shiftIt function to allow the multiplexing action to be observed. By using the map function I am varying the delay from 1 to 100 ms, but the problem is that the delay is either all on or all off so to speak. So at one end of pot travel the minimal delay is showing a solid digit as expected but to get good resolution of the delay time is very difficult. After approx 5 degrees of rotation the delay is at its maximum. I assume that this may possibly be  a result of the uneven distribution from integer math nature of the map function. Is there any way that I can make the pot more responsive to the upper and lower delay values that I have picked rather than the min and max values being executed in the first 5 degrees of travel. Thanks.

Code: [Select]
 //  7-Segment LED counter, multiplexing using 74HC595 8-bit shift register, increment counter zero to eight
  //  to zero via push button switches
  //  pot connected to A0 varies the  delay in function shiftIt
  //  Code mangled together from these sources, thanks fellas
  //  http://thecustomgeek.com/2011/06/29/multiplexing-for-a-7-year-old/
  //  http://nootropicdesign.com/projectlab/2009/10/25/led-clock/
  //  original tutorial link for 7Seg display functions dead; author at
  //  https://www.flickr.com/people/markymoo/
  
  byte latchPin = 5;  // Pin connected to Pin 12 of 74HC595 (Latch)
  byte dataPin  = 6;  // Pin connected to Pin 14 of 74HC595 (Data)
  byte clockPin = 7;  // Pin connected to Pin 11 of 74HC595 (Clock)
  byte upPin = 12;      // pushbutton attached to pin 12
  byte downPin = 13;      // pushbutton attached to pin 13
  byte currUpState = 1;   // initialise currUpState as HIGH
  byte currDownState = 1;   // initialise currDownState as HIGH
  byte prevUpState = 0;
  byte prevDownState = 0;
  byte counter = 0;          // initialise counter as zero
  byte i = 0;
  byte potReading = 0;
  byte numbers[10] =  // Describe each digit in terms of display segments  0, 1, 2, 3, 4, 5, 6, 7, 8, 9
  {
    B11111100,  // Displays 0
    B01100000,  // Displays 1
    B11011010,  // Displays 2
    B11110010,  // Displays 3
    B01100110,  // Displays 4
    B10110110,  // Displays 5
    B10111110,  // Displays 6
    B11100000,  // Displays 7
    B11111110,  // Displays 8
    B11100110,  // Displays 9 - currently not used
  };
  void setup()
  {
   //Serial.begin(9600);
    pinMode(latchPin, OUTPUT);   // set SR pins to output
    pinMode(clockPin, OUTPUT);
    pinMode(dataPin, OUTPUT);
    pinMode(upPin, INPUT);   // sets pin 12 as pushbutton INPUT
    pinMode(downPin, INPUT);   // sets pin 13 as pushbutton INPUT
  }
  void loop()
  {
    currUpState = digitalRead(upPin);
    if (prevUpState != currUpState)             // has the state changed from
    {                                           // HIGH to LOW or vice versa
      prevUpState = currUpState;
      if (currUpState == HIGH)                  // If the button was pressed
        counter++;          // increment the counter by one
  
    }
    if(counter > 8)
      counter-=1;
    show(numbers[counter]); // display the current digit
    currDownState = digitalRead(downPin);
    if (prevDownState != currDownState)         // has the state changed from
    {                                           // HIGH to LOW or vice versa
      prevDownState = currDownState;
      if (currDownState == HIGH)                // If the button was pressed
        counter-=1;                             // decrement the counter by one
  
    }
    if(counter < 0)
      counter++;
    
      
    show(numbers[counter]); // display the current digit
  }
  void show( byte number)
  {
    // Use a loop and a bitwise AND to move over each bit that makes up
    // the seven segment display (from left to right, A => G), and check
    // to see if it should be on or not
    for(byte j = 0; j <= 7; j++)
    {
      byte toWrite = number & (B10000000 >> j);
      if(!toWrite) {
        continue;
      }                 // If all bits are 0 then no point writing it to the shift register,so break out and
      //move on to next segment.
      shiftIt(toWrite); // Otherwise shift it into the register
    }
  }
 void shiftIt (byte data)
{
  digitalWrite(latchPin, LOW);      // Set latchPin LOW while clocking these 8 bits in to the register
  for (byte k=0; k <= 7; k++)
  {
    digitalWrite(clockPin, LOW);    // clockPin LOW prior to sending a bit
    if ( data & (1 << k) )
    {
      digitalWrite(dataPin, HIGH); // turn "On"
    }
    else
    {
      digitalWrite(dataPin, LOW); // turn "Off"
    }
    digitalWrite(clockPin, HIGH); // and clock the bit in
  }
  digitalWrite(clockPin, LOW);   //stop shifting out data
  digitalWrite(latchPin, HIGH);  //set latchPin to high to lock and send data
  {
    potReading = analogRead (A0);
    {
      potReading = map(potReading, 0, 1023, 1, 100);
      {
        if(potReading > 1)
          potReading --;
        delay(potReading);
      }
      {
        if(potReading < 100)
          potReading ++;
        delay(potReading);
        //Serial.println(potReading);
      }
    }
  }
}


http://www.pedroduino.com

Riva

What is the potReading ++ and potReading -- in the code for?

You define potReading as a byte but it should be an int as result is 10 bit value.

Is the potentiometer linear or log type?

Code: [Select]
   int potReading = analogRead (A0);
   potReading = map(potReading, 0, 1023, 1, 100);
   delay(potReading);


 
Don't PM me for help as I will ignore it.

Pedro147

What is the potReading ++ and potReading -- in the code for?

You define potReading as a byte but it should be an int as result is 10 bit value.
Two very good questions  8)  They are gone and byte changed to int. Problem is still apparent but thanks for pulling me up on these mistakes.

The pot is linear. I have tried expanding the range of the map values for delay to no avail.
http://www.pedroduino.com

Riva

Two very good questions  8)  They are gone and byte changed to int. Problem is still apparent but thanks for pulling me up on these mistakes.

The pot is linear. I have tried expanding the range of the map values for delay to no avail.
Try just connecting the pot to A0 and continually printing it value to the serial monitor while adjusting the wiper between ends and see what values you get for each end and if the values change smoothly while slowly wiping. Maybe you have a bad pot/connection/wiring.
Don't PM me for help as I will ignore it.

Pedro147

I tried two pots and they are both very erratic. I will buy a better one tomorrow and try that. Thanks for your help Riva.
http://www.pedroduino.com

PaulRB

Hi Pedro, what value are those pots? 10K is ideal. 4K7, 1K, 47K or 100K is ok. But 470K, 1M or 10M would be too high and might not give reliable readings.

Paul

Pedro147

#6
Jan 11, 2015, 12:29 am Last Edit: Jan 11, 2015, 08:39 am by Pedro147 Reason: additional information
Hi Paul. The first one was  a 50K B (Linear) at least I learned about pot marking codes. The second is a 10K linear which is much better although for some reason it does seem to give me two positions of minimal delay (solid digit display) One at one end of pot rotation and another at half pot rotation. This being said it is giving me much better control of the delay period. Thanks for your suggestions.

Rudimentary Video
http://www.pedroduino.com

PaulRB

You could replace this code

Code: [Select]


  for (byte k=0; k <= 7; k++)
  {
    digitalWrite(clockPin, LOW);    // clockPin LOW prior to sending a bit
    if ( data & (1 << k) )
    {
      digitalWrite(dataPin, HIGH); // turn "On"
    }
    else
    {
      digitalWrite(dataPin, LOW); // turn "Off"�
    }
    digitalWrite(clockPin, HIGH); // and clock the bit in
  }
  digitalWrite(clockPin, LOW);   //stop shifting out data



with a single shiftOut().

It will be interesting to know if your new pot fixes the problem. I have a feeling it won't...

Pedro147

#8
Jan 11, 2015, 11:31 am Last Edit: Jan 11, 2015, 11:32 am by Pedro147
You could replace this code
with a single shiftOut().
How would I incorporate this into the rest of the existing code please Paul :D
http://www.pedroduino.com

PaulRB

You would replace exactly all that code I quoted with this line:

Code: [Select]
shiftOut(dataPin, clockPin, MSBFIRST, data);

It won't fix your pot problem in any way, just make your sketch shorter!

PaulRB

Quote
for some reason it does seem to give me two positions of minimal delay

Did you change that byte to an int as Riva pointed out?

Pedro147

#11
Jan 11, 2015, 10:20 pm Last Edit: Jan 11, 2015, 10:22 pm by Pedro147
You would replace exactly all that code I quoted with this line:

Code: [Select]
shiftOut(dataPin, clockPin, MSBFIRST, data);

I tried that giving this

Code: [Select]
void shiftIt (byte data)
{
  digitalWrite(latchPin, LOW);      // Set latchPin LOW while clocking these 8 bits in to the register
 shiftOut(dataPin, clockPin, MSBFIRST, data);
  digitalWrite(latchPin, HIGH);  //set latchPin to high to lock and send data
  {
    potReading = analogRead (A0);
    {
      potReading = map(potReading, 0, 1023, 1, 100);
      {
        if(potReading > 1)
          potReading --;
        delay(potReading);
      }
      {
        if(potReading < 100)
          potReading ++;
        delay(potReading);
        //Serial.println(potReading);
      }
    }
  }
}



but it does not display the digits correctly (see image for display of "zero") I think that it possibly has something to do with this line

Code: [Select]
if ( data & (1 << k) )
and I did change the numbers array to datatype int
http://www.pedroduino.com

PaulRB

#12
Jan 12, 2015, 12:32 am Last Edit: Jan 12, 2015, 12:44 am by PaulRB
Quote
it does not display the digits correctly (see image for display of "zero") I think that it possibly has something to do with this line

My bad. I should have said "LSBFIRST" not "MSBFIRST". Sorry!
Quote
I did change the numbers array to datatype int

That's not what Riva said. You should go back and read Riva's post again, because the things you said you removed have reappeared, and you changed the wrong variable from byte to int.

Pedro147

Thanks Paul that works perfectly now. A case of me reading but not seeing and consequently trying to fit all of a households possessions into a tiny garden shed  8)

Riva - thanks for picking up my killer mistake so early
http://www.pedroduino.com

Riva

Glad you got it sorted in the end Pedro.
Don't PM me for help as I will ignore it.

Go Up