Du solltest dir mal Grundlagen in C aneignen. sleep.h wird bereits mit der toolchain mitgeliefert. Die sollte somit auch mit #include <avr/sleep.h> eingebunden werden können.
Einen Microview in Sleep zu versetzen hat wenig Sinn. Das OLED das drauf ist, verbraucht Strom und das auch wenn der Controller fast nichts verbraucht weil in sleep.
In den sleep geschickt und mit Masse an Pin2 geweckt:
[code]
#include <avr/sleep.h>
#include <avr/power.h>
#include <MicroView.h> // include MicroView library
int pin2 = 2;
/***************************************************
* Name: pin2Interrupt
*
* Returns: Nothing.
*
* Parameters: None.
*
* Description: Service routine for pin2 interrupt
*
***************************************************/
void pin2Interrupt(void)
{
/* This will bring us back from sleep. */
/* We detach the interrupt to stop it from
* continuously firing while the interrupt pin
* is low.
*/
detachInterrupt(0);
}
/***************************************************
* Name: enterSleep
*
* Returns: Nothing.
*
* Parameters: None.
*
* Description: Enters the arduino into sleep mode.
*
***************************************************/
void enterSleep(void)
{
/* Setup pin2 as an interrupt and attach handler. */
attachInterrupt(0, pin2Interrupt, LOW);
delay(100);
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sleep_mode();
/* The program will continue from here. */
/* First thing to do is disable sleep. */
sleep_disable();
}
/***************************************************
* Name: setup
*
* Returns: Nothing.
*
* Parameters: None.
*
* Description: Setup for the Arduino.
*
***************************************************/
void setup()
{
Serial.begin(9600);
/* Setup the pin direction. */
pinMode(pin2, INPUT);
Serial.println("Initialisation complete.");
}
/***************************************************
* Name: loop
*
* Returns: Nothing.
*
* Parameters: None.
*
* Description: Main application loop.
*
***************************************************/
int seconds=0;
void loop()
{
delay(1000);
seconds++;
uView.begin(); // start MicroView
uView.clear(PAGE); // clear page
uView.print("wach fuer ");
uView.print(seconds, DEC);
uView.print(" s");
uView.display();
if(seconds == 3)
{
uView.begin(); // start MicroView
uView.clear(PAGE); // clear page
uView.print("starte sleep");
uView.display();
delay(200);
seconds = 0;
enterSleep();
}
}
[/code]
Wenn ich uView weglasse geht er von 65mA auf 25mA runter (mit uView von 68 auf 28mA) - gar nicht so schlecht. Der Micro sollte ohne Display noch sparsamer sein...
Ich versuche das OLED (zwecks Bildschirmschoner) nur einzuschalten wenn der angeschlossene Bewegungsmelder sich meldet.
Ausschalten kann ich es per uView.end();. Das klappt auch. Nur geht es nicht wieder mit uView.begin(); an. Einmal aus - immer aus - das will ich nicht glauben!?
Bin wohl der Einzige, der den MicroView nutzt... ;D
Hab was rausgefunden:
Wenn ich nach uView.display(); ein Delay(1000); setze wird wieder was angezeigt.
Liegt wohl daran dass solange (digitalRead(PirPIN) == HIGH) ist immer wieder uView.display(); durchlaufen wird. Das geht wohl so schnell, dass es nicht zur Anzeige kommt.
Ich müsste sicherstellen das nach (digitalRead(PirPIN) == HIGH) die Anzeigeroutine nur einmal durchlaufen wird.
Nur weiß ich nicht so recht WIE - habt ihr einen Tip für mich?
// Verriegelungszeit Bewegungsmelder
if (digitalRead(PirPIN) == HIGH)
{
aktBewMillis = millis();
BewegungErkannt = HIGH;
DisplayChange = HIGH
}
if (millis() - aktBewMillis > BewMeldverzoegerung) // Bewegungsmelder aus
{
BewegungErkannt = LOW;
Serial.println ("Bewegung auf LOW");
//delay(2000);
}
Serial.println (BewegungErkannt);
//Anzeige
if (BewegungErkannt == HIGH)
{
if (DisplayChange == HIGH)
{
uView.begin(); // start MicroView
uView.clear(PAGE); // clear page
uView.setCursor(0,0); // set cursor at 0,0
uView.print(Zeile1);
uView.setCursor(0,9);
uView.print(Zeile2);
uView.setCursor(0,18);
uView.print(Zeile3);
uView.setCursor(0,27);
uView.print(Zeile4);
uView.setCursor(0,36);
uView.print(Zeile5);
uView.display();
DisplayChange = LOW;
}
}
if (BewegungErkannt == LOW)
{
uView.begin(); // start MicroView
uView.clear(PAGE); // clear page
uView.display();
digitalWrite(LED,LOW);
}
Setz doch eine Art "Display-Flag"... so im Sinne von:
.
.
.
flag = true;
.
.
.
if( flag == true )
{
ZeigeDiesesUndJenes();
flag = false;
}
.
.
.
und irgendwann später, wenn wieder etwas gezeigt werden soll:
flag = true;
Ich habe jetzt das Programm umgestellt und die Anzeige-Routine als Unterprogramm laufen lassen.
Das funktioniert prima. Mein Plan ist das einmalige Durchlaufen der Anzeige-Routine im Unterprogramm besser steuern zu können.
#include <MicroView.h> // include MicroView library
int Pin0 = 0;
int Pin1 = 1;
int Pin2 = 2;
int Pin3 = 3;
int Pumpe = 5;
int State0 = HIGH;
int LastState0 = HIGH;
int State1 = HIGH;
int LastState1 = HIGH;
int State2 = HIGH;
int LastState2 = HIGH;
int State3 = HIGH;
int LastState3 = HIGH;
int Pumpenverzoegerung = 10000;
String Zeile1;
String Zeile2;
String Zeile3;
String Zeile4;
String Zeile5;
String Zeile6;
String Ereignis;
bool AutoPumpeAus = LOW;
bool AutoPumpeAusErkannt = LOW;
bool SchonAngezeigt1 = LOW;
bool SchonAngezeigt2 = LOW;
bool SchonAngezeigt3 = LOW;
bool SchonAngezeigt4 = LOW;
bool SchonAngezeigt5 = LOW;
bool SchonAngezeigt6 = LOW;
bool SchonAngezeigt7 = LOW;
bool SchonAngezeigt8 = LOW;
bool SchonAngezeigt9 = LOW;
bool SchonAngezeigt10 = LOW;
unsigned long aktMillis, altMillis, printMillis, pumpenMillis; // speichert wie viele Sekunden seit derletzten Änderung vergangen sind
void setup()
{
Serial.begin(9600);
/* Setup the pin direction. */
pinMode(Pin0, INPUT);
pinMode(Pin1, INPUT);
pinMode(Pin2, INPUT);
pinMode(Pin3, INPUT);
pinMode(Pumpe, OUTPUT);
digitalWrite(Pumpe, LOW);
uView.begin(); // start MicroView
uView.clear(PAGE); // clear page
uView.setCursor(5,0);
uView.print("Sprenger");
uView.setCursor(12,9);
uView.print("Pumpen-");
uView.setCursor(5,18);
uView.print("Steuerung");
uView.display();
delay(3000);
}
void loop()
{
State0 = digitalRead (Pin0);
State1 = digitalRead (Pin1);
State2 = digitalRead (Pin2);
State3 = digitalRead (Pin3);
//Aktion für Pin0
if(LastState0 == LOW && State0 == HIGH)
{
Zeile2 = "Spr O aus";
LastState0 = State0;
AutoPumpeAus = HIGH;
SchonAngezeigtLoeschen (); //Unterprogramm aufrufen
Anzeige (); //Unterprogramm um Daten anzuzeigen
}
if(LastState0 == HIGH && State0 == LOW)
{
Zeile2 = "Spr O an";
Zeile1 = "Pumpe an";
LastState0 = State0;
digitalWrite(Pumpe, HIGH);
AutoPumpeAus = LOW;
AutoPumpeAusErkannt = LOW;
Anzeige (); //Unterprogramm um Daten anzuzeigen
}
//Aktion für Pin1
if(LastState1 == LOW && State1 == HIGH)
{
Zeile3 = "Spr S aus";
LastState1 = State1;
AutoPumpeAus = HIGH;
SchonAngezeigtLoeschen (); //Unterprogramm aufrufen
Anzeige (); //Unterprogramm um Daten anzuzeigen
}
if(LastState1 == HIGH && State1 == LOW)
{
Zeile3 = "Spr S an";
Zeile1 = "Pumpe an";
LastState1 = State1;
digitalWrite(Pumpe, HIGH);
AutoPumpeAus = LOW;
AutoPumpeAusErkannt = LOW;
Anzeige (); //Unterprogramm um Daten anzuzeigen
}
//Aktion für Pin2
if(LastState2 == LOW && State2 == HIGH)
{
Zeile4 = "Spr W aus";
LastState2 = State2;
AutoPumpeAus = HIGH;
SchonAngezeigtLoeschen (); //Unterprogramm aufrufen
Anzeige (); //Unterprogramm um Daten anzuzeigen
}
if(LastState2 == HIGH && State2 == LOW)
{
Zeile4 = "Spr W an";
Zeile1 = "Pumpe an";
LastState2 = State2;
digitalWrite(Pumpe, HIGH);
AutoPumpeAus = LOW;
AutoPumpeAusErkannt = LOW;
Anzeige (); //Unterprogramm um Daten anzuzeigen
}
//Aktion für Pin3
if(LastState3 == LOW && State3 == HIGH)
{
Zeile5 = "Spr N aus";
//Zeile1 = "Pumpe aus";
LastState3 = State3;
AutoPumpeAus = HIGH;
SchonAngezeigtLoeschen (); //Unterprogramm aufrufen
Anzeige (); //Unterprogramm um Daten anzuzeigen
}
if(LastState3 == HIGH && State3 == LOW)
{
Zeile5 = "Spr N an";
Zeile1 = "Pumpe an";
LastState3 = State3;
digitalWrite(Pumpe, HIGH);
AutoPumpeAus = LOW;
AutoPumpeAusErkannt = LOW;
Anzeige (); //Unterprogramm um Daten anzuzeigen
}
//Automatische Pumpenabschaltung nach Zeit
if(AutoPumpeAus == HIGH)
{
if(AutoPumpeAusErkannt == LOW)
{
aktMillis = millis();
altMillis = aktMillis;
AutoPumpeAusErkannt = HIGH;
}
Ereignis = "Automatische Pumpenabschaltung an";
switch ((millis() - altMillis)/1000)
{
case 1:
Zeile1 = "Pumpe 9s";
if (SchonAngezeigt1 == LOW)
{
Anzeige (); //Unterprogramm um Daten anzuzeigen
SchonAngezeigt1 = HIGH;
}
break;
case 2:
Zeile1 = "Pumpe 8s";
if (SchonAngezeigt2 == LOW)
{
Anzeige (); //Unterprogramm um Daten anzuzeigen
SchonAngezeigt2 = HIGH;
}
break;
case 3:
Zeile1 = "Pumpe 7s";
if (SchonAngezeigt3 == LOW)
{
Anzeige (); //Unterprogramm um Daten anzuzeigen
SchonAngezeigt3 = HIGH;
}
break;
case 4:
Zeile1 = "Pumpe 6s";
if (SchonAngezeigt4 == LOW)
{
Anzeige (); //Unterprogramm um Daten anzuzeigen
SchonAngezeigt4 = HIGH;
}
break;
case 5:
Zeile1 = "Pumpe 5s";
if (SchonAngezeigt5 == LOW)
{
Anzeige (); //Unterprogramm um Daten anzuzeigen
SchonAngezeigt5 = HIGH;
}
break;
case 6:
Zeile1 = "Pumpe 4s";
if (SchonAngezeigt6 == LOW)
{
Anzeige (); //Unterprogramm um Daten anzuzeigen
SchonAngezeigt6 = HIGH;
}
break;
case 7:
Zeile1 = "Pumpe 3s";
if (SchonAngezeigt7 == LOW)
{
Anzeige (); //Unterprogramm um Daten anzuzeigen
SchonAngezeigt7 = HIGH;
}
break;
case 8:
Zeile1 = "Pumpe 2s";
if (SchonAngezeigt8 == LOW)
{
Anzeige (); //Unterprogramm um Daten anzuzeigen
SchonAngezeigt8 = HIGH;
}
break;
case 9:
Zeile1 = "Pumpe 1s";
if (SchonAngezeigt9 == LOW)
{
Anzeige (); //Unterprogramm um Daten anzuzeigen
SchonAngezeigt9 = HIGH;
}
break;
}
if (millis() - altMillis > Pumpenverzoegerung) //Pumpe aus
{
Ereignis = "5s Automatische Pumpenabschaltung vorbei";
Zeile1 = "Pumpe aus";
Anzeige (); //Unterprogramm um Daten anzuzeigen
digitalWrite(Pumpe, LOW);
AutoPumpeAusErkannt = LOW;
AutoPumpeAus = LOW;
SchonAngezeigtLoeschen (); //Unterprogramm aufrufen
}
}
}
// ab hier Unterprogramme....................................................................................
void Anzeige () // Unterprogramm um Daten anzuzeigen
{
uView.begin(); // start MicroView
uView.clear(PAGE); // clear page
uView.setCursor(0,0); // set cursor at 0,0
uView.print(Zeile1);
uView.setCursor(0,9);
uView.print(Zeile2);
uView.setCursor(0,18);
uView.print(Zeile3);
uView.setCursor(0,27);
uView.print(Zeile4);
uView.setCursor(0,36);
uView.print(Zeile5);
uView.display();
}
void SchonAngezeigtLoeschen () //Unterprogramm
{
SchonAngezeigt1 = LOW;
SchonAngezeigt2 = LOW;
SchonAngezeigt3 = LOW;
SchonAngezeigt4 = LOW;
SchonAngezeigt5 = LOW;
SchonAngezeigt6 = LOW;
SchonAngezeigt7 = LOW;
SchonAngezeigt8 = LOW;
SchonAngezeigt9 = LOW;
SchonAngezeigt10 = LOW;
}
Jetzt also den Bewegungsmelder mit einprogrammiert.
Anzeige wird korrekt bei Bewegung ein und nach Zeitverzögerung 10s wieder ausgeschalten.
Aber was ist das: Eingang PIN1 (Spr S an) spielt IRRER IWAN !!
Schon nach dem Einschalten wird Spr S an als aktiv erkannt und schaltet nach ein paar Sekunden allein auf inaktiv.
An meiner Hardwarebeschaltung hat sich nix geändert. Muss also am Programm liegen.
Ich finde auch keine Überschneidung von Variablen:
Code mit Bewegungsmelder im nächsten Post - weil sonst zu lang.
Stoni geht ein Licht auf! Ja, sowas passiert manchmal auch...
Lt. Pin-Configuration ist auf Pin1 auch TXD. Bei Serial.println sende ich also an den Pin1 Daten welche von meinem Programm registriert wurden und den irren Iwan auslösten.
Also alles Physik und keine versteckte Kamera! Aber erst mal drauf kommen...