Professional Documents
Culture Documents
5 integrated buttons.
* The transfer protocol used is based on the document as511protocol_description by Luca Gallina dated March 17, 2004.
* Also, by modifying the "standard" TTY/RS232 converter found by our friend Google, a third computer can monitor the serial communications
* between the programming unit (I.E the computer running S5) and the PLC AS511 PG port by using for example an excellent freeware called
* Realterm, to confirm proper communications to/from the PLC.
* All information shared within, as is and with no strings attached whatsoever, is already available for download elsewhere on the WWW.
* Standard disclaimer applies, I.E use at your own risk. If TSHTF = Don't come crying to me.
*
*/
int back = 0;
int old = 0;
int uld = 0;
int cur = 0;
int inhib = 0;
int buff[255];
int x = 0;
int y = 0;
int lsb = EEPROM.read(50);
int msb = EEPROM.read(55);
int outp = 0;
int setp = 0;
int contr[19] = {16, 6, 2, 22, 16, 3, 16, 6, 2, 9, 16, 16, 6, 16, 6, 2, 18, 16, 3};
int xsum = 0;
long timeout = 0;
bool brejk = false;
bool AS511_tx_rx = false;
bool up = false;
bool down = false;
bool left = false;
bool right = false;
bool kok = false;
void MAX(){
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Max value =");
lcd.setCursor(0, 1);
lcd.print("32767");
lcd.noCursor(); }
void basic0(){
lcd.setCursor(0, 0);
lcd.print("Setpoint");}
void basic1(){
lcd.setCursor(0, 1);
lcd.print("Input");}
void plcnofun(){
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("PLC not");
lcd.setCursor(0, 1);
lcd.print("responding");
delay(250);
lcd.clear();
delay(150); }
void again(){
lcd.clear();
basic0();
if (outp <=9){ cur = 15; }
if (outp <=99 && outp >= 10){ cur = 14; }
if (outp <=999 && outp >= 100){ cur = 13; }
if (outp <=9999 && outp >= 1000){ cur = 12; }
if (outp <=32767 && outp >= 10000){ cur = 11; }
lcd.setCursor(cur,0);
lcd.print(outp);
basic1();
if (setp <=9){ cur = 15; }
if (setp <=99 && setp >= 10){ cur = 14; }
if (setp <=999 && setp >= 100){ cur = 13; }
if (setp <=9999 && setp >= 1000){ cur = 12; }
if (setp <=32767 && setp >= 10000){ cur = 11; }
lcd.setCursor(cur,1);
lcd.print(setp);
}
void setup() {
uint8_t i=0;
void loop() {
lcd.noCursor();
down = true;
if (inhib < 1) {
if (cur == 15) { if ((setp - 1) > 0) { setp = setp - 1; }}
if (cur == 14) { if ((setp - 10) > 0) {setp = setp - 10; }}
if (cur == 13) { if ((setp - 100) > 0) {setp = setp - 100; }}
if (cur == 12) { if ((setp - 1000) > 0) {setp = setp - 1000; }}
if (cur == 11) { if ((setp - 10000) > 0) {setp = setp - 10000; }}
if (setp >=0 and setp <=9) { lcd.setCursor(11,1); lcd.print(" "); lcd.setCursor(15,1); }
if (setp >=10 and setp <=99) { lcd.setCursor(11,1); lcd.print(" "); lcd.setCursor(14,1); }
if (setp >=100 and setp <=999) { lcd.setCursor(11,1); lcd.print(" "); lcd.setCursor(13,1); }
if (setp >=1000 and setp <=9999) { lcd.setCursor(11,1); lcd.print(" "); lcd.setCursor(12,1); }
if (setp >=10000 and setp <=32767) { lcd.setCursor(11,1); }
if (setp <=0) { setp = 1; lcd.setCursor (15,1); lcd.print(setp); }
if (setp > 0) { lcd.print(setp); }
inhib = 1; }
}
lcd.noCursor();
left = true;
if (inhib < 1) {
if (cur > 11) {
cur = cur - 1; }
else { MAX();
delay(2000);
again();
cur = 11;
lcd.cursor();
lcd.setCursor(cur,1);
}
inhib = 1; }
}
lcd.noCursor();
right = true;
if (inhib < 1) {
if (cur < 15) {
cur = cur + 1; }
inhib = 1; }
}
}
}
else { inhib = 0;
if (up || down || left || right) { lcd.cursor(); lcd.setCursor(cur,1); }
}
if (AS511_tx_rx) { // As the data to the PLC is sent using serial port 3 we can
// use the native serial monitor to check both what we send
// and what we receive to/from the PLC.
if (x == 0){
Serial3.write(2); // Send #02 (STX) to the PLC. This is a general AS511 code used
Serial.println("PG: 02"); // to prepare the PLC for what we're about to do, which can be to
x=x+1; } // either read or write some data to/from it, or to initiate some
// command or what have you.
// In this particular application we want to use the LCD's
// buttons to change the value of a setpoint and then send
// it to the PLC.
// The setpoint is written to DB48/DW0 in the PLC.
if (x == 1){
if (Serial3.available() >=2 ) { // Get confirmation from the PLC, we're expecting to receive
for (int y=0; y<2; y++) { // #10 (DLE) and #06 (ACK) as a token of "message received and
buff[y] = Serial3.read(); } // understood" from the PLC, basically indicating that the PLC is
Serial.print("AG: "); // ready to do what we ask of it.
for (int y=0; y<2; y++) {
if (buff[y]<=9){ Serial.print("0");}
Serial.print(buff[y], HEX);
Serial.print(" ");}
Serial.println();
x=x+1; timeout = 0;} // All the receive sequences (data coming from the PLC to the
// Arduino) have a timeout safeguard preventing the Arduino from
// freezing.
else { timeout=timeout + 1;
if (timeout >= 50){ brejk=true; x=17; }
}
}
if (x == 2){
Serial3.write(8); // Send #08 (B_OWRITE) to the PLC. This tells the PLC that
Serial.println("PG: 08"); // we're about to overwrite, in this case, DB48/DW0, which
x=x+1; } // is where the PLC in this application reads it's data from
// with regards to whatever changes in operation we want the
// PLC to execute.
if (x == 3){
if (Serial3.available() >=1 ) { // Expecting to receive #02 (STX) from the PLC.
buff[2] = Serial3.read();
Serial.print("AG: ");
if (buff[2]<=9){ Serial.print("0");}
Serial.print(buff[2], HEX);
Serial.println();
x=x+1; timeout = 0;}
else { timeout=timeout + 1;
if (timeout >= 50){ brejk=true; x=17; }
}
}
if (x == 4){
Serial3.write(16); // Send #10 (DLE) & #06 (ACK) to the PLC, all according
Serial3.write(6); // to the AS511 protocol.
Serial.println("PG: 10 06");
x=x+1; }
if (x == 5){
if (Serial3.available() >=3 ) { // Expecting #16, #10 and #03 from the PLC.
for (int y=3; y<6; y++) {
buff[y] = Serial3.read(); }
Serial.print("AG: ");
for (int y=3; y<6; y++) {
if (buff[y]<=9){ Serial.print("0"); }
Serial.print(buff[y], HEX);
Serial.print(" ");}
Serial.println();
x=x+1; timeout = 0;}
else { timeout=timeout + 1;
if (timeout >= 50){ brejk=true; x=17; }
}
}
if (x == 6){
if (brejk){ x=17; }
Serial3.write(16); // Preparing the PLC for overwriting the data in DB48/DW0.
Serial3.write(6);
Serial3.write(1);
Serial3.write(48); // Pointing at DB48.
Serial3.write(0);
Serial3.write(6);
Serial3.write(16);
Serial3.write(3);
x=x+1;
Serial.println("PG: 10 06 01 30 00 06 10 03"); }
if (x == 7){
if (Serial3.available() >=3 ) { // Expecting #10, #06 and #02 from the PLC.
for (int y=6; y<9; y++) {
buff[y] = Serial3.read(); }
Serial.print("AG: ");
for (int y=6; y<9; y++) {
if (buff[y]<=9){ Serial.print("0"); }
Serial.print(buff[y], HEX);
Serial.print(" ");}
Serial.println();
x=x+1; timeout = 0;}
else { timeout=timeout + 1;
if (timeout >= 50){ brejk=true; x=17; }
}
}
if (x == 8){
Serial3.write(16); // Another #10 & #06 to the PLC.
Serial3.write(6);
Serial.println("PG: 10 06");
x=x+1; }
if (x == 9){
if (Serial3.available() >=3 ) { // Expecting #09, #10 & #03 from the PLC.
for (int y=9; y<12; y++) {
buff[y] = Serial3.read(); }
Serial.print("AG: ");
for (int y=9; y<11; y++) {
if (buff[y]<=9){ Serial.print("0"); }
Serial.print(buff[y], HEX);
Serial.print(" ");}
Serial.println();
x=x+1; timeout = 0;}
else { timeout=timeout + 1;
if (timeout >= 50){ brejk=true; x=17; }
}
}
if (x == 10){
Serial3.write(16); // Send #10, #06 & #02 to the PLC.
Serial3.write(6);
Serial3.write(2);
Serial.println("PG: 10 06 02");
x=x+1; }
if (x == 11){
if (Serial3.available() >=2 ) { // Expecting #10 & #06 from the PLC.
for (int y=11; y<13; y++) {
buff[y] = Serial3.read(); }
Serial.print("AG: ");
for (int y=11; y<13; y++) {
if (buff[y]<=9){ Serial.print("0"); }
Serial.print(buff[y], HEX);
Serial.print(" ");}
Serial.println();
x=x+1; timeout = 0;}
else { timeout=timeout + 1;
if (timeout >= 50){ brejk=true; x=17; }
}
}
if (x == 12){
Serial.print("PG: 00 70 70 01 30 80 00 00 00 00 06 ");
if (msb <= 15){ Serial.print("0"); }
Serial.print(msb, HEX);
Serial.print(" ");
if (msb == 16){
Serial.print(msb, HEX);
Serial.print(" ");}
if (lsb <= 15){ Serial.print("0");}
Serial.print(lsb, HEX);
Serial.print(" ");
if (lsb == 16){
Serial.print(lsb, HEX);
Serial.print(" "); }
Serial.println("10 04"); }
if (x == 13){
if (Serial3.available() >=3 ) { // Expecting #10, #06 & #02 from the PLC.
for (int y=13; y<16; y++) {
buff[y] = Serial3.read(); }
Serial.print("AG: ");
for (int y=13; y<16; y++) {
if (buff[y]<=9){ Serial.print("0"); }
Serial.print(buff[y], HEX);
Serial.print(" ");}
Serial.println();
x=x+1; timeout = 0;}
else { timeout=timeout + 1;
if (timeout >= 50){ brejk=true; x=17; }
}
}
if (x == 14){
Serial3.write(16); // Another #10 & #06 to the PLC.
Serial3.write(6);
Serial.println("PG: 10 06");
x=x+1; }
if (x == 15){
if (Serial3.available() >=3 ) { // Expecting #12, #10 & #03 from the PLC.
for (int y=16; y<19; y++) {
buff[y] = Serial3.read(); }
Serial.print("AG: ");
for (int y=16; y<19; y++) {
if (buff[y]<=9){ Serial.print("0"); }
Serial.print(buff[y], HEX);
Serial.print(" ");}
Serial.println();
x=x+1; timeout = 0;
xsum = 0;
for (int y=0; y<19; y++){ // XOR checking what was reveived from the PLC versus
xsum = xsum + (buff[y] ^ contr[y]);} // what is expected to be received from the PLC during
// a successful B_OWRITE sequence.
if (xsum > 0){ brejk = true; }}
else { timeout=timeout + 1;
if (timeout >= 50){ brejk=true; x=17; }
}
}
if (x == 16){
Serial3.write(16); // Send the last #10 & #06 to the PLC, this ends the TX/RX
Serial3.write(6); // sequence for B_OWRITE for this time.
Serial.println("PG: 10 06"); // As the B_OWRITE sequence was successfull then we print
x=x+1; // the new setpoint on the LCD display, let's the user know
outp = setp; // that the PLC now has a new setpoint to work with.
lcd.noCursor();
if (setp >=0 and setp <=9) { lcd.setCursor(11,0); lcd.print(" "); lcd.setCursor(15,0); }
if (setp >=10 and setp <=99) { lcd.setCursor(11,0); lcd.print(" "); lcd.setCursor(14,0); }
if (setp >=100 and setp <=999) { lcd.setCursor(11,0); lcd.print(" "); lcd.setCursor(13,0); }
if (setp >=1000 and setp <=9999) { lcd.setCursor(11,0); lcd.print(" "); lcd.setCursor(12,0); }
if (setp >=10000 and setp <=32767) { lcd.setCursor(11,0); }
if (setp <=0) { lcd.setCursor (11,0); lcd.print(" 0"); }
if (setp > 0) { lcd.print(setp); }}
msb = int(outp/256);
lsb = int(outp - msb*256);
EEPROM.write(50,lsb);
EEPROM.write(55,msb);
if (x == 17){
x=0;
AS511_tx_rx = false;
timeout = 0;
delay(50);
}
}
}