|
@@ -0,0 +1,599 @@
|
|
|
+//////////////////////////////////////////////////////////////////////
|
|
|
+// //
|
|
|
+// Programmname: <MODBUS-Protokoll> //
|
|
|
+// Datum: TT.MM.JJJJ //
|
|
|
+// Beschreibung: <Kurze Beschreibung des Programms> //
|
|
|
+// //
|
|
|
+// 1. Autor: Nataliia Leonova, 5088216. //
|
|
|
+// 2. Autor: Svitlana Sokulieva, 5088203 //
|
|
|
+// //
|
|
|
+//////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+////////// Inkludierte Header-Dateien //////////
|
|
|
+#include "Modbus.h"
|
|
|
+
|
|
|
+////////// Globale Variablen //////////
|
|
|
+SoftwareSerial RS485=SoftwareSerial(RX_PIN,TX_PIN);
|
|
|
+////////////////////ACHTUNG////////////////
|
|
|
+// auf 158 bitte geben Sie die Master Adresse bei jedem Master-wechsel.
|
|
|
+/////////////////////////////////////////
|
|
|
+bool is_Master;
|
|
|
+bool message_here;
|
|
|
+const char* addressList[] = {"01", "02", "03", "04", "05", "06", "07", "08"};
|
|
|
+// Number of addresses
|
|
|
+const int numAddresses = sizeof(addressList)/sizeof(addressList[0]);
|
|
|
+byte step_send=0;
|
|
|
+byte buffer_RS485[MAX_DATA]="";
|
|
|
+byte buffer_PC[PAYLOAD]="";
|
|
|
+byte addresse[2]="";
|
|
|
+byte Adresse[2]="";
|
|
|
+byte nachricht_buffer[241]="";
|
|
|
+byte bufflen_PC=0;
|
|
|
+byte bufflen_RS485=0;
|
|
|
+byte address_len=0;
|
|
|
+
|
|
|
+byte MASTER_ADRESSE[2]="";
|
|
|
+byte MEINE_ADRESSE[2]="";
|
|
|
+////////// Setup-Funktion //////////
|
|
|
+
|
|
|
+void setup(void) { // put your setup code here, to run once:
|
|
|
+
|
|
|
+ ////////// Lokale Variablen //////////
|
|
|
+ MEINE_ADRESSE[0]='0';
|
|
|
+ MEINE_ADRESSE[1]='6';
|
|
|
+ MEINE_ADRESSE[2]=0;
|
|
|
+//MEINE_ADRESSE[2]="06";
|
|
|
+ ////////// GPIO Setup //////////
|
|
|
+ Serial.begin(BAUDRATE);
|
|
|
+ RS485.begin(BAUDRATE);
|
|
|
+ ////////// Einmalige Anweisungen //////////
|
|
|
+//спросить мастер ли я ,если нет то спросить адрес мастера,если да,то адрес мастера равен моему алресу
|
|
|
+ byte address[2]="";
|
|
|
+ bool answer_write=false;
|
|
|
+ byte step_write=0;
|
|
|
+ Serial.print(F("Ist dieser Benutzer Master?(y/n)"));
|
|
|
+ delay(1000);
|
|
|
+ while (answer_write==false && step_write==0){
|
|
|
+ if(Serial.available()){
|
|
|
+ PC_read(buffer_PC,&bufflen_PC);
|
|
|
+ buffer_PC[bufflen_PC]=0;
|
|
|
+
|
|
|
+
|
|
|
+ if(buffer_PC[0]=='y'){
|
|
|
+ sprintf((char*)MASTER_ADRESSE,"%s",MEINE_ADRESSE);
|
|
|
+ Serial.println(F("Sie sind Master"));
|
|
|
+ is_Master=true;
|
|
|
+ bufflen_PC=0;
|
|
|
+ answer_write=true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ else if(buffer_PC[0]=='n'){
|
|
|
+ is_Master=false;
|
|
|
+ Serial.println(F("Geben Sie bitte die Adresse des Masters:(als ein Zeichen z.B 1)"));
|
|
|
+ Serial.println(F("Die verfuegbaren Adressen sind 1-8"));
|
|
|
+ bufflen_PC=0;
|
|
|
+ step_write++;
|
|
|
+ }
|
|
|
+ else{Serial.println(F("Geben Sie bitte die Antwort noch mal als ein Zeichen"));bufflen_PC=0;delay(1000);}
|
|
|
+ }
|
|
|
+ }
|
|
|
+ while(answer_write==false && step_write==1){
|
|
|
+ if(Serial.available()){
|
|
|
+ PC_read(buffer_PC,&bufflen_PC);
|
|
|
+ buffer_PC[bufflen_PC]=0;
|
|
|
+
|
|
|
+ address[0]='0';
|
|
|
+ address[1]=buffer_PC[0];
|
|
|
+ address[2]=0;
|
|
|
+
|
|
|
+ if(findAddress((char*)address) == true){
|
|
|
+ sprintf((char*)MASTER_ADRESSE,"%s",address);
|
|
|
+ Serial.println(F("Master Adresse ist: "));
|
|
|
+ Serial.println((char*)MASTER_ADRESSE);
|
|
|
+ bufflen_PC=0;
|
|
|
+ answer_write=true;
|
|
|
+ step_write=0;
|
|
|
+ break;}
|
|
|
+ else{Serial.println(F("Bitte geben Sie die Adresse noch mal"));delay(1000);bufflen_PC=0;}
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+////////// Loop-Funktion //////////
|
|
|
+
|
|
|
+void loop(void) { // put your main code here, to run repeatedly:
|
|
|
+
|
|
|
+ ////////// Lokale Variablen //////////
|
|
|
+
|
|
|
+ int lrc;
|
|
|
+
|
|
|
+ unsigned long timestamp;
|
|
|
+ unsigned long startMillis;
|
|
|
+
|
|
|
+ ////////// Hauptprogramm //////////
|
|
|
+
|
|
|
+
|
|
|
+ /////////////////////////////////////////////////////////////
|
|
|
+ //////////////////////////////SLAVE//////////////////////////
|
|
|
+ /////////////////////////////////////////////////////////////
|
|
|
+ if(is_Master==false){
|
|
|
+
|
|
|
+ if(step_send==0){
|
|
|
+ Serial.println(F("Geben Sie bitte die Nachricht ein: "));
|
|
|
+ step_send++;
|
|
|
+ }
|
|
|
+ if(step_send==1 && Serial.available()){
|
|
|
+ PC_read(buffer_PC,&bufflen_PC);
|
|
|
+ buffer_PC[bufflen_PC]=0;
|
|
|
+ step_send++;
|
|
|
+ }
|
|
|
+ if(step_send==2){
|
|
|
+ if(bufflen_PC>0){
|
|
|
+ Serial.println(F("Nachricht wurde ausgelesen: "));
|
|
|
+ message_here=true;
|
|
|
+ Serial.println((char*)buffer_PC);
|
|
|
+ step_send++;
|
|
|
+ }
|
|
|
+ else if(bufflen_PC==0){Serial.println(F("Nachricht wurde nicht eingegeben"));message_here=false;}
|
|
|
+ }
|
|
|
+
|
|
|
+ if(RS485.available()){
|
|
|
+ RS485_read(buffer_RS485,&bufflen_RS485);
|
|
|
+ buffer_RS485[bufflen_RS485]=0;
|
|
|
+
|
|
|
+ if((buffer_RS485[1]== '0' && buffer_RS485[2]=='6') || (buffer_RS485[1]=='0' && buffer_RS485[2]=='0')){
|
|
|
+ lrc=pruefeLRC(buffer_RS485,bufflen_RS485);
|
|
|
+ bufflen_RS485=0;
|
|
|
+ if(lrc == 0){
|
|
|
+//////////////////////02//////////////////////////////////////
|
|
|
+
|
|
|
+ if(message_here==false && (buffer_RS485[3]== '0' && buffer_RS485[4]=='2')){
|
|
|
+ allgemein_packet(MASTER_ADRESSE,(byte*)"04"); // Отправляем NACK
|
|
|
+ Serial.println(F("NACK gesendet."));
|
|
|
+ bufflen_RS485=0;
|
|
|
+ step_send=0;
|
|
|
+ }
|
|
|
+
|
|
|
+ else if(message_here==true && (buffer_RS485[3]== '0' && buffer_RS485[4]=='2')){
|
|
|
+ Serial.println((char*)MASTER_ADRESSE);
|
|
|
+ Serial.println((char*)buffer_PC);
|
|
|
+ send_Nachricht((byte*)"03",buffer_PC);
|
|
|
+ bufflen_PC=0;
|
|
|
+ Serial.println(F("Nachricht geschickt"));
|
|
|
+ step_send=0;
|
|
|
+ bufflen_RS485=0;
|
|
|
+ message_here=false;
|
|
|
+ startMillis=millis();
|
|
|
+ while(millis() - startMillis <= TIMEOUT){//Prüfe ob ACK erhalten ist
|
|
|
+ if(RS485.available()){
|
|
|
+ RS485_read(buffer_RS485,&bufflen_RS485);
|
|
|
+ buffer_RS485[bufflen_RS485]=0;
|
|
|
+ //////LRC beim Empfang//////////////////
|
|
|
+ lrc=pruefeLRC(buffer_RS485,bufflen_RS485);
|
|
|
+ buffer_RS485[bufflen_RS485]=0;
|
|
|
+ step_send=0;
|
|
|
+ if(lrc==0){// ensure null termination
|
|
|
+ if( buffer_RS485[1]== '0' && buffer_RS485[2]=='6'&& buffer_RS485[3]== '0' && buffer_RS485[4]=='3'){
|
|
|
+ Serial.println(F("ACK erhalten")); //ACK wird nicht an meine Adresse geschickt, schau Timeout an oder
|
|
|
+ bufflen_RS485=0;
|
|
|
+ step_send=0;
|
|
|
+ message_here=false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ else{bufflen_RS485=0;}
|
|
|
+ }
|
|
|
+ else{Serial.print(F("Fehler_2.LRC stimmt nicht"));bufflen_RS485=0;
|
|
|
+ }}
|
|
|
+ }
|
|
|
+ if(millis()-startMillis>TIMEOUT && message_here==true){Serial.println(F("Fehler_3.Timeout ist abgelaufen. Kein ACK"));message_here=true;step_send=3;}
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+///////////////////////02////////////////////////////////////////////////
|
|
|
+
|
|
|
+
|
|
|
+///////////////////////////////////////01/////////////////////////////////
|
|
|
+ if((buffer_RS485[3]== '0' && buffer_RS485[4]=='1')){
|
|
|
+
|
|
|
+ allgemein_packet(MASTER_ADRESSE,(byte*)"03");
|
|
|
+ for (byte i = 5; i < strlen((char*)buffer_RS485)-4; i++) {
|
|
|
+ nachricht_buffer[i-5] = buffer_RS485[i];
|
|
|
+ }
|
|
|
+ Serial.println(F("Sie haben die Nachricht erhalten: "));
|
|
|
+ Serial.println((char*)nachricht_buffer);//nur PAYLOAD zeigen
|
|
|
+ bufflen_RS485=0;
|
|
|
+ }
|
|
|
+ //////////////////////////////////////01//////////////////////////////
|
|
|
+
|
|
|
+
|
|
|
+ ///////////////////////////////////05//////////////////////////////
|
|
|
+ if((buffer_RS485[3]== '0' && buffer_RS485[4]=='5')){
|
|
|
+ Serial.println(F("Master-Token Verschiebung"));
|
|
|
+ byte datei[2]="";
|
|
|
+ datei[0]=buffer_RS485[5];
|
|
|
+ datei[1]=buffer_RS485[6];
|
|
|
+ datei[2]=0;
|
|
|
+ if(datei[0]==MEINE_ADRESSE[0] && datei[1]==MEINE_ADRESSE[1] ){
|
|
|
+ allgemein_packet((byte*)"00",(byte*)"03");
|
|
|
+ delay(500);//ACK an alle, dass Master-Token erhalten wurde
|
|
|
+ Serial.println(F("Sie haben Master-Token erhalten"));
|
|
|
+ sprintf((char*)MASTER_ADRESSE,"%s",MEINE_ADRESSE);
|
|
|
+ bufflen_RS485=0;
|
|
|
+ is_Master=true;
|
|
|
+ step_send=0;
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ bufflen_RS485=0;
|
|
|
+ timestamp=millis();
|
|
|
+ while((millis()-timestamp)<=TIMEOUT){
|
|
|
+ RS485_read(buffer_RS485,&bufflen_RS485);
|
|
|
+ buffer_RS485[bufflen_RS485]=0;
|
|
|
+ //////LRC beim Empfang//////////////////
|
|
|
+ lrc=pruefeLRC(buffer_RS485,bufflen_RS485);
|
|
|
+ if(lrc==0){
|
|
|
+ if(buffer_RS485[1]== '0' && buffer_RS485[2]=='0' && buffer_RS485[3]== '0' && buffer_RS485[4]=='3'){
|
|
|
+ bufflen_RS485=0;
|
|
|
+ Serial.println(F("Neuer Master hat den Master-Token Empfang bestätigt. Der neue Master ist: "));
|
|
|
+ Serial.println((char*)datei);
|
|
|
+ sprintf((char*)MASTER_ADRESSE,"%s",datei);
|
|
|
+ is_Master=false;
|
|
|
+ step_send=0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else{Serial.println(F("Fehler_2.LRC stimmt nicht"));bufflen_RS485=0;}
|
|
|
+ }
|
|
|
+ if(millis()-timestamp>TIMEOUT){Serial.println(F("Fehler_3.Timeout ist abgelaufen. Der alte Master bleibt Master."));is_Master=false; step_send=0;bufflen_RS485=0;}
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ //////////////////////////////////05/////////////////////////////
|
|
|
+
|
|
|
+ }
|
|
|
+ else{Serial.println(F("Fehler_2.LRC stimmt nicht"));bufflen_RS485=0;}
|
|
|
+ }
|
|
|
+ else{bufflen_RS485=0;}
|
|
|
+ }
|
|
|
+ //////LRC beim Empfang//////////////////
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+/////////////////////////////////////////////////////////////
|
|
|
+//////////////SLAVE_ENDE/////////////////////////////////////
|
|
|
+/////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+/////////////////////////////////////////////////////////
|
|
|
+////////////////////////////MASTER///////////////////////
|
|
|
+/////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+ if(is_Master==true){
|
|
|
+
|
|
|
+
|
|
|
+ char address_loop[2]="";
|
|
|
+/////////////POLLEN////////////////
|
|
|
+ for (int i = 0; i < numAddresses; i++) {
|
|
|
+ // Rufe die Funktion für jedes Array-Element auf
|
|
|
+ if(i!=5){
|
|
|
+ allgemein_packet((byte*)addressList[i],(byte*)"02");
|
|
|
+ delay(500);
|
|
|
+ }
|
|
|
+ }
|
|
|
+///////////POLLEN//////////////////
|
|
|
+
|
|
|
+//Abfrage 01 oder 05 und 02 muss ständig sein
|
|
|
+ if(step_send==0){
|
|
|
+ Serial.println(F("Geben Sie bitte die Funktion ein (als ein Zeichen, z.B 1)\n 1 - Nachricht schicken \n 5 - Master-Token Verschiebung."));
|
|
|
+ step_send++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(step_send==1 && Serial.available()){
|
|
|
+ PC_read(buffer_PC,&bufflen_PC);
|
|
|
+ buffer_PC[bufflen_PC]=0;
|
|
|
+
|
|
|
+ step_send++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(step_send==2 ){
|
|
|
+ if(bufflen_PC==1 && buffer_PC[0]=='1'){bufflen_PC=0; Serial.println(F("Geben Sie bitte die Adresse ein(als ein Zeichen): ")); message_here=true;bufflen_PC=0;step_send++;
|
|
|
+ }
|
|
|
+ else if (bufflen_PC==1 && buffer_PC[0]=='5'){bufflen_PC=0; Serial.println(F("Geben Sie bitte die Adresse des neuen Masters ein*(als ein Zeichen): "));message_here=false; bufflen_PC=0;step_send++;
|
|
|
+ }
|
|
|
+ else{Serial.println(F("Falsche eingabe, geben Sie bitte entweder 1 oder 5"));bufflen_PC=0;step_send=1;}
|
|
|
+ }
|
|
|
+
|
|
|
+ if(step_send==3 && Serial.available()){
|
|
|
+ PC_read(addresse,&address_len);
|
|
|
+ addresse[address_len]=0;
|
|
|
+ sprintf(address_loop,"0%c",addresse[0]);
|
|
|
+ address_loop[2]='\0';
|
|
|
+ step_send++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(step_send==4){
|
|
|
+ if(address_len==1){
|
|
|
+ if(findAddress((char*)address_loop) == true){
|
|
|
+ if(message_here==true){sprintf((char*)Adresse,"0%c",addresse[0]); Serial.println((char*)Adresse);
|
|
|
+ Serial.println(F("Geben Sie bitte die Nachricht ein"));step_send++;
|
|
|
+ }
|
|
|
+ if(message_here==false){step_send++;}
|
|
|
+ }
|
|
|
+ else {Serial.println(F("Adresse steht in der Liste nicht, geben sie bitte die nochmal."));
|
|
|
+ address_len=0;step_send=3;}
|
|
|
+ }
|
|
|
+ else{Serial.println(F("Bitte geben Sie Adresse als ein Zeichen"));
|
|
|
+ address_len=0;step_send=3;}
|
|
|
+ }
|
|
|
+
|
|
|
+ if(step_send==5 && message_here==true && Serial.available()){
|
|
|
+ PC_read(buffer_PC,&bufflen_PC);
|
|
|
+ buffer_PC[bufflen_PC]=0;
|
|
|
+ if(bufflen_PC>241){Serial.println("Die Nachricht ist zu gross, geben Sie bitte die noch mal");bufflen_PC=0;step_send=4;}
|
|
|
+ else{step_send++;}
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+///////////////NACHRICHT/////////////////////////////
|
|
|
+ if(step_send==6 && message_here==true){
|
|
|
+ send_Nachricht(Adresse, buffer_PC);
|
|
|
+ Serial.println("Die Nachricht geschickt");
|
|
|
+ delay(500);
|
|
|
+ step_send=0; message_here=false; address_len=0;
|
|
|
+ }
|
|
|
+ /////////////NACHRICHT////////////////////
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+//////////////MASTER-TOKEN-VERSCHIEBUNG/////////////
|
|
|
+ if(step_send==5 && message_here==false){
|
|
|
+ sprintf((char*)Adresse,"0%c",addresse[0]);
|
|
|
+ Serial.println((char*)Adresse);
|
|
|
+ sendMasterToken(Adresse);
|
|
|
+ bufflen_PC=0;
|
|
|
+ timestamp=millis();
|
|
|
+ while((millis()-timestamp)<=TIMEOUT){
|
|
|
+ RS485_read(buffer_RS485,&bufflen_RS485);
|
|
|
+ buffer_RS485[bufflen_RS485]=0;
|
|
|
+ //////LRC beim Empfang//////////////////
|
|
|
+ lrc=pruefeLRC(buffer_RS485,bufflen_RS485);
|
|
|
+ if(lrc == 0){
|
|
|
+ if(buffer_RS485[1]== '0' && buffer_RS485[2]=='0' && buffer_RS485[3]== '0' && buffer_RS485[4]=='3'){
|
|
|
+ Serial.println(F("Master-Token wurde erfolgreich verschoben. "));
|
|
|
+ sprintf((char*)MASTER_ADRESSE,"%s",Adresse);
|
|
|
+ is_Master=false;
|
|
|
+ Serial.println(F("Sie werden zum Slave"));
|
|
|
+ address_len=0;
|
|
|
+ bufflen_RS485=0;
|
|
|
+ step_send=0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ else{bufflen_RS485=0;}
|
|
|
+ }
|
|
|
+ else {Serial.println(F("Fehler_2.LRC stimmt nicht")); bufflen_RS485=0;}//Es gibt zwei Optionen, entweder Timer abläuft und dann werden alle arrays gelöscht falls etwas erhalten wurde wird alles auch gelöscht, also beim LRC brauche ich kein break
|
|
|
+ }
|
|
|
+ if(millis()-timestamp>TIMEOUT){Serial.println(F("Fehler_3.Timeout ist abgelaufen. Sie bleiben Master. "));address_len=0;bufflen_RS485=0;is_Master=true;step_send=0;}
|
|
|
+ step_send=0;
|
|
|
+ }
|
|
|
+////////////////MASTER-TOKEN-VERSCHIEBUNG//////////////
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if(RS485.available()){
|
|
|
+ RS485_read(buffer_RS485,&bufflen_RS485);
|
|
|
+ buffer_RS485[bufflen_RS485]=0;
|
|
|
+ if((buffer_RS485[1]== '0' && buffer_RS485[2]=='6') || (buffer_RS485[1]=='0' && buffer_RS485[2]=='0')){
|
|
|
+ lrc=pruefeLRC(buffer_RS485,bufflen_RS485);
|
|
|
+ bufflen_RS485=0;
|
|
|
+ if(lrc == 0){
|
|
|
+ ///////////////////////////////////////01/////////////////////////////////
|
|
|
+ if(buffer_RS485[3]== '0' && buffer_RS485[4]=='1'){
|
|
|
+ allgemein_packet(MASTER_ADRESSE,(byte*)"03");
|
|
|
+ for (byte i = 5; i < strlen((char*)buffer_RS485)-4; i++) {
|
|
|
+ nachricht_buffer[i-5] = buffer_RS485[i];
|
|
|
+ }
|
|
|
+ Serial.println(F("Sie haben die Nachricht erhalten: "));
|
|
|
+ Serial.println((char*)nachricht_buffer);//nur PAYLOAD zeigen
|
|
|
+ bufflen_RS485=0;
|
|
|
+ }
|
|
|
+ //////////////////////////////////////01//////////////////////////////
|
|
|
+
|
|
|
+ ///////////////////////////////////////04/////////////////////////////////
|
|
|
+ if(buffer_RS485[3]== '0' && buffer_RS485[4]=='4'){
|
|
|
+ Serial.println(F("NACK erhalten"));
|
|
|
+ bufflen_RS485=0;
|
|
|
+ }
|
|
|
+ //////////////////////////////////////04//////////////////////////////
|
|
|
+
|
|
|
+ ///////////////////////////////////////03/////////////////////////////////
|
|
|
+ if(buffer_RS485[3]== '0' && buffer_RS485[4]=='3'){
|
|
|
+ Serial.println(F("ACK erhalten"));
|
|
|
+ bufflen_RS485=0;
|
|
|
+ }
|
|
|
+ //////////////////////////////////////03//////////////////////////////
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+ else{Serial.println(F("Fehler_2.LRC stimmt nicht"));bufflen_RS485=0;}
|
|
|
+ }
|
|
|
+ else{bufflen_RS485=0;}
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+/////////////////////////////////////////////////////////
|
|
|
+///////////////////MASTERENDE////////////////////////////
|
|
|
+/////////////////////////////////////////////////////////
|
|
|
+ ///////LOOP ENDE
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void RS485_read(byte* buffer, byte* bufflen){
|
|
|
+ unsigned long timestamp=millis();
|
|
|
+ bool packetComplete = false;
|
|
|
+
|
|
|
+ while((millis()-timestamp)<=TIMEOUT && *bufflen < MAX_DATA){
|
|
|
+ if(!packetComplete){
|
|
|
+ if(RS485.available()){
|
|
|
+ char c = RS485.read();
|
|
|
+ buffer[(*bufflen)++] = c;
|
|
|
+
|
|
|
+ if(c == '\n' && *bufflen > 1 && buffer[(*bufflen)-2] == '\r'){
|
|
|
+ packetComplete = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else{break;}
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+///PC_read
|
|
|
+
|
|
|
+void PC_read(byte* buffer, byte* bufflen) {
|
|
|
+ unsigned long timestamp = millis();
|
|
|
+ if (Serial.available()) {
|
|
|
+ while ((millis() - timestamp) <= TIMEOUT) {
|
|
|
+ if(Serial.available()){
|
|
|
+ buffer[*bufflen] = Serial.read();
|
|
|
+ if (!isControl(buffer[*bufflen])) *bufflen = *bufflen + 1;
|
|
|
+ timestamp=millis();
|
|
|
+ // Erhöhe die Länge des Puffers
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+////RS485write
|
|
|
+
|
|
|
+void RS485_write(byte* buffer, byte bufflen){
|
|
|
+ byte iter;
|
|
|
+
|
|
|
+ for(iter=0;iter<bufflen;iter++){
|
|
|
+ RS485.write(buffer[iter]);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+////PCwrite
|
|
|
+void PC_write(byte* buffer, byte bufflen){
|
|
|
+
|
|
|
+ byte iter;
|
|
|
+
|
|
|
+ for(iter=0;iter<bufflen;iter++){
|
|
|
+ Serial.write(buffer[iter]);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+ ///LRC
|
|
|
+short berechneLRC(byte* buffer, byte start,byte end) {
|
|
|
+
|
|
|
+ // Lokale Variablen
|
|
|
+ byte hByte, lByte, lrc = LRCVALUE;
|
|
|
+
|
|
|
+ // Funktionsanweisungen
|
|
|
+ for(byte i = start; i < end; i++) lrc += buffer[i];
|
|
|
+ lrc = ~lrc+1;
|
|
|
+
|
|
|
+ // Hex-Wert in ASCII umwandeln
|
|
|
+ hByte = lrc >> 0x04;
|
|
|
+ lByte = lrc & 0x0F;
|
|
|
+
|
|
|
+ if(hByte >= 10) hByte += 0x37;
|
|
|
+ else hByte += 0x30;
|
|
|
+
|
|
|
+ if(lByte >= 10) lByte += 0x37;
|
|
|
+ else lByte += 0x30;
|
|
|
+
|
|
|
+ return (hByte << 8) | lByte;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////////////Unterfunktionen////////////////////////////////////////////////////////////////////////
|
|
|
+//funktioniert
|
|
|
+void send_Nachricht(byte address[3],byte message[241]) {
|
|
|
+ char lrc_str[3]="";
|
|
|
+ short lrc;
|
|
|
+ byte headerb[246];
|
|
|
+ byte packetb[251];
|
|
|
+ // Create header and add message
|
|
|
+ sprintf((char*)headerb, "%s01%s",address,message);
|
|
|
+ //save header in headerb
|
|
|
+ headerb[246] = 0;
|
|
|
+ // Calculate LRC
|
|
|
+ lrc = berechneLRC(headerb,0,strlen((char*)headerb));
|
|
|
+ // Convert LRC to hex and append to packet
|
|
|
+ sprintf(lrc_str,"%c%c",lrc >> 8,lrc & 0x00FF);
|
|
|
+ // pack package and Append CRLF
|
|
|
+ sprintf((char*)packetb,":%s%s%c%c",headerb,lrc_str,'\r','\n');
|
|
|
+ packetb[251]=0;
|
|
|
+ return RS485_write(packetb, strlen((char*)packetb));
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+//при вызове функции нужно указывать функцию и адрес
|
|
|
+//Funktion funktioniert
|
|
|
+void allgemein_packet(byte address[3],byte function[2]) {
|
|
|
+ char lrc_str[3]="";
|
|
|
+ short lrc;
|
|
|
+ byte headerb[5];
|
|
|
+ byte packetb[10];
|
|
|
+ // Create header
|
|
|
+ sprintf((char*)headerb, "%s%s", address,function);
|
|
|
+ headerb[5] = 0;
|
|
|
+ // Calculate LRC
|
|
|
+ lrc = berechneLRC(headerb,0,strlen((char*)headerb));
|
|
|
+ // Convert LRC to hex and append to packet
|
|
|
+ sprintf(lrc_str,"%c%c",lrc>>8,lrc & 0x00FF);
|
|
|
+ // Append CRLF
|
|
|
+ sprintf((char*)packetb,":%s%s%c%c",headerb,lrc_str,'\r','\n');
|
|
|
+ packetb[10]=0;
|
|
|
+ return RS485_write(packetb, strlen((char*)packetb));
|
|
|
+}
|
|
|
+
|
|
|
+//funktioniert
|
|
|
+void sendMasterToken(byte newMasterAddress[3]) {
|
|
|
+ char lrc_str[3]="";
|
|
|
+ short lrc;
|
|
|
+ byte headerb[7];
|
|
|
+ byte packetb[12];
|
|
|
+ //Add message to header
|
|
|
+ sprintf((char*)headerb,"0005%s",newMasterAddress);
|
|
|
+ //save header in headerb
|
|
|
+ headerb[7]=0;
|
|
|
+ // Calculate LRC
|
|
|
+ lrc = berechneLRC(headerb,0,strlen((char*)headerb));
|
|
|
+ // Convert LRC to hex and append to packet
|
|
|
+ sprintf(lrc_str,"%c%c",lrc >> 8,lrc & 0x00FF);
|
|
|
+ // pack package and Append CRLF
|
|
|
+ sprintf((char*)packetb,":%s%s%c%c",headerb,lrc_str,'\r','\n');
|
|
|
+ packetb[12]=0;
|
|
|
+ return RS485_write(packetb, strlen((char*)packetb));
|
|
|
+}
|
|
|
+
|
|
|
+int pruefeLRC(byte *buffer,byte bufflen){
|
|
|
+ char lrc_str[3]="";
|
|
|
+ short lrc;
|
|
|
+ char lrc_empf[3]="";
|
|
|
+ lrc = berechneLRC(buffer,1,bufflen-4);
|
|
|
+ sprintf(lrc_str,"%c%c",lrc >> 8,lrc & 0x00FF);
|
|
|
+ lrc_empf[0] = (char)buffer[bufflen - 4];
|
|
|
+ lrc_empf[1] = (char)buffer[bufflen - 3];
|
|
|
+ lrc_empf[2] = 0; // ensure null termination
|
|
|
+ if(strcmp(lrc_str,lrc_empf) == 0) return 0;
|
|
|
+ else return 1;
|
|
|
+}
|
|
|
+
|
|
|
+bool findAddress(const char* address) {
|
|
|
+ // Durchlaufe das Array und vergleiche jede Adresse
|
|
|
+ for (int i = 0; i < numAddresses; i++) {
|
|
|
+ if (strcmp(addressList[i], address) == 0) {
|
|
|
+ return true; // Adresse gefunden
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false; // Adresse nicht gefunden
|
|
|
+}
|