PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ASURO mit Ultraschallsensor (SRF05) for Dummies



negji
12.07.2007, 18:37
Hi Leute,

ich habe meinen ASURO mit dem Ultraschallsensor SRF05 ausgestattet. Da ich nirgends eine Komplett-beschreibung und auch keinen getesteten Code gefunden habe mit dem dieser Sensor angesprochen werden konnte habe ich mir gedacht, ich fasse mal alle wichtigen zu diesem Thema gehörigen Informationen zusammen. Ich habe keine Erweiterungsplatine etc. eingesetzt weil mir das alles zu kompliziert erschien. Für die Ansteuerung des SRF05 habe ich die Linienverfolgung opfern müssen, sollte aber zu verschmerzen sein wenn mann im Gegenzug mit Ultraschall durch die Gegend fahren kann.

Der Code zur Ansteuerung des Sensors exisitiert in ähnlicher Form schon irgendwo in diesem Forum, allerdings waren noch einige Fehler enthalten.
Zur Hardware: Der SRF05-Sensor wird von mir im SRF05 Modus betrieben, d.h. nur ein Pin wird für die Ansteuerung und für die Messung benötigt. Insgesamt müssen also 3 Pins des SRF05 an den ASURO angeschlossen werden, die Stromversorgung (5V und GND) und das Ansteuerpin (Auslösen und Messen).
Folgende Pinbelegung habe ich verwendet:
5V (SRF05) -> OUT+ (ASURO)
Ansteuerpin (mittleres Pin am SRF05) -> PD6 (ASURO)
GND -> OUT- (ASURO)

Der Anschluss der Spannungsversorgung an den Sensor sollte kein Problem darstellen. Auf dem Asuro sind ja zu diesem Zweck schon zwei Stellen auf der Platine vorhanden (OUT+, OUT-). Das Ansteuerpin des SRF05 habe ich an PD6 am ASURO angelötet. Dazu habe ich D11 entfernt und den Wiederstand R9 (220 Ohm) überbrückt. D11 ist die mittlere (rote) LED auf der Unterseite des ASURO und wird zur Linienverfolgung eingesetzt. Im Prinzip könnte man auch andere Pins zur Ansteuerung verwenden aber da die Linienverfolgung meiner Meinung nach nicht so wichtig ist habe ich D11 verwendet um den Ultraschallsensor anzuschließen.
Um R9 zu überbrücken muss man den halben Tischtennisball abnehmen, die richtigen Lötstellen (Beinchen von R9) identifizieren und am besten mit einem kleinen Stück Draht überbrücken. R9 muss überbrückt werden da er sich nicht wie im Schaltplan nach sondern vor D11 befindet.

damaltor
13.07.2007, 15:39
sehr gut, endlich mal alles zusammengefasst. du hättest auch die erweiterungsplatine nutzen können, dann wäre dein asuro noch kompatbel zu anderen erweiterungen geblieben. die pins out+, out- sowie einige portpins, auch pd6, sind auf die platine herausgeführt.

wer also die erweiterungsplaine nutzt, kann genau diesen code verwenden. der auslöser vom DRF muss dann an den frontled-pin.

ich bin mir allerdings recht sicher, dass der schaltplan stimmt. bitte schaut bei eurem asuro nach (nicht in der anleitung, sondern auf der platine!), bevor ihr die brücke baut die ihr evtl nicht braucht. wenn der widerstand HONTER der led ist, dann gilt folgendes:

den widerstand R9 muss man NICHT überbrücken. dieser ist nämlich mit der masse verbunden, und wnn die frontled ausgebaut ist und der SRF oder die erweiterungsplatine drin ist, dann hat dieser keine bedeutung mehr weil er vom prozessor und der restlichen elektronik getrennt ist.

vorher:
+ --- Prozessor ---- Diode ---- R9 ---- Masse


nachher:
+ --- Prozessor ---- SRF od. erweiterungsplatine --- Masse
und
Übrig gebliebenr pin der erweiterungsplatine --- R9 -- masse

also hat dieser keinen einfluss auf den srf.

ippeb
06.10.2009, 17:47
Hallihallo

Sorry, aber diesmal habe ich nicht viel Zeit - muss daher ziemlich stressen.

Also, ich habe den SRF05 am ASURO montiert, nun das Programm (welches oben gepostet wurde) funktioriert - abr naja - mit riesigen Ungenauigkeiten. i.e. Ich kann zwar unterscheiden ob meine hand vor dem US-Ranger liegt (3cm -12 cm) aber etwas in 30 cm Entfernung wird als 50cm, 20cm oder etwas zwischen drin angegeben. Über ~60cm kommt er nicht hinaus. An der Spannung sollte es aber nicht liegen.

Kann mir jemand (schnell) helfen!?

cheers
ippeb

robo.fr
07.10.2009, 12:23
Vielleicht findest Du in diesem (http://www.hobby-roboter.de/forum/viewtopic.php?f=4&t=32) Thread eine Lösung zu Deinem Problem.

Gruß,
robo.fr

KingTobi
11.10.2009, 14:46
Hi

Ich habe das selbe Problem.
Ich habe es schon mit einem Korrekturwert probiert, aber der ist auch jedesmal unterschiedlich.
Und wenn ich die 58µs warte bekomm ich immer nur Werte von 1 - 6.



uint16_t getAbstand(uint8_t sensor)
{
uint16_t abstand = 0; // abstand in cm

DDRC |= (1<<sensor); // sensor Pin auf Ausgang
PORTC |= (1<<sensor); // sensor Pin auf high setzen

waitUs(20); // 20 mikrosek. warten

PORTC &= ~(1<<sensor); // sensor Pin auf low setzen (ist noch als Ausgang konfiguriert)
DDRC &= ~(1<<sensor); // sensor Pin auf Eingang setzen

while(!(PINC & (1<<sensor))); // auf Sensorantwort warten (Eingang wird high)

while(PINC & (1<<sensor)) // warten bis Signalende bis Eingang low wird
{
waitUs(1); // 58 mikrosec. warten entspricht 1cm entfernung
abstand++; // Anzahl der cm erhöhen
}

return abstand; // gemessenen Abstand zurückgeben
}

/////////////////////////////////////////////////////////////////////////////
// Main-Funktion
/////////////////////////////////////////////////////////////////////////////
main()
{
uint16_t x = 0;
char ausgabe[10]="\0";

lcdInit();
lcdString("X ");
x = getAbstand(5);
itoa(x/1.36, ausgabe, 10);

lcdString(ausgabe);
lcdString("cm");

while (true) // Mainloop-Begin
{
//...
} // Mainloop-Ende
}

ippeb
11.10.2009, 16:32
Genau! Genau das gleiche Problem hab' ich auch... und ich habe (von der Hardware her) alles gecheckt. Der SRF05 auch nicht kaputt oder so... habe es gerade neu gekauft.

Hatte jemand das gleiche Problem - und habt ihr es lösen können - wie?

cheers ippeb

KingTobi
11.10.2009, 17:23
So, hab eben mitm Osziloskop kontrolliert ob das Timing stimmt und siehe da, das war sowas von daneben das da auch nichts richtiges bei rauskommen konnte!
Habe den Fehler noch nciht genau ausmachen können, habe es aber soweit korrigiert das die Messungen jetzt zu stimmen scheinen.

ippeb
12.10.2009, 22:41
Hey KingTobi

Sorry... muss nun wirklich stressen...

Wie hast du das hinbekommen mit dem Oszilloskop?
Ich hab' leider keins zuhause, und momentan haben wir Ferien - und am ersten Schultag muss ich unbedingt fertig sein...

Koentest du mir vielleicht sagen, was du geaendert hast (sodass ich kein Oszilloskop benoetigen muesste)?

Waere wirklich sehr sehr dankbar... ich bin schon zwei ganze Monate an diesem Problem stecken geblieben ... haette nicht gedacht, dass es am Timer liegen koennte...

mfg
ippeb

ippeb
12.10.2009, 22:46
Hey KingTobi... noch Was, koenntest du mir auch gleich konkret die Werte angeben, die du korrigieren musstest. Waere wirklich super toll wenn's bei mir klappen wuerde.

Ausserdem: Wie genau kannst du nun messen?

KingTobi
13.10.2009, 10:01
Nachdem ich die optimierung eingeschaltet hab, waren die Unterbrechungen waren alle 5mal so lang wie sie sein sollten. Kann bei dir aber anders dein.

Im Nahbereich ist er jetzt sehr genau, auf größere Entfernungen (2m) weicht er etwas ab. Das Timing ist aber auch nicht perfekt.

ippeb
13.10.2009, 12:47
Mmh...also bei mir funktioniert es immer noch nicht... es gibt immernoch sehr ungenaue Daten, obwohl ich nun beliebige Unterbrechungen von 1 bis 70 uM gemacht habe.

Kannst du mir bitte genau sagen, was du mit was verbunden hast, damit dein gepostet Programm bei mir laeuft - ich benutze einen normal aufgebauten ASURO ohne LCD display ? Ich weiss, es wir oben schon erklaert, aber irgendwie hab' ich das Gefuehl, dass ich etwas falsch mache. Also ich hab' es so angeschlossen:

5v supply - out+
0 Ground - out-
der 'Mittlere',also trigger input,output - CON1
No connection - PD6

mit folgendem programm


#include "asuro.h"


#ifndef F_CPU
/* wenn F_CPU nicht bereits vorher definiert (z.B. durch
Übergabe als Parameter zum Compiler innerhalb des Makefiles) */
#define F_CPU 8000000UL /* Quarz mit 8 Mhz */
#endif
#include <util/delay.h>


// Funktion: Abstand per Ultraschall messen über SRF05
// Parameter:
// sensor: PIN an dem der Sensor hängt
// Rückgabewert: gemessener Abstand in cm


uint16_t getAbstand(uint8_t sensor) {
uint8_t tmp_sreg;
tmp_sreg = SREG;
cli(); // interrupts deaktivieren
uint16_t abstand = 0; // abstand in cm


DDRD |= (1<<sensor); // sensor Pin auf Ausgang
PORTD |= (1<<sensor); // sensor Pin auf high setzen

_delay_us(20); // 20 mikrosek. warten

PORTD &= ~(1<<sensor); // sensor Pin auf low setzen (ist noch als Ausgang konfiguriert)


DDRD &= ~(1<<sensor); // sensor Pin auf Eingang setzen
while(!(PIND & (1<<sensor))); // auf Sensorantwort warten (Eingang wird high)

while(PIND & (1<<sensor)) // warten bis Signalende bis Eingang low wird
{
_delay_us(58); // 58 mikrosec. warten entspricht 1cm entfernung
abstand++; // Anzahl der cm erhöhen
}

SREG=tmp_sreg; // Register zurücksetzen

return abstand; // gemessenen Abstand zurückgeben
}

uint16_t avrAbstand(uint8_t sensor) {
uint8_t k=0;
uint16_t average=0;
for (k=0; k<50; k++)
average=average+getAbstand(sensor);
return (average/50);
}

int main(void)
{
Init();
int i=0;
int j,k;
BackLED(ON,ON);
char S[100];
while(1)
{
uint16_t abstand = avrAbstand(PD6);
sprintf(S,"\n\rA:%4d\n\r",abstand);
SerWrite(S,strlen(S));

}
}

Also, dieses Programm funktioniert bei mir. Ich weiss, eigentlich sollte bei "No connection" auch nichts verbunden sein, aber bei mir gibt es nur mit dieser Einsteckvariante Messungen aus.

KingTobi
13.10.2009, 12:56
Bist du sicher das du ihn im Betriebsmodus 2 verwendest?!

Also, 1. Pin an 5V, 2. Pin frei lassen, den mittleren Pin an PD6, 4. und 5. Pin an Masse! So und nicht anders!

Deine Funktion "avrAbstand" versteh ich nicht, ist doch total überflüssig?!

ippeb
13.10.2009, 14:10
Was muss man machen, dass er im Betriebsmodus 2 ist?

Ok, ich werd's mal so wie bei dir versuchen. Laeuft dein gepostetes Programm fuer den PD6 als Ansteuerpin? Und muesste das rote LED am SRF05 leuchten?

KingTobi
13.10.2009, 14:14
Um ihn in den BEtriebsmodus 2 zu bekommen musst du Pin4 mit GND verbinden.
Liess dir mal die Anleitung dazu durch!

Hier mal mein Code, bedenke aber das die Pausenzeiten "passend gemacht" sind.
Läuft dein Asuro wirklich auf 8MHz?


uint16_t getAbstand(uint8_t sensor)
{
uint16_t abstand = 0; // abstand in cm

DDRC |= (1<<sensor); // sensor Pin auf Ausgang
PORTC |= (1<<sensor); // sensor Pin auf high setzen

_delay_us(4); // 20 mikrosek. warten

PORTC &= ~(1<<sensor); // sensor Pin auf low setzen (ist noch als Ausgang konfiguriert)
DDRC &= ~(1<<sensor); // sensor Pin auf Eingang setzen

while(!(PINC & (1<<sensor))); // auf Sensorantwort warten (Eingang wird high)

while(PINC & (1<<sensor)) // warten bis Signalende bis Eingang low wird
{
_delay_us(1); // 58 mikrosec. warten entspricht 1cm entfernung
abstand++; // Anzahl der cm erhöhen
}

return abstand; // gemessenen Abstand zurückgeben
}

/////////////////////////////////////////////////////////////////////////////
// Main-Funktion
/////////////////////////////////////////////////////////////////////////////
main()
{
uint16_t x = 0;
char ausgabe[10]="\0";

lcdInit();
lcdString("X ");
x = getAbstand(5);
itoa((x/22), ausgabe, 10);

lcdString(ausgabe);
lcdString("cm");

while (true) // Mainloop-Begin
{


} // Mainloop-Ende

ippeb
13.10.2009, 14:17
Mmh... Also, um sicher zu gehen:

Ich stecke alles so ein, wie beschrieben, Pin 1,3 und 5. Dann kompiliere ich das Programm, flashe es auf den ASURO ... und nichts laueft... das habe ich nun ein paar Mal wiederholt... immer das gleiche Resultat.... mache ich etwas falsch?

ippeb
13.10.2009, 14:19
Wo gibt's die Anleitung? Ich habe schon ein paar SRF05 datasheets angeschaut... da wird aber nicht so viel dazu erklaert... alles recht kurz.

KingTobi
13.10.2009, 14:21
http://www.robotikhardware.de/download/srf05doku.pdf

ippeb
13.10.2009, 14:22
Und wo ist der GND konkret am ASURO? (Sorry dass ich so bloede Fragen stelle, bin noch recht ein Anfaenger)

KingTobi
13.10.2009, 14:25
GND ist Masse, bzw. 0V! Und da muss Pin 4 mit ran.

ippeb
13.10.2009, 14:32
jipppiiii
es laeuft -> juipiduippiiii
Zwar nicht so genau... aber es tut sich was! ich glaub's fast nicht :D ... nach zwei Monaten Hardware check, endlich!

Ich hab' vergessen (bzw. nirgends gelesen) dass man den 4.Pin mit dem 5.Pin am SRF05 kurzschliessen muss...

KingTobi
13.10.2009, 14:33
Das steht in dem Link den ich weiter oben gepostet hab.

ippeb
13.10.2009, 14:37
Du bist einfach Klasse -> KingTobi <-

Falls du Mal ein Problem mit C++ oder etwas Algorhmisches hast, kannst du mir gerne ein Mail schreiben, ich wuerde dir auch gern Mal irgendwie helfen ^^

Also, jetzt werde ich die Praezision noch etwas verbessern.

ippeb
14.10.2009, 16:43
Komisch... nun heute bin ich augestanden, und hab' genau den US-range wieder ausprobieren wollen... jedoch gibt er kein Signal... und wenn man "hinhoert", gibt's auch kein biipen mehr, ich glaub' der Transmitter ist kaputt gegangen oder so...

Gibt es eine Art das zu ueberpruefen? Vielleicht mit den Hersteller Pins oder so?

KingTobi
14.10.2009, 16:48
Du hattest vorher ein biepen?! Bei meinem höre ich nichts.
Hast du schon geprüft ob der µC tut was er soll?
Was sagt die LED am US Sensor?

ippeb
14.10.2009, 17:04
Doch, es kommt ein Signal raus, aber immer die "305". Wenn ich die ultrasonic delay aendere, kommen andere Werte raus.
Die LED leuchtet, aber Helligkeit aendert sich nicht mit der Distanz zum Objekt. Der Microcontroller funktioniert auch super. Der SRF05 habe ich auf beiden meiner ASUROs getestet, bei beiden das gleiche Resultat...

ippeb
14.10.2009, 17:11
Das Problem liegt auch ganz bestimmt nicht an den Batterien....

ippeb
14.10.2009, 17:39
mmh... und wenn ich laute "Pfeifgeraeusche" mache, aendert sich was in der Anzeige!

ippeb
14.10.2009, 18:49
Was denkt ihr? Der Transmitter muss wohl kaputt sein! Nun, ich hab' den Transmitter vom SRF04 zuhause. Sollte ich den an den SRF05 löten? Wäre das Problem dann gelöst?