PWM defekt ? bei Wert < 255 kommt 0V an

Hallo,

ich bräuchte mal einen Rat bzgl. meines PWM Signals, ich habe eine Schaltung erweitert, in der bereits eine LED verbaut war und die mit dem PWM Wert 100 angesteuert (PIN 3) war und auch geleuchtet hat.

Nach der Erweiterung ging die LED nicht mehr an; nach langer Suche hab ich den Wert von 100 auf 255 gesetzt und sie geht wieder; auf 254 nicht.

Ich habe jetzt mal nachgemessen und gesehen, dass sobald ich einen Wert von kleiner als 255 als PWM benutze ich 0V habe und bei 255 sind es 5V.

Habe auch schon das selbe mich PIN 9 probiert, auch dieser lässt sich nicht regeln.

Lade ich ein anderes Programm drauf, eines das nur die LED ansteuern soll, dann geht alles wie gewohnt; also muss es an meiner Software liegen, allerdings fällt mir da nichts ungewöhnliches auf.

Hat mir irgendjemand einen Tip ?

DaniChloe: Lade ich ein anderes Programm drauf, eines das nur die LED ansteuern soll, dann geht alles wie gewohnt; also muss es an meiner Software liegen, allerdings fällt mir da nichts ungewöhnliches auf.

Das ist doch die Essenz aus deinem Beitrag: Kein Hardwareschaden, sondern ein Softwareproblem. Dir fällt nichts Ungewöhnliches auf, den geschulten Augen der werten Mitleserschaft hingegen vielleicht. Da sollte doch die erste Idee sein, den Code mal zu zeigen, oder? :)

also muss es an meiner Software liegen, allerdings fällt mir da nichts ungewöhnliches auf.

Mir auch nicht!

Wir könnten ein Quiz veranstalten: Schreibe einen Sketch, der sich so verhält wie DaniChloe schreibt.

Was gibt es als Preis zu gewinnen, DaniChloe?
Deine Wahl: wer kommt deinem “Fehler” am nächsten oder welches Beispiel findest du am schönsten ?

Mein erster Beitrag:

void setup() { pinMode(9, OUTPUT); }
void loop() {
   static byte x;
   digitalWrite(9, x ++ == 00);
   delay(100);
}

Ungetestet
Das sollte etwa alle halbe Minute eine LED an Pin 9 kurz aufblitzen lassen.

combie: Mir auch nicht!

Wieso sollte mir dann etwas auffallen?

@DaniChloe Mein Tip: Laß mal den Sketch sehen.

Grüße Uwe

michael_x:
Ungetestet
Das sollte etwa alle halbe Minute eine LED an Pin 9 kurz aufblitzen lassen.

Thema verfehlt, hier gehts ja um analogWrite(); :slight_smile:

Thema verfehlt, hier gehts ja um analogWrite();

Sollte! Nur leider ist weit und breit kein analogWrite() zu sehen....

sth77: Thema verfehlt, hier gehts ja um analogWrite(); :)

Das hat meine Glaskugel, die recht kreativ ist, was mögliche Fehler angeht, gemeint: Vielleich hat er gar kein analogWrite verwendet. Aber ein Beispiel mit analogWrite, das einen merklichen Unterschied zwischen 254 und 255 macht, wäre auch hübsch, nur zu!

In meinem Beispiel kann man natürlich die 00 durch 255 oder 254 oder manches andere ersetzen, was in jedem Fall das gleiche Verhalten produziert, aber 00 fand ich in dem Zusammenhang netter.

Na wenigstens hast du meinen Grinsesmilie mitzitiert, soll ja heißen, dass die Botschaft nicht ganz ernst gemeint ist.

Hallo DaniChloe, wie Du sicher bereits bemerkt hast, ist dieses Forum ein aktives, deren Mitglieder neben aller Ernsthaftigkeit auch zu feiner Ironie fähig sind. Sie warten nun ungeduldig, nicht nur Deiner LED sondern auch Dir ein Licht aufgehen zu lassen!

haha ok ich kann verstehen, dass meine art zu fragen ohne einen code einzubinden für Belustigung sorgt.

es gibt allerdings auch einen Grund, dass ich das nicht getan habe, denn er ist sehr sehr lange:)

ich denke ich bin es euch schuldig :stuck_out_tongue: hier ist mein code, bitte findet den Fehler :slight_smile: danke

#include <Servo.h>   //servo bibliothek
Servo servomotor;     //deklaration servomotor

#include <IRremote.h>

int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;

//############################ SCHRITT ################################
int schritt = 0;

//############################# DEFINITIONEN SENSOREN ###########################################

//####SENSOR AN DER SEITE HINTEN########

int triggerSH=7;        // trigger auf Pin 7 (SH = auf der rechten Seite; Hinten)
int echoSH=6;            //echo auf Pin 6
long dauerSH=0;
long entfernungSH=0;
int SensorSV = 9; // Versorgt SensorSV

//###################### ANTRIEB ##################################
int Antrieb = 3;
//############################### METHODE ANTRIEB ###################################

void MotorVor(){
delay (50);
Serial.println("Motor lauft vorwarts");
analogWrite(Antrieb, 255);
delay (50);
}

//####SENSOR AN DER SEITE VORNE########
int dauerSV = 0;
long entfernungSV = 0;
int triggerSV = 2;
int echoSV = 5;
int SensorSH = 10;

//##################################### METHODEN LENKEN ################################
//####### MOTOR RECHTS ###########

void servomotorgradzahl_rechts (int entfernungSH, int sollabstand, int gradzahl, int bereichsgrenze){
if (entfernungSH > sollabstand && entfernungSH < bereichsgrenze){
servomotor.write (gradzahl);
delay(500);
}
}

//####### MOTOR LINKS ############

void servomotorgradzahl_links (int entfernungSH, int entfernungSV, int gradzahl){

if ((entfernungSV < 80 && entfernungSH < 140) && (entfernungSV/entfernungSH) < 0.7){
servomotor.write (gradzahl);
delay(500); 
} 
}

//######## MOTOR GERADE##########
void servomotor_gerade (int entfernungSH , int entfernungSV, int gradzahl){

if (((entfernungSV/entfernungSH) < 1.15 && (entfernungSV/entfernungSH) > 0.85) && entfernungSV < 90){
servomotor.write (gradzahl);
delay(200); 
} 
}

//########################################### METHODEN SENSOREN ##############################################

//####SENSOR AN DER SEITE HINTEN####
int ultraschallsensorSH (int trigger, int echo){

digitalWrite(trigger, LOW);     // Spannung zu LOW, damit man beim senden des Trigger-Signals ein rauschfreies Signal hat.

delay(5);                       //5ms Verzögerung, dann startet trigger für 5ms.
digitalWrite(trigger, HIGH);
delay(5);
digitalWrite(trigger, LOW);
dauerSH = pulseIn(echo, HIGH);     //Zeit wird "gestoppt
entfernungSH = ((dauerSH/2) / 29.1) * 10; //Zeit durch 2 teilen, wegen Hin- und Rueckweg, dann teilen durch
                                     // 29.1 us/cm und zum Schluss mal 10 damit man von cm auf mm kommt 
Serial.print(entfernungSH);
Serial.println(" mm Sensor an der Seite Hinten");
return entfernungSH;
delay(500);
 }

//###### SENSOR AN DER SEITE VORNE ##########
int ultraschallsensorSV (int trigger, int echo){
digitalWrite(trigger, LOW);     // Spannung zu LOW, damit man beim senden des Trigger-Signals ein rauschfreies Signal hat.
delay(5);                       //5ms Verzögerung, dann startet trigger für 5ms.
digitalWrite(trigger, HIGH);
delay(5);
digitalWrite(trigger, LOW);
dauerSV = pulseIn(echo, HIGH);     //Zeit wird "gestoppt

entfernungSV = ((dauerSV/2) / 29.1) * 10; //Zeit durch 2 teilen, wegen Hin- und Rueckweg, dann teilen durch
                                     // 29.1 us/cm und zum Schluss mal 10 damit man von cm auf mm kommt 

Serial.print(entfernungSV);
Serial.println(" mm Sensor an der Seite Vorne");
return entfernungSV;
delay(500);
 }


//########################### METHODE EIN/AUSSCHALTEN #####################################

void ein_aus_schalten (){
if (irrecv.decode(&results)) {

Serial.print(results.value, DEC);
Serial.println (" Wert der Fernbedientung");

if (schritt == 0){
if (results.value == 2534850111) // Wert der Taste 2 auf der Fernbedienung 1033561079 ---> ausgelesen mit Serieller Monitor
{
 Serial.println ("Wagen gestartet");
schritt = 1;
}
}

//################################### DIESER TEIL IST FÜR DAS AUSSCHALTEN ########################################
if (schritt >= 1){

if (results.value == 1033561079){  // Wert der Taste 2 auf der Fernbedienung 1033561079 ---> ausgelesen mit Serieller Monitor

Serial.println ("Wagen gestoppt"); 
 schritt = 0;
} }
irrecv.resume(); //damit der nächste Wert empfangen wird
}
}

//################################################################################################################################


void setup(){
//####################### SENSOREN SPANNUNG EIN UND AUSGÄNGE #############################
pinMode(SensorSV, OUTPUT);
analogWrite(SensorSV, 255);  //Spannungsversorgung SensorSV
pinMode(SensorSH, OUTPUT);
analogWrite(SensorSH, 255);
pinMode(triggerSH, OUTPUT);
pinMode(echoSH, INPUT);
pinMode(triggerSV, OUTPUT);
pinMode(echoSV, INPUT);


//################## Infrarot Sensor ##########################

irrecv.enableIRIn();

//###############################################################

pinMode(Antrieb, OUTPUT);
Serial.begin (9600);
servomotor.attach(8);   //ansteuerung auf pin 8
}

void loop()
{
ein_aus_schalten ();

Serial.print(schritt);
Serial.println(" schritt");

while (schritt == 1){

ein_aus_schalten ();

ultraschallsensorSH (triggerSH, echoSH);
ultraschallsensorSV (triggerSV, echoSV);

MotorVor();

servomotorgradzahl_rechts (entfernungSH,120,120,400);       //ist ein Bereich von 130mm frei (aber kleiner als 400mm, wegen methode), servomotor auf 120°

servomotorgradzahl_links (entfernungSH, entfernungSV, 60);  
servomotor_gerade (entfernungSH, entfernungSV, 90);
 
if (((entfernungSV/entfernungSH) < 1.15 && (entfernungSV/entfernungSH) > 0.85) && entfernungSV < 90)
{
schritt = schritt + 1;
}
delay (50);    
}


while (schritt == 2) {

ein_aus_schalten ();

ultraschallsensorSH (triggerSH, echoSH);
ultraschallsensorSV (triggerSV, echoSV);

delay (200);

analogWrite(Antrieb, 255);
delay (200);
analogWrite(Antrieb, 0);
delay (100);
analogWrite(Antrieb, 255);
delay (200);
analogWrite(Antrieb, 0);
delay (100);
servomotor.write(90);
delay (400);

if (entfernungSH > 300){
delay (3000);
servomotor.write (60);
delay (3000);
servomotor.write (110);
delay (400);
// Jetzt rückwärts

schritt = schritt + 1; 
}

}}

ich sollte eventuell noch hinzufügen, dass int antrieb = 3; in meinem code für die LED steht; falls ihr euch fragt warum, ich hab noch keinen motor und simuliere ihn durch die LED :)

Bitte setze Deinen Sketch in code-Tags, links oben der Button </>.

ich sollte eventuell noch hinzufügen, dass int antrieb = 3; in meinem code für die LED steht

Das hab ich mir allerdings gedacht.
Unklar ist mir nur, was das servo-gedöns, die Ultraschall-Sensoren und die Fernbedienung mit deinem Problem zu tun hat.
Was passiert, wenn du das einfach weg lässt ?

Und wenn du das ganze einigermassen lesbar formatierst und in Code tags </> packst ?

servomotor.attach(8); // das ist halb so schlimm

Das folgende ist allerdings eine Zumutung, reparieren hilft evtl. auch dir beim Verständnis:

}

}}

Ok hab es in code tags gepackt; also als letztes habe ich die Bibliothek (IRremote.h) für die Infrarotdiode und das Programm zum auslesen der Infrarotdiode eingebunden und seit dem geht PWM nicht mehr, das Programm macht so weit was es soll. Kann es vielleicht sein, dass das einbinden der IRremote bibliothek mir die probleme verschafft hat ? denn um PWM mit dem Arduino anzuwenden braucht man ja zwar keine library aber vielleicht hat es ja irgendeinen einfluss auf das “system” das die PWM steuert. ist halt echt komisch das bei dem PWM wert von 254; 0V anliegen :frowning:

#include <IRremote.h>


#include <Servo.h>   //servo bibliothek
Servo servomotor;     //deklaration servomotor


int RECV_PIN = 11;

IRrecv irrecv(RECV_PIN);

decode_results results;

//############################ SCHRITT ################################

int schritt = 0;

//############################# DEFINITIONEN SENSOREN ###########################################


//####SENSOR AN DER SEITE HINTEN########

int triggerSH=7;        // trigger auf Pin 7 (SH = auf der rechten Seite; Hinten)
int echoSH=6;            //echo auf Pin 6
long dauerSH=0;
 
long entfernungSH=0;
int SensorSV = 9; // Versorgt SensorSV



//###################### ANTRIEB ##################################


int Antrieb = 3;

//############################### METHODE ANTRIEB ###################################

void MotorVor(){

 delay (10);
 Serial.println("Motor lauft vorwarts");
 analogWrite(Antrieb, 255);
delay (50);

}
//############################# METHODE ANTRIEB AUS ###############################

void MotorAus(){

delay(10);
Serial.println("Motor aus");
analogWrite(Antrieb, 0);
delay(10);


  
}






//####SENSOR AN DER SEITE VORNE########
 

int dauerSV = 0;
long entfernungSV = 0;

int triggerSV = 2;
int echoSV = 5;
int SensorSH = 10;

 
 //##################################### METHODEN LENKEN ################################
 




//####### MOTOR RECHTS ###########


 void servomotorgradzahl_rechts (int entfernungSH, int sollabstand, int gradzahl, int bereichsgrenze){

if (entfernungSH > sollabstand && entfernungSH < bereichsgrenze){

servomotor.write (gradzahl);

delay(300);

}

 }




//####### MOTOR LINKS ############

void servomotorgradzahl_links (int entfernungSH, int entfernungSV, int gradzahl){

if ((entfernungSV < 80 && entfernungSH < 140) && (entfernungSV/entfernungSH) < 0.7){

servomotor.write (gradzahl);

delay(300);

  
}





  
}


//######## MOTOR GERADE##########


void servomotor_gerade (int entfernungSH , int entfernungSV, int gradzahl){

if (((entfernungSV/entfernungSH) < 1.15 && (entfernungSV/entfernungSH) > 0.85) && entfernungSV < 90){



servomotor.write (gradzahl);



delay(200);
  
}



  
}

 //########################################### METHODEN SENSOREN ##############################################


//####SENSOR AN DER SEITE HINTEN####


int ultraschallsensorSH (int trigger, int echo){

digitalWrite(trigger, LOW);     // Spannung zu LOW, damit man beim senden des Trigger-Signals ein rauschfreies Signal hat.
 
delay(5);                       //5ms Verzögerung, dann startet trigger für 5ms.
digitalWrite(trigger, HIGH);
delay(5);
digitalWrite(trigger, LOW);
dauerSH = pulseIn(echo, HIGH);     //Zeit wird "gestoppt

entfernungSH = ((dauerSH/2) / 29.1) * 10; //Zeit durch 2 teilen, wegen Hin- und Rueckweg, dann teilen durch
                                      // 29.1 us/cm und zum Schluss mal 10 damit man von cm auf mm kommt 

 

Serial.print(entfernungSH);
Serial.println(" mm Sensor an der Seite Hinten");


return entfernungSH;

delay(500);

  }


//###### SENSOR AN DER SEITE VORNE ##########








int ultraschallsensorSV (int trigger, int echo){

digitalWrite(trigger, LOW);     // Spannung zu LOW, damit man beim senden des Trigger-Signals ein rauschfreies Signal hat.
 
delay(5);                       //5ms Verzögerung, dann startet trigger für 5ms.
digitalWrite(trigger, HIGH);
delay(5);
digitalWrite(trigger, LOW);
dauerSV = pulseIn(echo, HIGH);     //Zeit wird "gestoppt

entfernungSV = ((dauerSV/2) / 29.1) * 10; //Zeit durch 2 teilen, wegen Hin- und Rueckweg, dann teilen durch
                                      // 29.1 us/cm und zum Schluss mal 10 damit man von cm auf mm kommt 

 

Serial.print(entfernungSV);
Serial.println(" mm Sensor an der Seite Vorne");

return entfernungSV;


delay(500);

  }


//########################### METHODE EIN/AUSSCHALTEN #####################################

void ein_aus_schalten (){
if (irrecv.decode(&results)) {

Serial.print(results.value, DEC);
Serial.println (" Wert der Fernbedientung");



if (schritt == 0){

if (results.value == 2534850111) // Wert der Taste 2 auf der Fernbedienung 1033561079 ---> ausgelesen mit Serieller Monitor
{

  Serial.println ("Wagen gestartet");
 schritt = 1;


}
}

//################################### DIESER TEIL IST FÜR DAS AUSSCHALTEN ########################################






if (schritt >= 1){

if (results.value == 1033561079){  // Wert der Taste 2 auf der Fernbedienung 1033561079 ---> ausgelesen mit Serieller Monitor


Serial.println ("Wagen gestoppt");
  
  schritt = 0;
  
  
  

} }


irrecv.resume(); //damit der nächste Wert empfangen wird

}


}






//################################################################################################################################

 
void setup(){

//####################### SENSOREN SPANNUNG EIN UND AUSGÄNGE #############################
pinMode(SensorSV, OUTPUT);

  analogWrite(SensorSV, 255);  //Spannungsversorgung SensorSV

pinMode(SensorSH, OUTPUT);

analogWrite(SensorSH, 255);

pinMode(triggerSH, OUTPUT);

pinMode(echoSH, INPUT);


pinMode(triggerSV, OUTPUT);

pinMode(echoSV, INPUT);


//################## Infrarot Sensor ##########################

irrecv.enableIRIn();


//###############################################################

pinMode(Antrieb, OUTPUT);





Serial.begin (9600);



servomotor.attach(8);   //ansteuerung auf pin 8


 }



 
void loop(){




MotorAus();

ein_aus_schalten ();

Serial.print(schritt);
Serial.println(" schritt");



while (schritt == 1){


ein_aus_schalten ();

ultraschallsensorSH (triggerSH, echoSH);

ultraschallsensorSV (triggerSV, echoSV);

MotorVor();
 

servomotorgradzahl_rechts (entfernungSH,120,120,400);       //ist ein Bereich von 130mm frei (aber kleiner als 400mm, wegen methode), servomotor auf 120°
  


servomotorgradzahl_links (entfernungSH, entfernungSV, 60);  

  

servomotor_gerade (entfernungSH, entfernungSV, 90);
  
if (((entfernungSV/entfernungSH) < 1.15 && (entfernungSV/entfernungSH) > 0.85) && entfernungSV < 90){

schritt = schritt + 1;

}


 delay (50);   
  
  
}


while (schritt == 2) {

ein_aus_schalten ();

ultraschallsensorSH (triggerSH, echoSH);

ultraschallsensorSV (triggerSV, echoSV);


delay (200);



analogWrite(Antrieb, 255);
delay (200);
analogWrite(Antrieb, 0);
delay (100);
analogWrite(Antrieb, 255);
delay (200);
analogWrite(Antrieb, 0);
delay (100);

servomotor.write(90);

delay (400);

if (entfernungSH > 300){



delay (3000);

servomotor.write (60);

delay (3000);

servomotor.write (110);

delay (400);
// Jetzt rückwärts

schritt = schritt + 1;




  
}

}}

Soweit ich das richtig gesehen habe nutzt die IRRemote-Library auf Boards mit einem Atmega328 den Timer 2. Das ist zufällig auch der Timer, der für PWM-Pin 3 verantwortlich ist. Dise Überschneidung könnte durchaus der Knackpunkt sein. Also einfach mal einen anderen PWM-Pin nehmen, jedoch nicht die 11.

@sth77 danke das werde ich gleich mal ausprobieren:)

@sth77 hab es mit PIN 10 probiert, leider ohne erfolg.

aber habe gerade gelesen, dass es möglich sein muss einen anderen Timer zu verwenden und dann das problem eventuell behoben ist, man soll in der library IRremoteInt.h den Timer TA1XX zu TA0XX umschreiben, aber leider finde ich dort diesen Eintrag nicht zum ändern.

Zum Zusammenhang zwischen PWM und IRremote ist Ken Shirriff's blog sehr lehrreich.

At the low level, enableIROut sets up the timer for PWM output on pin 3 at the proper frequency.

Brauchst du die IR Sende - Richtung ?

@michael_x

danke, ich schau mir die Seite gleich mal an;

ich bräuchte eigentlich nur die empfangsrichtung der ir Diode, was für ein unterschied macht das ?

gruß dani