?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函数是按字节发送的,整型数据必须拆分发送
|