- LiFePO4 Speicher Test         
Ergebnis 1 bis 6 von 6

Thema: Sensorecho an Atmega328P am D6 - PCINT22 abfragen ?

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    RN-Premium User Fleißiges Mitglied
    Registriert seit
    19.05.2012
    Ort
    Sigmaringen
    Beiträge
    169

    Sensorecho an Atmega328P am D6 - PCINT22 abfragen ?

    Hey... folgende sache...

    Ich habe bereits timer für Servos und Motor-PWM in verwendung und möchte deshalb einen
    Ultraschallsensor (SRF04) am D6 (PCINT22) abfragen.
    Da nurnoch timer 2 dafür zur verfügung steht hatte ich mir überlegt, den wert einfach mit den Überläufen hochzurechnen.

    Nun hab ich noch herausgefunden, das der gesamte D-Port reagiert, wenn man es nicht über Pcmsk beschränkt.
    Ich hoffe das ist soweit richtig gelöst.

    soweit so gut...
    allerdings habe ich hier ein kleines Testprogramm... das trotzdem recht
    verwirrende Werte ausgibt.

    Code:
    $regfile = "m328pdef.dat"                                   'eingesetzter Mikrocontroller
    $crystal = 8000000                                          'eingestellte Taktfrequenz (8MHz)
    $hwstack = 100                                              'Standardwert
    $swstack = 100                                              'Standardwert
    $framesize = 100                                            'Standardwert
    $baud = 9600
    
    '-------------------------------------------------------------------------------
    'Ports/Pins/Configs
    '-------------------------------------------------------------------------------
    Config Portb.0 = Output                                     'Funkmodul ENABLE
    Funk_enable Alias Portb.0
    Config Portb.1 = Output                                     'Motor2 Geschwindigkeit (PWM)
    Motor2speed Alias Portb.1
    Config Portb.2 = Output                                     'Motor1 Geschwindigkeit (PWM)
    Motor1speed Alias Portb.2
    Config Portb.3 = Output                                     'Servo1 (PWM)
    Servo1 Alias Portb.3
    Config Portb.4 = Output                                     'Motor2a
    Motor2b Alias Portb.4
    Config Portb.5 = Output                                     'Motor2b
    Motor2a Alias Portb.5
    
    Config Portc.0 = Output                                     'Motor1b
    Motor1b Alias Portc.0
    Config Portc.1 = Output                                     'Motor1a
    Motor1a Alias Portc.1
    'Config Portc.2 = Output
    'Xx Alias Portc.2
    'Config Portc.3 = Output
    'Xx Alias Portc.3
    'Config Portc.4 = Output
    'Xx Alias Portc.4
    'Config Portc.5 = Output
    'Xx Alias Portc.5
    
    'Config Portd.2 = Output
    'Xx Alias Pind.2
    'Config Portd.3 = Output
    'Xx Alias Portd.3
    'Config Portd.4 = Output
    'Xx Alias Portd.4
    'Config Portd.5 = Output
    'Xx Alias Portd.5
    Config Pind.6 = Input                                       'Ultraschall Echo
    Us_echo Alias Pind.6
    Config Portd.7 = Output                                     'Ultraschall Trigger
    Us_trigger Alias Portd.7
    
    '-------------------------------------------------------------------------------
    'Timer/OCR/PWM/ISR usw. setzen
    '-------------------------------------------------------------------------------
    
    Pcicr = &B100
    Pcmsk2 = &B01000000
    On Pcint2 Echowechsel
    Enable Pcint2
    
    Config Timer2 = Timer , Prescale = 1                        ' Echo vom Ultraschallsensor zählen
    On Timer2 Isr_timer2
    Enable Timer2
    
    Enable Interrupts                                           'Interrupts global aktivieren
    
    '-------------------------------------------------------------------------------
    'Variablen
    '-------------------------------------------------------------------------------
    
    Dim Temp_string As String * 10
    Dim Temp_long As Long
    
    Dim Timerueberlauf As Long
    Timerueberlauf = 0
    Dim Messung_starten As Bit                                  ' Zeigt an, ob Messung gestartet werden soll
    Messung_starten = 1
    Dim Messung_beendet As Bit                                  ' Zeigt an, ob Messung beendet ist
    Messung_beendet = 0
    Dim Messergebniss As Long                                   ' Ergebniss der Messung in us
    Messergebniss = 0
    Dim Entfernung As Long                                      ' Entfernung in mm
    Entfernung = 0
    Dim Position_x_soll As Word
    Dim Start_pause As Single
    Start_pause = 1000
    Dim Triggersignal_laenge As Single
    Triggersignal_laenge = 10
    Dim Timer_ueberlauf As Word
    Timer_ueberlauf = 0
    
    
    Declare Sub Triggersignal_senden(byval Start_pause As Single , Byval Triggersignal_laenge As Single)
    '-------------------------------------------------------------------------------
    'Hauptprogramm
    '-------------------------------------------------------------------------------
    
    Hauptprogramm:
    Do
    
       For Position_x_soll = 8 To 22 Step 2
          Timerueberlauf = 0
          Messergebniss = 0
          Temp_long = 0
          Entfernung = 0
          Messung_beendet = 0
          Call Triggersignal_senden(start_pause , Triggersignal_laenge)
          Do
             Waitus 1
          Loop Until Messung_beendet = 1
          If Messung_beendet = 1 Then
          Print "'t=" ; Timerueberlauf
    
          Print "_T=" ; Temp_long
          Messergebniss = Messergebniss + Temp_long
          Print "_M=" ; Messergebniss
          Entfernung = Messergebniss * 172
          Entfernung = Entfernung / 10000                       ' Ergebniss in mm ?
          Temp_string = Str(entfernung)
          Temp_string = Format(temp_string , "000000")
    
          Waitms 500
          Print "==" ; Temp_string ; "mm"                       ' Ausgabe des Ergebniss
          End If
       Next
    
    Loop
    
    End
    
    
    
    '-------------------------------------------------------------------------------
    'Subs
    '-------------------------------------------------------------------------------
    
    
    Sub Triggersignal_senden(byval Start_pause As Single , Byval Triggersignal_laenge As Single)
          Messung_beendet = 0
          Waitms Start_pause                                    ' minimale Wartezeit um "Fehlechos" auszuschliessen
          Portd.7 = 1                                           ' Impuls an Triggerport senden
          Waitus Triggersignal_laenge                           ' Impulsdauer 10us
          Portd.7 = 0
    End Sub
    
    '-------------------------------------------------------------------------------
    'Interrupt
    '-------------------------------------------------------------------------------
    
    Isr_timer2:
     Timerueberlauf = Timerueberlauf + 1                        'Timerüberläufe zählen
    Return
    
    
    Echowechsel:                                                ' Interrupt startet bei Signalwechsel am Echopin
       If Pind.6 = 1 Then                                       ' Wenn Pin zu High wechselt ...
          Timer2 = 0
    
        Else                                                    ' wenn Pin zu LOW wechselt....
          Messergebniss = Timer2                                '  Messergebniss in Variable speichern
          Temp_long = Timerueberlauf * 255                      ' aktuelle Timerüberläufe übernehmen
          Messung_beendet = 1                                   ' Anzeigen, das Messung beendet is
       End If
    Return
    nichtmal der wert "Temp_long" wird korrekt berechnet...
    kann es sein, das der 328p mir da irgendwie rechenfehler reinbaut ? o.O

    NACHTRAG:
    Es werden z.b. solche (nur mit geringen Schwankungen) Werte ausgegeben:
    t=5241 _T=1327530 _M1327777 ==022837mm

    und als Quarz ist ein 8mhz-Quarz verbaut und als fuse ist eingestellt:
    Ext.Crystal Osc.; Frequ. 3,0-8,0MHz; ... 16/14/65ms


    Kann bitte jemand meinen blinden Augen auf die sprünge helfen ?
    Geändert von JoeM1978 (29.09.2013 um 20:34 Uhr)
    JAAAA... Microchips kann man essen... aber der Geschmack ist furchtbar.

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.01.2007
    Ort
    Göttingen
    Beiträge
    706
    kann es sein, das der 328p mir da irgendwie rechenfehler reinbaut ? o.O
    Hier kann ein Taschenrechner äußerst wertvolle Dienste leisten! Wenn man damit Deine angegebenen Werte mal so verrechnet wie es der Mega328P tun soll, kommt man zu überraschend ähnlichen Ergebnissen. Rechenfehler seitens des Controllers sind es also schon mal nicht (und wären auch absolut nicht zu erwarten).

    Erstmal zwei "Schönheitsfragen":

    Was ist der Sinn der For-Next-Schleife?
    Wieso fragst Du nach dem Befehl "Loop Until Messung_beendet = 1" nochmal "If Messung_beendet = 1" ab?

    Das erklärt die seltsamen Werte aber zugegebenermaßen nicht. Was mir insgesamt auffällt ist die extrem hohe Anzahl an Timer-Überläufen ( > 5000...).
    Bei einer Taktfrequenz von 8 MHz und einem Prescaler von 1 läuft der 8-Bit-Timer alle 32µS über. 5000 Überläufe während des auszumessenden Impulses würden also bedeuten, dass der Impuls eine Größenordnung von ca. 160mS hat - und das ist zu viel. Der SRF04 soll einen Impuls von maximal 32ms erzeugen (wenn kein reflektiertes Echo erkannt wurde), und ansonsten zwischen 100µs und 18mS. Mit dieser Größenordnung ist also schon mal was faul.

    Den Timer ohne jeden Prescaler zu betreiben, ist möglicherweise auch etwas problematisch: Nach dem Auslösen einer ISR braucht der Controller schon mal weit mehr als 50 Takte um alle Register zu "retten" - und nach dem Return nochmal so viele, um die Registerinhalte alle wieder zurückzuschreiben. Wenn also alle 256 Takte in eine Timer-ISR gesprungen wird, ist der Controller schon mal mindestens die Hälfte der Zeit mit nix anderem beschäftigt, als Registerinhalte hin- und herzuschieben. Und dabei könnte vielleicht einiges auf der Strecke bleiben.

    Wenn Du den Timer mit einem Prescaler von 64 betreibst, ist die Auflösung jedes Zählschrittes immer noch 8µs, d.h. die relevante Pulsbreite von 100µs bis 16ms könnte damit in knapp 2000 Stufen aufgelöst werden. Bei einer maximaler Impulslänge von 32 ms (d.h. kein Echoreflex) würde es übersichtliche 15 Timer-Überläufe geben, d.h. man könnte das Ganze auch mit Word-Variablen berechnen.

    Die konkrete Berechnung müsste dann natürlich mit etwas anderen Zahlen ausgeführt werden, was ja aber kein Problem sein sollte wenn man weiß, wie der Zusammenhang zwischen Pulsdauer und Entfernung ist.

Ähnliche Themen

  1. ATmega328P - SMD austauschen
    Von Greensiver im Forum AVR Hardwarethemen
    Antworten: 5
    Letzter Beitrag: 12.02.2013, 11:17
  2. ATMEGA328P-PU Brenner gesucht
    Von Maximilian Koch im Forum AVR Hardwarethemen
    Antworten: 15
    Letzter Beitrag: 07.11.2012, 00:04
  3. Atmega328p wird heiß
    Von Gorn im Forum Elektronik
    Antworten: 0
    Letzter Beitrag: 17.01.2012, 20:47
  4. UART Register beim ATMEGA328P
    Von mrmajo im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 23.12.2010, 15:31
  5. ATMega328P Programmer, Ponyprog
    Von autoguider im Forum AVR Hardwarethemen
    Antworten: 2
    Letzter Beitrag: 16.08.2009, 18:37

Berechtigungen

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

12V Akku bauen