锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

node-red温湿度传感器节点

时间:2022-08-29 03:30:01 嵌入式传感器节点node传感器

node-red温湿度传感器节点

  • 1 modbus-serial
  • 2 serialport
    • 2.1 串口使用
    • 2.2 crc16校验
  • 3 程序调试
    • 3.1 修改文档位置,导致节点不存在
    • 3.2 单元测试
      • 3.2.1 方法一
      • 3.2.2 方法二
    • 3.3 单步调试
    • 3.4 解决单步调试中遇到的问题
    • 3.5 其他相关问题
      • 3.5.1 打印日志
      • 3.5.2 闪退现象
      • 3.5.3 点击按钮不显示温湿度

??在温湿度节点的设计中,我采用了两种编写方法,一种是使用modbus-serial模块 ,一个是使用serialport模块。因为我是在一个程序中写的,所以取消一种方法,然后使用另一种方法。但是下次找出哪一部分是serialport可以在程序中VScode中使用Ctrl F调出查找
在这里插入图片描述
modbus-serial模块可以通过串口和网线分别使用modbus-RTU和modbus-TCP两种协议连接设备的优点是使用方便,编写功能直观,不需要计算验证码,缺点是不能定制buffer,自由度低。
serialport模块只能通过串口连接读取设备数据,需要定义要发送的数据buffer,在收到数据后,它只是最原始的buffer需要进一步提取和处理数据。

1 modbus-serial

记录器UDP使用方法:

// create an empty modbus client(创造新的modbus客户端) var ModbusRTU = require("modbus-serial");//引入外部serialport节点,require从外部获取模块的接口 var client = new ModbusRTU();///新建一个modbus-serial部分  // open connection to a udp line(打开连接到udp线) client.connectUDP("127.0.0.1", { 
         port: 8502 }); client.setID(1);  // read the values of 10 registers starting at address 0(从地址0开始读取10个寄存器的值 ) // on device number 1. and log the values to the console.(在设备号1上。 并将值记录到控制台) setInterval(function() { 
        //周期函数     client.readHoldingRegisters(0, 10, function(err, data) { 
                 console.log(data.data);     }); }, 1000); 

2 serialport

  通过引用外部serialport模块,实现串口的数据通讯。通过界面设置参数,接收到上游的消息后触发新建serialport对象并发送modbus协议数据帧,接收到响应帧后进行数据解析,提取出温度和湿度最后以对象的形式传递给msg.payload发送。

2.1 串口使用

const SerialPort = require('serialport')
const port = new SerialPort('/dev/tty-usbserial1', { 
        
  baudRate: 57600
})//端口的路径必须,波特率这些东西可选

构造一个SerialPort对象会立即打开一个端口,允许之后串口数据的随时读取和写入,但大多数端口功能都需要打开端口

2.2 crc16校验

具体CRC16码的计算方法是:

  1. 预置1个16位的寄存器为十六进制FFFF(即全为1);称此寄存器为CRC寄存器;
  2. 把第一个8位二进制数据 (既通讯信息帧的第一个字节)与16位的CRC寄存器的低8位相异或,把结果放于CRC寄存器;
  3. 把CRC寄存器的内容右移一 位(朝低位)用0填补最高位,并检查右移后的移出位;
  4. 如果移出位为0:重复第3步(再次右移一位);如果移出位为1:CRC寄存器与多项式A001(1010 0000 0000 0001)进行异或;(Modbus)
  5. 重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理;
  6. 重复步骤2到步骤5,进行通讯信息帧下一个字节的处理;
  7. 将该通讯信息帧所有字节按上述步骤计算完成后,得到的16位CRC寄存器的高、低字节进行交换;
  8. 最后得到的CRC寄存器内容即为:CRC码。
 var k, j, temp;
            var crc = 0xFFFF;
            for (k = 0; k < num; k++) { 
        
                crc = crc ^ shujv[k];    //一个十六进制的数和一个十进制的数也能直接进行异或逻辑运算(js中会默认先把两个数转成统一的二进制数,在进行异或逻辑运算)
                for (j = 0; j < 8; j++) { 
             //循环移位八次;
                    temp = crc & 0x0001;   //判断CRC寄存器最后一位是否是1
                    crc = crc >> 1;     //CRC寄存器右移一位,整个循环下来总共移了八位;
                    if (temp)              //CRC寄存器最后一位是1,则执行以下异或逻辑
                    { 
        
                        crc = crc ^ 0xA001;      //CRC寄存器最后一位是1,再与0xA001异或运算;
                    }
                }
            }

3 程序调试

3.1 修改文档位置,导致节点不存在

  node-red页面中存在没有定义的节点时会影响部署,比如说有一个节点没有安装在node-red中,就像我改变了文件的地址,这样就会在node-red中是个虚框,然后如果不把他删除就会影响部署。一旦删除虚框节点就得到了结果。
  之所以会出现这种情况就是我更改了文件的地址(之前在D盘,我改到了C盘),在节点文件夹位置改变以后要重新在node-red安装节点,npm install一下。这里要注意文件名不能是有空格的,比如lower case不可以,要用lower_case。

  • 变量后边不能加逗号,比如var a 不能写成var a,

3.2 单元测试

  测试有两种办法,有一种是在node-red中写test_spec.js文件。另一种办法是复制出来除了node-red的结构的语句,然后提出来命名js文件。

3.2.1 方法一

方法一:在做本地测试的时候,把js文件复制出来,不要用node-red的任何结构。

Launch.json是程序调试的一个自动化脚本。需要在里边写上如图的语句,只有有这个才能一步一步的调试。

3.2.2 方法二

方法二:单步调试(写测试结构用例)
Custom_node是在打印日志以后根据打印的信息修改的test.spec.js。根据下图信息修改,都需要那些属性。

在终端执行npm test 得到结果:

这个之所以不能用下图这种是因为运行如下图中的语句,是因为该结构中有node-red的结构,只能用npm test。

3.3 单步调试

问题一:
  监听test1,显示未定义,test1是test函数的内部变量,等进到test函数里的时候test1才会有数。

问题二:
  这个测试框架必须是基于_spec.js测试用例的,所以js文件也是在这个的基础上进行测试的,比如说有个节点按钮功能,这个按钮功能在测试用例中并没有写,所以在测试的时候应该把他先给注销,然后在单步调试,不然的话,就会出现错误。

问题三:
  添加断点后,单步调试时程序运行暂停,且单步调试按键变灰无法点击,需要检查一下有没有打开错的调试文件或者出现已经运行完毕需要重新运行的问题

  打开以后需要看错误出现在哪里,然后把断点放在哪里,然后进行单步调试。

  从cmd中找到错误出现在第53行,把断点加在53行,既然不能读出数据,表示buffer出现了问题,也就是test1出现了问题,添加一个监视test1,然后发现buffer里面只有一个数据,无法取到3,4,5,6个数据。

3.4 解决单步调试遇到的问题

出错问题
TypeError: Cannot read properties of undefined (reading ‘toString’)

  该错误为无法读取未定义的属性(toString)。即程序中s2的值无法读取,进一步查找错误发现s2中为空值,s2取得是buffer数组中的第四位数据,通过多次单步调试最终找到错误,串口数据有时并不能将所有数据全部返回,当只返回两三位数据时,第四位即没有数据,就会出现上述错误。
解决办法:可以使用serialport中内置的一些数据解析器,主要用来处理收到的一些常见形式的串口数据。在这里可以用到ByteLength Parser,它可以以收到的数据长度为单位进行解析:

const SerialPort = require('serialport');
const port = new SerialPort('COM6');

const Delimiter = require('@serialport/parser-delimiter');
const parser = port.pipe(new Delimiter({ 
         delimiter: '\n' })); // 以 \n 分隔处理数据
parser.on('data', chunk => { 
        
    console.log(chunk.toString()); // 打印收到的数据
});

  下图红框是buffer的九位,其中包括数据位,地址位…校验位共九位。
  我的温湿度获取的时候出现了温度飙升的问题。然后是因为转换的时候出现了问题。

  红色的是加的语句,从buffer中读取9位数,出现错误要相应的把绿色框中的port改为parser。
  红框中在没改红色的10以前是16,16是错误的,会影响数据的采集,出现温度过高的问题。

  黄框中就是温度过高,温度过高检查办法:
可以先在node-red界面中设置一个流测试所出现的问题是否为在十进制转十六进制中转换出错,是否不需要转换。

  这个buffer中输入数组[1,1],然后写函数,看看转出来的数据是否为所需要的。

  这个函数是从我的temperature1.js 文件中提出来的温度获取的那部分。取buffer的第0位和第一位,而buffer又是[1,1],所以最后取出来的数就是0101,0101转换成10进制就是257。
  var abc = parseInt(c, 10) / 10,因为我有这一步,之前是(c,16),当是16的时候获取的数是599。parseInt是把一个几进制数改为十进制数。我写16的时候是把16进制c改为10进制。

3.5 其他相关的问题

3.5.1 打印日志

  图框中标红的在终端为什么看不到打印日志的东西,因为这个必须在node-red里面才能看到,要运行一次。才能在cmd中看到想要看到的东西。在js文件里打印日志—console.log(node),在cmd中运行。

3.5.2 闪退现象

  运行程序的时候闪退的问题,点一下没反应,点一下没反应,一定要在点一个断点然后才能一步一步的调试。在调试的过程中,一定要看控制面板部分的调试控制台,如果出错误,没有看到调试控制台,而调试控制台一直有错误出现着,也会出现一直闪退的现象。像下图中是因为串口没有定义,由于接触不良造成了这样的问题。我再单步调试的时候也出现了一直闪退的现象。

3.5.3 点击按钮不出现温湿度显示

在node-red中点击按钮不出现温湿度显示。

  出现问题,先进行temperature_spec.js调试,在调试的时候,哪怕是官方调试工具也没有找到波特率和设备地址的信息,

然后找设备的问题,设备蓝线和棕线短路。
这些调好后,依然不能解决问题,开始进行程序调试,打开temperature.js文件,然后点击运行和调试,launch program(temperature)进行单步调试。

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章