PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Asuro: PollSwitch im Interrupt betrieb



MadMan2k
18.02.2006, 13:34
int main(void) {
Init();
EncoderInit();
StartSwitch();
unsigned char sw_data;

while(TRUE) {
if(sw_pressed) {
MotorState(BREAK, BREAK);

sw_data = PollSwitch(); // wenn ich die zeile auskommentiere gehts

Rotate(180, 200);

sw_pressed = FALSE;
StartSwitch();
} else {
MotorState(FWD, FWD);
MotorSpeed(200, 200);
}
}

return 0;
}

muss man bei der benutzugn von poll switch irgendwas besonderes beachten?
Denn wenn ich es benutze ist sw_pressed nach dem ersten interrupt dauerhaft TRUE.

Andun
18.02.2006, 14:20
Also so weit ich das verstanden habe, brauchst du die PollSwitch() im Interrupt Betrieb nciht, da du damit manuell ne Messung anstößt.

Andun

MadMan2k
18.02.2006, 15:58
das Problem ist, dass er mir im Interrupt Betrieb nur sagt, dass ein Schalter gedrückt wurde und nicht welcher.

MadMan2k
18.02.2006, 23:05
ok, scheinbar löst er nach einem PollSwitch noch ne weile Interrupts aus.
Wenn ich demnach ein


while(sw_pressed) {
sw_pressed = FALSE;
StartSwitch();
}

in die sw_pressed behandlung einbaue gehts.

Aber wenn jemand ne elegantere Lösung hat - immer her damit...

Mooses78
15.01.2007, 14:16
Hi MadMan

hab grad das gleiche Problem.

wo wird die Variable sw_pressed bei dir denn gesetzt?

MadMan2k
15.01.2007, 15:58
das macht ein interrupt in der erweiterten asurolib, siehe:
https://gna.org/projects/asuro-tools/

Mooses78
15.01.2007, 16:21
Danke, werd ich mir mal anschaun.

Mooses78
15.01.2007, 16:33
hm, ok, habs gesehen.
nun will ich mir die SIGNAL routine (ich verwende hier nich die original lib und die alte avr-libc) eigentlich selbst schreiben.

Naja, sowas wie die Interrupts abfangen ist natürlich möglich, aber ich geb dir recht, elegant ist was anderes ;-)

muss mal in mich gehen, wieso denn da am Pin noch low anliegt (nachdem der Schalter losgelassen wurde), bzw wie mans umgehen kann.

Viele Grüße

Mooses

Mooses78
16.01.2007, 08:51
Ok, das problem ist natürlich wieder der bewusste Kondensator. Wenn der Schalter losgelassen wird ist die Spannung da erstmal auf logisch 0 und der Kondensatur muss über den 1M Widerstand von Versorgungsspannung aufgeladen werden.

Was ich jetzt gemacht hab ist, dass ich den Asuro zurücksetzenlasse (für ne halbe sekunde) und in dieser Zeit einfach den Interruptpin wieder auf Ausgang und 1 schalte (wird ja nach PollSwitch() wieder auf Eingang gesetzt ), ich lade also den Kondensator über Versorgung und den Interruptpin, das scheint zu funktionieren.

Bis dann

Mooses

damaltor
17.01.2007, 20:41
genau so ist es. der kondensator ist schuld. bei mir hat es sehr geholfen, ihn auszubauen bzw. abzukneifen.
Die signal routine kannst du natürlich selbst schreiben, öffne die asuro.c und kommentiere die alte routine aus, dann kannst du einen neue schreiben.

Mooses78
18.01.2007, 07:09
Hab schon gelesen, dass ein paar Leute ihn ausgebaut haben, due Lösung hat mir aber nicht so gut gefallen. Jetzt lade ich ihn einfach über den Interruptpin, das funktioniert ganz gut.

Ich verwende bisher noch die alte asuro.c, hol mir ersmal nur Anregungen aus der neuen, und bastel mir dann zusätzliche source-files für die unrterschiedlichen anwendungen.

farratt
21.03.2008, 19:07
Heißt das also, dass man in der original asuro.c in PollSwitch() die Zeile mit SWITCH_OFF vor dem return durch ein SWITCH_ON ersetzen muss? Genau das bewirkt doch, dass der Pin per Pullup hochgezogen wird, oder?

Gruß farratt

damaltor
22.03.2008, 18:19
wie kommst du darauf?

farratt
22.03.2008, 18:48
Naja, Mooses78 hat geschrieben, dass das Problem darin liegt, dass der Pin nach der Messung auf 0 ist und erst langsam über das RC-Glied wieder geladen wird. Das bedeutet, dass eine StartSwich()-Anweisung einen Interrupt auslöst, wenn sie direkt hinter einem PollSwitch() ausgeführt wird.
Dieses Verhalten ließe sich vermeiden, wenn man den Pin manuell auf high legt und genau das macht doch SWITCH_ON, oder?
SWITCH_ON steht für PORTD |= 1<<PD3.
Und das bewirkt doch, dass der Pin mittels internem PullUp auf high gezogen wird oder?
Außerdem hab ich seit dem ich das gemacht hab keine Probleme mehr; es funktioniert alles bestens. Auch bei komplexen Programmen mit viellen PollSwitch-, StartSwitch- und StopSwitch-Anweisungen.

Gibt es denn noch eine andere Lösung? (Ich meine Lösung, nicht Workaround 8) )

Gruß farratt

damaltor
22.03.2008, 19:37
das klingt sehr vernünftig, da bin ich nicht drauf gekommen. recht hast du. aber verfälscht das dann nicht die pollswitch werte bei der nächsten messung durch die zusätzliche spannung über den pullup?

farratt
22.03.2008, 19:50
also wie gesagt. bei mir funktionierts. Außerdem wird die Anweisung SWITCH_ON am Anfang jeder PollSwitch()-Anweisung ausgeführt. Das bedeutet, dass der Pullup bei jeder Messung sowieso im Spiel ist.
Aber denk ruhig noch ein bisschen drauf rum. Die Entwickler der original-Lib haben sich doch bestimmt was dabei gedacht, am Ende von PollSwitch SWITCH_OFF und nicht (wie von mir vorgeschlagen) SWITCH_ON zu schreiben.

Gruß farratt

damaltor
23.03.2008, 14:06
das ist anzunehmen, ja... evtl um ein kleies bisschen strom zu sparen, denn über den pullup fließt ja dauerhaft strom nach masse. aber ob das alles ist.... o0 diese pullups waren doch einige kΩ groß, dementsprechend könnte man nur einige µA sparen. kann mir nicht vorstellen dass das alles ist, wenn ich ehrlich bin.

farratt
23.03.2008, 14:43
kannst du das vielleicht auch mal testen?

damaltor
24.03.2008, 20:36
mein asuro ist gerade in mehr teile zerlegt, als in dem bausatz waren... aber allein von der theorie her wäre es so. schalte ein multimeter zwischen batterien und asuro, und probiere es aus.

farratt
25.03.2008, 14:50
Könnte man sagen, dass es sich bei der Geschichte um einen Bug handelt?
Wenn ja, dann müssten sich doch jetzt auch mal die Leute, die die Lib pflegen dazu melden. So wies im Moment ist, kann mans jedenfalls nicht lassen.
Ich glaube jedenfalls eine Lösung gefunden zu haben, aber das müsste man eben groß angelegt testen. Ich werde mal ein kleines Programm zum testen hochladen.

Gruß farratt

farratt
25.03.2008, 15:28
Hier also das Programm:


#include <stdint.h>
#include "asuro.h"
#include <stdlib.h>

static volatile uint8_t switched=0;

ISR(INT1_vect)
{
StopSwitch();
switched=1;
}

inline void msleep(uint16_t time)
{
uint16_t i;
for(i=time;i>0;i--)
Sleep(72);
}

void write(char* text)
{
uint8_t i=0;
while((text[i]!='\0')&&(i<255))
i++;

SerWrite((unsigned char*)text,i);
}

void writeint(int16_t zahl)
{
char text[7]={'\0'};
itoa(zahl,text,10);
write(text);
}


int main(void)
{
Init();
write("\n\rSchaltertest im Interruptbetrieb\n\r");

while(1)
{
StatusLED(GREEN);

StartSwitch(); //Interruptbetrieb starten
while(switched==0); //Wenn kein Schalter betätigt, dann mach nix

StatusLED(RED);
writeint(PollSwitch()); //gib Schalterwert aus
write("\n\r"); //gib Zeilenumbruch aus
msleep(500); //warte...
switched=0; //switched zurücksetzen
}
}




Möglicherweise müsst ihr das Programm noch ein wenig anpassen, damits bei euch läuft. Ich hab einige Funktionen mit in den Code gepackt, die bei höheren Lib-Versionen (die ich nicht verwende, weil ichs lieber selber machen will) möglicherweise standarmäßig dabei sind.

Nun zu den Ergebnissen:

Wenn man die original PollSwitch()-Funktion verwendet passiert folgendes im Hyperterminal:

Schaltertest im Interruptbetrieb
1
0
0
4
0
0
0
0
2
0
0
0

Die innere while-Schleife wird gar nicht erst betreten, weil der Interrupt schon durch die StartSwitch()-Funktion ausgelöst wird. Damit wird PollSwitch ausgeführt, ohne das ein Schalter gedrückt wurde. Das erzeugt die vielen Nullen. Die anderen Zahlen stimmen jeweils mit der entsprechenden Taste überein.

Ersetzt man in der PollSwitch, das letzte SWITCH_OFF durch ein SWITCH_ON erhält man das gewünschte Ergebnis:

Schaltertest im Interruptbetrieb
1
2
4
8
16
32
32
32
16
8
4
2
1


Gruß farratt

m.a.r.v.i.n
21.04.2008, 20:41
Hallo faratt,

hat leider eine Weile gedauert, aber jetzt konnte ich mich deinem Problem etwas näher widmen. Deine Lösung funktioniert zwar, aber es sollte etwas anders gelöst werden. Der Fehler steckt wie du schon richtig erkannt hast, in der PollSwitch Funktion.

RN-User thowil hatte mich schon vor über einem Jahr auf den Fehler hingewiesen und mir eine funktionierende Lösung geschickt. Leider habe ich die wohl irgendwie verschlampt. :oops:
Schande über mich.

So geht es richtig:


DDRD |= SWITCHES; // Port-Bit SWITCHES als Output
SWITCH_ON; // Port-Bit auf HIGH zur Messung
i = ReadADC(SWITCH, 10);

DDRD &= ~SWITCHES; // Port-Bit SWITCHES als Input
SWITCH_OFF; // Port-Bit auf LOW (PullUp abschalten)

Der Port Bit muß am Ende der Funktion wieder auf Eingang geschaltet werden. Diese Zeile fehlte.

farratt
24.04.2008, 14:10
Cool!

Sobald ich wieder Zugriff auf meinen Asuro habe, werd ichs mal ausprobieren.
Wird die Sache dann im nächsten Lib-Release geändert?

Gruß farratt