I have my modbus read and write working at 9600 baud to a Click PLC but when I change things to 38400 (default on PLC) my receive buffer gets out of order and fails. The last byte in will be at position 0 and all the other 8 bytes are pushed down 1 location. Change back to 9600 and it works fine. I am using a blob for receive array and a callback receive routine.
`
local buffer = blob(50);
local cnt = 0;
local gotmod;
local result = 0;
function crc16(crc, data){
local Poly16=0xA001;
local LSB, i;
crc = ((crc^data) | 0xFF00) & (crc | 0x00FF);
for (i=0; i<8; i++) {
LSB=(crc & 0x0001);
crc=crc/2;
if (LSB)
crc=crc^Poly16;
}
return(crc);
}
function readSerial() {
local g,crcl,crch;
buffer.writen(hardware.uart57.read(),'b');
cnt++;
if (domodwrite){
if (cnt >= 8 && buffer[5] == 1){
domodwrite = 0;
return(0);
}
}
if (cnt > 8) {
local crc = 0xffff;
for (g = 0; g <= 6; g++){
crc = crc16(crc,buffer[g]);
}
crch = crc>>8;
crcl = crc & 0xff;
if (crcl == buffer[7] && crch == buffer[8]){
server.log("crcok");
gotmod = 1;
buffer.seek(3,'b');
result = buffer.readn('b') * 256 + buffer.readn('b');
server.log(result);
dlogr = result;
}
else{
for (g = 0; g <= 8; g++){
server.log(g + ":" + buffer[g]);
}
server.log("-");
server.log(crcl);
server.log(crch);
}
}
}
function modread(address,numreg){
local adh = (address & 0xff00)>>8;
local adl = address & 0xff;
cnt = 0;
buffer.flush();
buffer.seek(0,‘b’);
domodwrite = 0;
local crco = 0xffff;
crco = crc16(crco,1);
hardware.uart57.write(1);//PLCID
crco = crc16(crco,3);
hardware.uart57.write(3);//Read Registers
crco = crc16(crco,adh);
hardware.uart57.write(adh);//vmem address high 600h = V3000
crco = crc16(crco,adl);
hardware.uart57.write(adl);//vmem address low
crco = crc16(crco,0);
hardware.uart57.write(0);//num registers to read high
crco = crc16(crco,numreg);
hardware.uart57.write(numreg); //num registers to read low
local crcl = crco & 0xff;
hardware.uart57.write(crcl);
crcl = crco>>8;
hardware.uart57.write(crcl);
gotmod = 0;
}
function modwrite(address,val){
//return(0);
domodwrite = 1;
local adh = (address & 0xff00)>>8;
local adl = address & 0xff;
local valh = (val & 0xff00)>>8;
local vall = val & 0xff;
cnt = 0;
local crco = 0xffff;
crco = crc16(crco,1);
hardware.uart57.write(1);//PLCID
crco = crc16(crco,0x10);
hardware.uart57.write(0x10);//Write Registers
crco = crc16(crco,adh);
hardware.uart57.write(adh);//vmem address high 600h = V3000
crco = crc16(crco,adl);
hardware.uart57.write(adl);//vmem address low
crco = crc16(crco,0);
hardware.uart57.write(0);//Quantity of registers high
crco = crc16(crco,1);
hardware.uart57.write(1); //Quantity low
crco = crc16(crco,2);
hardware.uart57.write(2); //
crco = crc16(crco,valh);
hardware.uart57.write(valh);//vmem address high 600h = V3000
crco = crc16(crco,vall);
hardware.uart57.write(vall);//vmem address low
local crcl = crco & 0xff;
hardware.uart57.write(crcl);
crcl = crco>>8;
hardware.uart57.write(crcl);
}
function mainloop(){
modread(99,2);
imp.wakeup(5,mainloop);
}
hardware.uart57.configure(38400, 8, PARITY_ODD, 1, NO_CTSRTS, readSerial);
imp.wakeup(1,mainloop);
`