Da der Analog-Digital-Converter (ADC) um ein Bit zappelt, und bei echten Sensoren evtl. ein noch größeres Rauschen nicht zu vermeiden ist, kann man das Beispiel etwas modifizieren:
Der Trick ist, dass static bewirkt dass die Variable Ihren Wert behält,
und dass das = in der Definition kein normaler Zuweisungsoperator, sondern nur die Erst-Initialisierung ist.
Danke für die ausführliche Antwort.
bei mir handelt es sich um ein Drehprotentiometer und die Skalierung der Wert auf 0 bis 100 funktioniert ganz gut ohne eine Hysterese einzubauen.
wie kann ich den Wert "PreviusValue" speichern um mit dem momentanen "Value" zu vergleichen.
while(true) {
int Value = analogRead(0);
Value = map(Value, 0, 1023, 0, 100);
Serial.println(Value);
if (Value<10) {
digitalWrite(dirPin, HIGH); // HIGH = Vorwärts, LOW = Rückwärts
digitalWrite(stepPin, HIGH);
delayMicroseconds(1000); // Pulsdauer
digitalWrite(stepPin, LOW);
delayMicroseconds(100); // Pause zwischen den Pulsen
}
if (Value>60) {
digitalWrite(dirPin, LOW); // HIGH = Vorwärts, LOW = Rückwärts
digitalWrite(stepPin, HIGH);
delayMicroseconds(1000); // Pulsdauer
digitalWrite(stepPin, LOW);
delayMicroseconds(100); // Pause zwischen den Pulsen
}
}
}
static int previousValue;
int Value = map(analogRead(A0),0,1024,0,100); // auf 100 Werte ( 0 .. 99 ) normiert
if ( Value != previousValue ) {
previousValue = Value;
// hier nur einmal bei einer Änderung
}
Wenn du die Bedeutung von static nicht lernen willst, kannst du stattdessen auch eine globale Variable nehmen.
Sorry alle, aber das hat wirklich nichts mit wollen zu tun. Ich bin eher ein SPS Programmierer und hatte bis vor 3 Tage mit c++ nicht viel zu tun gehabt.
ich habe nun den Code angepasst. Folgendes sollte passieren.
wenn der Value steigt, dann fahre ich den Motor Vorwärts
wenn der Value abfällt, dann fahre ich Motor Rückwärts.
leider funktioniert das aber nicht wirklich.
// Pin Definitionen
const int dirPin = 8;
const int stepPin = 9;
const int enPin = 7;
static int previousValue;
int Value = map(analogRead(A0), 0, 1023, 0, 100);
void setup() {
// start Serial for Poti
Serial.begin(9600);
// Setze die Pin-Modi
pinMode(dirPin, OUTPUT);
pinMode(stepPin, OUTPUT);
pinMode(enPin, OUTPUT);
// Aktiviere den Treiber
digitalWrite(enPin, LOW);
}
void loop() {
// put your main code here, to run repeatedly:
while(true) {
if (Value<previousValue) {
digitalWrite(dirPin, HIGH); // HIGH = Vorwärts, LOW = Rückwärts
digitalWrite(stepPin, HIGH);
delayMicroseconds(1000); // Pulsdauer
digitalWrite(stepPin, LOW);
delayMicroseconds(100); // Pause zwischen den Pulsen
}
if (Value>previousValue) {
digitalWrite(dirPin, LOW); // HIGH = Vorwärts, LOW = Rückwärts
digitalWrite(stepPin, HIGH);
delayMicroseconds(1000); // Pulsdauer
digitalWrite(stepPin, LOW);
delayMicroseconds(100); // Pause zwischen den Pulsen
}
}
}
Ist Dir klar, was Du da programmiert hast? Denk mal darüber nach. Dann kommt Dir vielleicht in den Sinn, warum das nicht funktionieren kann.
Googel mal nach C/C++ und Gültigkeitsbereich von Variablen. Was ist eine Zuweisung und was macht while(true) ?
Mal abgesehen davon, dass Dir schon gesagt wurde, der Ausdruck while(true) ist fehl am Platze weil schon void loop() wie eine Endlosschleife funktioniert.
Hier ist ein einfaches Beispiel, bei dem ein Schrittmotor entsprechend der Potentiometer Stellung bewegt wird. Eine volle Umdrehung ist möglich.
//
// Globale Konstanten definieren
//
constexpr byte DIR_PIN {4};
constexpr byte STEP_PIN {5};
constexpr byte ANALOG_PIN {A0};
constexpr unsigned int STEPS_PER_REVOLUTION {200};
constexpr unsigned int STEPPER_DELAY_US {2000}; // Mikroskunden!
// Struktur für die Daten, die zur Steuerung des Steppers erforderlich sind deklarieren
struct Steps {
unsigned int analogValue;
unsigned int prevAnalogValue;
unsigned int position;
unsigned int count;
};
//
// Feststellen ob eine Bewegung im Uhrzeigersinn (CW) oder Gegenuhrzeigersinn (CCW)
// erforderlich ist. Das Ergebnis ist abhängig von dem gemessenen Potentiometerwert
//
void prepareSteps(byte pin, Steps& st) {
if (st.analogValue > st.prevAnalogValue) {
digitalWrite(pin, HIGH);
st.count = st.analogValue - st.position;
st.position += st.count;
} else {
digitalWrite(pin, LOW);
st.count = st.position - st.analogValue;
st.position -= st.count;
}
st.prevAnalogValue = st.analogValue;
}
//
// Den Schrittmotor um die errechnete Anzahl an Schritten CW oder CCW bewegen.
//
void driveStepper(byte pin, unsigned int stepCount) {
for (size_t x = 0; x < stepCount; ++x) {
digitalWrite(pin, HIGH);
delayMicroseconds(STEPPER_DELAY_US);
digitalWrite(pin, LOW);
delayMicroseconds(STEPPER_DELAY_US);
}
}
void setup() {
pinMode(STEP_PIN, OUTPUT);
pinMode(DIR_PIN, OUTPUT);
}
void loop() {
static Steps steps {0, 0, 0, 0}; // Strutur anlegen und Member mit 0 initialisieren.
// Potentiometerwert lesen und auf die maximale Schrittzahl für eine Umdrehung des
// Steppermotors umrechnen.
steps.analogValue = map(analogRead(ANALOG_PIN), 0, 1023, 0, STEPS_PER_REVOLUTION);
// Wenn sich der gelesenen Analogwert verändert hat den Stepper entsprechend bewegen.
if (steps.analogValue != steps.prevAnalogValue) {
prepareSteps(DIR_PIN, steps);
driveStepper(STEP_PIN, steps.count);
}
}