NEWS
Скрипт для датчика CO2 MH-Z14 (MH-Z19)
-
Дело в том что мне попадались 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()
-
Какая 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
-
Какая 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
-
адаптер прямо в порту торчит. чип CP2102. датчик - проводочки сантиметров пять. Просадку не смотрел. Два разных адаптера (одинаковых, впрочем, по чипу и схеме).
Скрипт на питоне - работает как из пушки. Ни одной ошибки. `
Попробуй поменять в коде на````
var buflen = 9;Ещё вероятно причина в драйвере serialport. Видно же что ответ ненормальный идёт. Сделайте дебаг вывод ответа питона и сравните с nodejs. С питоном также дублированы байты ответа? Когда работает с портом iobroker (nodejs) - другие скрипты на уровне OS (питон) с этим портом не работают?
-
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 очень странно работает.
-
с питоном ничего не дублируется, с терминалкой тоже все ок. никаких других скриптов кроме этого вообще нет. питон на время экспериментов остановил.
похоже, что-то в недрах nodejs.serialport очень странно работает. `
Посмотреть кто занял порт:
fuser /dev/ttyUSB1
Иногда javascript driver надо перезапустить чтобы порт освободить.
Это не помогло?
var buflen = 9;
-
Посмотреть кто занял порт:
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]
-
Скрипт на питоне - работает как из пушки. Ни одной ошибки. `
Что-то не видно проверки CRC на питоне. Понятно что без проверки ошибок нет -
Скрипт на питоне - работает как из пушки. Ни одной ошибки.
Что-то не видно проверки CRC на питоне. Понятно что без проверки ошибок нет :)
то был первый вариант питон принимает строго нужное количество байт, crc совпадает
-
то был первый вариант питон принимает строго нужное количество байт, crc совпадает `
CRC вычисляется в именно в строгом количестве байт, смотрите даташит на датчик. В вашем коде на питоне проверки CRC нет. -
то был первый вариант питон принимает строго нужное количество байт, 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)