[mw_shl_code=arduino,true]主MCU代码:
//due端,键盘输入、字符作用区分、屏幕显示、菜单控制
#include <SPI.h>
#include <SdFat.h>
#include <KeyboardController.h>
USBHost usb;
KeyboardController keyboard(usb);
#define STARTCHAR '{'//分段,开始
#define ENDCHAR '@'//完结
#define PAGECHAR '}'//句号
#define RADIOCHAR '^'//无线电信号
#define WARNCALL "XXX"//警报信号
#define DIAGONAL "/"//斜线
#define BRACKET "<"//括号
#define CORRECTS "?"//改错,数码
#define CORRECTL "|"//改错,字码、混合码
#define POINT "."//小数点
#define MAXSPEED 200//最大发报速度
#define MINSPEED 60//最小发报速度
#define FREELENGTHMAX 50//自由区内容最大长度
#define MSGMAXLENGTH 254//报文区最大字符数
//命令代码
#define AUTOCALLSTART 242//警报台自动呼叫开始
#define AUTOCALLSTOP 243//警报台自动呼叫结束
#define CHANGESPEED 240//调整速度命令,发给nano时用
#define RECORDSTART 246//开始记录发报内容
#define RECORDSTOP 247//结束记录发报内容
#define UPLOADLOG 248//通知Nano回传记录的发报内容
#define USEDATASTART 251//开始调用报底发报
#define USEDATAEND 252//结束调用报底发报
#define STOPFORREADY 250//通知Nano停止发报,并将除发报记录外的各参数复位
#define NEXTPAGE 126//Nano请求发下一页报文
SdFat sd;
const byte pinChipSelect =44;// 30;
const byte pinLedR = 38;//32;
const byte pinLedG = 36;//34;
const byte pinLedB = 34;//36;
//const byte pinDisplayPower=25;//此脚控制显示屏的供电
const byte numberLong=-15;
byte sys0=1;//电报的报文内容是随输随发1,还是一页一键发送0,还是调用发送2(调用报底发送时用)sendActId
//byte wordsTotal=0;//报文组数
//byte proFlag=0;//一般电报处理进程标识,0没有开始,1已发报头,2已发开始符号,3已发结束符号
int sendActId=1;//发报界面活动控件:0报文区,1自由勤务,2速度,3号数,4组数,5等级,6日期,7时间,8备注,9号数2,10组数2;调用报文界面:0种类,1页码,2组数;
byte actIdPre=0;//前一活动控件id
byte sys1=1;//报文分类:1电 报,2业务公电,3无线信号,4警报信号,5通信检查,0自由联络
byte scrId=1;//当前所处界面:0主界面main,1发报send,2自动呼叫autoCall,3调用报文useData,4工作日志workLog,5系统设置sysSet,6关于about,7输入对话框,8确认对话框
byte sys2=0;//标识数码电报是长码1还是短码0
byte endFlag=0xff;
byte saveOrUse=0;//标识调用自动呼叫界面时,是保存1还是调入0
byte autoCallIndex=0;
byte cSave=0;//标识当前是否记录工作日志
String msgFileName="";//文件名
//String msgFileName2="";//文件名
String msgSpeed="100";//范围60-250
String numberForNano="";
String numberForScrn="";
String msgGroup="";
String msgClass="";
String msgDate="";
String msgTime="";
String msgMarket="";
String msg="";//报文区内容,发往Nano的
String msgForDisplay="";//报文区内容,发往显示屏显示的
String freeForNano="";//自由区内容,发往nano的
String freeForScrn="";//自由区内容,发往显示屏的
//报底调用变量
byte dataKind=0;//报底种类:0数码(共有999页),1字码(共99页),2混合码(共99页)
bool dataSendStarted=false;//调用报底时使用,标识报底是否已发送 // note check kil
int dataPageNow=1;//当前界面显示发送的是第几页
int dataPage=1;//共有多少页
int dataGroup=100;//剩多少组没读取发送
int dataPositionFrom=0;//起始位置
//String dataMsg="";//调用报底内容
byte pgIndex=0;//系统调试项目下标
void closeOrOpenDisplay(){
//digitalWrite(pinDisplayPower,!digitalRead(pinDisplayPower));
return;
}
bool initDataNum(bool balance=false){//999页
sd.remove("SYSDATANUM.txt");
if (sd.exists("SYSDATANUM.txt")) {
Serial.println(" delete fail !");
return false;
}
randomSeed(analogRead(0));
SdFile myFile("SYSDATANUM.txt", FILE_WRITE);
if (myFile.isOpen()) {
for(int i=1;i<1000;i++){
for(int j=1;j<101;j++){
myFile.print(random(10));
myFile.print(random(10));
myFile.print(random(10));
myFile.print(random(10));
myFile.print(" ");
}}
//myFile.save();
myFile.close();
Serial.println("init success !");
return true;
} else {
Serial.println("write fail !");
return false;
}
}
bool initDataChr(bool balance=false){//99页
sd.remove("SYSDATACHR.txt");
if (sd.exists("SYSDATACHR.txt")) {
Serial.println(" delete fail !");
return false;
}
randomSeed(analogRead(0));
SdFile myFile("SYSDATACHR.txt", FILE_WRITE);
if (myFile.isOpen()) {
for(int i=1;i<1000;i++){
for(int j=1;j<101;j++){
myFile.write(random(65,91));
myFile.write(random(65,91));
myFile.write(random(65,91));
myFile.write(random(65,91));
myFile.print(" ");
}}
myFile.close();
Serial.println("init success !");
return true;
} else {
Serial.println("write fail !");
return false;
}
}
bool initDataBoth(){//99页
sd.remove("SYSDATABOTH.txt");
if (sd.exists("SYSDATABOTH.txt")) {
Serial.println(" delete fail !");
return false;
}
randomSeed(analogRead(0));
SdFile myFile("SYSDATABOTH.txt", FILE_WRITE);
if (myFile.isOpen()) {
for(int i=1;i<100;i++){
for(int j=1;j<101;j++){
if(random(2)){
myFile.write(random(48,58));
}else{
myFile.write(random(65,91));}
if(random(2)){
myFile.write(random(48,58));
}else{
myFile.write(random(65,91));}
if(random(2)){
myFile.write(random(48,58));
}else{
myFile.write(random(65,91));}
if(random(2)){
myFile.write(random(48,58));
}else{
myFile.write(random(65,91));}
myFile.print(" ");
}}
myFile.close();
Serial.println("init success !");
return true;
} else {
Serial.println("write fail !");
return false;
}
}
//读取1页系统报底,2个使用场合:调用发送时调用报底,供sendDataNextPage调用
bool readData(){
if(dataGroup<=0)return false;
String tem="";
char* fileName;
unsigned int dataPositionEnd=0;
if(dataGroup>=100){
dataPositionEnd=dataPositionFrom+500;
dataGroup=dataGroup-100;
}else{
dataPositionEnd=dataPositionFrom+dataGroup*5;
dataGroup=0;
}
if(dataKind==0){
fileName="SYSDATANUM.txt";
}else if(dataKind==1){
fileName="SYSDATACHR.txt";
}else{
fileName="SYSDATABOTH.txt";
}
SdFile myFile4(fileName, FILE_READ);
if (myFile4.isOpen()) {
myFile4.seekSet(dataPositionFrom);
while (dataPositionFrom<=dataPositionEnd && myFile4.available()) {
tem=tem + char(myFile4.read());
}
myFile4.close();
dataPositionFrom=dataPositionEnd;
Serial.println("read success");
if(dataGroup){
msgForDisplay=String(STARTCHAR) + tem + String(PAGECHAR);
}else{
msgForDisplay=String(STARTCHAR) + tem + String(ENDCHAR);
}
return true;
} else {
Serial.println("open error");
return false;
}
}
String replaceNumberToLong(String msg){
msg.replace('0','!');
msg.replace('1','"');
msg.replace('2','#');
msg.replace('3','$');
msg.replace('4','%');
msg.replace('5','&');
msg.replace('6','\'');
msg.replace('7','(');
msg.replace('8',')');
msg.replace('9','*');
return msg;
}
//读取并使用1页报底,使用在2个地方:Nano发来的请求命令,调用发送时在报文区按回车开始发送(fistPage=true)
bool sendDataNextPage(bool fistPage=false){
if(!fistPage){
if(!readData())return false;
cmdToDisplay("t10.txt=\"" + msgForDisplay + "\"");//显示报文
}else{
byteToNano(USEDATASTART);
dataSendStarted=true;//标识开始发送
}
dataPageNow=dataPageNow+1;
cmdToDisplay("nPage.txt=\"" + String(dataPageNow) + "/" + String(dataPage) + "\"");//更新界面页码
msg=msgForDisplay;
if(sys2==1 || dataKind==2){//数字发长码
msg=replaceNumberToLong(msg);
}
msgToNano(msg);
if(dataPageNow>=dataPage){
byteToNano(USEDATAEND);//已发送完,通知Nano,且发送模式自动变为一键发送
sys0=0;
cmdToDisplay("sys0=0");
cmdToDisplay("click t11,0");
return false;
}
}
//读worklog
String readLog(){
String msg="";
SdFile myFile("WORKLOG.txt", FILE_READ);
if (myFile.isOpen()) {
while (myFile.available()) {
msg=msg + String(char(myFile.read()));
}
myFile.close();
Serial.println(msg);
return msg;
} else {
Serial.println("read error");
myFile.close();
return "";
}
}
//电报记录
bool saveLog(String fileContent){
//SdFile myFile;
File myFile;
myFile = sd.open("WORKLOG.txt", FILE_WRITE);//Nano的内容
if (myFile.isOpen()) {
myFile.println(fileContent);
myFile.close();
Serial.println("SAVELOG ok !");
return true;
}else{
Serial.println("SAVELOG FAIL !");
myFile.close();
return false;
}
}
//保存自动呼叫
bool saveCall(){
freeForScrn.replace(" "," ");
freeForScrn.replace(" "," ");
freeForScrn.replace(" "," ");
String call=String(autoCallIndex) + "." +freeForScrn;
SdFile myFile("AUTOCALL.txt", FILE_WRITE);
if (myFile.isOpen()) {
Serial.println("writing:" + call);
myFile.seekSet(15*autoCallIndex);
myFile.print(call);
myFile.close();
autoCallIndex=0;
Serial.println("save ok ...");
return true;
}
myFile.close();
autoCallIndex=0;
return false;
}
bool initAutocall(){//初始化自动呼叫文件
SdFile myFile("AUTOCALL.txt", FILE_WRITE);
if (!myFile.isOpen())return false;
for(byte i=0;i<10;i++){
myFile.seekSet(15*i);
myFile.print(String(i)+". ");
}
myFile.close();
return true;
}
//读取全部呼叫
String readAll(){
String tem="";
for(int i=0;i<10;i++){
tem=tem + readCall(i) + char(13) + char(10);
}
Serial.println(tem);
return tem;
}
//读取单条呼叫,主要被readAll调用
String readCall(byte index){
String msg="";
byte i=0;
SdFile myFile("AUTOCALL.txt",FILE_READ);
if (myFile.isOpen()) {
myFile.seekSet(15*index);
while (i<15 && myFile.available()) {
i++;
msg=msg + String(char(myFile.read()));
}
myFile.close();
Serial.println(msg);
return msg;
} else {
Serial.println("read error");
myFile.close();
return "";
}
}
bool saveAs(char * fileName){
SdFile myFile("WORKLOG.txt", FILE_READ);
if (!myFile.isOpen())return false;
if (!myFile.rename(sd.vwd(),fileName)) return false;
return true;
}
//发往显示屏的字符
bool charToDisplay(String cmd){
cmdToDisplay("send.valStrS.txt=\"" + cmd + "\"");
cmdToDisplay("click btnDisplay,1");
}
//发往显示屏的命令
bool cmdToDisplay(String cmd){
Serial.println(cmd);
//return true;
Serial1.print(cmd);
Serial1.write(endFlag);
Serial1.write(endFlag);
Serial1.write(endFlag);
return true;
}
//发往Nano的消息
bool msgToNano(String msg){
Serial3.print(msg);
Serial.println(msg);
return true;
}
bool byteToNano(byte msg){
Serial3.write(msg);
Serial.println(msg);
return true;
}
//速度值验证
void checkSpeed(){
//if(sendActId || scrId!=1)return;
int temVal=msgSpeed.toInt();
if(temVal>=60 && temVal<=250)return;
if(temVal<60)temVal=60;
if(temVal>250)temVal=250;
msgSpeed=String(temVal);
byteToNano(CHANGESPEED);
byteToNano(byte(msgSpeed.toInt()));
cmdToDisplay("t0.txt=\"" + msgSpeed + "\"");
}
//号数中0的处理,若号数为数字与字母混合,数字0发长码,被sendEnter调用
String SLTranslate(String numberForNano){
if(numberForNano.indexOf("/")>-1 && numberForNano.indexOf("0")>-1){
numberForNano.replace('0','!');
}
return numberForNano;
}
//所有退格的处理
void proBackSpace(){
switch(sendActId){
case 0:
msgSpeed=msgSpeed.substring(0,msgSpeed.length()-1);
cmdToDisplay("t0.txt=t0.txt-1");
break;
case 1:
freeForNano=freeForNano.substring(0,freeForNano.length()-1);
freeForScrn=freeForScrn.substring(0,freeForScrn.length()-1);
cmdToDisplay("t1.txt=t1.txt-1");
break;
case 2:
numberForNano=numberForNano.substring(0,numberForNano.length()-1);
numberForScrn=numberForScrn.substring(0,numberForScrn.length()-1);
cmdToDisplay("t2.txt=t2.txt-1");
break;
case 3:
msgGroup=msgGroup.substring(0,msgGroup.length()-1);
cmdToDisplay("t3.txt=t3.txt-1");
break;
case 4:
msgClass=msgClass.substring(0,msgClass.length()-1);
cmdToDisplay("t4.txt=t4.txt-1");
break;
case 5:
msgDate=msgDate.substring(0,msgDate.length()-1);
cmdToDisplay("t5.txt=t5.txt-1");
break;
case 6:
msgTime=msgTime.substring(0,msgTime.length()-1);
cmdToDisplay("t6.txt=t6.txt-1");
break;
case 7:
numberForNano=numberForNano.substring(0,numberForNano.length()-1);
numberForScrn=numberForScrn.substring(0,numberForScrn.length()-1);
cmdToDisplay("t7.txt=t7.txt-1");
break;
case 8:
msgGroup=msgGroup.substring(0,msgGroup.length()-1);
cmdToDisplay("t8.txt=t8.txt-1");
break;
case 9:
msgMarket=msgMarket.substring(0,msgMarket.length()-1);
cmdToDisplay("t9.txt=t9.txt-1");
break;
case 10://发报界面-报文区
msg=msg.substring(0,msg.length()-1);
msgForDisplay=msgForDisplay.substring(0,msgForDisplay.length()-1);
cmdToDisplay("t10.txt=t10.txt-1");
break;
case 11://调用报文界面-报文种类
break;
case 12://调用报文界面-起始页码
dataPage=dataPage/10;
//if(dataPage)dataPage=1;
cmdToDisplay("n1.val=" + String(dataPage));
break;
case 13://调用报文界面-调用组数
dataGroup=dataGroup/10;
//if(dataGroup)dataGroup=1;
cmdToDisplay("n2.val=" + String(dataGroup));
break;
case 71://输入对话框
msgFileName=msgFileName.substring(0,msgFileName.length()-1);
cmdToDisplay("t0.txt=t0.txt-1");
break;
default:
break;
}
}
//所有清空的处理
void proDel(){
switch(sendActId){
case 0:
msgSpeed="";
cmdToDisplay("t0.txt=\"\"");
break;
case 1:
freeForNano="";
freeForScrn="";
cmdToDisplay("t1.txt=\"\"");
break;
case 2:
numberForNano="";
numberForScrn="";
cmdToDisplay("t2.txt=\"\"");
break;
case 3:
msgGroup="";
cmdToDisplay("t3.txt=\"\"");
break;
case 4:
msgClass="";
cmdToDisplay("t4.txt=\"\"");
break;
case 5:
msgDate="";
cmdToDisplay("t5.txt=\"\"");
break;
case 6:
msgTime="";
cmdToDisplay("t6.txt=\"\"");
break;
case 7:
numberForNano="";
numberForScrn="";
cmdToDisplay("t7.txt=\"\"");
break;
case 8:
msgGroup="";
cmdToDisplay("t8.txt=\"\"");
break;
case 9:
msgMarket="";
cmdToDisplay("t9.txt=\"\"");
break;
case 10:
if(sys0==2)return;
msg="";
msgForDisplay="";
cmdToDisplay("t10.txt=\"\"");
break;
case 11://调用报文界面-报文种类
break;
case 12://调用报文界面-起始页码
dataPage=0;
cmdToDisplay("n1.val=0");
break;
case 13://调用报文界面-调用组数
dataGroup=0;
cmdToDisplay("n2.val=0");
break;
case 71://输入对话框
msgFileName="";
cmdToDisplay("t0.txt=\"\"");
break;
}
}
//隐藏字符输入验证及处理;按下ctrl键即响应
void checkHide(byte chOemKey,int chMod){//扫描码,控制键状态(ctrl alt shift)
Serial.println(chOemKey);
//Serial.println(chMod);
//-------del(76)-------清空
if(chOemKey==76){
proDel();
return;
}
//-------backSpace(42)-------退格
if(chOemKey==42){
proBackSpace();
return;
}
if(!chMod)return;
//--------F12(69)--------焦点定位移动至报文区
if(chOemKey==69){
if(sendActId==0)checkSpeed();//纠正速度值至合理范围
if(sendActId<10){//当为10时已在报文区,故不响应
sendActId=10;
cmdToDisplay("click t1,0");
cmdToDisplay("send.sendActId.val=10");
}
return;
}
//--------F11(68)-------焦点定位移动至自由区
if(chOemKey==68){
if(sendActId==0)checkSpeed();
if(sendActId<11 && sendActId!=1){
sendActId=1;
cmdToDisplay("click t1,0");
cmdToDisplay("send.sendActId.val=1");
}
return;
}
//--------左箭头(80)-------焦点前移
if(chOemKey==80){
if(sendActId<21)cmdToDisplay("click t1,0");//先去掉原光标符号
switch(sendActId){
case 0:
checkSpeed();//纠正速度值
sendActId=10;
break;
case 1:
sendActId=0;
break;
case 2:
sendActId=1;
break;
case 3:
sendActId=2;
break;
case 4:
sendActId=3;
break;
case 5:
sendActId=4;
break;
case 6:
sendActId=5;
break;
case 7:
sendActId=1;
break;
case 8:
sendActId=7;
break;
case 9:
if(sys1==1)
sendActId=6;
else
sendActId=8;
break;
case 10:
sendActId=9;
break;
case 11://调用报文界面-报文种类(理论上不会为11)
sendActId=13;
cmdToDisplay("n1.picc=2");
cmdToDisplay("n2.picc=4");
break;
case 12://调用报文界面-起始页码
sendActId=13;
cmdToDisplay("n1.picc=2");
cmdToDisplay("n2.picc=4");
break;
case 13://调用报文界面-调用组数
sendActId=12;
cmdToDisplay("n1.picc=4");
cmdToDisplay("n2.picc=2");
break;
case 51://计算器第1个数
sendActId=52;
cmdToDisplay("n0.picc=2");
cmdToDisplay("n1.picc=4");
break;
case 52://计算器第1个数
sendActId=51;
cmdToDisplay("n0.picc=4");
cmdToDisplay("n1.picc=2");
break;
case 71://输入对话框
break;
default:
if(sendActId>=20 && sendActId<=25){//---main界面---
cmdToDisplay("click b" + String(sendActId-20) + ",0");
if(sendActId==20){
sendActId=25;
}else{
sendActId=sendActId-1;
}
cmdToDisplay("click b" + String(sendActId-20) + ",1");
}
return;
}
cmdToDisplay("send.sendActId.val=" + String(sendActId));
return;
}
//-------右箭头(79)-------焦点后移
if(chOemKey==79){
if(sendActId<21)cmdToDisplay("click t1,0");//先去掉原光标符号
switch(sendActId){
case 0:
checkSpeed();//纠正速度值
sendActId=1;
break;
case 1:
if(sys1==1)
sendActId=2;
else
sendActId=7;
break;
case 2:
sendActId=3;
break;
case 3:
sendActId=4;
break;
case 4:
sendActId=5;
break;
case 5:
sendActId=6;
break;
case 6:
sendActId=9;
break;
case 7:
sendActId=8;
break;
case 8:
sendActId=9;
break;
case 9:
sendActId=10;
break;
case 10:
sendActId=0;
break;
case 11://调用报文界面-报文种类(理论上不会为11的)
sendActId=12;
cmdToDisplay("n1.picc=4");
cmdToDisplay("n2.picc=2");
break;
case 12://调用报文界面-起始页码
sendActId=13;
cmdToDisplay("n1.picc=2");
cmdToDisplay("n2.picc=4");
break;
case 13://调用报文界面-调用组数
sendActId=12;
cmdToDisplay("n1.picc=4");
cmdToDisplay("n2.picc=2");
break;
case 51://计算器第1个数
sendActId=52;
cmdToDisplay("n0.picc=2");
cmdToDisplay("n1.picc=4");
break;
case 52://计算器第1个数
sendActId=51;
cmdToDisplay("n0.picc=2");
cmdToDisplay("n1.picc=4");
case 71://输入对话框
break;
default:
if(sendActId>=20 && sendActId<=25){//---main界面---
cmdToDisplay("click b" + String(sendActId-20) + ",0");
if(sendActId==25){
sendActId=20;
}else{
sendActId=sendActId+1;
}
cmdToDisplay("click b" + String(sendActId-20) + ",1");
}
}
cmdToDisplay("send.sendActId.val=" + String(sendActId));
return;
}
//-------F9(66)-------调整工作业务类型,仅发报界面
if(chOemKey==66){
if(sendActId<=10){
//wordsTotal=0;//报文组数
//proFlag=0;
if(sys1==5){
sys1=1;
if(sendActId==7)sendActId=2;
if(sendActId==8)sendActId=3;
}else{
sys1+=1;
if(sendActId==2)sendActId=7;
if(sendActId>2 && sendActId<7)sendActId=8;
}
msgToNano(String(char(AUTOCALLSTOP)));// 通知NANO暂停警报台自动呼叫(249命令不存在,但nano收到任何信息都会先暂停自动呼叫)
cmdToDisplay("sys1=" + String(sys1));
cmdToDisplay("click t21,0");//改显示屏上报文类型
}
return;
}
//-------上箭头(82)---------调高数值,改变枚举变量类型内容
if(chOemKey==82){
if(chMod==3){//ctrl+shift,调高屏幕亮度,弹起事件
cmdToDisplay("click tDisplayCtr,0");
return;
}
if(sendActId==0){//发报界面速度控件t0接受,调高发报速度
if(msgSpeed.toInt()+5<=MAXSPEED){
msgSpeed=String(msgSpeed.toInt()+5);
cmdToDisplay("t0.txt=\"" + msgSpeed + "\"");
byteToNano(CHANGESPEED);
byteToNano(byte(msgSpeed.toInt()));}
return;
}
if(sendActId==31){//自动呼叫界面,循环递增自动呼叫下标0-9
if(autoCallIndex==9){
autoCallIndex=0;
}else{
autoCallIndex++;
}
cmdToDisplay("t1.txt=\"" + String(autoCallIndex) + "\"");
return;
}
if(sendActId>=11 && sendActId<=19){//调用报底界面:循环改变报底种类:数码、字码、混合码
if(dataKind==2)
dataKind=0;
else
dataKind++;
cmdToDisplay("va0.val=" + String(dataKind));
cmdToDisplay("click t3,0");
}
if(sendActId==101){//系统调试
if(pgIndex==9){
pgIndex=0;
}else{
pgIndex++;
}
cmdToDisplay("t1.txt=\"" + String(pgIndex) + "\"");
return;
}
if(sendActId==51 || sendActId==52){//计算器,循环改变运算符+-*/%
cmdToDisplay("click t3,1");
return;
}
return;
}
//-------下箭头(80)--------调低数值
if(chOemKey==81){
if(chMod==3){//ctrl+shift,调暗屏幕,按下事件
cmdToDisplay("click tDisplayCtr,1");
return;
}
if(sendActId==0){//发报界面速度控件t0,调低发报速度
if(msgSpeed.toInt()-5>=MINSPEED){
msgSpeed=String(msgSpeed.toInt()-5);
cmdToDisplay("t0.txt=\"" + msgSpeed + "\"");
byteToNano(CHANGESPEED);
byteToNano(byte(msgSpeed.toInt()));}
return;
}
if(sendActId==31){//自动呼叫界面,循环递减自动呼叫下标0-9
if(autoCallIndex==0){
autoCallIndex=9;
}else{
autoCallIndex--;
}
cmdToDisplay("t1.txt=\"" + String(autoCallIndex) + "\"");
return;
}
if(sendActId>=11 && sendActId<=19){//调用报底界面:循环改变报底种类:数码、字码、混合码
if(dataKind==0)
dataKind=2;
else+
dataKind--;
cmdToDisplay("va0.val=" + String(dataKind));
cmdToDisplay("click t3,0");
return;
}
if(sendActId==51 || sendActId==52){//计算器,循环改变运算符+-*/%
cmdToDisplay("click t3,0");
return;
}
if(sendActId==73){//自动呼叫界面,循环递减自动呼叫下标0-9
if(pgIndex==0){
pgIndex=9;
}else{
pgIndex--;
}
cmdToDisplay("t1.txt=\"" + String(pgIndex) + "\"");
return;
}
return;
}
//--------F10(67)---------调整发送模式,仅发报界面
if(chOemKey==67){
if(sendActId<=10){
if(sys0>=1){
sys0=0;
}else{
sys0++;
}
cmdToDisplay("sys0=" + String(sys0));
cmdToDisplay("click t11,0");
}
return;
}
//--------F8(65)---------调整长短码,仅发报界面
if(chOemKey==65){
if(sendActId<=10){
if(sys2==1){
sys2=0;
cmdToDisplay("sys2=0");
}else{
sys2=1;
cmdToDisplay("sys2=1");
}
cmdToDisplay("click t12,0");
}
return;
}
//--------home()74-------返回主界面
if(chOemKey==74){
sendActId=20;
cmdToDisplay("page main");
return;
}
//--------F1(58)-------保存,工作日志的保存
if(chOemKey==58){
if(sendActId<=10 && cSave){//仅发报界面且处于保存状态下时响应
actIdPre=sendActId;
sendActId=71;//输入对话框界面
cmdToDisplay("page inputBox");
cmdToDisplay("t0.txt=\"" + msgFileName + "\"");//此处没有赋空串值,在不重启情况下默认为上次输入的名字
byteToNano(UPLOADLOG);//让nano把剩余的、未满页的内容发过来
}
return;
}
//--------F2(59)-------保存 //警报呼叫:自呼与被用的保存
if(chOemKey==59){
if(sendActId<=10 && sys1==4){//仅发报界面,且为警报信号时响应
actIdPre=sendActId;
sendActId=31;
saveOrUse=1;
autoCallIndex=0;
cmdToDisplay("page autoCall");
cmdToDisplay("va0.val=1");//标识保存
cmdToDisplay("click t1,0");
cmdToDisplay("t2.txt=\"" + readAll() + "\"");//将当前的自呼与自用全部读出展示
}
return;
}
//--------F3(60)-------报底调用,仅用于电报(调入系统报底、工作记录)、警报呼叫(调入自动呼叫的自呼和被用)
if(chOemKey==60){
if(sendActId<=10){
if(sys1==1){//发界面,电报,报底的调入
dataPage=1;
dataGroup=100;
dataKind=0;
actIdPre=sendActId;
sendActId=12;//激活控件id
cmdToDisplay("page useData");
cmdToDisplay("va0.val=0");
cmdToDisplay("n1.picc=4");
cmdToDisplay("n2.picc=2");
return;
}
if(sys1==4){//发界面,警报呼叫,调入自呼与被用
actIdPre=sendActId;
sendActId=31;//激活控件id
saveOrUse=0;
autoCallIndex=0;
cmdToDisplay("page autoCall");
cmdToDisplay("va0.val=0");//标识调用
cmdToDisplay("click t1,0");
cmdToDisplay("t2.txt=\"" + readAll() + "\"");
return;
}
return;
}
return;
}
//--------F4(61)-------日志保存开始/结束切换(若要保存日志,必须先保存,再结束,因为一但结束就会清空日志缓存变量)
if(chOemKey==61){
if(sendActId<=10){
if(cSave){
cSave=0;
byteToNano(RECORDSTART);
}else{
cSave=1;
byteToNano(RECORDSTOP);
}
cmdToDisplay("cSave.val=" + String(cSave));//更新显示显示屏上的选择框
if(cSave)sd.remove("WORKLOG.txt");//删除原日志文件,可能会有上次的记录(如上次开始记录了,但没有保存)
}
return;
}
//--------ESC(41)-------取消
if(chOemKey==41){
if((sendActId>=11 && sendActId<=19) || sendActId==31 || sendActId==71){
sendActId=actIdPre;
if(sendActId>10)sendActId=1;//防止意外发生
cmdToDisplay("page send");
return;
}
if(sendActId<=10 || sendActId==41 || sendActId==91 || sendActId==51 || sendActId==52){
sendActId=20;
cmdToDisplay("page main");
}
return;
}
//--------PgUp(73)-------上一页
if(chOemKey==173){//暂时取消
return;
if(sendActId<=10 && sys0==2){//发报界面,调用报底,显示上一页,循环式
if(dataPageNow==1){//当前为第一页则显示最后一页
dataPageNow=dataPage;
}else{
dataPageNow=dataPageNow-1;
}
msgForDisplay=msg.substring((dataPageNow-1)*500,499);//报文全部读出,需视情更改
cmdToDisplay("t10.txt=\"" + msgForDisplay + "\"");//显示第一页报文
cmdToDisplay("nPage.val="+dataPageNow);//更新界面页码
}
return;
}
//--------PgDn(81)-------下一页
if(chOemKey==81){//暂时取消
return;
if(sendActId<=10 && sys0==2){//发报界面,调用报底,显示下一页
if(dataPageNow==dataPage){
dataPageNow=1;
}else{
dataPageNow=dataPageNow+1;
}
msgForDisplay=msg.substring((dataPageNow-1)*500,499);
cmdToDisplay("t10.txt=\"" + msgForDisplay + "\"");//显示第一页报文
cmdToDisplay("nPage.val="+dataPageNow);//更新界面页码
}
return;
}
//--------PrtSc(55)-------打开、关闭显示屏(控制显示屏的供电)
if(chOemKey==55){
closeOrOpenDisplay();
}
//--------insert(73)-------编程调试
if(chOemKey==73){
sendActId=101;
pgIndex=0;
cmdToDisplay("page sysPg");
}
}
//所有界面回车的处理sendActId
void sendEnter(byte sys,int chMod){
String tem;
switch(sys){
case 0://在速度区按回车,速度值纠正,并焦点移动至自由区kill
checkHide(byte(79),1);
break;
case 1://在自由区按回车
if(sys1==4){//若警报业务,则自动呼叫开始
freeForNano.trim();
if(!freeForNano.length())return;//空,不响应
Serial.println("warn auto call start !");
msgToNano(String(char(AUTOCALLSTART)) + freeForNano + String(char(AUTOCALLSTART)));
}else{
msgToNano(freeForNano);
}
break;
case 2://在2--8按回车等价于后移焦点
return checkHide(79,1);
break;
case 3:
return checkHide(79,1);
break;
case 4:
return checkHide(79,1);
break;
case 5:
return checkHide(79,1);
break;
case 6:
return checkHide(79,1);
break;
case 7:
return checkHide(79,1);
break;
case 8:
return checkHide(79,1);
break;
case 9://附注区
//if(proFlag>0)return checkHide(79,1);//报头已发,跳至报文区
if(sys1==1){//为电报业务或业务公电,在附注区按回车发送电报头
numberForScrn.trim();
msgClass.trim();
msgDate.trim();
msgTime.trim();
msgMarket.trim();
if(numberForScrn.length()<1)return;//交付时更改条件
if(msgGroup.toInt()<1)return;
if(msgClass.length()<1)return;
if(msgDate.length()<1)return;
if(msgTime.length()<1)return;
tem="NR " + SLTranslate(numberForScrn) + " CK " + msgGroup + " " + msgClass + " " + msgDate + " " + msgTime;
if(msgMarket.length()>0)tem=tem +" RMKS " + msgMarket;
}else{
if(sys1==4)return;
numberForScrn.trim();
msgTime.trim();
msgMarket.trim();
if(numberForScrn.length()<1)return;//交付时更改条件
if(msgTime.length()<1)return;
tem="NR " + SLTranslate(numberForScrn) + " " + msgTime;
if(msgMarket.length()>0)tem=tem +" RMKS " + msgMarket;
}
msgToNano(tem);
checkHide(79,1);//调用右箭头
break;
case 10://报文区
msg.trim();//去掉空格
msgForDisplay.trim();
if(!chMod){
msgForDisplay=msgForDisplay + char(13)+char(10);
charToDisplay(String(char(13)));
charToDisplay(String(char(10)));
msg=msg+" ";
return;
}
//以下为用户发出整页发送命令
if(msg.length()<1)return;
if(sys1==1){//电报,一次性发送或调用发送
if(sys0==1)return;
if(sys0==0){
if(!msg.startsWith("{") && !dataSendStarted)msg=msg+"{";
msgToNano(msg);
msg="";//一次性发送后清屏
msgForDisplay="";
cmdToDisplay("t10.txt=\"\"");
dataSendStarted=true;//标识已经开始发送了
}
if(sys0==2){
sendDataNextPage(true);
}
return;;
}
if(sys1==2){//业务公电,一次性发送
msgToNano(msg);
return;
}
if(sys1==3){//无线电信号,一次性发送
msgToNano(String(RADIOCHAR) + " NR " + numberForNano + " " + msgTime + " " + String(STARTCHAR) + " " + msg + " " + String(ENDCHAR));
return;
}
if(sys1==4){//发警报信号,nano处于自动警报呼叫时,收到数据即停止自动呼叫!
byteToNano(AUTOCALLSTOP);
msgToNano("XXX "+ String(STARTCHAR)+ " " + msg + " " + String(ENDCHAR) + " XXX "+ String(STARTCHAR) + " " + msg + " " + String(ENDCHAR));
return;;
}
if(sys1==5){//通信检查,一次性发送
if(msg.indexOf("{")==-1)msgToNano("V V V " + String(STARTCHAR) + " " + msg + " " + msg + " " + msg + " " + String(ENDCHAR));
}
break;
case 11://报底调用,回车后仅当前显示改变,不发送
if(dataPage<1 || dataGroup<1) return;//非法,不处理
dataPositionFrom=(dataPage-1)*500;
if(!readData())return;
dataPage=dataGroup/100;
if(dataGroup%100)dataPage=dataPage+1;
dataPageNow=0;
dataSendStarted=false;
//界面显示
sendActId=actIdPre;
sys0=2;
cmdToDisplay("page send");//返回发报界面
cmdToDisplay("sys0=2");//此处两行更改发送模式为“调用发送”
cmdToDisplay("t10.txt=\"" + msgForDisplay + "\"");//显示第一页报文
cmdToDisplay("nPage.val=0/"+String(dataPage));//更新界面页码
break;
case 12:
sendEnter(11,chMod);
break;
case 13:
sendEnter(11,chMod);
break;
case 20:
sendActId=1;
actIdPre=20;
cmdToDisplay("page send");
break;
case 21:
sendActId=31;
actIdPre=20;
saveOrUse=2;
autoCallIndex=0;
cmdToDisplay("page autoCall");
cmdToDisplay("va0.val=2");//标识浏览
cmdToDisplay("click t1,0");
cmdToDisplay("t2.txt=\"" + readAll() + "\"");
break;
case 22:
sendActId=12;
cmdToDisplay("page useData");
break;
case 23://辅助工具`
sendActId=51;
cmdToDisplay("page tool");
break;
case 24://系统设置
sendActId=41;
cmdToDisplay("page sysSet");
break;
case 41:
sendActId=20;
cmdToDisplay("page main");
break;
case 25://关于
sendActId=91;
cmdToDisplay("page about");
break;
case 91:
sendActId=20;
cmdToDisplay("page main");
break;
case 31://自动呼叫的回车
sendActId=actIdPre;
if(actIdPre==20){
cmdToDisplay("page main");
return;
}else{
cmdToDisplay("page send");
}
if(saveOrUse==1){//保存
saveCall();
}else{//调用
freeForScrn=readCall(autoCallIndex);
freeForScrn.trim();
freeForScrn=freeForScrn.substring(2);
cmdToDisplay("t1.txt=\"" + freeForScrn + "\"");
freeForNano=replaceNumberToLong(freeForScrn);
}
break;
case 101:
sendActId=1;
cmdToDisplay("page send");
switch(pgIndex){
case 0://初始化自动呼叫文件
if(initAutocall()){
Serial.println("initAutocall init ok !");
}else{
Serial.println("initAutocall init fail !");
}
break;
case 1://初始化数码报底
if(initDataNum()){
Serial.println("initDataNum init ok !");
}else{
Serial.println("initDataNum init fail !");
}
break;
case 2://初始化字码报底
if(initDataChr()){
Serial.println("initDataChr init ok !");
}else{
Serial.println("initDataChr init fail !");
}
break;
case 3://初始化混合报底
if(initDataBoth()){
Serial.println("initDataBoth init ok !");
}else{
Serial.println("initDataBoth init fail !");
}
break;
}
break;
case 51:
cmdToDisplay("click t5,1");
break;
case 52:
cmdToDisplay("click t5,1");
break;
case 71://输入对话框:工作日志保存
msgFileName.trim();
if(!msgFileName.length())return;
sendActId=1;
tem=msgFileName + ".txt";
//sd.remove("WORKLOG.txt");
SdFile myFile("WORKLOG.txt", FILE_WRITE);
if (!myFile.rename(sd.vwd(),tem.c_str())){
Serial.println("WORKLOG RENAME OK !");
}else{
Serial.println("WORKLOG RENAME fAIL !");
}
sendActId=actIdPre;
cmdToDisplay("page send");//返回发报界面
break;
}
}
//显示字符输入验证,仅对输入的字符本身验证以及长度验证,不验证数值;true通过验证,false验证失败
void checkShow(byte sys,byte chKey,byte chOemKey,int chMod){
if(chKey>=97 && chKey<=122)chKey-=32;//小写转为大写
if(chKey==19)sendEnter(sendActId,chMod);//回车处理:发送
switch(sys){
case 10://报文区
//if(wordsTotal>=100)return;//满页不再接受输入
if(msgForDisplay.length()>=MSGMAXLENGTH)return;
//空格的处理
if(chKey==32){
if(msg.endsWith(" ") || !msg.length())return;//无效空格
if(sys1==1){//业务类型为电报
msg=msg + " ";
msgForDisplay=msgForDisplay + " ";
charToDisplay(" ");
if(sys0==1)msgToNano(" ");//当前为随输随发模式,发送
//wordsTotal++;//更新组数
}
return;
}
if((chKey>=48 && chKey<=57) || (chKey>=65 && chKey<=90) || chKey==46 || chKey==63 || chKey==33 || chKey==47 || chKey==95){//数字,字母,句号,问号(数码改错),感叹号(混合码改错),“/-”
msgForDisplay=msgForDisplay+char(chKey);
charToDisplay(String(char(chKey)));
if((sys2==1 || sys1>1) && (chKey>=48 && chKey<=57))chKey+=numberLong;//仅为电报短码时数字按短码处理,否则转为长码98->107
if(sys0) msgToNano(String(char(chKey)));//随输随发模式
msg=msg+char(chKey);
}
break;
case 1://自由勤务区,不受sys1限制,数字一律按长码发送
if(freeForScrn.length()>=FREELENGTHMAX) return;//长度验证
if(chKey==32 || (chKey>=48 && chKey<=57) || (chKey>=65 && chKey<=90) || chKey==63 || chKey==47 || chKey==33 || chKey==45){//空格、数字、字母、问号、!、“/-”
freeForScrn=freeForScrn+char(chKey);
charToDisplay(String(char(chKey)));
if(chKey>=48 && chKey<=57)chKey+=numberLong;
freeForNano=freeForNano+String(char(chKey));}
break;
case 2://号数,受限于电报
if(sys1!=1)return;//仅电报时可输入
if(numberForScrn.length()>=8)return;//长度验证
if(chKey>=48 && chKey<=57){//数字
numberForNano+=char(chKey);
numberForScrn+=char(chKey);
cmdToDisplay("t2.txt=\"" + numberForScrn + "\"");
//charToDisplay(String(char(chKey)));
return;}
if(chKey==47 && numberForScrn.indexOf("/")==-1){
numberForScrn+=char(chKey);
numberForNano+=char(chKey);
cmdToDisplay("t2.txt=\"" + numberForScrn + "\"");
return;
}
if((chKey==69) && numberForScrn.indexOf("E")==-1){
numberForScrn+=char(chKey);
numberForNano+=char(chKey);
cmdToDisplay("t2.txt=\"" + numberForScrn + "\"");
return;
}
if((chKey==88) && numberForScrn.indexOf("X")==-1){
numberForScrn+=char(chKey);
numberForNano+=char(chKey);
cmdToDisplay("t2.txt=\"" + numberForScrn + "\"");
}
break;
case 3://组数,受限于电报
if(sys1!=1)return;//仅电报时可输入
if(msgGroup.length()>=5) return;//长度验证
if(chKey>=48 && chKey<=57){
msgGroup+=char(chKey);
cmdToDisplay("t3.txt=\"" + msgGroup + "\"");
}
break;
case 4://等级,受限于电报
if(sys1!=1)return;//仅电报时可输入
if(msgClass.length()>=5) return;//长度验证
if(chKey>=48 && chKey<=57){
msgClass+=char(chKey);
cmdToDisplay("t4.txt=\"" + msgClass + "\"");
}
break;
case 5://日期,受限于电报
if(sys1!=1)return;//仅电报时可输入
if(msgDate.length()>=4) return;//长度验证
if(chKey>=48 && chKey<=57){
msgDate+=char(chKey);
cmdToDisplay("t5.txt=\"" + msgDate + "\"");
}
break;
case 6://时间,受限于电报
if(sys1==0 || sys1==4)return;//仅电报时可输入
if(msgTime.length()>=4) return;//长度验证
if(chKey>=48 && chKey<=57){
msgTime+=char(chKey);
cmdToDisplay("t6.txt=\"" + msgTime + "\"");
}
break;
case 7://号数2,受限于无线电信号,公电
if(sys1!=2 && sys1!=3 && sys1!=5)return;//通信检查、无线电信号,公电时可输入
if(numberForScrn.length()>=8) return;//长度验证
if(chKey>=48 && chKey<=57){
numberForScrn+=char(chKey);
numberForNano+=char(chKey);
cmdToDisplay("t7.txt=\"" + numberForScrn + "\"");
return;
}
if(chKey==47 && numberForScrn.indexOf("/")==-1){
numberForScrn+=char(chKey);
numberForNano+=char(chKey);
cmdToDisplay("t7.txt=\"" + numberForScrn + "\"");
return;
}
if((chKey==69 || chKey==101) && numberForScrn.indexOf("E")==-1){
numberForScrn+=char(chKey);
numberForNano+=char(chKey);
cmdToDisplay("t7.txt=\"" + numberForScrn + "\"");
return;
}
if((chKey==88 || chKey==120) && numberForScrn.indexOf("X")==-1){
numberForScrn+=char(chKey);
numberForNano+=char(chKey);
cmdToDisplay("t7.txt=\"" + numberForScrn + "\"");
}
break;
case 8://时间2,受限于无线电信号,公电
if(sys1!=2 && sys1!=3 && sys1!=5)return;//通信检查、无线电信号,公电时可输入
if(msgTime.length()>=4) return;//长度验证
if(chKey>=48 && chKey<=57){
msgTime+=char(chKey);
cmdToDisplay("t8.txt=\"" + msgTime + "\"");
}
break;
case 9://附注,受限于电报,无线电信号,公电
if(sys1==0 || sys1==4 || sys1==5)return;//仅电报,无线电信号,公电时可输入
if(msgMarket.length()>=50) return;//长度验证
if((chKey>=65 && chKey<=90) || (chKey>=48 && chKey<=57) || chKey==47 || chKey==45){//字母、数字、“/”、“-”
msgMarket+=char(chKey);
charToDisplay(String(char(chKey)));
//cmdToDisplay("click btnDisplay,1");
}
break;
case 0://速度
if(msgSpeed.length()>=3) return;//长度验证
if(chKey>=48 && chKey<=57){//数字
msgSpeed+=char(chKey);
cmdToDisplay("t0.txt=\"" + msgSpeed + "\"");
}
break;
case 51://计算器的第1个数,仅响应数字
if(chKey>=48 && chKey<=57){//数字
cmdToDisplay("va0.val=" + String(chKey-48));
cmdToDisplay("click n0,1");
}
break;
case 52://计算器的第2个数,仅响应数字
if(chKey>=48 && chKey<=57){//数字
cmdToDisplay("va0.val=" + String(chKey-48));
cmdToDisplay("click n1,1");
}
break;
case 71://日志保存输入框
if(msgFileName.length()>=15) return;//长度验证
if((chKey>=48 && chKey<=57) || (chKey>=97 && chKey<=122) || (chKey>=65 && chKey<=90)){//数字字母
msgFileName+=char(chKey);
cmdToDisplay("t0.txt=\"" + msgFileName + "\"");
}
break;
case 12://报底调用:起始页码
if(chKey>=48 && chKey<=57){//数字
long tem;
tem=dataPage*10+chKey-48;
if(dataKind==0 && tem<=999){
dataPage=tem;
if(dataGroup>(999-tem+1)*100)dataGroup=(999-tem+1)*100;//自动纠正组数
cmdToDisplay("n1.val=" + String(dataPage));
cmdToDisplay("n2.val=" + String(dataGroup));
return;
}
if(dataKind>0 && tem<=99){
dataPage=tem;
if(dataGroup>(99-tem+1)*100)dataGroup=(99-tem+1)*100;//自动纠正组数
cmdToDisplay("n1.val=" + String(dataPage));
cmdToDisplay("n2.val=" + String(dataGroup));
}
}
break;
case 13://报底调用:调用组数
if(chKey>=48 && chKey<=57){
long tem;
tem=dataGroup*10+chKey-48;
if((dataKind==0 && (dataPage*100+tem)<=99900) || (dataKind>0 && (dataPage*100+tem)<=9900)){
dataGroup=tem;
cmdToDisplay("n2.val="+String(dataGroup));
}
}
break;
}
}
void keyPressed() {
byte chKey=keyboard.getKey();//内码
byte chOemKey=keyboard.getOemKey();//扫描码
int chMod = keyboard.getModifiers();//修饰符
//Serial.println(chKey);
if(chKey>0){
checkShow(sendActId,chKey,chOemKey,chMod);//输入的显示字符非法,不响应
}else{
checkHide(chOemKey,chMod);//输入的隐藏字符非法,不响应
}
}
void setup() {
//pinMode(pinDisplayPower, OUTPUT);
//digitalWrite(pinDisplayPower,HIGH);
pinMode(pinLedR, OUTPUT);
digitalWrite(pinLedR,LOW);
pinMode(pinLedG, OUTPUT);
digitalWrite(pinLedG,HIGH);
pinMode(pinLedB, OUTPUT);
digitalWrite(pinLedB,HIGH);
Serial.begin(115200);//调试用
while (!Serial);
Serial3.begin(115200);//去往Nano
while (!Serial1);
Serial1.begin(115200);//去往显示屏
while (!Serial3);
Serial.println("due started");
if (!sd.begin(pinChipSelect, SD_SCK_MHZ(5))) {
Serial.println("sd failed!");
}else{
Serial.println("sd ok...");
sd.remove("WORKLOG.txt");
sd.remove("WORKLOG2.txt");
}
//系统初始化,让屏幕保持一致
delay(3000);
cmdToDisplay("page send");
cmdToDisplay("sys1=1");//设定工作类型为电报
cmdToDisplay("sys0=1");//设定发送模式为随输随发
cmdToDisplay("send.sendActId.val=1");//设定焦点为自由输入区
cmdToDisplay("tmr0.en=1");//启动光标效果
digitalWrite(pinLedR,HIGH);
digitalWrite(pinLedG,LOW);
}
void loop() {
usb.Task();
SerialEventP();
}
void SerialEventP(){
if(!Serial3.available())return;
String tem="";
while (Serial3.available()) {
tem=tem + char(Serial3.read());
}
if(tem.length()>1){
Serial.println("information for save !");
saveLog(tem);
}else{
if(msg.equals("~"))sendDataNextPage();//调用发送模式下,nano请求下一页内容
}
}
[/mw_shl_code] |