Multiple values from a single POT

I have a programming feasibility question regarding a potential project.

The project would be a relay sequencer that can be configured without adjusting and re uploading the sketch. One input to start the sequence and relays triggered individually after a set time.

My first thought was to have a pot mapped to 10 seconds and use this value to determine the delay for the output pin but this would mean one pot per output pin. So my question is would it be feasible to somehow select an output pin, record the pot value and assign it and then move on to another output pin assign a different value from the pot and so on?

I am a complete novice with programming so please forgive the lack of specifics, I'm just trying to see if its achievable before I start with the blood, sweat and tears

If I understand, the single pot adjusts the delay period to determine the delays between each relay triggering.

If you want different delays for each output, how do you know which relay you are adjusting ?

It's feasible.
You could use one push button to select the output pin and another as a"store the value" button.
You will need some kind of display to show which output pin is selected.

use a rotary encoder (KY-040 style) and the encoder library. They also embed a push button (use the Toggle Button library from @dlloyd) so that you could use that to signal you want to go to the next pin

are you suggesting that the pot value be recorded when a button is pressed and that multiple values are stored in an array which is used later, possibly after a 2nd button is pressed?

How will you know where the pot is set (1 to 10)?

Sure, that's that's possible - but very cumbersome for the user!

You could combine that onto just one button to do "store & select next".

Re-inventing the terrible UI of early VCRs ... :scream:

3 Likes

Thanks for all the input guys,

I'll explain the project a little further in an ideal world I'd have an lcd display with a few buttons (output select, store, value select and value up & down) where the user could define the starting position of the relay (open or closed) straight high or low activation or pulse with an adjustable duration and then a delay from initial start input.

However my idea is vastly ahead of my coding so I dumbed it down as much as I could (hence the pots) so I had a fighting chance of getting it to work.

I guess the road block for me was looking at the coding and not seeing a way in which the code wouldn't just see the current pot value and apply that.

So from what everyone is saying it is possible to adjust and store values inside a sketch from a combination of buttons, lcd, pots or whatever?

Absolutely!

That's pretty much what all code boils down to: reading some inputs; doing some stuff with the values read; setting some outputs correspondingly.

1 Like

Don't try to do anything tricky like one button does everything, it will just make the code more complicated.

2 Likes

Just read a section on variables but its still little over my head,

Out of interest is there a sort of paid coding service or advice available on here?

1 Like

sure here is an example (10 minute work) leveraging existing libraries

everything is hard coded and sequential, so this is just a proof of concept but then the sky is the limit

1 Like

I mean wow, yeah exactly the sort of thing.

How accurate can an Arduino go? if the delay was down to a hundredth of a second?

As always. I was hoping to find a French idiom to match, only got a literal translation. :frowning:

a7

1 Like

yeah if you code correctly you can easily go below the 10th of millisecond. of course you would not handle the loop as I did

(added LEDs so that the sequence can be visible)

1 Like

we would say just "Tout est possible" :slight_smile:

2 Likes

Here's a little sketch I worked up, for my own purposes, to experiment with encoders.  It only prints to the serial monitor but I think it does illustrate what you want to do encoder-wise.  Maybe you can adapt it for your use.

/*
  Demonstrate a simple two level menu system on the serial monitor
  using a quadrature encoder and integral pushbutton.

  Navigation mode uses the encoder to select a variable to change.
  Alter mode uses the encoder to adjust the selected value.
  The encoder pushbutton toggles between navigation and alter modes.

  v8 combines the value adjustment code with the 'build an integer'
  code to adjust a large value one digit at a time. The builtup
  number is displayed following the individual digits.

  Toggling the two booleans is retained and added is the ability for
  one of the bools to control the sign of the number.
*/

#include <Bounce2.h> // a library to handle the pushbutton
#define BOUNCE_PIN A0
Bounce encoderPB = Bounce();

#define INTPIN1 PIN2   // Rotary encoder interrupt on this Arduino Uno pin.
#define INTPIN2 PIN3   // Rotary encoder interrupt on this Arduino Uno pin.

#include <Rotary.h>  // encoder handler by Buxton
//                   https://github.com/buxtronix/arduino/tree/master/libraries/Rotary
//

// variables having to do with the encoder

volatile int8_t encoderDirection = 0;  //  Encoder direction value, set in the 'rotate' ISR
//                                         0 = no movement, +1 = CW, -1 = CCW
const int8_t numberOfValues = 8; // total number of variables used / displayed
//                                  this determines when to wrap the 'cursor' position
int8_t valueToAdjust = 0; // Selects which value will be adjusted
bool isNavigationMode = true; // controls select vs. alter mode

const int8_t numberOfArrayElements = 5; // The five array elements represent five digits
//                                         which will be joined, according to their
//                                         respective place values, in largeNumber

unsigned long largeNumber; // all the digits together in one place

int8_t digitNumber[numberOfArrayElements]; // compiler will initialize to zero
byte numElements = sizeof digitNumber / sizeof digitNumber[0];

bool signIndicator = true, bool2; // one sign toggle, one toggle switch

const uint8_t modeIndicator = 12; // Pin number for common anode LED

// enum values for the switch / case construct

enum valueSelect {tenPwr0, tenPwr1, tenPwr2, tenPwr3, tenPwr4, fullNumber, signToggle, switchToggle};

/*
   Rotary encoder pin assignments
*/
Rotary rotary = Rotary(INTPIN1, INTPIN2);  // interrupts are used on both pins 2 & 3
//
// === S E T U P ===

void setup() {
  Serial.begin(115200);
  attachInterrupt(0, rotate, CHANGE);
  pinMode(INTPIN1, INPUT_PULLUP);
  attachInterrupt(1, rotate, CHANGE);
  pinMode(INTPIN2, INPUT_PULLUP);
  encoderPB.attach(BOUNCE_PIN, INPUT_PULLUP);
  encoderPB.interval(5);
  pinMode(modeIndicator, OUTPUT); // Common anode LED
  displayAllValues();
}

void loop() {

  encoderPB.update(); // Refresh the pushbutton object variables

  if (encoderPB.fell()) { // User pushed a button
    isNavigationMode = !isNavigationMode; // Toggle navigate/adjust mode
    digitalWrite(modeIndicator, (isNavigationMode ? LOW : HIGH)); // Annunciate mode via LED
  }

  if ( encoderDirection != 0) { // Test if encoder moved.
    // Select the value of interest
    if (isNavigationMode) {
      selectValue();
    }

    else {
      changeDataValues();
    }

    encoderDirection = 0; // Reset the increment value
    displayAllValues(); // Update the display
  }
} // end of loop

//
//-------------------------------------------------------
//

void changeDataValues() {
  //
  // In data change mode we come here to increment/decrement numeric values
  // and toggle boolean values

  uint8_t switchUse = (numberOfArrayElements - 1) - valueToAdjust;

  switch (valueToAdjust) {
    case tenPwr0...tenPwr4:
      digitNumber[switchUse] += encoderDirection;
      if (digitNumber[switchUse] < 0) digitNumber[switchUse] = 0;
      if (digitNumber[switchUse] > 9) digitNumber[switchUse] = 9;
      break;

    // For booleans encoder direction is irrelevant. If we've made
    // it this far the encoder moved so toggle the indicated bool.

    case (signToggle):
      signIndicator = !signIndicator;
      break;

    case (switchToggle):
      bool2 = !bool2;
      break;

    default: break;
  }
}

//
//--------------------------------------------------
//

long digitsToNumber() {
  /*
    Build a unified, single integer from separate digits taken
    from an array.

    The array elements (digits) are manipulated individually by
    the changeDataValues menu function
  */
  long largeNumber = 0;
  unsigned long tenXMultiplier = 1;

  for (int8_t i = 0; i < numElements; i++) {
    largeNumber += digitNumber[i] * tenXMultiplier;
    tenXMultiplier *= 10;
  }
  
  if (signIndicator == false) {
    largeNumber *= -1;
  }
  return largeNumber;
}

//
//-------------------------------------
//

void selectValue() {
  /*
    If the encoder moved, the value which selects the array element
    to be changed is incremented or decremented accordingly. Values
    wrap in both directions.
  */
  valueToAdjust += encoderDirection;
  if (valueToAdjust >= numberOfValues) valueToAdjust = 0;
  if (valueToAdjust < 0) valueToAdjust = numberOfValues - 1;
}

//
//---------------------------------------------------------
//

void rotate() { // Encoder ISR
  /*
    Interrupt Service Routine for rotary encoder:
    An interrupt is generated any time either of the rotary
    inputs change state. Once the interrupt is acted upon,
    other code will clear encoderDirection to zero.
  */
  byte result = rotary.process();
  if (result == DIR_CW) {
    encoderDirection = +1;
  } else if (result == DIR_CCW) {
    encoderDirection = -1;
  }
}

//
//------------------------------------
//

void displayAllValues() {
  /*
      Format and print the values and add headings and a position cursor
  */
  for (int8_t  i = numberOfArrayElements; i > 0; i--) {
    Serial.print(i );
    Serial.print("\t");
  }
  Serial.print("number\t");
  Serial.print("sign\t");
  Serial.println("bool2");

  for (int8_t i = numberOfArrayElements - 1; i >= 0; i--) {
    Serial.print(digitNumber[i]);
    Serial.print("\t");
  }

  //  Serial.print(unifiedDigits);
  long x14 = digitsToNumber();
  Serial.print(x14);
  Serial.print("\t");

  if (signIndicator) Serial.print("pos");
  else Serial.print("neg");
  Serial.print("\t");

  if (bool2) Serial.print("true");
  else Serial.print("false");
  Serial.println();

  for (byte i = 0; i < numberOfValues; i++) {
    if (i == valueToAdjust) Serial.print("--\t");
    else Serial.print("\t");
  }
  Serial.println();
  Serial.println(F("............................................................"));
}

1 Like

Beside the arduino catagory, there's freelancer, upwork, fiver, and Guru
Plenty of coders on freelancer.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.