Go Down

Topic: Problem: Steuerung eines Schrittmotors mit Lichtsensor + Taster (Read 367 times) previous topic - next topic

FabianW

Hallo Zusammen,
ich bin grade dabei einen Schrittmotor mit Hilfe eines Lichtsensors und eines Tasters anzusteuern.
Nachdem ich das Internet auf den Kopf gestellt habe bin ich jetzt an meine Grenzen gekommen und hoffe dass ihr mir weiter helfen könnt.

Mein Ziel ist es die unten im Code beschriebenen Aktionen durchzuführen. Leider dreht der Schrittmotor momentan fröhlich vor sich hin und reagiert weder auf den Taster noch auf Schwellwert des Potis. Während der Schrittmotor dreht reagiert außerdem die LCD Anzeige nicht mehr...

Wäre cool wenn mir jmd. helfen könnte, habe grad ein paar Knoten zu viel im Hirn! :smiley-confuse:

Gruß, Fabian
 
Code: [Select]
int Lichtstaerke;
int Lichtstaerkestore;
int LEDPin = 13;
int Potiwert;
int Potistore;

int Pin1 = 7;
int Pin2 = 8;
int Pin3 = 9;
int Pin4 = 10;

const int Taster1 = 5;
int Taster1State = 0; // Variable zum Erkennen des TasterStatus

#include <LiquidCrystal.h>
const int rs = 12, en = 11, d4 = 6, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

#include <Stepper.h>
const int SPR = 2048;
Stepper Motor(SPR, 7, 8, 9, 10);

/////////////////////////////////////////////////
void setup() {
Serial.begin(9600);

// LED
pinMode(LEDPin,OUTPUT);
 
// Motor
pinMode(Pin1, OUTPUT);
pinMode(Pin2, OUTPUT);
pinMode(Pin3, OUTPUT);
pinMode(Pin4, OUTPUT);

Motor.setSpeed(10);

// LCD
lcd.begin(16, 2);
lcd.print("Lichtstaerke");
lcd.setCursor(0,1);
lcd.print("Schwellwert");

// Taster
pinMode(Taster1,INPUT);
}

/////////////////////////////////////////////////
void loop() {
 
  Potiwert = analogRead(1) / 10;
  Serial.println(Potiwert);

  Lichtstaerke = analogRead(0) / 20; 
  Serial.println(Lichtstaerke);

  Taster1State = digitalRead(Taster1);

////// DARSTELLUNG LCD ////////////////////////
  lcd.setCursor(13,0);
  lcd.leftToRight();
  lcd.print(Lichtstaerke,DEC);
 
  if (Lichtstaerkestore != Lichtstaerke)
  {
    lcd.setCursor(13,0); lcd.print(Lichtstaerke); // Variable ausgeben
    if (Lichtstaerke < 10) lcd.print("  ");      // 2 Leerzeichen
    else if (Lichtstaerke < 100) lcd.print(" "); // 1 Leerzeichen
  }
  Lichtstaerkestore = Lichtstaerke;
 
  delay(300);
  lcd.setCursor(13,1);
  lcd.leftToRight();
  lcd.print(Potiwert,DEC);

  if (Potistore != Potiwert)
  {
    lcd.setCursor(13,1); lcd.print(Potiwert); // Variable ausgeben
    if (Potiwert < 10) lcd.print("  ");      // 2 Leerzeichen
    else if (Potiwert < 100) lcd.print(" "); // 1 Leerzeichen
  }
  Potistore = Potiwert;
////// Ende DARSTELLUNG LCD ///////////////////////

/// Ab hier fangen meine Probleme an:
/// Steuerung des Motors / LED in Abhängikeit zu dem Lichtsensor + Taster

  if (Lichtstaerke <= Potiwert) /// Sobald der Wert der Lichtstärke kleiner/gleich des Potiwertes ist...
  {
  digitalWrite(LEDPin,HIGH);    /// ...geht die LED an
  Motor.step(2048);             /// ... & der Motor beginnt an zu drehen. (Umdrehungen in vorerst in Steps angegeben)
    if (Taster1State = HIGH)    /// Wenn der Taster gedrückt wird...
    {
    Motor.step(0);              /// ... soll der Motor stoppen.(LED bleibt an)
    }
  }

  if (Lichtstaerke >= Potiwert) /// Sobald der Wert der Lichtstärke größer/gleich des Potiwertes ist...
  {
  digitalWrite(LEDPin,LOW);     /// ...geht die LED aus
  Motor.step(2048);             /// ... & der Motor beginnt an zu drehen. (Umdrehungen in vorerst in Steps angegeben)
    if (Taster1State = HIGH)    /// Wenn der Taster gedrückt wird...
    {
    Motor.step(0);              /// ... soll der Motor stoppen.(LED bleibt aus)
    } 
  }
}

FabianW

Vlt. trägt es zu Verständnis bei, wenn ich kurz die Anwendung beschreibe:

Tür Steuerung eines Hühnerstalls.

Wenn es dunkel wird soll sich die Klappe schließen.
(Die Klappe ist angetrieben durch den Schrittmotor, sobald die Klappe zu ist wird ein Taster aktiviert und der Schrittmotor ausgeschaltet.)

Wenn es hell wird soll sich die Klappe öffnen.
(Sobald die Klappe offen ist wird ein Taster aktiviert und der Schrittmotor ausgeschaltet.)

Der Schwellwert soll über einen Poti eingestellt werden.

Tommy56

Die Stepper-Lib blockiert das Programm solange, wie der Motor läuft. In der Zeit werden keine anderen Aktionen ausgeführt. Während delay() übrigens auch nicht.
Während dieser Zeit wird auch kein Taster gelesen.

Probiere mal lieber die Lib AccelStepper, die blockiert nicht.

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

FabianW


FabianW

Habe jetzt die AccelStepper Lib in Gebrauch. Das LCD Display ist nicht mehr eingefroren und der Sensor arbeitet auch wieder so wie er soll.  :)
Leider bewegt sich der Motor nicht mehr...   :smiley-sad-blue:

Code: [Select]
int Lichtstaerke;
int Lichtstaerkestore;
int LEDPin = 13;
int Potiwert;
int Potistore;

int Pin1 = 7;
int Pin2 = 8;
int Pin3 = 9;
int Pin4 = 10;

const int Taster1 = 5;
int Taster1State = 0; // Variable zum Erkennen des TasterStatus

#include <LiquidCrystal.h>
const int rs = 12, en = 11, d4 = 6, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

#include <AccelStepper.h>
AccelStepper Motor(AccelStepper::FULL4WIRE, 7, 8, 9, 10);

/////////////////////////////////////////////////
void setup() {
Serial.begin(9600);

// LED
pinMode(LEDPin,OUTPUT);
 
// Motor
pinMode(Pin1, OUTPUT);
pinMode(Pin2, OUTPUT);
pinMode(Pin3, OUTPUT);
pinMode(Pin4, OUTPUT);



Motor.setSpeed(15);

// LCD
lcd.begin(16, 2);
lcd.print("Lichtstaerke");
lcd.setCursor(0,1);
lcd.print("Schwellwert");

// Taster
pinMode(Taster1,INPUT);
}

/////////////////////////////////////////////////
void loop() {
 
  Potiwert = analogRead(1) / 10;
  Serial.println(Potiwert);

  Lichtstaerke = analogRead(0) / 20; 
  Serial.println(Lichtstaerke);

  Taster1State = digitalRead(Taster1);

////// DARSTELLUNG LCD ////////////////////////
  lcd.setCursor(13,0);
  lcd.leftToRight();
  lcd.print(Lichtstaerke,DEC);
 
  if (Lichtstaerkestore != Lichtstaerke)
  {
    lcd.setCursor(13,0); lcd.print(Lichtstaerke); // Variable ausgeben
    if (Lichtstaerke < 10) lcd.print("  ");      // 2 Leerzeichen
    else if (Lichtstaerke < 100) lcd.print(" "); // 1 Leerzeichen
  }
  Lichtstaerkestore = Lichtstaerke;
 
  delay(300);
  lcd.setCursor(13,1);
  lcd.leftToRight();
  lcd.print(Potiwert,DEC);

  if (Potistore != Potiwert)
  {
    lcd.setCursor(13,1); lcd.print(Potiwert); // Variable ausgeben
    if (Potiwert < 10) lcd.print("  ");      // 2 Leerzeichen
    else if (Potiwert < 100) lcd.print(" "); // 1 Leerzeichen
  }
  Potistore = Potiwert;
////// Ende DARSTELLUNG LCD ///////////////////////

/// Ab hier fangen meine Probleme an:
/// Steuerung des Motors / LED in Abhängikeit zu dem Lichtsensor + Taster

  if (Lichtstaerke <= Potiwert) /// Sobald der Wert der Lichtstärke kleiner/gleich des Potiwertes ist...
  {
  digitalWrite(LEDPin,HIGH);    /// ...geht die LED an
  Motor.run();             /// ... & der Motor beginnt an zu drehen. (Umdrehungen in vorerst in Steps angegeben)
    if (Taster1State = HIGH)    /// Wenn der Taster gedrückt wird...
    {
    Motor.stop();              /// ... soll der Motor stoppen.(LED bleibt an)
    }
  }

  if (Lichtstaerke >= Potiwert) /// Sobald der Wert der Lichtstärke größer/gleich des Potiwertes ist...
  {
  digitalWrite(LEDPin,LOW);     /// ...geht die LED aus
  Motor.run();             /// ... & der Motor beginnt an zu drehen. (Umdrehungen in vorerst in Steps angegeben)
    if (Taster1State = HIGH)    /// Wenn der Taster gedrückt wird...
    {
    Motor.stop();              /// ... soll der Motor stoppen.(LED bleibt aus)
    } 
  }
}

Tommy56

Da könnten evtl. Infos zum Motor weiter helfen. Evtl. braucht der was anderes als FULL4WIRE.

Übrigens: Diskussionen zu Hühnerklappensteuerungen gib es hier im Forum schon.

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

FabianW

Ich versuche mir mit diesem Projekt Arduino beizubringen, daher habe ich mir die bereits erarbeiteten Lösungen für Hühnerklappen noch nicht näher angeschaut. Ich versuche das ganze Schritt für Schritt zu verstehen und nicht einfach nach zu basteln...

Auf dem Motor steht Step Motor 28BY-48 5V DC 61018209 (Der soll aber später ausgetauscht werden, da zu schwach)

agmue

Auf dem Motor steht Step Motor 28BY-48
Das ist ein unipolarer Motor, vertausche mal die Anschlüsse an Pin 8 und 9.

FabianW

Das ist ein unipolarer, vertausche mal die Anschlüsse an Pin 8 und 9.

leider keine Veränderung...

agmue

Was tut der Motor zusammen mit einem Testsketch der Bibliothek, beispielsweise Random?

FabianW

Was tut der Motor zusammen mit einem Testsketch der Bibliothek, beispielsweise Random?
Er dreht minimal sobald die Impulse schnell hintereinander kommen. Die LED des Treibers leuchten immer in der Reihenfolge ACBD

FabianW

Tausche ich die Pins 8 und 9, so wie du vorgeschlagen hast, dreht der Motor vor und zurück (zwar minimal aber er macht es) Eine Reihenfolge der LED's kann ich nicht erkennen, es wechseln zumindest immer 2 auf einmal.

Mir erscheint diese Variante richtiger als die zuvor...
in meinem Haupt sketch klappt es leider dennoch nicht... Hab ich vlt einen Fehler in der If Funktion?

postmaster-ino

Hi

Der unipolare Schrittmotor möchte, wenn ich mich recht entsinne, in folgender Reihenfolge haben:
0101
0110
1010
1001

Entspricht aber halbwegs Deinem oben genanntem ACBD.
Die linken zwei Bits sind für das eine Spulenpaar, somit die Anderen für das andere Paar.

Würde Das ganz ohne Lib im 100ms-Takt ausgeben und erst Mal schauen, daß der Stepper zum Drehen kommt.
Dir sollte aber jetzt schon klar sein, daß ein 'richtiger' Stepper mit diesem Code nicht laufen wird.
Vll. kannst Du den Stepper ja noch weiter untersetzen - dann braucht die Hühnerklappe halt etwas länger, bis Diese oben oder unten angekommen ist - wobei diese Motörchen eben keine Kraftprotze sind (habe davon auch ein halbes Dutzend hier rumfliegen, aber auch erst zwei Mal mit 'gespielt' - mindestens einen Motor 'gehackt', also rote Draht raus und die Leiterbahn-Verbindung zwischen den Mittelanzapfungen aufgetrennt)

MfG

agmue

(zwar minimal aber er macht es)
Das ist gut! Du hast einen Motor, der wegen des Getriebes etwas andere Werte benötigt. Versuche mal dies:

Code: [Select]
#include <AccelStepper.h>

// Define a stepper and the pins it will use
AccelStepper stepper(AccelStepper::FULL4WIRE, 7, 8, 9, 10);

void setup()
{
    stepper.setMaxSpeed(1000);
    stepper.setAcceleration(1000);
}

void loop()
{
  if (stepper.distanceToGo() == 0)
  {
    // Random change to speed, position and acceleration
    // Make sure we dont get 0 speed or accelerations
    delay(1000);
    stepper.move(2048);
  }
  stepper.run();
}


run() muß durchlaufen werden, wenn eine Bewegung erfolgen soll
move (long relative) Relative Bewegung ab der aktuellen Position
moveTo (long absolute) Bewegung zu einer absoluten Position.

Nun sollte der Motor eine Umdreheung machen, dann Pause, dann wieder eine Umdreheung usw.

Tut er das?

FabianW

Danke für euer Feedback! Für heute ist Schluss. Ich werde es morgen Abend mal testen.

Go Up