- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 10 von 10

Thema: PWM Initialisierung beeinflusst externe Interrupts

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Benutzer Stammmitglied
    Registriert seit
    07.07.2009
    Alter
    28
    Beiträge
    96

    Frage PWM Initialisierung beeinflusst externe Interrupts

    Hallo Roboternetz!

    Ich versuche ein 2-rädriges Fahrzeug mit Rad-Encodern zu bauen.
    Diese werden über Lichtschranken realisiert und alles funktioniert soweit super.

    Also ich kann die Flanken des Encoders über einen Interrupt einlesen und daher die Anzahl der durchlaufenden "Löcher" über UART ausgeben.


    Sobald ich jedoch einen beliebigen Timer für ein PWM Signal initialisiere funktioniert das nicht mehr ganz so.
    Dann werden manchmal mehrere Flanken erkannt (oft 2 auf einmal oder ganz viele hintereinander) und der Encoder wird unbrauchbar.

    Ich nutze ein Arduino Mega (ATMega 2560), und programmiere diesen mit dem AVR-GCC Compiler.
    PWM funktioniert einzeln und auch die Interrupts funktionieren einzeln, zusammen jedoch leider nicht

    hier der Code:

    Code:
    #include <avr/io.h>    #include <util/delay.h>
    #include <stdlib.h>
    #include <avr/interrupt.h>
    #include "uart.h"
    
    
    
    
    uint16_t counter_l=0,counter_r=0;
    char s[10];
    
    
    
    
    void PWM_Init(void){
        TCCR3A = (1<<WGM30)|(1<<COM3A1)|(1<<COM3B1);
        TCCR3B = (1<<WGM32)|(1<<CS31);
    }
    
    
    ISR(INT2_vect)
    {
        counter_l++;
        uart_puts("Left: ");
        uart_puts(itoa( counter_l, s, 10 ) );
        uart_puts("Right: ");
        uart_puts(itoa( counter_r, s, 10 ) );
        uart_putc('\n');
    }
    
    
    ISR(INT3_vect)
    {
        counter_r++;
        uart_puts("Left: ");
        uart_puts(itoa( counter_l, s, 10 ) );
        uart_puts("Right: ");
        uart_puts(itoa( counter_r, s, 10 ) );
        uart_putc('\n');
    }
    
    
    void interrupt_init(void){
        DDRD &= ~(1<<2);
        DDRD &= ~(1<<3);
        
        EICRA = (1<<ISC21)|(1<<ISC31);            //falling edge detection for ext.int2,ext.int3
        EIMSK = (1<<INT2)|(1<<INT3);            //turn on ext.int2,ext.int3
        sei();
    }
    
    
    int main(void){
        //OUTPUTS
        DDRE |= (1<<3);    //Motor ? PWM
    
    
        DDRE |= (1<<4);    //Motor ? PWM
        
        //Pre Settings
        //PWM_Init();
    
    
        uart_init();
        interrupt_init();
        
        //OCR3A=0;
        //OCR3B=0;
        
        while(1){
            
        }
        return 0;
    }
    habt ihr eine Idee, was das Problem sein könnte?
    Danke schon mal im voraus!

    Gruß Lukas

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Karlsruhe
    Alter
    36
    Beiträge
    1.225
    Störungen durch das PWM-Signal die auf die Encoder zurückkoppeln (Motorendstufe -> Spanungseinbrüche oder -spitzen)?

    Davon abgesehen: Es ist meistens keine gute Idee, in ISRs langsame Funktionen wie itoa oder gar blockierende Vorgänge wie die (ungepufferte) Ausgabe über Kommunikationsschnittstelle auszuführen.

    mfG
    Markus
    Tiny ASURO Library: Thread und sf.net Seite

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    07.07.2009
    Alter
    28
    Beiträge
    96
    Danke für die schnelle Antwort!

    Nein das kann eigentlich nicht der Grund sein, da ich ja OCR3A/B noch auf 0 habe -> daher laufen die Motoren ja noch garnicht.
    Oder denke ich da falsch?

    Ja das ist mir bewusst, das sollte nur eine vorläufige Debugging Ausgabe sein. Sollte man das trotzdem auch beim debugging vermeiden?

    Gruß Lukas

  4. #4
    Erfahrener Benutzer Robotik Visionär Avatar von 021aet04
    Registriert seit
    17.01.2005
    Ort
    Niklasdorf
    Alter
    36
    Beiträge
    5.070
    Im Programm sehe ich soweit keinen groben Fehler (habe aber die genauen Register, ... nicht angeschaut).
    Ich würde in der Hauptschleife die UART Übertragung machen. Im Interrupt eine variable setzen. Wenn diese gesetzt ist wird die Datenübertragung gestartet (= Minimierung des Datenverkehrs).

    Was mir noch auffällt ist das du die variablen im Interrupt nicht als volatile hast. Infos findest du z.b. Bei www.mikrocontroller.net im Artikel GCC tutorial (bzw im Interrupt artikel).

    PS: hast du ein oszi damit man sich etwas anschauen könnte?

    MfG Hannes

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    07.07.2009
    Alter
    28
    Beiträge
    96
    Danke auch dir für deine Antwort!

    ich hab jetzt das UART wie du sagtest in die main gepackt und die variablen als volatile.

    Wenn ich PWM_Init() nicht aufrufe läuft alles wie es soll.
    Sobald ich es tue geht immer noch alles schief.
    Jetzt sind es mehrere 1000 Aufrufe der ISR, da ja die Zeitverzögerung vom UART nicht mehr da ist..

    Ich habe leider kein Oszilloskop da :/ zur not könnte ich es aber mal mit zum Studium nehmen Montag, da hab ich die Möglichkeit.
    Allerdings hab ich auch schon eine Hardwareentprellung mit 100nF dran, sodass das nach meinem Verständnis nicht mehr prellen sollte...

    Der Zusammenhang mit der Initialisierung des PWMs ist wohl höhere Magie..

    Gruß Lukas

  6. #6
    Erfahrener Benutzer Robotik Visionär Avatar von 021aet04
    Registriert seit
    17.01.2005
    Ort
    Niklasdorf
    Alter
    36
    Beiträge
    5.070
    Mit dem Atmega 2560 habe ich noch nicht gearbeitet, jedoch bei den anderen mit denen ich gearbeitet habe habe ich noch nie solche Probleme gehabt.
    Prellen hast du eigentlich nur bei mechanischen Schaltern. Du verwendest vermutlich eine Lichtschranke, dort gibt es soetwas nicht. Was ich mir nur vorstellen könnte ist das die Räder ganz leicht hin und her bewegen und somit die Lichtschranke ständig schaltet.

    Du könntest noch versuchen eine direkte Verbindung zwischen INT Eingang und Masse machen (direkt am arduino). Dann hast du auch ausgeschlossen das du dir Störungen über die signalleitungen einfängst.

    Du könntest auch eine Led am Eingang anschließen (eine superhelle wäre von Vorteil) . Wenn es flackert oder blinkt schaltet der INT.

    MfG Hannes

Ähnliche Themen

  1. externe Interrupts stören sich
    Von Otzelott im Forum C - Programmierung (GCC u.a.)
    Antworten: 2
    Letzter Beitrag: 11.04.2007, 09:53
  2. Externe Interrupts?
    Von Dane im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 16.12.2005, 22:24
  3. zwei externe Interrupts
    Von globe im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 4
    Letzter Beitrag: 27.02.2005, 16:55
  4. Externe Interrupts beim Atmega32
    Von Javik im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 11
    Letzter Beitrag: 23.11.2004, 16:04
  5. Externe Interrupts
    Von BomberD im Forum C - Programmierung (GCC u.a.)
    Antworten: 6
    Letzter Beitrag: 12.11.2004, 06:35

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

fchao-Sinus-Wechselrichter AliExpress