I'm currently trying to build a belt-conveyor with a Steppermotor.
Planed Components are:
ESP8266 NodeMCU
KY-040 Encoder
Keyes Stepper Motor for arduino controll with A4988 Driver
Stepperonline Nema17 Steppermotor (1.8°, 2.0A)
APKLVSR 1.3" 128x64 OLED-Display (SH1106/I²C)
The Steppermotor has a seperate 24V DC 5A Powersupply. The ESP is powered trough USB from an external Powerdistributionboard.
The Driver-Logic and the Display also get 5V from that board. The Encoder gets 3.3V fron the ESP.
Cureently I am at implementing the Display, but now the Motor stopped working correctly and I am unsure why.
Based on the Encoder- and ContinuousStepper-Libary I programed the following code, that works fine.
I can change the speed of the Stepper by turning the encoder, it only goes up to the desired maximum speed and starts and stops by pressing the button.
#include <ContinuousStepper.h> // Library for stepper motor control.
#include <Encoder.h> // Library for encoder evaluation.
// For the encoder:
Encoder myEnc(D5, D6); // Define the pins for the encoder.
long oldPosition = -999; // Set an unlikely value for the first encoder evaluation loop.
const uint16_t potReadInterval = 500; // in milliseconds
// For the encoder button:
const int SW = D7; // Define the pin for the encoder button.
int state = LOW; // Current state of the encoder button.
int reading; // Temporary storage for the button reading.
int previous = LOW; // Stores the last read value.
long LastTime = 0; // Stores the last timestamp when the button was pressed.
long DebounceInterval = 200; // Sets the debounce time interval.
// For the stepper motor:
const uint8_t stepPin = D3; // Define the STEP pin.
const uint8_t dirPin = D4; // Define the DIR pin.
ContinuousStepper<StepperDriver> stepper; // Specify the stepper motor control method.
int stepperSpeed = 0; // Initial stepper motor speed in [steps/second].
int maxSpeed = 2500; // Maximum stepper motor speed [steps/second].
void setup() {
stepper.begin(stepPin, dirPin); // Set the pins for motor control.
//stepper.powerOff(); // Set the motor status to off, so it doesn't start spinning immediately.
Serial.begin(9600); // Start serial communication at a baud rate of 9600.
pinMode(SW, INPUT_PULLUP); // Enable the pull-up resistor for the button pin.
}
void loop() {
// Encoder:
long newPosition = myEnc.read(); // Read the encoder.
if (newPosition != oldPosition) { // Check if the encoder position has changed.
oldPosition = newPosition; // Update the old position.
Serial.println(newPosition); // Print the current encoder value.
}
// Button:
reading = digitalRead(SW); // Read the encoder button.
if (reading == HIGH && previous == LOW && millis() - LastTime > DebounceInterval)
{
if (state == HIGH){ // Check the current button state.
state = LOW; // Change the button state to LOW.
stepper.powerOn(); // Power on the motor at the current speed.
}
else{
state = HIGH; // Change the button state to HIGH.
stepper.powerOff(); // Power off the motor; speed value is retained.
}
LastTime = millis(); // Store the last activation timestamp.
}
previous = reading; // Save the last button state for activation detection.
// Stepper motor:
stepperSpeed = newPosition * 10; // Set the speed as a multiple of the encoder value.
if (stepperSpeed >= maxSpeed){ // Check if the maximum positive speed is exceeded.
stepperSpeed = maxSpeed; // Limit the speed to the maximum.
}
if (stepperSpeed <= 0 - maxSpeed){ // Check if the maximum negative speed is exceeded.
stepperSpeed = 0 - maxSpeed; // Limit the speed to the maximum.
}
stepper.spin(stepperSpeed); // Spin the stepper motor at the set speed.
stepper.loop(); // Must be called as often as possible to ensure continuous motor rotation.
}
Seperately I created the following code for the display:
#include <Arduino.h>
#include <U8g2lib.h>
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
float Text = 30.015678;
void setup(void) {
pinMode(4, OUTPUT); //SDA
pinMode(5, OUTPUT); //SCL
digitalWrite(4, 0);
digitalWrite(5, 0);
u8g2.begin();
u8g2.setPowerSave(0);
}
void loop(void) {
u8g2.clearBuffer(); // clear the internal memory
u8g2.setFont(u8g2_font_spleen6x12_mf); // choose a suitable font
u8g2.drawStr(5,10,"set Speed:"); // write something to the internal memory
u8g2.setFont(u8g2_font_spleen32x64_mn); // choose a suitable font
u8g2.setCursor(0,63);
u8g2.print(Text);
u8g2.sendBuffer(); // transfer internal memory to the display
}
That Code also does what I expected it to do.
Now I have tried to merge the Code, sothat the Display shows the speed, that is set by the encoder:
#include <ContinuousStepper.h> // Library for stepper motor control.
#include <Encoder.h> // Library for encoder evaluation.
#include <Arduino.h>
#include <U8g2lib.h>
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
// For the encoder:
Encoder myEnc(D5, D6); // Define the pins for the encoder.
long oldPosition = -999; // Set an unlikely value for the first encoder evaluation loop.
const uint16_t potReadInterval = 500; // in milliseconds.
// For the encoder button:
const int SW = D7; // Define the pin for the encoder button.
int state = LOW; // Current state of the encoder button.
int reading; // Temporary storage for the button reading.
int previous = LOW; // Stores the last read value.
long LastTime = 0; // Stores the last timestamp when the button was pressed.
long DebounceInterval = 200; // Sets the debounce time interval.
// For the stepper motor:
const uint8_t stepPin = D3; // Define the STEP pin.
const uint8_t dirPin = D4; // Define the DIR pin.
ContinuousStepper<StepperDriver> stepper; // Specify the stepper motor control method.
int stepperSpeed = 0; // Initial stepper motor speed in [steps/second].
int maxSpeed = 2500; // Maximum stepper motor speed [steps/second].
// For the display:
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
float Display = 30.015;
void setup() {
stepper.begin(stepPin, dirPin); // Set the pins for motor control.
//stepper.powerOff(); // Set the motor status to off, so it doesn't start spinning immediately.
Serial.begin(9600); // Start serial communication at a baud rate of 9600.
pinMode(SW, INPUT_PULLUP); // Enable the pull-up resistor for the button pin.
pinMode(4, OUTPUT); // SDA
pinMode(5, OUTPUT); // SCL
digitalWrite(4, 0);
digitalWrite(5, 0);
u8g2.begin();
u8g2.setPowerSave(0);
}
void loop() {
// Encoder:
long newPosition = myEnc.read(); // Read the encoder.
// Button:
reading = digitalRead(SW); // Read the encoder button.
if (reading == HIGH && previous == LOW && millis() - LastTime > DebounceInterval)
{
if (state == HIGH){ // Check the current button state.
state = LOW; // Change the button state to LOW.
stepper.powerOn(); // Power on the motor at the current speed.
}
else{
state = HIGH; // Change the button state to HIGH.
stepper.powerOff(); // Power off the motor; speed value is retained.
}
LastTime = millis(); // Store the last activation timestamp.
}
previous = reading; // Save the last button state for activation detection.
// Stepper motor:
stepperSpeed = newPosition * 10; // Set the speed as a multiple of the encoder value.
if (stepperSpeed >= maxSpeed){ // Check if the maximum positive speed is exceeded.
stepperSpeed = maxSpeed; // Limit the speed to the maximum.
}
if (stepperSpeed <= 0 - maxSpeed){ // Check if the maximum negative speed is exceeded.
stepperSpeed = 0 - maxSpeed; // Limit the speed to the maximum.
}
stepper.spin(stepperSpeed); // Spin the stepper motor at the set speed.
stepper.loop(); // Must be called as often as possible to ensure continuous motor rotation.
if (newPosition != oldPosition) { // Check if the encoder position has changed.
oldPosition = newPosition; // Update the old position.
Serial.println(newPosition); // Print the current encoder value.
Display = newPosition;
u8g2.clearBuffer(); // Clear the display buffer.
u8g2.setFont(u8g2_font_spleen6x12_mf); // Set font for the heading.
u8g2.drawStr(5,10,"set Speed:"); // Write the heading to the buffer.
u8g2.setFont(u8g2_font_spleen32x64_mn); // Set font for the value display.
u8g2.setCursor(0,63); // Set the position for value display.
u8g2.print(Display); // Write the value to the buffer.
u8g2.sendBuffer(); // Send the buffer content to the display.
}
}
The Encoder is still working as before and the Display does as expected, but the Motor stoped working correctly, it does not spin constantly, every time I turn the encoder the motor stops for a splitsecont and then returns to spinning. If I increase the speed the Motor stalls at 1/3rd of the speed it reached before.
What did I do wrong?
Kind regards,
Christian
Sorry for the load of code, but I did not know a better way to discripe my Problem.