Problem mit LEDs (ATmega168)

Hallo,

ich habe ein für mich absolut unverständliches Problem.

Habe eine Ampelschaltung auf 2 unterschiedliche Weisen programmiert. Zum einen direkt mit:

int rotPin =12;

void setup() {
pinMode(rotPin, OUTPUT);
}

void loop()
{
digitalWrite (rotPin, HIGH);
}

hier nur stark vereinfacht, das Ergebnis ist einwandfrei LED leuchtet schön hell (Widerstände und alles nach Plan verbaut)

Hier nun mein Problem: Ich habe das gleiche Programm mit identischer Schaltung objektorientiert nachgebaut (Habe eine klasse LED erstellt. etc.)
Programm funktioniert auch. LEDs werden auch angesteuert, allerdings ist die Leuchtleistung der LEDs jetzt so schwach das man nur noch im Dunkeln erkennen kann das sie überhaupt leuchten.
Woran kann denn das liegen????? Die Befehle sind wie gesagt die gleichen.
Bin für jede Hilfe echt dankbar, da ich absolut keine Erklärung für das Phänomen habe.

liebe Grüße

ominum

Hallo,

hab das Problem nun eingegrenzt. Wenn ich in meinem *.cpp file den Ausgang direkt angebe ist die led stärker,
wenn ich allerdings über den arduino compiler ein Objekt der Klasse led erzeuge und diesem danach erst einen ausgang zuweise ist die led schwächer(kaum noch zu sehen).
Bleibt immer noch die Frage woran liegt das?
Da mein Projekt voraussetzt das ich Klassen und Objekte verwende bleibt mir auch keine andere Wahl als es so zu machen.
Gibt es denn noch ander Möglichkeiten als LOW und HIGH um die LEDs zum leuchten zu bringen?

vg

Ominum

Ich tippe auf die Einschaltdauer des LEDs. Hast Du ein Oszilloskop und kannst den LED-Ausgang mal kontrollieren?
Schick mal den gesamten Code.
Grüße Uwe

Hallo,
Oszilloskop hab ich leider nicht.
Die Einschaltdauer hab ich mal auf 20 sekunden gelassen, hat aber nichts gebracht.

Hier der Code:

VERSUCH.h
#ifndef VERSUCH_h
#define VERSUCH_h

#include "WProgram.h"

class VERSUCH {
public:

byte VERSUCH_PIN;
VERSUCH();
~VERSUCH();
void on();
void off();
void blink(int time);
void Led_Nummer(byte test);
};

#endif

Die Datei Versuch.cpp

#include <VERSUCH.h> //include the declaration for this class

byte VERSUCH_PIN;

//Konstruktor
VERSUCH::VERSUCH(){
pinMode(VERSUCH_PIN, OUTPUT); //Gewünschte LED als OUTPUT definieren
}

//<>
VERSUCH::~VERSUCH(){}

//LED anschalten
void VERSUCH::on(){
digitalWrite(VERSUCH_PIN,HIGH); //Setzt den PIN auf HIGH und schaltet LED an
}

//turn the LED off
void VERSUCH::off(){
digitalWrite(VERSUCH_PIN,LOW); //setzt den PIN auf LOW und schaltet LED ab
}

//Blinken
void VERSUCH::blink(int time){
on(); //LED an
delay(time/2); //wartet
off(); //LED aus
delay(time/2); //wartet
}
void VERSUCH::Led_Nummer(byte test){

VERSUCH_PIN = test;
}

Und hier das Programm für den Arduino:

#include <VERSUCH.h>

VERSUCH led;//initialize an instance of the class

void setup(){
Serial.begin(9600);

}
void loop(){

led.Led_Nummer(11);

led.on();

delay(20000);
//Serial.println(VERSUCH_PIN);

}

viele Grüße
Ominum

Hallo,

ich habe jetzt mit einem Multimeter mal die Spannung gemessen.
Bei Version 1 habe ich 1,9 Volt.
Bei Version 2 dann 1,7 Volt.

Kann aber immer noch nicht nachvollziehen wie das passieren kann.
Bin für jede Hilfe echt dankbar.

vg
Ominum

Mein C++ ist etwas eingerostet, aber hat bei

VERSUCH::VERSUCH(){
    pinMode(VERSUCH_PIN, OUTPUT); //Gewünschte LED als OUTPUT definieren
}

VERSUCH_PIN nicht den Wert 0, weil er noch nicht explizit gesetzt wurde? Je nach Aufbau deiner Schaltung könnte ein HIGH auf Pin 0 vielleicht stören.

Hallo ominum,

ich habe zwar fast alles über C++ vergessen, aber die Deklaration von "byte VERSUCH_PIN" am Anfang der Datei "versuch.cpp" kommt mir etwas ungewöhnlich vor. Kann natürlich auch an meinen mangelhaften C++-Kenntnissen liegen.

Könnte es sein, dass dadurch die Member-Variable "VERSUCH_PIN" in der Klasse (in versuch.h) überdeckt wird und daher im Ablauf des Programms je nach Kontext auf unterschiedliche "VERSUCH_PIN"s zugegriffen wird?

Vielleicht kann ja einer der hier sicherlich vorhandenen C++-Experten etwas dazu sagen oder du probierst es selbst mal aus...

Gruß
Wolfgang

"pinMode(VERSUCH_PIN, OUTPUT);" setzt Pin 0, da im Konstruktor VERSUCH_PIN noch nichts zugewiesen wurde und somit 0 ist.
Der anschließende Aufruf von "led.Led_Nummer(11);" bewirkt gar nichts.

Lösung:
Verpasse dem Konstruktor einen Parameter.

//Konstruktor
VERSUCH::VERSUCH(byte test){
    VERSUCH_PIN = test;
    pinMode(VERSUCH_PIN, OUTPUT); //Gewünschte LED als OUTPUT definieren
}

Die Funktion "void Led_Nummer(byte test);" wird dann nicht mehr gebraucht und die Variable VERSUCH_PIN kannst Du dir dann eigentlich auch sparen.

Die globale Variable VERSUCH_PIN und die Klassenvariable VERSUCH_PIN sind zwei paar Schuhe.
Beri einem Zugriff auf VERSUCH_PIN wird innerhalb einer Klassenfunktion die Klassenvariable und ausserhalb der Klasse die globale Variable angesprochen.
Solche Konstruktionen sollte man tunlichst vermeiden, da sind Programmfehler schon vorprogrammiert ]:smiley:

Hi,

erstmal vielen Dank, jetzt funktionierts. Wenn ich dem Konstruktor gleich nen Parameter verpasse wie MaFu geschrieben hat gehts einwandfrei.
Muss aber trotzdem nochmal widersprechen, dass der Aufruf von led.Led_Nummer(11) nichts bewirkt.
Ich kann nämlich sehen das er was bewirkt, nur eben das er weniger bewirkt.

Also vielen Dank nochmal, habt mir echt den Tag gerettet.

lg
Ominum

ominum:
Muss aber trotzdem nochmal widersprechen, dass der Aufruf von led.Led_Nummer(11) nichts bewirkt.
Ich kann nämlich sehen das er was bewirkt, nur eben das er weniger bewirkt.

Der Pin wird nur im Konstruktor auf OUTPUT gesetzt. Wenn Du jetzt über "led.Led_Nummer(11)" die Pinnummer änderst, so wird natürlich bei "on()" bzw. "off()" der Pin 11 auf HIGH bzw. LOW gesetzt. Da dieser Pin aber nie auf OUTPUT gesetzt wurde, ist es ein Input-Pin. Und somit bewirkt HIGH nur, dass der interne PullUp aktiviert wird. Und bei LOW wird der PullUp wieder ausgeschaltet. Das kann durchaus bewirken (man möge mich korrigieren wenn ich falsch liege), dass die LED minimal glimmt.
Wenn Du den Ausgang im laufenden Betrieb ändern willst, dann mach es so:

void VERSUCH::Led_Nummer(byte test){
                      VERSUCH_PIN = test;
                      pinMode(VERSUCH_PIN, OUTPUT);
}

MaFu:
Da dieser Pin aber nie auf OUTPUT gesetzt wurde, ist es ein Input-Pin. Und somit bewirkt HIGH nur, dass der interne PullUp aktiviert wird. Und bei LOW wird der PullUp wieder ausgeschaltet. Das kann durchaus bewirken (man möge mich korrigieren wenn ich falsch liege), dass die LED minimal glimmt.

Damit dürftest Du meiner Meinung nach genau richtig liegen, der interne 20k Pullup wird reichen um die LED minimal leuchten zu lassen.