Επιστροφή στο Forum : Συνεχιση του κωδικα μετα το interrupt βοηθεια?
Εχω την εξης εντολη interrupt στον κωδικα μου για να σταματω ενα stepper οταν χτυπηθει ενας διακοπης.
Η εντολη αυτη σταματα το μοτερ αλλα μετα δεν μπορω να συνεχισω στον κωδικα μου παρα μονο με reset.
Εχει κανεις καμμια ιδεα για το πως να συνεχιζει ο κωδικας στην loop?
Το κομματι του κωδικα για το interrupt ειναι το παρακατω
const int BUTTON = 21; // INTERRUPT BUTTON
void setup(void) {
pinMode (BUTTON, INPUT_PULLUP);
digitalWrite (BUTTON,HIGH);
attachInterrupt (2, switchPressed, CHANGE); // see https://www.arduino.cc/en/Main/ArduinoBoardMega2560 for No of pins(it's first No,here is 0-pin 2) // External Interrupts: 2 (interrupt 0), 3 (interrupt 1), 18 (interrupt 5), 19 (interrupt 4), 20 (interrupt 3), and 21 (interrupt 2).
// These pins can be configured to trigger an interrupt on a low level, a rising or falling edge, or a change in level.
}
// Interrupt Service Routine (ISR)
void switchPressed ()
{
while (digitalRead (BUTTON) == LOW)
stepper.stop();
}
Γιατί επαναλαμβάνεις τόσες φορές το stepper.stop(); Φοβάσαι μήπως δεν το καταλάβει με την πρώτη φορά;
Πως περιμένεις να ξαναρχίσει μετά το σταμάτημα (με τί τρόπο);
Γιατί κάνεις interrupt στο change και όχι στο low;
Η stepper.stop() επιτρέπεται να κληθεί δεύτερη φορά ή τα κάνει μαντάρα;
Έχει τόσο απλό κώδικα που να μπορεί να κληθεί μέσα απο interrupt ή τα κάνει μαντάρα;
Γιατί επαναλαμβάνεις τόσες φορές το stepper.stop(); Φοβάσαι μήπως δεν το καταλάβει με την πρώτη φορά;
Πως περιμένεις να ξαναρχίσει μετά το σταμάτημα (με τί τρόπο);
Γιατί κάνεις interrupt στο change και όχι στο low;
Η stepper.stop() επιτρέπεται να κληθεί δεύτερη φορά ή τα κάνει μαντάρα;
Έχει τόσο απλό κώδικα που να μπορεί να κληθεί μέσα απο interrupt ή τα κάνει μαντάρα;
Κατα την γνωμη σου πως θα πρπει να ειναι ο κωδικας σ'αυτο το σημειο για να μπορει να συνεχει την κυριως λουπα?
Οσο για το change και το low ενταξει μπορει να αλαγχθει αν και δουλευει και ετσι
// Interrupt Service Routine (ISR)
void switchPressed ()
{
if(digitalRead (BUTTON) == LOW)
stepper.stop();
}
α) Δεν ξέρω τι λειτουργίες εκτελεί η stepper.stop() αν την εχεις γραψει εσυ, ανεβασε τη. Αν ειναι πολυπλοκη, θα πρεπει να βγει εξω απο το interrupt.
β) δεν ξερω αν τα interrupt του arduino είναι πραγματικά ή software interrupts
γ) δεν ξέρω από arduino
Έχει κλάσεις το Arduino ?
Έχει κλάσεις το Arduino ?
C++ είναι, γιατί να μην έχει? 'αλλωστε, όλες (οι περισσότερες) οι βιβλιοθήκες τι είναι, κλάσεις είναι...
Έχει κλάσεις το Arduino ?
Οι βιβλιοθήκες του Arduino (http://playground.arduino.cc/Code/Library) είναι στην ουσία κλάσεις και ακολουθούν τη σύνταξη της C++.
(με πρόλαβε ο προλαλήσας :001_smile:)
Fire Doger
26-10-16, 11:20
Γιατί δεν το σκέφτεσαι βήμα βήμα?
Πάει παει το μοτερ....
Χτυπάει τερματικό το οποίο δίνει low
Μπαίνει σε interrupt.
Όσο είναι low δηλαδή πατημένο το τερματικό σταμάτα. Δηλαδή για πάντα εφόσον η εντολή εκτελέστηκε επειδή πατήθηκε το τερματικό....
Έστω οτι αφαιρεις το while.
Χτυπάει τερματικό σταματάει.
Του λες πανε από την άλλη, μολις ξεπατηθει το τερματικό θα σταματήσει ξανά.
Βγάλε το while, αλλαξε το interrupt σε falling edge και πες μας τι κάνει. Λειτουργεί και το if του klik αλλά θα εχεις άσκοπα interrupt.
Για σκεψου έτσι όπως το έχεις τι θα γίνει αν χτυπήσει τερματικο, σταματήσει και το στειλεις ξανά στην ιδια κατεύθυνση. Όχι κάτι ευχάριστο αν δεν ελεγχεις αν είναι πατημένο κάποιος τερματικός καθέ φορά που κάνεις εκκίνηση...
Μπορείς και να κρατήσεις το change και να παίζεις με σημαία που θα ανεβοκατεβαζεις ανάλογα στις παρυφές και θα ελεγχεις την σημαία κατά την εκκίνηση.
Καλό είναι ηwhile να γίνει if. Αν θες όταν αφήνεις το κουμπί να ξανά ξεκινάει τότε η μέσα στο interrupt θα βάλεις μια else στην if όπου θα ξανά ξεκινάς το moter όπως στο setup, η να βάλεις και την συνάρτηση loop που λείπει και η οποία εκτελείται συνεχώς σε αντίθεση με την setup που εκτελείται μια φορά. Εκεί μπορείς επίσης να ελέγχεις την κατάσταση του κουμπιού και να πράξεις ανάλογα.
Δεν καλουμε συναρτησεις ΠΟΤΕ μεσα σε interrupt.Κρατα το ποτε.
Καλουμε ΜΟΝΟ οταν ξερουμε ακριβως τι κανουμε,στη περιπτωση σου δεν ξερεις τι εκτελει το σκελος της συναρτησης που καλεις όυτε υποθετω αν μπερδευεται ο compiler.
Αυτό που θυγετε είναι το retrancy , δεν σε αφήνει ο compiler να τις καλέσεις και από τη Main και από το interrupt . Και από το interrupt να τη καλέσεις δεν υπάρχει κανένα πρόβλημα .
Υπάρχουν και controller που έχουν stack για τις συναρτήσεις τότε κάλεις και από τα 2 πχ dspic και pic32 κτλ.
Το προβλημα είναι ότι όταν καλέσεις τη συνάρτηση στη μαιν θα έχει κοινά δεδομένα με αυτή που θα τρέξει στο ιντεραπτ
To re-entrancy μηπως εννοείς;Εαν ναι,τοτε αυτο εννοω οτι ο Compile μπορει να μπερδευεται.
Γιατι δεν βαζεις απλα ενα Flag οταν ερχεται η διακοπη και να καλεις απο main;
αφου έχεις τον interrupt να ενεργοποιήται όταν πατάς το κουμπί για ποιόν λόγο εχεις την while ξανά να ελέγχει το πάτημα του κουμπιού;
ενδεχομένως να μποκάρει στην while γιατί το κουμπί έχει γίνει πάλι high μεσα στον interupt
Γιατί δεν το σκέφτεσαι βήμα βήμα?
Πάει παει το μοτερ....
Χτυπάει τερματικό το οποίο δίνει low
Μπαίνει σε interrupt.
Όσο είναι low δηλαδή πατημένο το τερματικό σταμάτα. Δηλαδή για πάντα εφόσον η εντολή εκτελέστηκε επειδή πατήθηκε το τερματικό....
Έστω οτι αφαιρεις το while.
Χτυπάει τερματικό σταματάει.
Του λες πανε από την άλλη, μολις ξεπατηθει το τερματικό θα σταματήσει ξανά.
Βγάλε το while, αλλαξε το interrupt σε falling edge και πες μας τι κάνει. Λειτουργεί και το if του klik αλλά θα εχεις άσκοπα interrupt.
Για σκεψου έτσι όπως το έχεις τι θα γίνει αν χτυπήσει τερματικο, σταματήσει και το στειλεις ξανά στην ιδια κατεύθυνση. Όχι κάτι ευχάριστο αν δεν ελεγχεις αν είναι πατημένο κάποιος τερματικός καθέ φορά που κάνεις εκκίνηση...
Μπορείς και να κρατήσεις το change και να παίζεις με σημαία που θα ανεβοκατεβαζεις ανάλογα στις παρυφές και θα ελεγχεις την σημαία κατά την εκκίνηση.
const int BUTTON = 21; // INTERRUPT BUTTON
void setup(void) {
pinMode (BUTTON, INPUT_PULLUP);
digitalWrite (BUTTON,HIGH);
attachInterrupt (2, switchPressed, FALLING); // see https://www.arduino.cc/en/Main/ArduinoBoardMega2560 for No of pins(it's first No,here is 0-pin 2) // External Interrupts: 2 (interrupt 0), 3 (interrupt 1), 18 (interrupt 5), 19 (interrupt 4), 20 (interrupt 3), and 21 (interrupt 2).
// These pins can be configured to trigger an interrupt on a low level, a rising or falling edge, or a change in level.
}
void loop(){
// ΜΕΤΑΚΙΝΕΙ ΤΟ STEPPER ΣΕ ΔΙΦΟΡΕΣ ΘΕΣΕΙΣ ΣΕ mm
}
// Interrupt Service Routine (ISR)
void switchPressed ()
{
digitalRead (BUTTON == LOW);
stepper.stop(); //Ο ΔΙΑΚΟΠΤΗΣ ΣΤΑ 2600 mm
stepper.moveTo(2490);
}
Κατι τετοιο ενοεις? Πρεπει να βαλω κατι αλλο?
Εαν υποθεσουμε οτι o διακοπτης ειναι στα 2600 mm
Πως ξερεις οτι δεν εκτελει την διακοπη δεκαδες φορές λογω Debounce και τρελενεται το Servo;
Δεν καταλαβαινω τι κανει αυτο: digitalRead (BUTTON == LOW);
Μεσα σε ιντεραπτ δεν μπορεις να βαζεις χρονοβορες λειτουργιες οπως μετακινηση στεπερ. Επισης το digitalRead σου ειναι λαθος. Διαβαζει την ακιδα 0 ή την 1 και πεταει το αποτελεσμα
Μεσα σε ιντεραπτ δεν μπορεις να βαζεις χρονοβορες λειτουργιες οπως μετακινηση στεπερ. Επισης το digitalRead σου ειναι λαθος. Διαβαζει την ακιδα 0 ή την 1 και πεταει το αποτελεσμα
Δεν ειναι πανακεια βεβαια αυτο,απλα πρεπει να ξερεις τι κανεις και να εισαι προσεκτικος.
Για να μπει στο Vector σημαινει οτι ηρθε διακοπη οποτε δεν χρειαζεται να διαβαζεις παλι το Pin.Κανε '1' ή '0' ενα Flag και στη main() σου κανε μετα οτι θελεις.
Δεν ειναι πανακεια βεβαια αυτο,απλα πρεπει να ξερεις τι κανεις και να εισαι προσεκτικος.
Για να μπει στο Vector σημαινει οτι ηρθε διακοπη οποτε δεν χρειαζεται να διαβαζεις παλι το Pin.Κανε '1' ή '0' ενα Flag και στη main() σου κανε μετα οτι θελεις.
Εαν κανω μια Flag θα αφησω stepper.stop(); η θα χρησιμοποιησω state = !state; ?
#include <Stepper.h>
int BUTTON = 21; // INTERRUPT BUTTON
volatile int state = HIGH;
volatile int must_spin=0; //δημιουγω μια flag για να βλέπω πότε μπηκα στο interrupt volatile για να μην έχω πρόβλημα με τα optimization
AccelStepper stepper(1, A0, A1); // 1 = Easy Driver interface
// Arduino A0 connected to STEP pin of Easy Driver
// Arduino A1 connected to DIR pin of Easy Driver
void setup()
{
stepper.setMaxSpeed(200); // Not to fast or you will have missed steps
stepper.setAcceleration(50); // Same here
pinMode (BUTTON, INPUT_PULLUP);
attachInterrupt (2, switchPressed, FALLING);
}
void loop()
{
digitalWrite(BUTTON, state);
if(must_spin) // ελεγχουμε συνεχώς εαν πρεπει να κινηθει το μοτερ και εφοσον πρεπει
{
stepper.step(100); //το κινούμε
must_spin=0; //και του λέμε κιόλας οτι οκ καναμε το βήμα που θέλαμε μην κάνεις άλλο βήμα
}
}
void switchPressed()
{
state = !state;
must_spin=1; //οταν μπω στο interrupt η flag θέτω ασσο στην μεταβλητή άρα το μοτερ πρέπει να κινηθει
}
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions Inc. All rights reserved.