这个项目首先是基于一个手术医生的私人微信云开发小程序。众所周知,腾讯为微信云开发小程序提供了5GB的免费云存储,足够一般用户个人的账目需求,而且云存储又有随时随地方便访问的特点,只要有wifi、有流量,拿起手机、打开微信,就能调用自己的小程序访问、查询、统计自己的私人数据。这个医生在湖南株洲是很有名气,作为人才引进来到深圳平乐骨伤科医院,认识到一位帮人做微信小程序的深圳软件工程师,惊喜云开发小程序的妙用,尝试了第一个自己的微信云开发小程序:记录、查询、统计多年来自己做过的超过千台数量的泌尿科结石手术。通过小程序中提供的时间段查询功能,可以方便快捷的查询某年、某月的手术数量,通过小程序的综合查询统计功能,输入不同的“关键字”,可以统计某个医院、某个部位的结石、某种治疗结石的技术以及其他某种特定的说明的手术数量。下图(1)是这个微信小程序的4个界面。
图(1)云开发小程序的4个界面
在手术室我们使用STONE的触控串口屏会更适合,STONE串口屏很高兴能为医疗器械提供更安全可靠的显示和控制界面。如果我们在手术室里要录入这些手术内容,手术设备的型号、参数也当然更加容易得到,甚至可以从系统中通过共享得到,更准确且省去了二次录入,当然这样的功能需要在设备前期规划,此处我通过STONE串口屏来演示这个微信小程序功能(不涉及数据库和云存储),作为抛砖引玉,读者有兴趣还可以进一步通过蓝牙配对,实现系统与手机的数据共享,完成本地数据的云端存储、以及云端数据下载到本地,通过蓝牙也能实现手机对STONE屏的控制、以及屏对手机端的反馈等。
结合STONE串口屏的软件平台,图(1)中的界面需做一些修改,操作方式和展示方法也会有所不同,当然程序代码也差别很大。微信小程序是基于JavaScript的,本STONE串口屏项目是基于arduino的ESP32环境。新的STONE界面医生手术笔记项目记录将按如下展开。
叙述内容:
- 人机界面和控件制作说明
- 界面下载
- 硬件连接与指令测试
- 调试代码
- 附录:ASCII码表
1.人机界面和控件制作说明
如图(2)开机可以通过不同的按钮分别进入手术记录---图(3)、时间段查询---图(5)、综合查询功能---图(7)。
如图(3),手术记录界面首先通过text_selector控件选择手术时间:年、月、日,选择手术部位,然后通过edit控件填入手术地点、手术使用的关键设备、手术说明,完成后点击save按钮,会弹出记录成功界面如图(4)。
图(2)开机功能界面
图(3)手术记录界面
在图(4)界面点击back按钮,返回到图(2)功能界面。若选择时间段查询,就进入图(5)界面,这里也是通过text_selector控件选择查询的开始日期和结束日期的年、月、日,再点击read按钮,进入图(6)查询结果展示。
图(4)记录成功界面
图(5)时间段查询界面
图(6)将展示指定时间段总共有记录多少台手术,并将第一台手术记录的内容展示在屏幕中间,点击Next按钮,会依次展示第二台、第三台的内容。这些内容都是通过ESP32控制表与STONE屏串口通讯传入到label控件、HScroll_label滚动控件中显示的。其中年、月、日、手术总数都是label控件,其他都是HScroll_label控件,可以滚动显示更多的内容。点击Back按钮返回在到图(2)功能界面。若在图(2)选择综合查询功能,就进入图(7)界面。
图(6)时间段查询结果界面
图(7)综合查询功能界面
在图(7)中通过edit接收关键字输入,点击read按钮进入图(8)结果界面,点击Back按钮返回图(2)。在图(8)中同图(6)类似,展示了符合关键字的总共手术台数,配合Next按钮展示全部手术的内容。也通过Back按钮返回图(2)。
上述提到的各个界面中涉及编程需要的控件name和范围、内容等,统一陈列在一起,方便编程时查阅。
图(8)综合查询结果界面
编程控件name:
手术记录界面save按钮:name = b12
手术记录内容text_selector,name分别为: year = ts11,month = ts12,day = ts13,part = ts14
其中:
ts11(2000--2099)年,ts12(1--12)月,ts13(1--31)日,
ts14(1:left renal;2:right renal;3:left ureteral;4:right ureteral;5:bladder;6:urethral;7:others;)
手术记录内容edit,name分别为:
Location = e11,Equipment = e12,Description = e13
手术时间段查询read按钮:name = b32
Start date:year = ts31,month = ts32,day = ts33
End date:year = ts34,month = ts35,day = ts36
范围同上。
时间段查询结果 Next 按钮:name = b42
Labal显示name分别为:
year = l41,month = l42,day = l43,total = l44
Hscroll label显示name分别为:
Location = hl41,equipment = hl42,part = hl43,description = hl44,during = hl45
关键字read按钮:name = b52,edit name = e51
关键字查询结果Next按钮:name = b62
Labal显示name分别为:
year = l61,month = l62,day = l63,total = l64
Hscroll label显示name分别为:
Location = hl61,equipment = hl62,part = hl63,description = hl64,during = hl65
2.界面下载
参照充电桩项目的方法B下载界面成功。
3.硬件连接与指令测试
图(9)串口助手指令测试V1.2转接板跳线链接图
STONE新版软件在持续升级完善中,使用中发现有部分功能与手册有出入,因此有必要在编程之前对需要用到的指令进行验证。按图(9)连接,通过串口助手查看STONE的反馈、验证指令的有效性。
本项目涉及的控件有button、label、HScroll_Label、edit、text_selector共5种,下面我们逐个测试验证。
button相关:
0x1001 button键值主动下发
键值(数据部分最后一字节):
0x01 press down按钮按下
0x02 press up 按钮松开(按钮完成 触发click点击事件)
例:
手术记录界面save按钮(name = b12 )按下主动下发指令:
ST<0x10 0x01 0x00 0x04 b12 0x01>ET
串口助手返回十六进制数据: 验证OK
53 54 3C 10 01 00 04 62 31 32 01 3E 45 54 5C 4F
按钮松开(完成按钮click动作)主动下发指令
ST<0x10 0x01 0x00 0x04 b12 0x02>ET
串口助手返回十六进制数据: 验证OK
53 54 3C 10 01 00 04 62 31 32 02 3E 45 54 18 4F
注:按钮b12(ASCII码 0x62 0x31 0x32)。
label相关:
set_text 设置label显示的文本
例:
设置文本: (关键字查询总数 name = l64)
ST<{"cmd_code":"set_text","type":"label","widget":"l64","text":"520"}>ET 验证上屏OK
hscroll_label相关:
set_text 设置hscroll_label显示的文本
例:
设置文本:
ST<{"cmd_code":"set_text","type":"hscroll_label","widget":"hl61","text":"ShenZhen"}>ET NG
ST<{"cmd_code":"set_text","type":"label","widget":"hl61","text":"ShenZhen"}>ET OK
注:NG是手册上给出的指令格式, OK是我自己尝试成功上屏的指令格式!这也是验证的重要收获!
edit相关:
get_text 获取edit显示的内容
0x1070 edit文本下发 (主动被动下发 可以是edit数据更改之后主动下发 也可以使用get_text主动获取)
文本: "控件名称":文本内容 数据长度不能超过1024字节 (:号之后的文本内容)
例:
获取文本: (手术记录的 Location 处edit控件 name = e11)
ST<{"cmd_code":"get_text","type":"edit","widget":"e11"}>ET
串口助手反馈十六进制数据如下:
53 54 3C 10 70 00 0C 22 65 31 31 22 3A 61 62 63 64 65 66 3E 45 54 20 FF
edit文本数据下发指令: 验证 OK
ST< 0x10 0x70 0x00 0x0C "e11": abcdef >ET e11文本数据:abcdef
text selector相关:
get_text 获取文本选择器的当前文本
get_value 获取文本选择器的当前数值
get_selected 获取文本选择器当前选择项序号(获取的是当前选择项的序号)
0x1080 text selector文本下发 (被动下发 MCU使用get_text主动获取)
0x1081 text selector数值下发 (int类型 主动/被动下发:MCU使用get_value命令获取)
0x1082 text selector序号下发 (int类型 被动下发:MCU使用get_selected命令获取)
数据格式:
text文本:"控件名称":文本内容 长度不超过1024字节 (控件名称:号之后的文本内容)
value数值:数据部分最后四字节
index数值:数据部分最后四字节
例1: (手术记录的部位控件name = ts14,当前是序号为0的“1:left renal;”)
获取文本选择器t14当前文本:
ST<{"cmd_code":"get_text","type":"text_selector","widget":"ts14"}>ET
串口助手反馈十六进制数据是:
53 54 3C 10 80 00 11 22 74 73 31 34 22 3A 6C 65 66 74 20 72 65 6E 61 6C 3E 45 54 F1 FE
屏下发的指令即为:
ST< 0x10 0x80 0x00 0x11 "ts14":left renal >ET ts14文本数据: left renal OK
获取文本选择器t14当前数值:
ST<{"cmd_code":"get_value","type":"text_selector","widget":"ts14"}>ET
串口助手反馈十六进制数据是:
53 54 3C 10 81 00 08 74 73 31 34 00 00 00 01 3E 45 54 DE CA OK
屏下发的指令即为:
ST<0x10 0x81 0x00 0x08 ts14 0x00 0x00 0x00 0x01 >ET ts14当前数值数据:1
获取文本选择器t14当前序号:
ST<{"cmd_code":"get_selected","type":"text_selector","widget":"ts14"}>ET
串口助手反馈十六进制数据是:(ts14是序号为0的“1:left renal;”)
53 54 3C 10 82 00 08 74 73 31 34 00 00 00 00 3E 45 54 21 C8 OK
屏下发的指令即为:
ST<0x10 0x82 0x00 0x08 ts14 0x00 0x00 0x00 0x00 >ET ts14当前序号:0
注:ts14的options为,
1:left renal;2:right renal;3:left ureteral;4:right ureteral;5:bladder;6:urethral;7:others;
***本处使用get_value获取的是格式中的编号; 而使用get_selected获取的是当前选择项的序号(该序号是从0开始的)。
例2: (手术记录的年控件name = ts11,options:2000-2099,当前:2022)
获取文本选择器t11当前文本:
ST<{"cmd_code":"get_text","type":"text_selector","widget":"ts11"}>ET
串口助手反馈十六进制数据是:(ts11是2022)
53 54 3C 10 80 00 0B 22 74 73 31 31 22 3A 32 30 32 32 3E 45 54 D7 37
屏下发的指令即为:
ST< 0x10 0x80 0x00 0x0B "ts11":2022 >ET ts11当前文本: 2022 OK
获取文本选择器t11当前数值:
ST<{"cmd_code":"get_value","type":"text_selector","widget":"ts11"}>ET
串口助手反馈十六进制数据是:
53 54 3C 10 81 00 08 74 73 31 31 00 00 07 E6 3E 45 54 95 89 OK
屏下发的指令即为:
ST<0x10 0x81 0x00 0x08 ts11 0x00 0x00 0x07 0xE6 >ET ts11当前数值:2022 = 7E6
获取文本选择器t11当前序号:
ST<{"cmd_code":"get_selected","type":"text_selector","widget":"ts11"}>ET
串口助手反馈十六进制数据是:(0x16 = 22)
53 54 3C 10 82 00 08 74 73 31 31 00 00 00 16 3E 45 54 56 0C OK
屏下发的指令即为:
ST<0x10 0x82 0x00 0x08 ts11 0x00 0x00 0x00 0x16 >ET ts11当前序号: 0x16 = 22
有了上面的指令测试,接下来就可以放心编程实现手术医生的记录、查询、统计功能了。当然首先还是硬件连接。我们是用ESP32开发板来实现与STONE串口屏的通讯。
如图(10),NodeMCU-32S开发板TX0、RX0、GND是需和STONE屏转接板对应连接,见图(11),以完成HMI信息交互。STONE屏接口是232信号,通过V1.2转接板变成MCU接口需要的TX、RX信号,才能电平匹配。图(11)左边是NodeMCU-32S板,蓝色(TX0)、红色(RX0)线接V1.2转接板跳线位置(旁边是取下的蓝色跳线),黑色连GND。
图(10)NodeMCU-32S开发板的TX0、RX0位置图
图(11)NodeMCU-32S开发板与V1.2转接板通讯连接图
4.调试代码
鉴于篇幅的原因,本项目重点在按钮解码和查询、统计编程。关于记录的输入或者系统规划前的数据共享、或者手机蓝牙的导入,因此这里就不做细节解码。
/*
Frank for Doctor T in 2022.05.01
use ESP32 of NodeMCU-32s in arduino 1.8.13
use STONE HMI in shenzhen
*/
//------Doctor T use----------2022.05.01------
int iSave = 0; // 1 = save key is true, 0 = save key is false.
int iReadTime = 0; // 1 = read time find is true, 0 = false.
int iNextTime = 0; // 1 = read time next is true, 0 = false.
int iReadWord = 0; // 1 = read word find is true, 0 = false.
int iNextWord = 0; // 1 = read word next is true, 0 = false.
int yearStart,monthStart,dayStart,yearEnd,monthEnd,dayEnd; //int (-32768,32767) unsigned int(0,65535)
String iwordIn,iwordBuf; // note: S is big of s.
int years[10],months[10],days[10];
String locations[10],equipments[10],parts[10],descriptions[10];
int totalTime,totalWord;
int iNumRecord = 0; // record num!
int nowNumWord = -1; //
int nowNumTime = -1; //
int i3;
int LED_blue = 2; // IO2, turn the LED on (HIGH is the voltage level)
int ii = 0;
int iii = 0;
//------------
unsigned int time_1s=0;
unsigned int time_1m=0;
unsigned int time_1h=0;
void setup() {
Serial.begin(115200);
pinMode(LED_blue, OUTPUT);
}
void loop() {
int inChar;
// 读取串口发送的信息,并简单解码:
if (Serial.available() > 0) {inChar = Serial.read();}
if (inChar == 0x62)
{
if (Serial.available() > 0){inChar = Serial.read();}
if (inChar == 0x31) {
if (Serial.available() > 0){ inChar = Serial.read();}
if (inChar == 0x32)
{
if (Serial.available() > 0){ inChar = Serial.read();}
if (inChar == 0x02)
{
iSave = 1; //62 31 32 02 is save key ok!
iReadWord = 0;
iReadTime = 0;
iNextWord = 0;
iNextTime = 0;
}
}
} else if (inChar == 0x33)
{
if (Serial.available() > 0){ inChar = Serial.read();}
if (inChar == 0x32)
{
if (Serial.available() > 0){ inChar = Serial.read();}
if (inChar == 0x02)
{
iReadWord = 0;
iReadTime = 1; //62 33 32 02 is time read key ok!
iNextWord = 0;
iNextTime = 0;
i3 = 0;
totalTime = 0;
nowNumTime = 0;
}
}
} else if (inChar == 0x34)
{
if (Serial.available() > 0){ inChar = Serial.read();}
if (inChar == 0x32)
{
if (Serial.available() > 0){ inChar = Serial.read();}
if (inChar == 0x02)
{
iNextWord = 0;
iNextTime = 1; //62 34 32 02 is time Next key ok!
}
}
} else if (inChar == 0x35)
{
if (Serial.available() > 0){ inChar = Serial.read();}
if (inChar == 0x32)
{
if (Serial.available() > 0){ inChar = Serial.read();}
if (inChar == 0x02)
{
iReadWord = 1; //62 35 32 02 is word read key ok!
iReadTime = 0;
iNextWord = 0;
iNextTime = 0;
i3 = 0;
totalWord = 0;
nowNumWord = 0;
}
}
} else if (inChar == 0x36)
{
if (Serial.available() > 0){ inChar = Serial.read();}
if (inChar == 0x32)
{
if (Serial.available() > 0){ inChar = Serial.read();}
if (inChar == 0x02)
{
iNextWord = 1; //62 36 32 02 is word find Next key ok!
iNextTime = 0;
}
}
}
}
//-------------test------begin----------------
years[0]=2021;
months[0]=1;
days[0]=1;
locations[0]="ShenZhen PinLe";
equipments[0]="holmic laser light";
parts[0]="left renal";
descriptions[0]="0.6cm";
years[1]=2021;
months[1]=2;
days[1]=2;
locations[1]="ShenZhen PinLe";
equipments[1]="holmic laser light";
parts[1]="right renal";
descriptions[1]="0.8cm";
iNumRecord = 2;
yearStart = 2021;
monthStart = 1;
dayStart = 1;
yearEnd = 2022;
monthEnd = 5;
dayEnd = 1;
iwordIn = "left";
//-------------test-----end-----------------
if(iReadTime == 1) // the time find!
{
iReadTime = 0;
for(int i = 0; i < iNumRecord; i++) // look totalTime
{
if(yearEnd > years[i] && years[i] > yearStart){
totalTime += 1;
if(nowNumTime == -1){ nowNumTime = i; }
}
else if(yearEnd == years[i]){
if(months[i] < monthEnd)
{
totalTime += 1;
if(nowNumTime == -1){ nowNumTime = i; }
}
else if(months[i] == monthEnd && days[i] <= dayEnd)
{
totalTime += 1;
if(nowNumTime == -1){ nowNumTime = i; }
}
}
else if(years[i] == yearStart)
{
if(months[i] > monthStart){
totalTime += 1;
if(nowNumTime == -1){ nowNumTime = i; }
}
else if(months[i] == monthStart && days[i] >= dayStart){
totalTime += 1;
if(nowNumTime == -1){ nowNumTime = i; }
}
}
}
if(nowNumTime >= 0)
{
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"l41\",\"text\":\"");
Serial.print(years[nowNumTime]);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"l42\",\"text\":\"");
Serial.print(months[nowNumTime]);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"l43\",\"text\":\"");
Serial.print(days[nowNumTime]);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"l44\",\"text\":\"");
Serial.print(totalTime);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"hl41\",\"text\":\"");
Serial.print(locations[nowNumTime]);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"hl42\",\"text\":\"");
Serial.print(equipments[nowNumTime]);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"hl43\",\"text\":\"");
Serial.print(parts[nowNumTime]);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"hl44\",\"text\":\"");
Serial.print(descriptions[nowNumTime]);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"hl45\",\"text\":\"");
Serial.print(String(yearStart)+"."+String(monthStart)+"."+String(dayStart)+"--"+String(yearEnd)+"."+String(monthEnd)+"."+String(dayEnd));
Serial.println("\"}>ET");
}
}
if(iNextTime == 1 && nowNumTime >=0 )
{
int i4 = nowNumTime + 1;
iNextTime = 0;
for(int i = i4; i < iNumRecord; i++) // look Next
{
if(yearEnd > years[i] && years[i] > yearStart){
if(nowNumTime < i4){ nowNumTime = i; }
}
else if(yearEnd == years[i]){
if(months[i] < monthEnd)
{
if(nowNumTime < i4){ nowNumTime = i; }
}
else if(months[i] == monthEnd && days[i] <= dayEnd)
{
if(nowNumTime < i4){ nowNumTime = i; }
}
}
else if(years[i] == yearStart)
{
if(months[i] > monthStart){
if(nowNumTime < i4){ nowNumTime = i; }
}
else if(months[i] == monthStart && days[i] >= dayStart){
if(nowNumTime < i4){ nowNumTime = i; }
}
}
}
if(nowNumTime >= i4)
{
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"l41\",\"text\":\"");
Serial.print(years[nowNumTime]);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"l42\",\"text\":\"");
Serial.print(months[nowNumTime]);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"l43\",\"text\":\"");
Serial.print(days[nowNumTime]);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"l44\",\"text\":\"");
Serial.print(totalTime);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"hl41\",\"text\":\"");
Serial.print(locations[nowNumTime]);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"hl42\",\"text\":\"");
Serial.print(equipments[nowNumTime]);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"hl43\",\"text\":\"");
Serial.print(parts[nowNumTime]);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"hl44\",\"text\":\"");
Serial.print(descriptions[nowNumTime]);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"hl45\",\"text\":\"");
Serial.print(String(yearStart)+"."+String(monthStart)+"."+String(dayStart)+"--"+String(yearEnd)+"."+String(monthEnd)+"."+String(dayEnd));
Serial.println("\"}>ET");
}
}
if(iReadWord == 1) // the word find!
{
iReadWord = 0;
for(int i = 0; i < iNumRecord; i++) // look totalWord
{
if(locations[i].indexOf(iwordIn) >= 0 || equipments[i].indexOf(iwordIn) >= 0 )
{
totalWord += 1;
if(nowNumWord == -1){ nowNumWord = i; }
} else if(parts[i].indexOf(iwordIn) >= 0 || descriptions[i].indexOf(iwordIn) >= 0)
{
totalWord += 1;
if(nowNumWord == -1){ nowNumWord = i; }
}
}
if(nowNumWord >= 0)
{
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"l61\",\"text\":\"");
Serial.print(years[nowNumWord]);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"l62\",\"text\":\"");
Serial.print(months[nowNumWord]);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"l63\",\"text\":\"");
Serial.print(days[nowNumWord]);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"l64\",\"text\":\"");
Serial.print(totalWord);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"hl61\",\"text\":\"");
Serial.print(locations[nowNumWord]);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"hl62\",\"text\":\"");
Serial.print(equipments[nowNumWord]);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"hl63\",\"text\":\"");
Serial.print(parts[nowNumWord]);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"hl64\",\"text\":\"");
Serial.print(descriptions[nowNumWord]);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"hl65\",\"text\":\"");
Serial.print(iwordIn);
Serial.println("\"}>ET");
}
}
if(iNextWord == 1 && nowNumWord >=0 )
{
int i5 = nowNumWord + 1;
iNextWord = 0;
for(int i = i5; i < iNumRecord; i++) // look Next
{
if(locations[i].indexOf(iwordIn) >= 0 || equipments[i].indexOf(iwordIn) >= 0 ){
if(nowNumWord < i5){ nowNumWord = i; }
}
else if(parts[i].indexOf(iwordIn) >= 0 || descriptions[i].indexOf(iwordIn) >= 0)
{
if(nowNumWord < i5){ nowNumWord = i; }
}
}
if(nowNumWord >= i5)
{
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"l61\",\"text\":\"");
Serial.print(years[nowNumWord]);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"l62\",\"text\":\"");
Serial.print(months[nowNumWord]);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"l63\",\"text\":\"");
Serial.print(days[nowNumWord]);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"l64\",\"text\":\"");
Serial.print(totalWord);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"hl61\",\"text\":\"");
Serial.print(locations[nowNumWord]);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"hl62\",\"text\":\"");
Serial.print(equipments[nowNumWord]);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"hl63\",\"text\":\"");
Serial.print(parts[nowNumWord]);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"hl64\",\"text\":\"");
Serial.print(descriptions[nowNumWord]);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"hl65\",\"text\":\"");
Serial.print(iwordIn);
Serial.println("\"}>ET");
}
}
//---time ++ ------
ii = ii + 1;
if(ii > 29){
time_1s = time_1s + 1;
ii = 0;
if(iii == 0){
digitalWrite(LED_blue, HIGH);
iii = 1;
}else{
iii = 0;
digitalWrite(LED_blue, LOW);
}
}
if(time_1s >= 60){
time_1s = 0;
time_1m = time_1m + 1;
if(time_1m >= 60){
time_1m = 0;
time_1h = time_1h + 1;
}
}
delay(10);
}
查询说明:
综合查询的包含关键字判断使用了String对象的indexOf() 方法(一个字符串在另一个字符串中的位置!)
语法:string.indexOf(val)
string.indexOf(val, from)
参数: string: a variable of type String
val: the value to search for - char or String
from: the index to start the search from
返回值:在其中的位置,否则返回 -1
例:
stringOne = "<HTML><HEAD><BODY>";
int bodyTag = stringOne.indexOf("<BODY>");
5.附录:ASCII码表
图(12)