Problem mit Interrupt

Mehr
01 Mär 2020 11:05 #640 von Jo
Jo erstellte das Thema Problem mit Interrupt
Hallo allerseits
Habe ein hartnäckiges Problem mit einem Interrupt. Folgender Code läuft auf einer ESP8266
NodeMCU:
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// Wifi Connection
const char* ssid = "xxx";
const char* password = "xxx";

// MQTT Server address
const int mqtt_port = 1983;
const char* mqtt_server = "192.168.178.xx";
//Topics
const char* gate_topic = "Garage/Gate";

const int interruptGate = D7;//D7

WiFiClient espClient;
PubSubClient client(espClient);

void setup() {
  Serial.begin(9600);
  setup_wifi();
  client.setServer(mqtt_server, mqtt_port);
  client.setCallback(callback);
  //Gate In/Out
  pinMode(interruptGate, INPUT_PULLUP);
  //digitalWrite(interruptGate, HIGH);
  attachInterrupt(digitalPinToInterrupt(interruptGate), handleInterruptGate, CHANGE);
}

void setup_wifi() {
  delay(2);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
  //Car In
  if (strcmp(topic, gate_topic) == 0) {
   Serial.print("Message arrived\ntopic = ");
   Serial.print(topic);
   Serial.print(" - ");
    String spayload = "";
    for (int i = 0; i < length; i++) {
      spayload = spayload + (char)payload[i];
    }
    Serial.print("payload = " + spayload + "\n");
  }
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("Combi_Switch")) {
      Serial.println("connected");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

ICACHE_RAM_ATTR void handleInterruptGate() {
  static unsigned long last_interrupt_time = 0;
  unsigned long interrupt_time = millis();
  if (interrupt_time - last_interrupt_time > 20)
  {
    int dr = digitalRead(interruptGate); <--- Das funktioniert nicht zuverlässig!
    if(dr == LOW) {
      client.publish(gate_topic, "true", true);
    } else {
      client.publish(gate_topic, "false", true);
    }
    last_interrupt_time = interrupt_time;
  }
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
}

Der Interrupt an sich läuft zuverlässig auf "CHANGE", doch bei der Abfrage des momentanen Zustandes vom Eingang
"interruptGate" (in der ISR-Routine) erhält die Variable dr nicht immer den richtigen Wert.
Alle Hardwareteile sind geprüft und nicht defekt. Habe das auch mit externen Pullup-Widerständen getestet, von
10K runter auf 680R - keine Besserung.
Mit der Debounce-Time habe ich auch variiert, der Wert 20 reicht völlig,
Habe viele Varianten getestet, doch nichts war wirklich zuverlässig.
Was stimmt hier nicht?

Freundliche Grüße
Jo

Bitte Anmelden oder Registrieren um der Konversation beizutreten.

Powered by Kunena Forum