Умный огород, проблема с часами реального времени!

Тема в разделе "Iskra JS, Espruino, Йодо", создана пользователем Recha, 30 июл 2019.

  1. Recha

    Recha Нуб

    Всем доброго времени суток.Прошу помощи знающих людей. Столкнулся с проблемой с часами реального времени, загружаю код в Искру и к примеру после удачного полива из каких либо секторов начинает сыпаться ошибки и больше огород не поливает, если нажать ресет все повторяется!

    Код (Javascript):
    //Датчик уровня вода бочка нижняя граница
    var watlev1 = require('water-level').connect(P3);
    //Датчик уровня воды бочка верхняя граница
    var watlev2 = require('water-level1').connect(P1);
    //Датчик уровня воды в колодце
    var watlev3 = require('water-level2').connect(P2);
    //Датчик света
    var svet = require('light-sensor').connect(A1);
    //Реле на насос в колодце
    var relay1 = require('relay1').connect(P4);
    //Реле на насос в колодце 2
    var relay2 = require('relay2').connect(P5);
    //Реле на клапан пополнения запаса воды в бочке
    var relay3 = require('relay3').connect(P6);
    //Реле на клапан капельного полива
    var relay4 = require('relay4').connect(P7);
    //Реле на насос капельного полива
    var relay5 = require('relay5').connect(P8);
    //Реле на клапан полива сектор 1
    var relay6 = require('relay6').connect(P9);
    //Реле на клапан полива сектор 2
    var relay7 = require('relay7').connect(P10);
    //Реле на открывание\закрывание дверей
    var relay8 = require('relay8').connect(P11);
    //Датчик влажности и температуры
    var tmpvlg = require('DHT11').connect(P12);
    //Часы реального времени + настройка
    E.setTimeZone(+3);
    PrimaryI2C.setup({sda: SDA, scl: SCL, bitrate: 100000});
    var rtc = require('rtc').connect();
    //----------------------------------------------
    //Открывание и закрывание дверок в парнике
    setInterval(function() {
    var pasmyrno = 3000;
    var luxes = svet.read('lx');
    if (luxes > pasmyrno) {
    relay8.turnOff();
    }
    else {
    relay8.turnOn();
    }
    },60000*30);
    //----------------------------------------------
    //Пополнение бочки запасом воды
    //Если в колодце нет воды
    setInterval(function() {
    if (watlev3.read() === 'up') {
    relay2.turnOff();
    relay3.turnOff();
    }
    },5000);
    //Полная бочка
    setInterval(function() {
    if (watlev2.read() === 'up') {
    relay2.turnOff();
    relay3.turnOff();
    }
    },5000);
    //Кончилась вода в бочке
    setInterval(function() {
    if (watlev1.read() === 'down') {
    if (watlev3.read() === 'down') {
    relay2.turnOn();
    relay3.turnOn();
    }
    }
    },5000);
    //--------------------------------------------
    //Проверка влажности и температуры (включать или не включать полив зон)
    var vlaga = tmpvlg.read(function(a) {
    vlaga = a.rh.toString();
    });
    var temp = tmpvlg.read(function(a) {
    temp = a.temp.toString();
    });
    //Параметр минимального значения влажности и температуры
    var dojdik = 80;
    var holodno = 12;

    //Таймер полива парника
    var parnik = -1;
    setInterval(function () {
    var date = rtc.getTime();
    if (parnik === date.getDate()) return;
    if (date.getHours() ===6) {
    if (watlev1.read() === 'up') {
    parnik = date.getDate();
    relay4.blink(4800);
    relay5.blink(1800);
    }
    else {
    relay4.blink(2400);
    relay5.turnOff();
    }
    }
    }, 5000);
    //Таймер полива основного огорода, зона 1
    var polivzona1 = -1;
    setInterval(function () {
    var date1 = rtc.getTime();
    if (polivzona1 === date1.getDate()) return;
    if (date1.getHours() === 20) {
    if (vlaga <= dojdik) {
    if (temp > holodno) {
    if (watlev3.read() === 'down') {
    polivzona1 = date1.getDate();
    relay6.blink(600);
    relay1.blink(600);
    }
    }
    }
    else {
    relay6.turnOff();
    relay1.turnOff();
    }
    }
    }, 5000);
    //Таймер полива основного огорода, зона 2
    var polivzona2 = -1;
    setInterval(function () {
    var date2 = rtc.getTime();
    if (polivzona2 === date2.getDate()) return;
    if (date2.getHours() === 21) {
    if (vlaga <= dojdik) {
    if (temp > holodno) {
    if (watlev3.read() === 'down') {
    polivzona2 = date2.getDate();
    relay7.blink(700);
    relay1.blink(700);
    }
    }
    }
    else {
    relay7.turnOff();
    relay1.turnOff();
    }
    }
    }, 5000);
    Uncaught InternalError: Timeout on I2C Write BUSY
    at line 1 col 55
    ...i2c.writeTo(this._address,b),this._i2c.readFrom(this._addres...
    ^
    in function "read" called from line 1 col 20
    var b=this.read(0,7);this._time=new Date(this._bcdToDec(b[6]...
    ^
    in function "getTime" called from line 1 col 24
    var date = rtc.getTime();
    ^
    in function called from system
    at line 1 col 55
    ...i2c.writeTo(this._address,b),this._i2c.readFrom(this._addres...
    ^
    in function "read" called from line 1 col 20
    var b=this.read(0,7);this._time=new Date(this._bcdToDec(b[6]...
    ^
    in function "getTime" called from line 1 col 25
    var date1 = rtc.getTime();
    ^
    in function called from system
    at line 1 col 55
    ...i2c.writeTo(this._address,b),this._i2c.readFrom(this._addres...
    ^
    in function "read" called from line 1 col 20
    var b=this.read(0,7);this._time=new Date(this._bcdToDec(b[6]...
    ^
    in function "getTime" called from line 1 col 25
    var date2 = rtc.getTime();
    ^
    in function called from system
    >
    Room lightness: 1175.41899398247 luxes
    Temp is 27 and RH is 64
    < << {"VERSION":"2v01.49","GIT_COMMIT":"e424443","BOARD":"ISKRAJS","FLASH":1048576,"RAM":196608,"SERIAL":"1e002a00-1850484e-52333720","CONSOLE":"USB","MODULES":"Flash,Storage,heatshrink,fs,net,dgram,tls,http,NetworkJS,WIZnet,crypto,neopixel","EXPTR":536871140} >> >


    Часы подключены к 13 пину и SDA\SCL соответственно, перемычки на платах стоят на V2+5V, сама Искра питается от внешнего блока питания (питаю 6в.) батарейка в часах живая (уже целая коллекция их)
    [​IMG]


    Временно вырубил датчик влажности почвы (ужжж очень быстро окисляется).

    Помогите, спасите, скоро заканчивается отпуск а все коряво работает.
     
    Последнее редактирование: 30 июл 2019
  2. Recha

    Recha Нуб

    И еще вопрос к гуру, может кто поможет прикрутить самодельный анемометр (с герконом на борту)
    Код (Javascript):
    var lastRotation = getTime();
    function anemRotated(e) {
      var d = e.time-lastRotation;
      lastRotation = e.time;
      console.log("Speed = "+(60/d)+" rpm");
    }
    pinMode(P0, "input_pullup");
    setWatch(anemRotated, P0, {repeat:true, edge:"falling"});
    не могу понять почему выдает сразу по 4 значения? Пробывал перемудрить код из этой статьи http://wiki.amperka.ru/projects:pov-speedometr тоже самое, почему то в консоль показывает по 4 значения :(
     
    Последнее редактирование: 30 июл 2019
  3. NikitOS

    NikitOS Король шутов Администратор

    Вставьте код и ошибки правильно :)
     
  4. ИгорьК

    ИгорьК Гуру

    Я не спец по JavaScript, но, ИМХО, столько таймеров плата не может "протягивать". Код надо в принципе писать по-другому.
     
  5. ИгорьК

    ИгорьК Гуру

  6. ИгорьК

    ИгорьК Гуру

    Замените на две вязальные спицы.
     
  7. Recha

    Recha Нуб

    Тоже так думаю, но в JS не силен - может кто подскажет как два таймера зогнать в один но с интервалом т.е. полилась одна зона а потом следом за ней вторая????
    - оригинально, попробую спасибо!
     
  8. ИгорьК

    ИгорьК Гуру

    Есть такое явление - callback.
    Вот здесь я объясняю как это на Lua, но на JS точно также: http://forum.amperka.ru/threads/esp-8266-lua-азы-программирования-nodemcu.12558/page-12#post-160314
     
  9. Recha

    Recha Нуб

    Думал под спойлером будет удобнее, спасибо за подсказку!!!
     
  10. Recha

    Recha Нуб

    буду изучать, спасибо большое. Но пока не совсем въехал как его впихнуть сюда
    Код (Javascript):
    var polivzona2 = -1;
    setInterval(function () {
    var date2 = rtc.getTime();
    if (polivzona2 === date2.getDate()) return;
    if (date2.getHours() === 21) {
    if (vlaga <= dojdik) {
    if (temp > holodno) {
    if (watlev3.read() === 'down') {
    polivzona2 = date2.getDate();
    relay7.blink(700);
    relay1.blink(700);
    }
    }
    }
    else {
    relay7.turnOff();
    relay1.turnOff();
    }
    }
    }, 5000);
    но думаю соображу, Спасибо за помощь ИгорьК
     
  11. ИгорьК

    ИгорьК Гуру

    Смотрите, у вас по таймерАМ проверяется куча событий.
    Я не делал такого на JS, но правильным будет иметь всего один таймер, указатель на очередную проверку вместе с интервалом этой проверки.

    Я могу вас запутать, но логика здесь такова, что один таймер читает некую таблицу, где стоит указатель на функцию, которую надо вызывть (вызывает ее) и время, когда надо прочитать очередную строку, вызывать функцию из нее и узнать время, когда читать следующую, etc.
     
  12. ИгорьК

    ИгорьК Гуру

  13. Recha

    Recha Нуб

    Уххх без пива здесь точно не обойтись, мысленно понимаю про что речь но вот как ее воплотить в код JS это сложно, пока что сложно... Будем читать, думать, отправные точки есть... Спасибо


    Ухххх новые слова за 33 года узнаю :confused:
     
  14. Recha

    Recha Нуб

    Снова всем привет, вопрос на засыпку сколько таймеров может переварить IskraJS?
    Слегка упростил задачу Iskre с надеждой что этот код съест, но увы!-надежды рухнули
    Код (Javascript):
    // Модуль датчика уровня воды
    var level = require('water-level');
    // Датчик на дне бочки
    var onBottom = level.connect(P3, {debounce: 3});
    // Датчик на дне колодца
    var onBottom2 = level.connect(P2, {debounce: 3});
    // Датчик на крышке бочки
    var onTop = level.connect(P1, {debounce: 3});
    // Модуль реле
    var relay = require('relay');
    // Реле на насос в колодце 1
    var relay1 = relay.connect(P4);
    // Реле на насос в колодце 2
    var relay2 = relay.connect(P5);
    // Реле на клапан пополнения запаса воды в бочке
    var relay3 = relay.connect(P6);
    // Реле на клапан капельного полива
    var relay4 = relay.connect(P7);
    // Реле на насос капельного полива
    var relay5 = relay.connect(P8);
    // Реле на клапан полива сектор 1
    var relay6 = relay.connect(P9);
    // Реле на клапан полива сектор 2
    var relay7 = relay.connect(P10);
    // Реле на открывание\закрывание дверей
    var relay8 = relay.connect(P11);
    // Датчик света
    var svet = require('light-sensor').connect(A1);
    // Датчик влажности и температуры
    var tmpvlg = require('DHT11').connect(P12);
    //Часы реального времени + настройка
    var rtc = require('rtc').connect();
    //----------------------------------------------
    //Открывание и закрывание дверок в парнике
    setInterval(function() {
    var pasmyrno = 1000;
    var luxes = svet.read('lx');
    if (luxes > pasmyrno) {
    relay8.turnOff();
    }
    else {
    relay8.turnOn();
    }
    },1800000);
    //----------------------------------------------
    // Пополнение бочки запасом воды
    var switchOn = function() {
    // Включаем насос
      relay1.turnOn();
      relay3.turnOn();
    // Проверка датчика воды в колодце
      setInterval(function() {
        if (onBottom2.read() === 'up') {
    // Выключаем насос во избежание перегрева
            switchOff();
            print('Net vodi v kolodce');
          }
        }, 5000);
    };

    var switchOff = function() {
    // Выключаем насос
      relay1.turnOff();
      relay3.turnOff();
    };
    // Если датчик на дне бочки опустился
    if (onBottom.read() === 'down') {
    // Включаем насос
      switchOn();
      print('Sosy vodichky s kolodca');
    }
    // Датчик на крышке бочки поднялся
    onTop.on('up', function () {
      print('Vodi polnaja bochka');
    // Выключаем насос
      switchOff();
    });
    // Датчик на дне бочки опустился
    onBottom.on('down', function () {
    // Включаем насос
      switchOn();
      print('Vodichki v bocke net');
    });
    //--------------------------------------------
    //Таймер полива парника
    var parnik = -1;
    setInterval(function () {
    var date = rtc.getTime();
    if (parnik === date.getDate()) return;
    if (date.getHours() ===12) {
    if (onBottom.read() === 'up') {
    parnik = date.getDate();
    relay4.blink(4800);
    relay5.blink(1800);
    print('vse good parnik polivaetsja');
    }
    else {
    relay4.blink(2400);
    relay5.turnOff();
    }
    }
    }, 10000);
     
    Даже после уменьшения количества таймеров, после уменьшения задач, часы реального времени отваливаются спустя ~30 минут работы с такой же ошибкой что и в первом случае
    Код (Text):
    Uncaught InternalError: Timeout on I2C Write BUSY
    at line 1 col 55
    ...i2c.writeTo(this._address,b),this._i2c.readFrom(this._addres...
                                  ^
    in function "read" called from line 1 col 20
    var b=this.read(0,7);this._time=new Date(this._bcdToDec(b[6]...
                       ^
    in function "getTime" called from line 1 col 24
    var date = rtc.getTime();
                           ^
    in function called from system
    Закрадываются мысли, может блоки питания которые установлены в ящике создают нейкие помехи и из-за этого весь геморой?Да на выходе от розетки до электроники стоит ИБП на 650Вт. растояние между ИБП и электроникай порядком 60 метров
    ИгорьК - начал изучать, спасибо, реально полезная статья - но тут вопрос если Искра не может переварить это кол-во таймеров, сможет ли она переварить еще круче код и не чуть меньше таймеров чем я привел пример в этой статье? Просто стоит ли забивать голову JS или проще взять игрушку понадежней а именно Arduino и забивать голову С\С++??? Почитав кучу информации, все масштабные проекты собирают именно на ней

    Спасибо статье http://wiki.amperka.ru/projects:barrel#исходный_код тут познакомился как правильно подкидывать одинаковые модули и не побоюсь этого слова слизал часть кода, респект и спасибо! Хоть частично начинаю вкуривать что да как.
     
    Последнее редактирование: 5 авг 2019
  15. ИгорьК

    ИгорьК Гуру

    Не ту информацию вы читали. Ардуино стало жупелом и фетишем у определенной части диайвайщиков, той, что сами не разрабатывают, а лишь, повизгивая от счастья, повторяют чужие решения.

    Кто старается хотя-бы что-то разработать сам, быстро понимает потолок Ардуино, и дальше должен либо лезть в дебри монотонного изучения регистров микроконтроллеров, а также указателей (и тучи еще чего) в языке Си/Си++ либо менять платформу на более мощную.

    В своих проектах не помню, чтобы мне когда-то требовалось больше трех таймеров, и то в целом, а постоянно тикающих - ну максимум два.

    Если возникает вопрос о количестве таймеров - вы продолжаете писать плохой код.
     
  16. ИгорьК

    ИгорьК Гуру

    Может говорить о чем угодно, в т.ч. о плохом контакте, проблемах модуля часов, питания.
    Изучите что есть функция try() и можно ли ее здесь применить. https://javascript.ru/try-catch
     
  17. ИгорьК

    ИгорьК Гуру

    ps. Комментированный код - это очень хорошо, но, надеюсь, в таком виде вы не пытаетесь его втыкать в Искру.
    Кроме того, в JavaScript существует хорошая традиция, что код пишется так, что сами функции и переменные себя комментируют, "чистые" комментарии, обычно, нужны лишь в редких случаях.
     
    Igor68 нравится это.
  18. Igor68

    Igor68 Гуру

    Иногда надо этот JS конечно не в искре... и комментарии из кода никуда не уходят, но значительно добавляют вес.:( Это же не компилятор. Не знаток конечно, но это не замедляет интерпретацию?
    Спасибо!
     
  19. ИгорьК

    ИгорьК Гуру

    upload_2019-8-5_23-3-57.png

    Модуль минификации при загрузке данных в плату должен вычищать и "плющить" скрипт. Другое дело, как хорошо он работает с комментариями на кириллице.
     
    Igor68 нравится это.
  20. Recha

    Recha Нуб

    Спору нет, все написанное из краткого курса молодого бойца вики Амперки. Пытаюсь понять то что вы прислали ИгорьК я про ссылки, и честно уже не совсем понимаю даже с чего начать. Примеры конечно хороши в статьях, но пока курю бамбук, сложновато чуйнику, куда проще было коммутировать железки и проводочки!!!

    Модуль часов уже второй стоит с первым та же история, провода переставлял не один раз история та же, батарейка в норме но тоже переставлял не один раз :( к сожалению уже нет возможности оставить только один таймер и посмотреть что будет. Но что самое интересное, в самом начале до монтажа всего этого, все работало как часы и таймеров было в разы больше ( сейчас вспоминаю ) - в тестовом режиме работало 3 дня. но без дополнительных усиленных реле и дополнительных трансов

    Код (Javascript):
    //Датчик уровня вода бочка нижняя граница
    var watlev1 = require('water-level').connect(P3);
    //Датчик уровня воды бочка верхняя граница
    var watlev2 = require('water-level1').connect(P1);
    //Датчик уровня воды в колодце
    var watlev3 = require('water-level2').connect(P2);
    //Датчик света
    var svet = require('light-sensor').connect(A1);
    //Вывод информации с датчика освещенности
    setInterval( function() {
    console.log('Room lightness:', svet.read('lx'), 'luxes');
    },5000);
    //Реле на насос в колодце
    var relay1 = require('relay1').connect(P4);
    //Реле на насос в колодце 2
    var relay2 = require('relay2').connect(P5);
    //Реле на клапан пополнения запаса воды в бочке
    var relay3 = require('relay3').connect(P6);
    //Реле на клапан капельного полива
    var relay4 = require('relay4').connect(P7);
    //Реле на насос капельного полива
    var relay5 = require('relay5').connect(P8);
    //Реле на клапан полива сектор 1
    var relay6 = require('relay6').connect(P9);
    //Реле на клапан полива сектор 2
    var relay7 = require('relay7').connect(P10);
    //Реле на открывание\закрывание дверей
    var relay8 = require('relay8').connect(P11);
    //Датчик влажности и температуры
    var tmpvlg = require('DHT11').connect(P12);
    //Датчик влажности почвы + значение влажности
    var hyst = require('hysteresis')
    .create({high: 0.4, low: 0.2});
    setInterval(function() {
    hyst.push(analogRead(A0));
    }, 2000);
    //Вывод информации о влажности почвы
    setInterval(function() {
    var value = analogRead(A0); print(value);
    },10000);
    //Часы реального времени + настройка
    E.setTimeZone(+3);
    PrimaryI2C.setup({sda: SDA, scl: SCL, bitrate: 100000});
    var rtc = require('rtc').connect();
    rtc.setTime('2019-5-31T21:30:00');
    //----------------------------------------------
    //Открывание и закрывание дверок в парнике
    setInterval(function() {
    var pasmyrno = 1;
    var luxes = svet.read('lx');
    if (luxes > pasmyrno) {
    relay8.turnOn();
    }
    else {
    relay8.turnOff();
    }
    },5000);
    //Пополнение бочки запасом воды
    //В колодце нет воды
    setInterval(function() {
    if (watlev3.read() === 'up') {
    relay2.turnOff();
    relay3.turnOff();
    print('vodichki v kolodce xyi');
    }
    },5000);
    //Полная бочка
    setInterval(function() {
    if (watlev2.read() === 'up') {
    print('vodichki polnaja bochka');
    relay2.turnOff();
    relay3.turnOff();
    }
    },5000);
    //Кончилась вода в бочке
    setInterval(function() {
    if (watlev1.read() === 'down') {
    if (watlev3.read() === 'down') {
    relay2.turnOn();
    relay3.turnOn();
    print('sosy vodichky s kolodca');
    }
    }
    },5000);
    //Включение и выключени капельного полива
    hyst.on('low', function() {
    relay4.turnOn();
    relay5.turnOn();
    print('Syhovato polit bi');
    });
    hyst.on('high', function() {
    relay4.turnOff();
    relay5.turnOff();
    print('Hvatit yje mokro');
    });
    //Если в бочке мало воды
    setInterval(function() {
    if (watlev1.read() === 'down') {
    print('v bochke net vodi');
    relay5.turnOff();
    }
    },5000);
    //--------------------------------------------
    //Проверка погоды и температуры (включать или не включать полив зон)
    setInterval(function () {
    tmpvlg.read(function (a) {
    console.log("Temp is "+a.temp.toString()+" and RH is   "+a.rh.toString());
    });
    },20000);
    var vlaga = tmpvlg.read(function(a) {
    vlaga = a.rh.toString();
    });
    var temp = tmpvlg.read(function(a) {
    temp = a.temp.toString();
    });
    //Параметр минимального значения влажности и температуры
    var dojdik = 80;
    var holodno = 15;

    //Таймер полива основного огорода зона 1
    var polivzona1 = -1;
    setInterval(function () {
    var date = rtc.getTime();
    print(date.toString());
    if (polivzona1 === date.getDate()) return;
    if (date.getHours() === 21) {
    if (vlaga <= dojdik) {
    if (temp > holodno) {
    if (watlev3.read() === 'down') {
    polivzona1 = date.getDate();
    relay6.blink(100);
    relay1.blink(100);
    print('vse good polivzona1');
    }
    }
    }
    else {
    relay6.turnOff();
    relay1.turnOff();
    }
    }
    }, 5000);

    //Таймер полива основного огорода зона 2
    var polivzona2 = -1;
    setInterval(function () {
    var date2 = rtc.getTime();
    if (polivzona2 === date2.getDate()) return;
    if (date2.getHours() === 22) {
    if (vlaga <= dojdik) {
    if (temp > holodno) {
    if (watlev3.read() === 'down') {
    polivzona2 = date2.getDate();
    relay7.blink(100);
    relay1.blink(100);
    print('vse good polivzona2');
    }
    }
    }
    else {
    relay7.turnOff();
    relay1.turnOff();
    }
    }
    }, 5000);

     
    Головоломка