Hallo Zusammen!
Ich stehe vor einem kleinen Problem.
Ich möchte Stromzähler auslesen, automatisch wahlweise über die S0 LED oder über die optische D0 Schnittstelle.
Einfache erkennung: kommen die Impulse zu schnell muss es die D0 Schnittstelle sein. Ich starte mit S0 per Interrupt.
Ist der Impulsabstand < 1000ms wird der Interrupt detached und mit Serial.begin(9600) die Serielle Verbindung gestartet. Kommen da länger als 12 sec. keine Daten mehr wird die serielle Verbindung beendet "Serial.end();" und der Interrupt wieder attached. Leider löst der Interrupt dann aber nicht mehr aus. Hat da jemand Erfahrungen mit oder Infos darüber?
Burkhard
Hier noch der Codeauszug:
#define Sensor 3 // RX pin connected to phototransistor
volatile unsigned long EventMicros = 0; //< Zeitstempel des letzten Impulses
volatile unsigned long lastEventMicros = 0; //< Zeitstempel des vorherigen Impulses
unsigned long lastSerial; // last serial receive from powermeter
volatile double S0Energy = 0;
bool UseS0=true;
unsigned long Impulsabstand = 0; //< Differenz aus den obigen Werten
int NumIncommingBytes=0;
byte IncommingByte[200];
void IRAM_ATTR S0_Interrupt1();
void setup(void)
{
pinMode (Sensor,INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(Sensor), S0_Interrupt1, FALLING);
}
void loop(void)
{
if (!UseS0 && millis() - lastSerial > 50000) //switch back to S0
{
Serial.end();
lastEventMicros=0; // set to maximum distance
attachInterrupt(digitalPinToInterrupt(Sensor), S0_Interrupt1, FALLING);
UseS0=true;
}
if (lastEventMicros < EventMicros) // hat es einen neuen Impuls gegeben?
{
Impulsabstand = EventMicros - lastEventMicros;
if (Impulsabstand < 1000 && lastEventMicros!=0) // to fast, switch to D0 seriell
{
UseS0=false;
detachInterrupt(digitalPinToInterrupt(Sensor));
lastSerial = millis(); // remember when we start seriell
Serial.begin(9600);
}
else
{
// calculate the power
}
}
NumIncommingBytes=Serial.available();
if (NumIncommingBytes&&!UseS0)
{
for(int i=0;i<NumIncommingBytes+1;i++)
{
IncommingByte[i]=Serial.read();
}
}
// code for display here
}
void IRAM_ATTR S0_Interrupt1()
{
lastEventMicros = EventMicros; // vorherigen Timestamp speichern
EventMicros = micros(); // neuen Timestamp setzten
S0Energy+=0.1;
}