问题描述
这是我的问题。该程序是FSM,应控制百叶窗的步进器。大多数代码都可以正常工作,但是我无法反转步进器的方向。
方向改变应该在“状态B100”中发生,但步进器却朝着相同的方向前进。
#include <AccelStepper.h> // Stepper LIB
#include <Wire.h> // I2C LIB
#include <EEPROM.h> // EEPROM LIB
// Definiere Taster am Gehäuse
#define T1_Jalousie_down 2
#define T2_Jalousie_up 3
// Definiere Stepper Motor Verbindungen
#define EN_Stepper 6 //EN+
#define dirPin 5 //CW+
#define stepPin 4 //CLK+
// Definiere Auflösung der Umdrehungen / Schritte
#define stepsPerRevolution 1600
/* 1 = 200 S3 Off; S4 Off
1/2 = 400 S3 On; S4 Off
1/8 = 1600 S3 On; S4 On
1/16 = 3200 S3 Off; S4 On */
// Umdrehung zu bestimmten Positionen
#define Position_Unten (stepsPerRevolution * 10)
#define Winkel_geschlossen (stepsPerRevolution)
#define Winkel_Schlitz (stepsPerRevolution / 2)
#define Winkel_offen (stepsPerRevolution)
#define Manuelle_Fahrt (stepsPerRevolution / 10)
// Timer Zeiten
#define Manueller_Modus 3000
#define Manuller_Modus_Pause 3000
// Definiere stepper als Motor mit ensprechenden Pins
#define motorInterfaceType 1
AccelStepper stepper = AccelStepper(motorInterfaceType,stepPin,dirPin);
// VariablendeFinition
volatile uint16_t timer = 0; // Timer Variable für State Maschine
volatile uint8_t fheM_Befehl = 0; // xxxy = xxx% der Jalousie geschlossen; y = Öffnungswinkel (1 bis 3)
volatile uint8_t fheM_Flag = 0; // Flag wird gesetzt wenn Daten empfangen werden
volatile uint8_t Jalousie_Winkel = 0; // Öffnungswinkel der Jalousie
volatile uint8_t T1_HIGH_Flanke = 0;
volatile uint8_t T2_HIGH_Flanke = 0;
volatile uint8_t T1_LOW_Flanke = 0;
volatile uint8_t T2_LOW_Flanke = 0;
uint8_t state = B000; // State Maschine Variable in Binär
//************************************************************************************
// Initialisierung
//************************************************************************************
void setup() {
Serial.begin(9600);
// Timer konfigurieren
TCCR0A = (1 << WGM01); //Set the CTC mode
OCR0A = 0xF9; //Value for ORC0A for 1ms
TimsK0 |= (1 << OCIE0A); //Set the interrupt request
sei(); //Enable Interrupt
TCCR0B |= (1 << CS01); //Set the prescale 1/64 clock
TCCR0B |= (1 << CS00);
//I2C konfigurieren
Wire.begin(2); //I2C-Adresszuweisung: Slave 2
Wire.onReceive(receiveEvent); //Handler für das I2C-Empfangsereignis konfigurieren
Wire.onRequest(requestEvent); //Handler für das I2C-Sendeereignis konfigurieren
// Taster als INPUT konfigurieren
pinMode(T1_Jalousie_down,INPUT);
pinMode(T2_Jalousie_up,INPUT);
// Analogpin zum messen als INPUT konfigurieren
pinMode(A0,INPUT);
// ISR festlegen
attachInterrupt(digitalPinToInterrupt(T1_Jalousie_down),T1_Interrupt,CHANGE);
attachInterrupt(digitalPinToInterrupt(T2_Jalousie_up),T2_Interrupt,CHANGE);
// Eigenschaften vom Stepper Motor konfigurieren
stepper.setMaxSpeed(stepsPerRevolution);
stepper.setacceleration(stepsPerRevolution / 4);
// Pins vom Stepper Motor
pinMode(stepPin,OUTPUT);
pinMode(dirPin,OUTPUT);
pinMode(EN_Stepper,OUTPUT);
// Enable Pin konfigurieren
stepper.setEnablePin(EN_Stepper);
stepper.setPinsInverted(false,false,true);
//Setzen des Nullpunkts auf gespeicherte Position
stepper.setCurrentPosition( - EEPROM.read(0));
Jalousie_Winkel = EEPROM.read(1);
// disablen von Stepper Outputs
stepper.disableOutputs();
//digitalWrite(EN_Stepper,HIGH);
Serial.print("Position: "); Serial.println(stepper.currentPosition());
}
//************************************************************************************
// Hauptprogramm
//************************************************************************************
void loop() {
if (state != B000) {
stepper.run();
}
// State Maschine
switch(state) {
// Idle State
case B000:
stepper.stop();
stepper.disableOutputs();
if (T1_HIGH_Flanke == 1 && stepper.currentPosition() < Position_Unten) {
state = B001;
Reset_Flags();
stepper.enableOutputs();
}
if (T2_HIGH_Flanke == 1 && stepper.currentPosition() > 0) {
state = B100;
Reset_Flags();
stepper.enableOutputs();
}
if (fheM_Flag == 1) {
state = B111;
Reset_Flags();
stepper.enableOutputs();
}
break;
// Jalousie fährt bis zum Ende Runter
case B001:
stepper.moveto(Position_Unten);
if (T1_HIGH_Flanke == 1 || T2_HIGH_Flanke == 1 || stepper.distancetoGo() == 0) {
state = B000;
Reset_Flags();
}
if (T1_LOW_Flanke == 0 && timer >= Manueller_Modus) {
state = B011;
Reset_Flags();
}
break;
// Jalousie fährt manuell Runter
case B011:
stepper.moveto( ((stepper.currentPosition() + Manuelle_Fahrt) >= Position_Unten) ? Position_Unten : (stepper.currentPosition() + Manuelle_Fahrt));
if (T1_LOW_Flanke == 1 || stepper.currentPosition() == Position_Unten) {
state = B010;
Reset_Flags();
}
break;
// Jalousie fährt bis zum Ende Hoch
case B100:
stepper.moveto(0);
if (T1_HIGH_Flanke == 1 || T2_HIGH_Flanke == 1 || stepper.distancetoGo() == 0) {
state = B000;
Reset_Flags();
}
if (T2_LOW_Flanke == 0 && timer >= Manueller_Modus) {
state = B011;
Reset_Flags();
}
break;
// Jalousie fährt manuell Hoch
case B110:
stepper.moveto( ((stepper.currentPosition() - Manuelle_Fahrt) <= 0) ? 0 : (stepper.currentPosition() - Manuelle_Fahrt));
if (T2_LOW_Flanke == 1 || stepper.currentPosition() == 0) {
state = B010;
Reset_Flags();
}
break;
// Jalousie wartet auf manuelle Eingabe
case B010:
stepper.stop();
stepper.disableOutputs();
if (timer >= Manuller_Modus_Pause) {
state = B000;
Reset_Flags();
}
if (T1_HIGH_Flanke == 1 && stepper.currentPosition() < Position_Unten) {
state = B001;
Reset_Flags();
stepper.enableOutputs();
}
if (T2_HIGH_Flanke == 1 && stepper.currentPosition() > 0) {
state = B100;
Reset_Flags();
stepper.enableOutputs();
}
break;
// FEHLER!!!!
default: digitalWrite(LED_BUILTIN,HIGH); break;
}
}
//************************************************************************************
// Funktionen State Maschine
//************************************************************************************
void Reset_Flags() {
T1_HIGH_Flanke = 0;
T1_LOW_Flanke = 0;
T2_HIGH_Flanke = 0;
T2_LOW_Flanke = 0;
fheM_Flag = 0;
timer = 0;
Serial.print("State: "); Serial.print(state,BIN); Serial.println(" #######");
Serial.print("Position: "); Serial.println(stepper.currentPosition());
Serial.print("Weg dahin: "); Serial.println(stepper.distancetoGo());
Serial.print("Ziel: "); Serial.println(stepper.targetPosition());
}
//************************************************************************************
// Taster ISR
//************************************************************************************
void T1_Interrupt () {
T1_HIGH_Flanke = (digitalRead(T1_Jalousie_down) == 1) ? 1 : T1_HIGH_Flanke;
T1_LOW_Flanke = (digitalRead(T1_Jalousie_down) == 0) ? 1 : T1_LOW_Flanke;
}
void T2_Interrupt () {
T2_HIGH_Flanke = (digitalRead(T2_Jalousie_up) == 1) ? 1 : T2_HIGH_Flanke;
T2_LOW_Flanke = (digitalRead(T2_Jalousie_up) == 0) ? 1 : T2_LOW_Flanke;
}
//************************************************************************************
// Timer ISR
//************************************************************************************
ISR(TIMER0_COMPA_vect) {
timer++;
}
有人可以发现我几个小时以来一直在尝试的错误吗?
感谢所有帮助 阿德里安
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)