Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Русский
    3. ioBroker
    4. Скрипты
    5. ioBroker скрипты
    6. Скрипт для датчика CO2 MH-Z14 (MH-Z19)

    NEWS

    • Neuer Blog: Fotos und Eindrücke aus Solingen

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    Скрипт для датчика CO2 MH-Z14 (MH-Z19)

    This topic has been deleted. Only users with topic management privileges can see it.
    • A
      andrey99986 last edited by

      @artko:

      А никому не приходилось бороться со странными зависами при setTimeout в скриптах?

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

        console.log('wait response');
                  setTimeout(readport, 200);
                  function readport() {
                                              console.log('readport enter');   
      
      

      в логе вижу первый вывод в консоль - и все, глухой вис. в top висит процесс iobroker.javascript с 100% загрузкой, драйвер javascript в панели тоже останавливается. Приходится вручную процесс убивать.

      Иногда по непонятной причине - проходит, результат получается нормально. `
      Какая OS?

      Сколько свободной памяти показывает iobroker?

      1 Reply Last reply Reply Quote 0
      • A
        artko last edited by

        @andrey99986:

        Дело в том что мне попадались 2 типа USB-Uart адаптера.

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

        При чём у разных адаптеров разный % CRC Error.

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

        Длина кабеля?

        Уверены что нет просадки напряжения на самом датчике в моменты ИК-свечения (ток вроде 300мА)?

        Какой у вас адаптер?

        В первые пару минут - CRC error это нормально.

        Попробуйте другой адаптер.

        У меня на таком FTDI_FT232R_USB_UART_AH05SK6S CRC ошибок менее ~3 %

        P.S.Мой скрипт написан для MH-Z14, на MH-Z19 ещё не проверял. Скоро проверю, сам датчик уже есть. Судя по документации логика абсолютно одинаковая. `

        адаптер прямо в порту торчит. чип CP2102. датчик - проводочки сантиметров пять. Просадку не смотрел. Два разных адаптера (одинаковых, впрочем, по чипу и схеме).

        Скрипт на питоне - работает как из пушки. Ни одной ошибки.

        import MySQLdb
        import string
        import time
        import serial
        
        from datetime import datetime
        
        ser = serial.Serial('/dev/ttyUSB0',
                              baudrate=9600,
                              bytesize=serial.EIGHTBITS,
                              parity=serial.PARITY_NONE,
                              stopbits=serial.STOPBITS_ONE,
                              timeout=1.0)
        result=ser.write("\xff\x01\x86\x00\x00\x00\x00\x00\x79")
        s=ser.read(9)
        if s[0] == "\xff" and s[1] == "\x86":
          co2 = ord(s[2])*256 + ord(s[3])
        
        print "co2=", co2
        
        ts = time.time()
        ts1 = int(ts * 1000)
        print "ts=", ts1
        
        db = MySQLdb.connect(host="localhost", user="xxxx", passwd="xxxxx", db="iobroker", charset="utf8")
        cursor = db.cursor()
        sql = """insert iobroker.ts_number(id, ts, val, ack, _from, q) values (12,%(ts)s,%(val)s,0,2,0) """ %{"ts":ts1, "val":co2}
        print "sql=", sql
        cursor.execute(sql)
        db.commit()
        db.close()
        
        
        1 Reply Last reply Reply Quote 0
        • A
          artko last edited by

          @andrey99986:

          Какая OS?

          Сколько свободной памяти показывает iobroker? `

          Ubuntu 16.04LTS.

          Всего RAM - Используется: 325 Мб / Свободно: 176 Мб (9%) [Сервер: atom-nb - 9 процессов]

          %Cpu(s): 8,0 us, 2,0 sy, 0,0 ni, 87,0 id, 3,0 wa, 0,0 hi, 0,0 si, 0,0 st

          КиБ Mem : 2050484 total, 179628 free, 520800 used, 1350056 buff/cache

          КиБ Swap: 8269820 total, 8203072 free, 66748 used. 1233352 avail Mem

          1 Reply Last reply Reply Quote 0
          • A
            andrey99986 last edited by

            @artko:

            @andrey99986:

            Какая OS?

            Сколько свободной памяти показывает iobroker? `

            Ubuntu 16.04LTS.

            Всего RAM - Используется: 325 Мб / Свободно: 176 Мб (9%) [Сервер: atom-nb - 9 процессов]

            %Cpu(s): 8,0 us, 2,0 sy, 0,0 ni, 87,0 id, 3,0 wa, 0,0 hi, 0,0 si, 0,0 st

            КиБ Mem : 2050484 total, 179628 free, 520800 used, 1350056 buff/cache

            КиБ Swap: 8269820 total, 8203072 free, 66748 used. 1233352 avail Mem `

            У меня драйвер javascript при работе с ком-портами периодически самоперегружается, поэтому я скрипты работающие с ком-портами запускаю в дополнительной инстанции, чтобы сбой не повлиял на работу других скриптов. Причина где то в недрах библиотеки serialport nodejs. По идее надо дебажить и создавать issue на https://github.com/node-serialport/node … ort/issues

            1 Reply Last reply Reply Quote 0
            • A
              andrey99986 last edited by

              @artko:

              адаптер прямо в порту торчит. чип CP2102. датчик - проводочки сантиметров пять. Просадку не смотрел. Два разных адаптера (одинаковых, впрочем, по чипу и схеме).

              Скрипт на питоне - работает как из пушки. Ни одной ошибки. `

              Попробуй поменять в коде на````
              var buflen = 9;

              Ещё вероятно причина в драйвере serialport. Видно же что ответ ненормальный идёт. Сделайте дебаг вывод ответа питона и сравните с nodejs.
              
              С питоном также дублированы байты ответа?
              
              Когда работает с портом iobroker (nodejs) - другие скрипты на уровне OS (питон) с этим портом не работают?
              1 Reply Last reply Reply Quote 0
              • A
                artko last edited by

                12:25:19.724 [info] javascript.0 script.js.common.Скрипт1: registered 0 subscriptions and 1 schedule

                12:26:00.729 [error] javascript.0 at co2_gd (script.js.common.Скрипт1:20:16)

                12:26:00.730 [error] javascript.0 at Object. (script.js.common.Скрипт1:93:5)

                20 var port = new SerialPort(device_port,{

                93 co2_gd(cmd_init,18, function(data) {

                с питоном ничего не дублируется, с терминалкой тоже все ок. никаких других скриптов кроме этого вообще нет. питон на время экспериментов остановил.

                похоже, что-то в недрах nodejs.serialport очень странно работает.

                1 Reply Last reply Reply Quote 0
                • A
                  andrey99986 last edited by

                  @artko:

                  с питоном ничего не дублируется, с терминалкой тоже все ок. никаких других скриптов кроме этого вообще нет. питон на время экспериментов остановил.

                  похоже, что-то в недрах nodejs.serialport очень странно работает. `

                  Посмотреть кто занял порт:

                   fuser /dev/ttyUSB1
                  

                  Иногда javascript driver надо перезапустить чтобы порт освободить.

                  Это не помогло?

                  var buflen = 9;
                  
                  1 Reply Last reply Reply Quote 0
                  • A
                    artko last edited by

                    @andrey99986:

                    Посмотреть кто занял порт:

                     fuser /dev/ttyUSB1
                    

                    Иногда javascript driver надо перезапустить чтобы порт освободить. `

                    никто не занимает, ну и проверяю в процессах - уже вижу, если висит io.javascript c 100% загрузкой ядра - то ой. почему-то вешается именно при ожидании данных.

                    сделал себе вот такой вариант скрипта для проверки по этапам:

                    `createState('CO2_UART');
                    
                    var device_port = '/dev/ttyUSB0';
                    var buflen = 64;
                    var sleep_time = 200; // Sleep time between request and wait for response.
                    var SerialPort = require('serialport');
                    var ByteLength = SerialPort.parsers.ByteLength;
                    var ppm;
                    
                    var cmd_init = new Buffer ([0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79]);
                    var cmd_set_zero = new Buffer ([0xFF, 0x01, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78]);
                    //var cmd_abc_off = new Buffer ([0xFF, 0x01, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86]);
                    //var cmd_abc_on= new Buffer ([0xFF, 0x01, 0x79, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xE6]);
                    
                    function co2_gd(cmd,buflen,callback)
                    {
                    
                        var port = new SerialPort(device_port,{
                        baudRate: 9600,
                        dataBits: 8,
                        parity: 'none',
                        autoOpen: false
                        });
                    
                        port.open(function (err) {
                            if (err) {
                                return console.log('Error opening port: ', err.message);
                            }
                            console.log('port opened');
                            console.log ('request='+JSON.stringify(cmd));
                    
                            const parser = port.pipe(new ByteLength({length: buflen}));
                            port.pipe(parser);
                    
                            port.write(cmd, function(err) {
                                if (err) {
                                    return console.log('Error on write: ', err.message);
                                }
                                console.log('message written');
                                const parser = port.pipe(new ByteLength({length: buflen}));
                                port.pipe(parser);
                    
                                console.log('wait response');
                    
                                setTimeout(readport, 200);
                                function readport() {
                                                            console.log('readport enter');      
                                                            parser.on ('data', function (result) { 
                                                            console.log ('result='+JSON.stringify(result));
                                                            var i = 0;
                                                            while (i < 18)
                                                            {
                                      if (result[i] == result[i+1])
                                      {
                                          i += 2;
                                      }
                                      else
                                      {
                                          if ((i + 2) < 18)
                                          {
                                              if (result[i] == result[i+2])
                                              {
                                                  console.log ('fix data at position ' + i);
                                                  result[i+2] = result[i+1];
                                                  result[i+1] = result[i];
                                                  i += 2;
                                              }
                                          }
                                      }
                                     console.log('fix cycle ' + i);
                                    }
                    
                                                            ppm = null;
                                                            var CRC_calc=0;
                                                            var CRC_get = result[16];
                                                            CRC_calc = (255 - (result[2] + result[4] + result[6] + result[8] + result[10] + result[12] + result[14]) % 256) + 1;
                                                            if (CRC_get != CRC_calc)
                                                            {
                                        console.log ('CRC ERROR');
                                        console.log('CRC_get='+(CRC_get));
                                        console.log('CRC_calc='+(CRC_calc));
                                        }
                                                            else
                                                            {
                                                ppm = result[4] * 256 + result[6];
                                                console.log('ppm='+ppm);
                                                if (ppm> 5000 )
                                                {
                                                    console.log ('CRC OK');
                                                    console.log('ppm='+ppm);
                                                    console.log('CRC_get='+(CRC_get));
                                                    console.log('CRC_calc='+(CRC_calc));   
                                                    ppm = null;
                                                }
                                        }
                                                            if (callback && typeof(callback) === "function") {
                                                                callback(ppm);
                                                            } 
                                                            port.pause();
                                                            port.close();
                                                            return (ppm);
                                                        })
                                }
                                });
                        });
                    
                    }  //end function co2_gd
                    
                    //co2_gd(cmd_set_zero,18, function(data) {} ); //Set CO2 level as zero  (400 ppm)
                    
                    schedule("*/15 * * * * *", function () {
                        console.log('co2 request');
                        co2_gd(cmd_init,18, function(data) { 
                            //console.log('CO2 ppm='+data);
                            setState("CO2_UART",data);
                        });
                    });` 
                    
                    ~~[quote]~~
                    Это не помогло?
                    `~~[code]~~var buflen = 9;[/code]` `  ` 
                    
                    неа, в таком виде как скрипт из первого сообщения - вообще не хочет работать. с ошибками.[/i][/i][/i]
                    
                    1 Reply Last reply Reply Quote 0
                    • A
                      andrey99986 last edited by

                      @artko:

                      Скрипт на питоне - работает как из пушки. Ни одной ошибки. `
                      Что-то не видно проверки CRC на питоне. Понятно что без проверки ошибок нет 🙂

                      1 Reply Last reply Reply Quote 0
                      • A
                        artko last edited by

                        @andrey99986:

                        @artko:

                        Скрипт на питоне - работает как из пушки. Ни одной ошибки. Что-то не видно проверки CRC на питоне. Понятно что без проверки ошибок нет :)

                        то был первый вариант 🙂 питон принимает строго нужное количество байт, crc совпадает 🙂

                        1 Reply Last reply Reply Quote 0
                        • A
                          andrey99986 last edited by

                          @artko:

                          то был первый вариант 🙂 питон принимает строго нужное количество байт, crc совпадает 🙂 `
                          CRC вычисляется в именно в строгом количестве байт, смотрите даташит на датчик. В вашем коде на питоне проверки CRC нет.

                          1 Reply Last reply Reply Quote 0
                          • A
                            artko last edited by

                            @andrey99986:

                            @artko:

                            то был первый вариант 🙂 питон принимает строго нужное количество байт, crc совпадает 🙂 CRC вычисляется в именно в строгом количестве байт, смотрите даташит на датчик. В вашем коде на питоне проверки CRC нет.

                            я же написал, то был первый вариант….

                            import MySQLdb
                            import string
                            import time
                            import serial
                            
                            from datetime import datetime
                            
                            ser = serial.Serial('/dev/ttyUSB0',
                                                  baudrate=9600,
                                                  bytesize=serial.EIGHTBITS,
                                                  parity=serial.PARITY_NONE,
                                                  stopbits=serial.STOPBITS_ONE,
                                                  timeout=1.0)
                            result=ser.write("\xff\x01\x86\x00\x00\x00\x00\x00\x79")
                            s=ser.read(9)
                            
                            str = ""
                            for ch in s:
                            	str += hex(ord(ch))+ " "
                            print str
                            crc_get = ord(s[8])
                            crc_calc = (255 - (ord(s[1]) + ord(s[2]) + ord(s[3]) + ord(s[4]) + ord(s[5]) + ord(s[6]) + ord(s[7]))) % 256 + 1
                            print "crc calc=" + hex(crc_calc) + " crc get=" + hex(crc_calc)
                            if s[0] == "\xff" and s[1] == "\x86" and crc_calc == crc_get:
                               co2 = ord(s[2])*256 + ord(s[3])  
                               print "crc ok"
                            else:
                               co2 = 0
                               print "crc error"
                            print "co2=", co2
                            
                            ts = time.time()
                            ts1 = int(ts * 1000)
                            print "ts=", ts1
                            
                            db = MySQLdb.connect(host="localhost", user="xxxxxxx", passwd="xxxxxxx", db="iobroker", charset="utf8")
                            cursor = db.cursor()
                            sql = """insert iobroker.ts_number(id, ts, val, ack, _from, q) values (12,%(ts)s,%(val)s,0,2,0) """ %{"ts":ts1, "val":co2}
                            print "sql=", sql
                            cursor.execute(sql)
                            db.commit()
                            db.close()
                            
                            

                            вывод исполнения

                            0xff 0x86 0x1 0xca 0x57 0x40 0x28 0x58 0x98

                            crc calc=0x98 crc get=0x98

                            crc ok

                            co2= 458

                            ts= 1514450008318

                            sql= insert iobroker.ts_number(id, ts, val, ack, _from, q) values (12,1514450008318,458,0,2,0)

                            1 Reply Last reply Reply Quote 0
                            • First post
                              Last post

                            Support us

                            ioBroker
                            Community Adapters
                            Donate

                            920
                            Online

                            31.9k
                            Users

                            80.1k
                            Topics

                            1.3m
                            Posts

                            2
                            16
                            2871
                            Loading More Posts
                            • Oldest to Newest
                            • Newest to Oldest
                            • Most Votes
                            Reply
                            • Reply as topic
                            Log in to reply
                            Community
                            Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                            The ioBroker Community 2014-2023
                            logo