Hallo zusammen,
ich schreibe gerade ein Programm, mit dem ich die Vorschubgeschwindigkeit in mm/min für die Achsen XYZ und in rpm für die A-Achse steuern kann. Die Geschwindigkeit für die Schrittmotoren wird über die Frequenz der Rechteckimpulse gesteuert. Zur Erzeugung der Rechtecksignale verwende ich die Bibliothek Tone.h. Jeder Motor hat einen Plus- und Minus-Taster und zusätzlich einen Taster für den Eilgangmodus.
Wird der Eilgangmodus aktiviert, soll die bisherige Geschwindigkeit (currentSpeed) in der Variable oldSpeed gespeichert werden und in currentSpeed wird der Wert von maxSpeed geschrieben. Wenn der Eilgangmodus verlassen wird, soll der Wert von oldSpeed zurück in currentSpeed geschrieben werden, damit nach dem Eilgang wieder die zuvor eingestellte Geschwindigkeit vorliegt.
Leider funktioniert das nicht, denn auch nach dem verlassen des Eilgangmodus bleibt die Geschwindigkeit auf dem Wert von maxSpeed.
Kann mir bitte jemand helfen und sagen wo mein Fehler liegt?
Vielen Dank und Grüße
Daniel
Code:
/* Manual Mill Controller v1.0
* written by Iron-Dan
* Creates stepper pulses to set speeds in mm/min and rpm and included rapid traverse mode.
* Implemented with the usage of the libraries which are included below.
*/
/*********************************************************************
This is an example for our Monochrome OLEDs based on SSD1306 drivers
Pick one up today in the adafruit shop!
------> http://www.adafruit.com/category/63_98
This example is for a 128x64 size myOLED using I2C to communicate
3 pins are required to interface (2 I2C and one reset)
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, check license.txt for more information
All text above, and the splash screen must be included in any redistribution
*********************************************************************/
/*********************************************************************
I change the adafruit SSD1306 to SH1106
SH1106 driver don't provide several functions such as scroll commands.
*********************************************************************/
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH1106.h>
#define OLED_RESET -1
Adafruit_SH1106 myOLED(OLED_RESET);
#include <Tone.h>
// Variables
const byte minusButtonA = 8; // Minus Button for speed value on A-Axis at Arduino Pin 10.
const byte plusButtonA = 7; // Plus Button for speed value on A-Axis at Arduino Pin 9.
const byte rapidButtonA = 2; // Button for rapid traverse mode on A-Axis at Arduino Pin 2.
const byte rapidLEDA = 11; // LED for indication of rapid traverse mode on A-Axis at Arduino Pin 11.
volatile byte stateRapidModeA = LOW; // State of rapid traverse mode on A-Axis.
const float maxSpeedA = 20.0; // Max. speed in rpm.
volatile float currentSpeedA = 0.0; // Current speed in rpm.
volatile float oldSpeedA = 0.0; // Old speed in rpm.
const byte minusButtonXYZ = 10; // Minus Button for speed value on XYZ-Axis at Arduino Pin 8.
const byte plusButtonXYZ = 9; // Plus Button for speed value on XYZ-Axis at Arduino Pin 7.
const byte rapidButtonXYZ = 3; // Button for rapid traverse mode on XYZ-Axis at Arduino Pin 3.
const byte rapidLEDXYZ = 12; // LED for indication of rapid traverse mode on XYZ-Axis at Arduino Pin 12.
volatile byte stateRapidModeXYZ = LOW; // State of rapid traverse mode on XYZ-Axis.
const float maxSpeedXYZ = 2000.0; // Max. speed in mm/min.
volatile float currentSpeedXYZ = 0.0; // Current speed in mm/min.
volatile float oldSpeedXYZ = 0.0; // Old speed in mm/min.
// Timer variables
unsigned long lastIntTimeA = 0; // Time value in ms when ISR rapidModeA was called last time.
unsigned long newIntTimeA; // New time value in ms when ISR rapidModeA is called.
unsigned long previousMillisMinusButtonA = 0; // Store time in ms as MinusButtonA was clicked first time.
unsigned long currentMillisMinusButtonA = 0; // Store time value as long as MinusButtonA is held.
unsigned long previousMillisPlusButtonA = 0; // Store time in ms as PlusButtonA was clicked first time.
unsigned long currentMillisPlusButtonA = 0; // Store time value as long as PlusButtonA is held.
unsigned long lastIntTimeXYZ = 0; // Time value in ms when ISR rapidModeXYZ was called last time.
unsigned long newIntTimeXYZ; // New time value in ms when ISR rapidModeXYZ is called.
unsigned long previousMillisMinusButtonXYZ = 0; // Store time in ms as MinusButtonXYZ was clicked first time.
unsigned long currentMillisMinusButtonXYZ = 0; // Store time value as long as MinusButtonXYZ is held.
unsigned long previousMillisPlusButtonXYZ = 0; // Store time in ms as PlusButtonXYZ was clicked first time.
unsigned long currentMillisPlusButtonXYZ = 0; // Store time value as long as PlusButtonXYZ is held.
// Stepper variables
unsigned int microStepsA = 16;
unsigned int motorStepsA = 200;
unsigned int turnsPerRoundA = 90;
unsigned int microStepsXYZ = 16;
unsigned int motorStepsXYZ = 200;
unsigned int mmPerRoundXYZ = 5;
unsigned int frequencyA = 0;
unsigned int frequencyXYZ = 0;
Tone pulseA; // Create Tone object pulseA.
Tone pulseXYZ; // Create Tone object pulseXYZ.
// Interrupt Service Routines (ISR)
void rapidModeA()
{
newIntTimeA = millis();
if (newIntTimeA - lastIntTimeA > 200) // Push button debouncing.
{
stateRapidModeA = !stateRapidModeA; // Toggle stateRapidModeA when rapidButtonA was pressed.
}
lastIntTimeA = newIntTimeA;
if (stateRapidModeA == HIGH)
{
digitalWrite(rapidLEDA, HIGH);
oldSpeedA = currentSpeedA; // Store previous speed for A-Axis.
currentSpeedA = maxSpeedA; // Set max speed for A-Axis.
}
else if (stateRapidModeA == LOW)
{
digitalWrite(rapidLEDA, LOW);
currentSpeedA = oldSpeedA; // Restore speed value before rapid traverse mode was entered.
}
}
void rapidModeXYZ()
{
newIntTimeXYZ = millis();
if (newIntTimeXYZ - lastIntTimeXYZ > 200) // Push button debouncing.
{
stateRapidModeXYZ = !stateRapidModeXYZ; // Toggle stateRapidModeXYZ when rapidButtonXYZ was pressed.
}
lastIntTimeXYZ = newIntTimeXYZ;
if (stateRapidModeXYZ == HIGH)
{
digitalWrite(rapidLEDXYZ, HIGH);
oldSpeedXYZ = currentSpeedXYZ; // Store previous speed for XYZ-Axis.
currentSpeedXYZ = maxSpeedXYZ; // Set max speed for XYZ-Axis.
}
else if (stateRapidModeXYZ == LOW)
{
digitalWrite(rapidLEDXYZ, LOW);
currentSpeedXYZ = oldSpeedXYZ; // Restore speed value before rapid traverse mode was entered.
}
}
void setup() {
pinMode(minusButtonA, INPUT_PULLUP);
pinMode(plusButtonA, INPUT_PULLUP);
pinMode(rapidButtonA, INPUT_PULLUP);
pinMode(minusButtonXYZ, INPUT_PULLUP);
pinMode(plusButtonXYZ, INPUT_PULLUP);
pinMode(rapidButtonXYZ, INPUT_PULLUP);
pinMode(rapidLEDA, OUTPUT);
pinMode(rapidLEDXYZ, OUTPUT);
attachInterrupt(digitalPinToInterrupt(rapidButtonA), rapidModeA, FALLING);
attachInterrupt(digitalPinToInterrupt(rapidButtonXYZ), rapidModeXYZ, FALLING);
pulseA.begin(5); // Init stepper pulses for A-Axis at Arduino Pin 5.
pulseXYZ.begin(6); // Init stepper pulses for XYZ-Axis at Arduino Pin 6.
bootScreen(); // Show Boot Screen
}
void loop() {
readMinusButtonA();
readPlusButtonA();
readMinusButtonXYZ();
readPlusButtonXYZ();
updateDisplay();
if (currentSpeedA > 0)
{
frequencyA = (round(currentSpeedA) * microStepsA * motorStepsA * turnsPerRoundA) / 60;
pulseA.play(frequencyA);
}
else
{
pulseA.stop();
}
if (currentSpeedXYZ > 0)
{
frequencyXYZ = (round(currentSpeedXYZ) * microStepsXYZ * motorStepsXYZ) / (60 * mmPerRoundXYZ);
pulseXYZ.play(frequencyXYZ);
}
else
{
pulseXYZ.stop();
}
}
void bootScreen()
{
myOLED.begin(); // Init the OLED.
myOLED.clearDisplay(); // Clear display buffer.
myOLED.setTextSize(1);
myOLED.setTextColor(WHITE);
myOLED.setCursor(0, 0);
myOLED.print("MANUAL");
myOLED.setCursor(0, 10);
myOLED.print("MILL");
myOLED.setCursor(0, 20);
myOLED.print("CONTROLLER");
myOLED.setCursor(0, 30);
myOLED.print("v1.0");
myOLED.setCursor(0, 40);
myOLED.print("BY IRON-DAN");
myOLED.display();
delay(3000);
myOLED.clearDisplay(); // Clear display buffer.
myOLED.setTextSize(2);
}
void updateDisplay()
{
myOLED.setCursor(0, 0);
myOLED.print("XYZ");
myOLED.setCursor(40, 0);
myOLED.print(currentSpeedXYZ);
myOLED.setCursor(0, 30);
myOLED.print("A");
myOLED.setCursor(40, 30);
myOLED.print(currentSpeedA);
myOLED.display();
delay(100);
myOLED.clearDisplay(); // Clear display buffer.
}
void readMinusButtonA()
{
if (!digitalRead(minusButtonA))
{
previousMillisMinusButtonA = millis(); // Store first time value when MinusButtonA was clicked.
while (!digitalRead(minusButtonA))
{
currentMillisMinusButtonA = millis(); // Update time value as long as MinusButtonA is held.
if (currentMillisMinusButtonA - previousMillisMinusButtonA > 50 && currentMillisMinusButtonA - previousMillisMinusButtonA <= 1000)
{
currentSpeedA -= 0.01;
if (currentSpeedA < 0)
{
currentSpeedA = 0;
}
updateDisplay();
}
else if (currentMillisMinusButtonA - previousMillisMinusButtonA > 1000 && currentMillisMinusButtonA - previousMillisMinusButtonA <= 5000)
{
currentSpeedA -= 0.10;
if (currentSpeedA < 0)
{
currentSpeedA = 0;
}
updateDisplay();
}
else if (currentMillisMinusButtonA - previousMillisMinusButtonA > 5000)
{
currentSpeedA -= 1.00;
if (currentSpeedA < 0)
{
currentSpeedA = 0;
}
updateDisplay();
}
}
}
}
void readPlusButtonA()
{
if (!digitalRead(plusButtonA))
{
previousMillisPlusButtonA = millis(); // Store first time value when PlusButtonA was clicked.
while (!digitalRead(plusButtonA))
{
currentMillisPlusButtonA = millis(); // Update time value as long as PlusButtonA is held.
if (currentMillisPlusButtonA - previousMillisPlusButtonA > 50 && currentMillisPlusButtonA - previousMillisPlusButtonA <= 1000)
{
currentSpeedA += 0.01;
if (currentSpeedA > maxSpeedA)
{
currentSpeedA = maxSpeedA;
}
updateDisplay();
}
else if (currentMillisPlusButtonA - previousMillisPlusButtonA > 1000 && currentMillisPlusButtonA - previousMillisPlusButtonA <= 5000)
{
currentSpeedA += 0.10;
if (currentSpeedA > maxSpeedA)
{
currentSpeedA = maxSpeedA;
}
updateDisplay();
}
else if (currentMillisPlusButtonA - previousMillisPlusButtonA > 5000)
{
currentSpeedA += 1.00;
if (currentSpeedA > maxSpeedA)
{
currentSpeedA = maxSpeedA;
}
updateDisplay();
}
}
}
}
void readMinusButtonXYZ()
{
if (!digitalRead(minusButtonXYZ))
{
previousMillisMinusButtonXYZ = millis(); // Store first time value when MinusButtonXYZ was clicked.
while (!digitalRead(minusButtonXYZ))
{
currentMillisMinusButtonXYZ = millis(); // Update time value as long as MinusButtonXYZ is held.
if (currentMillisMinusButtonXYZ - previousMillisMinusButtonXYZ > 50 && currentMillisMinusButtonXYZ - previousMillisMinusButtonXYZ <= 1000)
{
currentSpeedXYZ -= 0.01;
if (currentSpeedXYZ < 0)
{
currentSpeedXYZ = 0;
}
updateDisplay();
}
else if (currentMillisMinusButtonXYZ - previousMillisMinusButtonXYZ > 1000 && currentMillisMinusButtonXYZ - previousMillisMinusButtonXYZ <= 5000)
{
currentSpeedXYZ -= 0.10;
if (currentSpeedXYZ < 0)
{
currentSpeedXYZ = 0;
}
updateDisplay();
}
else if (currentMillisMinusButtonXYZ - previousMillisMinusButtonXYZ > 5000 && currentMillisMinusButtonXYZ - previousMillisMinusButtonXYZ <= 10000)
{
currentSpeedXYZ -= 1.00;
if (currentSpeedXYZ < 0)
{
currentSpeedXYZ = 0;
}
updateDisplay();
}
else if (currentMillisMinusButtonXYZ - previousMillisMinusButtonXYZ > 10000)
{
currentSpeedXYZ -= 10.00;
if (currentSpeedXYZ < 0)
{
currentSpeedXYZ = 0;
}
updateDisplay();
}
}
}
}
void readPlusButtonXYZ()
{
if (!digitalRead(plusButtonXYZ))
{
previousMillisPlusButtonXYZ = millis(); // Store first time value when PlusButtonXYZ was clicked.
while (!digitalRead(plusButtonXYZ))
{
currentMillisPlusButtonXYZ = millis(); // Update time value as long as PlusButtonXYZ is held.
if (currentMillisPlusButtonXYZ - previousMillisPlusButtonXYZ > 50 && currentMillisPlusButtonXYZ - previousMillisPlusButtonXYZ <= 1000)
{
currentSpeedXYZ += 0.01;
if (currentSpeedXYZ > maxSpeedXYZ)
{
currentSpeedXYZ = maxSpeedXYZ;
}
updateDisplay();
}
else if (currentMillisPlusButtonXYZ - previousMillisPlusButtonXYZ > 1000 && currentMillisPlusButtonXYZ - previousMillisPlusButtonXYZ <= 5000)
{
currentSpeedXYZ += 0.10;
if (currentSpeedXYZ > maxSpeedXYZ)
{
currentSpeedXYZ = maxSpeedXYZ;
}
updateDisplay();
}
else if (currentMillisPlusButtonXYZ - previousMillisPlusButtonXYZ > 5000 && currentMillisPlusButtonXYZ - previousMillisPlusButtonXYZ <= 10000)
{
currentSpeedXYZ += 1.00;
if (currentSpeedXYZ > maxSpeedXYZ)
{
currentSpeedXYZ = maxSpeedXYZ;
}
updateDisplay();
}
else if (currentMillisPlusButtonXYZ - previousMillisPlusButtonXYZ > 10000)
{
currentSpeedXYZ += 10.00;
if (currentSpeedXYZ > maxSpeedXYZ)
{
currentSpeedXYZ = maxSpeedXYZ;
}
updateDisplay();
}
}
}
}