Hi, thanks for letting me join, I'm hooping someone eon here can help me with a couple of issues i am having getting a project working for my local model club.
I'm building Arduino controlled stepper driven turntable assemblies for two layouts at my local railway club.
I have the mechanical setup working with Arduino Uni, A4988 driver and Nema 17 stepper motor fitted directly to turntables and a hall effect sensor and magnet correctly locating a home starting position each time the system is turned on.
And I have 2 buttons that when pressed move the turntable 180' and then back home again respectively.
The issue I am having now is I need to provide the ability for the users of the layout to program 3 different track settings for the loco sheds, these will be stored in the Arduinos eeprom and i have currently worked out the programming and reading code for this on one instance at the moment, but I have now introduced a rotary encoder so the user can turn the turntable to the desired location manually and then store its position in the memory. the issue is when running the encoder loop to turn the stepper motor the serial monitor does not record the current or new position of the stepper motor, this means i cant read it and store it. also my stepper is bouncing randomly when turning the encoder is this some thing i can tune out?
really hope someone can help as this had been a fun project and learning exercise and I feel I'm pretty close just missing a trick somewhere.
thanks my code is below.
#include <AccelStepper.h>
#include <EEPROM.h>
// Rotary Encoder Module connections
const int PinCLK = 2; // Generating interrupts using CLK signal
const int PinDT = 3; // Reading DT signal
const int PinSW = 4; // Reading Push Button switch
// A4988 Driver connections
#define motorInterfaceType 1
#define dirPin 8
#define stepPin 9
#define MS1 10 // Pin 10 connected to MS1 pin
#define MS2 11 // Pin 11 connected to MS2 pin
//#define SLEEP 12 // Pin 12 connected to SLEEP pin
// Hall Sensor connections
#define HALL_SENSOR 7
// Stepper Home & Travel Variables
long TravelX; // Used to store the X value entered in the Serial Monitor
int move_finished = 1; // Used to check if move is completed
long initial_homing = -1; // Used to Home Stepper at startup
// Create a new instance of the AccelStepper class:
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);
int Position1 = 0;
int Position2 = 0;
int a = 1;
int value;
volatile boolean TurnDetected; // to detect rotation of Rotary Encoder
volatile boolean rotationdirection; // CW or CCW rotation
volatile boolean rswitch = 1; // Variable to store rotary encoder switch state
volatile boolean led_speed_change; // to detect change of speed
volatile int StepsToTake = 2; // Controls the speed of the Stepper per Rotary click
int direction; // Variable to set Rotation (CW-CCW) of stepper
//define rotary switch pin
//const int switchPin = 9;
//define push button pins
const int buttonPin = 12;
//create a variable to store a counter and set it to 0
int counter = 0;
unsigned long last_button_time = 0; //for saving last millis button 1
const int buttonPin1 = 13;
//create a variable to store a counter and set it to 0
int counter1 = 0;
unsigned long last_button_time1 = 0; //for saving last millis button 1
// Interrupt routine runs if CLK goes from HIGH to LOW
void rotarydetect () {
delay(4); // delay for Debouncing Rotary Encoder
if (rswitch == 1) {
if (digitalRead(PinCLK)) {
if (digitalRead(PinDT)) {
if (StepsToTake > 2) {
StepsToTake = StepsToTake - 1;
}
}
if (!digitalRead(PinDT)) {
if (StepsToTake < 9) {
StepsToTake = StepsToTake + 1;
}
}
led_speed_change = true;
}
}
else {
if (digitalRead(PinCLK))
rotationdirection = digitalRead(PinDT);
else
rotationdirection = !digitalRead(PinDT);
TurnDetected = true;
}
}
void setup()
{ // initialize the serial port:
Serial.begin(9600);
pinMode(HALL_SENSOR, INPUT);
delay(5);
// Set the maximum speed and acceleration:
stepper.setMaxSpeed(60);
stepper.setAcceleration(100);
//initialise pins as inputs
pinMode(MS1, OUTPUT);
pinMode(MS2, OUTPUT);
pinMode(buttonPin, INPUT);
digitalWrite(buttonPin, HIGH);
pinMode(buttonPin1, INPUT);
digitalWrite(buttonPin1, HIGH);
value = EEPROM.read(a);
digitalWrite(MS1, HIGH); // Configures to Full Steps
digitalWrite(MS2, HIGH); // Configures to Full Steps
// Start Homing procedure of Stepper Motor at startup
Serial.print("Stepper is Homing . . . . . . . . . . . ");
while (digitalRead(HALL_SENSOR)) { // Make the Stepper move CCW until the switch is activated
stepper.moveTo(initial_homing); // Set the position to move to
initial_homing--; // Decrease by 1 for next move if needed
stepper.run(); // Start moving the stepper
delay(5);
}
stepper.setCurrentPosition(0); // Set the current position as zero for now
stepper.setMaxSpeed(60.0); // Set Max Speed of Stepper (Slower to get better accuracy)
stepper.setAcceleration(100.0); // Set Acceleration of Stepper
initial_homing = 1;
while (!digitalRead(HALL_SENSOR)) { // Make the Stepper move CW until the switch is deactivated
stepper.moveTo(initial_homing);
stepper.run();
initial_homing++;
delay(5);
}
stepper.setCurrentPosition(0);
Serial.println("Homing Completed");
Serial.println("");
Serial.print (stepper.currentPosition());
Serial.println ();
//digitalWrite(MS1, HIGH); // Configures to Full Steps
//digitalWrite(MS2, LOW); // Configures to Full Steps
pinMode(PinCLK, INPUT); // Set Pins to Inputfor rotary encoder
pinMode(PinDT, INPUT);
pinMode(PinSW, INPUT);
digitalWrite(PinSW, INPUT_PULLUP); // use internal resistor of UNO for Rotary Encoder switch
attachInterrupt (0, rotarydetect, FALLING); // interrupt 0 always connected to pin 2 on Arduino UNO
}
void loop()
{
if (!(digitalRead(PinSW))) { // Do if Rotary Encoder switch is pressed
delay(250); // debounce switch
if (rswitch == 0) {
rswitch = 1;
}
else {
rswitch = 0;
}
}
// Runs if Rotary Encoder switch is pressed
if (rswitch == 1) {
}
// Runs if rotation was detected
if (TurnDetected) {
TurnDetected = false; // do NOT repeat IF loop until new rotation detected
// Which direction to move Stepper motor
if (rotationdirection) { // Move motor CCW
digitalWrite(dirPin, HIGH); // (HIGH = anti-clockwise / LOW = clockwise)
for (int x = 1; x < StepsToTake; x++) {
digitalWrite(stepPin, HIGH);
delay(1);
digitalWrite(stepPin, LOW);
delay(1);
}
// Serial.print (stepper.currentPosition()); // inserted to try and view steps taken when using rotary encoder
// Serial.println ();
}
if (!rotationdirection) { // Move motor CW
digitalWrite(dirPin, LOW); // (HIGH = anti-clockwise / LOW = clockwise)
for (int x = 1; x < StepsToTake; x++) {
digitalWrite(stepPin, HIGH);
delay(1);
digitalWrite(stepPin, LOW);
delay(1);
}
// Serial.print (stepper.currentPosition()); // inserted to try and view steps taken when using rotary encoder
// Serial.println ();
}
}
//if rotary switch not pushed these functions will run in the loop
fullSwing();
returnHome();
}
void fullSwing()
{
bool buttonState; // local variable to hold the pushbutton states
//read the digital state of buttonPin with digitalRead() function and store the value in buttonState variable
buttonState = digitalRead(buttonPin);
//if the button is pressed increment counter and wait a tiny bit to give us some time to release the button
if (buttonState == LOW && millis() - last_button_time > 200 ) // checks to see if button has been pressed and time since last button press is greater than 200ms
{
last_button_time = millis();
counter++;
{
// Set the maximum speed and acceleration:
stepper.setMaxSpeed(50);
stepper.setAcceleration(20);
stepper.moveTo(value * 8); //(801)180 Spin
stepper.runToPosition();
}
}
//Position1 = stepper.currentPosition(); // inserted to view end position of stepper motor
//Serial.print (Position1);
//Serial.println ();
{
// EEPROM.write(0, Position1/8); //currently not used but will be used to store the position of the stepper motor to a memory location.
}
}
void returnHome()
{
bool buttonState1; // local variable to hold the pushbutton states
//read the digital state of buttonPin with digitalRead() function and store the value in buttonState variable
buttonState1 = digitalRead(buttonPin1);
//if the button is pressed increment counter and wait a tiny bit to give us some time to release the button
if (buttonState1 == LOW && millis() - last_button_time1 > 200 ) // checks to see if button has been pressed and time since last button press is greater than 200ms
{
last_button_time = millis();
counter++;
{
// Set the maximum speed and acceleration:
stepper.setMaxSpeed(50);
stepper.setAcceleration(20);
stepper.moveTo(0);
stepper.runToPosition();
}
}
// Position2 = stepper.currentPosition(); // inserted to view end position of stepper motor
// Serial.print (Position2);
// Serial.println ();
{
// EEPROM.write(5, Position2/8); //currently not used but will be used to store the position of the stepper motor to a memory location.
}
}