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
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?
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?
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("............................................................"));
}