Why do my function write_ACK_ONLY()
change my global variable? Im passing the rxUartBuffer
to write_ACK_ONLY()
as data = new Array(20)
but as you can se in the Log Output. The Function do change also the rxUartBuffer
Code Part
console.log(this.toHexString(rxUartBuffer));
this.write_ACK_ONLY(rxUartBuffer)
console.log(this.toHexString(rxUartBuffer));
log Output
aa|02|00|01|00|00|0b|00|00|00|00|00|00|00|00|00|00|01|1d|d5|
aa|02|00|01|00|40|0b|00|00|00|00|00|00|00|00|00|00|01|1d|d5|
Code
import {Module} from './module';
import {PCP} from './pcp';
import {Logic} from "./logic";
const SerialPort = require('serialport');
const Ready = require('@serialport/parser-ready');
const CRC = require('crc-full').CRC;
var gpio = require('rpi-gpio')
var gpiop = gpio.promise;
gpiop.setup(7, gpio.DIR_OUT);
export class RsBUS{
/*SERIAL*/
private port = new SerialPort('/dev/ttyS0', {
baudRate: 19200, dataBits: 8
});
private pcp = new PCP();
// private ByteLength = require('@serialport/parser-byte-length')
// private PCP_BIT_ERR_A:number = 0x01;//BIT 1 vom STATUS BYTE [5]
private uartCounter: number = 0;
private crc8 = new CRC("CRC8", 8, 0xd5, 0x0000, 0x0000, false, false);
private txBuffer:number[] = new Array(20);
constructor(){
const rxUartBuffer:number[] = new Array(20);
let buf_len = rxUartBuffer.length;
let txUartBuffer:number[] = new Array(20);
let endOfTransmision:boolean = false;/*TRUE = END, FALSE = ANFANG der Übermittlung*/
this.port.on('data', (rxData) =>{
rxUartBuffer[this.uartCounter] = rxData[this.pcp.START];
if(rxUartBuffer[this.uartCounter] == this.pcp.START_BIT){
endOfTransmision = false;
rxUartBuffer[this.uartCounter] = this.pcp.START_BIT;
}
this.uartCounter++; // Counter MUSS hier hochgezählt werden.
/*FEHLER BEIM EMPFANGEN*/
if(rxUartBuffer[this.pcp.START] != this.pcp.START_BIT){
console.log("RS ERROR");
this.uartCounter = 0;
//write_ERROR_ALL(0x02); //0b00000010 = ERR Bit
//SENDE AN ALLE "HAB ICH NICHT VERSTNANDEN" > "DER, der kein ACK bekommen hat, sendet nochmal"
}
if(rxUartBuffer[this.uartCounter-1] == this.pcp.END_BIT){ //counter wird vorher schon hochgezählt
console.log("\nEnde angekommen");
endOfTransmision = true;
}
if(this.uartCounter == 20 && rxUartBuffer[this.pcp.START] == this.pcp.START_BIT/* <--das testenm, und dann kann das --> weg: rxUartBuffer[this.PCP_START] == this.PCB_BIT_START*/){
console.log("Daten erfolgreich empfangen!");
//console.log(toHexString(rxUartBuffer));
txUartBuffer = rxUartBuffer;
this.uartCounter = 0;
//CRC CHECK
var crcCeckedBuffer = this.checkCrcChecksum(rxUartBuffer);
if(crcCeckedBuffer){
//CRC OK
console.log("CRC OK!");
this.logPCPHeader();
console.log(this.toHexString(rxUartBuffer));
this.write_ACK_ONLY(rxUartBuffer)
console.log(this.toHexString(rxUartBuffer));
this.analyzePCP(rxUartBuffer);
// this.write_ACK_ONLY(rxUartBuffer)
}else{
//CRC NOT OK
console.log("CRC korrupt!");
this.write_ERROR(txUartBuffer); //CRC EROR
}
}else if(endOfTransmision == true){ //ENDE DA, aber die 20 Byte sind noch nicht voll. Also Fehler
console.log(this.uartCounter)
console.log(rxUartBuffer[this.pcp.START])
console.log(this.pcp.START_BIT)
endOfTransmision = false;
this.uartCounter = 0;
console.log("Fehler beim empfangen!");
//write_ERROR_ALL(0x02); //0b00000010 = ERR Bit
//SENDE AN ALLE "HAB ICH NICHT VERSTNANDEN" > "DER, der kein ACK bekommen hat, sendet nochmal"
}
});
}
logPCPHeader(){
console.log("00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19");
console.log("--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--");
}
toHexString(byteArray) {
return Array.from(byteArray, (byte:any)=>{
return ('0' + (byte & 0xFF).toString(16)).slice(-2) + "|";
}).join('')
// console.log("\n");
}
/*ERROR_ALL erstmal außenvorlasen.
//SENDE AN ALLE "HAB ICH NICHT VERSTNANDEN" > "DER, der kein ACK bekommen hat, sendet nochmal"
Dh. Evtl. wird das garnicht benötigt da ja das Modul auf ein ACK wartet. Wird das nicht gesendet bzw. vom Modul empfangen dann schickt der die Daten erneut*/
write_ERROR_ALL(ErrorBit){
this.txBuffer[0] = 0xAA;
this.txBuffer[1] = 0x3F; //SENDE AN ALLE
this.txBuffer[5] = ErrorBit;
this.txBuffer[19] = 0xd5;
gpiop.write(7, true);
setTimeout(()=>{
var crcCeckedBuffer = this.createCrcChecksum(this.txBuffer);
this.port.write(crcCeckedBuffer, (err, result) => {
this.uartCounter=0;
if (err) {
console.log('Error while sending message : ' + err);
}
if (result) {
console.log('Response received after sending message : ' + result);
}
});
},200);
setTimeout(function(){ gpiop.write(7, false);},300);
}
write_ERROR(data = new Array(20)){
gpiop.write(7, true);
data[this.pcp.STATUS] = this.pcp.ERR_BIT;
setTimeout(()=>{
var crcBuffer = new Array(17);
for(var i = 0;i<17;i++){
crcBuffer[i] = data[i];
}
var crcCeckedBuffer = this.createCrcChecksum(data);
this.port.write(crcCeckedBuffer, (err, result) => {
console.log("Sende ERROR BIT");
this.uartCounter=0;
if (err) {
console.log('Error while sending message : ' + err);
}
if (result) {
console.log('Response received after sending message : ' + result);
}
});
},200);
setTimeout(function(){ gpiop.write(7, false);},300);
}
write_ACK_ONLY(data = new Array(20)){//SENDE NUR ACK ohne Daten, bzw. mit den Empfangen Daten
gpiop.write(7, true);
data[this.pcp.STATUS] = this.pcp.ACK_BIT ;
setTimeout(() => {
var crcCeckedBuffer = this.createCrcChecksum(data);
// console.log(crcCeckedBuffer);
this.port.write(crcCeckedBuffer, (err, result) => {
console.log("Sende ACK");
this.uartCounter=0;
if (err) {
console.log('Error while sending message : ' + err);
}
if (result) {
console.log('Response received after sending message : ' + result);
}
});
},200);
setTimeout(function(){ gpiop.write(7, false);},300);
}
/*WIRD NOCH angepasst... oder? Vielleicht braucht man write_ACK garnicht?*/
write_DATA(data = new Array(20)){
gpiop.write(7, true);
data[this.pcp.STATUS] |= this.pcp.ACK_BIT;
setTimeout(()=>{
var crcCeckedBuffer = this.createCrcChecksum(data);
this.port.write(crcCeckedBuffer, (err, result) => {
console.log("Sende Daten");
this.uartCounter=0;
if (err) {
console.log('Error while sending message : ' + err);
}
if (result) {
console.log('Response received after sending message : ' + result);
}
});
},200);
setTimeout(function(){ gpiop.write(7, false);},300);
}
analyzePCP(receivedPcp){//Hier vorher PCP_evaluate
/*DASD SIT NEUES MODUL UND SO*/
//neues Modul initialisieren
console.log(receivedPcp[this.pcp.STATUS])
switch(receivedPcp[this.pcp.STATUS]){
case this.pcp.INIT_BIT:
{
// INIT
console.log("Modul init");
var id = new Module().initNewModule(receivedPcp, (newID:number)=>{
//console.log(newID);
receivedPcp[this.pcp.DATA1] = newID;/*0x0E soll eine neue ID darstellen*/
receivedPcp[this.pcp.STATUS] = this.pcp.INIT_BIT;/*0x0E soll eine neue ID darstellen*/
this.write_DATA(receivedPcp);
});
break;
}
case 0x00:
{
var mod = new Module(receivedPcp[this.pcp.RSADDR], receivedPcp[this.pcp.DEVTYPE]);
new Logic().checkRuleByModule(mod);
}
}
// if(receivedPcp[this.pcp.STATUS] == this.pcp.INIT_BIT){
// console.log("Modul init");
// var id = new Module().initNewModule(pcp, (newID)=>{
// //console.log(newID);
// pcp[this.pcp.DATA1] = newID;/*0x0E soll eine neue ID darstellen*/
// pcp[this.pcp.STATUS] = this.pcp.INIT_BIT;/*0x0E soll eine neue ID darstellen*/
// this.write_DATA(pcp);
// });
// //ansonsten ACK
// }else{
// this.write_ACK_ONLY(pcp);
// }
}
/*Erstellt eine fertiges Buffer mit Checksumme z.b. uzm Verchicken*/
private createCrcChecksum(buf):number[]{
var crcBuffer = new Array(17);
for(var i = 0;i<17;i++){
/*SCHNAPPT SICH NUR die ersten 17 Bytes*/
crcBuffer[i] = buf[i];
}
/*erstellt daraus eine Checksumme*/
var crc8_result = this.crc8.compute(crcBuffer);
/*und teilt sie auf in byte 17 und 18*/
buf[17] = crc8_result >> 7;
buf[18] = crc8_result & 0x7F;
/*Den fertigen Buffer mit der Checksume gibt er zurück*/
return buf;
}
/*prüft ob die Empfange Checksumme (steckt in Byte 17 & 18) gleich ist mit der neu erstellen aus den Bytes 0-16*/
private checkCrcChecksum(buf):boolean{
var crcBuffer = new Array(17);
for(var i = 0;i<17;i++){
/*SCHNAPPT SICH NUR die ersten 17 Bytes*/
crcBuffer[i] = buf[i];
}
/*nimmt sich aus dem empfangsBUF die CRC aus 17 und 18*/
var crc8_h = (buf[17]<<7);
var crc8_complete = (buf[18] | crc8_h);
/*prüft ob Checksume aus Byte 0-16 gleich ist der welche in Byte 17 und 18 empfangen wurde*/
return crc8_complete == this.crc8.compute(crcBuffer);
}
}