#include <SoftwareSerial.h>
#include <EEPROM.h>
SoftwareSerial TJC(A8, A9);
//#define TJC Serial
#define FRAME_LENGTH 5
uint16_t modbus_crc16(unsigned char *data, uint8_t length) {
uint16_t crc = 0xFFFF;
for (uint8_t i = 0; i < length; i++) {
crc ^= data[i];
for (uint8_t j = 8; j > 0; j--) {
if (crc & 0x0001) {
crc = (crc >> 1) ^ 0xA001;
} else {
crc >>= 1;
}
}
}
return crc;
}
char str[100];
int set[8];
int control_outside = 1;
int reset_step = 0;
int height1 = 0;
int height2 = 0;
void refsh_setting() {
reset_step = 20;
for (int i = 0; i < 4; i++) {
int lb = EEPROM.read(4 + i * 2);
int hb = EEPROM.read(5 + i * 2);
lb = hb * 256 + lb;
set[i] = lb;
sprintf(str, "x%d.val=%d\xff\xff\xff", i, lb);
TJC.print(str);
}
//control_outside = EEPROM.read(0x14);
//sprintf(str, "n0.val=%d\xff\xff\xff", control_outside);
//TJC.print(str);
//sprintf(str, "bt0.val=%d\xff\xff\xff", control_outside);
//TJC.print(str);
//reset_step = EEPROM.read(0x15);
//sprintf(str, "n1.val=%d\xff\xff\xff", reset_step);
//TJC.print(str);
//sprintf(str, "t10.txt=\"-2000\"\xff\xff\xff");
//TJC.print(str);
//sprintf(str, "h0.val=2000\xff\xff\xff");
//TJC.print(str);
//sprintf(str, "h0.maxval=4000\xff\xff\xff");
//TJC.print(str);
}
void setup() {
TJC.begin(9600);
Serial.begin(9600);
Serial.println(9600);
for (int i = 2; i <= 20; i++) {
pinMode(i, OUTPUT);
}
for (int i = 26; i <= 40; i++) {
pinMode(i , INPUT);
}
refsh_setting();
}
//26-38输入2-19输出
byte DI[15] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
byte DO[19] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
void refesh_io() {
int val = 0;
for (int i = 0; i < 15; i++) {
val = digitalRead(i + 26);
if (val != DI[i]) {
DI[i] = val;
sprintf(str, "DI%d.val=%d\xff\xff\xff", i, val);
TJC.print(str);
}
}
for (int i = 0; i < 19; i++) {
val = digitalRead(i + 2);
if (val != DO[i]) {
DO[i] = val;
sprintf(str, "DO%d.val=%d\xff\xff\xff", i, val);
TJC.print(str);
}
}
}
void refesh_io1() {
int val = 0;
for (int i = 0; i < 15; i++) {
val = digitalRead(i + 26);
DI[i] = val;
sprintf(str, "DI%d.val=%d\xff\xff\xff", i, val);
TJC.print(str);
}
for (int i = 0; i < 19; i++) {
val = digitalRead(i + 2);
DO[i] = val;
sprintf(str, "DO%d.val=%d\xff\xff\xff", i, val);
TJC.print(str);
}
}
int step = -1; //外设控制步骤
int tstep = -1;
int tdelayc = 0;
float ma[2];
float pa[2];
void screw() {
float tpa[2];//start delta
while (tstep != -1) {
while (tdelayc > 0) {
if (digitalRead(27)) { //停止按钮
tstep = 6;
tdelayc = 1;
}
if (digitalRead(29) && control_outside == 1) { //复位按钮
tstep = 6;
tdelayc = 1;
}
delay(100);
tdelayc = tdelayc - 1;
}
switch (tstep) {
case 0://伺服启动
//sprintf(str, "page 1\xff\xff\xfft2.txt=\" \"\xff\xff\xfft2.bco=1048\xff\xff\xfft7.txt=\"X10pa\"\xff\xff\xffleak.pco=1048\xff\xff\xff");
sprintf(str, "t13.txt=\"伺服启动\"\xff\xff\xff");
TJC.print(str);
digitalWrite(16, HIGH);
digitalWrite(18, HIGH);
tstep = tstep + 1;
tstep = -1;
break;
case 1://检测伺服输出信号
if (digitalRead(37) && digitalRead(39)) {
digitalWrite(16, LOW);
digitalWrite(18, LOW);
sprintf(str, "t13.txt=\"拧紧完成\"\xff\xff\xff");
TJC.print(str);
tstep = tstep + 1;
}
if (digitalRead(38) || digitalRead(40)) {
digitalWrite(3, HIGH);
digitalWrite(16, LOW);
digitalWrite(18, LOW);
sprintf(str, "t13.txt=\"拧紧失败\"\xff\xff\xff");
TJC.print(str);
tstep = -1;
}
break;
case 2://滑台上升
digitalWrite(12, LOW);
digitalWrite(14, LOW);
digitalWrite(13, HIGH);
digitalWrite(15, HIGH);
tstep = tstep + 1;
break;
case 3://上升到位
if (digitalRead(33) && digitalRead(35)) {
digitalWrite(13, LOW);
digitalWrite(15, LOW);
digitalWrite(10, HIGH);
tstep = tstep + 1;
break;
}
case 4://向左到位
if (digitalRead(31)) {
digitalWrite(10, LOW);
digitalWrite(12, HIGH);
digitalWrite(14, HIGH);
tstep = tstep + 1;
break;
}
case 5://测高度
if (digitalRead(34) && digitalRead(36)) {
height1 = analogRead(A0);
height2 = analogRead(A1);
sprintf(str, "height1.val=d%\xff\xff\xff", height1);
TJC.print(str);
sprintf(str, "height2.val=d%\xff\xff\xff", height2);
TJC.print(str);
tstep = tstep + 1;
break;
}
case 6://滑台上升
digitalWrite(12, LOW);
digitalWrite(14, LOW);
digitalWrite(13, HIGH);
digitalWrite(15, HIGH);
tstep = tstep + 1;
break;
case 7://上升到位
if (digitalRead(33) && digitalRead(35)) {
digitalWrite(13, LOW);
digitalWrite(15, LOW);
digitalWrite(11, HIGH);
tstep = tstep + 1;
break;
}
case 8://向右到位
if (digitalRead(31)) {
digitalWrite(11, LOW);
tstep = -1;
}
break;
}
refesh_io();
}
}
int cpin = -1; //当前控制引脚
int cdir = HIGH;
int dstep = -1;//延时
int pstep = -1;//暂停
int delayc = 0;//延时时间*10ms
int paused = 0;
void control_device() {
// delayc=delay_clcle:
//sprintf(str, "control_outside()");
//Serial.print(str);
if (step == -1) {
return;
}
if (step == 0) {
sprintf(str, "va8.val=0\xff\xff\xff");
TJC.print(str);
}
if (step == reset_step) { //显示复位
sprintf(str, "t13.txt=\"正在复位\"\xff\xff\xff");
TJC.print(str);
}
while (step != -1) {
refesh_io();
Serial.println(step);
// height1 = analogRead(A0);
// height2 = analogRead(A1);
// Serial.println(height1);
//Serial.println(height2);
//delay(500);
if (delayc > 0) {
if (step != -1) {
dstep = step;
step = -1;
}
delay(10);
delayc = delayc - 1;
}
else if (step == -1 && dstep != -1) {
step = dstep;
dstep = -1;
}
if (!digitalRead(27)) { //停止按钮
sprintf(str, "t13.txt=\"急停\"\xff\xff\xfft13.pco=63488\xff\xff\xff");
TJC.print(str);
step = -1;
tstep == -1;
dstep == -1;
pstep == -1;
delayc = 1;
for (int i = 2; i < 19; i++) {
digitalWrite(i, LOW);
}
}
if (!digitalRead(28) ) { //光栅暂停
sprintf(str, "t13.txt=\"光栅暂停\"\xff\xff\xfft13.pco=63488\xff\xff\xff");
TJC.print(str);
if ( paused == 0 && cpin !=-1) {
//digitalWrite(cpin, LOW);
step = step - 1;
paused = 1;
}
continue;
}
else if ( paused == 1) {
sprintf(str, "t13.txt=\"恢复运行\"\xff\xff\xfft13.pco=0\xff\xff\xff");
TJC.print(str);
paused = 0;
}
switch (step) {
case 0://滑台原位确认
sprintf(str, "t2.bco=65535\xff\xff\xfft3.bco=65535\xff\xff\xff");
TJC.print(str);
sprintf(str, "height1.bco=65535\xff\xff\xffheight1.bco=65535\xff\xff\xff");
TJC.print(str);
sprintf(str, "height1.val=0\xff\xff\xffheight2.val=0\xff\xff\xff");
TJC.print(str);
cpin = -1;
if (digitalRead(32) && digitalRead(33) && digitalRead(35)) {
step = step + 1;
} else {
sprintf(str, "t13.txt=\"滑台不在原点\"\xff\xff\xfft13.pco=63488\xff\xff\xff");
TJC.print(str);
step = -1;
}
break;
case 1://检查伺服状态
cpin = -1;
if (!digitalRead(38) && !digitalRead(40)) {
step = step + 1;
} else {
sprintf(str, "t13.txt=\"伺服未复位\"\xff\xff\xfft13.pco=63488\xff\xff\xff");
TJC.print(str);
step = -1;
}
break;
case 2://压紧
sprintf(str, "t13.txt=\"工件压紧\"\xff\xff\xfft13.pco=0\xff\xff\xff");
TJC.print(str);
digitalWrite(5, LOW);
cpin = 4;
cdir = HIGH;
digitalWrite(cpin, cdir);
step = step + 1;
//delayc = 150;//延迟1.5s
delay(2000);
break;
case 3://压紧到位
step = step + 1;
sprintf(str, "va8.val=1\xff\xff\xff");
TJC.print(str);
break;//屏蔽压紧到位信号
if (digitalRead(30)) {
cpin = -1;
step = step + 1;
sprintf(str, "va8.val=1\xff\xff\xff");
TJC.print(str);
}
break;
case 4://滑台下
digitalWrite(8, LOW);
digitalWrite(15, LOW);
cpin = 12;
cdir = HIGH;
digitalWrite(cpin, cdir);
digitalWrite(14, cdir);
step = step + 1;
sprintf(str, "va8.val=2\xff\xff\xff");
TJC.print(str);
delay(3000);
//delayc = 300;//延迟3秒
break;
case 5://启动拧紧
cpin = -1;
sprintf(str, "t13.txt=\"伺服启动\"\xff\xff\xfft13.pco=0\xff\xff\xff");
TJC.print(str);
digitalWrite(16, HIGH);
digitalWrite(18, HIGH);
step = step + 1;
sprintf(str, "va8.val=3\xff\xff\xff");
TJC.print(str);
break;
case 6://检测伺服输出信号
cpin = -1;
if (digitalRead(37) && digitalRead(39)) {
digitalWrite(16, LOW);
digitalWrite(18, LOW);
sprintf(str, "t13.txt=\"拧紧完成\"\xff\xff\xfft13.pco=0\xff\xff\xff");
TJC.print(str);
sprintf(str, "t2.bco=2016\xff\xff\xfft3.bco=2016\xff\xff\xff");
TJC.print(str);
step = step + 1;
}
if (digitalRead(38) || digitalRead(40)) {
digitalWrite(3, HIGH);
sprintf(str, "t13.txt=\"拧紧失败\"\xff\xff\xfft13.pco=63488\xff\xff\xff");
TJC.print(str);
if (digitalRead(38)) {
digitalWrite(16, LOW);
sprintf(str, "t2.bco=634488\xff\xff\xff");
TJC.print(str);
}
if (digitalRead(40)) {
digitalWrite(18, LOW);
sprintf(str, "t3.bco=634488\xff\xff\xff");
TJC.print(str);
}
}
if (digitalRead(37) && digitalRead(40)) {
step = -1;
}
if (digitalRead(38) && digitalRead(39)) {
step = -1;
}
if (digitalRead(38) && digitalRead(40)) {
step = -1;
}
break;
case 7://滑台上升
sprintf(str, "va8.val=4\xff\xff\xff");
TJC.print(str);
cpin = 8;
cdir = HIGH;
digitalWrite(12, LOW);
digitalWrite(14, LOW);
digitalWrite(8, HIGH);
digitalWrite(15, HIGH);
step = step + 1;
//step=12;
break;
case 8://上升到位-向左
if (digitalRead(33) && digitalRead(35)) {
sprintf(str, "va8.val=5\xff\xff\xff");
TJC.print(str);
//digitalWrite(13, LOW);
//digitalWrite(15, LOW);
cpin = 10;
cdir = HIGH;
digitalWrite(cpin, cdir);
step = step + 1;
break;
}
break;
case 9://向左到位-准备测高度
if (digitalRead(31)) {
digitalWrite(10, LOW);
cpin = 12;
cdir = HIGH;
sprintf(str, "va8.val=6\xff\xff\xff");
TJC.print(str);
//digitalWrite(8, LOW);
//digitalWrite(15, LOW);
//digitalWrite(12, HIGH);
//digitalWrite(14, HIGH);
step = step + 1;
break;
}
break;
case 10://下降到位-测高度
delay(10);
height1 = analogRead(A0);
height2 = analogRead(A1);
Serial.println(height1);
Serial.println(height2);
sprintf(str, "height1.val=%d\xff\xff\xffheight2.val=%d\xff\xff\xff", height1, height2);
Serial.print(str);
step=step+1;
break;
case 40://下降到位-测高度
if (digitalRead(34) && digitalRead(36)) {
sprintf(str, "va8.val=7\xff\xff\xff");
TJC.print(str);
cpin = -1;
height1 = analogRead(A0);
height2 = analogRead(A1);
Serial.println(height1);
Serial.println(height2);
sprintf(str, "height1.val=d%\xff\xff\xffheight2.val=d%\xff\xff\xff", height1, height2);
TJC.print(str);
if (height1 > set[0] || height1 < set[1]) {
sprintf(str, "height1.bco=63448\xff\xff\xff");
TJC.print(str);
step = -1;
break;
} else {
sprintf(str, "height1.bco=2016\xff\xff\xff");
TJC.print(str);
}
if (height2 > set[2] || height2 < set[3]) {
sprintf(str, "height2.bco=63448\xff\xff\xff");
TJC.print(str);
step = -1;
break;
} else {
sprintf(str, "height2.bco=2016\xff\xff\xff");
TJC.print(str);
}
step = step + 1;
break;
}
break;
case 11://滑台上升
sprintf(str, "va8.val=8\xff\xff\xff");
TJC.print(str);
cpin = 13;
cdir = HIGH;
digitalWrite(12, LOW);
digitalWrite(14, LOW);
digitalWrite(8, HIGH);
digitalWrite(15, HIGH);
step = step + 1;
break;
case 12://上升到位-向右3
if (digitalRead(33) && digitalRead(35)) {
sprintf(str, "va8.val=9\xff\xff\xff");
TJC.print(str);
cpin = 11;
cdir = HIGH;
//digitalWrite(13, LOW);
//digitalWrite(15, LOW);
digitalWrite(11, HIGH);
step = step + 1;
break;
}
break;
case 13://向右到位-松开
if (digitalRead(32)) {
sprintf(str, "va8.val=10\xff\xff\xff");
TJC.print(str);
digitalWrite(11, LOW);
digitalWrite(2, HIGH);
cpin = 5;
cdir = HIGH;
digitalWrite(5, HIGH);
digitalWrite(4, LOW);
step = step + 1;
step = -1;
delay(3000);
}
break;
case 14://松开完成
digitalWrite(5, LOW);
step = -1;
break;
case 20://复位
//滑台上升
sprintf(str, "t13.txt=\"复位中\"\xff\xff\xfft13.pco=0\xff\xff\xff");
TJC.print(str);
cpin = 8;
cdir = HIGH;
digitalWrite(3, LOW);
digitalWrite(12, LOW);
digitalWrite(14, LOW);
digitalWrite(8, HIGH);
digitalWrite(15, HIGH);
step = step + 1;
break;
case 21://上升到位-向右3
if (digitalRead(33) && digitalRead(35)) {
cpin = 11;
cdir = HIGH;
//digitalWrite(13, LOW);
//digitalWrite(15, LOW);
digitalWrite(11, HIGH);
step = step + 1;
break;
}
break;
case 22://向右到位-//伺服复位
if (digitalRead(32)) {
digitalWrite(11, LOW);
cpin = -1;
digitalWrite(17, HIGH);
digitalWrite(19, HIGH);
step = step + 1;
}
break;
case 23://松开
cpin = 5;
cdir = HIGH;
digitalWrite(5, HIGH);
step = step + 1;
break;
if (digitalRead(31)) {
digitalWrite(11, LOW);
digitalWrite(2, HIGH);
cpin = 5;
cdir = HIGH;
digitalWrite(5, HIGH);
digitalWrite(4, LOW);
step = step + 1;
//delayc = 200;
}
break;
case 24://伺服复位完成-结束
cpin = -1;
//delayc = 100;
sprintf(str, "t13.txt=\"复位完成\"\xff\xff\xfft13.pco=0\xff\xff\xff");
TJC.print(str);
sprintf(str, "t2.bco=65535\xff\xff\xfft3.bco=65535\xff\xff\xff");
TJC.print(str);
sprintf(str, "height1.bco=65535\xff\xff\xffheight1.bco=65535\xff\xff\xff");
TJC.print(str);
sprintf(str, "height1.val=0\xff\xff\xffheight2.val=0\xff\xff\xff");
TJC.print(str);
digitalWrite(17, LOW);
digitalWrite(19, LOW);
//digitalWrite(5, LOW);
step = step + 1;
break;
case 25:
step = -1;
break;
}
refesh_io();
//执行结束
}
//sprintf(str, "t13.txt=\"待机\"\xff\xff\xfft13.pco=0\xff\xff\xff");
//TJC.print(str);
step = -1;
}
void loop() {
if (!digitalRead(27)) { //停止按钮
sprintf(str, "t13.txt=\"急停\"\xff\xff\xfft13.pco=63488\xff\xff\xff");
TJC.print(str);
tstep = -1;
tdelayc = 1;
for (int i = 2; i < 19; i++) {
digitalWrite(i, LOW);
}
}
if (digitalRead(26)) { //开始按钮
step = 0;
control_device();
}
if (digitalRead(29) ) { //复位
step = reset_step;
control_device();
}
refesh_io();
//当串口缓冲区大于等于6时
while (TJC.available() >= FRAME_LENGTH) {
unsigned char u[FRAME_LENGTH];
unsigned char frame_header = TJC.peek();
//通讯格式5位
//52 00 00 00 00 刷新IO
//52 00 01 00 00 读充气、平衡、检测、排气时间、控制设备、复位步骤编号
//52 00 02 xx 00 读xx步骤的输入输出、地址、执行后延迟时间
//52 03 00 00 00 启动
//52 03 01 00 00 停止,停止时,tstep=排气步骤
//52 04 00 00 00 读取传感器数值
//52 01 xx xx 00 写1位eeprom,1位地址,一位数据,1位00
//52 02 xx xx xx 写2位eeprom,一位地址,连续两位数据,串口屏输入低位在前高位在后。如写充气时间、检查参数
//eeprom 0-3 密码,4-5充气时间、6-7平衡,8-9检测,A-B排气,C-D泄漏量,E-F容积,10控制设备,11复位步骤编号,20以上控制步骤
if (frame_header == 0x52 || frame_header == 0x50 || frame_header == 0x59 || frame_header == 0x79 || frame_header == 0x53 ) {
//从串口缓冲区读取7字节
TJC.readBytes(u, FRAME_LENGTH);
//Serial.println(u[1]);
if (u[0] == 0x59) {//Y on
digitalWrite(u[1] + 2, HIGH);
//sprintf(str, "DO%d.txt=\"ON\"\xff\xff\xff", u[1]);
//TJC.print(str);
}
else if (u[0] == 0x79) {//Y off
digitalWrite(u[1] + 2, LOW);
//sprintf(str, "DO%d.txt=\"OFF\"\xff\xff\xff", u[1]);
//TJC.print(str);
}
else if (u[0] == 0x52) {
if (u[1] == 0x00 && u[2] == 0x00) { //R 刷新IO
for (int i = 0; i < 15; i++) {
DI[i] = 0;
}
for (int i = 0; i < 18; i++) {
DO[i] = 0;
}
refesh_io1();
}
else if (u[1] == 0x00 && u[2] == 0x01) { //R 刷新设备参数
refsh_setting();
}
else if (u[1] == 0x00 && u[2] == 0x02) { //读工步参数
int add1 = EEPROM.read(30 + u[3] * 3);
if (add1 > 10) {
add1 = 10;
}
int ele1 = EEPROM.read(31 + u[3] * 3);
int delay1 = EEPROM.read(32 + u[3] * 3) ;
sprintf(str, "cb0.val=%d\xff\xff\xff", add1);
TJC.print(str);
sprintf(str, "cb1.val=%d\xff\xff\xff", ele1);
TJC.print(str);
sprintf(str, "x9.val=%d\xff\xff\xff", delay1);
TJC.print(str);
}
else if (u[1] == 0x01) { //写1位eeprom
EEPROM.update(u[2], u[3]);
}
else if (u[1] == 0x02) { //写2位eeprom
EEPROM.update(u[2], u[3]);
EEPROM.update(u[2] + 1, u[4]);
}
else if (u[1] == 0x03) { //启动、停止
if (u[2] == 0x00) {
tstep = 0;
screw();
}
else if (u[2] == 0x01) {
tstep = 6;
tdelayc = 1;
screw();
}
}
else if (u[1] == 0x04) { //读取传感器数值
height1 = 135 - analogRead(A0) * (70 / 1024);
height2 = 135 - analogRead(A1) * (70 / 1024);
sprintf(str, "height1.val=d%\xff\xff\xff", (int)(height1 * 100));
TJC.print(str);
sprintf(str, "height2.val=d%\xff\xff\xff", (int)(height2 * 100));
TJC.print(str);
}
}
else if (u[0] == 0x50) {//P核对密码
int login = 0;
byte e[4];
for (int i = 0; i < 4; i++) {
e[i] = EEPROM.read(i);
}
if (u[1] == 0x2D && u[2] == 0x2E && u[3] == 0x2E && u[4] == 0x2D) {
login = 1;
}
if (e[0] == 255 && e[1] == 255 && e[2] == 255 && e[3] == 255) {
login = 1;
}
if (e[0] == u[1] && e[1] == u[2] && e[2] == u[3] && e[3] == u[4]) {
login = 1;
}
if (login == 1) {
sprintf(str, "login.val=1\xff\xff\xff");//给HMI赋值登录成功
TJC.print(str);
sprintf(str, "\x74\x33\x2E\x74\x78\x74\x3D\x22\xB5\xC7\xC2\xBC\xB3\xC9\xB9\xA6\xA3\xAC\xBD\xE2\xCB\xF8\xB2\xCE\xCA\xFD\xC9\xE8\xD6\xC3\xD2\xB3\xC3\xE6\x22\xff\xff\xff");
TJC.print(str);//t3.txt="登录成功,解锁参数设置页面"
}
}
else if (u[0] == 0x53) {//S设置密码
for (int i = 0; i < 4; i++) {
EEPROM.update(i, u[i + 1]);
delay(30);
}
sprintf(str, "t3.txt=\"\xC7\xEB\xC0\xCE\xBC\xC7\xD0\xC2\xC3\xDC\xC2\xEB ASIIC%d%d%d%d\"\xff\xff\xff", u[1], u[2], u[3], u[4]);
TJC.print(str);
}
} else {
TJC.read(); //从串口缓冲读取1个字节并删除
}
}
}