PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Schalter auswerten funktioniert nicht



dasisch
21.05.2007, 21:07
Hi Leutz,

bin noch relativ unbeholfen, da ich es vorgestern geschafft habe, meinen Asuro zusammenzulöten und ich vorher noch nichts hardwareseitig programmiert habe. Es funktioniert auch alles (Selbsttest ist wunderbar durchgelaufen) und ich habe auch schon ein paar Dinge programmiert. Allerdings bleibe ich immer bei den Tastsensoren hängen. Ich möchte die gern auswerten und bin jetzt dem Schema des Selftests gefolgt. Kann mir vielleicht jemand sagen, wo der Fehler liegt, dass die Tastsensoren in meinem Programm nicht ausgewertet werden?


#include "asuro.h"

void Msleep (int dauer)
{
int z;
for (z = 0; z < dauer; z++)
Sleep (36);
}

void beruehrstop ()
{
unsigned char sw;
sw = PollSwitch();

if (sw & 0x01)
MotorDir(BREAK,BREAK);
if (sw & 0x02)
MotorDir(BREAK,BREAK);
if (sw & 0x04)
MotorDir(BREAK,BREAK);
if (sw & 0x08)
MotorDir(BREAK,BREAK);
if (sw & 0x10)
MotorDir(BREAK,BREAK);
if (sw & 0x20)
MotorDir(BREAK,BREAK);
}

void beschleunigen (int beschl, int geschwindigkeit)
{
int a=90;
for (a=90;a<geschwindigkeit;++a)
{
MotorDir(RWD,RWD);
MotorSpeed(a,a);
BackLED (ON, ON);
Msleep(beschl);
beruehrstop();
}
BackLED (OFF, OFF);
}

int main(void)
{
Init();

beschleunigen (300, 200);
Msleep (2000);
MotorDir(BREAK,BREAK);

while(1);
return 0;
}


Wäre euch sehr dankbar :)

Viele Grüße und vielen Dank schonmal im Voraus!
Sven

Asuro-n00b
21.05.2007, 21:20
Du hast dein Programm in mehrere Funktionen aufgeteilt. Der Asuro springt immer zuerst in die Main-Funktion, dort müsstest du dann zB. dein beruehrstop aufrufen.
Außerdem hast glaub ich eine Funktion Msleep genannt. In der neuen Lib ist Msleep schon vergeben, das könnte auch Probleme geben.

Was gibt er dir denn aus, wenn du kompilierst?

Asuro-n00b
21.05.2007, 21:26
if (sw & 0x01)
MotorDir(BREAK,BREAK);
if (sw & 0x02)
MotorDir(BREAK,BREAK);
if (sw & 0x04)
MotorDir(BREAK,BREAK);
if (sw & 0x08)
MotorDir(BREAK,BREAK);
if (sw & 0x10)
MotorDir(BREAK,BREAK);
if (sw & 0x20)
MotorDir(BREAK,BREAK);
Du fragst hier alle Taster einzeln ab, das brauchst du garnicht, du kannst auch alle gleichzeitig auswerten.
--> if (PollSwitch()>0)
MotorDir(BREAK,BREAK);
Außerdem müssten die letzten beiden 16 und 32 statt 10 und 20 heißen.

dasisch
21.05.2007, 21:26
Hi,

danke für die schnelle Antwort.

Er gibt nichts negatives aus - sagt auch er hätte 0 Fehler gefunden. Ich habe die neue lib nicht installiert, sodass es da eigentlich keine Probleme geben sollte mit der Msleep (wird ja auch nichts angezeigt). Die Funktion beruehrstop habe ich ja in der zweiten Funktion aufgerufen (in der beschleunigen), die widerum in der main-funktion aufgerufen wird. Wenn ich beruehrstop in der main-funktion aufrufe, dann wird ja während dem Beschleuinigen nicht überprüft, ob einer der Schalter gedrückt wurde...

Ich weiss nicht so ganz weiter, weil ohne Taster ist das alles bischen blöd...

Viele Grüße,
Sven

[edit] da war ich wohl etwas spät. werde das mit dem gesamtauswerten ausprobieren und melde mich dann zurück. wer trotzdem nochwas dazu weiss, nur zu :-)

Asuro-n00b
21.05.2007, 21:31
Ach ja, ich hab deine Funktion beschleunigen mit deiner Variable beschl durcheinander gebracht ^^
Ich hab leider nur die neue Library drauf. Würd dir gerne helfen, aber ich hatte Probleme bis die neue Lib bei mir funste und will jetzt nicht wieder auf die alte umsteigen. Never change a running system.
Beschreib dochmal was du von deinem Programm erwartest.

dasisch
21.05.2007, 21:42
also eigentlich erwarte ich ja nur, dass er stopt, wenn er irgendwo dran fährt. hab das problem auch herausgefunden. scheinbar hat er ein problem, wenn ich die funktion beruehrstop() nach dem Msleep aufrufe. Habs jetzt davor gesetzt und jetzt funzts einigermaßen (das problem ist nur, dass ein Schalter bei längerem Drücken irgendwie immer so aussetzer hat...) vielen dank auf jeden fall nochma für die hilfe!

das mit der neuen lib läuft bei mir auch garnicht. ich krieg die nicht mal installiert. liegt vielleicht daran, weil ich auch noch delphi installiert hab und da musste ich ohnehin schon die pfade für das programmers notepad neu eintragen. aller anfang ist schwer ;-)

damaltor
21.05.2007, 21:46
die zahlen sind ok.

0x10 = 16
0x20 = 32

In dem programmcode oben wird beruehrstop() gar nciht aufgerufen. postest du mal deinen neuen programmcode?

Asuro-n00b
21.05.2007, 21:48
Ich hab für die Taster auch ewig gebraucht. ;)
Freut mich, dass es jetzt klappt.
Ich hatten den gleichen Fehler, wie du, dass er mir andre Werte ausgeben hat, wenn ich einen Taster länger gedrückt habe.
Versuch mal etwas mit dem Kondensator C7 rumzuspielen. Ich habe ihn jetzt ganz rausgenommen und seit dem die besten Werte. :)

Asuro-n00b
21.05.2007, 21:51
Doch beruehrstop wird in der beschleunigen-Funktion aufgerufen.
Ach ja, ich sollt mich endlich mal mit dem Zahlensystem auseinander setzen. ;)

dasisch
21.05.2007, 21:56
#include "asuro.h"

void Msleep (int dauer)
{
int z;
for (z = 0; z < dauer; z++)
Sleep (36);
}

void beruehrstop ()
{
unsigned char sw;
sw = PollSwitch();

if (sw & 0x01)
MotorDir(BREAK,BREAK);
if (sw & 0x02)
MotorDir(BREAK,BREAK);
if (sw & 0x04)
MotorDir(BREAK,BREAK);
break;
if (sw & 0x08)
MotorDir(BREAK,BREAK);
if (sw & 0x10)
MotorDir(BREAK,BREAK);

if (sw & 0x20)
MotorDir(BREAK,BREAK);
}

void beschleunigen (int beschl, int geschwindigkeit)
{
int a=90;
for (a=90;a<geschwindigkeit;++a)
{
MotorDir(RWD,RWD);
MotorSpeed(a,a);
BackLED (ON, ON);
beruehrstop();
Msleep(beschl);
}
BackLED (OFF, OFF);
}

int main(void)
{
Init();

beschleunigen (300, 200);
Msleep (2000);
MotorDir(BREAK,BREAK);

while(1);
return 0;
}


Apropos Zahlencodes: Kann mir jemand sagen, wo ich rauskriege, was das alles für Zahlencodes sind und was die bedeuten? In der selftest stehen noch mehr 0x... drin, wie beispielsweise 0xFE00. aber leider habe ich keinen blassen schimmer, was die bedeuten.

ehenkes
21.05.2007, 22:43
Das sind Zahlen im Hexadezimalsystem. Nimm den Taschenrechner aus dem MS Windows Zubehör, stelle ihn auf wissenschaftliche Ansicht. Dann tippst Du in der Auswahl HEX die Zahl FF ein, stellst dann in der Auswahl auf Dez um und erhälst 255. 0xFE00 bedeutet 65024.

http://de.wikipedia.org/wiki/Hexadezimalsystem

dasisch
21.05.2007, 23:00
joa, das weiss ich, die braucht man ja auch für farbcodes. ich weiss nur nicht, was hinter diesen zahlen steckt. also was genau spreche ich jetzt mit 0xfe00 an - weisst du, was ich meine?

radbruch
21.05.2007, 23:12
Die Taster sind jeweils über einen Widerstand mit einem gemeinsamen Pin des ATMega verbunden. Jeder Tastendruck erzeugt eine andere Widerstandskombination und damit eine andere Spannung, die an dem Pin gemessen werden kann. Der Messwert wird dann noch so umgerechnet, dass jedem Bit im Ergebnis von PollSwitch() einem bestimmten Taster entspricht. Also mal vereinfacht gesagt. Verwirrend ist dann noch, das Bit0 für den Switch6 steht...

Sternthaler
21.05.2007, 23:47
Hallo dasisch,
das Problem, ist eigendlich nicht ein 0x??-Wert, sondern eher die Funktion beschleunigen(). Ich habe die mal kopiert und KOMMENTIERT:


void beschleunigen (int beschl, int geschwindigkeit)
{
int a=90;
for (a=90;a<geschwindigkeit;++a)
{
2) MotorDir(RWD,RWD); <-- Jetzt geht es aber weiter ...
3) MotorSpeed(a,a); <-- .. mit einer neuen Geschwindigkeit!!!
BackLED (ON, ON);
1) beruehrstop(); <-- Taste gedrückt, dann MotorDir(BREAK,BREAK) <-- das geht.
Msleep(beschl);
}
BackLED (OFF, OFF);
}
Die Reihenfolge von beruehrstop() und Msleep() ist deshalb bei dir so wichtig, weill dann NACH dem wiedereinschalten der Motoren ja sehr schnell wieder abgeschaltet wird (durch weiterhin gedrückten Taster).
Nun kommt das Msleep() mit einer im Verhältnis zur 'ein'-Zeit der Motoren sehr langen Zeit. Somit hast du den Strom nur ganz kurz an, und lange aus, also 'glaubst' du, dass die Motoren stehen.

Es könnte so gehen, dass die Motoren komplett gestoppt werden:


void beschleunigen (int beschl, int geschwindigkeit)
{
int a=90;
for (a=90;a<geschwindigkeit;++a)
{
MotorDir(RWD,RWD);
MotorSpeed(a,a);
BackLED (ON, ON);
if (beruehrstop() == TRUE) // dann muss halt was zurueckkommen.
break; // beendet hier das for{}, nicht die Funktion!
Msleep(beschl);
}
BackLED (OFF, OFF);
}

Ich frage mich allerdings, ob in der Funktion beruehrstop() das break; bei
if (sw & 0x04)
MotorDir(BREAK,BREAK);
break;
gewollt ist??
Es verhindert eigendlich nur, das die Taster auf 0x08, 0x10 und 0x20 abgefragt werden, da es a) immer aufgerufen wird, und b) die Funktion verläßt.

Du solltest aber trotzdem überlegen, ob die Lösung von Asuro-n00b mit dem:
if (PollSwitch()>0)
MotorDir(BREAK,BREAK);
nicht doch sinnvoll ist. Du umgehst damt tatsächlich (fast) alle Probleme die bei den Tastern bzw. der Auswertung vorhanden sind.

Noch ein Wort zu dem 0xFE00 aus SelfTest()
Die Werte sind so ziemlich willkürlich gewählt und werden nur benutzt um die einzelnen Test (LineTest() SwitchTest() OdometrieTest() ...) ein bischen in die Länge zu ziehen. Sonst hast du ja nichts davon, wenn die nur 0,03 ms laufen würden :-)

dasisch
22.05.2007, 06:08
hi,

erstmal: das break soll natürlich nicht da rein, das war versehentlich noch beim kopieren drin. macht ja auch keinen sinn, im gegenteil...

ich habe das mit dem motor jetzt folgendermaßen gelöst:



void beschleunigen (int beschl, int geschwindigkeit)
{
int a=90;
for (a=90;a<geschwindigkeit;++a)
{
MotorDir(RWD,RWD);
MotorSpeed(a,a);
BackLED (ON, ON);
if (beruehrstop()>0)
{
drehen();
break;
}
Msleep(beschl);
}
BackLED (OFF, OFF);


danach stoppt der motor auch wirklich und die funktion zum drehen wird aufgerufen. vielen dank aber nochmal fürs genaue drüberschauen!

das mit den hexadezimalcodes hab ich jetzt glaube ich verstanden. es ist also so, dass damit eigentlich nur die Zahlen anders notiert werden, sodass man statt einer ganzen zahl dann beispielsweise 0xfe00 hat.

zu dem pollswitch > 0. das funktioniert bei mir nicht so ganz, scheinbar weil der erste schalter, wie bereits beschrieben, irgendwelche aussetzer hat und scheinbar immer mal wieder ein signal sendet. es funktioniert nur, wenn ich die schalter wie im quelltext anspreche.

So, jetzt erstmal ab in die schule -.-

Gruß,
Sven

damaltor
22.05.2007, 07:44
Testweise kannst du auch PollSwitch()>3 machen. dann sind zwar 2 taster abgeschaltet, aber dafür weniger fehler.

Sternthaler
22.05.2007, 23:46
das mit den hexadezimalcodes hab ich jetzt glaube ich verstanden. es ist also so, dass damit eigentlich nur die Zahlen anders notiert werden, sodass man statt einer ganzen zahl dann beispielsweise 0xfe00 hat.

So, jetzt erstmal ab in die schule -.-
Schule? Mann, du schreibst strukturierten Code, da denkt man nicht an Schule.
Deshalb hier vielleicht doch noch mal eine Übersicht für die 0x??-Dinger, da es auch noch Binärzahlen, Oktalzahlen und weitere 'Notierungen' gibt:


Dezimal[10] Hexadezimal[16] Oktal[8] Dual[2]
0 0 0 0
1 1 1 1
2 2 2 10
3 3 3 11
4 4 4 100
5 5 5 101
6 6 6 110
7 7 7 111
8 8 10 1000
9 9 11 1001
10 A 12 1010
11 B 13 1011
12 C 14 1100
13 D 15 1101
14 E 16 1110
15 F 17 1111
16 10 20 10000
17 11 21 10001

Wie man sehen kann, benötigst du für jedes System so viele verschiedene Zeichen (0,1,2,...,9,A,B,..) wie das System nun heisst. (Dezimal, Dual, Oktal, Hexadezimal [auch nur Hex genannt])
Also 'zählst' du in der Einer-Stelle immer nur ein Zeichen weiter, bis du alle erlaubten Zeichen 'verbraucht' hast. Dann erhöhen wir nun die 'Zehner-Stelle', bzw. nehmen sie dazu und fangen wieder in der Einer-Stelle mit 0 an.
Bei anderen System als Dezimal, ist die Zehner-Stelle aber z.B. beim Hexadezimal-System, nun eine 16-ner-Stelle.

Im Dezimalsystem 'weisst' du seit der Grundschule, dass 572 eigendlich folgendes bedeutet:
5 * 10^2 plus
7 * 10^1 plus
2 * 10^0

Im Hex-System tauscht du nur die 10^ gegen 16^ aus und benutzt noch A bis F als 'Zahlen'.
Beispiel: 0xFE00 bedeutet:
F * 16^3 plus
E * 16^2 plus
0 * 16^1 plus
0 * 16^0

Dabei sind A=10, B=11, C=12, D=13, E=14 und F=15 einzusetzen.
Und um dieses 'Durcheinander' auseinanderzuhalten wurde das 0x erfunden. Heisst einfach, dass z.B. 0x123 eben 291 in dezimaler Schreibweise sein soll.
0b wird für Dualzahlen benutzt. (b wie binary)
0o wird für Oktal benutzt. (Bin mir hier nicht ganz sicher)

So, ich hoffe, dass ich noch eine Kerze zur Erleuchtung beitragen konnte.

dasisch
23.05.2007, 06:07
hi, vielen Dank für die genaue erklärung. jetzt hab ichs auch komplett verstanden ;-)

Gruß,
Sven

damaltor
23.05.2007, 13:14
0o123 ist richtig, oktalzahlen haben ein kleines o.

der compiler versteht allerdings nur dezimalzahlen und 0x-hex-zahlen

damaltor
27.05.2007, 20:58
ich muss mich korrigieren:


dezimalzahlen:

1234567890

binärzahlen:

0b01010101

hexadezimalzahlen:

0x90ABCDEF

oktalzahlen:

012345670

oktalzahlen werden nur dadurch ausgezeichnet dass sie eine null voranhaben, KEINEN buchstaben. allerdings weiss ich nicht, wie der gnu-compiler das handhabt, schliesslich will er ja auch keine binärzahlen kennen...