Programm läuft nur richtig, wenn Serieller Monitor geöffnet ist

Hallo,

ich habe folgendes Problem:
Mein Sketch funktioniert nur richtig, wenn der Serielle Monitor geöffnet ist.
Ist der Serielle Monitor offen, werden regelmäßig auf dem LCD Werte ausgegeben. :slight_smile:
Schließe ich den Monitor, werden die Werte nicht mehr aktualisiert. :confused:

Der Originalsketch ist von Jurs (Auslesen der Tchibo Wetterstation):
Klick

Das ist meine modifizierte Verion, die auf einem NodeMcu laufen soll:

#include <LiquidCrystal_I2CMS.h>

LiquidCrystal_I2C lcd(0x3F, 20, 4);
//3f, 20, 4
// connect data pin of rx433 module to a pin that can handle hardware interrupts
// with an Arduino UNO this is digital I/O pin 2 or 3 only
#define RX433DATAPIN D3

// hardware interrupt connected to the pin
// with Arduino UNO interrupt-0 belongs to pin-2, interrupt-1 to pin-3
#define RX433INTERRUPT 0

// Now make some suggestions about pulse lengths that may be detected
// minimum duration (microseconds) of the start pulse
#define MINSTARTPULSE 4500

// minimum duration (microseconds) of a short bit pulse
#define MINBITPULSE 450

// minimum duration (microseconds) of a HIGH pulse between valid bits
#define MINHITIME 50

// variance between pulses that should have the same duration
#define PULSEVARIANCE 250

// minimum count of data bit pulses following the start pulse
#define MINPULSECOUNT 36

// maximum count of data bit pulses following the start pulse
#define MAXPULSECOUNT 42

// buffer sizes for buffering pulses in the interrupt handler
#define PBSIZE 216
byte bufbin[MAXPULSECOUNT];  // linear buffer storing valid HIGH pulses

const int ledPin =  2;
int ledState = LOW;
unsigned long previousMillis = 0;
const long interval = 1000;

void setup()
{

  pinMode(ledPin, OUTPUT);
  lcd.init();
  lcd.clear();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Start");
  delay(1000);
  lcd.clear();
  pinMode(RX433DATAPIN, INPUT);
  attachInterrupt(RX433INTERRUPT, rx433Handler, CHANGE);
}

volatile unsigned int pulsbuf[PBSIZE]; // ring buffer storing LOW pulse lengths
volatile unsigned int hibuf[PBSIZE]; // ring buffer storing HIGH pulse lengths
unsigned int validpulsbuf[MAXPULSECOUNT]; // linear buffer storing valid LOW pulses
unsigned int validhibuf[MAXPULSECOUNT];  // linear buffer storing valid HIGH pulses

volatile byte pbread, pbwrite; // read and write index into ring buffer

void rx433Handler()
{
  static long rx433LineUp, rx433LineDown;
  long LowVal, HighVal;
  int rx433State = digitalRead(RX433DATAPIN); // current pin state
  if (rx433State) // pin is now HIGH
  {
    rx433LineUp = micros(); // line went HIGH after being LOW at this time
    LowVal = rx433LineUp - rx433LineDown; // calculate the LOW pulse time
    if (LowVal > MINBITPULSE)
    { // store pulse in ring buffer only if duration is longer than MINBITPULSE
      // To be able to store startpulses of more than Maxint duration, we dont't store the actual time,
      // but we store  MINSTARTPULSE+LowVal/10, be sure to calculate back showing the startpulse length!
      if (LowVal > MINSTARTPULSE) LowVal = MINSTARTPULSE + LowVal / 10; // we will store this as unsigned int, so do range checking

      pulsbuf[pbwrite] = LowVal; // store the LOW pulse length
      pbwrite++;  // advance write pointer in ringbuffer
      if (pbwrite >= PBSIZE) pbwrite = 0; // ring buffer is at its end
    }
  }
  else
  {
    rx433LineDown = micros(); // line went LOW after being HIGH
    HighVal = rx433LineDown - rx433LineUp; // calculate the HIGH pulse time
    if (HighVal > 31999) HighVal = 31999; // we will store this as unsigned int
    hibuf[pbwrite] = HighVal; // store the HIGH pulse length
  }
}


boolean counting;
byte i, counter;
int startBitDurationL, startBitDurationH, shortBitDuration, longBitDuration;

void showBuffer()
// this function will show the results on the serial monitor
// output will be shown if more bits than MINPULSECOUNT have been collected
{
  long sum;
  int avg;
  sum = 0;
  byte o;
  if (counter >= MINPULSECOUNT)
  { // only show buffer contents if it has enough bits in it
    for (i = 0; i < counter; i++)
    {
      sum += validpulsbuf[i];
    }

    avg = sum / counter; // calculate the average pulse length
    // then assume that 0-bits are shorter than avg, 1-bits are longer than avg
    for (o = 0; o < 8; o++)
    {
      if (validpulsbuf[o + 20] < avg) bufbin[o] = 0; else bufbin[o] = 1;
    }

    if (counter == 36) //dient nur der Unterscheidung der Funksensoren
    {
      lcd.setCursor(0, 0); //Start at character 0 on line 0
      lcd.setCursor(10, 0);
      lcd.print((startBitDurationL - MINSTARTPULSE) * 10L);
      lcd.setCursor(15, 0);
      lcd.print(startBitDurationH);
    }
    if (counter == 42) //dient nur der Unterscheidung der Funksensoren
    {
      lcd.setCursor(0, 2); //Start at character 0 on line 2
      lcd.setCursor(10, 2);
      lcd.print((startBitDurationL - MINSTARTPULSE) * 10L);
      lcd.setCursor(15, 2);
      lcd.print(startBitDurationH);
    }

  }

  counting = false;
  counter = 0;
}

void loop()
{

  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
    digitalWrite(ledPin, ledState);
  }



  long lowtime, hitime;
  if (pbread != pbwrite) // check for data in ring buffer
  {
    lowtime = pulsbuf[pbread]; // read data from ring buffer
    hitime = hibuf[pbread];
    cli(); // Interrupts off while changing the read pointer for the ringbuffer
    pbread++;
    if (pbread >= PBSIZE) pbread = 0;
    sei(); // Interrupts on again
    if (lowtime > MINSTARTPULSE) // we found a valid startbit!
    {
      if (counting) showBuffer(); // new buffer starts while old is still counting, show it first
      startBitDurationL = lowtime;
      startBitDurationH = hitime;
      counting = true;   // then start collecting bits
      counter = 0;       // no data bits yet
    }
    else if (counting && (counter == 0)) // we now see the first data bit
    { // this may be a 0-bit or a 1-bit, so make some assumption about max/min lengths of data bits that will follow
      shortBitDuration = lowtime / 2;
      if (shortBitDuration < MINBITPULSE + PULSEVARIANCE)
        shortBitDuration = MINBITPULSE;
      else
        shortBitDuration -= PULSEVARIANCE;
      longBitDuration = lowtime * 2 + PULSEVARIANCE;
      validpulsbuf[counter] = lowtime;
      validhibuf[counter] = hitime;
      counter++;
    }
    else if (counting && (lowtime > shortBitDuration) && (lowtime < longBitDuration))
    {
      validpulsbuf[counter] = lowtime;
      validhibuf[counter] = hitime;
      counter++;
      if ((counter == MAXPULSECOUNT) || (hitime < MINHITIME))
      {
        showBuffer();
      }
    }
    else // Low Pulse is too short
    {
      if (counting) showBuffer();
      counting = false;
      counter = 0;
    }
  }
}

Hardware: NodeMCU LoLin
I2C LCD 20*4 angeschlossen an D2, D1
RXB6 als Empfänger an D3

Änderung zum Originalsketch:

Eingangspin von 2 auf D3
Blinkende LED um zu sehen ob der Sketch noch läuft
LCD 20*4 eingebunden
Ausgabe von H und L Bit aus Display
Serial.begin + sämtliche Seriellen Ausgaben entfernt

Wo ist mein (Denk?)fehler? :confused:

Sicher, dass diese Stelle nicht auf RX also Port 0 geht?

// hardware interrupt connected to the pin
// with Arduino UNO interrupt-0 belongs to pin-2, interrupt-1 to pin-3
#define RX433INTERRUPT 0

Die Pins des UNO und des NodeMCU unterscheiden sich. Auch solltest Du aufpassen, welche PINs Du verwendest, die schon vom ESP8266 genutzt werden. Da kann man sich hervorragend in die Nesseln setzen.