Go Down

Topic: Chipsmaschine (Read 736 times) previous topic - next topic

postmaster-ino

Hi

Ob die Lichtschranke nun eine Gabel-Form hat, oder Sender/Empfänger sich nicht im gleichen Gehäuse befinden, dürfte für die Programmiererei unerheblich sein.

Was Du willst:
Erkennen, wenn Chips die Lichtschranke DAUERHAFT blockieren.
Ob die Lichtschranke JETZT GERADE unterbrochen ist, ist kein Hexenwerk, die Dauerhaftigkeit ist nur, eine bestimmte Zeit später immer noch nicht durchgucken zu können - und dafür willst Du KEIN delay() verwenden - da dann auch zwei nacheinander fallende Chips irrtümlich als 'noch immer blockiert' erkannt werden könnten.

MALE Dir auf, was Du wie machen willst - und programmiere Das nach.
Bei Problemen Beides hier hin - Dein Ablauf-Diagramm (Was wann wie und warum) wie auch Dein Sketch.

MfG

PS: Dir ist bewusst, daß besagte Markenchips nur immer die gleiche Form haben, da dort nicht wirklich Kartoffeln zum Einsatz kommen?
Oder Anders: Geprestes 'was halt so an den Maschinen vorbei fällt' für extra teuer zu verkaufen, ist eine Kunst, Die ich nie beherrschen werde ...
Und: Lass Dir den Appetit nicht verderben - kann halt nicht Jeder Alles mögen (oder dafür sein)
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

Rahmschnitzel

https://www.funduinoshop.com/epages/78096195.sf/de_DE/?ObjectPath=/Shops/78096195/Products/KT-10%2611


FÜr diese. Habe die 2 Mal.

Eine Lichtschranke soll angeben, ob der Füllstand erreicht ist. Also darf die nicht losgehen sobald ein Chips durchgeflogen ist, sondern erst wenn die Chipsmenge den Stand erreicht haben.
Ich bin damit leider schon überfordert und bitte um Hilfe :/


postmaster-ino

Hi

Das siehst Du falsch :)
Die Lichtschranke soll schon DIREKT melden, wenn Da Was im Weg ist.
Du willst aber einfach nur erst drauf reagieren, wenn diese Meldung länger als eine Sekunde ansteht.
Sobald die Lichtschranke unterbrochen ist, wird geprüft, ob seit dem letzten 'Frei' genügend Zeit vergangen ist für die Meldung, daß Da wohl was liegt.
Sobald die Lichtschranke frei ist, wird sich diese 'Frei'-Zeit gemerkt - also immer und immer wieder, bis die Lichtschranke wirklich länger unterbrochen ist.
Erst dann , die 'Frei'-Zeit wird nicht erneut auf die aktuelle Zeit gesetzt, kann sich eine Differenz-Zeit ergeben, Die Du mittels
if (millis()-freizeit>=wartezeit){
  //Da liegt was im Weg
}
abfragst.

MfG
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

arduarn

Fang mit dem Beispiel im Online-Shop an: Empfänger vebinden und mit einer Fernseher-Fernbedienung testen.

Danach: Ken Shirriff selber hat´s (auf Englisch) beschrieben, wie es weitergeht.
Ich würde persönlich einen höherwertigen Widerstand verwenden (zB. 400R). Du darfst nicht 20mA überschreiten.

Rahmschnitzel

Das ist momentan mein Sketch. Könnte das so funktionieren?


int UnterbrochenOben=0; //Unter der Variablen "messwert" wird später der Messwert der Lichtschranke gespeichert. Lichtschranke Obem
long startTime; // millis-Wert beim ersten Drücken der Taste  Lichtschranke Oben
long duration;  // Variable für die Dauer. Lichtschranke Oben
const long wartezeit= 1;

void setup() {
 
Serial.begin(9600); //Die Kommunikation mit dem seriellen Port wird gestartet. Das benötigt man, um sich den ausgelesenen Wert im serial monitor anzeigen zu lassen. Lichtschranke Oben
}

void loop() {
UnterbrochenOben=digitalRead(8); //Die Signalausgabe der Lichtschranke wird ausgelesen und unter der Variable „messwert" gespeichert.
                                 //Wenn die Lichtschranke unterbrochen wird, speichert der Mikrocontroller den Wert "1", ansonsten "0". Lichtschranke Oben
 if(digitalRead(8) == UnterbrochenOben)
 {
    // Sobald die Taste gedrückt wurde
    startTime = millis();
    while(digitalRead(8) == UnterbrochenOben)
       ; // Warten, solange die Taste gedrückt wird
    long duration = millis() - startTime;
     if (millis()- duration >= wartezeit){



     
     }
 
 }
 
}

Tommy56

Setze Deinen Code bitte in Codetags (</>-Button oben links im Forumseditor oder [*code] davor und [*/code] dahinter ohne *).
Das kannst Du auch noch nachträglich ändern.

Entferne bitte auch unnötige Leerzeilen und formatiere den Code ordentlich. <Strg>+T in der IDE hilft Dir dabei.

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

Rahmschnitzel

Code: [Select]

int UnterbrochenOben = 0; //Unter der Variablen "messwert" wird später der Messwert der Lichtschranke gespeichert. Lichtschranke Oben
long startTime; // millis-Wert beim ersten Drücken der Taste  Lichtschranke Oben
long duration;  // Variable für die Dauer. Lichtschranke Oben
const long wartezeit = 1;

void setup() {

  Serial.begin(9600); //Die Kommunikation mit dem seriellen Port wird gestartet. Das benötigt man, um sich den ausgelesenen Wert im serial monitor anzeigen zu lassen. Lichtschranke Oben
}

void loop() {
  UnterbrochenOben = digitalRead(8); //Die Signalausgabe der Lichtschranke wird ausgelesen und unter der Variable „messwert" gespeichert.
  //Wenn die Lichtschranke unterbrochen wird, speichert der Mikrocontroller den Wert "1", ansonsten "0". Lichtschranke Oben
  if (digitalRead(8) == UnterbrochenOben)
  {
    // Sobald die Taste gedrückt wurde
    startTime = millis();
    while (digitalRead(8) == UnterbrochenOben)
      ; // Warten, solange die Taste gedrückt wird
    long duration = millis() - startTime;
    if (millis() - duration >= wartezeit) {




    }

  }

}

postmaster-ino

Hi

Was soll Das:
Code: [Select]
UnterbrochenOben = digitalRead(8);
  if (digitalRead(8) == UnterbrochenOben){
...

Würde mich schwer wundern, wenn Du vorhersagbar NICHT in die IF-Abfrage kommst.
Dein delay() inerhalb der IF dürfte stören - oder wird der Stepper, Der für Nachschub sorgt, nicht von Diesem Arduino angesteuert?

Dachte ungefähr so:
Code: [Select]

If (Lichtschranke frei){
   lastfree=millis();
   schonerkannt=false;  //wenn die LS frei ist, kann Die noch nicht als 'lange genug geschlossen' erkannt worden sein
}
if (millis()-lastfree>wartezeit && schonerkannt==false){
   Serial.print("AAAaaarrrggg");
   schonerkannt=true;
}

Hätte auch den Vorteil, daß der Arduino zwischenzeitlich den Förder-Stepper befehligen kann.

MfG

PS: lastfree und wartezeit gerne als unsigned long - wir erwarten keine negativen Werte und wenn doch Welche kommen, stören Die nur.
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

Rahmschnitzel

Ich habe den ersten Motor nun hinzugefügt und versucht

 
Code: [Select]

If (Lichtschranke frei){
   lastfree=millis();
   schonerkannt=false;  //wenn die LS frei ist, kann Die noch nicht als 'lange genug geschlossen' erkannt worden sein
}
if (millis()-lastfree>wartezeit && schonerkannt==false){
   Serial.print("AAAaaarrrggg");
   schonerkannt=true;
}


umzusetzen. Hast du das so gemeint?


Rahmschnitzel

Code: [Select]


#include <Wire.
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"

Adafruit_MotorShield AFMS = Adafruit_MotorShield();

Adafruit_StepperMotor *myMotor = AFMS.getStepper(200, 1);


int UnterbrochenOben = 0; //Unter der Variablen "messwert" wird später der Messwert der Lichtschranke gespeichert. Lichtschranke Oben
long startTime; // millis-Wert beim ersten Drücken der Taste  Lichtschranke Oben
long duration;  // Variable für die Dauer. Lichtschranke Oben
const long wartezeit = 1;

void setup() {

  Serial.begin(9600); //Die Kommunikation mit dem seriellen Port wird gestartet. Das benötigt man, um sich den ausgelesenen Wert im serial monitor anzeigen zu lassen. Lichtschranke Oben
  AFMS.begin();
  myMotor->setSpeed(200);
}


void loop() {
  UnterbrochenOben = digitalRead(8); //Die Signalausgabe der Lichtschranke wird ausgelesen und unter der Variable „messwert" gespeichert.
  //Wenn die Lichtschranke unterbrochen wird, speichert der Mikrocontroller den Wert "1", ansonsten "0". Lichtschranke Oben
 
 if (UnterbrochenOben == 0){
   lastfree=millis();
   schonerkannt=false;  //wenn die LS frei ist, kann Die noch nicht als 'lange genug geschlossen' erkannt worden sein
}
if (millis()-lastfree>wartezeit && schonerkannt==false){
 
   schonerkannt=true;


      delay(1);

    }else{
      Motor.step(2048); // Der Motor macht 2048 Schritte, das entspricht einer Umdrehung.

    }

  }

}


postmaster-ino

Hi

Wenn ich den SKetch richtig verstehe, blockiert die Motoransteuerung den Ablauf?
Also, während der Motor die 2048 Schritte macht ('riecht' nach einem 28BYJ-48) kann die Lichtschranke tun und lassen, was Sie will - daran ändert Sich Nichts?

Wenn Du pro Motorumdrehung einen Chip in das Rohr wirfst, kannst Du Das auch so machen - selber benutzte ich dafür die AccelStepper, dort kannst Du den Zielpunkt angeben (hier halt 2048, für die nächsten Runde 4096, ...) und der Motor dreht (mit Rampen, wenn gewünscht), bis Er am Ziel angekommen ist.
GLEICHZEITIG kannst Du den Rest in Deinem Programm machen.

Die Umsetzung sieht soweit brauchbar aus.

Mit STRG+T in der IDE und dem Löschen unnötiger Leerzeilen kommt Das raus:
Code: [Select]
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"

Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_StepperMotor *myMotor = AFMS.getStepper(200, 1);

int UnterbrochenOben = 0; //Unter der Variablen "messwert" wird später der Messwert der Lichtschranke gespeichert. Lichtschranke Oben
long startTime; // millis-Wert beim ersten Drücken der Taste  Lichtschranke Oben
long duration;  // Variable für die Dauer. Lichtschranke Oben
const long wartezeit = 1;

void setup() {
  Serial.begin(9600); //Die Kommunikation mit dem seriellen Port wird gestartet. Das benötigt man, um sich den ausgelesenen Wert im serial monitor anzeigen zu lassen. Lichtschranke Oben
  AFMS.begin();
  myMotor->setSpeed(200);
}

void loop() {
  UnterbrochenOben = digitalRead(8); //Die Signalausgabe der Lichtschranke wird ausgelesen und unter der Variable „messwert" gespeichert.
  //Wenn die Lichtschranke unterbrochen wird, speichert der Mikrocontroller den Wert "1", ansonsten "0". Lichtschranke Oben
  if (UnterbrochenOben == 0) {
    lastfree = millis();
    schonerkannt = false; //wenn die LS frei ist, kann Die noch nicht als 'lange genug geschlossen' erkannt worden sein
  }
  if (millis() - lastfree > wartezeit && schonerkannt == false) {
    schonerkannt = true;
    delay(1);
  } else {
    Motor.step(2048); // Der Motor macht 2048 Schritte, das entspricht einer Umdrehung.
  }
}

//} <-- Das ist zu viel !!

Die letzte Klammer ist bei mir zu viel, oben bei wire. fehlt h>
Mir fehlt die Adafruit_Motorshield - weshalb der Sketch bei mir nicht kompiliert.

Schau Dir Mal mein Beispiel zum 28BYJ-48 (bzw Deren Zwei) an:
MultiStepper-Beispiel der AccellStepper Library mit 28BYJ-48 5V Stepper
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

Rahmschnitzel

Wenn ich den SKetch richtig verstehe, blockiert die Motoransteuerung den Ablauf?
Also, während der Motor die 2048 Schritte macht ('riecht' nach einem 28BYJ-48) kann die Lichtschranke tun und lassen, was Sie will - daran ändert Sich Nichts?


Der Motor soll immer laufen, außer der Füllstand ist erreicht. Dann soll er Pause machen und wenn der Stand wieder gesunken ist, weiter arbeiten.

Ich habe einen Nema 17 Motor.

Und es pro Umdrehung können unterschiedlich viele Chips ins Rohr fallen, denn es ist eine Scheibe, in der mehrere Löcher sind. Also wäre es am besten, dass der Motor sofort stopp und nicht noch erst die Umdrehung fertig macht. Jedoch habe ich das nicht hinbekommen.

postmaster-ino

Hi

Dann schaue Dir die AccelStepper aus der IDE an (sonst lässt sich Diese in der IDE nachinstallieren).
Dort dann die Beispiele dazu - oder meinen Versuchs-Sketch im oben verlinktem Thread.
Dort musst Du dann aber die Pins anpassen, wenn Du Richtung/Takt (Dir/Puls) hast, wäre Das 2-wire, bei 4-wire entfällt die 'Vertauschung' der mittleren Pins, Die ich für die 28BYJ-48 benutze - ist aber kommentiert.
Spiele mit dem Sketch Mal herum - mittels L/R kannst Du einen Dauerlauf links/rechts herum starten, mit G/S 'Go' starten oder 'S'toppen - mit h wird eine kleine Hilfe ausgegeben.

Die Stepper werden in JEDEM loop()-Durchlauf angesteuert - zumindest, wenn's einen Schritt zu Machen gibt.
Auch kannst Du dem Motor sagen, daß Er dort stehen bleiben soll, wo Er gerade ist (einfach die IST-Position als Soll-Position übergeben oder eine relative Entfernung von Null).

Die AcellStepper blockiert nicht - wenn halt gerade kein Step auszuführen ist, macht die Lib ... Nichts.
So wird die loop() immer möglichst schnell durchlaufen - Du kannst Deine Lichtschranke prüfen oder lustig LEDs blinken lassen - was einem so in den Kopf kommt.

MfG

PS: Durch die langsame Abarbeitung der seriellen Schnittstelle sind einige Sprünge im Motorlauf möglich - entweder die Serielle schneller machen, oder diverse Ausgaben rauswerfen sollte helfen.
Zum 'bisschen Spielen' sollte der Sketch aber durchaus brauchbar sein.
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

Rahmschnitzel

Da rall' ich leider gar nichts mehr :(

Ich erkläre einfach nochmal die Lage und vllt. kannst du mir eine Passende Lösung sagen :D.

Ich habe eine Maschiene die Oben einen Nema-17 Motor hat, der eine Scheibe betreibt, in der Löcher sind und durch die Wertmarken in ein Rohr einzeln fliegen. An einer bestimmten Stelle des Rohrs, liegt eine Lichtschranke vor, die dem Motor oben sagen soll, wenn so viele Chips in dem Rohr sind, dass die Lichtschranke erreicht ist, der Motor oben sofort pausiert und erst weiter dreht, wenn die Fülllinie unterschritten wird.

Da ich noch einen zweiten Nema-17 Motor habe, der die Chips aus dem Rohr befördert (per Schieber), benutze ich ein Motorshield.

Dieser Sketch MUSS funktionieren und zwar leider ziemlich bald schon, denn dies ist ein Schulprojekt, welches ich bald vorstellen muss.
Da wir in der Schule noch nicht mit einem Arduino gearbeitet haben, muss ich mir alles selber beibringen, deshalb verzeiht mir meine Unerfahrenheit.

Ich bräuchte konkrete Lösungen/Hilfen, um mein aktuelles Problem, die Verbindung der Lichtschranke und des oberen Motors, zu lösen.


Vielen Dank für die bereits geschriebenen, aber auch für die noch kommenden, Kommentare.

postmaster-ino

Hi

Du hast 2 Stepper?
Diese sollen gleichzeitig laufen?
2x Ja -> AccelStepper
Dort kannst Du für beide Stepper die zu benutzenden Pins einstellen (als 2-wire Takt und Richtung).
Dieser Lib kannst Du sagen, daß Sie doch bitte den Motor A um 123 Schritte nach + fahren soll, die Geschwindigkeit und Beschleunigung kannst Du für beide Stepper einzeln vergeben.
Zu jeder Tages und Nachtzeit kannst Du Stepper B befehligen, unabhängig von Stepper A.
Wenn Du willst, daß Stepper A stehen bleibt, kommt in Deinen Sketch
A.move(0);
A ist die eine Instanz, B die Andere.
In einem Nachbar-Thread wurde gerade herauskristalisiert, daß hierbei der Stepper 'ganz normal' abbremst, umdreht und zurück an den Punkt fährt, wo Er eigentlich hin sollte.
Dort habe ich vorgeschlagen, die Beschleunigung für den dortigen NotHalt auf einen utopischen Wert hoch zu setzen, damit 'direkt' abgebremst wird.
Das move() gibt das Ziel relativ an - eine 0 ist also 'Hier' - SOLL=IST, fertig.

Der ganze Kram braucht nahezu keine Zeit, beide Stepper werden in JEDEM loop()-Durchlauf aufgerufen und machen einen Step, wenn's halt schon wieder so weit ist - sonst eben nicht.
Somit kannst Du IMMER auch nach Deiner Lichtschranke schauen.
Die letzte Zeit merken, wo Diese noch frei war und ein MOTOR-STOOOOP auslösen, wenn die Lichtschranke doch Mal länger abgedunkelt war.

Vom Programm her sehe ich keine Probleme - nur wirst Du vll. verstehen, daß wir hier nicht Deine Hausaufgaben lösen wollen.

Habe aber noch Hoffnung.
Vereinzle die Probleme - versuche, die Lichtschranke ohne das ganze drum herum einzeln hinzubekommen.
Vorerst reicht Es, wenn die Onboard-LED angeht, wenn die Lichtschranke 1 Sekunde (oder länger) verdunkelt war.
Das machst Du OHNE delay() - da ja noch anderes Zeug gleichzeitig gemacht werden soll - z.B. ein/zwei Stepper antreiben.

Dann schaust Du Dir die Stepper-Geschichte an (oder meinen Sketch).
Damit kannst Du zumindest Deine beiden Stepper befehligen - Umschreiben auf 2-wire sollte hinzubekommen sein - nicht wundern, sonderlich übersichtlich ist der Sketch nicht wirklich, damit sollte sich aber Funktion aus dem Apparat kitzeln lassen.

Dann nimmst Du wieder Deinen Sketch, packst die Lichtschranke da rein und die AccelStepper, wie das STOOOP, wenn die Lichtschranke lange genug unterbrochen wurde.

Für Heute soll's reichen, befürchte, mein Chef will mich Morgen dann Mal wieder sehen ...

MfG
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

Go Up