Der Nachfolger des WDR-Computerclub mit Wolfgang Back und Wolfgang Rudolph - ...und immer ein Bit übrigbehalten!


Das Forum zur C-Control-1
Welche C-Control-Varianten existieren?
Übersicht - Suchen - Neueste 50 Beiträge - Neuer Beitrag - Login - Registrieren
INFO - FAQ - CC2-Forum - CCPro-Forum 

 Mit Ultraschall messen Kategorie: Open-Micro/Open-Mini/Open-Midi/Open-Macro/Open-Maxi (von Norbert - 3.03.2016 17:19)
Norbert nutzt:  Open-Micro, Open-Mini, Open-Midi, Open-Macro, Open-Maxi
Hallo!
Bei Amazon stieß ich auf preiswerte Ultraschallmodule HC-SR04. Das Stück für rund 3 Euro. Sie können Entfernungen von 2 bis etwa 300 cm mit einer Auslösung von 3 mm bestimmen. Die Handhabung ist einfach. Zum Auslösen eines Messintervalls muss man einen Triggerimpuls senden. Mit dem darauf folgenden Puls des Moduls im ms-Bereich kann man die Entfernung bestimmen. Als Grundlage diente mir das Programm "Tastverhältnis eines Rechtecksignals an PORT[2] ermitteln" von Dietmar Harlos, das ich auch für die Maxi an TPM2 modifizierte. Bei der Maxi fällt ein Jitter im Messergebnis auf, diese Schwankungen verfälschen den Wert um bis zu neun Prozent. Die Ursache könnte mit den Interrupts des OS an TPM1 zusammenhängen. Vielleicht kann jemand das genauer ergründen. Bei der Berechnung muss man berücksichtigen, dass die verarbeiteten Werte gerundet sind. Diese Abweichungen kann man im Nahbereich, wie erläutert wird, minimieren.  Nachfolgend das Programm.

Freundliche Grüße
Norbert



' ----------------------------------------------------------------------------
' Tastverhältnis eines Rechtecksignals an PORT[2] ermitteln.
' In OCBASIC 1.09a für Open-Macro von Dietmar Harlos am 22. September 2015.

' modifiziert für die Berechnung von Ultraschall-Laufzeiten
' Messergebnis * 1/3200*34,3/2 = Messergebnis * 0.00343 = Messergebnis / 186.5889212827988
' nach Dietmar Harlos
' für das Beispiel mit der Maxi gilt:
' Messergebnis * 1/5000*34,3/2 = Messergebnis * 0.00343 = Messergebnis / 291.5451895
' ----------------------------------------------------------------------------

' Dieses Programm mißt die ON-Zeit eines an PORT[2] (genauer: TCH1) einer
' Open-Macro angeschlossenen Rechtecksignals in 312.5-ns-Einheiten. Es können
' Frequenzen größer 48.8 Hz und kleiner ca. 25 kHz erfaßt werden. Der interne
' Pull-Up-Widerstand an PORT[2] wird während der Messung (leider) deaktiviert.
' Bei Bedarf muß also ein externer verwendet werden.
' Die gemessende ON-Zeit ist: tastver_ergebnis * 312.5E-9 s.
' Tastverhältnis: Frequenz_des_Rechtecksignals * tastver_ergebnis / 3.2E6

' In diesem Demoprogramm können Störungen auftreten, weil die Ausgabe eines
' Zeichens über die an PORT[1] liegende Serielle Schnittstelle zu lange
' dauert. Der Controller 'verschläft' dann eine Flanke des Signals. Das
' gleiche kann bei hohen Frequenzen in Kombination mit niedrigem
' Tastverhältnis passieren

' ----------------------------------------------------------------------------

INCLUDE "omac.def"         'Definitionen für die Open-Macro

DIM tastver_ergebnis WORD  'Ergebnis der Tastverhältnis-Messung
DIM tastver_letzter  WORD  'die letzte steigende Flanke merken
define Zahl  Word
define Taste   Port[3]     'stösst Messung an
define Trigger Port[4]     'löst Messung aus

PROCEDURE iiar_tim1 INLASM
 ! cbeqa #iTIM1,iiar_tim1_1 'Falls kein Aufruf durch TIM1-Interrupt,
 ! jmp iiar_tim1_ende+2     'dann zur nächsten IIAR in der Kette.
#iiar_tim1_1
! ldhx TCH1H
 ! brset bELS1A,TSC1,iiar_tim1_rising  'steigende oder fallende Flanke?
 ! txa                      'tastver_ergebnis = TCH1 - tastver_letzter
 ! sub tastver_letzter+1
 ! sta tastver_ergebnis+1
 ! pushh
 ! popa
 ! sbc tastver_letzter
 ! sta tastver_ergebnis
 ! mov #&b01000100,TSC1    'Input capture, Capture on rising edge only
 ! clc
 ! rts                      'Rücksprung ins Betriebssystem

#iiar_tim1_rising
! sthx tastver_letzter
 ! mov #&b01001000,TSC1    'Input capture, Capture on falling edge only
 ! clc
 ! rts                      'Rücksprung ins Betriebssystem
END PROCEDURE

PROCEDURE init_tim1 INLASM
'Before changing a channel function by writing to the MSxB or MSxA bit,
'set the TSTOP and TRST bits in the TIM status and control register (TSC).
 ! mov #&b00110000,TSC     'TSC: TOF TOIE TSTOP TRST 0 PS2 PS1 PS0
 ! mov #&b01000100,TSC1    'Input capture, Capture on rising edge only
 ! ldhx #&hffff
! sthx TMODH               'Modulo-Register auf Standardwert $ffff
'After initially enabling a TIM channel register for input capture operation
'and selecting the edge sensitivity, clear CHxF to ignore any erroneous
'edge detection flags.
 ! bclr bCH1F,TSC1
 ! mov #&b01000000,TSC     'Timer wieder starten
 ! rts
END PROCEDURE


' Timer Interface Module (TIM) wieder so setzen, wie vom OS erwartet

PROCEDURE reset_tim1 INLASM
 ! mov #&b00110000,TSC     'TSC: TOF TOIE TSTOP TRST 0 PS2 PS1 PS0
 ! clr TSC1                 'TIM Channel Status and Control Register
 ! ldhx #999               'Modulo-Register zurück auf OS-Wert
 ! sthx TMODH
 ! mov #&b01000110,TSC     'Timer wieder starten
 ! rts
END PROCEDURE

#iiar_tim1_ende           'hier hinter folgt die nächste IIAR
                            '(sofern vorhanden)
' --- Das Hauptprogramm -----------------------------------------------------

#main                     'Label für Hauptprogramm

 UIRTim1=ON                 'User-Assemblerroutine für TIM1 aktivieren
 init_tim1                  'Timer-Modul passend initialisieren

 'PrintSpc=ON                'SPACE vor einem dezimalen PRINT

WHILE true
if Taste=off then
  Trigger=on
  Pause 15
  Trigger=off
     PAUSE 5
     Zahl=tastver_ergebnis*10/187    'geht bis 16 cm, Pulsbreite 900 us
     PRINT Zahl/10;",";Zahl MOD 10;" cm"
     'Zahl=tastver_ergebnis/19      'ohne Nachkomma ab 16 cm
     'Print Zahl/10; " cm"
  Trigger=on
end if
WEND

 reset_tim1                 'Timer-Modul wieder auf Defaultkonfiguration
 End2Host=ON                'nach dem Programmende in den Host-Modus
END                         'Programmende

' ----------------------------------------------------------------------------

'Die Routinen für die Maxi (IR an DA2)

INCLUDE "omax.def"         'Definitionen für die Open-Maxi

DIM OnZeit WORD            'Ergebnis der Tastverhältnis-Messung
DIM tastver_letzter  WORD  'die letzte steigende Flanke merken
define Zahl  Word
define Taste   Port[9]
define Trigger Port[41] 'Beep

PROCEDURE iiar_tim1 INLASM
! cbeqa #iTPM2C1,isiTPM2C1
! jmp iiar_tim1_ende+2     'dann zur nächsten IIAR in der Kette.
#isiTPM2C1
! ldhx TPM2C1VH
! brset bELS1A,TPM2C1SC,iiar_tim21_rising  'steigende oder fallende Flanke?
! txa                                      'OnZeit = TCH1 - tastver_letzter
! sub tastver_letzter+1
! sta OnZeit+1
! pushh
! popa
! sbc tastver_letzter
! sta OnZeit
! mov #&b01000100,TPM2C1SC    'Input capture, Capture on rising edge only
! clc
! rts                      'Rücksprung ins Betriebssystem

#iiar_tim21_rising
! sthx tastver_letzter
! mov #&b01001000,TPM2C1SC    'Input capture, Capture on falling edge only
! clc
! rts                      'Rücksprung ins Betriebssystem
END PROCEDURE

PROC inittpm2 INLASM
! BSET bCH1IE,TPM2C1SC       'IR freischalten
'! mov #%00000000,TPM2SC    'TPM stop  ist nicht notwendig
! clr TPM2MODH
! clr TPM2MODL
! lda #%01000100           'Input capture, Capture on rising edge only, IR frei
! sta TPM2C1SC              'Timer 2 Channel 1 Status and Control Register
'! mov #%01001000,TPM2SC   'TPM clock input = BUSCLK/1 = 20000kHz, 50ns   (geht bis Pulsbreite 5us)
! mov #%01001010,TPM2SC    'TPM clock input = BUSCLK/4 = 5000kHz, 200ns
! rts
END PROC

' Timer Interface Module (TIM) wieder so setzen, wie vom OS erwartet
PROCEDURE reset_tim21 INLASM
! mov #%00000000,TPM2SC   'TPM stop
! ldhx #$00ff             'Timer 2 Counter Modulo Registers (TPMxMODH:TPMxMODL)
! sthx TPM2MODH            'von 0 bis inklusive 255 zählen (also Modulo 256) - (kein 100% duty cycle)
! lda #%00101000
! sta TPM2C1SC             'Timer 2 Channel 1 Status and Control Register /  High-true pulses
! mov #%00001101,TPM2SC   'TPM clock input = 20E6/32 = 625 kHz -> PWM-Frequenz 2441 Hz
! clc
! rts                      'Rücksprung ins Betriebssystem
end proc

#iiar_tim1_ende         'hier hinter folgt die nächste IIAR
                            '(sofern vorhanden)

' --- Das Hauptprogramm -----------------------------------------------------

#main                     'Label für Hauptprogramm

 UIRTPM2C1=ON              'User-Assemblerroutine für Timer 2, Kanal 1, DA2 aktivieren
 inittpm2                  'Timer-Modul passend initialisieren

WHILE true
if Taste=off then
  Trigger=on
  Pause 5
  Trigger=off
     PAUSE 5
     Zahl=OnZeit*10/291       'geht nur bis 10 cm Entfernung, ansonsten siehe Beispiel Macro
     PRINT Zahl/10;",";Zahl MOD 10;" cm"
end if
WEND

 UIRTPM2C1=off
 reset_tim21                'Timer-Modul wieder auf Defaultkonfiguration
 End2Host=ON                'nach dem Programmende in den Host-Modus
END                          'Programmende

' ----------------------------------------------------------------------------


 Antwort schreiben

Bisherige Antworten:

Re: Mit Ultraschall messen (von Norbert - 21.03.2016 12:49)
    über 32767 (von Dietmar - 21.03.2016 16:56)
        Re: über 32767 (von Norbert - 21.03.2016 17:57)
            Re: über 32767 (von Dietmar - 22.03.2016 0:44)
                Re: über 32767 (von Norbert - 22.03.2016 1:43)
                    Re: über 32767 (von Dietmar - 22.03.2016 13:41)
                       bei Open-Micro (von Dietmar - 23.03.2016 22:24)
Verbesserung für die Open-Maxi (von Dietmar - 9.03.2016 20:30)