Зависает iskra js

Тема в разделе "Iskra JS, Espruino, Йодо", создана пользователем OxyD, 7 окт 2021.

  1. OxyD

    OxyD Нуб

    Помогите, пожалуйста, разобраться, в чем причина: Iskra JS с прошивкой Espruino 2v01.49 зависает 1 - 2 раза в сутки. Какие модули куда подключены указал в комментариях к коду.

    Код (Javascript):
    //PROTOCOLS
    I2C1.setup({sda: SDA, scl: SCL, bitrate: 100000});//OLED Display & MeteoSensor
    SPI1.setup({baud:3200000, mosi:P3, sck:A5, miso:P2});//4x4 RGB on pin 3

    //MODULES
    var screen = require("SSD1306").connect(I2C1); //OLED
    var meteo = require('meteo-sensor').connect(); //MeteoSensor
    var rgb = require('led-strip').connect(SPI1, 16, 'GRB'); //4x4 RGB LEDs
    var Hr = require('relay').connect(P5); //Heater Relay (heater is connected to NO)
    var P1r = require('relay').connect(P6); //Pump1 mini-relay (pumps are connected to NC)
    var P2r = require('relay').connect(P7); //Pump2 AC/DC Shield-relay (NC)
    var bOn = require('button').connect(P10); //On/Off button
    var led = require('led').connect(P1).brightness(0.3).turnOff(); //On/Off LED
    var bMinus = require('button').connect(P2); //- button
    var bPlus = require('button').connect(P13);//+ button
    var Bz = require('buzzer').connect(P0).turnOff();//Buzzer

    var hysteresis = require('hysteresis').create({high: 22.5, highLag: 60, low: 22.5, lowLag: 60});

    //VARIABLES
    var HrStatus, P1rStatus, P2rStatus; //relays' status

    var work = false; //on/off state

    var Ttgt = 22.5; //target temperature
    var Tact, Rh; //meteosensor readings

    var i, j, k, l, m, n, o, p;

    var th = getTime(); //time when heater starts
    var tp = getTime(); //time when pumps stop
    var t = getTime(); //current time
    var dh = 20; //seconds before heater starts
    var dp = 180; //seconds before pumps stop

    //FUNCTIONS
    function hOn() { //Turn Heater on
      Hr.turnOn();
    }

    function hOff() { //Turn Heater off
      Hr.turnOff();
    }

    function pOn() { //Turn Pumps on
      P1r.turnOff();
      P2r.turnOff();
    }

    function pOff() { //Turn Pumps off
      P1r.turnOn();
      P2r.turnOn();
    }

    //Reset
    rgb.clear();
    screen.clear();
    hOff(); //heater off
    pOn(); //pumps on
    i=0;

    //On/Off button
    bOn.on('press', function() {
      work=!work;
      led.toggle();
    });

    //Target temperature settings
    bMinus.on('press', function() {
      Ttgt-=0.5;
      hysteresis._high = Ttgt;
      hysteresis._low = Ttgt;
    });

    bPlus.on('press', function() {
      Ttgt+=0.5;
      hysteresis._high = Ttgt;
      hysteresis._low = Ttgt;
    });


    setInterval(function() {
      //reset
      screen.clear();
      //check relay status
      HrStatus = Hr.isOn();
      P1rStatus = P1r.isOn();
      P2rStatus = P2r.isOn();
      if (HrStatus===true && P1rStatus===true) { //Heater on + Pumps off!!!
        hOff();
        pOn();
        th = getTime() + dp;
        tp = getTime() + dp;
        Bz.frequency(1760);
        Bz.beep(3);}
     
      //measurements
      meteo.read(function(err, data) {
        if (err) {
    //      console.log(err);
            Bz.frequency(1760);
            Bz.beep(0.5);
          }
        else {
          Tact = data.tempC.toFixed(1);
          Rh = data.humidity.toFixed(0);}
      });
     
      //print
      //console.log('T='+Tact+'*C; RH='+Rh+'%; Heat='+HrStatus+'; Pumps='+!P1rStatus+'; Ttgt='+Ttgt+'*C; Hyst='+hysteresis._high+'*C');
      screen.setFontVector(25);
      screen.drawString(Tact+'*C', 23, 0);
      screen.setFontVector(21);
      if (work === true) {screen.drawString('>>'+Ttgt+'*C', 23, 26);}
      else {screen.drawString('-BblKJI-', 23, 26);}
      screen.setFontVector(12);
      screen.drawString('Rh: '+Rh+' %', 46, 50);
      screen.setFontVector(9);
      if (HrStatus===true) {screen.drawString('H', 5, 6);} //heater on
      if (P1rStatus===false) {screen.drawString('P1', 3, 27);} //pump1 on
      if (P2rStatus===false) {screen.drawString('P2', 2, 49);} //pump2 on
      //screen.setFontBitmap();
      screen.drawLine(0, 0, 0, 63);
      screen.drawLine(17, 0, 17, 63);
      screen.drawLine(19, 0, 19, 63);
      screen.drawLine(0, 21, 17, 21);
      screen.drawLine(0, 42, 17, 42);
      screen.drawLine(0, 0, 17, 0);
      screen.drawLine(0, 63, 17, 63);
      screen.flip();
     
      if (work===true) { //ON state
        hysteresis.push(Tact); //check temperature
       
        //RGB animation
        j=i-1;
        if (i>3) {i=0; j=3;}
        k=i+8; l=j+8;
        m=i+12; n=j+12;
       
        if (HrStatus===true) { //heat on
          rgb.putColor(5, [0.01, 0, 0]);
          rgb.putColor(6, [0.01, 0, 0]);
          o = (i+1)%2;
          if (o!=0) {
            rgb.putColor(4, [0.01, 0, 0]);
            rgb.putColor(7, [0.01, 0, 0]);}
          else {
            rgb.putColor(4, [0, 0, 0]);
            rgb.putColor(7, [0, 0, 0]);}
        }
        else { //heat off
          rgb.putColor(4, [0, 0, 0]);
          rgb.putColor(5, [0, 0, 0]);
          rgb.putColor(6, [0, 0, 0]);
          rgb.putColor(7, [0, 0, 0]);}
       
        if (P1rStatus===false) { //pump 1 on
          rgb.putColor(k, [0, 0.01, 0.01]);
          rgb.putColor(l, [0, 0, 0]);}
        else { //pump 1 off
          rgb.putColor(8, [0, 0, 0]);
          rgb.putColor(9, [0, 0, 0]);
          rgb.putColor(10, [0, 0, 0]);
          rgb.putColor(11, [0, 0, 0]);}
       
        if (P2rStatus===false) { //pump 2 on
          rgb.putColor(m, [0, 0, 0.01]);
          rgb.putColor(n, [0, 0, 0]);}
        else { //pump 2 off
          rgb.putColor(12, [0, 0, 0]);
          rgb.putColor(13, [0, 0, 0]);
          rgb.putColor(14, [0, 0, 0]);
          rgb.putColor(15, [0, 0, 0]);}
       
        if (Tact>=Ttgt) { //green if target temperture reached
            rgb.putColor(1, [0, 0.01, 0]);
            rgb.putColor(2, [0, 0.01, 0]);}
        else {
            rgb.putColor(1, [0, 0, 0]);
            rgb.putColor(2, [0, 0, 0]);}
       
        rgb.apply();
        i++;}
     
      else { //OFF state
        rgb.clear();
        pOn();
        hOff();
        hysteresis.push(-1000);
        hysteresis.push(1000);
      }
    }, 1000);

    hysteresis.on('low', function() {
    //  console.log('LOW');
      t = getTime();
      if (HrStatus===false && P1rStatus===true) { //Heater off + Pumps off
        pOn();
        hOff();
        th = getTime() + dh;}
      if (HrStatus===false && P1rStatus===false && t>=th) { //Heater off + Pumps on
        hOn();
        pOn();
        Bz.frequency(196);
        Bz.beep(0.1);}
      hysteresis.push(1000); //reset hysteresis counter
    });
    hysteresis.on('high', function() {
    //  console.log('HIGH');
      t = getTime();
      if (HrStatus===true && P1rStatus===false) { //Heater on + Pumps on
        hOff();
        pOn();
        Bz.frequency(65);
        Bz.beep(0.1);
        tp = getTime() + dp;}
      if (HrStatus===false && P1rStatus===false && t>=tp) { //Heater off + Pumps on
        pOff();
        hOff();}
      hysteresis.push(-1000); //reset hysteresis counter
    });
     
  2. OxyD

    OxyD Нуб

    Попробовал отключить SPI и RGB-матрицу. Все равно зависает.
    Пробовал изменить периодичность снятия измерений с метеодатчика и их загрузку в гистерезис на 4 секунды вместо 1 - тоже виснет.
    Может у кого какие идеи есть?
    OLED отключать или менять метеодатчик не вижу смысла, так как параллельно у меня работает метеостанция на такой же Iskra JS, с этим же экраном и метеодатчиком - ни разу за месяц не зависала!
     
  3. OxyD

    OxyD Нуб

    Место не менял, так как подключена через AC/DC Shield напрямую к распределительной коробке 220 В. Не очень понял про связь: моей сборке никаких модулей связи нет. Ниже приведу список всех модулей.
    Когда плата зависает, то на экране остаются последние показания, но больше он не обновляется и на кнопки не реагирует (кроме ресета). Судя по показаниям, зависает между включением насосов и включением нагревателя при низкой температуре. Сейчас я экспериментирую с поочерёдным отключением модулей. Работает без RGB-матрицы 4х4. И гистерезис я убрал из программы - переписал на if-ах. Но зависает на том же моменте.

    Там Iskra JS + Troyka Shield LP + AC/DC Shield (в реле подключены провода насоса №2 на NC)
    В Troyka Shield воткнуты Тройка-модули:
    Возможно, ещё важно то, что к реле и мини-реле тянется патч-корд длиной около 5 м. И получается, что они сидят на одной "земле" и питании 5V - т. е. всего в патч-корде задействовано 4 провода: S1, S2, V2, G.

    Пока из идей для дальнейших экспериментов осталось:
    1) отключение дисплея и, соответственно, возможность регулировать температуру;
    2) замена метеодатчика на аналоговый термометр.
    Есть ли ещё какие-то предположения? Что можно попробовать?

    Код (Javascript):
    //PROTOCOLS
    I2C1.setup({sda: SDA, scl: SCL, bitrate: 100000});//OLED Display & MeteoSensor

    //MODULES
    var screen = require("SSD1306").connect(I2C1); //OLED
    var meteo = require('meteo-sensor').connect(); //MeteoSensor
    var Hr = require('relay').connect(P5); //Heater Relay (heater is connected to NO)
    var P1r = require('relay').connect(P6); //Pump1 mini-relay (pumps are connected to NC)
    var P2r = require('relay').connect(P7); //Pump2 AC/DC Shield-relay (NC)
    var bOn = require('button').connect(P10); //On/Off button
    var led = require('led').connect(P1).brightness(0.3).turnOff(); //On/Off LED
    var bMinus = require('button').connect(P2); //- button
    var bPlus = require('button').connect(P13);//+ button
    var Bz = require('buzzer').connect(P0).turnOff();//Buzzer

    //VARIABLES
    var HrStatus, P1rStatus, P2rStatus; //relays' status

    var work = false; //on/off state

    var Ttgt = 23; //target temperature
    var Tact, Rh; //meteosensor readings
    var Thi = Ttgt+0.1; //high limit
    var Tlo = Ttgt-0.1; //low limit

    var cy=0;

    var th = getTime(); //time when heater starts
    var tp = getTime(); //time when pumps stop
    var t = getTime(); //current time
    var dh = 25; //seconds before heater starts
    var dp = 175; //seconds before pumps stop

    //FUNCTIONS
    function hOn() { //Turn Heater on
      Hr.turnOn();
    }

    function hOff() { //Turn Heater off
      Hr.turnOff();
    }

    function pOn() { //Turn Pumps on
      P1r.turnOff();
      P2r.turnOff();
    }

    function pOff() { //Turn Pumps off
      P1r.turnOn();
      P2r.turnOn();
    }

    //Reset
    screen.clear();
    hOff(); //heater off
    pOn(); //pumps on

    //On/Off button
    bOn.on('press', function() {
      work=!work;
      led.toggle();
    });

    //Target temperature settings
    bMinus.on('press', function() {
      Ttgt-=0.5;
      Thi = Ttgt+0.1; //high limit
      Tlo = Ttgt-0.1; //low limit
    });

    bPlus.on('press', function() {
      Ttgt+=0.5;
      Thi = Ttgt+0.1; //high limit
      Tlo = Ttgt-0.1; //low limit
    });

    //MAIN CYCLE
    setInterval(function() {
      //reset
      screen.clear();
      if (cy>5) {cy=0;}
      //check relay status
      HrStatus = Hr.isOn();
      P1rStatus = P1r.isOn();
      P2rStatus = P2r.isOn();
      if (HrStatus===true && P1rStatus===true) { //Heater on + Pumps off!!!
        hOff();
        pOn();
        th = getTime() + dp;
        tp = getTime() + dp;
        Bz.frequency(1760);
        Bz.beep(3);}
     
      //measurements
      if (cy===0) {
        meteo.read(function(err, data) {
          if (err) {
    //        console.log(err);
              Bz.frequency(1760);
              Bz.beep(0.5);
          }
          else {
            Tact = data.tempC.toFixed(1);
            Rh = data.humidity.toFixed(0);}
        });
      }
      //print
      //console.log('T='+Tact+'*C; RH='+Rh+'%; Heat='+HrStatus+'; Pumps='+!P1rStatus+'; Ttgt='+Ttgt+'*C; Hyst='+hysteresis._high+'*C');
      screen.setFontVector(25);
      screen.drawString(Tact+'*C', 23, 0);
      screen.setFontVector(21);
      if (work === true) {screen.drawString('>>'+Ttgt+'*C', 23, 26);}
      else {screen.drawString('-BblKJI-', 23, 26);}
      screen.setFontVector(12);
      screen.drawString('Rh: '+Rh+' %', 46, 50);
      screen.setFontVector(9);
      if (HrStatus===true) {screen.drawString('H', 5, 6);} //heater on
      if (P1rStatus===false) {screen.drawString('P1', 3, 27);} //pump1 on
      if (P2rStatus===false) {screen.drawString('P2', 2, 49);} //pump2 on
      screen.drawLine(0, 0, 0, 63);
      screen.drawLine(17, 0, 17, 63);
      screen.drawLine(19, 0, 19, 63);
      screen.drawLine(0, 21, 17, 21);
      screen.drawLine(0, 42, 17, 42);
      screen.drawLine(0, 0, 17, 0);
      screen.drawLine(0, 63, 17, 63);
      screen.flip();
     
      if (work===true) { //ON state
        t = getTime();
        if (Tact>Thi && HrStatus===true && P1rStatus===false) { //Heater on + Pumps on + Tact>Ttgt
          hOff();
          pOn();
          Bz.frequency(49);
          Bz.beep(0.1);
          tp = getTime() + dp;}
        if (Tact>Tlo && HrStatus===false && P1rStatus===false && t>=tp && t>=th) { //Heater off + Pumps on + Tact>=Ttgt + delays passed
          pOff();
          hOff();}
        if (Tact<=Tlo && HrStatus===false && P1rStatus===false && t>=th && t>=tp) { //Heater off + Pumps on + Tact<Ttgt + delays passed
          hOn();
          pOn();
          Bz.frequency(196);
          Bz.beep(0.1);}
        if (Tact<Tlo && HrStatus===false && P1rStatus===true) { //Heater off + Pumps off + Tact<Ttgt
          pOn();
          hOff();
          th = getTime() + dh;}
      }
     
      else { //OFF state
        if (P1rStatus===true || P2rStatus===true) {pOn();}
        if (HrStatus===true) {hOff();}
      }
      cy++;
    }, 1000);