Microcontroller-Programmierung

Präsentation und Organisation von eigenen Projekten
Onraku
Beiträge: 43
Registriert: Fr Sep 09, 2011 2:14 pm

Re: Microcontroller-Programmierung

Beitrag von Onraku » So Jan 12, 2014 12:30 am

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.

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3123
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Microcontroller-Programmierung

Beitrag von cloidnerux » So Jan 12, 2014 12:12 pm

Erstmal ist der Source-Code falsch, zumindest das was du hier gepostet hast:

Code: Alles auswählen

  if(buttonState4 == HIGH) {
  digitalWrite(ledPin12, HIGH);
  }
  else {
    digitalWrite(ledPin12, LOW);
  }
  if(buttonState4 == HIGH) {
    digitalWrite(ledPin13, HIGH);
  }
  else {
    digitalWrite(ledPin12, LOW);
  }
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.
Redundanz macht wiederholen unnötig.
quod erat expectandum

Hallou
Beiträge: 25
Registriert: Mi Jan 09, 2013 3:20 pm

Re: Microcontroller-Programmierung

Beitrag von Hallou » So Jan 12, 2014 2:42 pm

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.

Hallou
Beiträge: 25
Registriert: Mi Jan 09, 2013 3:20 pm

Re: Microcontroller-Programmierung

Beitrag von Hallou » Di Apr 15, 2014 3:11 pm

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:

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);
  }
}
Habt ihr vielleicht einen Tipp, woran es noch liegen könnte?

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3123
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Microcontroller-Programmierung

Beitrag von cloidnerux » Di Apr 15, 2014 3:48 pm

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 das immer, wenn der Treiber des USB-Seriel Wandler nicht richtig funktionierte.
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

Hallou
Beiträge: 25
Registriert: Mi Jan 09, 2013 3:20 pm

Re: Microcontroller-Programmierung

Beitrag von Hallou » Di Apr 15, 2014 5:44 pm

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 :D

Trotzdem danke für die Hilfe.

Hallou
Beiträge: 25
Registriert: Mi Jan 09, 2013 3:20 pm

Re: Microcontroller-Programmierung: Probleme delay()

Beitrag von Hallou » Do Sep 11, 2014 1:48 pm

Ich update mal das Thema. Falls Ich doch lieber ein neues aufmachen sollte, sagt bescheid.

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);
  }
}
    
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

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3123
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Microcontroller-Programmierung

Beitrag von cloidnerux » Do Sep 11, 2014 3:33 pm

Allerdings sieht es aktuell so aus, dass "delay" das Programm für diesen Zeitraum pausiert und if dementsprechend nicht ausgeführt werden kann.
Exakt. Delay ist eine "Dumme" Funktion, sie wartet die angegebene Zeit und beendet sich dann.
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;
Und dann im Loop hast du ein switch:

Code: Alles auswählen

switch(state)
{
    case STATE_IDLE:
        if(SOME_CONDITION)
        {
            state = STATE_COIN_INSERT;
            break;
        }
         break;
Damit kannst du deine Statemachine so implementieren, wie du eine Entsprechende FSM zeichnen würdest. Jeder Zustand hat eine Nummer und jeder Übergang kann als if realisiert werden.

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);
http://www.atmel.com/images/Atmel-8271- ... mplete.pdf
Redundanz macht wiederholen unnötig.
quod erat expectandum

Hallou
Beiträge: 25
Registriert: Mi Jan 09, 2013 3:20 pm

Re: Microcontroller-Programmierung

Beitrag von Hallou » Mo Sep 15, 2014 9:03 am

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.

Antworten