Arduino AccelStepper库/更改方向

问题描述

这是我的问题。该程序是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 (将#修改为@)