Nodemcu读取编码器数据发送给Nodered并在ui显示

该博客介绍了如何使用NodeMCU连接编码器和4位TM1650数码管,实现实时数值累加显示,并通过UDP协议将数据发送到NodeRed进行同步显示。代码中包含了Arduino的编码器读取、数码管控制和UDP通信功能,以及NodeRed端的接收和显示逻辑。重点在于数据的拆分发送与重组以及心跳包的发送。

 nodemcu上连接编码器和4位TM1650数码管,编码器转动自动累加显示在数码管上,并通过UDP发送到Nodered 上实时同步显示

编码器连接在nodemcu 的I2C接口,TM1650模块连接见代码。

1代码

 platformio 上nodemcu代码

#include <Arduino.h>
#include <Wire.h>
#include <TM1650.h>

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <arduino-timer.h>

#ifndef STASSID
#define STASSID "xxxx"//写入自己烦人wifi热点的SSID
#define STAPSK "xxxxxx" //wifi热点的密码
#endif

#define LEFT D7
#define RIGHT D6
#define PUSH D5

TM1650 d;
uint8_t lrmem = 3;
int lrsum = 0;
int num = 0;
int temp_num = 0;
char charBuf[4];
char *cBuf;

unsigned int localPort = 8888; // local port to listen on
auto timer = timer_create_default(); // create a timer with default settings
// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE + 1]; //buffer to hold incoming packet,
char ReplyBuffer[4];						   //

WiFiUDP Udp;
bool heart(void * ) {
      Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
	  Udp.write('a');
	  Udp.endPacket();
	  return true;
}
int8_t rotary()
{
	static int8_t TRANS[] = {0, -1, 1, 14, 1, 0, 14, -1, -1, 14, 0, 1, 14, 1, -1, 0};
	int8_t l, r;
	l = digitalRead(LEFT);
	r = digitalRead(RIGHT);
	lrmem = ((lrmem & 0x03) << 2) + 2 * l + r;
	lrsum = lrsum + TRANS[lrmem];
	/* encoder not in the neutral state */
	if (lrsum % 4 != 0)
		return (0);
	/* encoder in the neutral state */
	if (lrsum == 4)
	{
		lrsum = 0;
		return (1);
	}
	if (lrsum == -4)
	{
		lrsum = 0;
		return (-1);
	}
	/* lrsum > 0 if the impossible transition */
	lrsum = 0;
	return (0);
}

char *ToDisplayBuf(unsigned int Low_Dat)
{
	//显示缓冲区
	static char DispTemp[5];
	if ((Low_Dat >= 0) && (Low_Dat < 10))
		DispTemp[0] = ' ';
	DispTemp[1] = ' ';
	DispTemp[2] = 48; //个位显示小数前加0
	DispTemp[3] = Low_Dat + 48;
	if ((Low_Dat >= 10) && (Low_Dat <= 99))
	{
		DispTemp[0] = ' ';
		DispTemp[1] = ' ';
		DispTemp[2] = Low_Dat % 100 / 10 + 48;
		DispTemp[3] = Low_Dat % 10 + 48;
	}
	if ((Low_Dat >= 100) && (Low_Dat <= 999))
	{
		DispTemp[0] = ' ';
		DispTemp[1] = Low_Dat % 1000 / 100 + 48;
		DispTemp[2] = Low_Dat % 100 / 10 + 48;
		DispTemp[3] = Low_Dat % 10 + 48;
	}
	if ((Low_Dat >= 1000) && (Low_Dat < 9999))
	{
		DispTemp[0] = Low_Dat / 1000 + 48;
		DispTemp[1] = Low_Dat % 1000 / 100 + 48;
		DispTemp[2] = Low_Dat % 100 / 10 + 48;
		DispTemp[3] = Low_Dat % 10 + 48;
	}
	DispTemp[4] = '\0';
	return DispTemp;
}
void setup()
{
   	pinMode(LEFT, INPUT);
	pinMode(RIGHT, INPUT);
	pinMode(PUSH, INPUT);
	pinMode(LEFT, INPUT_PULLUP);
	pinMode(RIGHT, INPUT_PULLUP);
	pinMode(PUSH, INPUT_PULLUP);
	// Wire.setSCL(A5);
	// Wire.setSDA(A4);
	Wire.begin(); //Join the bus as master
	// Serial.setRx(PA10);
	// Serial.setTx(PA9);
	Serial.begin(115200);
	Serial.println(num, DEC);
	d.init();
	d.displayOff();
	d.setBrightness(TM1650_MAX_BRIGHT);
	d.displayOn();
    
	WiFi.mode(WIFI_STA);
	WiFi.begin(STASSID, STAPSK);
	while (WiFi.status() != WL_CONNECTED)
	{
		Serial.print('.');
		delay(500);
	}
	Serial.print("Connected! IP address: ");
	Serial.println(WiFi.localIP());
	Serial.printf("UDP server on port %d\n", localPort);
	Udp.begin(localPort);
	timer.every(10000, heart);//15秒发送一次心跳
}
void loop()
{
	int8_t res;
	int packetSize = Udp.parsePacket();
	if (packetSize)
	{
		Serial.printf("Received packet of size %d from %s:%d\n    (to %s:%d, free heap = %d B)\n",
					  packetSize,
					  Udp.remoteIP().toString().c_str(), Udp.remotePort(),
					  Udp.destinationIP().toString().c_str(), Udp.localPort(),
					  ESP.getFreeHeap());

		// read the packet into packetBufffer
		int n = Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
		packetBuffer[n] = 0;
		Serial.println("Contents:");
		Serial.println(packetBuffer);
	}
	
		res = rotary();
		if (res != 0)
		{
			num = num + res;
			// Serial.println(num);
			if (num < 0)
				num = 0;
			temp_num=num;
			cBuf = ToDisplayBuf(num);
		    d.displayString(cBuf);
		    d.setDot(2, 1);
			// send a reply, to the IP address and port that sent us the packet we received
			ReplyBuffer[0] = temp_num & 255;
			ReplyBuffer[1] = temp_num >> 8;
			Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
			Udp.write(ReplyBuffer,4);
			Udp.endPacket();
		}
		if (digitalRead(PUSH) == 0)
		{
			// Serial.println(num);
			delay(250);
		}
		// dtostrf(num, 4, 0, charBuf);
		// d.displayString(charBuf);
	
	   timer.tick(); // tick the timer	
	}

NodeRed 代码

[
    {
        "id": "300270cf7ee6a48d",
        "type": "tab",
        "label": "接收NODEMCU 上传编码器数据",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "0f0d164254a400af",
        "type": "inject",
        "z": "300270cf7ee6a48d",
        "name": "",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "UDP消息来自NodeRed!这是第",
        "payloadType": "str",
        "x": 210,
        "y": 200,
        "wires": [
            [
                "aaa4d5c9a87dc066"
            ]
        ]
    },
    {
        "id": "64ce6c0c057e316b",
        "type": "udp out",
        "z": "300270cf7ee6a48d",
        "name": "esp8266",
        "addr": "192.168.8.100",
        "iface": "",
        "port": "8888",
        "ipv": "udp4",
        "outport": "49473",
        "base64": false,
        "multicast": "false",
        "x": 740,
        "y": 160,
        "wires": []
    },
    {
        "id": "b2de3e52e533b9ab",
        "type": "debug",
        "z": "300270cf7ee6a48d",
        "name": "1",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 730,
        "y": 300,
        "wires": []
    },
    {
        "id": "aaa4d5c9a87dc066",
        "type": "function",
        "z": "300270cf7ee6a48d",
        "name": "",
        "func": "var msg1=msg;\nvar cnt=global.get('counter')||0;//声明全局变量\ncnt+=1;\nmsg.payload=msg1.payload+cnt+\"次数发送消息\";\nglobal.set('counter',cnt);\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 450,
        "y": 200,
        "wires": [
            [
                "b2de3e52e533b9ab",
                "64ce6c0c057e316b"
            ]
        ]
    },
    {
        "id": "caf5712c0ec25d50",
        "type": "udp in",
        "z": "300270cf7ee6a48d",
        "name": "",
        "iface": "",
        "port": "49473",
        "ipv": "udp4",
        "multicast": "false",
        "group": "",
        "datatype": "buffer",
        "x": 120,
        "y": 360,
        "wires": [
            [
                "ebbbb413b28d9b67"
            ]
        ]
    },
    {
        "id": "df83f185889704bb",
        "type": "ui_text",
        "z": "300270cf7ee6a48d",
        "group": "5d26477fb5b7b266",
        "order": 1,
        "width": "0",
        "height": "0",
        "name": "",
        "label": "",
        "format": "<font size=30 font> {{msg.payload}}</font>",
        "layout": "col-center",
        "className": "",
        "x": 550,
        "y": 500,
        "wires": []
    },
    {
        "id": "ebbbb413b28d9b67",
        "type": "function",
        "z": "300270cf7ee6a48d",
        "name": "字节合并整型数",
        "func": "byteArrayToInt = function(/*byte[]*/byteArray) {\n    var value = 0;\n    for ( var i = byteArray.length - 1; i >= 0; i--) {\n        value = (value * 256) + byteArray[i];\n    }\n    return value;\n};\nif(msg.payload.length>1)\n {\n     a=byteArrayToInt(msg.payload);\n     msg.payload=a;\n     return msg;\n }",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 300,
        "y": 360,
        "wires": [
            [
                "df83f185889704bb",
                "e557418cb588041d"
            ]
        ]
    },
    {
        "id": "e557418cb588041d",
        "type": "debug",
        "z": "300270cf7ee6a48d",
        "name": "2",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 550,
        "y": 360,
        "wires": []
    },
    {
        "id": "5d26477fb5b7b266",
        "type": "ui_group",
        "name": "EC11数据显示",
        "tab": "5d4a1974427bbb81",
        "order": 1,
        "disp": true,
        "width": "3",
        "collapse": false,
        "className": "<font size=26 font> EC11数据显示</font>"
    },
    {
        "id": "5d4a1974427bbb81",
        "type": "ui_tab",
        "name": "Home",
        "icon": "dashboard",
        "disabled": false,
        "hidden": false
    }
]

2要点

1 UDP心跳

  每隔10秒发送一次字符‘a’数据给NodeRed。

2 UDP传送整形数据

  arduino 的UDP.write函数是按字节发送的,整型数据必须拆分发送

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

armcsdn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值