Microcontroller-Programmierung
Re: Microcontroller-Programmierung
Das löst dein Problem nicht, aber PIN13 hat eine Sonderfunktion: Dort ist neben einer LED auf der Platine noch ein passender Vorwiderstand dabei, der auf PIN12 fehlt.
Hast du LEDs mit eingebautem Vorwiderstand, oder einen passenden in deiner Schaltung ?
Neben dem Quellcode wäre eine genauer Schaltplan nützlich um dir zu helfen..
Auf die Entprellung wollte ich auch hinweisen, aber die sollte hier noch keine Rolle spielen, da du den Taster lange (länger als der Taster prellen kann) gedrückt hältst, und nach ein paar ms ein HIGH-Pegel am InputPIN anliegt.
Hast du LEDs mit eingebautem Vorwiderstand, oder einen passenden in deiner Schaltung ?
Neben dem Quellcode wäre eine genauer Schaltplan nützlich um dir zu helfen..
Auf die Entprellung wollte ich auch hinweisen, aber die sollte hier noch keine Rolle spielen, da du den Taster lange (länger als der Taster prellen kann) gedrückt hältst, und nach ein paar ms ein HIGH-Pegel am InputPIN anliegt.
- cloidnerux
- Moderator
- Beiträge: 3123
- Registriert: Fr Sep 26, 2008 4:37 pm
- Wohnort: Ram (Gibts wirklich)
Re: Microcontroller-Programmierung
Erstmal ist der Source-Code falsch, zumindest das was du hier gepostet hast:
Du überprüfst in beiden ifs die Variable buttenState4, der andere Taster wird nicht berücksichtigt.
Wenn du wild reagierende Schaltungen hast, ist das ein Zeichen von falsch Angeschlossenen CMOS-Eingängen. Die Eingangschaltung der µC ist sehr empfindlich auf kleine Ladungen, wenn du mit deinen Finger oder anders auch geringe Ladungen oder Ströme einbringst, kann alles mögliche Passieren.
Kontrolliere bitte deine Schaltung, ob dein Taster korrekt Angeschlossen ist:
Der Pin muss mit einem Widerstand(~10k Ohm) gegen Masse(-, GND) gezogen werden, damit der Pin immer auf deinem Definierten Pegel liegt.
Dann wird der Schalter mit der einen Seite gegen Vcc(+5V) geschaltet und mit der anderen gegen den Pin, das wird hier etwas besser gezeigt:
http://www.mikrocontroller.net/articles ... d_Schalter
Die LEDs müssen immer mit einem Vorwiderstand betrieben werden, da sonst zu viel Strom aus den Ausgängen des AVRs fließen. Die können nur maximal 20mA ohne Zerstört zu werden.
Der Widerstand sollte so zwischen 100 und 1k Ohm liegen, zum "nur" leuchten recht unkritisch, nur zu klein darf es nicht sein.
Ganz wichtig wenn du mit sowas Arbeitest: Du musst immer in einem definierten Zustand/Ablauf arbeiten. Wenn irgendwas irgendwie passiert, dann kann man nicht verstehen, wo der Fehler liegt.
Wenn du dir nicht sicher bist, ob deine Hardware funktioniert, dann teste sie.
Schreib ein Programm wo du nur LED1 jede Sekunde an und Aus schaltest(delay), dann LED2, dann testest du ob Schalter 1 und dann ob Schalter 2 funktioniert.
Wenn du dir nicht sicher sein kannst, dass deine Hardware funktioniert, wirst du auch keine Softwarefehler finden.
Code: Alles auswählen
if(buttonState4 == HIGH) {
digitalWrite(ledPin12, HIGH);
}
else {
digitalWrite(ledPin12, LOW);
}
if(buttonState4 == HIGH) {
digitalWrite(ledPin13, HIGH);
}
else {
digitalWrite(ledPin12, LOW);
}
Wenn du wild reagierende Schaltungen hast, ist das ein Zeichen von falsch Angeschlossenen CMOS-Eingängen. Die Eingangschaltung der µC ist sehr empfindlich auf kleine Ladungen, wenn du mit deinen Finger oder anders auch geringe Ladungen oder Ströme einbringst, kann alles mögliche Passieren.
Kontrolliere bitte deine Schaltung, ob dein Taster korrekt Angeschlossen ist:
Der Pin muss mit einem Widerstand(~10k Ohm) gegen Masse(-, GND) gezogen werden, damit der Pin immer auf deinem Definierten Pegel liegt.
Dann wird der Schalter mit der einen Seite gegen Vcc(+5V) geschaltet und mit der anderen gegen den Pin, das wird hier etwas besser gezeigt:
http://www.mikrocontroller.net/articles ... d_Schalter
Die LEDs müssen immer mit einem Vorwiderstand betrieben werden, da sonst zu viel Strom aus den Ausgängen des AVRs fließen. Die können nur maximal 20mA ohne Zerstört zu werden.
Der Widerstand sollte so zwischen 100 und 1k Ohm liegen, zum "nur" leuchten recht unkritisch, nur zu klein darf es nicht sein.
Ganz wichtig wenn du mit sowas Arbeitest: Du musst immer in einem definierten Zustand/Ablauf arbeiten. Wenn irgendwas irgendwie passiert, dann kann man nicht verstehen, wo der Fehler liegt.
Wenn du dir nicht sicher bist, ob deine Hardware funktioniert, dann teste sie.
Schreib ein Programm wo du nur LED1 jede Sekunde an und Aus schaltest(delay), dann LED2, dann testest du ob Schalter 1 und dann ob Schalter 2 funktioniert.
Wenn du dir nicht sicher sein kannst, dass deine Hardware funktioniert, wirst du auch keine Softwarefehler finden.
Redundanz macht wiederholen unnötig.
quod erat expectandum
quod erat expectandum
Re: Microcontroller-Programmierung
Danke für die Tipps.
Habe jetzt die Widerstände an den LEDs hinzugefügt (die an den Tastern hatte ich schon) und den Fehler im Code ausgebessert, jetzt funktioniert alles.
Die Ausgänge scheinen zum Glück nichts abbekommen zu haben.
Habe jetzt die Widerstände an den LEDs hinzugefügt (die an den Tastern hatte ich schon) und den Fehler im Code ausgebessert, jetzt funktioniert alles.
Die Ausgänge scheinen zum Glück nichts abbekommen zu haben.
Re: Microcontroller-Programmierung
Hi,
melde mich auch mal wieder.
Hatte wieder etwas Lust und Zeit mit meinem Arduino zu programmieren.
Allerdings hat es urplötzlich das Übertragen verweigert und zeigt seitdem immer folgende Fehlermeldung an: averdude: stk500_getsync(): not in sync: resp=0x00
Ich hatte eigentlich nur 2 Minuten vorher noch ein Programm erfolgreich überspielt und wollte nur einen Eingang nachträglich Umändern, habe aber ansonsten nicht umgesteckt, oder sonstiges gemacht
Board und Serieller Port sind richtig eingestellt, Programmer steht auf AVRISP mkll (ist der richtig? War zmd. auch vorher so...), habe Resetbutton auf dem Board schon getestet, die Arduino-Software neu installiert.
LED's und Taster haben die benötigten Widerstände, da es eines von Sainsmart ist, habe ich es auf 3,3V statt 5V laufen (also dürfte ja nichts durchgebrannt sein).
Hier nochmal das Programm, das hatte aber vorher mit "const int LED1 = 13;" noch problemlos funktioniert:
Habt ihr vielleicht einen Tipp, woran es noch liegen könnte?
melde mich auch mal wieder.
Hatte wieder etwas Lust und Zeit mit meinem Arduino zu programmieren.
Allerdings hat es urplötzlich das Übertragen verweigert und zeigt seitdem immer folgende Fehlermeldung an: averdude: stk500_getsync(): not in sync: resp=0x00
Ich hatte eigentlich nur 2 Minuten vorher noch ein Programm erfolgreich überspielt und wollte nur einen Eingang nachträglich Umändern, habe aber ansonsten nicht umgesteckt, oder sonstiges gemacht
Board und Serieller Port sind richtig eingestellt, Programmer steht auf AVRISP mkll (ist der richtig? War zmd. auch vorher so...), habe Resetbutton auf dem Board schon getestet, die Arduino-Software neu installiert.
LED's und Taster haben die benötigten Widerstände, da es eines von Sainsmart ist, habe ich es auf 3,3V statt 5V laufen (also dürfte ja nichts durchgebrannt sein).
Hier nochmal das Programm, das hatte aber vorher mit "const int LED1 = 13;" noch problemlos funktioniert:
Code: Alles auswählen
const int S1 = 2;
const int S2 = 0;
const int LED1 = 12;
const int LED2 = 10;
int S1State = 0;
int S2State = 0;
void setup(){
pinMode(S1, INPUT);
pinMode(S2, INPUT);
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
}
void loop() {
S1State = digitalRead(S1);
S2State = digitalRead(S2);
if (S1State == HIGH) {
digitalWrite(LED1, HIGH);
}
else {
digitalWrite(LED1, LOW);
}
if (S2State == HIGH) {
digitalWrite(LED2, HIGH);
}
else {
digitalWrite(LED2, LOW);
}
}
- cloidnerux
- Moderator
- Beiträge: 3123
- Registriert: Fr Sep 26, 2008 4:37 pm
- Wohnort: Ram (Gibts wirklich)
Re: Microcontroller-Programmierung
Ich hatte das immer, wenn der Treiber des USB-Seriel Wandler nicht richtig funktionierte.Allerdings hat es urplötzlich das Übertragen verweigert und zeigt seitdem immer folgende Fehlermeldung an: averdude: stk500_getsync(): not in sync: resp=0x00
Auf dem Arduino sitzt ein Schnittstellenbaustein, der auf der einen Seite eine USB-Verbindung hat, auf der anderen Seite einen UART. Wenn dieser Baustein nicht richtig angesprochen wird, dann funktioniert das nicht.
Versuch mal den Arduino aus zu stecken und wieder anstecken.
Vlt auch an einem anderen USB Port.
Redundanz macht wiederholen unnötig.
quod erat expectandum
quod erat expectandum
Re: Microcontroller-Programmierung
Um- und Ausstecken habe ich gleich am Anfang versucht, hat nicht wirklich geholfen...
Im Internet gibt es rund 300 Themen zu dieser Fehlermeldung mit geschätzt 150 Lösungsvarianten, die für den jeweiligen Einzelfall dann scheinbar auch geklappt haben.
Nach etlichen Versuchen habe ich die Lösung für meinen Fall gefunden: Beim Übertragen eines neuen Programms darf Pin 0 nicht angesteuert werden! Also ausgestöpselt, sicherheitshalber beim Programm noch einen anderen Pin festgelegt, aufgespielt und siehe da = alles funktioniert
Trotzdem danke für die Hilfe.
Im Internet gibt es rund 300 Themen zu dieser Fehlermeldung mit geschätzt 150 Lösungsvarianten, die für den jeweiligen Einzelfall dann scheinbar auch geklappt haben.
Nach etlichen Versuchen habe ich die Lösung für meinen Fall gefunden: Beim Übertragen eines neuen Programms darf Pin 0 nicht angesteuert werden! Also ausgestöpselt, sicherheitshalber beim Programm noch einen anderen Pin festgelegt, aufgespielt und siehe da = alles funktioniert
Trotzdem danke für die Hilfe.
Re: Microcontroller-Programmierung: Probleme delay()
Ich update mal das Thema. Falls Ich doch lieber ein neues aufmachen sollte, sagt bescheid.
Möchte einen Automaten basteln, bei dem nach Einwurf von Geld (buttonPin12) LED's in einer bestimmten Abfolge blinken.
Wenn allerdings nichts eingeworfen wird, soll nach einem gewissen Zeitraum (in diesem Fall 15min.) trotzdem ein paar Lichter kurz aufleuchten, um Aufmerksamkeit auf sich zu ziehen.
Allerdings sieht es aktuell so aus, dass "delay" das Programm für diesen Zeitraum pausiert und if dementsprechend nicht ausgeführt werden kann.
Wie muss ich es schreiben, um bei Einwurf von Geld jederzeit if ausführen kann, also else abgebrochen wird?
Habe schonmal nach millis() als Alternative geschaut, nur funktioniert das zumindest bei mir nicht richtig....
Danke schonmal für die Hilfe
Code: Alles auswählen
const int ledPin1 = 1;
const int ledPin2 = 2;
const int ledPin3 = 3;
const int ledPin4 = 4;
const int ledPin5 = 5;
const int ledPin6 = 6;
const int ledPin7 = 7;
const int ledPin8 = 8;
const int ledPin9 = 9;
const int ledPin10 = 10;
const int ledPin11 = 11;
const int buttonPin12 = 12;
int buttonState12 = LOW;
void setup () {
pinMode (ledPin1, OUTPUT);
pinMode (ledPin2, OUTPUT);
pinMode (ledPin3, OUTPUT);
pinMode (ledPin4, OUTPUT);
pinMode (ledPin5, OUTPUT);
pinMode (ledPin6, OUTPUT);
pinMode (ledPin7, OUTPUT);
pinMode (ledPin8, OUTPUT);
pinMode (ledPin9, OUTPUT);
pinMode (ledPin10, OUTPUT);
pinMode (ledPin11, OUTPUT);
pinMode (buttonPin12, INPUT);
}
void loop () {
buttonState12 = digitalRead (buttonPin12);
if (buttonState12 == HIGH) {
digitalWrite (ledPin1, HIGH);
digitalWrite (ledPin2, HIGH);
digitalWrite (ledPin3, HIGH);
digitalWrite (ledPin4, HIGH);
digitalWrite (ledPin5, HIGH);
delay (150);
digitalWrite (ledPin6, HIGH);
delay (300);
digitalWrite (ledPin7, HIGH);
digitalWrite (ledPin6, LOW);
delay (300);
digitalWrite (ledPin8, HIGH);
digitalWrite (ledPin7, LOW);
delay (300);
digitalWrite (ledPin9, HIGH);
digitalWrite (ledPin8, LOW);
delay (300);
digitalWrite (ledPin10, HIGH);
digitalWrite (ledPin9, LOW);
delay (300);
digitalWrite (ledPin11, HIGH);
digitalWrite (ledPin10, LOW);
delay (300);
digitalWrite (ledPin11, LOW);
delay (150);
digitalWrite (ledPin1, LOW);
digitalWrite (ledPin2, LOW);
digitalWrite (ledPin3, LOW);
digitalWrite (ledPin4, LOW);
digitalWrite (ledPin5, LOW);
delay (150);
digitalWrite (ledPin11, HIGH);
delay (300);
digitalWrite(ledPin10, HIGH);
delay (300);
digitalWrite (ledPin9, HIGH);
delay (300);
digitalWrite(ledPin8, HIGH);
delay (300);
digitalWrite (ledPin7, HIGH);
delay (300);
digitalWrite (ledPin6, HIGH);
delay (300);
digitalWrite (ledPin5, HIGH);
digitalWrite (ledPin4, HIGH);
digitalWrite (ledPin3, HIGH);
digitalWrite (ledPin2, HIGH);
digitalWrite (ledPin1, HIGH);
delay (1000);
digitalWrite (ledPin1, LOW);
digitalWrite (ledPin2, LOW);
digitalWrite (ledPin3, LOW);
digitalWrite (ledPin4, LOW);
digitalWrite (ledPin5, LOW);
digitalWrite (ledPin6, LOW);
digitalWrite (ledPin7, LOW);
digitalWrite (ledPin8, LOW);
digitalWrite (ledPin9, LOW);
digitalWrite (ledPin10, LOW);
digitalWrite (ledPin11, LOW);
}
else {
digitalWrite (ledPin1, LOW);
digitalWrite (ledPin2, LOW);
digitalWrite (ledPin3, LOW);
digitalWrite (ledPin4, LOW);
digitalWrite (ledPin5, LOW);
digitalWrite (ledPin6, LOW);
digitalWrite (ledPin7, LOW);
digitalWrite (ledPin8, LOW);
digitalWrite (ledPin9, LOW);
digitalWrite (ledPin10, LOW);
digitalWrite (ledPin11, LOW);
delay (900000);
digitalWrite (ledPin6, HIGH);
digitalWrite (ledPin7, HIGH);
digitalWrite (ledPin8, HIGH);
digitalWrite (ledPin9, HIGH);
digitalWrite (ledPin10, HIGH);
digitalWrite (ledPin11, HIGH);
delay (1000);
}
}
Wenn allerdings nichts eingeworfen wird, soll nach einem gewissen Zeitraum (in diesem Fall 15min.) trotzdem ein paar Lichter kurz aufleuchten, um Aufmerksamkeit auf sich zu ziehen.
Allerdings sieht es aktuell so aus, dass "delay" das Programm für diesen Zeitraum pausiert und if dementsprechend nicht ausgeführt werden kann.
Wie muss ich es schreiben, um bei Einwurf von Geld jederzeit if ausführen kann, also else abgebrochen wird?
Habe schonmal nach millis() als Alternative geschaut, nur funktioniert das zumindest bei mir nicht richtig....
Danke schonmal für die Hilfe
- cloidnerux
- Moderator
- Beiträge: 3123
- Registriert: Fr Sep 26, 2008 4:37 pm
- Wohnort: Ram (Gibts wirklich)
Re: Microcontroller-Programmierung
Exakt. Delay ist eine "Dumme" Funktion, sie wartet die angegebene Zeit und beendet sich dann.Allerdings sieht es aktuell so aus, dass "delay" das Programm für diesen Zeitraum pausiert und if dementsprechend nicht ausgeführt werden kann.
Was du brauchst ist ein timer interrupt.
Ein Interrupt ist eine Routine, die der Prozessor unabhängig vom momentanen Programm aufruft(damit alles andere blockiert), wenn ein bestimmte Bedingung erfüllt ist, z.B wenn eine steigende Flanke detektiert worden ist, wenn ein neues Byte auf dem UART Emfpangen wurde oder wenn ein Timer übergelaufen ist.
Das mit dem Timer ist was du willst.
Du hast 3 Timer. Jeder Timer hat einen Prescaler, der angibt, nach wie vielen Takten der Zähler eins hochgezählt wird sowie dieverse Modi wann und wie ein Interrupt ausgelöst wird.
Wenn du den 16-Bit Timer 1 verwendest, den Prescaler richtig setzt, den Modus CTC wählst damit du die Überlaufgrenze einstellen kannst, dann kannst du einen Timer alle 1/10s oder jede Sekunde auslösen um einen Variable hoch zu zählen.
Damit hast du einen Zähler, wie viel zeit vergangen ist. Wenn du also 15s warten willst, setzt du den Zähler auf 0 und wartest bis er 15 wird.
Deine Statemachine kannst du als solche implementieren.
Du definierst eine Variable, die deinen aktuellen Zustand beinhaltet sowie Variablen, die deine Zustände kennzeichnen:
Code: Alles auswählen
#define STATE_IDLE 0
#define STATE_COIN_INSERT 1
[...]
#define STATE_ERROR 100
int state = STATE_IDLE;
Code: Alles auswählen
switch(state)
{
case STATE_IDLE:
if(SOME_CONDITION)
{
state = STATE_COIN_INSERT;
break;
}
break;
Edit:
Hier ist das Datenblatt zu dem Atmega328, ab Seite 112 beginnt das Kapitel üben den Timer 1.
Die Register wie sie im Datenblatt genannt sind kannst du direkt nutzen:
Code: Alles auswählen
TCCR1B = (1 << WGM13) | (1 << WGM12);
Redundanz macht wiederholen unnötig.
quod erat expectandum
quod erat expectandum
Re: Microcontroller-Programmierung
Danke für die Antwort!
Bin gerade am einlesen und hab schon ein bisschen was in den Code eingefügt. Funktioniert zwar nocht nicht ganz wie gewünscht, scheint aber das zu sein, was ich benötige.
Bin gerade am einlesen und hab schon ein bisschen was in den Code eingefügt. Funktioniert zwar nocht nicht ganz wie gewünscht, scheint aber das zu sein, was ich benötige.