// ****************************************************************************
// PinA() - Called by the Interrupt pin when the Rotary Encoder Turned
// Routine based on Simon Merrett - Improved Arduino Rotary Encoder Reading
// https://www.instructables.com/id/Improved-Arduino-Rotary-Encoder-Reading/
// ****************************************************************************
void PinA() {
if (rotaryDisabled) return;
cli(); //stop interrupts happening before we read pin values
// read all eight pin values then strip away all but pinA and pinB's values
reading = PIND & 0xC;
//check that both pins at detent (HIGH) and that we are expecting detent on this pin's rising edge
if (reading == B00001100 && aFlag) {
rotaryRight();
bFlag = 0; //reset flags for the next turn
aFlag = 0; //reset flags for the next turn
}
//signal that we're expecting pinB to signal the transition to detent from free rotation
else if (reading == B00000100) bFlag = 1;
sei(); //restart interrupts
}
// ****************************************************************************
// PinB() - Called by the Interrupt pin when the Rotary Encoder Turned
// Routine based on Simon Merrett - Improved Arduino Rotary Encoder Reading
// https://www.instructables.com/id/Improved-Arduino-Rotary-Encoder-Reading/
// ****************************************************************************
void PinB() {
if (rotaryDisabled) return;
cli(); //stop interrupts happening before we read pin values
//read all eight pin values then strip away all but pinA and pinB's values
reading = PIND & 0xC;
//check that both pins at detent (HIGH) and that we are expecting detent on this pin's rising edge
if (reading == B00001100 && bFlag) {
rotaryLeft();
bFlag = 0; //reset flags for the next turn
aFlag = 0; //reset flags for the next turn
}
//signal that we're expecting pinA to signal the transition to detent from free rotation
else if (reading == B00001000) aFlag = 1;
sei(); //restart interrupts
}
// ****************************************************************************
// rotaryRight() - Rotary Encoder is turned 1 detent to the Right (clockwise)
// Insert your own code here.
// ****************************************************************************
void rotaryRight()
{
rotaryCount++;
}
// **********************************************************************************
// rotaryLeft() - Rotary Encoder is turned 1 detent to the Left (counter-clockwise)
// Insert your own code here.
// **********************************************************************************
void rotaryLeft()
{
rotaryCount--;
}
// ****************************************************************************
// rotaryClick() - Rotary Encoder Select Switch is pressed
// Insert your own code here.
// ****************************************************************************
void rotaryClick()
{
rotaryCount += 100;
}
// ****************************************************************************
// rotaryLongPress() - Rotary Encoder Select Switch is Held Down (Long Press)
// Insert your own code here.
// ****************************************************************************
void rotaryLongPress()
{
rotaryCount = 0;
}
// ****************************************************************************
// initializeRotaryEncoder() - Initialize the pins and interrupt functions
// for the Rotary Encoder
// ****************************************************************************
void initializeRotaryEncoder()
{
// Set the Directions of the I/O Pins
pinMode(PIN_ROTARY_CLK, INPUT_PULLUP);
pinMode(PIN_ROTARY_DAT, INPUT_PULLUP);
pinMode(PIN_ROTARY_SW, INPUT_PULLUP);
pinMode(PIN_ROTARY_GND, OUTPUT);
pinMode(PIN_ROTARY_5V, OUTPUT);
// Set the 5V and GND pins for the Rotary Encoder
digitalWrite(PIN_ROTARY_GND, LOW);
digitalWrite(PIN_ROTARY_5V, HIGH);
// set an interrupt on PinA and PinB, looking for a rising edge signal and
// executing the "PinA" and "PinB" Interrupt Service Routines
attachInterrupt(0, PinA, RISING);
attachInterrupt(1, PinB, RISING);
// Define the functions for Rotary Encoder Click and Long Press
btnRot.attachClick(&rotaryClick);
btnRot.attachLongPressStart(&rotaryLongPress);
btnRot.setPressTicks(2000);
rotaryDisabled = 0;
}
// ****************************************************************************
// initializeLcd() - Initialize the LCD
// ****************************************************************************
void initializeLcd()
{
lcd.begin();
lcd.backlight();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Test LCD & Rotry"));
}
// ****************************************************************************
// updateLcd() - Update the LCD with current Rotary Encoder detent count
// ****************************************************************************
void updateLcd()
{
rotaryDisabled = 1;
lcd.setCursor(0, 1);
lcd.print(F("Count = "));
lcd.print(rotaryCount);
lcd.print(F(" "));
rotaryDisabled = 0;
}
// ****************************************************************************
// setup() - Initialization Function
// ****************************************************************************
void setup()
{
initializeRotaryEncoder();
initializeLcd();
}
// ****************************************************************************
// loop() - Main Program Loop Function
// ****************************************************************************
void loop()
{
updateLcd();
btnRot.tick();
delay(50);
}
#include <Wire.h> // Include Wire library for I2C communication
#include <LiquidCrystal_I2C.h> // Include LCD library
#include <AccelStepper.h>
#include <OneButton.h>
#define PIN_ROTARY_CLK 2 // Used for generating interrupts using CLK signal
#define PIN_ROTARY_DAT 3 // Used for reading DT signal
#define PIN_ROTARY_SW 4 // Used for the Rotary push button switch
#define PIN_ROTARY_5V 5 // Set to HIGH to be the 5V pin for the Rotary Encoder
#define PIN_ROTARY_GND 6 // Set to LOW to be the GND pin for the Rotary Encoder
LiquidCrystal_I2C lcd(0x27, 20, 4); // LCD setup: Specify I2C address and dimensions
const int pressureInputPin = A0; // Analog input pin that the sensor is attached to
const float voltageMin = 0.5; // Voltage corresponding to minimum pressure (0 psi)
const float voltageMax = 4.5; // Voltage corresponding to maximum pressure (100 psi)
const float pressureMin = 0; // Minimum pressure value
const float pressureMax = 200; // Maximum pressure value
float pressure = 0; // Pressure value
float adcValue = 200; // Maximum pressure value
float target = 180; // Pressure Target - (The pressure at which the motor will turn)
long interval = 100; // Interval to check sensor and move motor
bool HasReachedMaxSteps = false;
AccelStepper stepper1(1, 9, A3); // (Typeof driver: with 2 pins, STEP, DIR)
unsigned long previousMillis = 0; //Used for the Millisdelay
float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; }
// OneButton class handles Debounce and detects button press
OneButton btnRot(PIN_ROTARY_SW, HIGH); // Rotary Select button
// Used for the Rotary Encoder interrupt routines PinA() and PinB()
volatile int rotaryCount = 0;
// Disables the Rotary Encoder interrupts while the LCD is being updated
byte rotaryDisabled;
volatile byte aFlag = 0; // lets us know when we're expecting a rising edge on pinA
// to signal that the encoder has arrived at a detent
volatile byte bFlag = 0; // lets us know when we're expecting a rising edge on pinB
// to signal that the encoder has arrived at a detent
// (opposite direction to when aFlag is set)
volatile byte reading = 0; //somewhere to store the direct values we read from our interrupt
// pins before checking to see if we have moved a whole detent
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
void setup() {
Serial.begin(9600); // Start serial communication at 9600 bps
pinMode(pressureInputPin, INPUT); // Set the pressure sensor pin as input
pinMode(LED_BUILTIN, OUTPUT); // Set Built in LED
lcd.init(); // Initialize the LCD
lcd.backlight(); // Turn on the backlight
stepper1.setMaxSpeed(2000); // Set maximum speed value for the stepper
stepper1.setAcceleration(4000); // Set acceleration value for the stepper
stepper1.setCurrentPosition(0); // Set the current position to 0 steps
// pinMode(motorD, OUTPUT);
// pinMode(motorS, OUTPUT);
// pinMode(motorE, OUTPUT);
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
void loop() {
if (HasReachedMaxSteps == true) {
lcd.setCursor(6, 0);
lcd.print("WARNING:");
lcd.setCursor(2, 2);
lcd.print("MAX STEP REACHED");
lcd.setCursor(4, 3);
lcd.print("PLEASE RESET");
delay(250);
}
int adcValue = analogRead(pressureInputPin); // Read the analog value from sensor
float voltage = adcValue * (5.0 / 1023.0); // Convert ADC reading to voltage
float pressure = mapfloat(voltage, voltageMin, voltageMax, pressureMin, pressureMax)-4.5; // Map voltage to pressure
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval && HasReachedMaxSteps == false) {
previousMillis = currentMillis;
lcd.setCursor(0, 0); // Set cursor to the first line
lcd.print("Pressure: ");
lcd.print(pressure, 1); // Display pressure with one decimal
lcd.print(" psi");
lcd.setCursor(0, 1); // Move to the next line
lcd.print("ADC Value: ");
lcd.print(adcValue); // Display the raw ADC value
lcd.setCursor(0, 3); // Move to the next line
lcd.print("Target Value: ");
lcd.print(target); // Display the raw ADC value
}
if (pressure > target && HasReachedMaxSteps == false) { // Assuming target is meant to be a pressure value
while (pressure > target) {
int adcValue = analogRead(pressureInputPin); // Read the analog value from sensor
voltage = adcValue * (5.0 / 1023.0); // Convert ADC reading to voltage
pressure = mapfloat(voltage, voltageMin, voltageMax, pressureMin, pressureMax)-4.5; // Map voltage to pressure
digitalWrite(LED_BUILTIN, HIGH);
stepper1.moveTo(10000);
stepper1.run(); //
// Check if motor reached the target position
if (stepper1.currentPosition() >= 9999) {
//digitalWrite(10, HIGH); // Output pin 10 high
HasReachedMaxSteps = true;
lcd.clear();
break; // Exit the while loop
}}}
else if (HasReachedMaxSteps == false)
{
stepper1.stop();
stepper1.runToPosition();
stepper1.setCurrentPosition(0);
digitalWrite(LED_BUILTIN, LOW);
}
}
This A4988 Driver is representative of the Driver inteneded to be used, which is a CL57T.
Link is as follows: https://www.omc-stepperonline.com/closed-loop-stepper-driver-0-8-0a-24-48vdc-for-nema-17-23-24-stepper-motor-cl57t
This Potentiometer is to represent
the pressure sensor. It can be roatated
to increase pressure.
The pressure sensor uses is a 0-200psi
sensor where 0 psi is 0.5v and 200 psi
is 4.5v.