PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Ultraschall - Entfernunsmessung mit Ultraschall Interface aus RN



Thegon
20.08.2011, 13:45
Hallo allerseits,

Ich werkle schon seit längerem an einer Ultraschall Enfernunsmessung und bin im Roboterwissen auf die Schaltung des Ultraschall - Interfaces von Manf gestoßen, bzw. hat mich besserwessi darauf aufmerksam gemacht. Diese Schaltung hat mir gleich zugesagt und ich habe es einmal ausprobiert, nur leider funktioniert es nicht so richtig.
Das stoppen der Zeit übernimmt ein ATmega48, der zuerst in einer Schleife 16 Perioden des US - Bursts erzeugt, die dann in den Start in Eingang der Ultraschall - Interface Schaltung gehen. Warum kein Timer? Das habe ich schon einmal in einen Thread gepostet, der Timer schafft in Bascom keine 40 kHz.
Dann beginnt das Stoppen der zeit, die dann in der isr des interruptpins umgerechnet und ausgegeben wird.
Das ganze soll starten, wenn per UART ein "go" eintrifft.
So weit so gut.

Nun kommt zwar etwas per UART herein, nur das ist ziemlich unbrauchbar.
Die Erste zahl ist total verrückt, die ist manchmal riesengroß, dann im minus und ich habe bemerkt, dass es einen unterschied macht, wie lange ich mir zwischen dem Go - Schreiben zeit lasse.
Darauf folgen konstant (fast immer, um genau zu sein) 16 Zahlen, die alle fast gleich groß sind, etwa um die 20 - 30, manchmal aber auch größer als 100.
Der Witz an der sache ist, dass dies per UART hereinkommt, egal, ob der Sendewandler angeschlossen ist oder nicht.


Ich habe lange herumprobiert, aber leider ohne erfolg.
Der Code des Atmels hier:


$regfile "M48def.dat"
$crystal = 1000000
$hwstack = 100
$swstack = 100
$framesize = 100
$baud = 2400

Dim Endtime As Long
Dim Countperoverflow As Integer
Dim Stringuser As String * 10
Dim Countperiodes As Byte

Config Timer0 = Timer , Prescale = 1
On Timer0 Isrtimer
Enable Interrupts

Config Int0 = Rising
Enable Int0
Enable Interrupts
On Int0 Isr_interrupt

Config Portd.3 = Output
Portd.3 = 1

Do
Input Stringuser
If Stringuser = "go" Then
'################# den Sendebrust generieren +++++++++
Countperiodes = 0
Do
Portd.3 = 0
Waitus 8
Portd.3 = 1
Waitus 8
Countperiodes = Countperiodes + 1
Loop Until Countperiodes > 16
Countperiodes = 0
Portd.3 = 1
'################################################# #####
'Warum nur acht us warten? Ich habe das einfach ausprobiert und so kommt man ungefähr auf 42 kHz

Enable Timer0
Stringuser = ""
End If
Loop


'###############TimerIsR##################
Isrtimer:
Countperoverflow = Countperoverflow + 1
Return
'#########################################

'#########Interrupt################
Isr_interrupt:
Disable Timer0
Endtime = Countperoverflow * 256
Endtime = Endtime + Timer0
Print Endtime
Endtime = 0
Countperoverflow = 0
Return


Wäre sehr dankbar, könnte mir jemand sagen, was ich anders machen sollte bzw. wo der Fehler liegt.
Dass die Schaltung des US - Interfaces fehler aufweist, glaube ich eher nicht, ich habe sie durchgeprüft und gemessen, wo es etwas zu messen gibt. Ich kann mich aber natürlich auch täuschen.

Richard
20.08.2011, 20:15
Das habe ich schon einmal in einen Thread gepostet, der Timer schafft in Bascom keine 40 kHz.


1e6÷40e3 = 25, 256-25 = 231. Warum sollte der Timer es nicht schaffen alle 25 µs einen über lauf zu produzieren? Zur Not kann man auch eine höhere Takt Frequenz wählen. Sehe Dir auch einmal die Bascom Funktion pulsout/pulsin oder sound an, gearbeitet habe ich damit aber auch noch nicht

Gruß Richard

Thegon
20.08.2011, 21:04
Hallo Richard,
der Thread ist hier:
https://www.roboternetz.de/community/threads/54220-ATmega48-Timer0-Problem-zählt-zu-langsam
Ich kann leider kein ASM, und die versuche einer Fastpwm bzw. CTC modus des timers haben leider nicht funktioniert.
Ich bin jetzt noch drauf gekommen, dass man das US - Modul mit der Schaltung völlig weglassen kann, man muss nur start in und pulse out verbinden und erhält genau das gleiche Resultat. Da kann doch etwas nicht ganz stimmen ...
Ich habe dann noch einen AVR so programmiert, dass er sozusagen eine virtuelle laufzeitverzögerung von 5000 us erzeugt, und es hat funktioniert, die zeit zu stoppen, mit genau diesem Code. Es muss also doch an der Hardware liegen.
Noch eine Frage: Ich habe Disable Timer0 geschrieben, nur irgentwie kommt mir vor, dass der timer weiterzählt und auch überläufe erzeugt. Kann das sein?

Ich habe auch auf dem US-Modul mit der schaltung zwischen START IN und PULSEOUT gemessen (Widerstand), doch der war zu groß, um ihn zu erfassen, es kann sich also nicht um einen Kurzschluss handeln. Hat jemand eine Idee, wie ein solch seltsames Ergebnis entstehen kann? Ich werde wohl noch alles durchmessen und berichten.
Mfg Thegon

Searcher
20.08.2011, 21:32
Hallo,
im anderen thread gab es Unstimmigkeiten mit der $crystal und tatsächlicher Prozessorfrequenz.

Hier hast Du 1MHz eingestellt. Wenn der Prozessor mit 8MHz läuft, könnten da die Probleme mit der UART liegen?

Gruß
Searcher

Thegon
20.08.2011, 21:37
Also jetzt läuft der prozessor mit 1 MHz, der 8 fach teiler ist aktiv. Uart macht eigentlich keine Probleme, ich sende einfach "go" und der AVR sendet mir ein Paar zahlen, mit denen ich leider nichts anfangen kann ;-)
Ich habe aber vorher auch schon text ans terminal gesendet und es hat ohne probleme funktioniert.
Mfg Thegon

Searcher
20.08.2011, 21:46
Noch eine Frage: Ich habe Disable Timer0 geschrieben, nur irgentwie kommt mir vor, dass der timer weiterzählt und auch überläufe erzeugt. Kann das sein?

Nochmal Hallo :-),

DISABLE TIMER0 unterdrückt Interrupts vom Timer0. Der Timer läuft aber weiter. Zum Anhalten: STOP TIMER0.

Es könnte sein, das noch das OVF0 Flag gesetzt ist, wenn der letzte Interrupt noch nicht abgearbeitet wurde. Könnte man sicherheitshalber nach Disable Timer0 mit SET TIFR0.OVF0 löschen oder TIFR0.OVF0 = 1

Gruß
Searcher

Thegon
20.08.2011, 21:55
Kann es sein, dass das register TIFR0.TOV0 heißt, denn OVF0 steht nicht im Datenblatt und wird von bascom nicht erkannt?

EDIT: Das Problem ist nämlich, dass die erste gesendete zahl umso größer wird, um so länger ich mir zeit lasse und das nächste mal go schreibe.
Wenn ich mir sehr viel zeit lasse, wird sie sogar negativ, ich nehme an, sie ist dann zu groß für long und es fängt dann alles von vorne an.
Ich habe stop geschrieben, dann auch Start timer0, aber es hat sich leider am resultat nichts getan.
Mfg Thegon

Searcher
20.08.2011, 21:58
Ja, ist TOV0. Hab mich verguckt. Bin mir nicht sicher, ob das hilft. Schaden kann es nicht.

Gruß
Searcher

Searcher
20.08.2011, 22:18
Hab noch mal eine Frage: Wie soll das Programm funktionieren?

1. Go kommt
2. mit 40kHz werden 16 Impulse erzeugt
3. in der INT0 ISR soll die Zeit vom Begin der 40kHz bis Auslösen des INT0 über UART mit Print ausgegeben werden.

Print braucht so seine Zeit. Der INT0 ist die ganze Zeit aktiv. Deshalb die 16 Zahlen über UART?
Vielleicht die gestoppte Zeit in Array speichern und nicht in der ISR ausgeben sondern im Hauptprogramm?


EDIT Wenn ich richtig sehe, ist INT0 auf PD2. Der ist nirgends konfiguriert. Kann es sein, das der floatet und von dem danebenliegenden Ausgabepin PD3 mitgezogen wird? Internen Pullup einschalten?

Gruß
Searcher

Thegon
21.08.2011, 11:11
Hallo Searcher,
du hast recht, der interrupt pin hat gefloatet, dauerhaft, am anfang. Dann habe ich einen Externen pulldown von 10k gegen masse angehängt und er hat Ruhe gegeben, nur dass er eben immer 16 zahlen zu viel sendet. Meine Theorie: am ausgang werden 17 impulse des US - bursts ausgegeben, diese kommen über einen Fehler auf der Platine an den Interruptpin, das würde auch von der zeit etwa zusammenstimmen. Wenn der letzte impuls kommt, wird der timer wieder resettet, da aber kein interrupt mehr kommt, läuft er weiter, bis das nächste mal go geschrieben wird, dann ist die zahl natürlich riesig.
Ich habe die Platine aber schon mitdestens fünf mal durchgeprüft und keine Fehler gefunden, leider will mein oszi nicht, und so stehe ich jetzt einmal an. Ich hatte an einen Fehler im Flipflop gedacht, sodass am ausgang immer das ausgegeben wird, was am eingang anliegt, aber ich kann beim besten willen nichts finden. Das verrückte ist ja, dass es nichts mit Ultraschall zu tun hat, mein seltsames ergebnis. Ich habe den sendewandler ausgelötet und : genau das gleiche.

Sonst: du hast das prinzip meines programmes völlig richtig erfasst, in deinm beitrag eins weiter oben.

Ich befürchte, die einzige möglichkeit, hier noch etwas zu machen, ist das oszi in gang zu bekommen und einmal zu schauen, was sich in der Schaltung wirklich abspielt, nachdem go gesendet wurde. Ich werde schreiben, wenn ich neue Erkenntnisse gemacht habe.
Mfg Thegon

Searcher
21.08.2011, 11:43
Hallo,
wenigstens schon etwas gefunden.

Mich interessiert die Schaltung auch. Hast Du die aus dem Wiki http://www.rn-wissen.de/index.php/Ultraschall-Interface 1:1 nachgebaut?

In Deinem Programm stört mich noch das Print in der ISR. Ablaufzeit in einer ISR sollte ja so kurz wie möglich sein. Wenn nur der erste Wert intressiert, wäre es egal...?

Ich habe vor so ein Meßprogramm zu schreiben. Dazu nehme ich mangels Bauteilen einen Atiny25 als Simulator, der mir entsprechende Anschlüsse und Signale des US-Interfaces zur Verfügung stellt. Ich denke zunächst mal an ein Eintreffen des Echos nach 3ms, daß einer Entfernung von ca 50cm entspricht. (Schallgeschwindigkeit 343m/s - 1s/343m = 0,0029s/m - Hin und zurück - Distanz 50cm)?

Gemessen wird dann mit einem Attiny45.

Mal sehen, ob es am Programm oder Platine liegt und ob ich überhaupt was hinkrieg.

Gruß
Searcher

Thegon
21.08.2011, 11:48
Ja, die habe ich fast 1:1 nachgebaut, nur der schwingkreis hat eine andere Spule, da ich die passende mit 4,7mH nicht habe, aber ich habe den Kondensator angepasst und somit hat er eine Resonanzfreq. von 40,1 kHz.
Bin schon gespannt, was bei dir rauskommt ;-)
Mfg Thegon

Thegon
21.08.2011, 19:56
Ich habe das Oszi in gang gebracht, jetzt muss ich von traurigen Erkenntnissen berichten: ;-(
als erstes hat einmal die Freqenz des Bursts nicht gestimmt, war mit etwa 30 kHz zu klein, die habe ich aber gleich ausgebessert.
dann habe ich am ausgang (pulse out) gemessen, es kommt gar nichts raus
Ich habe am transistor des Teiles "Amplifier" gemessen, (Kollektor): nichts was größer ist als 10 mV, das könnte gut auch rauschen sein.
Ich habe am transistor des Teiles "Swich & Comperator" gemessen (auch Kollektor): (Jetzt kommts...) Normaler weise 5V, dan sinkt der pegel im 40 kHz Takt ab und schießt rechteckartig wieder hoch, also so etwas wie eine verkehrte (nach unten gedrehte) Sätezahnspannung.
Dann habe ich den Emfangswander abgeschlossen: das gleiche Resultat. ;-( Es hat also nichts mit dem Ultraschall zu tun...
Ich habe dann den Gatterbaustein 4011 verdächtigt, den aber später durchgemessen und ausprobiert, der funktioniert jedoch wunderbar.
Die sendekapsel bekommt, was sie bekommen soll: eine Rechteckspannung mit einer Amplitude von 5 V gegen masse gemessen, es wären dann 10 V, wenn ich zwischen den beiden Pins des Wandlers messen würde, denke ich.
Jetzt weiß ich beim besten Willen nicht mehr, was falsch sein könnte. Hätte jemand eine Idee?
Falls noch irgenteine messung oder andere angaben benötigt werden, ich versuche, so schnell als möglich zu antworten.
Danke für die Antworten, die mir schon gegeben wurden und schon im voraus für die, die noch kommen ;-)
Mfg Thegon

Besserwessi
21.08.2011, 21:54
In dem Schaltplan fehlt der Kondensator an der Versorgungsspannung dadurch ist es möglich das Störungen über die Versorgungsspannung von der Sendeseite zur Empfangsseite kommen.

Der Eingangsteil kann auch Störungen einfach kapazitiv einfangen. Da sollte man ggf. etwas Abschirmung haben und ggf. den Test ohne Eingangssignal mit einem Kurzschluss über den Empfänger machen. Wenn man einfach die Empfangskapsel abklemmt, steigt die Empfindlichkeit gegen Störungen deutlich an.

Searcher
21.08.2011, 22:10
Hallo Thegon,
leider noch eine nicht so gute Nachricht:(.

Hab meinen Testaufbau fertig und das Meßprogramm ist in etwa so wie bei Dir aufgebaut:

Systemtakt ist bei mir 8Mhz interner Oszillator; Timer0 läuft mit 1MHz (Prescaler = 8 ). Der schnellere Systemtakt soll vor allem die ISRs schneller machen.

Gestartet wird über ein Taster

Nach Senden des Bursts, den ich nach Deiner Methode erzeuge (mit waitus 11 komme ich auf 41kHz), wird mit dem Timer die Zeitmessung gestartet. Bursts sind bei mir eigentlich egal, da der Tiny25 Simulator einfach nur auf ein low wartet und dann sofort einen Pin als Echo für 3ms nach low zieht. Hoffe, hab das richtig simuliert. Soll eine Distanz von ca 50cm darstellen.

Overflows werden im Timer0 OVF-Interrupt gezählt.

Trifft das Meßende nach ca 3000µs (mit Oszi kontrolliert) ein, wird in der INT0 ISR die Zeit gesichert und später im Hauptprogramm ausgegeben.

Bei meinem Glück/Pech trifft das Meßende in der Nähe eines Timer0 Überlaufs ein und damit geht ab und zu ein Überlauf verloren. Bedeutet eine Ungenauigkeit/Abweichúng von mindestens 256µs. Sieht aus, als wenn der Timerüberlauf gerade kommt, wenn der INT0 abgearbeitet wird.

Ansonsten ist die Abweichung der einzelnen Meßwerte untereinander zwischen 0 und 25µs.

Werde noch ein bißchen probieren, denke aber, das man da anders rangehen muß.

Besser wäre auf jeden Fall ein 16 Bit Timer. Du müßtest doch auf dem ATMega48 noch einen frei haben? Ohne die Overflow ISR sind die Abweichungen nur noch sehr gering.

Viel Glück bei der HW. Es kann nur noch bessser werden \\:D/ Der Oszi geht ja schon wieder.


Gruß
Searcher

Besserwessi
21.08.2011, 22:43
Mit etwas Umstand kann man den fehlenden Overflow Interrupt erkennen. Das geht so ähnlich wie bei der Erweiterung der ICP Funktion auf mehr als 16 Bit.

In der ISR zu INT0 prüft man ob der Timer-wert klein ist (z.B. kleiner als 128 ) und das Flag für den Overflow Interrupt gesetzt ist. In diesem Fall müsste der Overflow Interrupt erst vor den Signal kommen - man zählt also einfach einen Überlauf dazu.

Thegon
22.08.2011, 11:59
Hallo,
hat jetzt etwas gedauert, aber ich habe nun 2 Kondensatoren eingelötet, einen direkt an die versorgungsspannungsanschlüssen (220uF) und noch einen an die versorgungsspannungspins des 4011. Man kan wohl von einer veränderung sprechen: jetzt kommt überhaupt kein Interrupt mehr herein.
Naja, immerhin schon mal besser als 16, die nicht sollten.

Ich habe noch einmal die Frequenz des ausgangsbursts gemessen, sie beträgt wunderschöne 40,1 kHz, tastverhältnis 63 % (ich hoffe, das macht nichts ). diese kommen auch beim Sendewandler an. Die Veff zwischen den Sendewandlerpolen ist mit V~ einstellung des Multimeters nicht wirklich zu messen, kurz zeigt er ca. 11V an, dann nur mehr 0,6. Ich denke aber, dass die Freq. ein bisschen zu schnell für das messgerät ist. Ich nehme an, das Senden darf als Problemquelle erst einmal außer Acht gelassen werden. Ich komzentriere mich derzeit auf die Eingangsverstärkungund den Schwingkreis.

Ich habe dann noch einen interessanten test durchgeführt: mit einer Batterie (ca. 1V) an den Pins des Empfangswanlers "kitzeln" Dies löst Interrupts aus, was heißt, dass zumindest etwas durch die Schaltung durchkommt, wenn auch nur notdürftig.

Zu den obrigen beiträgen: wegen 25 us ungenauigkeit (die auch bei meinen simulations - tests auftraten) will ich mir nicht den Kopf zerbrechen, das wäre ja umgerechnet eine ungenauigkeit von weniger als 0,5 cm, so genau muss das ganze nicht sein, mir würde eine genauigkeit von 1-2 cm völlig genügen, was dan eine max. ungenauigkeit von 120 us wären.
EDIT: Ah, das mit dem Interupt habe ich erst nicht ganz genau gelesen, ich denke, daran lässt sich ja noch feilen, wie Besserwessi geschrieben hat.


Freut mich übrigens sehr, dass du (Searcher) dich auch tatkräftig mit meinem Problem beschäftigst ;-)
Mfg Thegon

Searcher
22.08.2011, 13:18
Hallo,


...jetzt kommt überhaupt kein Interrupt mehr herein. Naja, immerhin schon mal besser als 16, die nicht sollten.
aber es ist Bewegung drin und das ist immer gut :)

Ich bin auch weiter und habe meinen gegenwärtigen Code mal eingefügt. Bitte die umständliche Meßwertausgabe nicht weiter beachten :-) Unten dran noch der Simulatorcode.



In der ISR zu INT0 prüft man ob der Timer-wert klein ist (z.B. kleiner als 128 ) und das Flag für den Overflow Interrupt gesetzt ist.
Die Anregung ist eingeflossen durch Stoppen des Timers und Abfrage des TOV0 Flags in der INT0 ISR. Hatte gestern ähnlich probiert, aber die Timerstand Variable noch analog zum TCNT0 Register als Byte deklariert gehabt. Addieren von 256 brachte da noch irritierende Meßergebnisse.

Nun läuft es aber und die Abweichungen der Messergebnisse betragen nur noch maximal 16µs. Der tatsächliche Fehler muß noch kleiner sein, da ich auf dem mitlaufenden Oszilloskop kleine Veränderungen der Pulsweite auf "Pulse out" gemessen habe, die analog in das Meßergebnis eingingen.

Größenordnungen:
16Pulse mit 41kHz. Simulator schickt sofort Meßbeginn zurück. Meßende nach 3ms. Mit Oszi gemessener Meßpuls vom Simulator zwischen 2968µs und 2974µs, Meßanzeige zwischen 2592µs und 2608.

Das Ganze ist auf Steckbrett aufgebaut und die beiden Signalverbindungen zwischen den µCs über 1k Widerstände gemacht.

Weiter Daumen drückend für die HW und Dank auch Dir und allen Beteiligten für den thread.
Gruß
Searcher


'################################################# ##
'File: US-Meßprogramm.bas
'IDE: BASCOM-AVR DEMO Version 2.0.5.0
'Meßprogramm zum Messen von US-Laufzeit mit RN Wiki US-Interface
'Messung wird erst gestartet, wenn der Burst komplett gesendet wurde
'Messung wird gestoppt mit Eintreffen des 0 nach 1 Wechsel auf PB2
'
'ATtiny45
'Mit Taster an PB4 den Burst und Messen starten
'Eingang an PB2 (INT0) - Meßpulsempfang vom Interface
'Ausgang an PB1 - 16 Pulse mit 40kHz zum Interface
'Ausgabe der Meßwerte über PB3 mit SW UART an 4 fach 7-Segmentanzeige
'################################################# ######

$regfile = "attiny45.dat"
$framesize = 32
$swstack = 40
$hwstack = 40
$crystal = 8000000 'interner Oszillator

'##### Definitionen für 7segment ausgabe ######
Dim Num_to_disp As Word
Dim Y As Byte
Dim Helperbyte As Byte
Dim Index As Byte
Dim Disp_string As String * 6
Dim Digit_char As String * 1
Declare Sub Display_value(num_to_disp As Word)
Open "comb.3:115200,8,n,1" For Output As #1 'comb.3 -> TX ist Pin PB3
'#### ende Definitionen für 7segmentausgabe #######

Dim Pulsecount As Byte
Dim Timer0_overflows As Word 'kann 65535 overflows zählen
Dim Endtime As Word 'geht bis 65535 µs = 65,535 ms, meine Anzeige bis &D9999
Dim Timerstand As Word
Dim Flag_messung_ende As Byte
Dim Flag_ausgabe_fertig As Byte

Portb = &B11110101 'alle Pullups auf portb einschalten, Ausnahme PB1, PB3
Config Portb.1 = Output

Config Int0 = Rising
On Int0 Isr_stop_messung
Enable Int0

Config Timer0 = Timer , Prescale = 8 'Timer wird hier mit 1Mhz gestartet (8Mhz Systemclk)
On Timer0 Isr_count_overflows
Stop Timer0 'Timer stoppen
Enable Timer0 'overflow interrupts Timer0 erlauben

Portb.1 = 1 'Ausgangsruhezustand auf Burst out Pin

Endtime = 0
Call Display_value(endtime) '7 Segment initialisieren
Call Display_value(endtime) '7 Segment initialisieren

Enable Interrupts

Do 'Beginn Hauptprogramm
Do 'Warten auf Tastendruck (PB4 nach GND)
Debounce Pinb.4 , 0 , Start_mit_burst
Loop

Start_mit_burst:
For Pulsecount = 1 To 16 '16 Pulse erzeugen (Burst mit ca 41kHz)
Reset Portb.1
Waitus 11
Set Portb.1
Waitus 11
Next Pulsecount

Flag_messung_ende = 0
Flag_ausgabe_fertig = 0
Timer0_overflows = 0
Timer0 = 0 'Timerzähler (TCNT0) mit 0 initialisieren
Start Timer0 'Meßzeit beginnt

Do 'Schleife zum Warten auf Meßende
If Flag_messung_ende = 1 Then 'Wenn Messung zu Ende, dann zur Anzeige
Endtime = Timer0_overflows * 256 'Meßzeit in µs ausrechnen
Endtime = Endtime + Timerstand 'Meßzeit in µs ausrechnen
Disable Interrupts 'ohne disable irgendwelche Probleme bei meiner Spezialausgabe
Call Display_value(endtime) 'Meßzeitausgabe über 7 Segmentanzeige
Enable Interrupts
Endtime = 0
Flag_ausgabe_fertig = 1
End If
Loop Until Flag_ausgabe_fertig = 1 'Ende Warterei wenn Anzeige des Meßwertes erfolgt ist
Loop 'Loop Hauptprogramm

Isr_count_overflows: 'Ansprung, wenn Timer0 überläuft
Incr Timer0_overflows
Return

Isr_stop_messung: 'Ansprung bei Eintreffen rising edge an Pb2 über INT0
Stop Timer0 'Meßzeit Ende, Timer anhalten, neuen OVF0 verhindern
Timerstand = Timer0 'Timerstand sichern
If Tifr.tov0 = 1 Then 'Falls bis "Stop Timer0" noch ein OVF0 aufgetreten ->
Timerstand = Timerstand + 256 'hier berücksichtigen
Set Tifr.tov0 'Timeroverflowflag löschen
End If
Flag_messung_ende = 1 'Indikation für Ausführen der Anzeige Meßwert in Hauptprogramm
Return


'############ Folgende Zeilen bis zum Ende nur zur Datenausgabe über 7 Segmentanzeige #############
Sub Display_value(num_to_disp As Word) 'gibt Dezimalzahlen bis 9999 aus
Disp_string = Str(num_to_disp)
For Y = Len(disp_string) To 3
Helperbyte = Lookup(16 , Segmentpattern)
Put #1 , Helperbyte
Next
For Y = 1 To Len(disp_string)
Digit_char = Mid(disp_string , Y , 1 )
Index = Val(digit_char)
Helperbyte = Lookup(index , Segmentpattern)
Put #1 , Helperbyte
Next
End Sub

Segmentpattern: 'darzustellende Zeichen (hex 0..F...)
'Segmente abcdefg: ' ":" = Doppelpunkt in der Mitte
Data &B00000011 'Ziffer "0", 0 = segment ein, 1 = aus
Data &B10011111 'Ziffer "1"
Data &B00100101 'Ziffer "2"
Data &B00001101
Data &B10011001
Data &B01001001
Data &B01000001
Data &B00011111
Data &B00000001
Data &B00001001
Data &B00010001
Data &B11000001
Data &B01100011
Data &B10000101
Data &B01100001 'Ziffer "E"
Data &B01110001 'Ziffer "F"
Data &B11111111 'dunkel
Data &B11111101 'nur Segment g eingeschaltet (-)

'########### ENDE US-Meßprogramm.bas ##############################################





'################################################# ##
'File: US-Simulator.bas
'IDE: BASCOM-AVR DEMO Version 2.0.5.0
'Ulraschall Interface Simulator nach RN Wiki US-Interface
'
'ATtiny25
'Eingang an PB2 (INT0) - Start in
'Ausgang an PB3 - Pulse out
'################################################# ######

$regfile = "attiny25.dat"
$framesize = 32
$swstack = 40
$hwstack = 40
$crystal = 8000000 'interner Oszillator

Portb = &B11110111 'alle Pullups auf portb einschalten, Ausnahme PB3
Config Portb.3 = Output

Config Int0 = Falling 'INT0 bei Wechsel von 1 auf 0 an port PB2 "Start in"
On Int0 Isr_simulate_us_messung

Portb.3 = 1 'Wiki US Interface "Pulse out" Ruhezustand

Enable Int0
Enable Interrupts

Do
'Hauptschleife: INT0 macht schon die ganze Arbeit
Loop

Isr_simulate_us_messung: 'Ansprung Bei Eintreffen Von Pulsen An Pb2
Portb.3 = 0 'Pulse out auf 0 zeigt Meßbeginn
Waitms 3 'simulieren von 3ms Gesmatlaufzeit des Schalls
Portb.3 = 1 '"Echo" eingetroffen
Set Gifr.intf0 'durch empfangenen Burst neues anstehendes INTF0 Flag löschen
Return

'########## ENDE US-Simulator.bas #######################

Thegon
22.08.2011, 13:44
Danke für den Code, ich denke, ich werde meinen einmal ein bisschen verbessern.
Ich habe auch von der HW neuigkeiten: Das Problem sollte zwischen Empfängerkapsel und dem Collector des Transistors im Comperator & swich teil liegen,

denn neueste erkenntnisse lauten:
1) 20 perioden des US Bursts werden korrekt mit 40,7 khz ausgegeben, der Sendewandler hat an den Polen eine Amplitude von ca. 11V, wie sich das gehört.
2) Das Flipflop wird zum kippen gebracht, es geht Pulse out auf low.
3) Jetzt kommt kein Signal seiten der Empfängerschaltung, so bleibt das Flipflop für immer auf low. (am Pulse out) :-(
4) Die rampe wird gestartet und läuft, bis sie oben ansteht (ca. 4,5V wegen dioden, denke ich ) und bleibt so, da kein impuls oder ähnliches ankommt
5) Natürlich wird dann auch kein Interrupt ausgelöst

Das mit dem Oszi ist schon eine Seltsame geschichte:
es ist ein HPS5 von Vellemann, ziemlich alt und wird auch schon nicht mehr verkauft.
Manchmal will es einfach nicht starten: Ich stecke die Stromversorgung an (9V DC netztteil) und garnichts passiert. Ich habe das netzteil überprüft und wieder angeschlossen, da hat es einwandfrei funktioniert (ich habe dann geschieben: ich habe das Oszi wieder in gang gebracht)
Heute wollte ich an dem Amplifier Transistor messen, das oszi wieder angesteckt: leerer Bildschirm :-(
das ganze noch ein paar mal wiederholt, reset gedrückt usw. : ohne erfolg
Hat villeicht jemand eine Idee, was ich da tun könnte? Ohne oszi ist es nämlich schwierig, beim US - interface irgentwas herauszufinden...
Mfg Thegon

Searcher
22.08.2011, 16:53
Danke für den Code, ich denke, ich werde meinen einmal ein bisschen verbessern.

Hab bei mir noch eine Macke entdeckt. Habe die Pulsweite noch ein bißchen variirt und bekomme Werte von 2568 bis 2583 nicht angezeigt. Also kurz nach nach 10 Timer0 Überläufen.

Vermutung: INT0 trifft ein, wenn gerade die Überlauf-ISR läuft und der INT0 etwas warten muß.

Allein das würde eine "echte" Ungenauigkeit von 16µs verursachen. Denke auch, daß das vernachlässigbar ist. Bin gespannt, wie es mit dem richtigen Interface läuft.

PS @Thegon: Welche Schallwandler benutzt Du.

Leider traue ich mich nicht, Dir Tipps zum Oszi zu geben außer so Laienüberprüfungen wie Wackelkontakt? oder Netzteil tauschen? Ausgetrocknete Elkos? aber wo???
Gruß
Searcher

Besserwessi
22.08.2011, 17:15
Das Problem mit der Verzögerung durch den Overflow Interrupt kann gut sein. Ganz vermeiden kann man das nicht beim Tiny25, dazu bräuchte man schon einen µC mit "input capture" (z.B. Tiny2313 oder MEga48) oder eine ähnliche externe Hardware. Man kann das Problem aber reduzieren, indem man die ISR für den Overflow als Inline ASM schreibt. Die ISR ist in BASCOM ausgesprochen langsam, weil viel zu viele Register gerettet werden. So etwa 100 Zyklen sind das minimum für eine praktisch leere ISR. Da kommen die 16 µs gut hin. Mit Inline-ASM könnte man da auf etwa 10-15 Zyklen kommen, das wären dann nur 2 µs als möglicher Fehler. Einen Vorteil hat BASCOM immerhin, inline ASM ist relativ einfach im Vergleich zu GCC. Eine kurze Erklärung gibt es hier:
http://www.rn-wissen.de/index.php/Bascom_Debounce_ISR_in_Assembler#Warum_eine_ISR_in _Assembler_programmieren.3F

Thegon
22.08.2011, 17:23
Hallo,

Die schallwandler stammen aus einer Platine von Conrad, die ich mir ursprünlich für Abstandswarnung auf meinem Roboter gekauft habe. Da diese aber nur einen I/O ausgang hat ("kritische" entfernung per poti einstellbar) und noch dazu nicht genau ist, habe ich eben versucht, so was mit Laufzeitmessung zu bauen ;-)
Artikel hier: http://www.conrad.at/ce/de/product/114456/ULTRASCHALL-ABSTANDSWARNER-BAUSATZ/SHOP_AREA_17362&promotionareaSearchDetail=005
Es gibt auch eine anleitung dazu (wahrscheinlich interessanter)
http://www.conrad.at/ce/de/product/114456/ULTRASCHALL-ABSTANDSWARNER-BAUSATZ/SHOP_AREA_17362&promotionareaSearchDetail=005
Die Teile hab ich einfach ausgelötet und verwende sie nun. Auf der Platine haben sie bereits funktioniert.

Ich muss zugeben dass die Frage mit dem Oszi eigentlich eh etwas überflüssig war, weil ich so eine "Laienprüfung" durchgefürhrt (kein spannunseinbruch wackelkontakt oä., das Netzteil liefert auch eingesteckt 9V) habe und ich mich sowieso nicht trauen würde, im inneren etwas zu modifizieren. Genau genommen gehört es nicht einmal mir selbst, ein Bekannter hat es mir geliehen, da er es schon seit ewigkeiten nicht mehr wirklich gebraucht hat. Habe mir diesbezüglich aber nichts vorzuhalten, es ist ja wirklich schon alt und ich habe es immer wie ein Heiligtum behandelt ;-)

Da ich ohne Oszi eigentlich keine Cance habe, herauszufinden, wo der Fehler in der Schaltung liegt, ja nicht einmal ob etwas im Empfangswander ankommt, befürchte ich, so bald nichts neues berichten zu können. Ich kenne jemanden, der ein DSO besitzt und werde den mal fragen, ob ich ein paar messungen machen darf. Aber: Ich teste natürlich mit dem Voltmeter weiter ;-)
Überlege auch schon ernsthaft, ob ich mir einmal ein eigenes, nicht zu teures DSO zulegen soll...

EDIT: zu beitrag von Besserwessi
ASM .. oh je.. ;-) kann leider kein bisschen ASM
aber 16 us sind so wenig, dass das bei mir überhaupt keine Rolle Spielt.
Das Modul soll später einmal drehbar auf meinem Roboter montiert werden, dass er messungen in jede richtung durchführen kann und sich so über eventuelle hindernisse informieren kann, entweder für den Benutzer oder, um eben ein bisschen auszuweichen. Da spielt 1cm abweichung für mich überhaupt keine Rolle, mehr als 5cm wäre schlecht, aber 1cm liegt für mich absolut im Toleranzbereich.

Mfg Thegon

Searcher
22.08.2011, 17:34
Mit Inline-ASM könnte man da auf etwa 10-15 Zyklen kommen, das wären dann nur 2 µs als möglicher Fehler. Einen Vorteil hat BASCOM immerhin, inline ASM ist relativ einfach im Vergleich zu GCC

Ich winde mich hier auf meinem Stuhl hin und her :-) Die Möglichkeit ist mir bekannt und weis nicht, ob ich die Büchse der Pandora öffnen soll :-) Mal sehen, wäre ein neuer Schritt für mich... und reizt mich auch. Denke aber, es wird kein neues Programmupdate von mir geben, mindestens bevor das IF von Thegon fertig ist;)

@Thegon: Danke für die Info zum Schallwandler.
Ich habe am Anfang mal mit einem Soundkartenoszi gearbeitet. Das ging behelfsmäßig ganz gut bis etwa 10kHz. Ist auch von der verwendeten Soundkarte abhängig. Braucht aber mindestens einen Spannungsteiler am Sounkarteneingang. Ob das bei 40kHz wirklich weiterhilft?

Gruß
Searcher

Thegon
22.08.2011, 17:41
Soundkartenoszi, interessanter Gedanke, würde ja auch nichts kosten, wenn ich eine Freeware bekomme, und schaden kanns ja eigentlich auch nicht, wenn man vorsichtig ist.
Ich werde mich mal ein bisschen umschauen, danke für den Tipp!

Mfg Thegon

Manf
22.08.2011, 18:22
Ich habe bisher schon mitgelesen und wollte zunächst nur noch sagen, dass man grundsätzlich die möglichen Fehlerursachen so gut wie möglich voneinander trennen sollte. Es ist ja bei einer Analogschaltung ein großer Vorteil wenn ein Oszilloskop zur Verfügung steht. Bei dieser Schaltung sollte man dabei auf den Sendepuls triggern und das Empfangssignal möglichst direkt am Empfangswandler aufnehmen.
Man Überprüft damit zunächst eben nur die Wandler und schafft den Teil des Systems schon mal auf die sichere Seite.

Da ein Oszilloskop nicht gerade für unverstärkte Ultraschallsignale gebaut ist sollte man hierzu das Empfangssignal so groß wie möglich machen, beispielsweise durch das heranführen des Empfangswandlers an den Sendewandler. Da beim Senden die Störungen am größten sind hilft es, die Kopplung zwischen den Wandlern herzustellen und alternativ mit einem Blatt Papier zu trennen. Zwei lose Lagen sind schon eine gute Abschirmung. Man kann so erkennen was über die Wandler übertragen wird.

Störungsfrei und trotzdem stark wird das Signal, wenn man eine Laufzeit zwischen den Wandlern vorsieht die keine Ausbreitungsverluste hat, also ein Rohr zwischen den Wandlern, sind sie schon nebeneinander montiert, dann eben ein Stück Schlauch damit man um die Kurve kommt.

Wenn man sieht dass es ein Signal gibt das vom Sendepuls erzeugt wurde dann kann man sich in ähnlicher Weise den Verstärker vornehmen, zunächst mit starken Signalen ohne Ausbreitungsverluste. Die Verstärkung lässt sich dann gegebenenfalls auch noch erhöhen, Hauptsache man sieht erst einmal das Signal.

Thegon
22.08.2011, 18:57
Nun wie schon gesagt, es wird leider noch ein bisschen dauern bis ich wieder an ein Oszi komme, dann werde ich auf jeden Fall ausprobieren, was Manf geschieben hat. Zurzeit heißt es für mich warten, leider.
Mfg Thegon

Richard
22.08.2011, 19:05
Nun wie schon gesagt, es wird leider noch ein bisschen dauern bis ich wieder an ein Oszi komme, dann werde ich auf jeden Fall ausprobieren, was Manf geschieben hat. Zurzeit heißt es für mich warten, leider.
Mfg Thegon


Für Windows gibt es scope.EXE für Lau. :-)

Gruß Richard

Besserwessi
22.08.2011, 19:06
Die ISR zum Hochzählen einer Wordvariable ist wirklich nicht schwer in ASM. Da sollte sich eine passenden Hilfe finden. Immerhin ist das ja auch kein so seltener Fall. Das sind aber Feinheiten, erst sollte die Hardware funktionieren.

radbruch
22.08.2011, 19:53
Hallo

Mit US habe ich noch nichts gemacht, deshalb ist die Frage vielleicht blöd. Warum macht ihr es nicht so?


Disable Int0
do 'Beginn Hauptprogramm
Do 'Warten auf Tastendruck (PB4 nach GND)
Debounce Pinb.4 , 0 , Start_mit_burst
Loop

Start_mit_burst:
Endtime = 0
For Pulsecount = 1 To 16 '16 Pulse erzeugen (Burst mit ca 41kHz)
Reset Portb.1
Waitus 11
Set Portb.1
Waitus 11
Next Pulsecount

Disable Interrupts ' kann auch bei der Zeitmessung nicht schaden
While Pinb.0 = 0
Incr Endtime
Wend

Call Display_value(endtime) 'Meßzeitausgabe über 7 Segmentanzeige
Enable Interrupts

While Pinb.0 = 1
Wend

Loop 'Loop Hauptprogramm


Gruß

mic

Searcher
22.08.2011, 20:55
Mit US habe ich noch nichts gemacht, deshalb ist die Frage vielleicht blöd. Warum macht ihr es nicht so?
Keine Ahnung. Dann hätten wir keine Probleme mit dem Interrupt Timing und wir müßten kein ASM lernen :-)

Nein, etwas ernster: Ich denke nicht, daß das speziell was mit Ultraschall zu tun hat. Per Interrupt zu messen hätte den Vorteil, daß während der Meßzeit noch was in der Hauptschleife gemacht werden könnte. In der while Schleife zu zählen ist sehr einfach und ressourceschonend, vielleicht auch genauer, blockiert aber während der Meßzeit die Hauptschleife.

Thegon müßte auswählen, was besser in sein Konzept paßt. Ich würde für diese Anwendung wahrscheinlich per Interrupt und einem 16Bit Timer messen. Hoffentlich kommt die HW zum Probieren ans Laufen.

Gruß
Searcher

radbruch
22.08.2011, 21:17
Hallo

Danke für die "ernste" Antwort. Ein paar Millisekunden nicht blockierende US-Auswertung gegen schlanken Code. Ich verstehe ;) In der Praxis wird es wohl eh ein blockierendes getAbstand() werden...

Was mir noch aufgefallen ist: Der US-Simulator antwortet schon beim ersten Low des Burst, der echte Empfänger wird wohl mehrere Amplituten benötigen bevor er anspricht. Da sind dann wohl schnell ein paar waitus 11 zusammen. Da bringt das µs-Optimieren bei der Timerlösung auch nicht mehr viel.

btw. Vom Knicklenker zum Programmierer. Klasse wie du das geschafft hast.

Gruß

mic

Searcher
22.08.2011, 21:47
Hallo radbruch,

Der US-Simulator antwortet schon beim ersten Low des Burst, der echte Empfänger wird wohl mehrere Amplituten benötigen bevor er anspricht
ich bin mir da nicht so hundertprozentig sicher und "glaube", daß durch das Flip-Flop an "Pulse in" schon beim Eintreffen des ersten low des ersten Pulses des Bursts sofort der "Pulse out" auf low gebracht wird. Zum Meßende (Pulse out wieder auf high) braucht es dann die Anschwingzeit und die Schalllaufzeit.

Ist aber zum Test des Meßprogramms nicht so wichtig. Da wird man sicher noch kalibrieren müssen.

PS.
Vom Knicklenker zum Programmierer. Klasse wie du das geschafft hast
Danke *stolz* . Das RN hat sicher einen sehr großen Anteil daran! Je mehr ich lese (und auch Deine Projekte betrachte), desto mehr ist mir bewußt wie sehr ich noch am Anfang stehe.

Gruß
Searcher

Besserwessi
22.08.2011, 21:57
Das Flipflop wird schon auf den ersten Impuls ansprechen. Die Frage ist aber wie das mit dem Schwingkreis ist. Der wird für die volle Amplitude ein paar mehr Perioden brauchen und entsprechend kann man eine Verzögerung von 1-2 Perioden des 40 kHz Signals, also 25-50 µs an Verzögerung durchaus schon mal bekommen, wenn das Signal zu schwach ist um sofort zu reagieren.

radbruch
22.08.2011, 21:58
ich ... "glaube", daß durch das Flip-Flop an "Pulse in" schon beim Eintreffen des ersten low des ersten Pulses des Bursts sofort der "Pulse out" auf low gebracht wird.Das glaube ich nicht. Im Empfänger wird doch wohl irgendwas eingebaut sein das durch den Burst über den Schalldruck in Schwingung versetzt wird. Und dieses "irgendwas" benötigt sicher einige Schwingungen bevor es so sehr mitschwingt dass es reicht, den FlipFlop anzusteuern. Wenn das nicht so wäre, würde ein Burst mit nur einem Impuls ausreichen.

Lösung? Die Anzahl der Bursts langsam erhöhen bis ein Empfang erkannt wird. Dann erst die Laufzeitmessung mit den zuvor ermittelten Bursts.

PICture
22.08.2011, 22:19
Hallo!

Ich gebe dem Searcher vorsichtig Recht, weil für mich die Empfängerkapsel grundsätzlich ein US Mikrophon und kein Schwingkreis ist. ;)

Ubrigens, wie bei jedem Mikrophon gibt es sicher mechanische "Resonanze", die aber üblicherweise ausser nutzbarem Frquenzbereich liegen sollten.

RoboHolIC
23.08.2011, 02:05
Einspruch, Euer Ehren!
Was ich an Datenblättern über US-Kapseln bisher gesehen habe, waren keine Mikrofone im engeren Sinne sondern schmalbandige Detektoren. Schließlich macht die Schmalbandigkeit auch Sinn, damit der Sensor sich nicht bei jedem Klirren irgendeines Blechs, Glases, PWM-fiependen Motors etc. gleich angesprochen fühlt und ein Signal erzeugt. Sowohl Sender als auch Empfänger machen Einschwingvorgänge durch, die die Zeitauflösung von Laufzeitmessungen auf ein Mehrfaches der Periodendauer der Arbeitsfrequenz begrenzen.

Thegon
23.08.2011, 10:19
Hallo,
kommt ja ganz shön was zusammen, wenn man mal kurz nicht hin schaut :-)

Zu den Zeiten, die entstehen, wenn Filter bzw. der Empfangswandler anschwingen müssen:

Ich hatte eigentlich vor, die entgültige umrechnung der Timeroverflows in eine echte Entfernung (in cm) nicht aus der Schallgeschwindigkeit oder so zu berechnen, sondern das ganze rein zu Kalibrieren. Also messungen in entfernungen wie 25cm; 50cm; 1m; 1,5m usw. durchzuführen und so erst einmal alle fixen Reaktionszeiten, (Filteranschwingzeit, Anschwingzeit der US - Kapseln [obwohl mir das auch neu wäre] und noch verzögerungen innerhalb des AVR, falls solche auftreten) auf einmal wegzusubtahieren. Dann ausrechnen, wie oft der Timer pro cm entfernung tickt und den Ausgabewert der messung (Timerticks) durch diesen Wert dividieren.
Alle diese Messungen natürlich oft durchfürhren, um auf einen guten Durchschnitt zu kommen.

Ich denke, das wird genauer als dass ich die Entfernung durch die Schallgeschwindigkeit berechne, auch weil der AVR villeicht nicht ganz so genau (im bezug auf die wahre Echtzeit) ist, könnte nich mir vorstellen.

Die Methode von radbruch würde sicher funktionieren, ich werde sie auch einmal ausprobieren, wenn das IF einmal will, aber irgentwie sagt mir der timer da doch mehr zu, ob nun 8 oder 16 Bit.

Das Oszi hat sich seit dem letzten mal überhaupt nicht mehr anschalten lassen, ich fürchte, es ist seinem Lebensende nah...
Aber ich schätze, dass ich spätestens am Wochenende einmal die Eingansverstärkung duchmessen kann, villeicht auch schon früher, sicher bin ich aber nicht.

Mfg Thegon

Richard
23.08.2011, 10:58
Ich hatte eigentlich vor, die entgültige umrechnung der Timeroverflows in eine echte Entfernung (in cm) nicht aus der Schallgeschwindigkeit oder so zu berechnen, sondern das ganze rein zu Kalibrieren. Also messungen in entfernungen wie 25cm; 50cm; 1m; 1,5m usw. durchzuführen und so erst einmal alle fixen Reaktionszeiten,

Ja und dann ändert sich der Luftdruck/Temperatur und alles stimmt nicht mehr. :-) Millimeter genau wird das eh nie über US.

Gruß Richard

Thegon
23.08.2011, 12:09
Mit wieviel abweichtung ist denn bei einer großen Luftdruck / Temperaturänderung zu rechnen ?, also alles unter "Haushaltsüblichen" bedingungen.
Mehr als 2cm? Dann sollte ich beginnen, mir gedanken darüber zu machen.

Mfg Thegon

Manf
23.08.2011, 13:49
Kurz gesagt ist die Laufzeit nicht vom Druck aber von der Temperatur abhängig mit ca. 1% pro 5°C. Bei 2m Abstand sind das 2cm Abweichung bei 5°C Temeperaturänderung.

Ein Weiterer Einfluß ist die Abhängigkeit von der Signalamplitude. Den größten Einfluß auf die Signalamplitude hat die Größe, die Beschaffenheit und die Ausrichtung der Echofläche. Bei einer Bandbreite von ca. 2kHz bei 40kHz Arbeitsfrequenz kann die Erkennungsschwelle innerhalb der geschätzt maximal 20 Perioden Einschwingzeit erreicht werden. Da zwei Wandler im System sind ist die Verteilungsdichte der Triggerverzögerung eher die gefaltete Verteilungdichte der beiden Wandler. Man kann dann auch noch die Filterfunktion des Verstärkers einbeziehen. Für praktische Betrachtungen sind das für die meisten Fälle dann doch nur um die 4-8 Perioden Unsicherheit, also etwa 16-32 mm Abstandsunsicherheit.

Thegon
23.08.2011, 16:12
Vielen Dank für die genaue Erklärung, so wie ich das verstanden habe wäre dann aber das einzige, das man dagegen tun kann Temperatur messen und Messergebnis daran anpassen, oder?

Das wäre sicher einmal eine Verbesserung wert, würde mich auch reizen, da ich noch so gut wie nichts mit Temperaursensoren gearbeitet habe aber ich denke ich lasse mir damit einmal Zeit, zumindest solange, bis ich sagen kann, das Interface und das Zeitstoppen per AVR funktioniert.

Interessant aber, dass die Temperatur doch einen gar nicht so kleinen einfluss auf die Messungen haben kann, das hab ich vorher nicht gewusst.

Mfg Thegon

PICture
23.08.2011, 16:23
Normaleweise sollte zuerst festgelegtes Ziel die weitere Schritte beeinflüssen. Nur für Hinderniserkennung finde ich die Temperaturkompensation überflüssig, es sei denn, dass man sehr genaues Messystem strebt. ;)

Thegon
23.08.2011, 16:30
Naja, im Prinzip hast du eh recht, nur mehr als 5 cm sollten es nicht umbedingt sein, da der Roboter in ferner Zukunft einmal wie eine Art Gabelstapler Schachteln bewegen können sollte, und da braucht der den Sensor, um zu sehen, wo ungefähr die Schachtel steht, um dann dort hinzufahren, aber wie gesagt, in Ferner Zukunft. Zuerst muss er einmal Fernsteuerbar sein ;-)

Mfg Thegon

Richard
23.08.2011, 16:38
Normaleweise sollte zuerst festgelegtes Ziel die weitere Schritte beeinflüssen. Nur für Hinderniserkennung finde ich die Temperaturkompensation überflüssig, es sei denn, dass man sehr genaues Messystem strebt. ;)

Finde ich auch unnötig außer z.B. bei Füllstandmessung ehe die "Hütte" absäuft. :-) Normal macht so ein (besseres) Gerät einfach eine Referenzmessung bei festgelegter Länge und Speichert den Korrekturfaktor.

Gruß Richard

Besserwessi
23.08.2011, 17:40
Die Temperaturkompensation wird bei größerer Entfernung wichtig, und wenn die Temperatur sich aus deutlich ändern kann. Bei kleinen Abständen bis vielleicht 1 m ist da mehr der etwa konstante Fehler durch das Anschwingen wichtig. Eine Kalibrierung wird man ggf. brauchen um die Einschwingzeit zu erfassen, die dann hoffentlich nicht mehr so sehr schwankt. Um das zu verbessern müsste man dann schon die Amplitude erfassen und die Amplitude des Sendepulses oder die Verstärkung anpassen um immer auf die gleiche Amplitude beim Komperator zu erreichen.

Die Temperaturkompensation ist aber auch nicht so schwer, da eine Temperaturmessung eher einfach ist. Eine andere Einflussgröße ist die Luftfeuchte, da ist die Messung aber schon nicht mehr so einfach.

Thegon
28.08.2011, 13:25
Hallo zusammen,

jetzt gibt es wieder neuigkeiten vom Interface:

Das Oszi funktioniert wieder, und ich habe ein paar Messungen durchgeführt:

An der Sendekapsel: auf der einen Seite 40 kHz Rechtecksignal, auf der anderen Sinuswelle, auch 40 kHz.

An der Empfangskapsel: Sinuswelle, 40 kHz, Amplitude ca. 20 - 50 mV, schwankend. Ich habe ein Gebogenes Kupferblech benutzt, um die Amplitude zu erhöhen, sonst gibt es nichts zu messen, wie Manf geschrieben hat. Leider hat das Oszilloskop (Ein Taschenoszilloskop) keinen externen Triggereingang, so habe ich einfach dauernd 40 kHz gesendet, in dem ich die Schleife zur dauerschleife gemacht habe.

Am Kollektor des Amplifier Transistors: Gleiche Sinuswelle, die Ampliude jetzt ca. 250 mV, im optimalsten Fall, sonst weniger. Die Rampe steht immer so auf ca. 400mV, kann aber nicht weiter steigen, weil ja dauernd gesendet wird. Sonst steigt sie im nu auf 5V.

Auf der Basis des Transistors im Compare & switch teil: ein kleines bisschen weniger Amplitude als oben, so ca. 30 - 50 mV, sonst alles gleich wie oben.

Auf dem Collector des Transistors (compare u switch) etwas verzerrte Sinuswelle (steigt eher langsam an, und fällt schnell wieder zurück) Frequenz ebenfalls 40 kHz. Die Amplitude um einiges größer, jetzt etwa 300 - 400 mV, im optimalsten Fall, natürlich.

Klint meiner Meinung jetzt etwas wenig, aber ich habe am Poti gedreht, und das war das Beste, das herauszubekommen war.
Bei dieser Entfernung (= optimalster Fall) erhalte ich nach ca. 800 us einen Interrupt, wären dann umgerechnet 13cm. Kommt nicht wirklich hin, aber schon mal in die Nähe (es sind villeicht 8cm oder so). Entferne ich die Kupferplatte, bekomme ich keinen Interrupt mehr, der Timer zählt ins unendliche.

Meine Fehlerdiagnose: es wird zu wenig verstärkt und somit kann das Flipflop nicht zum Kippen gebracht werden. Es werden nämlich interrupts ausgelöst, wenn ich an den Polen des Empfanswandlers eine kleine Spannung aus einer fast leeren Batterie anlege, also villeicht 200mV.

Hat jemand eine Idee, woran das liegen könnte oder ab welchem gemessenen Punkt die Verstärkung zu klein ist, weil er es selbst schon einmal ausprobiert und gemessen hat?

Danke im Voraus!

EDIT: Villeicht könnte unklar sein, wie ich, wenn ich dauerhaft sende einen Interrupt erhalte. Immer, wenn ich von Interrupts spreche, habe ich nur 20 Impulse gesendet, wenn ich von Spannungen spreche, habe ich dauerhaft gesendt ;-)

Mfg Tegon

Manf
28.08.2011, 15:13
Das ist natürlich eine gute Voraussetzung zur Optimierung wenn man das Analogsignal vor sich hat.
Eine wirkungsvolle Maßnahme zur Erhöhung der Verstärkung wäre hier beispielsweise einen Widerstand von 100k bis 1M zwischen den Spannungsteiler und die Basis des zweiten Transistors einzusetzen. Da Signal vom Schwingkreis wird dabei weiter direkt über den 10n Kondensator an die Basis des Transistors angekoppelt.
Der Schwingkreis wird dadurch weniger gedämpft und die Amplitude steigt. Bei dem schmalbandigen Schwingkreis sollte man dann darauf achten, daß er auch wirklich auf die Arbeitsfrequenz abgstimmt ist.

Die Überprüfung der Abstimmung ist nicht so schwierig wie es im ersten Augenblick klingen mag. Man kann dazu die Induktiivtät leicht verändern und sehen, ob die Amplitude dabei steigt oder fällt. Diese kleinen Spulen sind ja häufig als Zylinderspulen ausgeführt, bei denen man durch Annähern von Ferritmaterial, (eine andere nicht angeschlossene Spule,) die Induktivität erhöhen kann. Durch Annähern eines Magneten kann man entsprechend die Induktivität probeweise senken.

Für eine dauerhafte Abstimung kann man dann den Kondensator verändern oder die Induktivität wie im Artikel Kleinsignalverstärker beschrieben abstimmbar machen. http://www.rn-wissen.de/index.php/Kleinsignalverstärker

Thegon
28.08.2011, 18:27
Also ich habe nun einen 330k Widerstand zwischen die mitte des Spannungsteilers (bestehend aus Poti und 47kWiderstand) und die Basis des 2. Transistors gelötet, aber irgentwie steigt die verstärkung nicht, im gegenteil. Ich erhalte eher Rauschen und so eine Unruhige Spannung. Hab ich da was falsch verstanden, war das mit diesem Widerstand anders gemeint?

Zum Schwingkreis: dieser besteht bei mir aus einem 1n und einem 1,8n Kondensator, Paralellgeschaltet, gibt dann 2,8nF und einer Spule von 5,6mH. Die Richtige Spule hatte ich leider nicht, also hab ich die Kondensatoren dran angepasst. Ich denke, ich werde mir einmal einen Funktionsgenerator ausleihen, damit kann ich die Resonanzfreq. dann ganz leicht herausfinden. Ich würde eine Drehkapazität besitzten, die hat max. 4,2mH, mehr weiß ich leider auch nicht, aber damit könnte ich eventuell einen passenden Schwingkreis zusammenbasteln, sollte der jetzige nicht die Richtige Resonanzfrequenz haben.
Ich melde mich, sobald ich den Frequenzgenerator habe.

Mfg Thegon

PICture
28.08.2011, 20:03
Hallo!

Als Frequenzgenerator sollte sich doch der Generator für Senderspule eignen. ;)

Manf
28.08.2011, 20:12
Ja ich weiß bei Analogschaltungen sind die Lösungen vielfältig.
Man kann die Schaltung auf die aktuellen Spezialbauteile (die Wandler) optimieren und gerade mit deren bester Frequenz betreiben. Alternativ kann man die die Verstärkung schlimmstenfalls mit einem weiteren Transistor und etwas Gegenkopplung soweit erhöhen, dass es für alle Toleranzen reicht.
Die erste Variante ist gut gegen Störungen die zweite ist unempfindlicher gegen den Temperatureinfluß. Ein Mittelweg ist dann wie immer der beste.

Thegon
28.08.2011, 20:32
Also, ich habe mir den FG ausgeliehen, und gleich einmal die Resonanzfrequenz des Schwingkreises bestimmt. Diese war schon einmal nicht richtig, sie betrug etwa 34 kHz. Ich habe dann einen anderen mit einer einstellbaren Induktivität und einem 5nF Kondensator eingebaut, aber ich kann nicht unbeding von einer Großen verbesserung sprechen. Das Ausgangssignal war wohl ein bisschen größer, aber ich habe das Kupferblech zum Löten entfernt, und danach wieder positioniert, und da kann sich der Abstand schon ein bisschen verändert haben. Mein Schwingkreis war wohl nicht besonders Schmalbandig ;-)

Dann habe ich den Sendewandler ausgelötet, und dann mittels FG betrieben, und das Ausgangssignal (des 2. transistors) ist 5V, schon rechtecksähnlich, also schon übersteuert, dies auch, wenn ich aus ca. 60cm auf dem Bildschirm "sende" und dann mittels Schaltung das Echo verstärke.
Als ich die Sendekapsel eingelötet und mittels AVR betrieben hatte, war an so ein Ergebnis nicht im entferntesten zu denken, Da war ich schon froh, wenn ich mittels Kupferblech in 10cm Entfernung eine Halbwegs Sichtbare Sinuswelle hereinbrachte.

Auch habe ich den FG anstelle des Empfangswandlers angeschlossen, Amplitude ca. 40mV, (weniger war leider nicht stabil einzustellen) und das Ausganssignal war wiederum eine stark übersteuerte Sinuswelle, eigentlich gleich wie oben.

All dies würde jetzt ja nicht unbedingt auf eine Schwache verstärkung hindeuten, deshalb verdächtige ich jetzt wieder mehr den Sendewandler, aber mir fällt nichts ein. Das einzige, das Komisch ist, ist, dass auf dem einen Pol (des Sendewandlers) korrekt 5V rechteck anliegen (die vom uC kommen), am anderen Pol ein seltsam verzerrtes und "flimmerndes" Signal, das auch keine 5V Amplitude hat, villeicht 3V oder so. Dieses Signal ist alles andere als ein Rechtecksignal, am ehersten mit Dreieckwelle zu vergleichen. Könnte da etwas nicht stimmen?

Ständig freut man sich, eine Unsimmigkeit gefunden zu haben, und dann ist das Resultat nur ein kleines Bisschen besser als davor, das ist richtig anstrengend ;-)

Mfg Thegon

Manf
28.08.2011, 20:42
Dann ist wohl das Gatter am Sender zu hochohmig. Wenn noch ein Gatter frei ist könnte man es parallel schalten.

Besserwessi
28.08.2011, 21:02
So besonders schmalbandig soll der Schwingkreis gar nicht sein. Wenn die Güte zu hoch ist, wird die Einschwingzeit zu lang und störend, weil dann ein schwaches Signal länger braucht um die nötige Amplitude zu erreichen. Man kann den Sender auch vom AVR Pin gegen GND laufen lassen, also ohne das Gatter. Das könnte immer noch stärker sein als ein eher schwaches 4011 Gatter. Sonst als kräftigerer Ersatz für den CD4011 ein 74HC00 - allerdings mit anderer Pinbelegung.

Wenn es mit dem 330 K Widerstand zwischen den Spannungsteiler und der Basis zu viel Rauschen gibt, könnte man einen etwas kleineren Widerstand (z.B: 47 K) probieren. Die wesentliche Last wird aber wohl der Transistor bleiben.

Edit:
Habe gerade gesehen, durch den hohen Widerstand am Kollektor ist der Transistor doch schon sehr hochohmig, trotz Emitterschaltung. Es könnte ggf. etwas helfen den 100 K Widerstand am Kollektor doch etwas kleiner zu machen, und damit die Stufe etwas schneller.

Thegon
28.08.2011, 21:07
Gatter war noch frei, hab ich sofort paralell geschalten und:
es gab eine deutliche verbesserung beim Aussehen des Signals auf der anderen Seite des Sendewandlers. Jetzt würde ich die Wellenform bereits als Rechteck identifizieren, die Amplitude beträgt jetzt 5V, sogar etwas drüber.
Der Sendewandler sendet Jetzt kräftiger, das ist sicher, aber leider hat auch das nicht die große Wende gebracht.
Die maximale entfernung wird wohl etwas größer geworden sein, ist aber noch nicht einmal die 60cm bis zum Bildschirm.

Etwas seltsames habe ich auch noch herausgefunden: Es werden nur Interrups geliefert, wenn das Poti unter einer Ganz bestimmten Stellung (etwa in der Mitte) steht, etwas weiter gedreht,(Weiter drehen heißt, Masse "näherbringen") und das Signal ist null (DC : 4,7V), nicht die Kleinste welle. Habe mich auch schon gefragt, warum das so ist. Ich habe bis jetzt alle Messungen in der optimalste Potistellung kurz vor dem mysteriösen Verschwinden durchgeführt.

Mfg Thegon

Besserwessi
28.08.2011, 21:24
Das mit dem Poti ist so normal. Der Transistor ist keine lineare Verstärkerstufe mehr. Unter einer gewissen Spannung sinkt der Basisstrom sehr schnell auf fast 0. Die Spannung am Ausgang ist dann fast 5 V.

Der wohl einfachste Weg um auch diese Stufe linear zu machen, wäre vermutlich daraus einen Verstärker mit Spannungsgegenkopplung zu machen - man spart sich damit auch weitgehend den etwas kniffligen Abgleich. Statt dem Spannungsteiler einen Widerstand (z.B. 470 K) vom Kollektor zur Basis und den Widerstand am Kollektor auf z.B. 2-50 K verkleinern, ggf. den 10 K Poti mit 1 K in Reihe.

Manf
28.08.2011, 21:32
Der zweite Transistor ist so etwas wie ein Verstärker oder auch ein Bisschen ein Komparator. Zum Erkennen des Echos in nachfolgenden Gatter geht es schon etwas über den Kleinsignalbetrieb hinaus und er schaltet praktisch durch. Dabei bezieht er sich auf seine Schwellspannung. Mit etwas Gegenkopplung wie gerade von Besserwessi beschrieben sollte sich der Temperatureffekt der Schwellspannung sogar noch etwas reduzieren lassen.

Thegon
29.08.2011, 19:44
Hmm, also das mit dem Poti stört mich nicht, wenn das normal ist. Der verstärker muss nicht unbedingt linear sein, denn das bringt ja eigentlich nur was, wenn man am Poti dreht, aber wenn das Poti einmal eingestellt ist, dann ist es doch egal, ob die Stufe Linear ist oder nicht, oder?

Mir ist dann noch eingefallen, dass ja die Rampe auf Grund des Dauersendens nicht steigen kann, und somit verstärkung nicht besonders hoch sein wird, meine Vermutung.
Ich habe dann den 1M Widerstand direkt auf 5V gelegt, und das ergebnis: Gewaltige verstärkung. Das US - Signal war vom Tisch bis zur Decke, eben die villeicht 1,7m und wieder zurück, hat dann ca. 1,4V und auch Interrupts ausgelöst. Ich denke, dass die kleine Verstärkung wohl in erster Line darauf zurückzuführen war, auch der Schwingkreis bewirkt etwas, aber da er bekanntlich nicht besonders Schmalbandig war, nur bedingt.
Nun, ich habe dann natürlich gleich mit dieser Konfiguration Bursts von 50 Perioden gesendet, und leider ist der Große erfolg noch nicht eigebrochen.
Ich erhalte nun Interrupts, wenn sich etwas sehr nahe am Modul befindet, sonst aber nicht.
Am ausgang villeicht 300mV verzerrte sinuswelle, von übersteuerung aber noch keine Spur. Lustiger weise erhalte ich jetz manchmal mehrere Interrupts, was für mich heißt, dass das Flipflop ein bisschen Flackert. Weiß auch nicht so recht, ich werde jetzt einmal das Flipflop überprüfen.
Sonst werde ich die verstärkung doch noch ein bisschen erhönen müssen, denke ich. Wie könnte ich das denn am einfachsten machen?

Mfg Thegon

Thegon
29.08.2011, 20:32
Ich habe jetzt noch etwas zu berichten:
Die Entfernungsmessung im Nahbereich (bis ca. 40cm) funktioniert, zumindest erhalte ich nun zahlen im halbwegs richigen bereich (auch nur ein Interrupt). Ich habe mich schon gefreut, doch dann doch eine große Ernüchterung: Die Zahlen kehren ständig wieder. Sie werden zwar größer, wird die Entfernung größer, aber in einem gewissen Bereich wird zum beispiel immer 607 us gesendet, also so ca. 10cm. die nächste stufe wäre dann 863, die Tritt bei etwas größerer Entfernung ein.
Irgentwas ist da doch nicht ganz richtig... Ich denke aber dass das auf die Software zurückzuführen ist, und damit befasse ich mich erst, wenn das Interface funktioniert.

Das Flipflop scheint dann doch zu funktionieren, denn es ist immer brav auf 5V, nur eben während eines Sendevorgangs auf 0V, spring, wenn das echo wieder eintrifft, zurück auf 5V.

Mfg Thegon

Manf
29.08.2011, 20:33
Man kann leicht die Kombination mit dem 1M Widerstand um den Faktor 3 niederohmiger machen.
1M -> 330k
220k -> 68k
47nF -> 150nF
An wieviel Verstärkung dachtest Du denn?

Ein flackerndes Flipflop ist nicht so richtig üblich, wie sieht es mit der Versorgungsspannung aus? sollte man da noch etwas mit Kondensatoren abstützen?

Antwort überschnitten,

Wenn Du den Impulsgenerator noch da hast kannst Du ja vielleicht auch noch einmal nachsehen ob die Frequenz so passt oder ob man, (ich weiß noch nicht wie in der späteren Schaltung,) die Frequenz etwas an die Wandler anpassen sollte.

Thegon
29.08.2011, 20:43
Naja, so genau weiß ich das auch nicht, ich kam eben zur erkenntnis, dass das Signal, das von der Decke kommt, eben zu schwach ist und somit das Flipflop nicht zum Kippen bringen kann. Es hat villeicht 300mV.

Also wenn das Verändern der 1M Kombination, wie oben geschrieben die Verstärkung um den Faktor drei erhöht, dann wäre das sicherlich einmal einen Versuch wert.

Eine Frage: Könnte es sein, dass das Schwache Signal auf meinen Sende- und Empfangswandler zurückzufühen sein kann, denn das ist ja eigentlich das einzige, das eventuell nicht in das Konzpt dieses Interfaces passen könnte, denn die Schaltung hat ja sicherlich so, wie sie im RN Wissen steht, zum Beispiel bei dir schon funktioniert. Gibt es da gravierende Unterschiede zwischen verschiedenen Piezo Wandlern, oder sind die alle etwa gleich?
Ich weiß nämlich langsam nicht mehr, was eigentlich nicht stimmen könnte ;-)


EDIT:
Also auf der versorgungsspannung hängt ein 220uF Kondensator, nochmal ein 220nF über den Versorgungspins des 4011, das hat mir schon mal jemand geraten, die einzubauen, dann hat auch das mit den vielen Interrups aufgehört, seitdem erhalte ich nur einen mehr, wenn überhaupt...
Den FG hab ich noch, aber am Schwingkreis Schraube ich sowieso ständig herum, schaue immer wieder, ob das Signal ein bisschen größer wird.

Mfg Thegon

Manf
30.08.2011, 07:18
Wenn es versteckte Unterschiede gibt dann kommen dafür vielleicht die Wandler in Frage die in ihrer Resonanzfrequenz etwas streuen.
https://www.roboternetz.de/community/threads/14559-Suche-Ersatzschaltbild-für-Ultraschallwandler/page3?p=139065&viewfull=1 (https://www.roboternetz.de/community/threads/14559-Suche-Ersatzschaltbild-für-Ultraschallwandler/page3?p=139065&viewfull=1)
https://www.roboternetz.de/community/attachment.php?attachmentid=4812&d=1138221019

Allgemein ist ja aber auch ein 300mV Signal schon eine gute Grundlage für Optimierungen, die einzige Sorge dabei wäre dass die Schaltung komplexer wird. Man sollte dann dabei die bevorzugten Ziele im Auge behalten.

In der Schaltung wir die Verstärkung über der Zeit erhöht. Die Verstärkung ist in der dargstellten Ausführung insgesamt nicht sehr groß und so wird für die Zeitkonstante der Verstärkungserhöhung (220k 47nF) eine Zeit von 10ms gewählt. Das entspricht einer Entfernung von 1,7m für eine Zeitkonstante. Man kann die Verstärkung auch schneller hochfahren und verliert dabei an Reichweite oder man erhöht die Reichweite und muss dafür die Verstärkung, beispielsweise mit einer weiteren Transistorstufe erhöhen. Zwei Transistoren nur zur Verstärkung sind schon relativ komplex und man kann überlegen, dann schon einen Operationsverstärker an der Stelle einzusetzen.

Wenn es sonst passt und die 300mV den Komparator eben nicht auslösen, dann kann man sich auch vorstellen, den Mittelwert des Signals am Komparatoreingang mit einem Potentiometer näher an die Triggerschwelle heranzuschieben (Mit Potentiometer die Versorgungsspannung herunterteilen und über hochohmigen Widerstand an den Komparatoreingang führen und das Signal mit einem Kondensator einkoppeln).

Thegon
01.09.2011, 12:25
Also ich habe jetzt zwischen 5V und GND ein Poti(250k) eingelötet und die Ausgangsspannung per 47k Widerstand (weil schon vorhanden) auf die Basis angeschlossen. Sind 47k in Ordnung, in welchem Bereich ist "Hochohmig" denn hier gedacht?

Gebracht hat das leider nichts, eher das gegenteil, es kamen immer weniger Interrupts rein, wenn ich die Spannung verkleinert habe.

Ich habe dann noch mal auf Pulse out gemessen und erhalte eigentlich genau das, was ich bekommen sollte: Wenn man auf "falling" Triggert, kommt nach ca. 2ms wieder das High und das bei ca. 40cm entfernung. Wird die Entfernung verringert, kommt das High früher.

Nur eben wie gesagt über 50cm hat man keine Chance, einen Interrupt auszulösen. Der 1M Wiederstand befindet sich übigens jetzt einmal immer auf 5V, also maximale Verstärkung.

Wenn ich bis zur Decke Messe, also die 1,7 m, dann kommt am Komperator Transistor villeicht 100mV heraus, also eben nicht genug, um den Komperator auszulösen.
Ich würde gerne die Verstärkung (des Amplifier Transistors) erhöhen, dass man eben am Komperator ein besseres Signal zur verfügung hat.

Das herumschrauben am Triggerlevel ist immer so eine "wackelige" Geschichte, man weiß nie so recht, ob man das ganze dann schon ein bisschen zu empfindlich gestellt hat und somit eben auch auf die kleinste Störung schon auslöst, oder ob villeicht noch ein bisschen mehr gehen würde.

Ich habe auch noch zum Ausprobieren eine dritte Transistorstufe eingebaut, leider hat sie noch nicht funktioniert. Ich denke aber, dass ich das nicht ganz richtig gemacht habe, weil eigentlich nur aus dem Kopf ausgedacht.
Wie müsste man so eine Transistorstufe denn einbauen, damit sie villeicht Verstärkungsfaktor 10 - 20 oder so hat ?
Ich weiß, eigentlich würden solche Fragen ja ins Elektronikforum gehören, aber jetzt ist der Thread halt hier und ich fange jetzt auch keinen Neuen an.

Mfg Thegon

Richard
01.09.2011, 13:29
eine Möglichkeit http://www.elektronik-kompendium.de/sites/slt/0205141.htm eine Andere http://www.elektronik-kompendium.de/sites/slt/0204133.htm wobei ich dabei die 2. mit Basis Spannungsteiler und Arbeitspunkt Einstellung meine. http://www.elektronik-kompendium.de/sites/slt/0204302.htm hohe Verstärkung aber auch hier besser die 2. Schaltung mit Basis Spannungsteiler. Ganz genaue nehmen die Emitter Schaltung und hängen als Impedaz Wandler eine Kollektor Schaltung dahinter. :-)

Gruß Richard

Thegon
01.09.2011, 14:40
Hallo,
ich habe nun eine Schaltung ausprobiert, aber leider kein erfolg.
Es ist die Emitterschaltung mit Arbeitspunkteinstellung. Am ausgang erhalte ich eine sehr verzerrte Sinuswelle von ca. 100mV ausgangsspannung, also leider nichts brachbares.

Die Schaltung, die ich jetzt verwende, ist im Anhang zu finden.
Ist natürlich nicht alles, aber eben die Eingansverstärkung.
Wäre Froh, würde jemand einen Fehler finden ;-)

Mfg Thegon

Richard
01.09.2011, 15:23
Hallo,
ich habe nun eine Schaltung ausprobiert, aber leider kein erfolg.
Es ist die Emitterschaltung mit Arbeitspunkteinstellung. Am ausgang erhalte ich eine sehr verzerrte Sinuswelle von ca. 100mV ausgangsspannung, also leider nichts brachbares.


Laut der Tabelle auf http://www.elektronik-kompendium.de/sites/slt/0204302.htm sollte die Verstärkung zwischen 20....und 100 liegen. Hast Du den Arbeitspunkt auch so eingestellt das (Gleichspannungsmäßig) am Kollektor Widerstand (Ausgang) 1/2 der Betriebsspannung anliegt? Und den Wandler über einen Elko Entkoppelt, gleiches beim Ausgang....

Gruß Richard

Besserwessi
01.09.2011, 17:57
Der Arbeitspunkt des 2. Transistors ist ziemlich kritisch, und schwer einzustellen, mit den gezeigten Werten ist vermutlich die Gleichspannung am Ausgang zu hoch. Ich würde die extra Stufe einfach mit Spannungsgegenkopplung, d.h. Mit Widerstand vom Kollektor zu Versorgung der Basis laufen lassen - das Spart einem da die Einstellung und macht die Schaltung weniger Temperaturempfindlich.

Thegon
01.09.2011, 19:58
@Besserwessi:
Das heißt, ich sollte einfach den 100k Widerstand mit dem Kollektor des 2. Transistors verbinden, anstatt mit 5V? Oder ist der wert nicht ideal? Und der zweite Widerstand im Spannungsteiler gegen Masse (10K), ist der dann überhaupt noch nötig?

@Richard:

Und den Wandler über einen Elko Entkoppelt, gleiches beim Ausgang....


Wie ist das gemeint? Mein aufbau sieht genauso aus wie die angehängte Schaltung meines letzten Beitrages. Um die Gleichspannungsanteile wegzubekommen, befindet sich nach jeder Stufe ein Koppelkondensator, wie eben im Schaltplan eingezeichnet. Die Versorgungsspannung ist mittels 220uF Elko "stabelisiert". Braucht man sonst noch irgentwo Kondensatoren ?

Mfg Thegon

Besserwessi
01.09.2011, 20:33
Die beiden Widerstände mit 100 K und 10 K wären etwa richtig für 6,5-7 V. Bei 5 V müsste der 10 K Widerstand wohl noch etwa größer (z.B. 12 K) . Weil die Verstärkung von DC an gilt ist das aber recht empfindlich, sogar auf Temperaturänderungen.

Wenn man den 100 K Widerstand an den Kollektor legt, sollte man auch den anderen Widerstand etwa anpassen (in etwa verdoppeln oder noch etwas größer). Gewollt ist hier etwa ein Teiler auf Vcc / 1,4 V. Halt so dass bei Vcc/2 am Ausgang noch etwa 0,7 V an der Basis ankommen.

Es gibt da noch eine andere Möglichkeit der Auslegung: nur ein Widerstand vom Kollektor zu Basis, und keiner von der Basis nach GND. Der Widerstand sollte dann etwa um den Verstärkungsfaktor des Transisitors größer sein als der Lastwiderstand am Kollektor. Solange man nicht den vollen Hub braucht ist der genaue Wert nicht so kritisch - man muss also den Transistor nicht unbedingt ausmessen.

Thegon
01.09.2011, 21:47
Es gibt da noch eine andere Möglichkeit der Auslegung: nur ein Widerstand vom Kollektor zu Basis, und keiner von der Basis nach GND. Der Widerstand sollte dann etwa um den Verstärkungsfaktor des Transisitors größer sein als der Lastwiderstand am Kollektor. Solange man nicht den vollen Hub braucht ist der genaue Wert nicht so kritisch - man muss also den Transistor nicht unbedingt ausmessen.

Also, mir gefällt die zweite möglichkeit besser, ich sollte dann demanch, wenn ich eine verstärkung von 20 haben möchte, den Kollektor und die Basis mit einem 2k2 * 20 = 44 k Wiederstand verbinden, der nächste in der Reihe wäre dann 47k, das Probiere ich gleich mal aus.

So, jetzt hats ein bisschen gedauert, aber leider gibts nun schon wieder Probleme. Ich erhalte nun 20 Interrupts, die Direkt dann kommen, wenn die Bursts gesendet werden.
Auch gibt es jetzt nichts mehr zu messen, zum Beispiel am Start - In pin. Kaum messe ich, ohne ihn mit dem Interface zu verbinden, erhalte ich 40 kHz rechtecksignal, eingestekt nichts! Sehr mysteriös!
Sonst: Alle messungen an der eingansverstärkung sind nichts, immer gerade Linie. Die 20 Interrupts, die eben 0 us ausgeben, die sind das einzige Lebenszeichen, das da raus kommt. Irgentwie alles ein bisschen seltsam, jetzt.
Ich muss wieder einmal fragen ob jemand eine Idee hat was man da machen könnte.

Mfg Thegon

Besserwessi
01.09.2011, 22:26
Solange man noch sendet kann es leicht zu Interrupts kommen. Das Flipflop wird ja immer wieder zurückgesetzt und das Starke Sendesignal geht auch mal andere als Geplante Wege. Dazu kommt ggf. auch eine direkte Elektrische Kopplung. Es reicht eigentlich die Interrupts erst nach dem Senden einzuschalten. Das davor kommt interessiert eigentlich nicht. Ggf. muss man sogar am Ende noch mal einen Nadelimpuls senden um das Flipflop zurück zu setzen.

Bei der Auslegung des Widerstandes gab es ein Missverständniss. Mit Verstärkung des Transistors war die Stromverstärkung gemeint, nicht die gewollte Spannungsverstärkung. Für einen Typischen Kleinsignaltransistor wie BC548 hat man da etwa 100-200 als Verstärkung. Also den Widerstand zur Basis etwa 100-200 mal so groß wie den am Kollektor wählen. Das wären hier als etwa 220 K - 390 K. Für eine Stufe mit maximal etwa 500 mV am Ausgang sollte das reichen. Um die Spannungsverstärkung zu begrenzen, kommt dann ggf. ein Widerstand in Reihe zum Koppelkondensator und ggf. noch ein kleiner Kondensator parallel zur Rückkopplung. Über die RC Werte kann man so noch einen untere und obere Grenzfrequenz festlegen.

Nachtrag:
Die Treiberschaltung kann ohne Signal von der Steuerung zu schwingen anfangen. So viel anders als ein Quarz verhält sich der Ultraschallsender nicht, nur halt bei 40 kHz und nicht so frequenzstabil.

Thegon
01.09.2011, 22:55
Also, das mit dem Widerstand hats gebracht: Ich erhalte nun am Ausgang der Verstärkung 40kHz 5V amplitude, auch gegen die Decke.
Nur irgentwie so ganz richtig funktioniert das ganze noch nicht:
Ich erhalte weiterhin die 20 Interrupts mit dem Inthalt 0, obwohl die Interrupts erst nach dem Senden Atkiviert werden und beim ersten eintreffenden Interrupt aktiviert werden. Aber das mit dem 5V signal ist schon mal gut.

Auch am Pulse out gibt es weiterhin nichts zu messen, was für mich auf sehr kurze zeiten hindeutet. Sehr seltsam das ganze...
Nun die Frage ist: warum macht der Komperator nichts sinnvolles, wenn er das 5V Signal von der Verstärkung erhält?
Oder kommt das 5V Singal villeicht garnicht vom Empfangswandler ?
Alles so seltsam und man kommt sich so hilflos vor, wenn man keine Sinnvollen Messbilder hat.
Das einzige, was ich sonst noch herausgefunden habe ist dass das Sendesignal wenn es den AVR verlässt, durch irgentwas stark verändert wird.
Es ist kaum noch zu erkennen mit dem Oszilloskop, es verändert sich ständig und hat, wenn man einmal zufällig richtig Triggert, eine gewaltig hohe Frequenz (500kHz) Habe aber auch nicht die geringste Ahnung warum das so ist.

Mfg Thegon

Besserwessi
01.09.2011, 23:09
Wenn die 2. verstärkerstufe schon 5 V liefert, braucht man doch keinen "Komperator mehr". Die Stufe sollte aber auch damit klar kommen. Was passieren kann, ist allerdings das man das Laden des Kondensators für die Verstärkungseinstellung mit bis zum Ausgang bekommt. Man hat da noch ein langsames Signal, das den 40 KHz überlagert ist und ggf. am Ausgang jetzt stört, denn die extra Verstärkerstufe invertiert das Signal.

Wenn beim Senden schon ein Starkes Signal ankommt, kann der Schwingkreis noch einige Zeit nach schwingen und auch kurz nach dem Ende des Sendens noch einen Interrupt auslösen.

Das Signal zum Senden sollte einigermaßen Sauber sein. Je nach Logic IC kann es sinnvoll sein einen kleinen Widerstand von vielleicht 100-300 Ohm in Reihe zum Sende Transducer zu haben. Man hat dann keine so kapazitive Last. Damit werden die Oberwellen des Rechtecksignals etwas gedämpft und die Spitzenströme werden begrenzt. Es gibt damit weniger Störungen auf der Versorgung.

Manf
02.09.2011, 08:09
Nachdem die Verstärkung die ganze Zeit zu klein war kommt es jetzt mit der zusätzlichen Stufen wenn sie den richtigen Arbeitspunkt haben zu einer recht hohen und ggf. auch zu hohen Verstärkung.
Wenn die Störungen speziell am Anfang nach dem Senden auftreten dann sieht es danach aus, dass der 1MOhm Widerstand für den Baisisstrom des ersten Transistors noch fest an 5V liegt.
Es ist aber schon ein wichtiger Teil des Konzepts mit der Rampe, dass der Eingangsverstärker während des Sendens noch inaktiv ist.

Thegon
02.09.2011, 11:08
Hallo allerseits

Ich habe den 100 Ohm wiederstand eingebaut und wieder auf Rampenbetrieb umgestellt, weiteres habe ich auch den Triggerlevel um ein gutes stück zurückgesetzt.
Nun: Ich kann es selber kaum glauben:
Ich erhalte nun immer interrupts, auch wenn ich bis zur decke messe, zum Beispiel.
es kommt auch immer nur ein Interrupt, und dieser Braucht um so länger, je weiter die Entfernung ist.
Ich kann nicht einmal Messbilder aus dem Oszi nennen, da es wieder einmal steikt, aber das ist mir jetzt auch egal, Ich nehme an, es wird wohl so stimmen ;-)

Kurz um: Das Interface erfüllt seine Aufgabe!!!


Das einzige was jetzt noch ein bisschen Probleme macht, ist die Software. Erstens stimmen die Ausgegebenen zeiten nicht mit den Soll - us zusammen, was mich aber weniger stören würde, da ich sowieso vor habe, das Interface zu eichen.
Auch kommen ganz bestimmte zeiten (z.B. 1729) besonders oft, sodass ich einen Denkfehler in der Programmstruktur vermute.
Ich hänge den derzeitig benutzten Code unten an den Beitrag an, wäre schön, könnte ihn mal jemand anschauen.

Dann einmal vielen vielen Dank allen Beiteiligten an diesem Thread, im Bezug auf die Hardware besonders Manf und Besserwessi, danke für die vielen Tipps und Lösungsvorschläge!

Naja, an der software gibts schon noch ein bisschen was zu verbessern, denn es gibt teilweise schlimme abweichungen von mehr als 200 us, auf grund dieser Zeiten, die besonders oft kommen, aber ich freue mich schon mal unglaublich, das die Hardware nun einmal keine Probleme macht.


Mfg Thegon

Hier noch einmal den zurzeit verwendeten Code:

$regfile "M48def.dat"
$crystal = 1000000
$hwstack = 100
$swstack = 100
$framesize = 100
$baud = 2400
Dim Endtime As Long
Dim Countperoverflow As Integer
Dim Struser As String * 10
Dim Countperiodes As Byte
Dim Timerstand As Byte

Config Timer0 = Timer , Prescale = 1
On Timer0 Isrtimer
Enable Timer0
Stop Timer0

Config Int0 = Rising
Enable Int0
On Int0 Isr_interrupt
Config Portd.3 = Output
Portd.3 = 1

Do
Input Struser
If Struser = "" Then
'################# den Sendebrust generieren +++++++++
Countperiodes = 0
Do
Portd.3 = 0
Countperiodes = Countperiodes + 2

Portd.3 = 1
Countperiodes = Countperiodes - 1

Loop Until Countperiodes > 20
Countperiodes = 0
Portd.3 = 1
'################################################# #####

Enable Interrupts
Start Timer0
Timer0 = 0
Struser = "sd"
End If

Loop


'###############TimerIsR##################
Isrtimer:
Countperoverflow = Countperoverflow + 1
Return
'#########################################

'#########ACI isr################
Isr_interrupt:
Stop Timer0
Timerstand = Timer0
If Tifr0.tov0 = 1 Then
Endtime = Endtime + 256
Set Tifr0.tov0
End If
Endtime = Countperoverflow * 256
Endtime = Endtime + Timerstand

Disable Interrupts
Print Endtime
Timer0 = 0
Timerstand = 0
Endtime = 0
Countperoverflow = 0
Return#

Searcher
02.09.2011, 14:43
Hi,

gratuliere!

Wegen der Abweichungen der Meßwerte bzw häufiges Vorkommen von bestimmten Werten:

Hatte ich in meinem Programmentwurf auch. und ist sehr wahrscheinlich, wie weiter vorne im thread erwähnt, durch Ablauf der "Isrtimer:" verursacht.

Um die Abweichungen kleiner zu bekommen könnte man als erstes den Systemtakt auf 8MHz stellen (Timer Prescaler dann gleichzeitig auf 8 .

Oder Du probierst den Vorschlag von radbruch aus - dann ist das Überschneiden der Interrupts ausgeschlossen.

Besserwessi hat die Verwendung von ICP (Input Capture Funktion) (http://www.rn-wissen.de/index.php/Timer/Counter_%28Avr%29#Input_Capture) vorgeschlagen. Das scheint mir genau die richtige Methode für solche Messungen zu sein. Allerdings nur für die 16 Bit Timer verfügbar:(

Gruß
Searcher

Besserwessi
02.09.2011, 14:51
Da ist ein Problem mit der Berücksichtigung der Überläufe von Timer 0. Einfacher wäre es man würde Timer1 nehmen, da könnte man sich das Problem sparen. Im Idealfall würde man die ISP Funktion nutzen und hätte die Zeitmessung fast komplett durch die Hardware erledigt.

Wenn es unbedingt mit timer 0 sein soll, hat man eine Schwierigkeit, wenn der Timer overflow und der externe Interrupt fast gleichzeitig auftreten. Da ist schon etwas Code in der ISR der wohl versuchen soll, das Problem zu behandeln, allerdings ist der Teil an der Falschen stelle und nur halb richtig. Das Problem ist, dass ggf. die Overfow ISR noch aussteht, also eine Überlauf zu wenig gezählt wurde. Erkennen kann man das am Interrupt-flag in Kombination mit dem Timer Wert:
If Tifr0.tov0 = 1 reicht dabei noch nicht, es muss außerdem der Timer-wert klein (z.B. < 100 sein). Ohne Vorteiler wird es mit den Zeiten aber auch schon recht knapp. Die Overflow ISR wird schon fast 50% der gesamten Rechenzeit verbrauchen.

Nachtrag: Wärend die Überlauf ISR läuft, kann nicht auf den anderen Interrupt reagiert werden. Entsprechend die Werte kurz nach dem Überlauf nicht möglich. Leider braucht auch die einfache ISR in BASCOM schon gut 100 Zyklen. Mit Inline ASM könnte man da noch etwas raushohlen, aber im Prinzip bleibt die kleine Lücke.

radbruch
02.09.2011, 14:54
Das einzige was mir noch auffällt:

Countperoverflow = 0

erst nach der ersten Messung in der ISR. Vermutlich wird das von Bascom schon beim Programmstart mit 0 belegt, aber darauf würde ich mich nicht verlassen. Die Systemtakterhöhung halte ich auch für sinnvoll.

Zu Rechenzeit in der ISR: Wird "incr Countperoverflow" schneller ausgeführt?

Gruß

mic

Besserwessi
02.09.2011, 15:37
Die Rechenzeit wird dominiert durch das Retten der Register auf den Stack. Das sind alleine schon etwas über 100 Zyklen, selbst wenn die ISR leer ist. Da hilft halt inline ASM, weil man da keine 26 Register retten muss, sondern nur 2.

radbruch
02.09.2011, 16:36
Das Speichern aller Register beim Aufruf der ISR kann man mit dem Parameter "nosave" unterdrücken. Infos in der Bascom-Hilfe unter "On Interrupt"

Thegon
02.09.2011, 17:29
Hallo,

Wenn es unbedingt mit timer 0 sein soll
nein, es muss nicht unbedingt Timer0 sein, ich hätte auch nichts gegen Timer1. Du meinst, man spart sich das Problem, weil der Interrupt ja erst bei 65536 ausgelöst wird, und eine So große Entfernung garnicht gemessen werden kann?
Nun das könnte sein, das Probiere ich einmal aus.


Das einzige was mir noch auffällt:

Countperoverflow = 0


Du hast recht, die Erste messung ist immer unbrauchbar, aber ab der zweiten stimmts. Das werde ich gleich ausbessern.

Sost Input Capture klingt vielversprechend, nur kenne ich mich damit nicht aus, und der Artikel ist in C, und irgentwie steht da zwar drin, wie ICP funktioniert, aber nicht, wie man ihn programmiert.

Naja, probiere jetzt mal den 16bit Timer.

Mfg Thegon

Besserwessi
02.09.2011, 17:44
Zum Programmieren des Input Capture hat man vermutlich 2 Möglichkeiten: man kann auf die Unterstützung von BASCOM setzen, sofern es die gibt, oder man schreibt direkt in die Register, dann geht es genau so wie in C. So viel zu programmieren gibt es da auch nicht. Der Timer läuft ganz normal als Timer durch. Die ICP Funktion ist immer aktiv, die kann man gar nicht abschalten. Das einzige was man noch zu tun hat, ist die passende Flanke auszuwählen und dann die Zeit aus den ICP Registern auszulesen. Statt den externen Interrupt nutzt man dann halt den ICP Interrrupt. Dabei muss man vermutlich am Anfang der Messung das Interrupt Flag löschen, damit man auch wirklich erst auf das Echo anspricht. Die Komplikation mit dem Overflow kann man sich hier sparen, denn 16 Bit Auflösung sollten reichen.

Thegon
02.09.2011, 17:57
Hmm, der 16 Bit timer macht bei mir nur Käse ;-)

Je weiter die Entfernung wird, desto kleiner werden die Zahlen :-(

ich habe auch schon kalibrierungsmessungen durchgefürht, und mich gewundert, wie klein der Unterschied zur Wahren Messung (mit messband) ist. Die Reaktionszeit scheint nur wenige us zu betragen.
Naja, nur eben das Problem mit den bestimmten Stellen, die immer gleich hoch bleiben.
Ach ja, diese Stellen sind übrigens immer ein vielfaches von 256...

Mfg Thegon

Searcher
02.09.2011, 18:42
Hallo,

ohne ganz genau zu wissen was ich da mache habe ich mal inline asm in meinem früheren geposteten Programm probiert. Die wenigen Befehle sind einfach nur aus dem Debounce Beispiel vom RN-Wissen (http://www.rn-wissen.de/index.php/Bascom_Debounce_ISR_in_Assembler#Beispiel_2:_Entpr ellung_einer_3_Tasten_Uhr_in_einer_Bascom-ISR_mit_Assembler-Unterst.C3.BCtzung) kopiert. Scheint aber zu funktionieren. Ohne Gewähr und mit zitternden Knien :-) .

Systemtakt = 8MHz, Timer läuft mit 1MHz (Prescaler = 8 ).
Im meinem vorherigen Programm hatte ich eine Anzeigelücke von 16µs. Die ist nun mit der neuen ISR auf 5µs. gesunken.


On Timer0 Isr_count_overflows Nosave

Isr_count_overflows: 'Ansprung, wenn Timer0 überläuft
!push r16
!in r16,sreg
!Push r16
Timer0_overflows = Timer0_overflows + 1
!pop r16
!out sreg,r16
!pop r16
Return 'Hier vielleicht !RETI ???


Zu Rechenzeit in der ISR: Wird "incr Countperoverflow" schneller ausgeführt?
Ich hab es mal im Simulator ausprobiert. INCR braucht 19 Zyklen und die +1 Variante nur 16. Ich war überrascht.

Gruß
Searcher

radbruch
02.09.2011, 18:49
Erstaunlich. Ich sollte auch mal den Simulator verwenden.

Thegon
02.09.2011, 19:07
Hallo allerseits,

Ich habe nun noch eine Umfangreiche Kalibrierung vorgenommen und war sehr erstaunt:
Das Signal ist schneller, als es tatsächlich sein sollte. Ich nehme an, der timer tickt dann zu langsam oder irgentetwas anderes bremtst das Zählen aus.
Da diese Ungenauigkeit aber immer gleich bleibt, habe ich einfach immer 600us dazugezählt.
Die Zeit wird dann noch in cm umgewandelt und im Terminal ausgegeben.

Weiters habe ich das Print in der ISR weggetan und nun stimmt die Messung:

Bei bereichen kleiner 60cm stimmt die Entfernung fast immer auf den cm genau mit der echten überein, bei größeren entfernungen gibt es abweichungen von bis jetzt max. 3cm, aber nur einmalig, dann kommen wieder viele Messungen, die ziemlich genau sind.
Ich bin sehr überrascht, wie genau das ganze nun entgültig funktioniert hat. Die kleinen Abweichungen befinden sich für mich absolut im Toleranzbereich, so genau war das ganze ursprünglich sowieso nicht geplant gewesen.
Danke zwar für den Tipp mit Inline ASM, aber ich denke, ich spare mir das ;-)

Die gleichbleibenden zahlen gibt es zwar immer noch, aber die sind dank des entfernens von Print aus der ISR nun so klein, dass sie villeicht einen cm Abweichung bewirken.

Ach ja, ich bin ganz glücklich ;-)

Ich habe noch vor, einen abschließenden Beitrag zu diesem Projekt zu gestalten, mit Bildern, Schaltplan, Code und Tipps, als Hilfe oder Anregung, zum Verlinken in anderen Threads, sozusagen als zusammenfassung. Wird allerdings noch ein bisschen Dauern.

Nochmals vielen Dank allen beteiligten an diesem Thread, danke für die Hilfe!

Mfg Thegon

Searcher
02.09.2011, 19:14
Ich habe noch vor, einen abschließenden Beitrag zu diesem Projekt zu gestalten, mit Bildern, Schaltplan, Code und Tipps...
Prima. Ich wollte sowieso noch nach dem endgültigen Schaltplan fragen. Ich kann aber auf die Zusammenfassung warten.

Gruß
Searcher

PICture
02.09.2011, 19:36
Hallo!

@ Thegon

Kannst du mir, bitte, sagen, wieviel Strom die ganze Messschaltung braucht, weil ich es eventuell pulsweise für meinen geplannten Solarbot verwenden möchte ? ;)

Besserwessi
02.09.2011, 19:58
Die oben gezeigte Inline ASM kann funktioniern, muss es aber nicht. Das hängt davon ab, wie BASCOM das hochzählen implementiert. Wenn da mehr als R16 benutzt wird, gibt es ggf. schwer zu findende Fehler. Da sollte man das Hochzählen auch in ASM machen. z.B. mit
LDS R16, {Timer0_overflows}
SUBI R16, 255
STS {Timer0_overflows},R16
LDS R16, {Timer0_overflows}+1
SBCI R16, 255
STS {Timer0_overflows}+1,R16

Wenn Timer0_overflows ein Byte Wert ist, kann die 2. Hälfte Wegfallen.

Thegon
02.09.2011, 20:02
Hallo Picture,

die Schaltung zieht im Leerlauf, also wenn sie gerade nicht misst, für mich lächerliche 20mA. Bei der arbeit wirds wohl etwas mehr sein, aber da mein Multimeter da nicht mitkommt, weiß ich das leider nicht.

Ich habe den Strom übrigens an einem 12V bleiakku gemessen, den ich dann an einen 7805 angeschlossen habe.

Mfg Thegon

PICture
02.09.2011, 20:10
Danke schön, fur mich sind leider für dich lächerliche 20 mA sehr viel, weil der gesamte Antrieb um 5-10 mA braucht. Bei kurzen Impulsen in µs Bereich ist es aber viel weniger als gebremster Motor am Hindernis. :D

Searcher
02.09.2011, 20:23
Da sollte man das Hochzählen auch in ASM machen. z.B. mit
LDS R16, {Timer0_overflows}
SUBI R16, 255
STS {Timer0_overflows},R16
LDS R16, {Timer0_overflows}+1
SBCI R16, 255
STS {Timer0_overflows}+1,R16

Danke für den Code. Hab ich gleich mal ausprobiert und "Timer0_overflows = Timer0_overflows + 1" durch alle ASM Befehle ersetzt ,da bei mir eine Word Variable. Hat nochmal eine µs gebracht. Lücke jetzt noch 4µs.

PS nach weiterem Tasten und Messen 3µs Lücke

EDIT
Echt stark, was Inline ASM bringt. Habe nun die Timer0_overflows Variable auf Typ Byte geändert. Damit kann sie eine Zeit bis ca 65ms abdecken, was hier für die US Messung mehr als genug wäre.

Die ganz neue ISR sieht nun so aus:


On Timer0 Isr_count_overflows Nosave

Isr_count_overflows: 'Ansprung, wenn Timer0 überläuft
!push r16
!in r16,sreg
!Push r16
!lds R16 , {timer0_overflows}
!SUBI R16, 255
!STS {Timer0_overflows},R16
!pop r16
!out sreg,r16
!pop r16
Return

Wenn ich nun meinen eigenen Tests trauen darf, liegt die Lücke bei nur noch bei 2µs. Die Simulation ist so eingestellt, daß 10 Überläufe auftreten. Nicht angezeigte Werte sind 2568µs und 2569µs. Anmerkung: ASM Code nur durch C&P entstanden.


Gruß
Searcher

Besserwessi
02.09.2011, 20:33
Die Schaltung selber sollte deutlich weniger Strom Verbrauchen, zumindest nach dem Schaltplan. Da wird viel von den 20 mA für den AVR und den 7805 verbraucht werden. Wenn die Schaltung nicht aktiv ist sollte man deutlich unter 1 mA kommen können (ohne den µC). Die größte Unsicherheit ist dabei das CMOS gatter hinter dem letzten Transistor. Je nach Einstellung der Schwelle kann da ein mittlerer Pegel anliegen und das Gatter dahinter ggf. etwas mehr Strom brauchen.

Beim Senden braucht man kurz mehr Strom - auch auch da kaum 20 mA, beim Empfangen wird man vielleicht auch 1-3 mA kommen.

In einer Spar-Version ohne den analogen Ausgang könnte man auch auf die Gatter verzichten und den 220 K Widerstand für die Rampe immer an 5 V haben. Die Funktion des Flipflops sollte der µC mit übernehmen können, ggf. auch gleich mit dem analog Comperator des µC, so dass man auch mit 1 Transistor auskommt. Damit sollte man im inaktiven Bereich auf einen Stromverbrauch von ca. 50 µA kommen und vielleicht 1 mA beim Empfangen.

PICture
02.09.2011, 20:48
Ich möchte die ganze möglichst vereinfachte Schaltung nur für Erkennung eventuellen Hindernises vom µC kurz einschalten und brauche eigentlich keine Messungen. Deshalb gefällt sie mir sehr ! :D

Thegon
02.09.2011, 20:56
Hallo allerseits,

ich habe jetzt doch Lust bekommen, eine zusammenfassung zu schreiben und somit fange ich einmal an:

Anfangs habe ich viele Versuche und Tests mit Operationsverstärkern durchgeführt, bis ich dann am Ende, als es mittels LF353 so einigermaßen funktioniert hat, draufgekommen bin, dass ich eine Verstärkung brauche, die sich mit der Laufzeit des Signals erhöht. Ich bin dann dank einem Roboternetzbenutzer auf das Ultraschall - Interface (http://www.rn-wissen.de/index.php/Ultraschall_Interface) von Manf gestoßen, das mir eigentlich gut gefallen hat.

Als Sende - und Empfangswandler benutze ich die aus einem Bausatz von Conrad, diesem hier. (http://www.conrad.at/ce/de/product/114456/ULTRASCHALL-ABSTANDSWARNER-BAUSATZ/SHOP_AREA_17362&promotionareaSearchDetail=005)


Grundsätzliches Funktionsprinzip:
Der Mikroprozessor erzeugt 20 Perioden mit einer Frequenz von 40kHz, der Resonanzfrequenz der Wandler.
Dieses Singal gelangt über Start In in das Interface.
Dort wird mit diesem Signal der Sendewandler betrieben, die Rampe gestartet und das Flipflop gestellt.
Unmittelbar nach dem Senden des Bursts, also der 20 Perioden beginnt der AVR, die Zeit zu stoppen. Dazu wird der Timer0 benutzt.
Trifft nun das Echo ein, so wird es vom Empfangswandler in eine Wechselspannung "verwandelt". Da diese sehr schwach ist, wird sie duch die Eingangsverstärkung verstärkt und setzt das Flipflop wieder zurück.
Der AVR bemerkt die Zurücksetzung des Flipflops per Interrupt und stoppt den Timer.
Danach wird wird die Zeit ausgewertetet, in cm umgerechnet und ausgegeben.


Das messen der Laufzeitverzögernung übernimmt ein ATmega48, obwohl der dafür ein bisschen überdimensioniert ist.
Als ein großes Problem Stellte sich die Verstärkung heraus, als Lösung wurde eine dritte Transistor Verstärkterstufe eingebaut.
Auch wurden Störunen durch die Betriebsspannung übertragen, so wurde diese mittels 220uF Kondensatoren gestützt.

Empfehlenswert ist es auch, eine veränderbare Induktivität einzuplanen, um den Schwingkreis eventuell abstimmen zu können, da die Resonanzfrequenz nicht unbedingt mit der berechneten übereinstimmt. (Bei mir zumindest nicht genau)

Die Vollständige und für meinen Fall optimierte Schaltung hier:


19873
EDIT: So ein Blödsinn, das Bild wird automatisch komprimiert, und so kann man die Bauteilwerte nicht mehr lesen.
Hier (http://hekaftp.jimdo.com/bilder/) noch einmal hochgeladen, da sollte die Auflösung passen.

Hier noch ein Paar weitere Biler vom aufbau des Modules:
19867
19869
19868

Soweit die Hardware.
Auch die Software hat einige Untstimmigkeiten mit sich gebracht, so ist die Erzeugung des Bursts, der in Start in geht, nun etwas unkonventionell gelöst, aber es funktioniert.
Die ISR ´s dürfen nicht zu lange sein, so zum Beispiel kein Print oder ähnliches, wie ich es ursprünglich gemacht habe.

Das Komplette Programm, das auf dem Mega48 läuft, hier:


'Ultraschall Entfernungsmessung messprogramm
' endgültige version
$regfile "M48def.dat"
$crystal = 1000000
$hwstack = 100
$swstack = 100
$framesize = 100
$baud = 2400
Dim Endtime As Long 'die entgültige zeitin us
Dim Countperoverflow As Integer 'dieOverflows des Timer0 werden hier gezählt
Dim Struser As String * 10 'die Eingabevariable des Users
Dim Countperiodes As Byte 'die Perioden des Us bursts werden gezählt
Dim Timerstand As Byte 'der stand des Timers beim Überlauf
Dim Ausgabefertig As Byte 'flag wird gesetzt, wenn die Zeitmessung erfolgt hat
Dim Entfernung As Word
'########## timer0 Kofigurieren und Initialisieren ##################
Config Timer0 = Timer , Prescale = 1
On Timer0 Isrtimer
Enable Timer0
Stop Timer0
'################################################# ######################
'Int0 Konfigurieren
Config Int0 = Rising
Enable Int0
On Int0 Isr_interrupt
'portd.3 als ausgang definieren, das ist der Start in Pin
Config Portd.3 = Output
Portd.3 = 1

'Alle variablen auf null setzen.
Endtime = 0
Countperoverflow = 0
Struser = "sd"
Countperiodes = 0
Timerstand = 0
Ausgabefertig = 0
Print "Ultraschall Entfernungsmessung Online"
Do
Input Struser
If Struser = "" Then
'################# den Sendebrust generieren +++++++++
Countperiodes = 0
Do
Portd.3 = 0 'man kommt so genau auf 40khz
Countperiodes = Countperiodes + 2

Portd.3 = 1
Countperiodes = Countperiodes - 1

Loop Until Countperiodes > 20
Countperiodes = 0
Portd.3 = 1
'################################################# #####

Enable Interrupts 'interrupts global aktivieren
Start Timer0 'timer starten, as stoppen der zeit beginnt jetzt
Timer0 = 0 'timer auf null setzen, dass die messung auch wirklich bei null beginnt
'variable verändern, dass nicht noch mal in die Schleife
Struser = "sd"
End If
If Ausgabefertig = 1 Then 'Wenn die Fertig flag gesetzt wurde
Entfernung = Endtime / 60 ' Umrchnung in cm
Entfernung = Entfernung + 10 ' auf grund von Kalibrierung nutwendig, kann angepasst werden
Print Entfernung ' Entfernung ausgeben (per UART)
Timer0 = 0
Timerstand = 0 'Alle Variablen wieder auf null setzen
Endtime = 0
Countperoverflow = 0
Ausgabefertig = 0
Entfernung = 0
End If
Loop

'###############TimerIsR##################
Isrtimer:
Countperoverflow = Countperoverflow + 1 'die timerüberläufe zählen
Return
'#########################################

'######### Interrupt isr################
Isr_interrupt:
Stop Timer0 'beim eintreffen der messung Timer stoppen
Timerstand = Timer0 'derzeitigen timerstand in Variable sichern
'Die Endtime in us ausrechnen
Endtime = Countperoverflow * 256
Endtime = Endtime + Timerstand

Disable Interrupts 'interrupts global deaktivieren, um eventuelle Störungen zwischen den pausen zu ignorieren
Ausgabefertig = 1 'die Flag setzen, dass die cm ausgegeben werden
Return
'############ End Programm ###############################################


Sonst: da die verstärkung nun schon sehr groß ist, werden manchmal auch echos von gegenständen, die nicht direkt in einer Linie mit den Kapseln stehen, empfangen und registriert. Für mich stellt dies aber kein Problem dar.

Die Ergebnisse enthalten (in meinem Falle) eine Maximale abweichung von 3cm, aber nicht sehr oft.

Viel Glück jedem, der auch einmal versuchen sollte, solch eine Entfernungsmessung zu realisieren!

Mfg Thegon

Manf
02.09.2011, 21:27
Meinen Glückwunsch zum erfolgreichen Abschluß, Du hast Dich da prima durchgearbeitet. Ich hätte manchmal gerne mehr geholfen nur kam ich in den letzten Tagen nicht richtig dazu. Und natürlich hat Besserwessi ja auch die guten Antworten schon so schnell gegeben dass mir kaum Gelegenheit dazu blieb.

Besserwessi
02.09.2011, 21:49
Beim Programm sind da noch ein Kleinigkeiten nicht optimal:
Das Disable Interrupts in der ISR sollte keinen Effekt haben. In der ISR sind weitere Interrupts ohnehin gesperrt. Am Ende der ISR werden die Interrupts wieder freigeben. Die Timer= Überlauf ISR ist recht langsam und verursacht damit eine leicht störende Pause - daher die Häufung von bestimmten Werten. Dazu kann es bei der Berücksichtigung der Zahl der Überläufe noch zu einem Problem kommen wenn beide Interrupts fast gleichzeitig auftreten. Das kommt eher selten vor, kann aber passieren und dann einen deutlichen Fehler verursachen.
Besser wäre es die Zeitmessung mit dem 16 Bit Timer1 zu machen, oder ganz ohne Interrupt einfach in einer Zählschleife im Hauptprogramm.

Thegon
04.09.2011, 11:34
Hallo
@Manf:
Danke ;-) Ich finde, du hast mir sehr viel geholfen, denn es ist immer gut, wenn der Macher der Schaltung selbst Hilfestellungen gibt.

@ Besserwessi:
Danke natürlich auch, die verbesserungsvorschläge wären sicherlich sinnvoll, aber ich denke, ich spare mir das, weil das Modul garnicht dazu gedacht war, genaue Entfernungen zu messen, sondern eben als Hindernisserkennung, also um villeicht eine Wand ungefähr zu erkennen und dann umzudrehen oder so. Das ganze soll einmal so eine Art "Radarbildschirm" werden, auf der die Unmittelbare Umgebung von villeicht 2m drauf ist oder so.

Mfg Thegon

Richard
04.09.2011, 15:57
Hallo
@Manf:
Danke ;-) Ich finde, du hast mir sehr viel geholfen, denn es ist immer gut, wenn der Macher der Schaltung selbst Hilfestellungen gibt.

@ Besserwessi:
Danke natürlich auch, die verbesserungsvorschläge wären sicherlich sinnvoll, aber ich denke, ich spare mir das, weil das Modul garnicht dazu gedacht war, genaue Entfernungen zu messen, sondern eben als Hindernisserkennung, also um villeicht eine Wand ungefähr zu erkennen und dann umzudrehen oder so. Das ganze soll einmal so eine Art "Radarbildschirm" werden, auf der die Unmittelbare Umgebung von villeicht 2m drauf ist oder so.

Mfg Thegon

Ich habe je fleißig mit gelesen weil es Spaß macht zu sehen wie jemand sich an das Problem heran tastet. :-) Respekt! das hast Du gut gemacht.
Aber wenn es darum geht schnell einfach und effektiv Hindernnisse + relativ deren Entfernung zu ermitteln ist z. B. ein SRF02 "einfacher" einzubinden.

Gruß Richard

Thegon
04.09.2011, 16:16
Aber wenn es darum geht schnell einfach und effektiv Hindernnisse + relativ deren Entfernung zu ermitteln ist z. B. ein SRF02 "einfacher" einzubinden.


ja sicherlich, ich habe mich auch vorher schon umgeschaut und über die Anschaffung eines SRF02 nachgedacht, aber irgentwie wollte ich es eben unbedingt selbst zusammenbasteln.
Wären alle meine Versuche gescheitert, hätte ich vermutlich auch ein SRF02 oder ähnliches gekauft ;-)

Sonst: Danke für das Lob *stolz* :-)

Mfg Thegon

radbruch
04.09.2011, 17:17
Hallo

Ich finde solche Projekte auch immer sehr interessant und für mich lehrreich. Und wenn's dann am Ende auch noch funktioniert ist das echt ein Grund stolz zu sein. Was mich dabei oft sehr beeindrukt ist das Zusammenwirken der unterschiedlichsten Fachbereiche und der jeweiligen Spezialisten hier im RN-Forum.

Da jetzt ja alles funktioniert wäre für mich noch ein Vergleich mit der schon erwähnten einfachen Zählschleife anstelle der Interruptlösung interessant. ;)

Gruß

mic

P.S.: Vielleicht bringen wir doch noch irgendwann einen RN-Bot auf den Mars. :)

Thegon
04.09.2011, 17:26
Hallo radbruch,

Die Zählschleife habe ich einmal ausprobiert, nur irgentwie hat diese (ich nehme an wegen if schleifen und so) sehr langsam gezählt. Die zahlen waren nur bei großen Entferunen im dreiselligen bereich, und da ich ja eigentlich nicht vor hatte, diese Lösung zu verwenden, habe ich sie nicht besonders Perfektioniert.
Naja, tut leid aber ich habe mich so lange auf das Interface konzentriert, und dann, als es funktioniert hat, da hab ich dann irgentwie keine Lust mehr gehabt, noch großartig an der Software herumzubasteln. Das kennt ihr sicher...

Solle es für dich wirklich wichtig sein, könnte ich es schon noch mal ausprobieren.

Und: man sieht deinen Hai nicht mehr, der dem Smily nachjagt, ist das absicht?

Mfg Thegon

Besserwessi
04.09.2011, 18:11
Die Zählschleife hätte zumindest den Vorteil, das man da keine Fehler bei einigen Werten bekommt (wenn gerade ein Interrupt dazwischenfunkt). So ganz langsam sollte es selbst mit BASCOM nicht werden, zumindest wenn man passende Variablen (WORD) nimmt. Als ein Nachteil ist die Zeit je Schleifendurchgang möglicherweise von der Compilerversion abhängig - lösen läßt sich das wohl nur mit ASM. Zumindest mit etwas ASM für die Schleife wäre das besser als die Lösung mit dem 8 Bit-Timer.

Bei der einfachen Hardware kann man ohnehin kaum mit einer Genauigkeit von besser als 1 Wellenlänge/Periode rechnen - wenn man besser werden wollte müsste man für ein konstante Amplitude des Echos sorgen oder breitbandigere Transducer nehmen. Das heißt man kommt eigentlich mit 25 µs Zeitauflösung aus. Mit passendem Vorteile könnte dann ggf. auch der 8 Bit timer mit dem Overflowbit (aber ohne Zählen !) auskommen. Das würde bis etwa 2 m reichen. Es gäbe für den 8 Bit Timer noch eine etwas komische Möglichkeit: man macht das Hochzähler (nur 8 Bit Byte!) der Overflows nicht im Interrupt, sonder in einer Schleife per Polling. Den Fall das Overflow und Interrupt dicht zusammen kommen muss man ohnehin extra berücksichtigen.

radbruch
04.09.2011, 18:35
Hallo

Mein Hai-Smile wird bei roboterbastler.de (http://roboterbastler.de) gehostet und da ACU grad an seinem Server rumschraubt können wohl kurzzeitige Ausfälle auftreten:
https://www.roboternetz.de/community/threads/54699-kostenloses-Hosting-f%C3%BCr-Roboter-und-Elektronikseiten-(ohne-Werbung)

Eine so geringe Auflösung mit der Zählschleife hätte ich nicht erwartet. Hier mal ein ungetesteter Beispielcode:

'Ultraschall Entfernungsmessung messprogramm

'Test mit Zählschleife

$regfile "M48def.dat"
$crystal = 1000000
$hwstack = 100
$swstack = 100
$framesize = 100
$baud = 2400

Dim Struser As String * 10 ' die Eingabevariable des Users
Dim Countperiodes As Byte ' die Perioden des Us bursts werden gezählt
Dim Entfernung As Word

'portd.3 als ausgang definieren, das ist der Start in Pin
Config Portd.3 = Output
Portd.3 = 1

Print "Ultraschall Entfernungsmessung Online"
Print "(mit Zählschleife)"

Do
Input Struser ' warten bis Eingabe erkannt
If Struser = "" Then
Entfernung = 0

'################# den Sendebrust generieren ##########
Countperiodes = 0
Do
Portd.3 = 0 ' man kommt so genau auf 40khz
Countperiodes = Countperiodes + 2

Portd.3 = 1
Countperiodes = Countperiodes - 1

Loop Until Countperiodes > 20
Portd.3 = 1
'################################################# #####

Do ' Warten und zählen bis Echo empfangen wird
Entfernung = Entfernung + 1
Loop Until Pind.2 = 1

Print Entfernung ' Entfernung ausgeben (per UART)

While Pind.2 = 1
Wend

End If
Loop
End

Ganz schön schlank, oder? :)

Gruß

mic

Searcher
05.09.2011, 23:00
Finde den thread auch toll und weil noch ein Programm zur Zeitnahme mit dem ICP fehlt, hab ich mich mal versucht. Ist zwar nicht ganz schlank geworden, enthält aber noch eine alternative Bursterzeugung.

Gruß
Searcher



'################################################# ##
'File: US-Meßprogramm_ICP.bas
'IDE: BASCOM-AVR DEMO Version 2.0.5.0
'Meßprogramm zum Messen von US-Laufzeit mit RN Wiki US-Interface
'Messung wird erst gestartet, wenn der Burst komplett gesendet wurde
'Messung wird gestoppt mit Eintreffen des 0 nach 1 Wechsel auf PA7 (ICP)
'
'ATtiny24
'PB2 : Mit Taster den Burst und Messen starten
'PA7 : (ICP) - Meßpulsempfang vom Interface
'PA3 : SW UART #2 , 40kHz Burst Ausgang zum Interface
'PB0 : SW UART #1 , für Ausgabe der Meßwerte an 4 fach 7-Segmentanzeige
'################################################# ######

$regfile = "attiny24.dat"
$framesize = 32
$swstack = 32
$hwstack = 36
$crystal = 8000000 'interner Oszillator

'##### Definitionen und Initialisierung für 7segment ausgabe ######
Dim Num_to_disp As Word
Dim Y As Byte
Dim Helperbyte As Byte
Dim Index As Byte
Dim Disp_string As String * 6
Dim Digit_char As String * 1
Declare Sub Display_value(num_to_disp As Word)
Open "comb.0:115200,8,n,1" For Output As #1 'comb.0 -> TX ist Pin PB0
Helperbyte = Lookup(17 , Segmentpattern) 'segment g
For Y = 1 To 5 : Put #1 , Helperbyte : Next '7 segment initialisieren
'#### Ende Definitionen und Initialisierung für 7 Segmentausgabe #######


Dim Flag_ausgabe_fertig As Byte
Dim Flag_messung_fertig As Byte
Dim Inputcapture_wert As Word
Porta = Porta Or &B11110111 'alle Pullips auf porta einschalten, Ausnahme PA3
Portb = Portb Or &B11111110 'alle Pullups auf portb einschalten, Ausnahme PB0

Config Timer1 = Timer , Capture Edge = Rising , Prescale = 8 'Timer mit 1Mhz und ICP gestartet (8Mhz Systemclk)
On Capture1 Isr_zeitnahme 'Bei Input Capture Event zur ISR für Zeitnahme
Open "coma.3:80000,8,n,1" For Output As #2 'coma.3 -> 40kHz Burst auf PA3 mit SW-UART
Enable Interrupts

Do 'Beginn Hauptprogramm
Do 'Warten auf Tastendruck (PB2 nach GND Wechsel)
Debounce Pinb.2 , 0 , Start_mit_burst
Loop

Start_mit_burst:
Print #2 , "UUUU" ; 'Burst Erzeugung (Jedes U erzeugt 5 Pulse)
Flag_ausgabe_fertig = 0
Flag_messung_fertig = 0
Timer1 = 0 'Timerzähler (TCNT1) mit 0 initialisieren, Meßzeit beginnt
Set Tifr1.icf1 'Eventuell anstehendes Input Capture Flag löschen
Enable Capture1 'Input Capture Interrupt scharf machen

Do 'Schleife zum Warten auf Meßende/Ausgabeende
If Flag_messung_fertig = 1 Then
Call Display_value(inputcapture_wert)
Flag_ausgabe_fertig = 1
End If
Loop Until Flag_ausgabe_fertig = 1 'Ende Warterei wenn Anzeige des Meßwertes erfolgt ist
Loop 'Loop Hauptprogramm

Isr_zeitnahme: 'Ansprung bei Input Capture Event an PA7
Inputcapture_wert = Capture1 'Inputcapture Register sichern
Flag_messung_fertig = 1 'Indication für Anzeige kann erfolgen
Disable Capture1 'Input Capture Interrupts unterbinden
Return


'############ Folgende Zeilen bis zum Ende nur zur Datenausgabe über 7 Segmentanzeige #############
Sub Display_value(num_to_disp As Word) 'gibt Dezimalzahlen bis 9999 aus
Disp_string = Str(num_to_disp)
For Y = Len(disp_string) To 3
Helperbyte = Lookup(16 , Segmentpattern)
Put #1 , Helperbyte
Next
For Y = 1 To Len(disp_string)
Digit_char = Mid(disp_string , Y , 1 )
Index = Val(digit_char)
Helperbyte = Lookup(index , Segmentpattern)
Put #1 , Helperbyte
Next
End Sub

Segmentpattern: 'darzustellende Zeichen (hex 0..F...)
'Segmente abcdefg: ' ":" = Doppelpunkt in der Mitte
Data &B00000011 'Ziffer "0", 0 = segment ein, 1 = aus
Data &B10011111 'Ziffer "1"
Data &B00100101 'Ziffer "2"
Data &B00001101
Data &B10011001
Data &B01001001
Data &B01000001
Data &B00011111
Data &B00000001
Data &B00001001
Data &B00010001
Data &B11000001
Data &B01100011
Data &B10000101
Data &B01100001 'Ziffer "E"
Data &B01110001 'Ziffer "F"
Data &B11111111 'dunkel
Data &B11111101 'nur Segment g eingeschaltet (-)

'########### ENDE US-Meßprogramm_ICP.bas ##############################################