I have been asked to modify a project. The project used ADC and three potentiometers to set operating setpoints. Now the project is several years old, it would appear some temperature drift is occuring in the potentiometers. The pots are not touched but as the air temp changes, the resistance changes and therefore the voltage reading and in turn the setpoint changes.
The decision was made to change from 3 pots to 1 rotary encoder and use the integrated push button to index through the setpoints to change them.
With all of that aside I started with a blank Arduino Mega and the encoder. I tried the encoder library with the encoder and it returned random results when the shaft was turned one notch (sometimes it incremented 4, sometimes 5, sometimes 6). I changed to the Notched_Shaft_Encoder library and that has provided stable results.
When the program starts the encoder starts at zero. It would be best if I could set the starting position to the first setpoint and have the encoder drive it directly.
I added noticed there was a reset function and tried to add a set_position function:
void NSEncoder::set_position(int16_t new_pos)
{
enc_old_step = new_pos;
enc_old_pulse = new_pos;
this->write(new_pos);//set the enocder counter to new_pos
}
I initialize sp [ x ] = {5, 20, 50};
That povided the results:
SP0: 5--
SP0: 1
SP0: 2
SP0: 1
SP0: 0
Change to SP1
SP1: 20--
SP1: 4
SP1: 3
SP1: 4
SP1: 5
Change to SP2
SP2: 50--
SP2: 12
SP2: 11
SP2: 12
#include <NSEncoder.h>
#define ENCODER_S1_PIN 5 //Define you encoder connection pin Here
#define ENCODER_S2_PIN 6
#define ENCODER_BTN_PIN 10
NSEncoder enc(ENCODER_S1_PIN, ENCODER_S2_PIN, 4);
#include <JC_Button.h>
Button Select_Btn(ENCODER_BTN_PIN);
uint8_t sp_idx=0;
int16_t sp[3] = {5, 20, 50};
int16_t enc_position;
void scan_buttons()
{
Select_Btn.read();
if (Select_Btn.wasReleased())
{
sp_idx++;
if (sp_idx>=3)
{ sp_idx = 0; }
Serial.print("Change to SP");
Serial.println(sp_idx);
enc.set_position(sp[sp_idx]);
enc.get_Position(sp[sp_idx]);
Serial.print("SP");
Serial.print(sp_idx);
Serial.print(": ");
Serial.print(sp[sp_idx]);
Serial.println("--");
}
}
void setup()
{
Serial.begin(115200);
Select_Btn.begin();
enc.set_position(sp[sp_idx]);
enc.get_Position(sp[sp_idx]);
Serial.print("SP");
Serial.print(sp_idx);
Serial.print(": ");
Serial.print(sp[sp_idx]);
Serial.println("--");
}
void loop()
{
scan_buttons();
if(enc.get_Position(sp[sp_idx])) //If value is updated
{
Serial.print("SP");
Serial.print(sp_idx);
Serial.print(": ");
Serial.println(sp[sp_idx]);
}
}
Plan A is the simplest solution, integrate a set position function so the setpoint is directly modified by the encoder position.
I have a plan B but arrays of setpoints are difficult to manage since you have to remember which index belongs to which setpoint while you are programming. There is also a plan C would be individual variables for each setpoint (far easier to read than Plan C) but requires several switch-case statements to get the encoder position to modify the initial value stored and loaded when the button is pressed and another to return it to the corresponding setpoint when the encoder is turned. Yeah, it is as clumsy as that sounds.
I'd like to get plan A to work if anyone has any information on how to add a set_position function to the Notched_Shaft_Encoder library, please let me know.