Projekt Alarmanlage plötzlich treten Fehler auf!

Hallo,

ich habe des längeren an einem Projekt gearbeitet: “Alarmanlage”. Mit den Komponenten NodeMCU ESP8266 12E, PIR Sensor, SD-Breadboard und einer TTL Camera habe ich eine kleine Alarmanlage gebastelt, die bei Bewegung ein Foto auslöst. Es hat auch alles funktioniert, bis sich auf einmal der Programmcode aufhing. Auf dem Serial Monitor erscheinen komische Ziffern nach dem Starten des Programms. Nach mehrmaligem betätigen des RST-Buttons läuft der Programm-Code wieder und hängt sich auch nicht mehr auf. Dennoch werden die Bilder nicht mehr auf der SD-Card gespeichert, lediglich wird die Bilddatei angelegt. Das einzigste was sich, von der Version die funktioniert hat bis hin zur defekten Version, geändert hat, war der Laptop mit dem Programmiert wurde und von dem der ESP die Spannung bekommt. (Laptop: Xiaomi Mi Air).

Code:

//*******************************************************
//*******************************************************
#include <SoftwareSerial.h>
#include <SPI.h>
#include <SD.h>
 
SoftwareSerial mySerial(D1,D2);          // Set Arduino pin 4 and 5 as softserial
 
byte ZERO = 0x00;
byte incomingbyte;
long int a=0x0000, j=0,k=0,count=0,i=0x0000;
uint8_t MH,ML;
boolean EndFlag=0;
File  myFile;
int globalCnt;
int pirPin = D3;
 
void SendResetCmd() {
  mySerial.write((byte)0x56);
  mySerial.write((byte)0x00);
  mySerial.write((byte)0x26);
  mySerial.write((byte)0x00);   
}
 
/*************************************/
/* Set ImageSize :
/* <1> 0x22 : 160*120
/* <2> 0x11 : 320*240
/* <3> 0x00 : 640*480
/* <4> 0x1D : 800*600
/* <5> 0x1C : 1024*768
/* <6> 0x1B : 1280*960
/* <7> 0x21 : 1600*1200
/************************************/
void SetImageSizeCmd(byte Size)
{
    mySerial.write(0x56);
    mySerial.write(ZERO);  
    mySerial.write(0x54);
    mySerial.write(0x01);
    mySerial.write(Size);
}
 
/*************************************/
/* Set BaudRate :
/* <1>¡¡0xAE  :   9600
/* <2>¡¡0x2A  :   38400
/* <3>¡¡0x1C  :   57600
/* <4>¡¡0x0D  :   115200
/* <5>¡¡0xAE  :   128000
/* <6>¡¡0x56  :   256000
/*************************************/
void SetBaudRateCmd(byte baudrate)
{
    mySerial.write(0x56);
    mySerial.write(ZERO);
    mySerial.write(0x24);
    mySerial.write(0x03);
    mySerial.write(0x01);
    mySerial.write(baudrate);
}
 
void SendTakePhotoCmd() {
  mySerial.write((byte)0x56);
  mySerial.write((byte)0x00);
  mySerial.write((byte)0x36);
  mySerial.write((byte)0x01);
  mySerial.write((byte)0x00);
  
  a = 0x0000; //reset so that another picture can taken
}
 
void SendReadDataCmd()
{
    MH=a/0x100;
    ML=a%0x100;
    
    mySerial.write(0x56);
    mySerial.write(ZERO);
    mySerial.write(0x32);
    mySerial.write(0x0c);
    mySerial.write(ZERO);
    mySerial.write(0x0a);
    mySerial.write(ZERO);
    mySerial.write(ZERO);
    mySerial.write(MH);
    mySerial.write(ML);
    mySerial.write(ZERO);
    mySerial.write(ZERO);
    mySerial.write(ZERO);
    mySerial.write(0x20);
    mySerial.write(ZERO);
    mySerial.write(0x0a);
    
    a+=0x20;
}
 
void StopTakePhotoCmd()
{
    mySerial.write((byte)0x56);
    mySerial.write((byte)ZERO);
    mySerial.write((byte)0x36);
    mySerial.write((byte)0x01);
    mySerial.write((byte)0x03);
}
 
void setup()
{
    globalCnt = 0;
    Serial.begin(19200);
    
    mySerial.begin(38400); //start serial with camera
    
    Serial.println("Initializing SD card...");

    if (!SD.begin(D8, SPI_HALF_SPEED)){
    do {Serial.println("initialization failed!");}
    while(!SD.begin(D8, SPI_HALF_SPEED));
    }
   //if (!SD.begin(D8, SPI_HALF_SPEED))
   // {
    //    Serial.println("initialization failed!");
    //    return;

   // }
    Serial.println("initialization done.");
    Serial.println("please waiting ....");
 
    
    SendResetCmd();
    delay(3000);
 
}
 
void loop()
{
    
    byte b[32];
    int ii;
    Serial.println("Start take photo");
    SendTakePhotoCmd(); //take photo
    
    delay(1000);
    
    while(mySerial.available()>0)
    {
        incomingbyte=mySerial.read();
        
    }
 
    myFile = SD.open("Pic" + String(globalCnt) + ".jpg", FILE_WRITE); //The file name should not be too long
    globalCnt++;
    while(!EndFlag)
    {
        j=0;
        k=0;
        count=0;
        //mySerial.flush();
        SendReadDataCmd();
        
        delay(75);
        while(mySerial.available()>0)
        {
            incomingbyte=mySerial.read();
            k++;
            //delay(1); //250 for regular
            if((k>5)&&(j<32)&&(!EndFlag))
            {
                b[j]=incomingbyte;
                if((b[j-1]==0xFF)&&(b[j]==0xD9))     //tell if the picture is finished
                {
                    EndFlag=1;
                }
                j++;
                count++;
            }
        }
 
/*        for(j=0;j<count;j++)
        {
            if(b[j]<0x10)  
            Serial.print("0");
            Serial.print(b[j],HEX);           // observe the image through serial port
            Serial.print(" ");
            
        }*/
 
        for(ii=0; ii<count; ii++) //?!??
        myFile.write(b[ii]);
        
//        Serial.println();

    }
    
    StopTakePhotoCmd(); //stop this picture so another one can be taken
    EndFlag = 0; // reset flag to allow another picture to be read
    Serial.println("End Programm...");
   
    myFile.close();
    Serial.println("Finished writing data to file");
    Serial.println("Wait for new Pic");
    delay(10000);
    
    
}

Fehler Serial Monitor:

Bin für jeden Lösungsvorschlag dankbar.

Grüße
Pommi

Nachtrag:

Das Fehlerbild erscheint auch, wenn ich ein einfachens Programm auf dem ESP ausführe. Auch bei einem anderen ESP erscheinen die Fehler. Wohlmöglich liegt der Fehler bei der Versorgungsspannung des USB-Port des Laptops?! Habe zur Zeit keine andere Möglichkeit Ihn wo anders zu testen. Kamen bei euch auch schon einmal solche Fehler auf?

Leider ist SoftwareSerial auf dem ESP8266 genauso schlecht implementiert wie auf den Arduino AVR-Typen. Während dem ganzen Empfang und auch während dem Senden eines Bytes werden die Interrupts ausgeschaltet und mittels einer leeren Schleife gewartet. Das wiederum heisst, dass alle Hintergrund-Tasks nicht genügend Aufmerksamkeit bekommen und Funktionen, die normalerweise gut funktionieren (wie z.B. die Ansteuerung einer seriellen Schnittstelle oder von USB) plötzlich schief gehen. Wenn Deine Kamera also genügend Daten überträgt, geht auch der sonst relativ leistungsfähige ESP8266 sehr schnell in die Knie. Dann können natürlich auch solche Sachen passieren. Leider habe ich für den ESP8266 keine alternative Software-Emulation der seriellen Schnittstelle anzubieten.

Die Komponenten die ich verwendet habe sind folgende:

-Linksprite JPEG Color Camera mit TTL Interface
-PIR-Sensor
-NodeMCU ESP8266 12-E
-Linksprite SD-Card-Breadboard

Aufbau Fritzing:

Gruß
Pommi

So ich hatte heute morgen ein wenig Zeit gehabt um einige Sachen testen zu können.
Nach meinen Tests habe ich zwei Fehlerquellen ausfindig machen können:

  1. Für den PIR Sensor habe ich Pin D3 belegt, dies führt zu der Fehlausgabe auf dem Serial Monitor -> Vermutlich weil der Pin für Flash Anwendungen resaviert ist?!
  2. Die Versorgungsspannung über den USB-Port reicht nicht aus. Nur wenn ich das Kameramodul nicht verbinde, läuft das Programm.

Frage:

  1. Welchen Alternativen GPIO Port kann ich für den PIR Sensor ansprechen? Wie spreche ich den GPIO10 oder GPIO9 Port auf dem ESP 12 E an?

Ich werde es heute Abend oder Morgen fruh mit einer zweiten Stromquelle für das Kameramodul testen und werde euch das Ergebnis berichten.

Danke Gruß
Pommi

Hallo,
ich sehe da keine festgesetzten ReaktionsZeiten, das Ding läuft einfach durch.
Du mußt z.B. der "SoftwareSerial.h" Zeit geben alles zu verarbeiten. Auch dem SD-Reader würde das gut tun.
Soll heißen: Eine Komponente ist noch nicht fertig, aber der Arduino mach schon etwas anderes.
Das hat nichts damit zu tun, das im Sketch einen nach dem anderen abläuft.
Gruß und Spaß
Andreas

Hallo,
was läuft einfach durch? Und wie und wo setze ich Reaktionszeiten? Verstehe nicht was du meinst? Glaube nämlich nicht, dass der Fehler daran liegt.

Gruß
Pommi

Hallo,
"Glaube nämlich nicht, dass der Fehler daran liegt"
Na, dann kann ich Dir wohl doch nicht helfen.
Ein Tip noch- Alarmanlage... in sensiblen Bereichen betreibt man eigentlich ein Fehlermanagement.
Wenn also etwas nicht rund läuft, wie in Deinem Fall (?), dann zeichnet man das auf.
So kann man später feststellen was nicht richtig läuft- auch eine konkrete Fragestellung ist so möglich.
Gruß und Spaß
Andreas

Du mußt z.B. der "SoftwareSerial.h" Zeit geben alles zu verarbeiten. Auch dem SD-Reader würde das gut tun.

Entschuldigung, aber das ist Blödsinn. SoftwareSerial muss sicher nicht noch mehr Zeit bekommen, als es sich ohnehin schon nimmt. Es ist bekannt dafür, dass es eben viel zu viel Prozessorzeit verbraucht, ohne wirklich etwas zu leisten.
Und der SD-Reader wird per SPI angesteuert, somit läuft der Transfer synchron ab, d.h. die Kommunikation ist abgeschlossen, wenn die Funktion zurückkehrt. Die Frage ist, ob die SD-Karte die Geschwindigkeit des SPI-Busses verdaut, aber aufgrund dessen, dass das Teil eigentlich durchlief und ich keine Angaben bzgl. der SD-Karte habe, würde ich mal annehmen, dass das funktonieren sollte. Falls der SPI zu schnell ist, dann muss aber nicht gewartet werden, sondern die Clock-Rate runtergeschraubt werden. Warten ist nur in den seltensten Fällen sinnvoll und in diesen ist es meist explizit im entsprechenden Datenblatt erwähnt.

Hallo,
na, dann habe ich ja wieder etwas dazu gelernt.
Der hat jetzt schon delay() drinne, weil sein Zeug´s unkontrolliert durchrast.
Nur schaffen die keine Abhilfe und sind absolut gefährlich in einer Alarmanlage.
Gruß und Spaß
Andreas