Как исправить 'I2C-связь между 2-мя микроконтроллерами, заинтервированными инттеруптом' - PullRequest
0 голосов
/ 10 мая 2019

Я делаю диммер с моим Arduino Nano, значения этого значения в диапазоне 0-128 от контроллера ESP8266 через I2C.Это нормально работает на нано, пока прерывание (обнаружение пересечения нуля) не прервет это.

Я попытался затемнить с помощью потенциометра, и это работало отлично, я попытался сделать это без intterupt (в последовательном мониторе), это сработало правильно.Я также попытался заменить прерывания и noInterrupts на sei () и cli () безрезультатно.Иногда я иногда работаю, но потом это выглядит так.

63
64
65
66
67
-1
69
-1
72
-1
74

После этого он перестает работать.

Ниже приведен мой код для устройства ESP8266 (Это временный тесткод).Это только отправляет значения в нано.

#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.

#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();
}

Результаты, которые я должен получить от нано, должнывыглядеть так

63
64
65
66
67
68
69
70
71
72
73
74

1 Ответ

0 голосов
/ 13 мая 2019

Проблема заключалась в том, что обработчик прерываний был занят слишком долго, что прервало обработку приема 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();
}

Спасибо всем, кто помог мне с этой проблемой!

...