PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Code aus dem Band I für US funktioniert nicht mit neuer Lib



ehenkes
02.06.2007, 21:07
Ich habe auf einen meiner ASUROs nun die US-Erweiterung aufgesteckt. Der Code aus dem Buch Mehr Spaß mit ASURO Band 1 funktioniert aber nicht. Auch die Suche im Forum nach einem Code für die neue Lib war nicht erfolgreich. Könnte bitte jemand einen funktionierenden Code posten, damit ich testen kann, ob die Hardware in Ordnung ist.

Sternthaler
02.06.2007, 21:44
Der Code im Buch ist auf der Counter-Variablen count72kHz aufgebaut.
Wenn du nur den Variablennamen geändert hast, dann stimmt das Timing nicht mehr, da in der neuen Lib der Zähler count36kHz ja nur noch halb so schnell hochgezählt wird.
Somit wird dann mit der Formel aus dem Buch auch der Registerwert OCR2 nicht mehr sinnvoll berechnet.

Falls du das schon gemacht hast, poste doch mal bitte deinen Code, denn sonst sind keine weiteren Differenzen vorhanden zwischen Asuro-Buch-Lib und der hier benutzten 'neuen Lib'.

ehenkes
02.06.2007, 21:51
#include "asuro.h"

void LocalInit(void)
{
// Change Oscillator-frequency of Timer 2
// to 40kHz, no toggling of IO-pin:
TCCR2 = (1 << WGM21) | (1 << CS20);
OCR2 = 0x64; // 40kHz @8MHz crystal
ADCSRA = 0x00; // ADC off
// Analog comparator:
ACSR = 0x02; // Generate interrupt on falling edge
ADMUX = 0x03; // Multiplexer for comparator to // ADC pin 3
SFIOR |= (1 << ACME); // Enable muliplexing of comparator
DDRD &= ~(1 << 6); // Port D Pin 6 is input!
}

void Ping(unsigned char length)
{
count36kHz = 0;
TCCR2 = (1 << WGM21) | (1 << COM20) | (1 << CS20); // Toggling of IO-Pin on

// generate the Chirp
while ( count36kHz*2 < length )
{
OCR2 = 0x64 + length/2 - count36kHz*2;
}
TCCR2 = (1 << WGM21) | (1 << CS20); // Toggling of IO-Pin off
OCR2 = 0x64; // set frequency back to 40kHz
}

int main(void)
{
int pos, i, posmarker;
Init();
LocalInit();

while(1)
{
posmarker = 0;
Ping(20);
StatusLED(YELLOW);
for(pos = 0; pos < 100; pos++)
{
Sleep(10);
if((ACSR & (1 << ACI)) != 0)
{
if(posmarker == 0) { posmarker = pos; }
}
ACSR |= (1 << ACI);
}

if(posmarker>10)
{
StatusLED(RED);
MotorDir(FWD, FWD);
MotorSpeed(200, 200);
}
else
{
StatusLED(GREEN);
MotorDir(FWD, RWD);
MotorSpeed(0, 200);
for(i = 0; i<100; i++)
{ Sleep(200); }
}
}
return 0;
}


Es tut sich nichts. Die Status-LED ist grün. Fertig.
Die Hardware habe ich an Sender/Empfänger mit dem Oszi gecheckt. Am Sender stabil 40 kHz (4V) und am Sender kommt ein Sinussignal im 10 mV Bereich an und reagiert auf Hindernisse.

m.a.r.v.i.n
02.06.2007, 22:12
Hi,



denn sonst sind keine weiteren Differenzen vorhanden zwischen Asuro-Buch-Lib und der hier benutzten 'neuen Lib'.


Das stimt nicht ganz, es wird auch ein anderer Interrupt verwendet.

@ehenkes: Hast du den Code aus der Asuro Lib 3.0 schon mal probiert. Der sollte auch mit der Lib V2.7 funktionieren.
http://svn.gna.org/viewcvs/*checkout*/asuro-tools/trunk/lib/ultrasonic.c?rev=10

Es muß allerdings noch folgende Zeile aus der ISR(TIMER2_COMP_vect) Funktion entfernt werden, damit es funktioniert.


TCNT2 += 0x25;

ehenkes
02.06.2007, 22:29
Also ich habe jetzt folgendes gemacht:
1) die Funktionen

/**************** Ultraschall asuro.c **************************/
void InitUltrasonics(void);
void RestoreAsuro(void);
int Chirp(void);
/* ----------- END ------------ */

in asuro.h deklariert und in asuro.c implementiert

2) Diese Funktion ist nun in asuro.c

ISR(TIMER2_COMP_vect)
{
//TCNT2 += 0x25;
count36kHz++;
if(!count36kHz) timebase++;
}

3) Folgender Code als Test:



#include "asuro.h"
int abstand=0;

int main(void)
{
Init();
SerWrite("\r\n --- ultrasonic test ---",29);
Msleep(1000);

do
{
abstand=Chirp();
SerWrite("\r\n distanz in cm: ",20);
Msleep(500);
PrintInt(abstand);
}
while(1);
return 0;
}

Ergebnis sieht interessant aus!!!

distanz in cm: 2
distanz in cm: 3
distanz in cm: 5
distanz in cm: 10
distanz in cm: 5
distanz in cm: 0
distanz in cm: 0
distanz in cm: 1
distanz in cm: 1
distanz in cm: 3
distanz in cm: 8
distanz in cm: 1
distanz in cm: 1
distanz in cm: 4
distanz in cm: 198
distanz in cm: 208
distanz in cm: 2
distanz in cm: 1
distanz in cm: 1
distanz in cm: 1
distanz in cm: 1
distanz in cm: 195
distanz in cm: 195

4) Als nächstes folgenden Code getestet:


#include "asuro.h"

void LocalInit(void)
{
// Change Oscillator-frequency of Timer 2
// to 40kHz, no toggling of IO-pin:
TCCR2 = (1 << WGM21) | (1 << CS20);
OCR2 = 0x64; // 40kHz @8MHz crystal
ADCSRA = 0x00; // ADC off // Analog comparator:
ACSR = 0x02; // Generate interrupt on falling edge
ADMUX = 0x03; // Multiplexer for comparator to // ADC pin 3
SFIOR |= (1 << ACME); // Enable muliplexing of comparator
DDRD &= ~(1 << 6); // Port D Pin 6 is input!
}

void Ping(unsigned char length)
{
count36kHz = 0;
TCCR2 = (1 << WGM21) | (1 << COM20) | (1 << CS20);
// Toggling of IO-Pin on // generate the Chirp
while((count36kHz*2) < length)
{
OCR2 = 0x64 + length / 2 - count36kHz*2;
}
TCCR2 = (1 << WGM21) | (1 << CS20); // Toggling of IO-Pin off
OCR2 = 0x64; // set frequency to 40kHz
}

int main(void)
{
int pos, i;
int posmarker;
Init();
LocalInit();
while(TRUE)
{
posmarker = 0;
Ping(20);
for(pos = 0; pos < 100; pos++)
{
Sleep(10);
if((ACSR & (1 << ACI)) != 0)
{
if(posmarker == 0) { posmarker = pos; }
}
ACSR |= (1 << ACI);
}

if(posmarker>10)
{
StatusLED(GREEN);
MotorDir(FWD, FWD);
MotorSpeed(200, 200);
}
else
{
StatusLED(RED);
MotorDir(FWD, RWD);
MotorSpeed(0, 200);
for(i = 0; i<100; i++)
{ Sleep(200); }
}
}
return 0;
}

Nichts funktioniert, nur grünes Licht.

Frage:
Hier könnte man doch abstand=Chirp(...) verwenden. Kann bitte mal jemand den Code aus dem Band 1 umschreiben? Ich stehe noch etwas auf dem Schlauch. ;-)

ehenkes
02.06.2007, 22:39
Quatsch, ist prinzipiell ganz einfach:


#include "asuro.h"

int main(void)
{
int abstand=0;
Init();
while(TRUE)
{
abstand=Chirp();
if(abstand>10)
{
StatusLED(GREEN);
MotorDir(FWD, FWD);
MotorSpeed(150, 150);
}
else
{
StatusLED(RED);
MotorDir(FWD, RWD);
MotorSpeed(0, 150);
Msleep(3);
}
}
return 0;
}


Hat das jemand schon optimiert?

Sternthaler
02.06.2007, 22:49
Das stimt nicht ganz, es wird auch ein anderer Interrupt verwendet.
Oh ja, Sleep() ändert sich ja auch.
Wenn nun in der "for (pos=0; pos<100; pos++)"-Schleife der Wert bei Sleep(10) auf 5 reduziert wird, dann sollte es aber doch wieder passen?

Muss dann aber nicht auch die 20 im Ping()-Aufruf halbiert werden?

ehenkes
02.06.2007, 23:03
Ping(...) und Sleep(...)? Den Code brauche ich nicht mehr. ;-)
Er funktioniert auch nicht. Ich habe nun die besseren Funktionen int abstand = Chirp(...) und Msleep(...). Zur Hardware: Auf welchen Widerstandswert sollte man den Rückkopplungstrimmer einstellen?

ehenkes
03.06.2007, 00:13
Welche Funktionen sind nach Anwendung von Chirp(...) deaktiviert? Geht z.B. Go(...) und Turn(...) - sprich die Encoder?

damaltor
03.06.2007, 14:19
nach cirp ist nix deaktiviert glaube ich, sondern nur nach der ultraschall-init-funktion. alles lässt sich aber mit restoreasuro() wieder richten.

ehenkes
03.06.2007, 15:06
Das wäre klasse. Merkwürdig, ich hatte das Gefühl, das Turn(...) nicht funktioniert. OK, werde ich nochmals genauer testen.

inka
18.06.2007, 11:28
hi ehenkes,
habe nun den folgenden code versucht:


#include "asuro.h"
#include "inka.h"
int dist;
int abstand=0;
int i;



int main(void)
{

Init();
WaitforStart();

while(1)
{
{
/*SerWrite("\r\n --- georgs ultrasonic test ---",32);
Msleep(1000);*/

do
{
BackLED(ON,OFF);
abstand=Chirp();

/*SerWrite("\r\n distanz in cm: ",16);
SerWrite("\r\n",5);
Msleep(500);
StatusLED(RED);
PrintInt(abstand);*/
BackLED(OFF,ON);

if(abstand > 20) {
StatusLED(GREEN);
MotorDir(FWD, FWD);
MotorSpeed(200, 200);
}
else {
StatusLED(RED);
MotorDir(FWD, RWD);
MotorSpeed(0, 200);
for(i = 0; i<150; i++) { Sleep(200); }
}
}
while(1);
}
}
return 0;
}
wenn ich die auskomentiertn zeilen aktiviere wird auch in etwa die gemessene entfernung geschrieben (der asuro ist dabei hochgebockt). Wenn ich ihn mit dem originalprogramm einschalte (und in der hand halte) reagiert er auch entsprechend auf verkleinerung der entfernung mit wenden und weiterfahren. Wenn ich ihn aber normal fahren lasse dreht er sich eigentlich nur im kreis (stück drehend zurück, stück vor usw.) liegt es nun am programm - was ich nicht glaube - oder an den fahrgeräuschen, die die US-messung stören?

ehenkes
18.06.2007, 18:00
Ich mache das so, dass ich die Bremsleuchten bediene, wenn der Abstand zu niederig ist. Dann kann man verfolgen, woher das Taumeln kommt. Geradeaus fahren gehört ja wirklich nichtn zu den Stärken des ASURO. Man kann aber Odometrie und US-Echolot mischen, z.B. so:


#include "asuro.h"
#define L_DIR ((PORTD & RWD) ? -1 : 1)
#define R_DIR ((PORTB & RWD) ? -1 : 1)

typedef int (*FunctionPointer) (int);
FunctionPointer actionList[];

int slow=60;
int fast=80;
unsigned char currentTask;

int leftSpeed=0;
int rightSpeed=0;
long motorTime=0;

int delta=100, Kp=20; // entspricht Kp=0.2

int wait(int msTime)
{
long t1=Gettime()+msTime;
unsigned char newTask, savedTask=currentTask;
int sensor, action=0;

do
{
for(newTask=0; newTask<savedTask; )
{
sensor=(*actionList[2*newTask])(newTask);
if(sensor)
{
currentTask=newTask;
action|=(*actionList[2*newTask+1])(sensor);
newTask=0;
}
else ++newTask;
}
}
while(t1 > Gettime());

currentTask=savedTask;
return action;
}

void drive(int leftSpeed_, int rightSpeed_)
{
leftSpeed = leftSpeed_;
rightSpeed = rightSpeed_;
}

int regel(int pwm, int e)
{
int y= (Kp * e)/100;
pwm+=y;
return (pwm>127)? 127 : ((pwm<-127) ? -127 : pwm);
}

int blink_SecTimer(int idx)
{
static int t1=0;
int t0=t1;
t1 = (Gettime()/1000) & 0x1;
return t0^t1; // bei Sekundenwechsel ==> 1 sonst 0
}

int blink_Action(int sensor)
{
static int led=GREEN;
if(led==GREEN)
led=RED;
else
led=GREEN;
StatusLED(led);
return 0x0;
}

int motor_Awake(int idx)
{
return Gettime()>motorTime;
}

int motor_Control(int sensor)
{
static int lpwm=0;
static int rpwm=0;
int l_ticks, r_ticks;
int Ta=Gettime()-motorTime+delta;

l_ticks=encoder[LEFT];
r_ticks=encoder[RIGHT];
EncoderSet(0,0); //Encoder Reset ();
motorTime=Gettime()+delta;

lpwm=regel(lpwm, leftSpeed -1240*L_DIR*l_ticks/Ta);
rpwm=regel(rpwm, rightSpeed-1240*R_DIR*r_ticks/Ta);

SetMotorPower(lpwm, rpwm);
return 0x1;
}

int avoid_Obstacle(int idx)
{
int abstand = Chirp();
if (abstand<10)
{
BackLED(ON,ON);
return abstand;
}
else
{
BackLED(OFF,OFF);
return 0;
}
}

int avoid_Action(int sensor)
{
static int flag;
drive(-slow, -slow); // 0,5 sec zurueck
wait(500);
if(flag)
{
drive(-slow, 0);
flag=0;
}
else
{
drive(0, -slow);
flag=1;
}
wait(200); // 0,2 sec Rückwaertskurve (abwechselnd links und rechts)
return 0x2;
}

int cruise_Forever(int idx)
{
return 1;
}

int cruise_Action(int sensor)
{
drive(fast, fast); // fahr rum
return 0x3;
}

FunctionPointer actionList[] =
{
// sense , // action
blink_SecTimer, blink_Action ,
motor_Awake , motor_Control,
avoid_Obstacle, avoid_Action ,
cruise_Forever, cruise_Action,
};

int main(void)
{
Init();
EncoderInit();
EncoderStart();

drive(0,0);
Msleep(1000);
currentTask=sizeof(actionList)/sizeof(FunctionPointer)/2;
return wait(0);
}

Du kannst das ja mal bei Dir testen. Die Werte in myasuro.h für die Odometrie anpassen.

inka
18.06.2007, 21:07
hmmm,
die myasuro.h habe ich mit den gemessenen werten versehen, neu übersetzt, dann ein neues projekt in avr-studio angelegt, projekteinstellungen ok, compiliert (nur eine warnung wegen init chirp)und geflasht...
der asuro steht mit angezogener handbremse (beide back-led´s an), die status led blinkt hektisch gelb, aber sonst passiert nix???

kannst du mir bitte unter die arme greifen? Denn deinen code vestehe ich nicht. Vielleicht so - hmm - mal in 2 jahren?

ehenkes
18.06.2007, 21:43
die status led blinkt hektisch gelbDas ist schlecht, denn diese soll im 1-Sekunden-Takt rot und grün blinken. OK, dann müssen wir Segel um Segel hochziehen, bis Dein ASURO soweit ist. Wir checken zunächst Dein Ultraschallortungssystem:


#include "asuro.h"
int abstand=0;

int main(void)
{
Init();
SerWrite("\r\n --- ultrasonic test ---",29);
Msleep(1000);

do
{
abstand=Chirp();
SerWrite("\r\n distanz in cm: ",20);
Msleep(500);
PrintInt(abstand);
}
while(1);
return 0;
}

Probiere mal, welche Werte bei Dir ankommen, und justiere Dein System so, dass die angegebenen Werte der Realität entsprechen. Vielleicht musst Du auch noch an dem 1MOhm-Trimmer des RC-Gliedes drehen. Bei mir steht der Widerstand etwa in der Mitte.

Dann vielleicht das hier:



#include "asuro.h"
#define MAXDIFF 90

int main(void)
{
int abstand, abstand_alt, diff, zaehler=0;
Init();
abstand = Chirp();

while(TRUE)
{
abstand_alt = abstand;
abstand = Chirp(); ++zaehler;
diff = abstand - abstand_alt;

if( (abstand>15) && (abs(diff)<MAXDIFF) )
{
StatusLED(GREEN);
MotorDir(FWD, FWD);
MotorSpeed(150, 150);
}
else if( (abstand>10) && (abstand<=15) && (abs(diff)<MAXDIFF) )
{
StatusLED(YELLOW);
MotorDir(FWD, FWD);
MotorSpeed(150, 100);
Msleep(10);
}
else
{
StatusLED(RED);
MotorDir(RWD, RWD);
MotorSpeed(150, 100);
Msleep(10);
}

if (zaehler > 800)
{
StatusLED(RED);
BackLED(ON,ON);
MotorDir(RWD, RWD);
MotorSpeed(200, 250);
Msleep(10);
BackLED(OFF,OFF);
}
if (zaehler > 810)
{
StatusLED(RED);
BackLED(ON,ON);
MotorDir(RWD, RWD);
MotorSpeed(250, 200);
Msleep(10);
BackLED(OFF,OFF);

if(zaehler > 820)
zaehler = 0;
}
}
return 0;
}
[/code]

ehenkes
18.06.2007, 21:59
Subsumption und Behavior:
http://en.wikipedia.org/wiki/Behavior-based_robotics
http://en.wikipedia.org/wiki/Subsumption_architecture

inka
19.06.2007, 08:06
danke ehenkes,
ich muss mich erstmal um die roots kümmern, go, turn und wie sie alle heissen mögen, sonst wird es nix...

ehenkes
19.06.2007, 16:29
Nur Geduld, das wird schon. :)

damaltor
20.06.2007, 10:40
der asuro steht mit angezogener handbremse (beide back-led´s an), die status led blinkt hektisch gelb, aber sonst passiert nix???


... Batterie leer? oder blinkt die anders?

inka
20.06.2007, 11:15
die batterie war voll, ich habe halt das problem, dass ich manche software (noch) nicht verstehe und dann nicht weiss woran sowas liegt. Siehe auch weiterer verlauf des threads - back to the roots...:-)

inka
30.09.2007, 18:54
Wir checken zunächst Dein Ultraschallortungssystem:


#include "asuro.h"
int abstand=0;

int main(void)
{
Init();
SerWrite("\r\n --- ultrasonic test ---",29);
Msleep(1000);

do
{
abstand=Chirp();
SerWrite("\r\n distanz in cm: ",20);
Msleep(500);
PrintInt(abstand);
}
while(1);
return 0;
}

Probiere mal, welche Werte bei Dir ankommen, und justiere Dein System so, dass die angegebenen Werte der Realität entsprechen.

wie justieren? womit?

das programm läuft, ergebnis - entfernung 0
Vielleicht musst Du auch noch an dem 1MOhm-Trimmer des RC-Gliedes drehen. Bei mir steht der Widerstand etwa in der Mitte.

das ist ja das einzige was an der us-erweiterung "justierbar" ist...trotz verstellungen am poti, StatusLED leuchtet grün, entfernung 0 wird im hyperterminal geschrieben, sonst nix...

Dann vielleicht das hier:



#include "asuro.h"
#define MAXDIFF 90

int main(void)
{
int abstand, abstand_alt, diff, zaehler=0;
Init();
abstand = Chirp();

while(TRUE)
{
abstand_alt = abstand;
abstand = Chirp(); ++zaehler;
diff = abstand - abstand_alt;

if( (abstand>15) && (abs(diff)<MAXDIFF) )
{
StatusLED(GREEN);
MotorDir(FWD, FWD);
MotorSpeed(150, 150);
}
else if( (abstand>10) && (abstand<=15) && (abs(diff)<MAXDIFF) )
{
StatusLED(YELLOW);
MotorDir(FWD, FWD);
MotorSpeed(150, 100);
Msleep(10);
}
else
{
StatusLED(RED);
MotorDir(RWD, RWD);
MotorSpeed(150, 100);
Msleep(10);
}

if (zaehler > 800)
{
StatusLED(RED);
BackLED(ON,ON);
MotorDir(RWD, RWD);
MotorSpeed(200, 250);
Msleep(10);
BackLED(OFF,OFF);
}
if (zaehler > 810)
{
StatusLED(RED);
BackLED(ON,ON);
MotorDir(RWD, RWD);
MotorSpeed(250, 200);
Msleep(10);
BackLED(OFF,OFF);

if(zaehler > 820)
zaehler = 0;
}
}
return 0;
}

hier leuchtet die StatusLED rot, die räder drehen so als wollte der asuro nach hinten fahren, von zeit zu zeit - ziemlich regelmäßig - leuchten die BackLED´s kurz auf, die motoren drehen kurz auf und dann geht das ganze von vorne los...


Ich vermute hardwareprobleme in der erweiterung. Kann mir bitte jemand vielleicht sagen, was ich mit einem multimeter wo messen kann (und was dort gemessen werden sollte) um die erweiterung zu überprüfen?
danke im voraus...

inka
05.01.2008, 09:48
hi allerseits,
ich teste wieder einmal meine hardware :-), versuche mit folgendem programm aussreiser bei entfernungsmessungen festzumachen, festzustellen wie oft sie vorkommen um sie letztendlich irgendwie "rauszurechnen"...

/*ladestation_anfahren*/

#include "asuro.h"
#include "inka.h"

int abstand,abst_1, abst_2, abst_3;
int main (void)
{
Init();

WaitforStart();

while(1)
{

{
abst_1=Chirp();
Msleep(200);
abst_2=Chirp();
Msleep(200);
abst_3=Chirp();
abstand=(abst_1+abst_2+abst_3)/3;
SerPrint("\r\n distanz in cm: ");
SerPrint(" ");
Msleep(500);
PrintInt (abst_1);
SerPrint(" ");
PrintInt (abst_2);
SerPrint(" ");
PrintInt (abst_3);
SerPrint(" ");
PrintInt (abstand);

if (abstand<10)
{
EncoderInit();
Go (-100,150);
StatusLED(RED);
Turn (-90, 150);
Msleep(200);
}
else {
EncoderInit();
Go (100, 150);
StatusLED(GREEN);
Msleep(200);
}
abstand=Chirp();
if (abstand<10)
{
EncoderInit();
Go (-100, 150);
Turn (-90, 150);
StatusLED(RED);
Msleep(200);
}
else {
EncoderInit();
Turn (90, 150);
StatusLED(GREEN);
Msleep(200);
}
}
}
return 0;
}

folgendes ergebnis:

distanz in cm: 144 118 126 129
distanz in cm: 151 0 138 96
distanz in cm: 123 127 147 132
distanz in cm: 152 143 130 141
distanz in cm: 140 147 136 141
distanz in cm: 147 148 139 144
distanz in cm: 145 125 136 135
distanz in cm: 0 122 0 40
distanz in cm: 123 138 120 127
distanz in cm: 132 137 137 135
distanz in cm: 116 118 127 120
distanz in cm: 0 0 0 0
distanz in cm: 146 157 137 146
distanz in cm: 146 147 127 140
distanz in cm: 141 148 146 145
distanz in cm: 140 137 147 141
distanz in cm: 0 0 0 0
distanz in cm: 0 0 0 0
distanz in cm: 121 127 118 122
distanz in cm: 121 136 135 130
distanz in cm: 134 133 121 129
distanz in cm: 120 114 126 120
distanz in cm: 138 134 118 130
distanz in cm: 0 0 0 0
distanz in cm: 127 135 127 129
distanz in cm: 138 133 119 130
distanz in cm: 118 126 137 127
distanz in cm: 120 118 127 121
distanz in cm: 125 0 128 84
distanz in cm: 0 136 140 92
distanz in cm: 149 133 0 94
distanz in cm: 123 118 120 120
distanz in cm: 0 118 11
distanz in cm: 121 0 137 86
distanz in cm: 133 146 128 135
distanz in cm: 0 0 0 0
distanz in cm: 130 146 136 137
distanz in cm: 0 134 0 44
distanz in cm: 142 118 0 86
distanz in cm: 132 157 137 142
distanz in cm: 0 127 136 87
distanz in cm: 112 105 112 109
distanz in cm: 118 140 134 130
distanz in cm: 131 128 119 126
distanz in cm: 0 0 0 0
distanz in cm: 126 128 128 127
distanz in cm: 109 112 118 113
distanz in cm: 109 0 118 75
distanz in cm: 105 118 127 116
distanz in cm: 112 0 11
distanz in cm: 0 176 184 120
distanz in cm: 0 118 129 82
distanz in cm: 140 146 137 141
distanz in cm: 110 126 0 78
distanz in cm: 122 0 140 87
distanz in cm: 121 117 137 125
distanz in cm: 140 137 137 138
distanz in cm: 131 126 146 134
distanz in cm: 123 125 135 127
distanz in cm: 142 135 137 138
distanz in cm: 121 0 0 40
distanz in cm: 128 117 136 127
distanz in cm: 127 110 130 122
distanz in cm: 109 131 137 125
distanz in cm: 134 0 129 87
distanz in cm: 0 0 0 0
distanz in cm: 142 137 118 132
distanz in cm: 123 128 127 126
distanz in cm: 0 0 133 44
distanz in cm: 138 135 127 133
distanz in cm: 0 140 0 46
distanz in cm: 0 0 131 43
distanz in cm: 134 136 145 138
distanz in cm: 145 0 0 48
distanz in cm: 133 125 118 125
distanz in cm: 0 115 128 81
distanz in cm: 0 116 0 38
distanz in cm: 126 0 130 85
der asuro steht aufgebockt, im bereich der us-kapseln vor ihm passiert nichts. Trotzdem misst er zwischendurch abstand 0!! Woher kann das kommen?

damaltor
05.01.2008, 12:13
das könnt epassieren wenn er anstatt dem echo sein eigenes signal direkt empfängt...

ehenkes
06.01.2008, 13:45
Sieht doch schon besser aus. Abstand 0 könnte der geometrische Kurzschluss zwischen Sender und Empfänger sein, den man über die e-Kurve abfangen will. Könnte auch eine Reflektion über den Boden sein. Verändere das Poti solange, bis die 0 verschwindet.

Ich muss meine Kiste auch mal wieder aktivieren. Vielleicht gewinnen wir gemeinsame Erkenntnisse. ;-)

inka
06.01.2008, 15:34
selbst mit dieser abschirmung ist es nicht gelungen die falschmessungen wegzubekommen...

http://www.a-g-k.com/_asuro/fotos/ultraschall/2008_01_05_01-1.jpg
da muss ich also noch dran arbeiten:-)
andere frage:
kann das sein, dass der einstellpoti probleme mit metallschraubenzieher hat?

damaltor
06.01.2008, 19:26
sollte eigentlich kein problem sein. sieh den schraubenzieher wieder raus :D

nein, ehrlich: du verdrehst ja nur den plastik teil, das eigentliche poti ist innen drin.

das bisschen schaustoff wird für den (erstaunlich lauten) ultraschallton nicht viel helfen. aber sieht sehr hübsch aus :D

inka
06.01.2008, 19:49
sagt meine tochter auch, erinnert irgedwie an ET...:-)

ich dachte weil der schaumstoff ja recht weich ist, dämmt er auch. Auch die oberfläche, es sind ja offene bläschen, also ich habe da diese eierkartons als dämm-material in erinnerung?

damaltor
07.01.2008, 02:42
probieren geht über studieren. aber denke daran, das signal ist wirklich SEHR laut, es wird nur von menschen nicht gehört. wenn du ein datenblatt findest zu den ultraschallkapseln, kannst du ja mal nachsehen, wie laut. dass da ein bisschen schaumstoff nicht reicht ist klar...

pinsel120866
08.01.2008, 10:04
Hallo Zusammen,

ich beginne jetzt mit dem Zusammenlöten des eBay-US-Bausatzes.

mal vorab dazu ein paar Fragen:

- falls ihr den Selben Bausatz habt, was muss ich beim Zusammenbau beachten?
- wie nahe soll der ASURO an das Hindernis herankommen um den vorhandenen Raum gut auszunützen?
- Müssen Sender und Empfänger genau parallel stehen oder kann man das noch Optimieren?

Es wäre schön wenn ihr mir eure Erfahrungen mitteilt.

Gruß
Pinsel

pinsel120866
08.01.2008, 11:21
Und gleich noch eine Frage:

ich habe gerade versucht mit der Lib 2.71 den US-Code der Homepage von Dr.Henkes (ich hoffe er hat nichts dagegen) zu kompilieren:


/*
Bewegung auf Basis Ultraschallortung
Dr. Erhard Henkes, Mai 2007
*/
#include "asuro.h" // incl. der Funktionen InitUltrasonics, RestoreAsuro, Chirp von "dopez" (roboternetz)
#define MAXDIFF 80 // Sehr große Sprünge zunächst ausblenden

int main(void)
{
int abstand, abstand_alt, diff, zaehler=0;
Init();
abstand = Chirp();

while(TRUE)
{
abstand_alt = abstand;
abstand = Chirp();
++zaehler;
diff = abstand - abstand_alt;

if( (abstand>15) && (abs(diff)<MAXDIFF) )
{
StatusLED(GREEN);
MotorDir(FWD, FWD);
MotorSpeed(150, 150);
}
else if( (abstand>10) && (abstand<=15) && (abs(diff)<MAXDIFF) )
{
StatusLED(GREEN);
MotorDir(FWD, FWD);
MotorSpeed(100, 150);
Msleep(30);
}
else
{
StatusLED(RED);
MotorDir(RWD, RWD);
MotorSpeed(150, 100);
Msleep(100);
}

if (zaehler > 400)
{
StatusLED(RED);
BackLED(ON,ON);
MotorDir(RWD, RWD);
MotorSpeed(200, 250);
Msleep(10);
BackLED(OFF,OFF);
}

if (zaehler > 405)
{
StatusLED(RED);
BackLED(ON,ON);
MotorDir(RWD, RWD);
MotorSpeed(250, 200);
Msleep(10);
BackLED(OFF,OFF);

if(zaehler > 410)
zaehler = 0;
}

}
return 0;
}


und kriege folgende Fehler:

C:\ASURO_SRC\asurolib\examples\FirstTry/test.c:12: undefined reference to `Chirp'
C:\ASURO_SRC\asurolib\examples\FirstTry/test.c:17: undefined reference to `Chirp'

Kann mir bitte jemand sagen wo ich den "Chirp" herkriege bzw. wo ich ihn einbinden muss?

inka
08.01.2008, 14:53
schaue dir die datei ultrasoni.c in der 2.7.1 lib an, dort ist beschrieben was zu tun ist...

pinsel120866
08.01.2008, 15:05
Heureka, Kompilierproblem gelöst!

In die asuro.h (bei mir unter c:\asuro_src\asurolib\lib ) folgenden Code (gefunden auf
http://www.henkessoft.de/Roboter/ASURO.htm) eingefügt:


/*****************ultrasonic*********************** *********/
/**
* being used insted TIMER2_OVF_vect during ultrasonic polling
*/
ISR(TIMER2_COMP_vect)
{
//TCNT2 += 0x25; //Wichtig!! Die Zeile muss entfernt werden, damit es funktioniert.
count36kHz++;
if(!count36kHz) timebase++;
}

/**
* initialises the Ultrasonic module
* this function is automaticly called by Chirp
*/
void InitUltrasonics(void)
{
// Change Oscillator-frequency of Timer 2
// to 40kHz, no toggling of IO-pin:
TCCR2 = (1 << WGM21) | (1 << CS20);
OCR2 = 100; // 40kHz @8MHz crystal
TIMSK |= (1 << OCIE2); // OCIE2: Timer/Counter2 Output Compare Match Interrupt Enable

ADCSRA = (0 << ADEN); // deactivate ADC
ACSR |= (1 << ACIS1); // Comparator Interrupt on Falling Output Edge

ADMUX = 0x03; // connect ADC3-input with comparator
SFIOR |= (1 << ACME); // connect ADC multiplexer to comparator
DDRD &= ~(1 << 6); // use Port D Pin 6 as input (AIN0)
}

/**
* restores the hardware after using the Ultrasonic module
* this function is called automaticly after a Chirp
*/
void RestoreAsuro(void)
{
TCCR2 = (1 << WGM20) | (1 << WGM21) | (1 << COM20) | (1 << COM21) | (1 << CS20);
OCR2 = 0x91; // duty cycle for 36kHz
TIMSK |= (0 << OCIE2); // OCIE2: Timer/Counter2 Output Compare Match Interrupt Enable

ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1); // clk/64
ACSR |= (0 << ACIS1);

if(autoencode)
{
EncoderInit();
}

Sleep(1);
}

/**
* @return distance in cm
*/
int Chirp(void)
{
unsigned int sleeptime = 0, dist = 0;

InitUltrasonics();

// chirpen:
count36kHz = 0;

while(count36kHz != 20)
{
OCR2 = 100 + 20 / 2 - count36kHz;
}

TCCR2 = (1 << WGM21) | (1 << CS20);
OCR2 = 100;

// analyse echoes:
while(TRUE)
{
Sleep(1);
sleeptime++;

if((ACSR & (1 << ACI)))
{
// Hinweis: 344 m/s Schallgeschwindigkeit in Luft bei ca. 20°C
dist = (unsigned int) ((long) ((344L * ((sleeptime * 1000L) / 72L) / 10000L) / 2L));
ACSR |= (1 << ACI);
break;
}

ACSR |= (1 << ACI);

if(sleeptime > 3500)
{
return -1;
}
}

RestoreAsuro();
return dist;
}



Nun stellt sich die Frage ob ich diese Datei abändern darf, oder ob ich das ganze in myasuro.c eintragen muss?

pinsel120866
08.01.2008, 15:09
@inka:

Danke für den Hinweis, hat wohl eine Überschneidung bei unseren Posts gegeben. Der Code in der ultrasonic.c scheint neuer als der von mir verwendete zu sein, mal sehen.

ehenkes
08.01.2008, 20:32
Freut mich, dass sich hier nun noch mehr Ultraschall-Asuros tummeln. ;-)

pinsel120866
08.01.2008, 21:00
hallo ehenkes,

mal eine Frage an den Fachmann:

Ich habe deinen Code geflasht:


/*****************ultrasonic*********************** *********/
/**
* being used insted TIMER2_OVF_vect during ultrasonic polling
*/
ISR(TIMER2_COMP_vect)
{
//TCNT2 += 0x25; //Wichtig!! Die Zeile muss entfernt werden, damit es funktioniert.
count36kHz++;
if(!count36kHz) timebase++;
}

/**
* initialises the Ultrasonic module
* this function is automaticly called by Chirp
*/
void InitUltrasonics(void)
{
// Change Oscillator-frequency of Timer 2
// to 40kHz, no toggling of IO-pin:
TCCR2 = (1 << WGM21) | (1 << CS20);
OCR2 = 100; // 40kHz @8MHz crystal
TIMSK |= (1 << OCIE2); // OCIE2: Timer/Counter2 Output Compare Match Interrupt Enable

ADCSRA = (0 << ADEN); // deactivate ADC
ACSR |= (1 << ACIS1); // Comparator Interrupt on Falling Output Edge

ADMUX = 0x03; // connect ADC3-input with comparator
SFIOR |= (1 << ACME); // connect ADC multiplexer to comparator
DDRD &= ~(1 << 6); // use Port D Pin 6 as input (AIN0)
}

/**
* restores the hardware after using the Ultrasonic module
* this function is called automaticly after a Chirp
*/
void RestoreAsuro(void)
{
TCCR2 = (1 << WGM20) | (1 << WGM21) | (1 << COM20) | (1 << COM21) | (1 << CS20);
OCR2 = 0x91; // duty cycle for 36kHz
TIMSK |= (0 << OCIE2); // OCIE2: Timer/Counter2 Output Compare Match Interrupt Enable

ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1); // clk/64
ACSR |= (0 << ACIS1);

if(autoencode)
{
EncoderInit();
}

Sleep(1);
}

/**
* @return distance in cm
*/
int Chirp(void)
{
unsigned int sleeptime = 0, dist = 0;

InitUltrasonics();

// chirpen:
count36kHz = 0;

while(count36kHz != 20)
{
OCR2 = 100 + 20 / 2 - count36kHz;
}

TCCR2 = (1 << WGM21) | (1 << CS20);
OCR2 = 100;

// analyse echoes:
while(TRUE)
{
Sleep(1);
sleeptime++;

if((ACSR & (1 << ACI)))
{
// Hinweis: 344 m/s Schallgeschwindigkeit in Luft bei ca. 20°C
dist = (unsigned int) ((long) ((344L * ((sleeptime * 1000L) / 72L) / 10000L) / 2L));
ACSR |= (1 << ACI);
break;
}

ACSR |= (1 << ACI);

if(sleeptime > 3500)
{
return -1;
}
}

RestoreAsuro();
return dist;
}


Wenn ich nun den Asuro einschalte fährt er nur Ruckartig rückwärts, wenn ich meine Hand davorhalte fährt er gleichmässig rückwärts. Leider nie vorwärts :-k

Die US-Sensoren scheinen zu funktionieren, oder nicht?

pinsel120866
09.01.2008, 09:21
Hallo,

ich habe für meine US-Kalibrierung den Code von ehenkes verwendet:


#include "asuro.h"
int abstand=0;

int main(void)
{
Init();
SerWrite("\r\n --- ultrasonic test ---",29);
Msleep(1000);

do
{
abstand = Chirp();
SerWrite("\r\n distanz in cm: ",20);
Msleep(500);
PrintInt(abstand);
}
while(1);
return 0;
}


mit diesen Messergebnissen:



distanz in cm: 0
distanz in cm: 05
distanz in cm: 14
distanz in cm: 15
distanz in cm: 15
distanz in cm: 14
distanz in cm: 05
distanz in cm: 15
distanz in cm: 15
distanz in cm: 14
distanz in cm: 15
distanz in cm: 14
distanz in cm: 15
distanz in cm: 14
distanz in cm: 15
distanz in cm: 04
distanz in cm: 0
distanz in cm: 0
distanz in cm: 0
distanz in cm: 0
distanz in cm: 0
distanz in cm: 0
distanz in cm: 0
distanz in cm: 697
distanz in cm: 698
distanz in cm: 698
distanz in cm: 698
distanz in cm: 498
distanz in cm: 597
distanz in cm: 697
distanz in cm: 697
distanz in cm: 675
distanz in cm: 697
distanz in cm: 697
distanz in cm: 671
distanz in cm: 698
distanz in cm: 713
distanz in cm: 0
distanz in cm: 14
distanz in cm: 19
distanz in cm: 19
distanz in cm: 09
distanz in cm: 19
distanz in cm: 19
distanz in cm: 19


Wenn ich nun diesen US-Code lade:


/*
Bewegung auf Basis Ultraschallortung
Dr. Erhard Henkes, Mai 2007
*/
#include "asuro.h" // incl. der Funktionen InitUltrasonics, RestoreAsuro, Chirp von "dopez" (roboternetz)
#define MAXDIFF 80 // Sehr große Sprünge zunächst ausblenden

int main(void)
{
int abstand, abstand_alt, diff, zaehler=0;
Init();
abstand = Chirp();

while(TRUE)
{
abstand_alt = abstand;
abstand = Chirp();
++zaehler;
diff = abstand - abstand_alt;

if( (abstand>15) && (abs(diff)<MAXDIFF) )
{
StatusLED(GREEN);
MotorDir(FWD, FWD);
MotorSpeed(150, 150);
}
else if( (abstand>10) && (abstand<=15) && (abs(diff)<MAXDIFF) )
{
StatusLED(GREEN);
MotorDir(FWD, FWD);
MotorSpeed(150, 100);
Msleep(30);
}
else
{
StatusLED(RED);
MotorDir(RWD, RWD);
MotorSpeed(100, 150);
Msleep(100);
}

if (zaehler > 400)
{
StatusLED(RED);
BackLED(ON,ON);
MotorDir(RWD, RWD);
MotorSpeed(250, 200);
Msleep(10);
BackLED(OFF,OFF);
}

if (zaehler > 405)
{
StatusLED(RED);
BackLED(ON,ON);
MotorDir(RWD, RWD);
MotorSpeed(200, 250);
Msleep(10);
BackLED(OFF,OFF);

if(zaehler > 410)
zaehler = 0;
}

}
return 0;
}


Nun dreht sich der Asuro ruckartig rückwärts im Kreis. Kann mir jemand einen Tip geben?

Danke
Pinsel

inka
09.01.2008, 09:33
hi,
hast du beim code 1 und den messergebnissen die entfernung (mit der hand z.b.) variiert?
zu code 2: du solltest versuchen die werte z.b. für MAXDIFF oder der abfrage zu abstand zu verändern...

pinsel120866
09.01.2008, 09:42
hi inka,

das variieren bei Code 1 habe ich gemacht. Geht, wenn auch der Wert schnell auf "0" springt. Der Poti ist so eingestellt, dass, wenn der Abstand und ca. 30 cm kommt "0" erscheint - dies war der beste Kompromiss nach 30 Minuten Poti einstellen.

Ist MAXDIFF der einzige Wert oder gibt es andere, die ich anpassen muß?

Noch was beim Kompilieren kommt folgende Warnung:
test.c:12: warning: implicit declaration of function 'Chirp'
kann ich die ignorieren?

Gruß
Pinsel

inka
09.01.2008, 10:06
hi,
man hat mir gesagt, bei der "0" handelt es sich um einen akustischen "kurzschluss" zwischen sender und empfänger und sollte eigentlich nicht vorkommen. Kommt aber vor, auch bei mir, isolierun so gut wie unmöglich. Also rausfilter, das versucht das zweite programm, wie, das habe ich noch nicht so genau verstanden...
Ob MAXDIFF die einzuge veränderbare größe ist kann i9ch also auch nicht so genau sagen...
die fehlermeldung beim kompilieren wird durch das "nichtanmelden" (deklarieren) der funktion Chirp() verursacht, ist durch das includen der datei in der diese definition bei dir definiert ist behebbar...

pinsel120866
09.01.2008, 10:30
OK, Wartung kommt nicht mehr. Mein Code sieht jetzt so aus:


#include "asuro.h" // incl. der Funktionen InitUltrasonics, RestoreAsuro, Chirp von "dopez" (roboternetz)
#include "ultrasonic.h"
#define MAXDIFF 80 // Sehr große Sprünge zunächst ausblenden

int main(void)
{
int abstand, abstand_alt, diff, zaehler=0;
Init();
abstand = Chirp();

while(TRUE)
{
abstand_alt = abstand;
abstand = Chirp();
++zaehler;
diff = abstand - abstand_alt;

if( (abstand>40) && (abs(diff)<MAXDIFF) )
{
StatusLED(GREEN);
MotorDir(FWD, FWD);
MotorSpeed(150, 150);
}
else if( (abstand>35) && (abstand<=40) && (abs(diff)<MAXDIFF) )
{
StatusLED(GREEN);
MotorDir(FWD, FWD);
MotorSpeed(150, 100);
Msleep(30);
}
else
{
StatusLED(RED);
MotorDir(RWD, RWD);
MotorSpeed(100, 150);
Msleep(100);
}

if (zaehler > 400)
{
StatusLED(RED);
BackLED(ON,ON);
MotorDir(RWD, RWD);
MotorSpeed(250, 200);
Msleep(10);
BackLED(OFF,OFF);
}

if (zaehler > 405)
{
StatusLED(RED);
BackLED(ON,ON);
MotorDir(RWD, RWD);
MotorSpeed(200, 250);
Msleep(10);
BackLED(OFF,OFF);

if(zaehler > 410)
zaehler = 0;
}

}
return 0;
}

Kannst du mal drübersehen? Ich habe immer noch das gleiche Problem mit dem "Rückwärtsgang".
Wie hast du deinen zum Laufen gebracht?

inka
09.01.2008, 10:43
hi,
es gibt noch viele, viele dinge beim asuro wo ich sehe, dass sie funktionieren aber noch nicht weiss warum. Habe jetzt z.b. folgenden code

#include "asuro.h"
#include "ultrasonic.h"


int main(void)
{
int abstand;
Init();
abstand = Chirp();

while(1)
{

abstand = Chirp();

StatusLED(GREEN);

if (abstand < 10)
{
StatusLED(RED);
BackLED(ON,ON);
EncoderInit();
GoTurn(0, -90, 150);
}
else
{
StatusLED(GREEN);
BackLED(OFF,OFF);
MotorDir(FWD, FWD);
MotorSpeed(170, 150);
}
}
return 0;
}
ausprobiert, der asuro fährt (einigermassen) geradeaus und biegt 10cm vor einem hindernis nach links ab. probiere es mal...

hoffe es hilft...

pinsel120866
09.01.2008, 11:03
Danke für den Code, habs getestet - gleiches Problem, Asuro dreht jetzt auch einem Rad rückwärts. Ich werde mir nochmal die US-Platine genau ansehen, möglicherweise habe ich beim zusammenbauen eine Fehler gemacht.

Gruß
Pinsel

pinsel120866
09.01.2008, 12:05
Hat irgend jemand von euch die US-Platine aus dem eBay (hinten steht "c by M. Klein drauf)?

Ich sollte wissen, wo genau welcher Widerstand hinkommt.

damaltor
09.01.2008, 15:00
ist im endeffekt doch nur ein teilesatz oder? ohne ebay nummer können wir das nicht wissen.

aber der schaltplan ist im ersten buch.

pinsel120866
09.01.2008, 15:58
OK dalmator,

ich habe mir nochmals den Schaltplan genau angesehen, Fehler gefunden und behoben. Es waren 2 Widerstände vertauscht. Jetzt funktionierts, wenn ich diesen Code verwende:


#include "asuro.h"
#include "ultrasonic.h"
#define MAXDIFF 100

int main(void)
{
int abstand, abstand_alt, diff, zaehler=0;
Init();
abstand = Chirp();

while(TRUE)
{
abstand_alt = abstand;
abstand = Chirp();
++zaehler;
diff = abstand - abstand_alt;

if( (abstand>15) && (abs(diff)<MAXDIFF) )
{
StatusLED(GREEN);
MotorDir(FWD, FWD);
MotorSpeed(150, 150);
}
else if( (abstand>10) && (abstand<=15) && (abs(diff)<MAXDIFF) )
{
StatusLED(GREEN);
MotorDir(FWD, FWD);
MotorSpeed(100, 150);
Msleep(30);
}
else
{
StatusLED(RED);
MotorDir(RWD, RWD);
MotorSpeed(150, 100);
Msleep(100);
}

if (zaehler > 400)
{
StatusLED(RED);
BackLED(ON,ON);
MotorDir(RWD, RWD);
MotorSpeed(200, 250);
Msleep(10);
BackLED(OFF,OFF);
}

if (zaehler > 405)
{
StatusLED(RED);
BackLED(ON,ON);
MotorDir(RWD, RWD);
MotorSpeed(250, 200);
Msleep(10);
BackLED(OFF,OFF);

if(zaehler > 410)
zaehler = 0;
}

}
return 0;
}


Damit kriegt allerdings mein Asuro mit der Zeit einen Linksdrall. Ich werde noch dran feilen, möglicherweise hast du mir noch einen Ratschlag...

Die eBay - Nummer vom US-Bausatz ist übrigens 330198321285, wenn's jemanden interessiert.

Gruß
Pinsel

damaltor
09.01.2008, 16:57
den linksdrall würde ich mir mit der ungleichheit der motoren erklären. wenn du den ultraschallbeusatz nich verwendest sondern der asuro nur mit 150,150 vorwährts fahren lässt, fährt er ja auch nicht geradeaus.