Moin moin,
zuerst mal bin ich völliger Newbie in diesem Bereich und habe nicht
wirklich viel Erfahrung im Bereich programmieren und würde mich über
hilfreiche Beitrage die mich weiterbringen sehr freuen !
Ich möchte gerne über meinen Attiny13 2 Ausgangskarten(Pollin Bausatz)
über einen Eingang(Taster) steuern, mit Folgender Funktion:
Wenn die Schaltung Spannung bekommt, soll als erstes Ausgangskarte 1
einmal 5 Sekunden lang angesteuert werden. Wenn ich nun meinen Schalter
betätige, soll Ausgangskarte 2 5 Sekunden angesteuert werden. Wenn ich
nun meinen Schalter erneut betätige soll wiederum Ausgangskarte 1 5
Sekunden angesteuert werden. Dies soll immer im Wechsel so weiter gehen.
Wichtig ist, das die Steuerung beim Start immer mit der selben
Ausgangskarte anfängt.
Ist dies einfach und mit einem Attiny13 zu realisieren ? Kann mir jemand
bei dem Programm auf die Sprünge helfen ?
MFG Steve
Steffen Ebeling schrieb:> Kann mir jemand> bei dem Programm auf die Sprünge helfen ?
Starte hier:
https://www.mikrocontroller.net/articles/AVR
und mach dann mit dem AVR Tutorial weiter. Wenn du eine LED blinken
lassen kannst, bist du in der Lage Ausgangspins zu steuern. Weiterhin
brauchst du für dein Projekt eine Art Uhr, die beim AVR Timer genannt
wird. Und du musst Eingangspins lesen können.
Das ist erstmal die Grundlage. Feinheiten sind z.B. die Entprellung
deines Schalters und das Speichern seines Zustandes, damit du die
Bedingung deines Projekts erfüllst.
Steffen E. schrieb:> zuerst mal bin ich völliger Newbie in diesem Bereich
Dann ist der Ratschlag meines Vorschreibers sehr zu beherzigen. Nutze
die genannten Lernhilfen!
> Ist dies einfach und mit einem Attiny13 zu realisieren
Logo.
> Kann mir jemand> bei dem Programm auf die Sprünge helfen ?
Jetzt ist die erste Frage: Welche Programmiersprache?
Ich empfehle da Assembler, da Du den Controller und dessen Möglichkeiten
dann mit dem Tiny13 Datenblatt in der Hand gleich von grundauf
kennenlernst.
> Wichtig ist, das die Steuerung beim Start immer mit der selben> Ausgangskarte anfängt.
Das wird schon dadurch sichergestellt, daß Dein Programm immer von der
gleichen Stelle aus anfängt und Du dann eben Deine vorgesehene Karte
samt eines sogenannten Hardware-Timers aktivierst.
> einmal 5 Sekunden lang
Für sowas brauchst Du diesen Timer des Tiny13.
Der wird in Abhängigkeit von der Taktfrequenz des Controllers zum
Beispiel so eingestellt, daß er nach Aktivierung durch die Tasterabfrage
los- und bei 5 Sekunden "überläuft" und dabei was sinnvolles auslöst-
wie eben das Deaktivieren der aktuellen Karte.
Die Tasterabfrage aktiviert neben dem Timer natürlich auch die nächste,
richtige Karte. Du hast nur zwei, also kann man sich den aktuellen
Zustand in einer binären Variable merken (beim Controllerstart auf 0
gesetzt). Die wird bei Timerablauf einfach noch mit invertiert, damit
die Tasterabfrage beim nächsten Auslösen wieder die andere Karte
aktivieren kann.
So weit so einfach- der ganz grobe Ablauf.
Eine solche Taster-Anwendung enthält aber oft noch eine besondere
Herausforderung: Mechanische Taster prellen. Das heißt, sie können in
kürzester Zeit mehrfach auslösen. Mit Deinem gemächlichen Vorhaben hast
Du aber Glück: Das muß Dich nicht interessieren. Die Tasterabfrage tut
bei aktiviertem 5s-Timer einfach nix...
Hi
Moin moin,
zuerst mal bin ich völliger Newbie in diesem Bereich und habe nicht
wirklich viel Erfahrung im Bereich programmieren und würde mich über
hilfreiche Beitrage die mich weiterbringen sehr freuen !
Nun, so allgemein wie du dein Anliegen vorbringst, liest sich das wie:"
Ich brauch ein Programm, wer macht mir das". Das ist jetzt nicht bös
gemeint, aber es wird ein weiter Weg, bis du ein Programm selbst
schreiben kannst. Sicherlich hast du den bereits erwähnten Hinweis auf
die Tutorials gesehen. Die sind gut verständlich und für Übungen bestens
geeignet. So lernst du die Controller kennnen. Zur Sprache kann ich auch
noch auf einen Beitrag im Forum von WWW.AVR-Praxis.de unter der Rubrik
FAQ verweisen. Dort findest du u.A. im Beitrag "keine Angst vor
Assembler" sicherlich alle benötigten Bausteine für deinen
Programmwunsch ausführlich beschrieben.
Gruß oldmax
Moby schrieb:> Jetzt ist die erste Frage: Welche Programmiersprache?> Ich empfehle da Assembler, da Du den Controller und dessen Möglichkeiten> dann mit dem Tiny13 Datenblatt in der Hand gleich von grundauf> kennenlernst.
Kommt drauf an wie weit du einsteigen willst.
Assembler ist schon eine Hausnummer mit der du dich gewaltig
beschäftigen muss.
Schau mal nach "Arduino"!
Damit kannst du das nach zwei Tagen realisieren. Nimmst du jetzt noch
einen "Arduino Nano", kannst du ihn nach bestandenen Tests in eine
Schaltung auf Lochraster Platinen übernehmen. Wobei ich dir die
Lochstreifenraster empfehle.
Wenn du mit C programmieren willst, bietet sich auch der ATmega328 an
(der auf dem Nano ist), weil du z.B. dieses Programm dann locker auf
einen ATtiny10 ohne große Änderungen laufen lassen kannst.
http://www.ebay.de/itm/Nano-V3-0-ATmega328-16M-5V-Micro-controller-CH340G-board-for-arduino-/371179047627?pt=LH_DefaultDomain_77&hash=item566bfecacb
foldi, der TE möchte das alles gerne mit dem ATTiny13 realisieren, was,
wie wir uns schon einig waren, ohne jedes Problem möglich ist, sonst
hätte ich auch gleich protestiert.
Das geht in Assembler oder in C, bei einem so überschaubaren Projekt ist
ASM das simpelste und man lernt den MC richtig gut kennen.
Der Tiny10 ist schon wieder eine andere Liga, die TPI Programmierung
kann nicht jeder Programmer und man muss mit den Pins ganz schön
haushalten. Hier würde es gerade reichen...
Da wir nichts darüber wissen, was der TE für Tools hat, nehmen ich mal
an, das der Tiny13 gerade da ist und programmiert werden kann.
Ulrich F. schrieb:> OnTime ist, und bleibt, 5000.> Oder habe ich was übersehen?
Warum? Wird einmal auf 5000 initialisiert und wird dann decrementiert.
Erst bei erneutem drücken des Tasters wird die Variable wieder auf 5000
gesetzt. Stichwort static
Edit:
Ja sorry, das Decrement fehlt :(
Da ist es aber nicht egal, wie der Schalter beim Start steht.
Es soll ja in jedem Fall erst Karte 1 laufen, und beim Umschalten dann
Karte 2. Man sollte also den Startzustand des Schalters in einem Flag
speichern und den Schalter damit vergleichen. Wenn gleich, dann Karte 1,
bei Unterschied dann Karte 2.
Einen hab ich noch.
Ich hoff, ich hab mich da jetzt nicht vertan.
Wenn während der 5 Sekunden der Taster erneut betätigt wird, kann es
sein, dass beide Karten angesteuert werden.
Obwohl: der TO hat ja nicht verraten, was in diesem Fall die korrekte
Reaktion wäre.
Genauso wie er nicht verraten hat, ab wann die Zeit laufen soll. Ab
niederdrücken oder ab loslassen. Kann man durch gedrückt halten des
Tasters die 5 Sekunden verlängern oder nicht?
Moin,
vielen Dank erst mal für die vielen Kommentare ! :)
Matthias Sch. schrieb:> Starte hier:> https://www.mikrocontroller.net/articles/AVR> und mach dann mit dem AVR Tutorial weiter. Wenn du eine LED blinken> lassen kannst, bist du in der Lage Ausgangspins zu steuern. Weiterhin> brauchst du für dein Projekt eine Art Uhr, die beim AVR Timer genannt> wird. Und du musst Eingangspins lesen können.
Ja habe mich auch schon eine Weile mit den Ganzen Grundlagen beschäftig.
Da das alles für mich Neuland ist, finde ich das es sehr viele
Informationen auf einmal sind.
Ingo Less schrieb:> Ich hab da grad mal Bock drauf:#include <avr/io.h>> #include <avr/interrupt.h>>> #define KARTE1 PB0> #define KARTE2 PB1> #define TASTER PB2>> int main(void)> {> // Timer> TCCR0A |= (1<<WGM00) | (1<<WGM01); // CTC> OCR0A = 149; // 9,6MHz / ((149+1) * 64) = 1KHz> TIMSK0 |= (1<<OCIE0A); // Capture Interrupt> TCCR0B |= (1<<CS00) | (1<<CS01); // Prescaler 64>> // IOs> PORTB = 0;> DDRB |= (1<<KARTE1) | (1<<KARTE2);> PORTB |= (1<<TASTER); // Pull-up enable>> // global Interrupt enable> sei();>>> while(1){;> //Nothing to Do> }> }>> /* 1kHz */> ISR (TIM0_COMPA_vect)> {> static uint16_t debounce = 0;> static uint16_t OnTime = 5000;> static uint8_t Kartenwahl = 0;>> if (debounce) debounce--;>> if (!(PINB & (1<<TASTER)) && !debounce){> debounce = 100;> OnTime = 5000;> Kartenwahl++;> }>> if (OnTime){> switch (Kartenwahl%2){> case 0: PORTB |= (1<<KARTE1); break;> case 1: PORTB |= (1<<KARTE2); break;> default: break;> }else{> PORTB &= ~( (1<<KARTE2) | (1<<KARTE1) );> }> }
Vielen dank! Könntest du eventuell die einzelnen Programmzeilen mal ein
wenig erklären, was mit welchen Befehlen genau gemacht wird und wie nun
mein gewünschter Ablauf entsteht ? Ich kann aus dem Programm nämlich
nicht genau die Zusammenhänge untereinander deuten. Ich würde das
Programm gerne verstehen wollen.
MFG
Karl Heinz schrieb:> Wenn während der 5 Sekunden der Taster erneut betätigt wird, kann es> sein, dass beide Karten angesteuert werden.>> Obwohl: der TO hat ja nicht verraten, was in diesem Fall die korrekte> Reaktion wäre.> Genauso wie er nicht verraten hat, ab wann die Zeit laufen soll. Ab> niederdrücken oder ab loslassen. Kann man durch gedrückt halten des> Tasters die 5 Sekunden verlängern oder nicht?
Das Ansteuern beider Karten gleichzeitig, würde in meinem fall keinen
Fehler und Fehlfunktion in meiner Schaltung hervorrufen.
Beim Auslösen des Schalters wäre eine steigende Flanke besser.
MFG
Hi
Steffen E. schrieb:> Beim Auslösen des Schalters wäre eine steigende Flanke besser.
In der Regel ist ein Eingang mit einem internen Pullup Widerstand
verschaltet. Das bedeutet für deine Schaltung, wenn du keinen externen
PullDown verwenden willst, das dein Schalter/ Taster genau anders herum
schaltet. Also, eine steigende Flanke bekommst du dann beim Loslassen.
Gruß oldmax
Steffen E. schrieb:> Vielen dank! Könntest du eventuell die einzelnen Programmzeilen mal ein> wenig erklären,
Das würde bedeuten, das Tutorial hier genau noch einmal hinzuschreiben.
> mein gewünschter Ablauf entsteht ? Ich kann aus dem Programm nämlich> nicht genau die Zusammenhänge untereinander deuten. Ich würde das> Programm gerne verstehen wollen.
Dann bleibt dir nichts anderes übrig als die Dinge zu lernen. Hier wird
dir keiner eine 12 Seiten Abhandlung schreiben, die alles im Detail
erläutert.
Arbeite das Tutorial durch, mach Übungen zu den einzelnen Themenkreisen.
Das ist der Weg, wie man Dinge lernt.
Schriftsteller zu werden lernt man auch nicht dadurch, dass einem ein
anderer Schriftsteller seinen Roman Wort für Wort auseinanderklaubt.
Ganz wichtig ist: Das Tutorial nur zu lesen ist zu wenig. Das ist wie
beim Radfahren. Du kannst hunderte Bücher über radfahren lesen. Solange
du dich nicht selbst in den Sattel setzt, wirst du dich nicht auf dem
Rad halten können.
Soviel kann man aber sagen:
zentrales Element ist ein Timer, der durch seine Einstellung einen
regelmässigen Basistakt (und damit eine definierte Zeitreferenz)
erzeugt. In genau diesem Takt wird die ISR aufgerufen. Der Rest ist dann
nur noch: Wenn ich 5 Sekunden benötige, und eine 'Uhr' zur Verfügung
habe, die mir jede zb Zehntelsekunde einen Beep gibt, dann muss ich 50
Beeps abzählen, bis 5 Sekunden beisammen sind. Die ISR ist so
eingestellt, dass sie jede 1 Millisekunde feuert, also muss ich 5000
derartige 'Feuerungen' abzählen (entweder von 0 bis 5000, oder von 5000
runter bis 0) um eine Zeit von 5 Sekunden abzumessen.
zusätzlich zum Tutorial:
FAQ: Timer
Aber Timer ist schon etwas für fortgeschrittene Anfänger, auch wenn kaum
ein Programm ohne sie auskommt. Mit einem Timer umgehen muss man können,
weil sie praktisch überall vorkommen. Nur ist das (noch) kein Thema,
wenn man bei 0 einsteigt. Da müssen zuerst andere Dinge verstanden
worden sein.
Karl Heinz schrieb:> Wenn während der 5 Sekunden der Taster erneut betätigt wird, kann es> sein, dass beide Karten angesteuert werden.
Ja das stimmt, das kann man ja aber abfangen wenn man will indem man
einfach die Tasterabfrage blockiert so lange noch eine Karte aktiv is.
Hi
Karl Heinz schrieb:> Dann bleibt dir nichts anderes übrig als die Dinge zu lernen. Hier wird> dir keiner eine 12 Seiten Abhandlung schreiben, die alles im Detail> erläutert.
Doch Karl Heinz. Im von mir angesprochenem Beitrag der AVR-Praxis
Gemeinde hab ich das mal gemacht. Nur lesen muss das jeder, der sich
dafür interessiert, schon selber. Und jetzt noch mal einzelne Auszüge
davon mundgerecht zu präsentieren, dazu hab ich natürlich keine Lust.
Gruß oldmax
oldmax schrieb:>> Dann bleibt dir nichts anderes übrig als die Dinge zu lernen. Hier wird>> dir keiner eine 12 Seiten Abhandlung schreiben, die alles im Detail>> erläutert.oldmax schrieb:> Doch Karl Heinz. Im von mir angesprochenem Beitrag der AVR-Praxis> Gemeinde hab ich das mal gemacht.
Ich glaube Karl-Heinz meint, dass sich jetzt niemand hinsetzt und mein
kleines Programm beschreibt!
Ich hätte natürlich jede Zeile kommentieren können, aber da war ich zu
faul zu...
Ingo Less schrieb:> Ich hätte natürlich jede Zeile kommentieren können, aber da war ich zu> faul zu...
Das ist auch nicht sinnvoll.
Denn Dinge wie
* Wie wird ein Bit gesetzt
* Wie wird es gelöscht"
* Wie fragt man einen Eingang ab
die müssen einfach im Schlaf sitzen, ehe man überhaupt daran denken
kann, ein Real-World Programm zu schreiben.
Damit ist aber noch lange nicht die Logik, die Idee die im Programm
steckt, beschrieben. Die Idee hab ich versucht kurz zu skizzieren. Damit
und mit ein wenig spielen mit Papier und Bleistift und verfolgen wie
sich die einzelnen Werte ändern, sollte es eigentlich möglich sein, zu
verfolgen wie sich daraus die gewünschte Funktionalität ergibt. Rein
durch hinsehen wird ein Anfänger die einzelnen Bestandteile und welche
Idee sie verkörpern nicht identifizieren, das ist mir schon klar. Aber
der beste Weg ist immer noch, sich da durchzu'quälen', auch wenn das
jetzt hart klingt. Hilft aber nichts, da musste jeder mal durch. Und mit
der Zeit wird man ja auch besser, weil man Dinge, bestimmte Konstrukte,
wiedererkennt.
Ist wie beim Schachspielen. Die Regeln sind schnell erklärt, aber in
einem realen Schachspiel steckt mehr als nur die Anwendung der Regeln.
Als Anfänger kannst du einem Hr. Pfleger stundenlang zu hören, du wirst
trotzdem nicht verstehen wovon er da redet, bzw. wie er darauf kommt.
Erst nach einiger Spielpraxis erschliesst sich vieles davon.
Karl Heinz schrieb:> Das ist auch nicht sinnvoll.
Macht meiner Meinung hier auch keinen Sinn, da das Programm genau das
verkörpert, was er wollte. Somit hat er seine Programmbeschreibung
selber geschrieben. Nur das "Wo passiert was" muss er sich halt selber
raus suchen. Ich denke aber, dass ist bei den paar Zeilen kein Ding der
Unmöglichkeit.
case0:PORTB|=(1<<KARTE1);break;// Wenn Kartenwahl 0 ist dann Portausgang für Karte1 setzen
53
case1:PORTB|=(1<<KARTE2);break;// Wenn Kartenwahl 1 ist dann Portausgang für Karte2 setzen
54
default:break;// Breakanweiseung auch hier bitte die switch Grundlagen lesen
55
}else{// Falls weder 0 noch 1 ist dann Portausgänge der beiden Karten auf 0 setzen
56
PORTB&=~((1<<KARTE2)|(1<<KARTE1));
57
}
58
}
Viel Spass damit // auch von mir
Ich schliesse mich meinen Vorschreibern an, bitte die Grundlagen
durchackern. Hier gab es ja schon viele Links
Gruß Greg
Greg schrieb:> debounce = 100;// Variable debounce auf 100 stellen
Ganau diese Art von Kommentar hilft garnicht.
Hier hätte es heißen müssen "Entprellzeit 100ms".
Moin Leute,
das Programm läuft wie es oben geschrieben wurde nicht wirklich.
Ausgangskarte 1 läuft immer dauerhaft und Ausgangskarte 2 geht an wenn
man den Taster drückt und wenn man Ihn 5 Sekunden hält und wieder los
lässt, geht Ausgangskarte 2 wieder aus aber auch nur dann.
Steffen E. schrieb:> Moin Leute,> das Programm läuft wie es oben geschrieben wurde nicht wirklich.
Welche Version?
Hast du auch die nachträglichen Änderungen noch eingepflegt?
Zum Rest:
Eigentlich ist das Programm so einfach, dass man auch einem Anfänger
zumuten kann zu analysieren, wie das ganze arbeitet.
Dreh und Angelpunkt ist die Erkentnis, dass die ISR-Funktion jede 1
Millisekunde aufgerufen wird. Das funktioniert also wie ein Wecker, der
alle x Zeiteinheiten läutet. Der Benutzer wacht auf, sieht sich um,
entscheidet was er zu tun hat (anhand seiner Umgebung) und macht die
entsprechenden Aktionen.
Mit dieser Vorgabe, einem Blatt Papier und Bleistift sollte es
eigentlich nicht mehr schwer sein, die Funktionalität nachvollziehen zu
können, bzw. zu ergründen, warum etwas nicht funktioniert.
Ingo Less schrieb:> Greg schrieb:>> debounce = 100;// Variable debounce auf 100 stellen> Ganau diese Art von Kommentar hilft garnicht.> Hier hätte es heißen müssen "Entprellzeit 100ms".
Und um das klar zu stellen: Das ist nur ein willkürlich
herausgegriffenes Beispiel für sinnlose Kommentierung.
Der Rest der Kommentierung (die nicht von Ingo stammen) ist vom genau
gleichen Kaliber: sinnlos
Sorry Greg. Aber du hast dir eine Menge Arbeit für nichts gemacht.
Steffen E. schrieb:> das Programm läuft wie es oben geschrieben wurde nicht wirklich.> Ausgangskarte 1 läuft immer dauerhaft und Ausgangskarte 2 geht an wenn> man den Taster drückt und wenn man Ihn 5 Sekunden hält und wieder los> lässt, geht Ausgangskarte 2 wieder aus aber auch nur dann.
Wie hast du deinen Taster angebunden? Wenn du alle Nachträge ins
Programm eingepflegt hast, dann sollte es funktionieren. Sofern der
Taster richtig angeschlossen ist.
Aber wie K.-H. schon schrieb. Das Programm ist überschaubar einfach. Es
soll dich ja auch dazu ermuntern es zu verstehen. Copy&Paste
funktioniert meist eh nicht auf Anhieb.
Da ich hier einen Internen Pull-up Widerstand benutze, ist von PB2 auf
den Taster und von dort auf 0V angeschlossen.
ich habe das Decrement noch eingefügt, bin mir aber auch nicht sicher ob
das an der richtigen Stelle war. Sonst habe ich nichts mehr eingepflegt.
Hast du eigentlich an den Fuses des AtTiny rumgemacht?
Denn wenn du da nichts getan hast, dann stimmt die Zeitberechnung im
Programm nicht. Der Timer ist so eingerichtet, dass die Zeiten bei
9.6Mhz Taktfrequenz stimmen. Hast du an den Fuses nichts gemacht, dann
läuft der Tiny aber nicht mit 9.6Mhz sondern mit 1.2Mhz.
Also Folge davon sind alle Zeiten real dann 8 mal so lang. Aus deinen 5
Sekunden werden ca. 40 Sekunden. Und die können laaaang sein, wenn man
vor einem Gerät sitzt und darauf wartet, dass etwas passiert.
Ich hätte hier
1
switch(Kartenwahl%2){
2
case0:PORTB|=(1<<KARTE1);
3
PORTB&=~(1<<KARTE2);
4
break;
5
6
case1:PORTB|=(1<<KARTE2);
7
PORTB&=~(1<<KARTE1);
8
break;
9
10
default:break;
11
}
ja dafür gesorgt, dass die Ausgänge mit Sicherheit immer wechselseitig
geschaltet sind.
Karl Heinz schrieb:> ja dafür gesorgt, dass die Ausgänge mit Sicherheit immer wechselseitig> geschaltet sind.
Ja, auch sinnvoll... Das kommt davon wenn man solch ein Progrämmchen mit
heißer Nadel schreibt. :)
Karl Heinz schrieb:> Hast du an den Fuses nichts gemacht, dann> läuft der Tiny aber nicht mit 9.6Mhz sondern mit 1.2Mhz.
Wenn es nur um die CKDIV8-Fuse geht, bevor das im Übereifer fehlschlägt:
Thomas Eckmann schrieb:> Wenn es nur um die CKDIV8-Fuse geht, bevor das im Übereifer fehlschlägt:> #include <avr/power.h>>> int main(void)> {> clock_prescale_set(clock_div_1);> .> .> .>> mfg.
Ich habe das noch nie verwendet. Wie genau ist das?
F. Fo schrieb:> Ich habe das noch nie verwendet. Wie genau ist das?
100%.
Damit stellt man den Clock Prescaler ein. Mit dieser Funktion lässt sich
der Takt auf 1, 1/2, 1/4 und 1/8 einstellen. Unabhängig von der
Fuse-Voreinstellung.
Das ist alles auch nichts Neues und setzt lediglich ein paar Bits im
CLKPR. Dieses Register muss aber in einer Timed Sequence beschrieben
werden, ähnlich dem Watchdog. Das Timing nimmt einem die Funktion ab.
Die berühmt-berüchtigte Fuse macht lediglich die Startvorgabe auf 1/8
oder 1. Also nicht "festverdrahtet" wie die Einstellung der Taktquelle.
mfg.