PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Terminalprogramm, Datenübertragung und



BlackDevil
25.08.2008, 21:38
Hi

Ich habe inzwischen einen USB Programmierer gefunden, 11€ kostet die Platine im Bausatz - ist ein "Privatmann" der den Spaß verkauft. Weis aber grad nich wie die heißt, sitze am Laptop - da hab ich die nicht gespeichert.

Jetz habe ich in dem Akku Thread im Elektronikbereich einen Datenlogger gesehen und das soll mein erstes Projekt werden. Quasi ein Vorprojekt für das Hauptprojekt.

Sinn der Aktion ist es, einen Motor mit 2, 4, 5 (oder 12V, wenn es ein 12V Motor ist) Festspannung zu versorgen und über 10s die Drehzahl zu loggen. Die gemessenen Drehzahlen und die verstrichene Zeit soll dann über den USB Logger auf den PC Übertragen werden, in das Terminal, und als Excel Datei speicherbar sein. Das das geht sah ich in dem anderne Thread, ich würde nur gerne mehr darüber lesen.

Prinzipell weis ich wie der logger aussieht:
Ich lass im Hintergrund einen Timer laufen der jede Sekunde die aktuell gemessene Drehzahl und die Aktuelle Zeit (da lass ich eine int Variable Mitlaufen) an den PC schickt, im richtigen Format.
Die Drehzahl würde ich über eine Gabellichtschranke an der Motorwelle messen. Frage: Gitb es einen Interrupt der immer dann eine Aktion auslöst wenn an einem bestimmten PIN eine 1 anliegt? Das wäre erste Sahne, dann könnte ich alles im Hintergrund laufen lassen...

Die Drehzahl würde ich auch über eine int Variable mitlaufen lassen. Immer wenn am Pin eine 1 anliegt Zähl ich die Variable um eins hoch. Da ich weis wieviele einsen eine Umdrehung hat, kann ich die gezählte Zahl durch diese Anzahl teilen und in der Drehzahlvariable speichern.

Oder denk ich da zu Primitiv?

Viele Grüße, Danke fürs lesen und helfen

Besserwessi
25.08.2008, 22:07
Der Witz bei dataloggern ist normalerweise, dass die Daten erst mal zwischen gespeichert werden, z.B. auf einer SD-karte oder im Dataflash. Erst Später wird der Pc angeschlossen und die Daten übertragen. Zum Teil kann man die Daten wohl auch direkt zum PC senden, dann ist das aber kein Standalone Data-logger mehr.

Es gibt externe interrrupts die genau auf signale am externen pine reagieren. Die Drehzahl mißt man besser über das stoppen der Zeit für eine Umdrehungen. Für diese kurzen Zeiten gäbe es da als Speziallfall noch die ICP-funktion. Die nimmt einem viel Arbeit bei der Zeitmessung ab und erlaubt Zeitmessungen mit einer Auflösung von 1 Zyklus (50 ns bei 20 MHz Takt).

BlackDevil
26.08.2008, 09:11
Naja Standalone muss der logger nich unbedingt sein - ich bin ja Mobil mit meinem Laptop und jetzt gleich mit SD Karte und kram einzusteigen würde mir misfallen - ich habe das ja nich umsonst ausgesucht: Das Projekt ist ja ziemlich Simpel.

Also, es scheint bessere möglichkeiten zum Drehzahlmessen zu geben. Die Ink. Scheiben haben ja, soweit ich das gelesen habe, zwei 90° zueinander verdrehte "Strichcodes". Hm - mit einer Gabellichtschranker hätte ich dann eine 1 wenn beide Striche nebeneinander liegen oder? Hab mich damit noch nicht ganz beschäftigt, neuland ;)

Andree-HB
26.08.2008, 09:36
mit einer Gabellichtschranker hätte ich dann eine 1 wenn beide Striche nebeneinander liegen oder?


...damit kann man die Drehrichtung bestimmen - also dadurch, welche Lichtschranke relativ zur Anderen Signal meldet.
http://www.dj5am.de/drehgeb/drehgeber.html

BlackDevil
26.08.2008, 10:07
Okay, das sind 2 Sensoren - Ich habe hier im Forum aber schon öfter die Drehzahlmessung über einen Sensor gesehen ... oder wäre es besser das ganze mit einem Magnet zu lösen? Wie beim Fahrradtacho ebend... da gabs ja glaube ich auch eine Lösung

oberallgeier
26.08.2008, 11:05
Okay, das sind 2 Sensoren - Ich habe hier im Forum aber schon öfter die Drehzahlmessung über einen Sensor gesehen ... Drehzahlmessung geht natürlich mit einem Sensor. Drehrichtungserkennung geht (nach allem was ich weiß) nur mit (mindestens) zwei Sensoren, aber da kannst Du auch die Drehzahl gleich mitmessen. Ich messe die Drehzahl an zwei Motoren mit dem extINT0 und ~1 an einem mega168 - der mega macht natürlich noch andere Dinge dazu. Das kann man dann mit fallender (oder steigender) Flanke messen, so bekommt man gerade einen Incrementalgeberstreifen mit - bei mir ist es ein einfacher Unterbrecherflügel auf der Motorwelle (https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=344432#344432). Diesen Incrementalgeberstreifen zählt man dann in einer recht kurzen ISR hoch und setzt den Zähler zurück, nachdem man - irgendwann - den Zählwert abgeholt hat. Abholen sollte man den Wert natürlich vorm Überlaufen *ggg*.


... oder wäre es besser das ganze mit einem Magnet zu lösen? Wie beim Fahrradtacho ebend... da gabs ja glaube ich auch eine LösungDamit habe ich keine Erfahrung. Ich bezweifle, dass das besser ist - der Motor erzeugt ein Magnetfeld das ne heftige Wechselfrequenz hat - ob das nicht stört ? ?

BlackDevil
26.08.2008, 16:50
Also rein vom Prinzip her misst du die Drehzahl so wie ich anfangs dachte. Die drehrichtung ist mir eigentlich wurscht, ich will nur die Drehzahl bei Konstanter Spannung wissen (den verlauf). extINT0 ist ein Interrupt der im Hintergrund läuft und immer dann etwas tut wenn an einem Pin eine 1 anliegt? Habe mich bisher nur mit Timer INterrupts beschäftigt

oberallgeier
26.08.2008, 17:50
Hallo BlackDevil,


Also rein vom Prinzip her misst du die Drehzahl so wie ich anfangs dachte ...Das dachte ich auch, daher auch meine Einmischung hier.


... extINT0 ist ein Interrupt der im Hintergrund läuft ...?Bitte nimm das nicht als vorwurfsvoll polemisch sondern eher als fachlich-pingelig: Interrupts laufen ja eigentlich fast immer "im Hintergrund". Sprich: Die Unterbrechung ist da, ohne dass "das Programm" was dazu tut - jedenfalls meistens.


... extINT0 ist ein Interrupt der ... immer dann etwas tut wenn an einem Pin eine 1 anliegt ...Jein. Der externe Interrupt ist (lass mich über den mega168 sprechen, da bin ich etwas zuhause) einer von zwei Interrupts mit z.B. folgenden Eigenschaften:
1) Sie sind sehr hoch priorisiert - wichtiger als jeder Timer! Beim mega168 kommen die beiden - extINT0 und extINT1 - gleich nach dem RESET-Vektor.
2) Zitat aus dem m168-doc: The INT0 and INT1 interrupts can be triggered by a falling or rising edge or a low level. Ich kann also je nach meinen Wünschen auf eine der beiden Flanken triggern (0 geht auf 1 oder 1 geht auf 0) oder auf den low-Level. Letzteres dürfte mit Vorsicht zu geniessen sein, weil dieser hoch priorisierte Interrupt bei anstehendem low level möglicherweise ständigen Aufruf der ISR bedeutet = Koma für den Controller. Aber das habe ich noch nie ausprobiert.
Der Interrupt kommt kann eben genau dann kommen, wenn eine Signaländerung am Pin ansteht - meiner Meinung nach genau das, was für eine Drehzahlmessung wünschenswert ist. (Beim m168 gibts noch auf praktisch allen Pins den PCI = pin change interrupt, der ähnliches macht).
3) Die Interrupts können ohne Rücksicht auf die Portdefinition kommen (genaueres dazu steht im doc).
4) Die Flankeninterrupts sind zwar an eine Systemclock gebunden, aber der Levelinterrupt nicht. Das heisst, dass der Controller "schlafen" kann - meist aus Energiespargründen und wenn ein Levelsignal erkannt wird, wacht er auf. Es gibt Einschränkungen dazu, steht wieder im doc.

Langer Rede kurzer Sinn - ich finde diese beiden Interrupts für Drehzahlmessung ideal. Aktuell läuft das bei mir so: ein TimerInterrupt mit 50 µs zählt mir eine Variable bis auf 20000 = 1 sec. Der extINTx zählt seine Aufrufe und liest den aktuellen Zeitwert aus. Dieser Zeitwert wird dann im "normalen" Programm und insbesondere in der Regelung ausgewertet. Für mich war das hauptsächliche Entwicklungsziel: Messwert der Drehzeit für die Regelung und Zählwert für die Wegmessung. Wegmessung wird bei mir noch nicht ausgewertet, die Regelung läuft (https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=390196#390196) für meine Begriffe perfekt. Auf Wunsch kann ich Dir auch den aktuellen Code posten - wenn Du Dir das nicht lieber selber erarbeiten willst.

BlackDevil
26.08.2008, 19:56
Code ist immer interessant, obgleich deine Variablen etwas schwierig zu entziffern sind (teilweise).

Mh - wenn es so einen Interrupt gibt (was mich gewundert hätte wenn es ihn nicht gegeben hätte) ist das ja schon was ich brauche.

Interrupt kommt => ticker +1
Wenn ticker = (zB) 20 erreicht hat => Umdrehung +1
Jede Sekunde dann den Aktuellen Wert (Zeit + Umdrehung) übertragen
fertig

Wäre so die einfachste Variante

Besserwessi
26.08.2008, 20:22
Zur Zeitmessung ist der ICP Interrupts besser geeignet. Hier wird die eigentliche Zeitmessung per hardware erledigt und wird daher nicht eventuell doch durch einen anderen Interrrupt um ein paar µs verzögert. Ansosnten verhält sich der ICP Pin wietgehend wie an externer Interrrupt.
Man muß die Zeit auch nicht von Hand weiterzählen, das kann man auch bei der Verwendung eines normalen externen Interrupts vom Timer erledigen lassen. Man braucht dann nur die Differenz der Zeiten vom Start und Stop zu bilden.
@blackdevil:
So war das Verfahren nicht gemeint. Da wurden wohl die beiden Verfahren ducheinander gebracht.

Das Einfachste (und auch ziehmlich das beste) ist so:
Beim externen Interrupt (oder besser ICP) die Zeit zum Interrupt auslessen. Von dieser Zeit die Zeit zum Interrupt davor abziehen. Die Zeit des Interrupts speichern für die nächste Messung. Bei den Zeitdifferenzen kann man mit unsigned ints rechnen und eventuelle Überläufe einfach ignorieren.

oberallgeier
26.08.2008, 22:11
Code ist immer interessant ...... dabei wollen wir mal festhalten, dass ich im Prinzip immer noch Anfänger bin - ich beschäftige mich grad ein knappes Jahr mit µC´s und mit der Sprache C erst seit letztem Dezember. Beschäftigen heißt ja auch nicht "können".


... obgleich deine Variablen etwas schwierig zu entziffern sind (teilweise) ...Du loos, ih wohn im beirischn Schwobn, des isch bei iis des Allgei - obwol i a Auslenda bi. Do wiatz scho a bizzle a drAnpassung liaga. (Kann ich bei Bedarf in die eine oder andere europäische Sprache übersetzen).

Zuerst muss man mal einen Timer initialisieren. Ich mach das mit dem Timer2, das ist der Timer mit der höchsten Interrupt-Priorität - also der, der als erster bedient wird! Der Timer2 wird bei mir wie folgt initialisiert - denk dran, ich arbeite mit dem mega168 und einem 20MHz-Takt, bei anderen Takten und Zeitschnippsel muss entsprechend angepasst werden. Hier kann ich übrigens nix für die Variablen - die sind im doc vorgeschrieben.

/* ================================================== ============================ */
/* === Initialisierung fuer Timer2 mega168 ===================================== */
void TC2TMR_init(void) // Init Tmr/Cntr 2, 8-Bit auf 20 kHz = 50 µs
{
TCCR2A |= (1<<WGM21); // Timer im CTC-Mode, Top=OCR2A doc S 157
TCCR2B |= (1<<CS21); // Prescaler 1/8 / Clock <- CPU doc S 158
OCR2A = 124; // Preset 125 für 50µs bei 20Mhz
TIMSK2 |= (1<<OCIE2A); // Tmr/Cntr2 CompareA interrupt enabled
}
/* ================================================== ============================ */
Da ich gerade beim Initialisieren bin, initialisiere ich auch gleich die beiden
externen Interrupts:

/* ================================================== ============================ */
/* === Initialisierung fuer EXT_INT0/1 auf Pin 4+5/PD2,3 bei m168 ================
$002 jmp SIG_INTERRUPT0 ; IRQ0 Handler _VECTOR(1)
$004 jmp SIG_INTERRUPT1 ; IRQ1 Handler _VECTOR(2) ================ */
void XTI_0_1_init( void )
{ //Initialisiere beide Interrupts auf rising edge
// d.h. EICRA ISC00,01,10+11 auf 1 (doc,S68)
EICRA |= (1<<ISC11)|(1<<ISC10)|(1<<ISC01)|(1<<ISC00);
EIMSK |= (1<<INT1)|(1<<INT0); // und erlaube diese I´s in EIMSK
// Initialisierung der Zeiten: // Der Kürze wegen hier nur für Kanal 0
Iz_diff0 = 0; // Differenz zwischen dem aktuellen und dem
// vorhergehenden Interrupt auf Kanal 0
Iz_xseci0 = 0; // Aktueller Zeitwert (Stand des 50µsec-Zählers)
// Lies die Variable mal so: Integer Zeit "X" (regelungstechnisch
// wird mit "X" der Ist-Wert bezeichnet sec => in Zeiteinheiten,
// aber eben nicht sec sondern 50 µsec, i => istwert 0 .. Kanal
Iz_xsecv0 = 0; // Vorhergehender Zeitwert auf Null initialisieren
}
/* ================================================== ============================ */
Damit meine Zeiteinheit = 50 µs-Zeitscheiben ausgewertet wird, gibts ne ISR, die diese 50µs-Zeitschnippsel hochzählt:

/* ================================================== ============================ */
/* === Nicht unterbrechbare ISR für timer2 ===================================== */
/* Routine zählt hoch im Takt 20 kHz = 50 µs.
==> Eine Zeiteinheit ist also 50 µs ! Der Zählerwert wird von den ISR für
EXT_INT0 und ~INT1 ausgelesen und den Werten Iz_yseci zugewiesen ...... */
ISR(TIMER2_COMPA_vect) // Vektor 7
{
if (Izeit_1 < 60000) //Timer bis 60 000 ==> 3 sec Datenerfassung möglich
Izeit_1 ++; // und Izeit_1 bleibt in der uint16-Grenze
else
{
Izeit_1 = 0; // ansonsten: Rückstellen auf Null
}
}
/* ================================================== ============================ */
Das Auslesen der Zeitdauer erfolgt in einer ISR die bei fallender Flanke am Pin (siehe Routine) ausgelöst wird:

/* ================================================== ============================ */
/* === Nicht unterbrechbare ISR für EXT_INT0 auf Pin 46/PD2/mega168 =========== */
/* Routine rechnet den Zeitbedarf vom vorhergehenden zum jetzigen Interrupt aus,
dieser Wert wird z.B. von der Regelung ausgelesen (nur dumm, wenn das erst nach
dem nächsten Interrupt passiert - das ist bei mir aber nicht der Fall! Nennt sich
Softwareengineering *ggggggg*
Der zugehörige Motor auf PD7/PB0 = re,li und PB1 Geschwind./PWM */
ISR(INT0_vect) // hiess mal: ISR(SIG_INTERRUPT0)
{ //
Iz_xseci0 = Izeit_1; //Weise Iz_xsec1 dem akt. Timerwert zu
Iz_diff0 = Iz_xseci0-Iz_xsecv0; //Neue Zeit-Differenz0 ausrechnen
Iz_xsecv0 = Iz_xseci0; //der aktuelle Zeitwert wird "Alter"
}
/* ================================================== ============================ */
So, das ist die ganze Sache. Wie bereits erwähnt, bei mir läufts - und die Coladose läuft mit zwei getrennten Motoren prächtig geradeaus. Achtung: es gibt sicher mehrere und auch bessere Möglichkeiten und verständlichere Variablen *gggg*.

Jetzt hoffe ich nur, dass ich nichts vergessen habe und nicht irgendeine Zeile entfernt habe, die für Deine Zwecke eher verwirrend wäre.

Viel Erfolg

Viel Glück.

BlackDevil
27.08.2008, 09:31
Okay Drehzahlmessung per Zeit schau ich mir mal näher an - ganz verstanden hab ichs noch nich aber das liegt an den Ferien und der Uhrzeit :D

Danke soweit - ich häng hier noch was an wenn ich noch fragen hab ;)


Die ColaDose läuft übrigens nicht zwingend wegen der Drehzahlmessung geradeaus :D

oberallgeier
27.08.2008, 10:26
... Die ColaDose läuft übrigens nicht zwingend wegen der Drehzahlmessung geradeaus ...Da hast Du natürlich völlig recht: die Genauigkeit der Drehzahlmessung hat allerdings erheblichen Einfluss auf die mögliche Genauigkeit der Regelung. Da ich zwei voneinander völlig getrennte Antriebe haben, ist der Geradeauslauf nur dann möglich, wenn die Vorgaben an die Antriebe genau befolgt werden - und da schließt sich der Kreis zur Drehzahlmessung *ggg*.


Okay Drehzahlmessung per Zeit ... ganz verstanden hab ichs noch nich ...Uuups - wieso? Wenn ich die Zeit für eine (halbe) Umdrehung des Motors habe, kann ich daraus die Drehzahl berechnen. Notfalls führe ich das noch aus.

BlackDevil
27.08.2008, 10:34
Mein Denkfehler hängt wohl die ganze zeit bei den Inkrementalscheiben
http://www.shop.robotikhardware.de/shop/catalog/images/GP1A038RBK.jpg

Die ich die ganze Zeit anders im Kopf hatte (mit zwei Verdrehten Strich scheiben drauf). Wenn ich natürlich eine Scheibe nehme die nur einen Strich drauf hat und ich weis wie lang der Strich brauch um wieder zu kommen, kann ich so die Drehzahl messen. Wobei mir da die Zeit eigentlich auch egal is, ich könnte jede 1 Zählen ^^

oberallgeier
27.08.2008, 10:54
Mein Denkfehler hängt wohl die ganze zeit bei den Inkrementalscheiben ... mit zwei Verdrehten Strich scheiben drauf ...... die sind ja (nur) für die Drehrichtungserkennung notwendig.


... Wenn ich natürlich eine Scheibe nehme die nur einen Strich drauf hat und ich weis wie lang der Strich brauch um wieder zu kommen, kann ich so die Drehzahl messen ...Fast richtig. Wenn Du viele Striche drauf hast und weisst wie viele das sind - und die sind gleich verteilt - dann kannst Du mit dieser "Übersetzung" natürlich in ähnlicher Weise die Drehzahl ausrechnen. Du musst eben die Zeit für eine Teilung mit der Anzahl der Teilungen multiplizieren, dann kannst Du daraus die aktuelle Geschwindigkeit zu der Zeit der Abstandsmessung errechnen. Ok?

BlackDevil
27.08.2008, 11:29
Ija klar, ich weis nur noch nich wieso ich die Zeit messe wenn ich doch auch einfach messen kann wie oft eine 1 vorbei kommt :-D Oder ist die Zeit (logisch eigentlich) in sofern Wichtig das ich gleich weis "Aha! 20x in einer Sekunde, das sind 120mal in der Minute!"?

Was völlig untern Tisch viel, ist die Frage ob ich mit dem USB Programmer ein Terminal Programm ansteuern kann und wie?
Soll sich um den http://www.ulrichradig.de/ Programmer handeln

Besserwessi
27.08.2008, 18:40
Bei so vielen Strichen kann man auch schon zählen, bei weniger Strichen wird aber die Auflösung beim Zählen relativ schlecht. Wenn man jeweils 1 s lang zählt krigt man bei den schätzten 100 Strichen eine Auflösung von 1/100 Umdrehungen je Sekunde oder rund 1 U/Min. das sollte normalerweise reichen.
Bei nur wenigen Strichen ist es halt besser die Zeit zwischen 2 Strichen zu messen.

Vom Terminalprogramm wird man einen ersten test machen können um z.B. die Software Version des Programmer auszulesen. Zum eigentlichen Programmieren braucht man eine Programm wie AVRDUDE oder eventuell Ponyprog. AVRDUDE ist schon im WinAvr Paket enthalten.

BlackDevil
27.08.2008, 20:00
Klar man brauch ein Programm, Hyperterminal fällt mir da spontan ein, fraglich is nur ob ich über den Programmer Kommunizieren kann und wie (Software/Hardware).

Das heist ich nehm so eine oder eine ähnliche Scheibe. Ich zähle über jede Sekunde wieviel Striche vergangen sind und rechne damit meine Umdrehung aus (Max/Ist) und freue mich?

Ich weis auch net - ich bin net dumm und im oberen drittel meines Jahrganges, aber bei sowas schmier ich hirnlich total ab Oo

oberallgeier
27.08.2008, 20:08
... Was völlig untern Tisch viel ... mit dem USB Programmer ein Terminal Programm ansteuern ...Ich kenne den genannten Programmer nicht, sage aber trotzdem: vermutlich nicht möglich. Denn ein Programmer spricht MISO, MOSI und SCK an - nicht aber TX und RX.

... Die gemessenen Drehzahlen und die verstrichene Zeit soll dann über den USB Logger auf den PC Übertragen werden, in das Terminal, und als Excel Datei speicherbar sein ...Das macht man hier im Forum relativ häufig, zum Beispiel hier (https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=386849#386849), meist über die RS232.


... aber bei sowas schmier ich hirnlich total ab ...Heee, langsam. Es sieht von "aussen" oft reichlich schwierig aus, wenn man es dann geschafft hat, wundert man sich ebenso oft, wie einfach es dann doch ist. Dazwischen liegt natürlich Arbeit.

BlackDevil
28.08.2008, 10:57
Hmm dann werd ich mich mal mit dem Radig kurzschliesen ob das nich doch geht. Diese hässliche USB RS232 Problematik, ich hab weder LPT noch RS232 an meinem Arbeits PC und mein großer ... da is kein Platz für solche Basteleien (ich hab auch keinen Platz für einen alten PC ..)

Gut ich grübel mla weiter ^^