如何修复 'I2C communication between 2 microcontrollers intterupted by an intterupt'
How to fix 'I2C communication between 2 microcontrollers intterupted by an intterupt'
我正在用我的 Arduino Nano 制作调光器,它通过 I2C 从 ESP8266 控制器获取 0-128 之间的值。这在 nano 上工作正常,直到中断(零交叉检测)中断它。
我试过用电位器调光,效果很好,我试过在没有中断的情况下(在串行监视器中),效果很好。我也尝试用 sei() 和 cli() 替换中断和 noInterrupts 但没有结果。我有时确实让它工作了一会儿,但后来看起来像这样。
63
64
65
66
67
-1
69
-1
72
-1
74
之后它停止工作。
下面是我的ESP8266设备代码(这是临时测试代码)。这只会将值发送到 nano。
#include <Wire.h>
void setup() {
Wire.begin();
}
void loop() {
for (int dimValue = 0; dimValue <= 128; dimValue++)
{
delay(50);
Wire.beginTransmission(8);
Wire.write(dimValue);
Wire.endTransmission();
}
}
下面是负责通过 I2C 调光和接收命令的 Nano 的代码。
#include <Wire.h>
int AC_LOAD = 8; // Output to Opto Triac pin
int dimming = 128; // Dimming level (0-128) 0 = ON, 128 = OFF
int zeroCross = 3; // zerocross pin
void setup()
{
pinMode(AC_LOAD, OUTPUT);// Set AC Load pin as output
attachInterrupt(digitalPinToInterrupt(3), zero_crosss_int, RISING);
Serial.begin(115200);
Wire.begin(8);
Wire.onReceive(receiveEvent);
}
void zero_crosss_int() //function to be fired at the zero crossing to dim the light
{
int dimtime = (75 * dimming); // For 60Hz =>65
delayMicroseconds(dimtime); // Wait till firing the TRIAC
digitalWrite(AC_LOAD, HIGH); // Fire the TRIAC
delayMicroseconds(10); // triac On propogation delay
// (for 60Hz use 8.33) Some Triacs need a longer period
digitalWrite(AC_LOAD, LOW); // No longer trigger the TRIAC (the next zero crossing will swith it off) TRIAC
}
void loop()
{
}
void receiveEvent() {
noInterrupts();
int x = Wire.read();
dimming = x;
Serial.println(x);
interrupts();
}
我应该从 nano 得到的结果应该是这样的
63
64
65
66
67
68
69
70
71
72
73
74
问题是中断处理程序忙了太久,中断了 I2C 接收处理,导致溢出。现在,通过将中断中的代码放入 loop()
.
中,它可以完全正常工作
#include <Wire.h>
int AC_LOAD = 9; // Output to Opto Triac pin
int dimming = 128; // Dimming level (0-128) 0 = ON, 128 = OFF
int zeroCross = 3; // zerocross pin
boolean triacFire = false;
void setup()
{
pinMode(AC_LOAD, OUTPUT);// Set AC Load pin as output
attachInterrupt(digitalPinToInterrupt(zeroCross), zero_crosss_int, RISING);
Serial.begin(115200);
Wire.begin(8); // join i2c bus with address #8
Wire.onReceive(receiveEvent); // register event
}
void zero_crosss_int() //function to be fired at the zero crossing to dim the light
{
triacFire = true;
}
void loop()
{
if (triacFire == true)
{
int dimtime = (75 * dimming); // For 60Hz =>65
delayMicroseconds(dimtime); // Wait till firing the TRIAC
digitalWrite(AC_LOAD, HIGH); // Fire the TRIAC
delayMicroseconds(10); // triac On propogation delay
// (for 60Hz use 8.33) Some Triacs need a longer period
digitalWrite(AC_LOAD, LOW); // No longer trigger the TRIAC (the next zero crossing will swith it off) TRIAC
triacFire = false;
}
}
void receiveEvent() {
noInterrupts();
byte x = Wire.read(); // receive byte as an byte
dimming = x;
Serial.println(x);
interrupts();
}
谢谢大家帮我解决这个问题!
我正在用我的 Arduino Nano 制作调光器,它通过 I2C 从 ESP8266 控制器获取 0-128 之间的值。这在 nano 上工作正常,直到中断(零交叉检测)中断它。
我试过用电位器调光,效果很好,我试过在没有中断的情况下(在串行监视器中),效果很好。我也尝试用 sei() 和 cli() 替换中断和 noInterrupts 但没有结果。我有时确实让它工作了一会儿,但后来看起来像这样。
63
64
65
66
67
-1
69
-1
72
-1
74
之后它停止工作。
下面是我的ESP8266设备代码(这是临时测试代码)。这只会将值发送到 nano。
#include <Wire.h>
void setup() {
Wire.begin();
}
void loop() {
for (int dimValue = 0; dimValue <= 128; dimValue++)
{
delay(50);
Wire.beginTransmission(8);
Wire.write(dimValue);
Wire.endTransmission();
}
}
下面是负责通过 I2C 调光和接收命令的 Nano 的代码。
#include <Wire.h>
int AC_LOAD = 8; // Output to Opto Triac pin
int dimming = 128; // Dimming level (0-128) 0 = ON, 128 = OFF
int zeroCross = 3; // zerocross pin
void setup()
{
pinMode(AC_LOAD, OUTPUT);// Set AC Load pin as output
attachInterrupt(digitalPinToInterrupt(3), zero_crosss_int, RISING);
Serial.begin(115200);
Wire.begin(8);
Wire.onReceive(receiveEvent);
}
void zero_crosss_int() //function to be fired at the zero crossing to dim the light
{
int dimtime = (75 * dimming); // For 60Hz =>65
delayMicroseconds(dimtime); // Wait till firing the TRIAC
digitalWrite(AC_LOAD, HIGH); // Fire the TRIAC
delayMicroseconds(10); // triac On propogation delay
// (for 60Hz use 8.33) Some Triacs need a longer period
digitalWrite(AC_LOAD, LOW); // No longer trigger the TRIAC (the next zero crossing will swith it off) TRIAC
}
void loop()
{
}
void receiveEvent() {
noInterrupts();
int x = Wire.read();
dimming = x;
Serial.println(x);
interrupts();
}
我应该从 nano 得到的结果应该是这样的
63
64
65
66
67
68
69
70
71
72
73
74
问题是中断处理程序忙了太久,中断了 I2C 接收处理,导致溢出。现在,通过将中断中的代码放入 loop()
.
#include <Wire.h>
int AC_LOAD = 9; // Output to Opto Triac pin
int dimming = 128; // Dimming level (0-128) 0 = ON, 128 = OFF
int zeroCross = 3; // zerocross pin
boolean triacFire = false;
void setup()
{
pinMode(AC_LOAD, OUTPUT);// Set AC Load pin as output
attachInterrupt(digitalPinToInterrupt(zeroCross), zero_crosss_int, RISING);
Serial.begin(115200);
Wire.begin(8); // join i2c bus with address #8
Wire.onReceive(receiveEvent); // register event
}
void zero_crosss_int() //function to be fired at the zero crossing to dim the light
{
triacFire = true;
}
void loop()
{
if (triacFire == true)
{
int dimtime = (75 * dimming); // For 60Hz =>65
delayMicroseconds(dimtime); // Wait till firing the TRIAC
digitalWrite(AC_LOAD, HIGH); // Fire the TRIAC
delayMicroseconds(10); // triac On propogation delay
// (for 60Hz use 8.33) Some Triacs need a longer period
digitalWrite(AC_LOAD, LOW); // No longer trigger the TRIAC (the next zero crossing will swith it off) TRIAC
triacFire = false;
}
}
void receiveEvent() {
noInterrupts();
byte x = Wire.read(); // receive byte as an byte
dimming = x;
Serial.println(x);
interrupts();
}
谢谢大家帮我解决这个问题!