Programm blockiert Knöpfe

Hallo

ich mir jetzt SSR-Relais geholt(um LCD-Probleme zu beseitigen(klappt wunderbar))
Um sie manuell zu betätigen habe ich noch 4 knöpfe angeschlossen.

ich habe 3 Programmabläufe die ich mit durch Status reguliere( also status 10 = aus, 0=1.programm, 20=2.prog., 30=3.prog.)

die status werden durch andere knöpfe reguliert.

Die programme laufen aber die ganze zeit im loop

programm1();
  programm2();
  programm3();
  
  
} // endklammer des loops

Nun wollte ich aber das die knöpfe nur regulierbar sind, wenn status 10 ist (status 10 = kein programm).

Mir ist aufgefallen das die knöpfe nicht funktionierten.
Da programm3() das neuste war habe ich es einfach mal aus dem loop rausgenommen und alles klappte wieder wunderbar( prog.1 und 2 blieben weiter im loop)

Nun suche ich nach dem Fehler finde aber keinen.
Warum blockiert programm3 die Relaisknöpfe?

Wenn ich etwas undeutlich formuliert habe(, was warscheinlich so ist) einfach fragen.

Den ganzen sketch habe ich hochgeladen weil er für den post zu groß ist.

Gruß

strohhirn

_9_9_2013_ino.ino (12.3 KB)

Dazu sollte man vielleicht wissen was Programm 3 macht. Werden da Delays verwendet oder auf irgendwas gewartet?

eigentlich dürfeten keine delais drinn sein und wenn sollte sie eig. doch nicht laufen.

Die 3 programme bestehen eig nur aus if- bedingungen die von status abhängig sind.

Und da der status standartmäsig auf 10 ist, dürfe ja eig. da nichts laufen. (status 30 und höher bei prog.3)

Was mir aber aufgefallen ist das bei prog.3 ein teil mit piezo buzzer ist:

else if (sensors.getTempC(Sensor[0]) >= 93 && status == 35) {
   noTone(8); // schalten Ton ab		
  tone(8, 4000, 1000); // geben Ton 4000 Hz, Dauer 1000 ms an Pin 9 aus

  noTone(8); // schalten Ton ab
  tone(8, 3000, 1000); // geben Ton 3000 Hz, Dauer 1000 ms an Pin 9 aus
 
   
   status = 36;
 }

void buzz(int targetPin, long frequency, long length)
{
  long delayValue = 1000000/frequency/2;
  long numCycles = frequency * length/ 1000; 
 for (long i=0; i < numCycles; i++){ 
    digitalWrite(targetPin,HIGH); 
    delayMicroseconds(delayValue);
    digitalWrite(targetPin,LOW); 
    delayMicroseconds(delayValue);
  }
}

Ok, habe mir mal das Programm angesehen. Dauert das auslesen der Temperatur-Sensoren nicht ziemliche lange (eventuell mehrere 100ms)? Ich glaube da habe ich was darüber gelesen. Statt das ständig zu wiederholen, reicht es auch das einmal zu machen und dann den abgespeicherten Wert als Vergleich zu nehmen. Anderseits funktioniert das ja anscheinend bei Prog1 und Prog2.

In dieser Zeile sollte man sicherheitshalber Klammern um die Teil-Terme setzen:
else if( status == 32 && millis() > nextMillis || sensors.getTempC(Sensor[0]) >= 25.0 && status ==30 ) {

Mit dem Tone hast du natürlich eine gewisse Verzögerung drin, während der das Programm nicht auf sonstige Kommandos reagiert. Kannst das ja mal testweise auskommentieren.

Das mit dem Status lässt sich übrigens schöner mit enums lösen:
enum { PROG1, PROG2, PROG3, AUS } status = PROG1;

Dann kannst du if(status == PROG1) machen und der Variable auch andere Zustände zuweisen die im enum definiert ist. Also "status = PROG2"

Ok, habe mir mal das Programm angesehen. Dauert das auslesen der Temperatur-Sensoren nicht ziemliche lange (eventuell mehrere 100ms)? Ich glaube da habe ich was darüber gelesen. Statt das ständig zu wiederholen, reicht es auch das einmal zu machen und dann den abgespeicherten Wert als Vergleich zu nehmen. Anderseits funktioniert das ja anscheinend bei Prog1 und Prog2.

Ich habe keine ahnung wie das mit dem abspeichern geht. Aber ich hatte glaube ich noch keine probleme damit.

Das mit dem Status lässt sich übrigens schöner mit enums lösen:
enum { PROG1, PROG2, PROG3, AUS } status = PROG1;

Dann kannst du if(status == PROG1) machen und der Variable auch andere Zustände zuweisen die im enum definiert ist. Also "status = PROG2"

Gut mal davon gehört zu haben, danke. Ich brauche aber auch innerhalb der programme die status für den ablauf.

Eigentlich will ich ja einen kleinen alarm mit nem piezo buzzer einbauen, kriegs aber nicht richtig hin.
Es sollen abwelchselde töne vorkommen (wie bei sirene) darf aber kein delay haben.

Kennt da jemand etwas simples?

Die Töne kann man auch ohne die Verzögerung setzen. Ich muss mal eben ein alten Sketch raussuchen, da hatte ich die StarWars Melodie umgeschrieben ohne delays.

const int buzzerPin = 3;    

#define c 261
#define d 294
#define e 329
#define f 349
#define g 391
#define gS 415
#define a 440
#define aS 455
#define b 466
#define cH 523
#define cSH 554
#define dH 587
#define dSH 622
#define eH 659
#define fH 698
#define fSH 740
#define gH 784
#define gSH 830
#define aH 880
#define pause 0


void setup() 
{
  pinMode(buzzerPin, OUTPUT);
  Serial.begin(9600);
}

void loop() 
{
  static unsigned long tempZeit;
  unsigned long aktuelleZeit = millis();
  static unsigned long tonBeginn;
  static unsigned long tonDauer;
  static int notenNr;
  Serial.println(aktuelleZeit - tempZeit);

  int noten[] = { 
    a, a, a, f, cH, a, f, cH, a, eH, eH, eH, fH, cH, gS, f, cH, a, aH, a, a, aH, gSH, gH, fSH, fH, fSH, 
    pause, f, gS, f, a, cH, a, cH, eH, aH, a, a, aH, gSH, gH, fSH, fH, fSH, 
    pause, aS, dSH, dH, cSH, cH, b, cH, 
    pause, f, gS, f, cH, a, f, c, a
  };

  int dauer[] = { 
    500, 500, 500, 350, 150, 500, 350, 150, 1000, 500, 500, 500, 350, 150, 500, 350, 150, 1000, 500, 350, 150, 500, 250,250, 125, 125, 250, 
    250, 125, 500, 375, 125, 500, 375, 125, 1000, 500, 320, 150, 500, 250, 250, 125, 125, 250, 
    250, 250, 500, 250, 250, 125, 125, 250, 
    250, 250, 500, 375, 125, 500, 375, 125, 1000
  };


  if(aktuelleZeit - tonBeginn > tonDauer )
  {
    if(noten[notenNr] == pause) noTone(buzzerPin);
    else tone(buzzerPin, noten[notenNr]);
    tonDauer = dauer[notenNr];
    notenNr++;
    if( notenNr ==  62) {
      notenNr = 0;
      noTone(buzzerPin);
    }
    tonBeginn = aktuelleZeit;
  }
  tempZeit = aktuelleZeit;
}

Zykluszeit 3-4ms.

strohhirn:
Gut mal davon gehört zu haben, danke. Ich brauche aber auch innerhalb der programme die status für den ablauf.

Geht auch. Das enum wird global definiert und ist gleichzeitig die Zustandsvariable. Wenn du meinst, dass du den Status für die Programme getrennt brauchst, muss man mehr enums anlegen und für jedes Programm eines machen. z.B. enum { AUS, S1, S2, S3, S4, S5, S6, S7 } statusProg3 = AUS;

Ist natürlich etwas mehr Schreib-Aufwand, aber der Vorteil ist halt, dass es besser lesbar ist und die Zustände aussagekräftiger sind.

Habs hingekriegt.
lag nicht an dem tone sondern an diesem teil:

else if (900 <=W < 1000 ) {
   mbar = 50;
   if (mb > mbar){
     fade--;
     analogWrite(ledPin, fade);
   }
   if (mb < mbar){
     fade++;
     analogWrite(ledPin, fade);  
   }
   status = 35;
 }

hab da ne status angabe in der if bedingung vergessen.

den alarm sketch wollt ich auch in mein sketch integrieren, aber ich kann folgendes nicht global deklarieren:

static unsigned long tempZeit;
  unsigned long aktuelleZeit = millis();
  static unsigned long tonBeginn;
  static unsigned long tonDauer;
  static int notenNr;
  Serial.println(aktuelleZeit - tempZeit);

denn kommt kein ton.

Wisst ihr wie ich diesen teil global deklarieren kann?

Übrigens ist mehr aufgefallen das der piezo ja doch sehr leise ist für einen alarm.
Kann man ihn irgendwie lautermachen oder sollte man sich da ein anderes teil holen?

Wieso immer global deklarieren, wenn es nur in einer Funktion genutzt wird. Mach aus loop() -> alarmbuzzer()?

Buzzer sind nicht zwingend gleich leise. Habe mir welche für 5V vom chinesen geholt. Sind deutlich leiser, als den ersten den ich zum testen hatte. Dieser war eigentlich für ein Mainboard gedacht.

Obs richtig laute für 5V gibt, weiß ich nicht. Man muss ja immer den Strom im Auge behalten. Max 40mA! Alles andere muss mit einer Treiberschaltung gelöst werden und dann wäre es auch möglich 12V oder ähnliche Buzzerspannung zu nehmen.

...
const int buzzerPin = 3;  

void setup() 
{
...
	pinMode(buzzerPin, OUTPUT);
}

void loop()
{
...
	alarmbuzzer();
}


void alarmbuzzer() 
{
#define c 261
#define d 294
#define e 329
#define f 349
#define g 391
#define gS 415
#define a 440
#define aS 455
#define b 466
#define cH 523
#define cSH 554
#define dH 587
#define dSH 622
#define eH 659
#define fH 698
#define fSH 740
#define gH 784
#define gSH 830
#define aH 880
#define pause 0

	static unsigned long tempZeit;
	unsigned long aktuelleZeit = millis();
	static unsigned long tonBeginn;
	static unsigned long tonDauer;
	static int notenNr;

	int noten[] = { 
		a, a, a, f, cH, a, f, cH, a, eH, eH, eH, fH, cH, gS, f, cH, a, aH, a, a, aH, gSH, gH, fSH, fH, fSH, 
		pause, f, gS, f, a, cH, a, cH, eH, aH, a, a, aH, gSH, gH, fSH, fH, fSH, 
		pause, aS, dSH, dH, cSH, cH, b, cH, 
		pause, f, gS, f, cH, a, f, c, a
	};

	int dauer[] = { 
		500, 500, 500, 350, 150, 500, 350, 150, 1000, 500, 500, 500, 350, 150, 500, 350, 150, 1000, 500, 350, 150, 500, 250,250, 125, 125, 250, 
		250, 125, 500, 375, 125, 500, 375, 125, 1000, 500, 320, 150, 500, 250, 250, 125, 125, 250, 
		250, 250, 500, 250, 250, 125, 125, 250, 
		250, 250, 500, 375, 125, 500, 375, 125, 1000
	};


	if(aktuelleZeit - tonBeginn > tonDauer )
	{
		if(noten[notenNr] == pause) noTone(buzzerPin);
		else tone(buzzerPin, noten[notenNr]);
		tonDauer = dauer[notenNr];
		notenNr++;
		if( notenNr ==  62) {
			notenNr = 0;
			noTone(buzzerPin);
		}
		tonBeginn = aktuelleZeit;
	}
	tempZeit = aktuelleZeit;
}

Hey, das klappt, danke, genau sowas wollt ich :smiley: wusste bloß nicht wie.