交流调光器EpS32

时间:2019-07-15 20:41:42

标签: arduino esp32

我有一个应用程序,可以从温度传感器读取的温度来控制ESP32调光器。规则很简单,当我的传感器读取的温度超过27ºC时,调光器应关闭灯。但是,这没有发生。

该代码的作用是,当系统打开时,灯泡会打开,并且会不时读取温度,但是当温度超过27ºC时,调光器不会关闭灯泡。我认为在zero_crosss_int例程中可能是我做错了,因为当温度达到其极限时,将显示“ TRIAC OFF”消息。

在使用的代码下面。

#define     ZERO_CROSS          2
#define     DIMMER_CONTROL      4

int dimming=64;
float programedTemp = 27.0;
int halfDimming=128;
int maxDimming=64;


void power(void *parameters){
    tempSensor.requestTemperaturesByIndex(0);
    temp=tempSensor.getTempCByIndex(0);
    if(temp<programedTemp){
        dimming=maxDimming;
        if(temp<(programedTemp-1.0)){
            dimming=maxDimming;
        } else if(temp<programedTemp){
            dimming++;
        }
    } else if(temp>programedTemp+0.9){
        dimming=128;
    }else{
        dimming=halfDimming;
    }
    delay(4000);
}


void zero_crosss_int() {
    if(dimming>=128){
      delayMicroseconds(8.333);
      digitalWrite(DIMMER_CONTROL, LOW);    // triac Off
      Serial.println((String) "=====>>> TRIAC OFF <<<=====");
    }else{
        int dimtime = (65*dimming);
        delayMicroseconds(dimtime);    // Off cycle
        digitalWrite(DIMMER_CONTROL, HIGH);   // triac firing
        delayMicroseconds(8.333);
        digitalWrite(DIMMER_CONTROL, LOW);    // triac Off
    }
}

void setup() {
  pinMode(DIMMER_CONTROL, OUTPUT);
  pinMode(ZERO_CROSS, INPUT);
  attachInterrupt(ZERO_CROSS, zero_crosss_int, RISING);
  Serial.begin(115200);
  xTaskCreatePinnedToCore(power,"controlDimm",10000,NULL,0,&mainsPower,0);
}

void loop() {

}

2 个答案:

答案 0 :(得分:0)

您在中断处理程序中做的太多了。令人惊讶的是,它不仅持续崩溃,而且没有发生的唯一原因很可能是因为您在loop()中没有执行任何操作。

在中断处理程序中调用大多数正在调用的函数并不安全。中断处理程序需要运行的时间尽可能短-其他中断可能会被锁定,并且可能会干扰网络堆栈和其他内部管理功能。您绝对不应该在中断处理程序中调用delayMicroseconds()或任何Serial方法,或在该处花费比绝对必要更多的时间。几乎所有ESP-IDF或Arduino Core函数都不安全地从中断处理程序中调用-中断处理程序可能会在状态不一致时中断对它们的另一个调用,或者可能在中间状态更改硬件设置使用该硬件。

如果您将代码结构化为这样,您的代码会更好:

volatile bool zero_crossing_flag = false;

void IRAM_ATTR zero_cross_int() {
  zero_crossing_flag = true;
}

void loop() {
  if(zero_crossing_flag) {
    zero_crossing_flag = false;

    if(dimming>=128){
      delayMicroseconds(8.333);
      digitalWrite(DIMMER_CONTROL, LOW);    // triac Off
      Serial.println((String) "=====>>> TRIAC OFF <<<=====");
    }else{
        int dimtime = (65*dimming);
        delayMicroseconds(dimtime);    // Off cycle
        digitalWrite(DIMMER_CONTROL, HIGH);   // triac firing
        delayMicroseconds(8.333);
        digitalWrite(DIMMER_CONTROL, LOW);    // triac Off
    }
  }
}

IRAM_ATTR上的zero_cross_int()属性告诉编译器该代码必须始终可用。如果您编写的中断处理程序不带IRAM_ATTR,那么它可以正确执行基本上是幸运的。

以这种方式重组代码可能无法解决您所要解决的问题,但可以使它以稳定,可重复的方式运行,这与现在编写的方式不太可能。

答案 1 :(得分:0)

使用您的ZCD输入生成中断。在ISR中,启动一个计时器,该计时器会在ZCD中断的0ms(全功率)到10ms(完全关闭)之间生成另一​​个中断。

我不明白要关掉灯,为什么要用TRIAC代替继电器。