Ich spüre Verantwortung auf meinen Schultern ![]()
- Bei analogWrite() nutzt Du einen Ausgang mit 490 Hz. Hast Du auch schon mal einen mit 980 Hz probiert?
- Bei
analogWrite()verwendest Du 30 und 100 als Tastverhältnis. Gibt es da tatsächlich einen Geschwindigkeitsunterschied? Wenn ja, wäre ein Sanftanlauf eine sinnvolle Idee?
Kosmetik mit Typ- und Namensanpassungen:
const byte dataPin = 6;
const byte clockPin = 7;
//Motor
const byte sensorPin = 2; // Interrupt Pin (nur 2 oder 3 @ Arduino Uno)
const byte brakePin = 8; // Pinausgang Bremse, HIGH = Vollbremsung
const byte SCHLEICH_POWER = 30; // Motor-Drehzahl-Schleichgang
const byte NORMAL_POWER = 100; // Motor-Drehzahl-Normalbetrieb
const byte pwmPin = 9; // Pinausgang für Drehzahl
const byte richtungsPin = 10; // Pin Drehrichtungswechsel LOW/HIGH Drehrichtung
Wartungsfreundlichkeit:
In motorSetup() hast Du eine Schrittkette (=finite state machine; =endlicher Automat) verwendet, die man m. E. etwas deutlicher und damit servicefreundlicher schreiben kann.
- START initialisiert
- KRIECH schleicht sich an den mechanischen Anschlag, der durch Blockieren und damit wenigen Impulsen erkannt wird
- ANSCHLAG läßt sich die Bewegung am Anschlag beruhigen
- STARTPOSITION setzt die Startposition und schaltet in den Normalbetrieb
- BETRIEB sollte eigentlich nie erreicht werden. Hier könnte man die ganze Funktion
motorMatik()unterbringen, muß aber auch nicht.
Da ich die Hardware nicht habe, ein gänzlich ungetesteter Vorschlag:
//Waage
#include "HX711.h"
HX711 scale;
uint8_t dataPin = 6;
uint8_t clockPin = 7;
//Motor
const uint8_t sensorPin = 2; // Interrupt Pin (nur 2 oder 3 @ Arduino Uno)
const uint8_t brakePin = 8; // Pinausgang Bremse, HIGH = Vollbremsung
const uint8_t KRIECH_POWER = 30; // Motor-Drehzahl-Kriechgang
const uint8_t NORMAL_POWER = 100; // Motor-Drehzahl-Normalbetrieb
const uint8_t pwmPin = 9; // Pinausgang für Drehzahl
const uint8_t richtungsPin = 10; // Pin Drehrichtungswechsel LOW/HIGH Drehrichtung
const uint32_t MESSINTERVALL = 500;
const uint32_t PAUSENINTERVALL = 1000;
volatile long Counter;
volatile bool dir; // true: incr ; false: decr
bool normalbetrieb = false;
uint8_t P = 0;
void count() {
Counter += dir ? +1 : -1;
}
void motor(bool Stop, bool Richtung, int pwmSignal) {
digitalWrite (brakePin, Stop);
digitalWrite (richtungsPin, Richtung);
analogWrite (pwmPin, pwmSignal);
}
void M_Stop() {
motor(HIGH, LOW, 0);
}
void M_Hoch() {
motor(LOW, HIGH, NORMAL_POWER);
}
void M_Runter() {
motor(LOW, LOW, NORMAL_POWER);
}
//**********************************************
void setup() {
Serial.begin(9600);
//Waage
scale.begin(dataPin, clockPin);
scale.set_scale(127.15);//es wird nur der Relativwert benötigt
pinMode(dataPin, INPUT);
pinMode(clockPin , OUTPUT);
//Motor
pinMode(sensorPin, INPUT); // definiertes Potenzial (HIGH/LOW) von einem Hall-Sensor
pinMode(brakePin , OUTPUT);
pinMode(pwmPin , OUTPUT);
pinMode(richtungsPin , OUTPUT); // Drehrichtung
attachInterrupt(digitalPinToInterrupt(sensorPin), count, CHANGE);
}
//**********************************************
void loop() {
if (normalbetrieb) {
motorMatik();
} else {
motorSetup();
}
}
void motorSetup() {
uint32_t jetzt = millis();
static uint32_t setupMillis = jetzt;
enum {START, KRIECH, ANSCHLAG, STARTPOSITION, BETRIEB};
static byte schritt = KRIECH;
switch (schritt) {
case START:
Counter = 0;
dir = 1;
setupMillis = jetzt;
motor(LOW, LOW, KRIECH_POWER); //Kriechgang zum Anfahren der Endposition (Anschlag)
schritt = KRIECH;
break;
case KRIECH:
if (jetzt - setupMillis >= MESSINTERVALL) {
setupMillis = jetzt;
if (Counter < 10) {
M_Stop (); // Drehzahl sinkt am Anschlag unter (10) , der Motor stoppt
schritt = ANSCHLAG;
} else {
Counter = 0;
}
}
break;
case ANSCHLAG:
if (jetzt - setupMillis >= PAUSENINTERVALL) {
Counter = 1000; // Counter wir auf 1000 gesetzt um ein "Überfahren" in den negativen Bereich zu verhindern
motor (LOW, HIGH, NORMAL_POWER); // Richtungswechsel nach Anschlag
schritt = STARTPOSITION;
}
break;
case STARTPOSITION:
if (Counter >= 1010) {//Fahrt auf Ausgangsposition (z.B X + 10)
M_Stop ();//Setup-Phase ist beendet, Motor steht in Ausgangsposition
normalbetrieb = true;
schritt = BETRIEB;
}
break;
case BETRIEB:
break;
default:
schritt = START;
break;
}
}
void motorMatik () {
static unsigned long m_Millis;
static unsigned long m_MillisH;
uint16_t wz = analogRead(A0);
long positionM[] = {1040, 1600};
long druckPosition = map (wz, 0, 1023, 1000, 1600);
if (druckPosition > (Counter + 1) && Counter < positionM[1]) {
P = 1;
if (millis() - m_Millis >= 1000) {//Pause, um M_Hoch auslaufen zu lassen
dir = 1;
M_Runter();//Druck läßt nach
m_MillisH = millis();
} else {
M_Stop();
}
}
else if (druckPosition < (Counter - 1) && Counter > positionM[0] ) {
P = 2;
if (millis() - m_MillisH >= 1000) {//Pause, um M_Runter auslaufen zu lassen
dir = 0;
M_Hoch();//Druck steigt
m_Millis = millis();
} else {
M_Stop();
}
}
else {
m_Millis = millis();
m_MillisH = millis();
M_Stop();
P = 3;
}
Serial.print("druckPosition: "); Serial.print(druckPosition);
Serial.print("\t Counter: "); Serial.print(Counter);
Serial.print("\t P_Position: "); Serial.print(P);
Serial.print("\t m_MillisH: "); Serial.print(m_MillisH);
/*
Serial.print("\t millis: ");
Serial.print(millis());
Serial.print("\t m_Millis: ");
Serial.print(m_Millis);
// */
Serial.println();
}
Du wirst sicherlich den bisherigen Ablauf wiedererkennen und kleine Fehler von mir korrigieren können.
Interessiert Dich mein Vorschlag?