Σελίδα 1 από 2 1 2 ΤελευταίαΤελευταία
Εμφάνιση αποτελεσμάτων : 1 έως 10 από 11

Θέμα: Servo (MG995) κάνει επανεκκίνηση το arduino

  1. #1
    Μέλος Το avatar του χρήστη Fire Doger
    Όνομα
    Στέφανος
    Εγγραφή
    Jan 2015
    Περιοχή
    .
    Μηνύματα
    1.519

    Προεπιλογή Servo (MG995) κάνει επανεκκίνηση το arduino

    Καλησπέρα,
    Έχω συνδέσει στο arduino nano (1117 regulator) ένα servo με την παρακάτω συνδεσμολογία. Το πρόβλημα είναι κατά την εκκίνηση που στέλνω εντολή να κινηθεί το servo (χωρίς φορτίο) να προκαλεί επανεκκίνηση στο arduino.
    Το δοκίμασα και με εξωτερική τροφοδοσία 12V και με καλώδιο usb. Στο Vin υπάρχει και πυκνωτής 47uF.
    Τι χρειάζεται? Μεγαλύτερο πυκνωτή? Δικό του σταθεροποιητή? Και τα 2?
    Ευχαριστώ

    0 Not allowed! Not allowed!

  2. #2
    Συντονιστής Το avatar του χρήστη lepouras
    Όνομα
    Γιανννης
    Εγγραφή
    Jan 2011
    Περιοχή
    ΚΑΙΣΑΡΙΑΝΗ
    Μηνύματα
    7.015

    Προεπιλογή

    τη εννοεις. προσπαθείς να το οδηγήσεις με το 1117 του αρντουινο? το ενδεχόμενο να μην φτάνει το ρεύμα του 1117 που είναι ελάχιστο και πρέπει να καλύψει και τις ανάγκες του επεξεργαστή το σκέφτηκες?

    1 Not allowed! Not allowed!
    «Η Ιστορία διδάσκει πως ουδείς διδάσκεται απ’ αυτήν».
    Ποτέ δεν νικάς έναν ηλίθιο ,θα σε ρίξει στο επίπεδό του και θα σε κερδίσει λόγω πείρας.

    www.drakotrypa.gr Να σκέφτεσαι σαν άνθρωπος της δράσης,και να δρας σαν άνθρωπος της σκέψης...

  3. #3
    Μέλος Το avatar του χρήστη Fire Doger
    Όνομα
    Στέφανος
    Εγγραφή
    Jan 2015
    Περιοχή
    .
    Μηνύματα
    1.519

    Προεπιλογή

    Αυτό σκέφτηκα αλλά λέω μήπως έχω κάνει και καμία βλακεία και δεν ακούγετε λογικό. ~300mA τραβούσε το σέρβο και μου φάνηκαν λίγα.
    Ευχαριστώ

    0 Not allowed! Not allowed!

  4. #4
    Μέλος Το avatar του χρήστη SProg
    Όνομα
    Σάββας
    Εγγραφή
    Mar 2014
    Περιοχή
    Θεσσαλονίκη
    Μηνύματα
    2.612

    Προεπιλογή

    Δεν εχει σχεση εαν το τροφοδοτεις απο USB ή απο αλλη πηγη.

    Με αυτα που γραφεις δεν θα επρεπε να εχει προβλημα.Κανονικα θελει ξεχωριστη πηγη ο σερβο-κινητηρας αλλα και ετσι θα επρεπε να δουλευει κανονικα.Εαν εχεις μονο τον σερβκινητηρα συνδεδεμενο και οχι επιπλεον στοιχεια (οθονες κτλ) τοτε κανει reset μονος του γιατι 'νομιζει' οτι κατι βραχυκυκλωνει και προσπαθει να προστατευτει.


    Υ.Γ

    Kατι αλλο που δεν θυμαμαι (..και βαριεμαι να ψαξω..ε ειναι και Πασχα) ειναι τι προεπιλογη εχει το ΒΟD.Εαν ειναι δηλαδη στα 2.7V ή στα 4.0V να κανει reset.Εαν ειναι στα 4.0V και ο μΕ κανει reset τοτε:

    Ο πυκνωτης που εχεις βαλει ειναι πολυ μικρος.Κατα την εκκινηση ο servo (δηλαδη ενας απλος DC κινητηρας με 2-3 μπιχλιμπιδια) τραβαει αρκετα παραπανω ρευμα απ οτι εν κενω για να ξεπερασει την ροπη αδρανειας.Υποθετω βυθιζει την Vcc πολυ και μεσω του BOD εχουμε το reset.

    Βαλε μεγαλυτερο πυκνωτη ή βαλε μερικους || προχειρα να δουμε τι γινεται.

    0 Not allowed! Not allowed!

  5. #5
    Μέλος Το avatar του χρήστη her
    Όνομα
    Ηρακλής
    Εγγραφή
    Jun 2007
    Περιοχή
    Αργυρούπολη
    Μηνύματα
    1.121

    Προεπιλογή

    Μετρα την ταση οταν κανει reset γιατι υπαρχει περιπτωση το προβλημα να μην ειναι τροφοδοσιας αλλα θορυβου.

    0 Not allowed! Not allowed!

  6. #6
    Μέλος Το avatar του χρήστη Fire Doger
    Όνομα
    Στέφανος
    Εγγραφή
    Jan 2015
    Περιοχή
    .
    Μηνύματα
    1.519

    Προεπιλογή

    Έχουμε BOD 2.7V (για uno)
    Είχα και μερικά κλαπατσίμπαλα γύρο γύρο, τα έβγαλα, έβαλα ένα πυκνωτή 1000μ και σταμάτησε να κάνει reset, άμα το ζορίσεις με διαδοχικές εκκινήσεις πάλι το κάνει, δυστυχώς δεν έχω παλμογράφο να δω, με το πολύμετρο 3.2V min έπιασα αλλά λογικά τα πέφτει ποιο χαμηλά και θα κλίνει. Σε μία εκκίνηση σηκώνει και την lcd ταυτόχρονα.
    Και εμένα ο θόρυβος με προβλημάτισε αλλά αφού είναι απλά η τροφοδοσία θα βάλω δικό του σταθεροποιητή να είμαι ήσυχος.
    Ευχαριστώ, και καλή όρεξη

    0 Not allowed! Not allowed!

  7. #7
    Μέλος Το avatar του χρήστη her
    Όνομα
    Ηρακλής
    Εγγραφή
    Jun 2007
    Περιοχή
    Αργυρούπολη
    Μηνύματα
    1.121

    Προεπιλογή

    Αν βαλεις δικο του σταθεροποιητη λυνεις το προβλημα ρευματος και θορυβου. Οποτε θα σου δουλεψει.

    0 Not allowed! Not allowed!

  8. #8
    Μέλος Το avatar του χρήστη SProg
    Όνομα
    Σάββας
    Εγγραφή
    Mar 2014
    Περιοχή
    Θεσσαλονίκη
    Μηνύματα
    2.612

    Προεπιλογή

    Δεν ειναι προβλημα θορυβου.Σιγα το κινητηρακι..εδω βιαζουμε τους μΕ καθημερινως με ταυτοχρονη χρηση PWM+ADC και δεν εχει θεμα.

    Εχω οδηγησει απευθειας απειρες φορες τετοιου ειδους κινητηρακια ειτε με δικη τους τροφοδοσια ειτε με τα 5V του board.


    Εαν βαλεις δικη του τροδοφοσια θα πρεπει και παλι να εχεις ενωμενες τις 2 γειωσεις.Εαν τις μοιρασεις σωστα τοτε θα περιοσισεις το θορυβο (που δεν ειναι το προβλημα σου αυτος..).Αλλη λυση ειναι δαιφορετικες τροφοδοσιες και απομονωση του σηματος.




    Υ.Γ

    Ο Arduino Mega που εχω βαλει απειρες φορες Servo απευθειας εχει διαφορετικο regulator απ'οτι το board του Νano.Toυ Mega ειναι το MC33269 με ρευμα 800ma και του Ναno ειναι το UA78M05 με 500ma...

    0 Not allowed! Not allowed!
    Τελευταία επεξεργασία από το χρήστη SProg : 01-05-16 στις 20:53

  9. #9
    Μέλος Το avatar του χρήστη SProg
    Όνομα
    Σάββας
    Εγγραφή
    Mar 2014
    Περιοχή
    Θεσσαλονίκη
    Μηνύματα
    2.612

    Προεπιλογή

    Ασχετο...εισαι σιγουρος οτι οδηγεις σωστα τον Servo;Βαλε τον κωδικα.

    0 Not allowed! Not allowed!

  10. #10
    Μέλος Το avatar του χρήστη Fire Doger
    Όνομα
    Στέφανος
    Εγγραφή
    Jan 2015
    Περιοχή
    .
    Μηνύματα
    1.519

    Προεπιλογή

    Σίγουρος δεν είμαι, δεν τον έγραψα εγώ, από εδώ είναι ο κώδικας. Χρησιμοποιεί τον Timer1 και για δειγματοληψία θερμοκρασίας.
    Αυτό ήθελα να δω τώρα που έχω κάνει ένα πρωτότυπο με πολλές αλλαγές. Τα διόρθωσα όλα και μου έμεινε αυτό τελευταίο που θα ανοίγει ένα πορτάκι. Δεν σκόπευα να το βάλω (για αυτό δεν το έψαξα και καθόλου) αλλά έτυχε να έχω 2 servo και είπα ας το δοκιμάσω...
    Πιθανό να έχει κάπου λάθος γιατί είναι γραμμένο για at32u4, όσο το κοίταξα δεν βρήκα καμία διαφορά.

    Κώδικας:
    // Timer 1 is used for 2 things:// 1. Take thermocouple readings every 200ms (5 times per second)
    // 2. Control the servo used to open the oven door
    //
    // Servo timer interrupt operation
    // ===============================
    // See http://en.wikipedia.org/wiki/Servo_control for more information regarding servo operation.
    // Note: Some (most) servos only rotate around 90°, not the 180° that is possible in theory
    // The servo position information should be sent every 20ms, or 50 times per second.  To do this:
    //   - Timer 1 is set to CTC mode
    //   - Compare A is set to a value to force a timer interrupt every 20ms
    // For every 10 times the timer fires, a call is made to get a thermocouple reading.
    // If servo movement is enabled (interrupt on Compare B, OCIE1B is set) then the servo pin
    // is set high.  It must be lowered somewhere between 1ms and 2ms later, depending on the desired
    // position.  To do this, the appropriate value is written to OCR1B.  Keep in mind that unlike
    // Compare A, Compare B does not reset Timer 1's counter.  The steps look something like this:
    //   a. Counter = 0: Write servo pin HIGH, and set Compare B to correct duration.
    //   b. Counter = Compare B: Write servo pin low
    //   c. Counter = Compare A: Counter is set back to 0 (go to a.)
    // Once the servo has reached the desired position, the Compare B interrupt is disabled
    //
    // With a 16MHz clock, the prescaler is set to 8.  This gives a timer speed of 16,000,000 / 8 = 2,000,000. This means
    // the timer counts from 0 to 2,000,000 in one second.  We'd like the interrupt to fire 50 times per second so we set
    // the compare register OCR1A to 2,000,000 / 50 = 40,000.
    
    
    #define SERVO_PIN               3     // The I/O pin used for the servo
    #define MIN_PULSE_WIDTH       544     // The shortest pulse sent to a servo (from Arduino's servo library)
    #define MAX_PULSE_WIDTH      2400     // The longest pulse sent to a servo (from Arduino's servo library)
    
    
    
    
    // Variables used to control servo movement
    int servoEndValue;                    // The desired pulse width
    volatile int servoMovements;          // Number of movements to reach the desired position
    int servoIncrement;                   // The amount to increase/decrease the pulse every interrupt
    
    
    
    
    // Initialize Timer 1
    // This timer controls both the thermocouple readings and the servo
    // It should fire 50 times every second (every 20ms)
    void initializeTimer(void) {
      cli();                               // Disable global interrupts
      TCCR1A = 0;                          // Timer 0 is independent of the I/O pins, CTC mode
      TCCR1B = _BV(WGM12) + _BV(CS11);     // Timer 0 CTC mode, prescaler is 64
      TCNT1 = 0;                           // Clear the timer count 
      OCR1A = 40000;                       // Set compare match so the interrupt occurs 50 times per second
      TIMSK1 |= _BV(OCIE1A);               // Enable timer compare interrupt
      sei();                               // Enable global interrupts
    
    
      // Set the servo pin as output
      pinMode(SERVO_PIN, OUTPUT);
      
      // Assume the servo is close to the closed position
      OCR1B = degreesToTimerCounter(getSetting(SETTING_SERVO_CLOSED_DEGREES) + 1);
    }
    
    
    
    
    // Timer 1 ISR
    // This timer fires 50 times per second (every 20ms)
    ISR(TIMER1_COMPA_vect)
    {
      volatile static int thermocoupleTimer = 0;
      
      // Read the thermocouple 4.1 times per second (every 0.24 seconds)
      if (++thermocoupleTimer >= 12) {
        thermocoupleTimer = 0;
        takeCurrentThermocoupleReading();
        
        // Don't move the servo - the pulse won't have the correct timing because of the time taken to read the thermocouple
        return;
      }
      
      // Is the servo timer interrupt active?
      if (TIMSK1 & _BV(OCIE1B)) {
        // Has the servo reached the desired position?
        if (!servoMovements)
          // Disable the servo interrupt
          TIMSK1 &= ~_BV(OCIE1B);
        else {
          // Move the servo to the next position
          OCR1B += servoIncrement;
          servoMovements--;
          // Write the servo signal pin high.  This is lowered when Compare B fires
          digitalWrite(SERVO_PIN, HIGH);
        }
      }
    }
    
    
    
    
    // Timer 1 Compare B interrrupt
    // This interrupt fires once the desired piulse duration has been sent to the servo
    ISR(TIMER1_COMPB_vect)
    {
      digitalWrite(SERVO_PIN, LOW);
    }
    
    
    
    
    // Move the servo to servoDegrees, in timeToTake milliseconds (1/1000 second)
    void setServoPosition(unsigned int servoDegrees, int timeToTake) {
      sprintf(debugBuffer, "Servo: move to %d degrees, over %d ms", servoDegrees, timeToTake);
      Serial.println(debugBuffer);
      // Make sure the degrees are 0 - 180
      if (servoDegrees > 180)
        return;
      // Figure out what the end timer value should be
      servoEndValue = degreesToTimerCounter(servoDegrees);
      
      // If the servo is already in this position, then don't do anything
      if (servoEndValue == (int) OCR1B)
        return;
        
      // Figure out how many movements this will take (a movement is made every 20ms)
      servoMovements = timeToTake / 20;
      
      // Is the movement small?
      if (abs(servoEndValue - (int) OCR1B) < servoMovements) {
        // Make the full movement in one go
        OCR1B = servoEndValue;
        servoIncrement = 0;
      }
      else {
        // Figure out the timer increment to achieve the end value
        servoIncrement = (servoEndValue - (int) OCR1B) / servoMovements;
        // There are rounding errors, so calculate the number of movements again
        servoMovements = (servoEndValue - (int) OCR1B) / servoIncrement;
      }
    
    
      // Enable the servo compare interrupt to start the servo motion
      TIMSK1 |= _BV(OCIE1B);
    } 
    
    
    
    
    // Convert degrees (0-180) to a timer counter value
    unsigned int degreesToTimerCounter(unsigned int servoDegrees) {
      // Get the pulse duration in microseconds
      unsigned int duration = map(servoDegrees, 0, 180, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);
      // Convert this to a timer value.  One microsecond is 2 timer counts
      return duration << 1;
    }

    0 Not allowed! Not allowed!

Σελίδα 1 από 2 1 2 ΤελευταίαΤελευταία

Παρόμοια Θέματα

  1. arduino servo
    By giorgosm3 in forum Μικροελεγκτές
    Απαντήσεις: 4
    Τελευταίο Μήνυμα: 15-06-17, 20:59
  2. Βοήθεια με arduino και servo
    By nicolouris in forum Μικροελεγκτές
    Απαντήσεις: 10
    Τελευταίο Μήνυμα: 05-01-16, 00:46
  3. Οδήγηση servo ηλεκτροβάνας με arduino
    By Holy Driver in forum Κυκλώματα για Auto & Moto
    Απαντήσεις: 1
    Τελευταίο Μήνυμα: 31-08-13, 17:38
  4. Arduino "μεγάλα" Servo
    By CivilSitis in forum Μικροελεγκτές
    Απαντήσεις: 11
    Τελευταίο Μήνυμα: 02-09-12, 20:04
  5. Απαντήσεις: 42
    Τελευταίο Μήνυμα: 18-11-11, 18:45

Tags for this Thread

Δικαιώματα - Επιλογές

  • Δημιουργία θεμάτων: Όχι
  • Υποβολή μηνυμάτων: Όχι
  • Σύναψη αρχείων: Όχι
  • Επεξεργασία μηνυμάτων: Όχι
  •  
  • BB code: σε λειτουργία
  • Smilies: σε λειτουργία
  • [IMG]: σε λειτουργία
  • [VIDEO] code is σε λειτουργία
  • HTML: εκτός λειτουργίας