MegaLight - контроллер освещения на Arduino Mega 2560+W5100

Подключение исполнительных устройств, датчиков, контроллеров.

Модератор: immortal

Yashalta
Сообщения: 315
Зарегистрирован: Вс май 20, 2018 9:27 am
Благодарил (а): 160 раз
Поблагодарили: 29 раз

Re: MegaLight - контроллер освещения на Arduino Mega 2560+W5100

Сообщение Yashalta » Ср янв 23, 2019 9:51 pm

gnom537 писал(а):
Ср янв 23, 2019 8:17 pm
тоже долго искал причину, много перепробовал и резисторы и конденсаторы и прочее! все оказалось очень просто....

в коде в блоке setup сделайте задержку delay! у меня 10 секунд стоит. шилд не успевает загрузиться! поле ввода задержки все четко работает.


void setup()
{
Serial.begin(57600);
delay (10000); // вот это задержка

#ifndef NO_PWM_LIB
InitTimersSafe();
#endif
Ниже код без изменений файла Setup поправьте его с учетом ваших замечаний. Я пробовал но, после моих изменений выскакивают ошибки при проверке...

Код: Выделить всё

#include <avr/wdt.h>

Scheduler runner;

Task t1(1, TASK_FOREVER, &buttonLoop, &runner);
Task t2(1, TASK_FOREVER, &relayLoop, &runner);
Task t3(1, TASK_FOREVER, &externalLoop, &runner);
Task t4(1, TASK_FOREVER, &webLoop, &runner);

void buttonLoop() {
  inputList.check();
  inputEM.processAllEvents();
}

void relayLoop() {
  outputEM.processAllEvents();
  outputList.check();
}

#define WBSIZE 1024
void webLoop()
{
  char webBuffer[WBSIZE];
  int buflen = WBSIZE;
  webserver.processConnection(webBuffer, &buflen);
}

void externalLoop()
{
  externalEM.processEvent();
}


bool loadConfig() {
  const uint8_t CONFIG_LINE_LENGTH = 127;
  // The open configuration file.
  SDConfigFile cfg;

  // Open the configuration file.
  if (!cfg.begin(CONFIG_FILE, CONFIG_LINE_LENGTH)) {
    Serialprint("Failed to open configuration file: %s\r\n", CONFIG_FILE);
    return false;
  }

  // Read each setting from the file.
  while (cfg.readNextSetting()) {

    if (cfg.nameIs("mac")) {
      parseBytes(cfg.getValue(), '-', mac, 6, 16);
      Serial.print("MAC="); Serial.println(cfg.getValue());

    } else if (cfg.nameIs("ip")) {
      parseBytes(cfg.getValue(), '.', ip, 4, 10);

    } else if (cfg.nameIs("mdHost")) {
      mdHost = cfg.getValue();

    } else if (cfg.nameIs("mdPort")) {
      mdPort = cfg.getIntValue();

    } else if (cfg.nameIs("mdAuth")) {
      mdAuth = cfg.getValue();
    }
  }

  // clean up
  cfg.end();
  return true;
}

bool setupSD() {
  if (!SD.begin(4)) {
    Serialprint("SD unavailable. Trying to load config from EEPROM.\r\n");
    return false;
  }
  Serialprint("SD initialization done.\r\n");
  return true;
}


void setupTasks()
{
  t1.enable();
  t2.enable();
  t3.enable();
  t4.enable();

  runner.init();

  runner.addTask(t1);
  runner.addTask(t2);
  runner.addTask(t3);
  runner.addTask(t4);
}

int setupInputsSD() {
  const uint8_t CONFIG_LINE_LENGTH = 127;

  String configDir = F("/INPUTS");
  File dir = SD.open(configDir);
  if (!dir.isDirectory())
    return 0;

  inputList.clearInputs();
  storageHeader.cntInputs = 0;
  int sz = 0;

  SDConfigFile cfg;

  while (true) {
    File inp = dir.openNextFile();
    if (!inp)
      break;

    if (inp.isDirectory())
    {
      inp.close();
      continue;
    }

    const char *id = inp.name();
    inp.close();

    ML2Input *b = new ML2Input(id);

    // The open configuration file.
    if (!cfg.begin(String(configDir + "/" + String(id)).c_str(), CONFIG_LINE_LENGTH)) {
      Serialprint("Failed to open input file: %s\r\n", id);
      delete b;
      cfg.end();
      continue;
    }


    // Read each setting from the file.
    while (cfg.readNextSetting()) {

      if (cfg.nameIs("pin")) {
        b->setPin(cfg.getIntValue());

      } else if (cfg.nameIs("pullup")) {
        const char *pu = cfg.getValue();
        if (!strcmp(pu, "intup"))
          b->setPullup(InputPullup::IntPullup);
        else if (!strcmp(pu, "extup"))
          b->setPullup(InputPullup::ExtPullup);
        else if (!strcmp(pu, "extdown"))
          b->setPullup(InputPullup::PullDown);

      } else if (cfg.nameIs("bounceint")) {
        b->setBounceInterval(cfg.getIntValue());

      } else if (cfg.nameIs("holdint")) {
        b->setHoldInterval(cfg.getIntValue());

      } else if (cfg.nameIs("repeat")) {
        b->setRepeat(cfg.getBooleanValue());

      } else if (cfg.nameIs("repeatint")) {
        b->setRepeatInterval(cfg.getIntValue());

      } else if (cfg.nameIs("dclickint")) {
        b->setDoubleClickInterval(cfg.getIntValue());

      } else if (cfg.nameIs("prevclick")) {
        b->setPreventClick(cfg.getBooleanValue());

      }
    }

    // clean up
    cfg.end();

    if (!inputList.addInput(b))
    {
      Serialprint("Failed to add input %s\r\n", id);
      delete b;
    }
    else
    {
      Serialprint("Added input %s on pin %d\r\n", id, b->pin());
      sz += saveInputEEPROM(b, storageHeader.addrInputs + sz);
      storageHeader.cntInputs++;
    }
  }

  dir.close();

  return sz;
}

int setupOutputsSD() {
  const uint8_t CONFIG_LINE_LENGTH = 127;

  String configDir = F("/OUTPUTS");
  File dir = SD.open(configDir);
  if (!dir.isDirectory())
    return 0;

  outputList.clearOutputs();
  storageHeader.cntOutputs = 0;
  int sz = 0;

  SDConfigFile cfg;

  while (true) {
    File inp = dir.openNextFile();
    if (!inp)
      break;

    if (inp.isDirectory())
    {
      inp.close();
      continue;
    }

    const char *id = inp.name();
    inp.close();

    ML2Output *b = new ML2Output(id);

    // The open configuration file.
    if (!cfg.begin(String(configDir + "/" + String(id)).c_str(), CONFIG_LINE_LENGTH)) {
      Serialprint("Failed to open output file: %s\r\n", id);
      delete b;
      cfg.end();
      continue;
    }


    // Read each setting from the file.
    while (cfg.readNextSetting()) {

      if (cfg.nameIs("pin")) {
        b->setPin(cfg.getIntValue());

      } else if (cfg.nameIs("pwm")) {
        b->setPWM(cfg.getBooleanValue());

      } else if (cfg.nameIs("invert")) {
        b->setInvert(cfg.getBooleanValue());

      } else if (cfg.nameIs("noreport")) {
        b->setNoreport(cfg.getBooleanValue());

      } else if (cfg.nameIs("on")) {
        cfg.getBooleanValue() ? b->setOn() : b->setOff();

      } else if (cfg.nameIs("value")) {
        b->setValue(cfg.getIntValue());

      } else if (cfg.nameIs("save")) {
        const char *pu = cfg.getValue();
        if (!strcmp(pu, "state"))
          b->setSaveState(OutputStateSave::State);
        else if (!strcmp(pu, "value"))
          b->setSaveState(OutputStateSave::Value);
        else if (!strcmp(pu, "both"))
          b->setSaveState(OutputStateSave::StateAndValue);

      }
    }

    // clean up
    cfg.end();

    if (!outputList.addOutput(b))
    {
      Serialprint("Failed to add output %s\r\n", id);
      delete b;
    }
    else
    {
      Serialprint("Added output %s on pin %d\r\n", id, b->pin());
      sz += saveOutputEEPROM(b, storageHeader.addrOutputs + sz);
      storageHeader.cntOutputs++;
    }
  }

  dir.close();
  return sz;
}


int loadRulesFromFile(File &dir, String path) {
  int sz = 0;
  while (true) {

    File entry =  dir.openNextFile();
    if (! entry) {
      // no more files
      break;
    }

    String npath = path + String("/") + entry.name();
    if (entry.isDirectory()) {
      sz += loadRulesFromFile(entry, npath);
      entry.close();
      continue;
    }
    entry.close();

    ML2Rule *rule = ML2Rule::fromFile(npath);
    if (rule) {
      int s = saveRuleEEPROM(rule, storageHeader.addrRules);
      sz += s;
      storageHeader.addrRules += s;
      storageHeader.cntRules++;
      delete rule;
      Serialprint("Loaded rule: %s\r\n", npath.c_str());
    }
  }
  return sz;
}

int setupRulesSD() {
  storageHeader.cntRules = 0;

  File root = SD.open(RULES_PATH);
  if (root) {
    return loadRulesFromFile(root, "");
  }
}

bool loadAllFromEEPROM() {
  int addr = CONFIG_START;
  int sz = loadConfigEEPROM(addr);
  if (!sz)
    return false;

  addr += sz;
  sz = loadHeaderEEPROM(addr);
  addr += sz;

  for (int i = 0; i < storageHeader.cntInputs; i++) {
    ML2Input *input = new ML2Input("");
    sz = loadInputEEPROM(input, addr);
    if (inputList.addInput(input))
      Serialprint("Added input %s on pin %d\r\n", input->ID, input->pin());

    addr += sz;
  }

  for (int i = 0; i < storageHeader.cntOutputs; i++) {
    ML2Output *output = new ML2Output("");
    sz = loadOutputEEPROM(output, addr);
    if (outputList.addOutput(output))
      Serialprint("Added output %s on pin %d\r\n", output->ID, output->pin());

    addr += sz;
  }

  for (int i = 0; i < storageHeader.cntRules; i++) {
    ML2Rule *rule = new ML2Rule("");
    sz = loadRuleEEPROM(rule, addr, true);
    Serialprint("Added rule %s\r\n", rule->ID.c_str());
    addr += sz;
    delete rule;
  }

  return true;
}

int setupConfigSD() {
  const uint8_t CONFIG_LINE_LENGTH = 127;
  SDConfigFile cfg;

  if (!cfg.begin(CONFIG_FILE, CONFIG_LINE_LENGTH)) {
    Serialprint("Failed to open configuration file: %s\r\n", CONFIG_FILE);
    return 0;
  }

  while (cfg.readNextSetting()) {
    if (cfg.nameIs("mac")) {
      parseBytes(cfg.getValue(), '-', mac, 6, 16);
      Serial.print("MAC="); Serial.println(cfg.getValue());

    } else if (cfg.nameIs("ip")) {
      parseBytes(cfg.getValue(), '.', ip, 4, 10);

    } else if (cfg.nameIs("mdHost")) {
      mdHost = cfg.getValue();

    } else if (cfg.nameIs("mdPort")) {
      mdPort = cfg.getIntValue();

    } else if (cfg.nameIs("mdAuth")) {
      mdAuth = cfg.getValue();
    }
  }

  // clean up
  cfg.end();

  return saveConfigEEPROM(CONFIG_START, false);
}

void saveAllToEEPROM() {
  int sz = setupConfigSD();
  if (!sz) {
    Serialprint("Failed to store config\r\n");
    return;
  }

  int addr = CONFIG_START + sz;
  int addrHeader = addr;
  addr += sizeof(storageHeader);

  storageHeader.addrInputs = addr;
  sz = setupInputsSD();
  addr += sz;
  Serialprint("Stored %d inputs (%d bytes)\r\n\r\n", storageHeader.cntInputs, sz);

  storageHeader.addrOutputs = addr;
  sz = setupOutputsSD();
  addr += sz;
  Serialprint("Stored %d outputs (%d bytes)\r\n\r\n", storageHeader.cntOutputs, sz);

  storageHeader.addrRules = addr;
  sz = setupRulesSD();
  addr += sz;
  Serialprint("Stored %d rules (%d bytes)\r\n\r\n", storageHeader.cntRules, sz);

  saveHeaderEEPROM(addrHeader);
  saveConfigEEPROM(CONFIG_START, true);

  Serialprint("Stored config to EEPROM (%d bytes)\r\n\r\n", addr - CONFIG_START);
}


int freeRam () {
  extern int __heap_start, *__brkval;
  int v;
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}

void setup() {

  wdt_disable();

  Serial.begin(115200);
  Serialprint("Starting...\r\n");

  if (setupSD()) {
    saveAllToEEPROM();
  } else {
    loadAllFromEEPROM();
  }

  setupWeb();
  setupEMs();
  setupTasks();

  Serialprint("Started (free RAM: %d)\r\n", freeRam());

  wdt_enable(WDTO_4S);
}

void loop() {
  wdt_reset();
  runner.execute();
}

void reset() {
  wdt_enable(WDTO_1S);
  while (1);
}
condor77
Сообщения: 36
Зарегистрирован: Пн окт 30, 2017 9:54 am
Благодарил (а): 8 раз
Поблагодарили: 2 раза

Re: MegaLight - контроллер освещения на Arduino Mega 2560+W5100

Сообщение condor77 » Пт янв 25, 2019 10:21 am

Походу вопрос прошёл не замеченным. Повторю.
condor77 писал(а):
Пн янв 21, 2019 2:50 pm
Добрый день. А подскажите где можно поменять порт чтоб устройство принимало get запросы по стандартному 80-му порту, а отправляло по какому -то другому? У меня первая версия контроллера. Я пробовал менять в файле MegaLight.ino скетча в блоке MajorDomo config. Контроллер вроде бы начал передавать запросы на указанном порту и даже не перестал принимать их на стандартном 80-м. Но при этом он занимает этот указанный порт и когда я пытаюсь на сервере скриптом поднять сервер для прослушивания порта он ругается на занятость последнего. Что я не так делаю?
olehs
Сообщения: 1115
Зарегистрирован: Вс июн 14, 2015 11:08 am
Благодарил (а): 85 раз
Поблагодарили: 342 раза

Re: MegaLight - контроллер освещения на Arduino Mega 2560+W5100

Сообщение olehs » Пт янв 25, 2019 11:35 am

condor77 писал(а):
Пт янв 25, 2019 10:21 am
Походу вопрос прошёл не замеченным. Повторю.
condor77 писал(а):
Пн янв 21, 2019 2:50 pm
Добрый день. А подскажите где можно поменять порт чтоб устройство принимало get запросы по стандартному 80-му порту, а отправляло по какому -то другому? У меня первая версия контроллера. Я пробовал менять в файле MegaLight.ino скетча в блоке MajorDomo config. Контроллер вроде бы начал передавать запросы на указанном порту и даже не перестал принимать их на стандартном 80-м. Но при этом он занимает этот указанный порт и когда я пытаюсь на сервере скриптом поднять сервер для прослушивания порта он ругается на занятость последнего. Что я не так делаю?
В MegaLight Вы все правильно сделали, потому и не стал отвечать, надеясь, что с проблемой на сервере сами разберетесь ))
Что занимает порты на сервере - только вам известно, т.к. "он" (контроллер) физически ничего не может занимать на другом устройстве.
gnom537
Сообщения: 111
Зарегистрирован: Вт июн 17, 2014 1:06 pm
Откуда: нижний новгород
Благодарил (а): 5 раз
Поблагодарили: 12 раз

Re: MegaLight - контроллер освещения на Arduino Mega 2560+W5100

Сообщение gnom537 » Пт янв 25, 2019 11:40 am

я пользуюсь первой версией. привел пример из нее.

у вас вторая похоже, почти в самом низу кода:

void setup() {

wdt_disable();

Serial.begin(115200);
Serialprint("Starting...\r\n");

delay (10000); //это задержка вставьте эту строчку

единственный минус нельзя сразу после включения выключателями щелкать, нужно задержку ждать.
condor77
Сообщения: 36
Зарегистрирован: Пн окт 30, 2017 9:54 am
Благодарил (а): 8 раз
Поблагодарили: 2 раза

Re: MegaLight - контроллер освещения на Arduino Mega 2560+W5100

Сообщение condor77 » Пн янв 28, 2019 1:14 pm

olehs писал(а):
Пт янв 25, 2019 11:35 am
В MegaLight Вы все правильно сделали, потому и не стал отвечать, надеясь, что с проблемой на сервере сами разберетесь ))
Что занимает порты на сервере - только вам известно, т.к. "он" (контроллер) физически ничего не может занимать на другом устройстве.
В том то и дело что когда я выключаю питание контроллера или вынимаю кабель ethernet, у меня скрипт создающий сервер для прослушки порта запускается без ошибок. А если контроллер включен и в сети то происходит ошибка.
Вот я и подумал что это контроллер занимает порт.
Yashalta
Сообщения: 315
Зарегистрирован: Вс май 20, 2018 9:27 am
Благодарил (а): 160 раз
Поблагодарили: 29 раз

Re: MegaLight - контроллер освещения на Arduino Mega 2560+W5100

Сообщение Yashalta » Вт янв 29, 2019 2:12 pm

olehs писал(а):
Ср авг 29, 2018 10:47 pm
Обновите скетч с гита - я там пофиксил парсинг отрицательного значения param, которое поломал прошлым апдейтом.
Во вложении конфиг с логикой, которую описал выше. Кнопка - на 7 пине, ШИМ - на 8-м.
Делаю димер но, что то не получается у меня!
Я скачал архив, залил на карту памяти. В результате у меня постоянно статус "OFF" и значение "value" не меняется а реле все время включено! НО, все адекватно реагирует на нажатие кнопки выключателя. Может я подключил не правильно? Я входящий pin вставил на 7 а реле подключил на 8.
Ниже то, что выдает "Монитор последовательного порта" на мои действия выключателем.

Код: Выделить всё

Starting...
SD initialization done.
MAC=34:ad:be:43:fe:68
Added input BUTTON on pin 7
Saved input BUTTON at 40 (17 bytes)
Stored 1 inputs (17 bytes)

Added output DIR on pin 255
Saved output DIR at 57 (7 bytes)
Added output LED on pin 8
Saved output LED at 64 (7 bytes)
Stored 2 outputs (14 bytes)

Saved rule /DIR at 71 (55 bytes)
Loaded rule: /DIR
Saved rule /HOLDDOWN at 126 (45 bytes)
Loaded rule: /HOLDDOWN
Saved rule /HOLDUP at 171 (34 bytes)
Loaded rule: /HOLDUP
Saved rule /OFF at 205 (25 bytes)
Loaded rule: /OFF
Saved rule /ON at 230 (27 bytes)
Loaded rule: /ON
Stored 5 rules (186 bytes)

Stored config to EEPROM (257 bytes)

Server started at 192.168.18.110
Started (free RAM: 4755)
Button BUTTON Pressed
Button BUTTON Released
Button BUTTON Click
Output LED Off
Status output LED State:Off Value:125
Button BUTTON Pressed
Button BUTTON Released
Button BUTTON Click
Output LED Off
Status output LED State:Off Value:125
Button BUTTON Pressed
Button BUTTON Hold
Button BUTTON Repeat
Button BUTTON Repeat
Button BUTTON Repeat
Button BUTTON Repeat
Button BUTTON Repeat
Button BUTTON Repeat
Button BUTTON Repeat
Button BUTTON Repeat
Button BUTTON Repeat
Button BUTTON Repeat
Button BUTTON Released
Button BUTTON LongClick
Button BUTTON Pressed
Button BUTTON Released
Button BUTTON Click
Output LED Off
Status output LED State:Off Value:125
Yashalta
Сообщения: 315
Зарегистрирован: Вс май 20, 2018 9:27 am
Благодарил (а): 160 раз
Поблагодарили: 29 раз

Re: MegaLight - контроллер освещения на Arduino Mega 2560+W5100

Сообщение Yashalta » Пт фев 01, 2019 12:33 pm

У меня все еще димер не работает! :(
Подскажите не понимаю!
У меня на карте SD в папке "RULS" есть фаил под названием "HOLDDOWN" в котором есть такие строки

Код: Выделить всё

...
event=repeat
condition=RLED&!RDIR&VLED>10
action=incvalue
param=-5
Я правильно читаю код?
В то время когда у нас нажата кнопка выключателя, при каждом авто повторе т.е. когда в "Мониторе последовательного порта" пишет "Button BUTTON Repeat" то, состояние выставляем такое RLED&!RDIR&VLED>10 а действие увеличиваем или уменьшаем значение диммера на фиксированное значение в нашем случае на -5 едениц?
И еще вопрос:
RLED, RDIR, VLED -это что такое? Если это название файлов LED, DIR, LED которые залиты на карту памяти то, что означает - "R"?
olehs
Сообщения: 1115
Зарегистрирован: Вс июн 14, 2015 11:08 am
Благодарил (а): 85 раз
Поблагодарили: 342 раза

Re: MegaLight - контроллер освещения на Arduino Mega 2560+W5100

Сообщение olehs » Пт фев 01, 2019 1:23 pm

RLED&!RDIR&VLED>10 - это не выставляем состояние, а условие. Описание всего этого есть в первом посте.
В данном случае, переводится это все так:
при событии reapeat, если включено реле LED и выключено реле DIR, а значение диммера LED больше 10, то нужно уменьшить значение диммера на 5
За это сообщение автора olehs поблагодарил:
Yashalta (Пт фев 01, 2019 4:28 pm)
Рейтинг: 1.16%
Yashalta
Сообщения: 315
Зарегистрирован: Вс май 20, 2018 9:27 am
Благодарил (а): 160 раз
Поблагодарили: 29 раз

Re: MegaLight - контроллер освещения на Arduino Mega 2560+W5100

Сообщение Yashalta » Пт фев 01, 2019 9:49 pm

Я не понимаю, подскажите!
Почему у меня при коротком нажатии т.е. когда событие/Event "click" все время отрабатывает статус "OFF"? Хотя в файле "ON" в правилах прописано если "condition=!RLED" то действие "action=on" а оно все время мне выдает "OFF"!
Изображение

Код: Выделить всё

Starting...
SD initialization done.
MAC=34:ad:be:43:fe:68
Added input BUTTON on pin 7
Saved input BUTTON at 40 (17 bytes)
Stored 1 inputs (17 bytes)

Added output DIR on pin 255
Saved output DIR at 57 (7 bytes)
Added output LED on pin 8
Saved output LED at 64 (7 bytes)
Stored 2 outputs (14 bytes)

Saved rule /DIR at 71 (55 bytes)
Loaded rule: /DIR
Saved rule /HOLDDOWN at 126 (45 bytes)
Loaded rule: /HOLDDOWN
Saved rule /HOLDUP at 171 (34 bytes)
Loaded rule: /HOLDUP
Saved rule /OFF at 205 (25 bytes)
Loaded rule: /OFF
Saved rule /ON at 230 (27 bytes)
Loaded rule: /ON
Stored 5 rules (186 bytes)

Stored config to EEPROM (257 bytes)

Server started at 192.168.18.110
Started (free RAM: 4755)
Button BUTTON Pressed
Button BUTTON Released
Button BUTTON Click
Output LED Off
Status output LED State:Off Value:125
Button BUTTON Pressed
Button BUTTON Released
Button BUTTON Click
Output LED Off
Status output LED State:Off Value:125
Button BUTTON Pressed
Button BUTTON Hold
Button BUTTON Repeat
Button BUTTON Repeat
Button BUTTON Repeat
Button BUTTON Repeat
Button BUTTON Repeat
Button BUTTON Repeat
Button BUTTON Repeat
Button BUTTON Repeat
Button BUTTON Repeat
Button BUTTON Repeat
Button BUTTON Released
Button BUTTON LongClick
Button BUTTON Pressed
Button BUTTON Released
Button BUTTON Click
Output LED Off
Status output LED State:Off Value:125
olehs
Сообщения: 1115
Зарегистрирован: Вс июн 14, 2015 11:08 am
Благодарил (а): 85 раз
Поблагодарили: 342 раза

Re: MegaLight - контроллер освещения на Arduino Mega 2560+W5100

Сообщение olehs » Пт фев 01, 2019 10:21 pm

Так все-таки папка называется RULS или RULES?
Ответить