Zeitproblem?

Hallo, habe folgende Frage: Habe ein Programm, das gleichzeitig einen Motor steuert und die Lufttemperaur misst ( SHT 75 ). Die Lichtschranke überwacht den Motor. Also wenn kein Signal von der Lichtschranke kommt, bleibt der Motor stehen und eine rote LED angeht. Funktioniert auch so weit. Wenn ich allerdings ein paar Serial.print Anweisungen in Programm einfüge. Funktionirt es nicht mehr, also der Motor dreht sich weiter, wenn die Lichtschranke nicht dran ist. Kann das sein, dass die Anweisungen Serial.print zu viel Zeit in Anspruch nehmen?

Normal nicht, ich denke eher, der restliche Code ist nicht so das wahre.

Sketch bitte!

User_ino: Kann das sein, dass die Anweisungen Serial.print zu viel Zeit in Anspruch nehmen?

Wenn du aus vollen Rohren aufs Terminal-Programm feuerst, dann kann das schon sein. Also nicht permanent per Serial Daten schreiben. Aber wie sschultewolter bereits sagte, ein Blick auf den Sketch ist meist aufschlussreicher als das Glaskugelsehen... :D

und vielleicht die Baudrate von 9600 auf zumindest 57600 hochsetzen.

sth77:

User_ino: Kann das sein, dass die Anweisungen Serial.print zu viel Zeit in Anspruch nehmen?

. Aber wie sschultewolter bereits sagte, ein Blick auf den Sketch ist meist aufschlussreicher als das Glaskugelsehen... :D

oder dem lesen des eigenen oder fremden Kaffeesatzes. ;) ;) Grüeß Uwe

User_ino: Kann das sein, dass die Anweisungen Serial.print zu viel Zeit in Anspruch nehmen?

Ja, wenn Du den seriellen Sendepuffer vollaufen läßt.

Der serielle Sendepuffer kann maximal 63 Zeichen aufnehmen. Weitere Zeichen werden danach erst dann gesendet, wenn der Sendepuffer so viele Zeichen weggesendet hast, wie Du neu in den Puffer reinschieben möchtest.

Beispiel: Du schiebst 63 Zeichen in den Sendepuffer und machst ihn damit voll: Serial.print("123456789012345678901234567890123456789012345678901234567890123"; Das dauert "praktisch kaum nennenswert Zeit". Die Zeichen werden im Hintergrund aus dem Puffer weggesendet.

Aber wenn Du den Puffer vollmachst und gleich 20 Zeichen hinterherschieben möchtest: Serial.print("123456789012345678901234567890123456789012345678901234567890123"; Serial.print("12345678901234567890";

Dann dauert die Abarbeitung der zweiten Zeile so lange, wie das Senden der Zeichen tatsächlich dauert. Das Programm ist währenddessen blockiert.

Bei 9600 Baud (960 Zeichen pro Sekunde) für ca, 20 Millisekunden pro 20 Zeichen.

Wenn Du über Serial senden möchtest, ohne das Programm zu blockieren, müßtest Du darauf achten, immer nur so viele Zeichen pro Zeit an Serial zu senden, dass der Sendepuffer nicht überläuft.

Also im Zweifelsfall Serial-Baudrate hochsetzen oder weniger Zeichen pro Zeit senden.

Maximal pro Sekunde gesendet werden können "Baudrate geteilt durch zehn" Zeichen.

Also das ist der loop ():

 {  if ( millis ()-prev_Miliis>1000)    // Überprüfung, ob sich ein x Wert nach einer Sekunde ändert. Wenn nicht, dann Motorstopp
  {  
    if (x==x_alt)                        //  
  {  analogWrite ( 3,0);
      digitalWrite(13, HIGH);       // Motorstop, led geht an
      z=113;     
  }
    
  x_alt=x;                    // der neue x Wert wird in den alten Wert überschrieben. 
  prev_Miliis=millis();        //die neue Zeit wird überschrieben
  if (z<100){ analogWrite(3,pwm=pwm+3); //Serial.print ("pwm:"); Serial.println(pwm);
   } 
   if (z>110) { analogWrite(3,pwm=pwm-3); //Serial.print ("pwm:"); Serial.println(pwm); 
   }
  
  }
  
}
Temperatursensor.measure(&Temperatur, &Luftfeuchte, &Taupunkt); // Funktion zur  Bearbeitung von Sensordaten
 Serial.print("\nTemperatur: "); // Befehl an den SerialMonitor, die ermittelten Werte dem Benutzer anzuzeigen.
 Serial.print(Temperatur);  
 Serial.println(" \262C");
  Serial.print("Luftfeuchte: ");
  Serial.print(Luftfeuchte);
  Serial.println(" %"); 
  Serial.print("Zyklen");
  Serial.print (x);
}

Entweder eieirt der Motor rum oder bleibt nicht stehen, oder steht nach paar Sekunden, obwohl die Lichtschranke darn ist

[EDIT] CODE-TAGS eingefügt. Uwe[/EDIT]

Wir (ich und die Arduino IDE) kommen mit deinen geschweifeten Klammern nicht klar.

Es sind irgendwie zu viele. Zum Code in einen Post einfügen bitte das "#" Symbol oben nehmen.

Als erste und schnellste Abhilfemaßnahme würde ich die Baudrate ändern. Serial.begin(57600); geht immer 115600 meist auch. (und natürlich im Monitorfenster rechts unten auch umstellen.

Jetzt hoffe ich daß ich beim # einfügen nicht etwas gelöscht habe.

lieber User_ino wir fragten nach dem Sketch und nicht nach der loop()-Funktion. Wenn wir die lopp() Funkton gewollt hätten, dann hatten wir schon danach gefragt.

Grüße Uwe

prev_Miliis schreibt man mit doppel “l” und nicht “i” :wink:

Das scheint, wie Uwe nur ein kleiner Ausschnitt des Sketches zu sein. Aber irgendwie ist die Formatierung aufgrund der vielen {} recht schwer zu lesen.

Im TEIL-SKETCH sehe ich jetzt nicht das Problem mit der Zeit.

Hier ist der ganze Code:

#include <Sensirion.h> // Für den Temp.Sensor

#define PWM_pin 3 // Pin, an dem das pulsweiten modulierte Signal erzeugt wird.
#define Motor_pin 4 // Richtungspin
#define Fehler_Led 13 //Ein Pin für die LED
const uint8_t dataPin = 5; // DataPin des Temperatursensors
const uint8_t clockPin = 6; // ClockPin des Temperatursensors
float Temperatur; // Variablen, die die später berechneten Messwerte beinhalten.
float Luftfeuchte;
float Taupunkt; // eigentlich unnötig

volatile unsigned long x = 0; // Wird für die ISR benötigt, zu Zählung von Impulsen
int z=0; // Wird benötigt für die Differenz zwischen Impulsen, Initialisirung mit 0 damit im PAM ein fester Speicherplatz reserviert wird
long x1=0; // Puls 1
long x2=0; // // Puls 2

unsigned long previousMillis = 0; //

int x_Zustand=1; // wird für die Fallunterscheidung benötigt
long prev_Miliis=0;
long x_alt=0;

byte pwm = 250; // pwm ist der Tastgrad des erzeugten Signals, 8 Bit wird reserviert
// int Input;
int Lichtschranke=2; // Lichtschranke am Pin 2 ( Interrupt Pin)
Sensirion Temperatursensor = Sensirion(dataPin, clockPin); // Objekt Temperatursensor wird erstellt

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

pinMode(PWM_pin, OUTPUT); // Ausgangspin
pinMode(Motor_pin, OUTPUT); // Ausgangspin
pinMode(Lichtschranke, INPUT); // Lichtschranken-Pin (Pin 2) wird als Input funktionalisiert
pinMode(13, OUTPUT); // Ausgangspin
analogWrite(3, pwm); // Anweisung zur Aktivierung des PWM

//Interrupts sind immer PIN 2 und PIN 3
//Mit 0 wird der Interrupt an PIN 2 aktiviert
//2. Parameter: Ist die Funktion die aufgerufen wird, hier ein Zähler
attachInterrupt(0, count, RISING);

}

void loop (){

{ if ( millis ()-prev_Miliis>1000) // Überprüfung, ob sich ein x Wert nach einer Sekunde ändert.
{
if (x==x_alt) // Wenn nicht, dann wurde vom Interrupt keine Drehung registriert, Zur Beginn ist x_alt=0
{ analogWrite ( 3,0); //Anweisung zum Stoppen des Motors, PWM Signal wird unterbunden
digitalWrite(13, HIGH); // LED leuchtet auf, zu Fehleranzeige
//lcd.print ( " Error")
z=213; // Damit das Programm keine weiteren Schritte unternimmt

}

x_alt=x; // der neue x Wert wird in den alten Wert überschrieben.
prev_Miliis=millis(); //die neue Zeit wird überschrieben
if (z<215){ analogWrite(3,pwm=pwm+3); //Serial.print (“pwm:”); Serial.println(pwm); // Regelung
}
if (z>220) { analogWrite(3,pwm=pwm-3); //Serial.print (“pwm:”); Serial.println(pwm);
}

}

}
Temperatursensor.measure(&Temperatur, &Luftfeuchte, &Taupunkt); // Funktion zur Ermittlung von Sensordaten
Serial.print("\nTemperatur: “); // Befehl an den SerialMonitor, die ermittelten Werte dem Benutzer anzuzeigen.
Serial.print(Temperatur);
Serial.println(” \262C");
Serial.print(“Luftfeuchte: “);
Serial.print(Luftfeuchte);
Serial.println(” %”);
Serial.print(“Zyklen”);
Serial.print (x);
}

// ISR
void count()
{
x++; // Zählung der Impulse bei steigender Flanke
if (x==1) { // Wir kontrollieren,
previousMillis=millis();
x_alt=0;
}
if (millis()-previousMillis>1000){ // Jedes mal nach Ablauf von einer Sekunde werden die Pulse 1 und 2 verglichen
switch (x_Zustand){ //
case 1: //
x1=x; // Puls 1 wird aufgenommen
x_Zustand=2; // Zustandswechsel
break;
case 2:
x2=x; // Puls 2 wird aufgenommen
z=x2-x1; // Die Differenz zwischen zweier Impulse wird ermittelt, damit gegebenenfalls eine Regelung vorgenommen wird
x_Zustand=3; // Zustandswechsel
break;
case 3:
x1=x; // Puls 1 wird nochmal aufgenommen
z=x1-x2; // Die Differenz zwischen zweier Impulse wird ermittelt, damit gegebenenfalls eine Regelung vorgenommen wird
x_Zustand=2; // Da als nächstes wieser x2-x1 ermittelt wird, werden die möglichen Fälle damit abgearbeitet
break;
}
previousMillis=millis(); // Nach Bearbeitung der Fallunterscheidung wird die aktuelle Zeit überschrieben
}

}

Das kann nicht gehen. millis() wird in ISRs nicht upgedatet, da das auf einem Timer läuft und sich auf dem AVR Interrupts nicht gegenseitig unterbrechen können. Man kann das einmal ganz am Anfang machen für einen Zeitstempel und das wars.

Wenn du in loop merken willst, dass ein Interrupt ausgelöst wurde, setze global einen boolean, z.B. volatile boolean interruptTriggered;

Den kannst du dann in der ISR setzten und in loop() mit if abfragen.