Изменение значений таймера с помощью I2C

Я хотел бы изменить значения «LED_T_ON» с помощью устройства с поддержкой I2C (например, RPi)

Код для ведомого устройства Arduino Mega:

//ведомый

#include <Wire.h>

#define SLAVE_ADDRESS 0x08


const int PWR_LED = 43;
int LED_TinH_ON = 18;
int LED_T_ON = 5000;
int LED_T_OFF = 5000;


String inString = "";    // строка для хранения ввода
byte LastMasterCommand = 0;
int Mval;

char user_input;

class Relay {
  int relayPin;
  long OnTime;     // миллисекунды включения
  long OffTime;    // миллисекунды времени выключения

  // Они поддерживают текущее состояние
  int relayState;                 // pumpState используется для установки PUMP
  unsigned long previousMillis;   // сохранит время последнего обновления PUMP

  // Конструктор — создает таймер и инициализирует переменные-члены и состояние
  public:
  Relay(int pin, long on, long off)
  {
    relayPin = pin;
    pinMode(relayPin, OUTPUT);     

    OnTime = on;
    OffTime = off;

    relayState = LOW; 
    previousMillis = 0;  //ИЗНАЧАЛЬНО 0
  }

  void Update()
  {
    // проверяем, пришло ли время изменить состояние ТАЙМЕРА
    unsigned long currentMillis = millis();

    if((relayState == HIGH) && (currentMillis - previousMillis >= OnTime))
    {
      relayState = LOW;  // Выключить
      previousMillis = currentMillis;  // Запомнить время
      digitalWrite(relayPin, relayState);  // Обновляем реальный светодиод
    }
    else if ((relayState == LOW) && (currentMillis - previousMillis >= OffTime))
    {
      relayState = HIGH;  // включаем
      previousMillis = currentMillis;   // Запомнить время
      digitalWrite(relayPin, relayState);   // Обновить фактическое РЕЛЕ
    }
  }
};

Relay relay3(PWR_LED, LED_T_OFF, LED_T_ON);

void setup() {
 // инициализируем последовательную связь с компьютером:
  Serial.begin(9600);

  Wire.begin(SLAVE_ADDRESS);

  Wire.onReceive(receiveData);
  Wire.onRequest(slavesRespond);

  pinMode(PWR_LED, OUTPUT);
}


void loop() {
  delay(1000);

  Serial.print("LED_T_ON=");
  Serial.println(LED_T_ON);
  Serial.print("LED_T_OFF=");
  Serial.println(LED_T_OFF);
  Serial.println();

  relay3.Update();

  switch (Mval) {
    case 1 ... 25:
      LED_TinH_ON = Mval;
      Serial.print("LED time on: ");
      Serial.print(LED_TinH_ON);
      Serial.println("h");
      LED_T_ON = LED_TinH_ON*1000;//*60*60;
      LED_T_OFF = (24-LED_TinH_ON)*1000;//*60*60;
    break;
  }
}


void receiveData(int byteCount) {
  LastMasterCommand = Wire.read();
  while (Wire.available()) {
    int msg = Wire.read();

    if (isDigit(msg)) {
      inString += (char)msg;
    }
  }
  Mval = inString.toInt();
  //Serial.println(LastMasterCommand);
  inString = "";
  //Serial.println(Mval);
}

void slavesRespond() {
}

Когда я изменяю значение на RPi, Arduino получает и отображает правильное значение, но реле с таймером фактически не используют обновленные значения.

Я что-то упускаю?

, 👍0

Обсуждение

Я не вижу там ничего, что связано с I2C. О каком «отображении правильного значения» может идти речь, если ни устройство ни получает значение, ни устройство ничего никуда не отображает?, @Majenko

То же самое. LED_T_ON нигде не меняется (как и OnTime)., @Nick Gammon

Моя ошибка, отредактировал, чтобы отобразить правильный код, @Yousef Abdelsalam

Предположим, у вас есть другой код, обрабатывающий бит I2C. Если этот код изменяет значение LED_T_ON, это не повлияет на объект реле, поскольку это значение передаётся во время построения. Вам потребуется обновить relay3.OnTime (ваш порядок/название также меняется, relay3(PWR_LED, LED_T_OFF, LED_T_ON); вызывает Relay(int pin, long on, long off)., @Chad G


1 ответ


Лучший ответ:

2

Вы обновляете LED_T_ON и LED_T_OFF, но эти значения уже были переданы в конструктор, и их изменение не изменит объект. Вам нужно обновить relay3.OnTime и relay3.OffTime

,