• No results found

Prototyputrustningen kan användas till det önskade ändamålet enligt det utförande som föreslagits i detta examensarbete. Det kan däremot vara av intresse att göra vissa fortsatta eller kompletterande utredningar. Framför allt skulle det vara lämp-ligt att ekonomiskt och underhållsmässigt utreda möjligheterna att ansluta fler en-heter med samma funktion som enhet 1 till enhet 2. Då kan fler områden övervakas genom att enbart addera en mikrokontrollplattform. Begräsningarna uppkommer i enhet 2 där speglingen av I/O i så fall sker från fler områden. En lämplig lösning på problemet är då att använda en Arduino MEGA 2560 som mikrokontrollerplattform som har fler I/O än Arduino UNO, se kapitel 2.1.2.1. Funktionen har förberetts med förslag på hur enhet 2 kan känna igen olika enheter, ”enhets ID” kan användas i det syftet.

För att stärka skyddet mot avlyssning är en lämplig fortsättning av projektet att im-plementera antingen RSA eller AES kryptering. En starkare kryptering utesluter be-hovet att göra en enskild bedömning av hur stark krypteringen behöver vara.

Om prototyputrustningen ska användas i en stor kvantitet är det lämpligt att genom-föra kompletteringar relaterad till området tillförlitlighet. Detta examenarbete utgår ifrån data till Arduino UNO:s komponenter för beräkningarna. Genom att genom-föra tester och mätningar på enheterna som används skulle resultatet i detta arbete kunna valideras, alternativt revideras. Metoden behandlas inte i detta examensarbete utan nämns bara ytligt som ett av två alternativ i kapitel 2.6.

Referenser

[1] “Transforming our world: the 2030 Agenda for Sustainable Development .:. Sustainable Development Knowledge Platform.” [Online]. Available:

https://sustainabledevelopment.un.org/post2015/transformingourworld. [Accessed: 22-Mar-2020].

[2] “Skyddslag (2010:305) Svensk författningssamling 2010:2010:305 t.o.m. SFS 2019:941 - Riksdagen.” [Online]. Available:

https://www.riksdagen.se/sv/dokument-lagar/dokument/svensk-forfattningssamling/skyddslag-2010305_sfs-2010-305. [Accessed: 19-May-2020].

[3] “Microcontroller Invention History - Who Invented first Microcontroller.” [Online]. Available: http://www.circuitstoday.com/microcontroller-invention-history. [Accessed: 15-Mar-2020].

[4] “Microcontrollers - Overview - Tutorialspoint.” [Online]. Available:

https://www.tutorialspoint.com/microprocessor/microcontrollers_overvie w.htm. [Accessed: 15-Mar-2020].

[5] “Introduction to Microcontroller - OpenLabPro.com.” [Online]. Available: https://openlabpro.com/guide/basics-of-microcontroller/. [Accessed: 15-Mar-2020].

[6] “1. The Arduino Family - Arduino: A Technical Reference [Book].” [Online]. Available:

https://www.oreilly.com/library/view/arduino-a-technical/9781491934319/ch01.html. [Accessed: 20-Mar-2020]. [7] “Arduino Official Store | Boards Shields Kits Accessories.” [Online].

Available: https://store.arduino.cc/. [Accessed: 15-Mar-2020]. [8] “Arduino - Warranty.” [Online]. Available:

https://www.arduino.cc/en/Main/warranty. [Accessed: 19-May-2020]. [9] “Arduino - Introduction.” [Online]. Available:

https://www.arduino.cc/en/Guide/Introduction. [Accessed: 20-Mar-2020].

[10] T. Arduino et al., “Arduino Tutorial for Ethernet Shield,” 2010. [11] K. & Co, Hur funkar Arduino? Kjell & Co, 2016.

[12] “Arduino - Libraries.” [Online]. Available:

https://www.arduino.cc/en/Reference/Libraries. [Accessed: 19-May-2020].

[13] “Mikrobrytare | OEM Automatic AB.” [Online]. Available: https://www.oemautomatic.se/produkter/sensor-,-a-,-maskinsäkerhet/mikrobrytare. [Accessed: 19-May-2020].

[14] N. Arya and A. P. Singh, “Fault tolerant design of digital systems,” in IET

Conference Publications, 2016, vol. 2016, no. CP739, doi:

10.1049/cp.2016.1534.

[15] B. W. Johnson, “Fault-tolerant Microprocessor-based Systems,” IEEE Micro, vol. 4, no. 6, pp. 6–21, 1984, doi: 10.1109/MM.1984.291277.

[16] A. Avizienis, “Fault-Tolerant Systems,” IEEE Trans. Comput., vol. C–25, no. 12, pp. 1304–1312, 1976, doi: 10.1109/TC.1976.1674598.

[18] A. C. Persya, “Fault-Tolerant Real-Time Systems,” Fault-Tolerant Real-Time

Syst., pp. 177–180, 1996, doi: 10.1007/b102609.

[19] R. Manuel and F. Lapa, “Intruder Alarm Systems - The Road Ahead,” in

Advanced Technologies, InTech, 2009.

[20] N. O. Loop, N. C. Loop, and S. B. Loop, “Wired loop principles | Jablotron Wired loop principles Wired loop principles | Jablotron,” pp. 1–2, 2009. [21] “kryptologi - Uppslagsverk - NE.se.” [Online]. Available:

https://www.ne.se/uppslagsverk/encyklopedi/lång/kryptologi. [Accessed: 19-May-2020].

[22] E. Sahinaslan and O. Sahinaslan, “Cryptographic methods and development stages used throughout history,” AIP Conf. Proc., vol. 2086, no. April, 2019, doi: 10.1063/1.5095118.

[23] S. Singh, The Code Book: How to make it, break it, hack it, crack it. 2001. [24] “Beskrivning av symmetrisk och asymmetrisk kryptering.” [Online].

Available: https://support.microsoft.com/sv-se/help/246071. [Accessed: 19-May-2020].

[25] S. Nisha and M. Farik, “RSA Public Key Cryptography Algorithm A Review,”

Int. J. Sci. Technol. Res., vol. 06, no. 07, pp. 187–191, 2017.

[26] B. Rothke, “A look at the Advanced Encryption Standard (AES),” Inf. Secur.

Manag. Handbook, Sixth Ed., pp. 1151–1158, 2007, doi:

10.1201/9781439833032.ch89.

[27] “What is AES? | TechRadar.” [Online]. Available:

https://www.techradar.com/news/what-is-aes. [Accessed: 21-May-2020]. [28] J. G. Elerath and M. Pecht, “IEEE 1413: An IEEE standard for reliability

predictions,” Proc. - 2010 11th Int. Conf. Electron. Packag. Technol. High Density

Packag. ICEPT-HDP 2010, no. January 2010, pp. 1–6, 2010, doi:

10.1109/ICEPT.2010.5582388.

[29] F. O. Ehiagwina, T. O. Adewunmi, E. O. Seluwa, O. O. Kehinde, and N. S. Abubakar, “A Comparative Overview of Electronic Devices Reliability Prediction Methods-Applications and Trends,” Majlesi J. Telecommun. Devices, no. December, 2017.

[30] DoD, “Reliability Prediction of Electronic Equipment (Military Handbook),”

Dep. Def. USA, p. 205, 1991.

[31] S. Pokorni, “Reliability Prediction of Electronic Equipment : Problems and Experience RELIABILITY PREDICTION OF ELECTRONIC

EQUIPMENT : PROBLEMS AND EXPERIENCE,” no. October 2016, 2019.

[32] S. Pokorni, “PROBLEMS OF RELIABILITY PREDICTION OF ELECTRONIC EQUIPMENT,” no. September 2014, 2019.

[33] G. Gupta, R. P. Mishra, and P. Jain, “Reliability analysis and identification of critical components using Markov model,” in IEEE International Conference on

Industrial Engineering and Engineering Management, 2016, vol. 2016-January,

pp. 777–781, doi: 10.1109/IEEM.2015.7385753.

[34] S. S. Jolly and B. J. Singh, “An approach to enhance availability of repairable systems: A case study of spms,” Int. J. Qual. Reliab. Manag., vol. 31, no. 9, pp. 1031–1051, Sep. 2014, doi: 10.1108/IJQRM-02-2014-0016.

[35] D. A. Rennels, “Fault-Tolerant Computing—Concepts and Examples,” IEEE

Trans. Comput., vol. C–33, no. 12, pp. 1116–1129, 1984, doi:

10.1109/TC.1984.1676390.

[36] M. Catelani, L. Ciani, and M. Venzi, “RBD Model-Based Approach for Reliability Assessment in Complex Systems,” IEEE Syst. J., vol. 13, no. 3, pp. 2089–2097, Sep. 2019, doi: 10.1109/JSYST.2018.2840220.

Bilaga A

I denna bilaga presenteras ett par fördjupningstips inom ramen för de teorier och metoder som presenteras i kapitel 2. Artiklarna lämnas åt läsaren att avgöra innehål-lets relevans.

1: Introductory Microcontroller Programming – Peter Alley 2011

2: Overview of Architectures with Arduino Boards as Building Blocks for Data Ac-quisition and Control Systems – V.M. Cvjetkovic, M. Matijevic - 2016

3: Advanced Encryption Standard – Douglas Selent 2010 4: Moderna krypteringssystem – Eva-Maria Vikström 2006

5: A new Symmetric Key Encryption Algorithm With Higher Performance, Abid Murtaza, Syed Jahanzeb Hussain Pirzada, Liu Jianwei 2019

6: Fault Tolerance for Real-Time Systems: Analysis and Optimization of Roll-back Recovery with Checkpointing – Nikolov Dimitar 2014

7: Reliability Analysis of Electrical Power System Using Graph Theory and Reliability Block Diagram - Bouziane Boussahoua, Ali Elmaouhab 2019 8: Markov Approach to Finding Failure Times of Repairable Systems – John A. Buzacott 1970

9: The Design and Analysis of Fault Tolerant Digital Systems – B.W. Johnsson 1989 10: Better prediction of software failure times using order statistics – Nasser Ab-osaq, Walter Bond – 2009

Bilaga B

Fig. B1 visar hur en potentiometer ansluts till en Arduino UNO via en analog in-gång. Fig. B2 visar hur en LED anslut till en Arduino UNO via en digital utin-gång. Ex-emplen är hämtade från Arduino.

Bilaga C

I Fig. C1 visas ett exempel på en ”Vigenére fyrkant”. Fyrkanten är uppbyggd av det svenska alfabetet där endast gemener har använts.

Bilaga D

I den här bilagan presenteras den uträknings som ligger till grund för de resulterande resistorvärdena för den dubbelbalanserade slingan som presenteras i kapitel 3.2.3.1. Beräkningarna baseras på principen av spänningsdelning enligt kretsen i Fig. D1 och ekvation (D1). De tre tillstånd som krävs för beräkningarna kan ses i Fig. D2 – D4. Genomgående används samma benämningar i ekvationerna som i figurerna i denna bilaga. Beräkningarna är baserad på en förväntad uppmätt spänning enligt:

𝑇𝑖𝑙𝑙𝑠𝑡å𝑛𝑑 1: 4𝑉 𝑇𝑖𝑙𝑙𝑠𝑡å𝑛𝑑 2: 1,5𝑉 𝑇𝑖𝑙𝑙𝑠𝑡å𝑛𝑑 3: 5𝑉 𝑉𝑢𝑡= 𝑍2 𝑍1 + 𝑍2𝑉𝑖𝑛 (D1) I detta examensarbete är: 𝑉𝑢𝑡 = 𝐴 − 𝐼𝑁 𝑉𝑖𝑛 = 5𝑉 Vilket resulterar i: 𝐴 − 𝐼𝑁 = 𝑍2 𝑍1 + 𝑍25𝑉 Tillstånd 1:

Identifierar 𝑍1, 𝑍2 och 𝐴 − 𝐼𝑁samt stoppar in dem i ekvation (D1) och bildar ekvat-ion (D2): { 𝐴 − 𝐼𝑁 = 4𝑉 𝑍1 = 𝑅1Ω 𝑍2 = 𝑅3Ω 4𝑉 = 𝑅3Ω 𝑅1Ω + 𝑅3Ω5𝑉 (D2)

Ekvation (D2) ger ekvation (D3):

𝑅1 =1

Tillstånd 2:

Identifierar 𝑍1, 𝑍2 och 𝐴 − 𝐼𝑁 samt stoppar in dem i ekvation (D1) och bildar ekvat-ion (D4): { 𝐴 − 𝐼𝑁 = 1,5𝑉 𝑍1 = 𝑅1Ω + 𝑅2Ω 𝑍2 = 𝑅3Ω 1,5𝑉 = 𝑅3Ω 𝑅1Ω + 𝑅2Ω + 𝑅3Ω5𝑉 (D4)

Ekvation (D4) ger ekvation (D5):

𝑅2 =7

3𝑅3 − 𝑅1 (D4)

Genom att stoppa in ekvation (D3) i ekvation (D5) erhålls ekvation (D6):

𝑅2 =7 3𝑅3 − 1 4𝑅3 = 25 12𝑅3 (D6) Tillstånd 3:

Identifierar 𝑍1, 𝑍2 och 𝐴 − 𝐼𝑁 samt stoppar in dem i ekvation (D1) och bildar ekvat-ion (D7): { 𝐴 − 𝐼𝑁 = 5𝑉 𝑍1 = 0Ω 𝑍2 = 𝑅3Ω 5𝑉 = 𝑅3Ω 0Ω + 𝑅3Ω5𝑉 (D7)

Ekvation (D7) ger ekvation (D8):

𝑅3 = 𝑅3 (D8)

Enligt ekvation (D3), (D6) och (D8) erhålls värdena på 𝑅1, 𝑅2 och 𝑅3.

{ 𝑅1 =1 4𝑅3 𝑅2 =25 12𝑅3 𝑅3 = 𝑅3

Resulterande värden:

𝑅1 och 𝑅2 beror av storleken på 𝑅3 som i sin tur är oberoende. 𝑅3 = 4700Ω antas fortsättningsvis. Resistorvärdet 𝑅3 är baserat på tillgången av resistorer hos författa-ren.

𝑅1 och 𝑅2 beräknas enligt:

{ 𝑅1 =1 44700Ω = 1175Ω ≈ 1200Ω 𝑅2 =25 124700Ω = 9790Ω ≈ 10000Ω R3 = 4700Ω

Vilket leder till slutresultat:

{

𝑅1 = 1200Ω 𝑅2 = 10000Ω

𝑅3 = 4700Ω

Kontroll:

Genom att beräkna ekvation (D1) med värdena på 𝑅1, 𝑅2 och 𝑅3 kontrolleras spän-ningsnivåerna för tillstånd 1 och 2:

𝑇𝑖𝑙𝑙𝑠𝑡å𝑛𝑑 1: 𝐴 − 𝐼𝑁 = 4700Ω

1200Ω + 4700Ω5𝑉 = 3.98𝑉 ≈ 4V 𝑇𝑖𝑙𝑙𝑠𝑡å𝑛𝑑 2: 𝐴 − 𝐼𝑁 = 4700Ω

Figur D1 – Principkrets för spänningsdelning. Vut är matande spänning. Z1 och Z2 är motstånd. Vin läser av spänningen över Z2.

Figur D2 – Kretsen som motsvarar tillstånd 1: Stäng mikrobrytare.

Figur D3 - Kretsen som motsvarar tillstånd 2: Öppen mikrobrytare.

Bilaga E

I den här bilagan presenteras den kod som skrivits till enhet 1 och enhet 2.

ENHET 1:

// Program created by: Stefan Wernhager // Date: 2020-05-28

// Description: UNIT 1:

// This

pro-gram reads analog input. Depending on the reading it ether sends it to unit 2 or waits until unit 2 asks for it, then sends it. // Before it sends data its encrypted. // See report for more details

//////////////////////////////////////// CONFIGURATION //////////////////////////////////////// ////////// Include libraries #include <SPI.h> #include <Ethernet.h> #include <avr/wdt.h>

////////// Ethernet communication configuration byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; IPAddress ip(192, 168, 1, 176); IPAddress gateway(192, 168, 1, 1); IPAddress subnet(255, 255, 255, 0); int port = 23; EthernetClient client; EthernetServer server(port); IPAddress unit2(192, 168, 1, 177); ////////// Device configuration

String unitID = "UNO001"; // The ID of this particular unit

const int sendIntervalMS = 1000; // The inter-val to send data if unnormal state is reached

const int analogPins[] = {A0, A1, A2, A3, A4, A5}; // A0 - A2 = Area 1, A3 - A5 = Area 51

////////// Device communication configuration

String sepMsg = "%"; // Sign that separates parts in the text mes-sage sent between devises

String endMsg = "!"; // Sign that tells that this is the end of the message

String unit2Command; boolean wait;

String waitUnit2 = "W"; String alarmUnit2 = "+"; char command[2] = {'C', 'A'}; char commandChar; String commandRandomNbr; String commandKeyPosition1; String commandKeyPosition2; String clearMsg; char tempChar;

////////// Crypt configuration int firstKey[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227}; // 10-58 st int secondKey[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227}; // 10-58 st int keyPos[2]; int key[2]; String encryptedMsg; ////////// Program variables int i;

unsigned long previousMillis = 0; unsigned long currentMillis; int state[2];

boolean alarm[2] = {false, false}; float voltage[2];

int voter[2];

//////////////////////////////////////// INITIALIZATION ////////////////////////////////////////

void setup() {

Ethernet.begin(mac, ip, gateway, subnet); // Init ethernet delay(1000); // Ethernet init time Serial.begin(9600); // Init serial port communication

while (!Serial) ; // Wait until its con-nected.

// Init analog pins

for (i = 0; i < sizeof(analogPins); i++) pinMode(analogPins[i], INPUT);

Serial.println("***** THIS IS UNIT 1 Program version 1.0 *****"); } //////////////////////////////////////// MAIN PROGRAM //////////////////////////////////////// void loop() { // Enable watchdog wdt_enable(WDTO_8S);

// Read sensorvalues from area 1 and area 2

// Check the input values for area1/2 with the voting algorithm, set alarmArea1/2 true if ADC differs from each other (Unnormal) voter[0] = majorityVoter(analogRead(analogPins[0]),

analogRead(analogPins[1]), analogRead(analogPins[2]), 1); // Read A0 - A2 = Area 1

voter[1] = majorityVoter(analogRead(analogPins[3]),

analogRead(analogPins[4]), analogRead(analogPins[5]), 2); // Read A3 - A5 = Area 2

// Check the state of the ADC values for area 1/2, set

alarmArea1/2 true if value are in the wrong state (Unnormal state) if (voter[0] != 9999) state[0] = checkState(voter[0]);

else state[0] = 3;

if (state[0] != 1) alarm[0] = true;

if (voter[1] != 9999) state[1] = checkState(voter[1]); else state[1] = 3;

// If alarm[0] or alarm[1] are HIGH, then we got un-normal

state, send data continuously during a predefined interval to unit 2

if ( alarm[0] || alarm[1]) { currentMillis = millis();

if ( (currentMillis - previousMillis) >= sendIntervalMS) { previousMillis = currentMillis;

// Put together the data to send

clearMsg = unitID + sepMsg + String(voter[0]) + sepMsg + String(alarm[0]) + sepMsg + String(state[0]) + sepMsg +

String(voter[1]) + sepMsg + String(alarm[1]) + sepMsg + String(state[1]); // Generate keys keyPos[0] = random(10, 58); keyPos[1] = random(10, 58); key[0] = firstKey[keyPos[0]]; key[1] = secondKey[keyPos[1]];

// Create string with the encrypted data and add the key po-sitions in front, send data to unit 2

encryptedMsg = alarmUnit2 + String(keyPos[0]) + String(key-Pos[1]) + String(encryptString(clearMsg, key[0], key[1])) + endMsg;

alarmSendToUnit2(encryptedMsg, unit2, port); encryptedMsg = ""; clearMsg = "";

} }

// If state is unchanged, run as normal and If something is re-ceived from master process it

unit2Command = communicateWithUnit2(waitUnit2); if ( unit2Command.length() > 0 ) {

// Divide message into useful parts

for (i = 0; i < unit2Command.length(); i++) { char temp = unit2Command[i];

if (i == 0) commandChar = temp; // Save the command identi-fier (First sign)

if (i > 0 && i < 6) commandRandomNbr += temp; // Save the 5 digit random number

if (i == 6 || i == 7 ) commandKeyPosition1 += temp; // Save the position for the first key

if (i > 7 && i < unit2Command.length()) commandKeyPosition2 += temp; // Save the position for the second key

}

// Get the keys

key[0] = firstKey[commandKeyPosition1.toInt()]; key[1] = secondKey[commandKeyPosition2.toInt()]; // Depending on the command C or A from unit 2

// C: Send unitID, ADC Area 1, alarm Area 1, state Area 1, ADC Area 2, alarm Area 2, state Area 2

// A: Send unitID, the random number received from unit 2, alarm Area 1, state Area 1, the random number received from unit 2, alarm Area 2, state Area 2

if (commandChar == command[0]) // C

clearMsg = unitID + sepMsg + String(voter[0]) + sepMsg + String(alarm[0]) + sepMsg + String(state[0]) + sepMsg +

String(voter[1]) + sepMsg + String(alarm[1]) + sepMsg + String(state[1]);

else if (commandChar == command[1]) // A

clearMsg = unitID + sepMsg + commandRandomNbr + sepMsg + String(alarm[0]) + sepMsg + String(state[0]) + sepMsg + com-mandRandomNbr + sepMsg + String(alarm[1]) + sepMsg +

else clearMsg = "";

// Encrypt the answer, add the termination sign and send it to Unit 2

encryptedMsg = String(encryptString(clearMsg, key[0], key[1])) + endMsg;

communicateWithUnit2(encryptedMsg); // Delete datastrings

tempChar = ' '; commandRandomNbr = ""; commandKeyPosition1 = ""; commandKeyPosition2 = ""; clearMsg = ""; encryptedMsg = ""; } // Reset Watchdog wdt_reset(); } //////////////////////////////////////// FUNCTIONS ////////////////////////////////////////

int majorityVoter( int ADC1, int ADC2, int ADC3, int Area) { // Majority voter algorithm with the possibility to set are-aAlarm HIGH/LOW

int temp = 9999;

int ADCArr[3] = {ADC1, ADC2, ADC3}; int tempArr[2] = {0, 2};

int hyst = 15;

if ( (abs(ADC1 - ADC2) < hyst) && (abs(ADC1 - ADC3) < hyst) && (abs(ADC2 - ADC3) < hyst) ) {

temp = random(0, 2); // 111 if (Area == 1) alarm[0] = false; if (Area == 2) alarm[1] = false; }

if ( (abs(ADC1 - ADC2) < hyst) && (abs(ADC1 - ADC3) > hyst) && (abs(ADC2 - ADC3) > hyst) ) {

temp = random(0, 1); // 110 if (Area == 1) alarm[0] = true; if (Area == 2) alarm[1] = true; }

if ( (abs(ADC1 - ADC2) > hyst) && (abs(ADC1 - ADC3) > hyst) && (abs(ADC2 - ADC3) < hyst) ) {

temp = random(1, 2); // 011 if (Area == 1) alarm[0] = true; if (Area == 2) alarm[1] = true; }

if ( (abs(ADC1 - ADC2) > hyst) && (abs(ADC1 - ADC3) < hyst) && (abs(ADC2 - ADC3) > hyst) ) {

temp = tempArr[random(0, 1)]; // 101 if (Area == 1) alarm[0] = true; if (Area == 2) alarm[1] = true; }

if ( (abs(ADC1 - ADC2) > hyst) && (abs(ADC1 - ADC3) > hyst) && (abs(ADC2 - ADC3) > hyst) ) {

temp = random(0, 2); // 000 if (Area == 1) alarm[0] = true; if (Area == 2) alarm[1] = true; return 9999;

}

return ADCArr[temp] ; }

int checkState(int ADCvalue) { // 0 V = kable cut - Sumalarm

// 4 V = Normal state switch closed - I/O signal // 1,5 V = Switch opened - I/O signal

// 5 V = Shortned - Sumalarm int state;

float volt;

volt = float(ADCvalue * 5) / 1023;

if ( ( volt > 3.9 ) && ( volt < 4.1 ) ) state = 1; // Normal else if ( ( volt > 1.4 ) && ( volt < 1.6 ) ) state = 2; // Open else state = 3; // Alarm

return state; }

void alarmSendToUnit2(String msg, IPAddress targetIP, int port) { // This function is based on the Telnet-server example at

www.arduino.cc

// Sends data to unit 2 if the unit is in alarm state char tempChar;

if ( client.connect(targetIP, port) ) { for (i = 0; i < msg.length(); i++) { client.print(char(msg[i])); delay(1); } while (client.available()) { tempChar = char(client.read()); delay(1); if ( tempChar == '!' ) client.stop(); } } } String communicateWithUnit2(String msg) {

// This function is based on the Telnet-server example at www.arduino.cc

// Function divided into two parts.

// PART 1: Receives a command from unit 2. Responds to that with "toSend" and put a wait-flag HIGH. Then return the received com-mand to the main program.

// PART 2 sends the answer "toSend" to the command received in PART 1. If the respond is "!" then the message are delivered and it put the wait-flag LOW.

String data = "";

EthernetClient client = server.available(); delay(20); // delay 20 ms

///////////////////// PART 1 ///////////////////// while (client && !wait) {

if ( client.available() > 0) { char tempChar = client.read(); data += tempChar; if (tempChar == '!') { wait = true; server.write("W"); tempChar = ' '; client.flush(); return data; } } } ///////////////////// PART 2 ///////////////////// while (client && wait) {

for (i = 0; i < msg.length(); i++) { client.print(char(msg[i]));

Serial.println(char(msg[i])); delay(1);

}

if ( client.available() > 0) { char tempChar = client.read(); data += tempChar;

if (tempChar == '!') { wait = false; client.stop(); tempChar = ' '; client.flush(); return data; } } } }

String encryptString(String clearMsg, int key, int changeStart) { int TOTAL_LETTERS = 93; int startASCIILetters = 34; int lastASCIILetters = 127; String temp; int k; for (k = 0; k < clearMsg.length() ; k++) {

int newCharacter = int(char(clearMsg[k])) + key + (changeStart * k);

while (newCharacter > lastASCIILetters) {

if (newCharacter >= lastASCIILetters ) newCharacter = new-Character - TOTAL_LETTERS;

else if (newCharacter < startASCIILetters) newCharacter = TOTAL_LETTERS - newCharacter; } temp += char(newCharacter); } return temp; }

ENHET 2:

// Program created by: Stefan Wernhager // Date: 2020-05-28

// Description: UNIT 2: //

This program checks if unit 1 has sent data or demand data from unit 1.

// It processes the data and communicate it through digital outputs

// Se report for more details //////////////////////////////////////// KONFIGURATION //////////////////////////////////////// ////////// Include libraries #include <SPI.h> #include <Ethernet.h> #include <avr/wdt.h>

////////// Ethernet communication configuration byte mac[] = { 0xDA, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; IPAddress ip(192, 168, 1, 177); IPAddress gateway(192, 168, 1, 1); IPAddress subnet(255, 255, 255, 0); int port = 23; EthernetServer server(port); EthernetClient client; IPAddress unit1(192, 168, 1, 176); ////////// Device configuration

const int sendIntervalMS = 3000; // 3 sec interval of demanding data from unit 1

const int digitalOut[] = {2, 3, 4}; // Alarmpin = 2, Unit 1 Area 1 = 3, Unit 1 Area 2 = 4

const int resetPin = 5; // If a reset in-pin is wanted ////////// Device communication configuration

char sepMsg = '%'; // Sign that separates parts in the text mes-sage sent between devises

char endMsg = '!'; // Sign that tells that this is the end of the message

String received Data; char command;

char commands[3] = {'C', 'A', 'E'}; int commandCount = 0;

String clearMsg;

////////// UNIT 1 Specific data String unit1ID = "UNO001";

String unitID; int value[6];

boolean unit1Area[2] = {true, true}; int unit1State[2]; boolean sumAlarmUnit1; ////////// Encryption int firstKey[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227};

int secondKey[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227}; // 10-58 st int keyPos[2]; int key[2]; String stringKeyPos1; String stringKeyPos2; String crypted; String decrypted; ////////// Program variables int i; int n;

boolean alarmState = false;

unsigned long previousMillis = 0; unsigned long currentMillis; int randomNbr;

int countTransmissionCycles = 0;

int maxTransmissionCycles = 5; // Max transmission tries before alarm

boolean lostContactAlarm = false;

//////////////////////////////////////// INITIALIZATION ////////////////////////////////////////

void setup() { // Init ethernet

Ethernet.begin(mac, ip, gateway, subnet); delay(1000); // Ethernet init time

server.begin();

// Init serial port communication Serial.begin(9600);

while (!Serial) {

; // wait for serial port to connect. }

// Init digital I/O

for (i = 0; i < sizeof(digitalOut); i++) { pinMode(digitalOut[i], OUTPUT);

}

pinMode(resetPin, INPUT); // Optional

Serial.println("***** THIS IS UNIT 2 Program version 1.0 *****"); } //////////////////////////////////////// MAIN PROGRAM //////////////////////////////////////// void loop() { // Enable watchdog wdt_enable(WDTO_8S); // Resetfunction if (sumAlarmUnit1) resetFunction(resetPin); // If unit 1 has sent data ()

received Data = recieveFromUnit1(); if ( receivedData.length() > 0 ) { alarmState = true;

command = commands[2]; }

// Demand data from unit 1 continuously during a predefined in-terval if the first sign is not "+".

if (char(receivedData[0]) != '+') {

if (sumAlarmUnit1) sumAlarmUnit1 = false; // Restore sumalarm unit 1

currentMillis = millis();

if ( (currentMillis - previousMillis) >= sendIntervalMS) { previousMillis = currentMillis;

commandCount++;

// Choose command C or A. Reset commandCount every 4 cycle if (commandCount == 1) command = commands[0];

else command = commands[1]; if (commandCount == 4) { commandCount = 0; }

//Generate keypositions for encryption and 5 digit random number between 10k-30k

keyPos[0] = random(10, 58); keyPos[1] = random(10, 58);

randomNbr = random(10000, 30000); // Send command to unit 1

delay(10);

clearMsg = String(randomNbr) + String(keyPos[0]) + String(keyPos[1]);

receivedData = communicateWithUnit1(command, clearMsg, endMsg, unit1, port);

// Count the number of transmissions, if it reaches a prede-fined number set alarm

countTransmissionCycles++;

if (countTransmissionCycles == maxTransmissionCycles) lostContactAlarm = true;

} }

// Decrypt the received message from unit 1 if ( receivedData.length() > 0 ) {

for (i = 1; i < receivedData.length(); i++) { char temp = recevedDiata[i];

if ( temp != '!' ) {

if ( alarmState && i < 5 ) { // Used if unit 1 has sent data

if (i == 1 || i == 2 ) stringKeyPos1 += temp; // Save the position for the first key

if (i == 3 || i == 4 ) stringKeyPos2 += temp; // Save the position for the second key

}

else crypted += temp; } if ( temp == '!' ) { if ( alarmState ) { keyPos[0] = stringKeyPos1.toInt(); keyPos[1] = stringKeyPos2.toInt(); } key[0] = firstKey[keyPos[0]]; key[1] = secondKey[keyPos[1]];

decrypted = decryptString(crypted, key[0], key[1]) + temp; }

} }

// Separate the message from unit 1 if ( decrypted.length() > 0 ) { String temp = "";

int count = 0;

// Reset countTransmissionCycles and set lostContact to false countTransmissionCycles = 0;

lostContactAlarm = false;

if ( decrypted[i] != '%' ) temp += decrypted[i]; if ( decrypted[i] == '%' || decrypted[i] == '!') { if (count == 0) unitID = temp; // Unit-ID

if (count == 1) value[0] = temp.toInt(); // ADC if case C, RandNR if case A - Area 1

if (count == 2) value[1] = temp.toInt(); // Alarm - Area 1 if (count == 3) value[2] = temp.toInt(); // State - Area 1 if (count == 4) value[3] = temp.toInt(); // ADC if case C, RandNR if case A - Area 2

if (count == 5) value[4] = temp.toInt(); // Alarm - Area 2 if (count == 6) value[5] = temp.toInt(); // State - Area 2 temp = "";

count ++; }

}

// Check Unit 1 Area 1 and Area 2

unit1Area[0] = checkUnitData(command, value[0], randomNbr); unit1Area[1] = checkUnitData(command, value[3], randomNbr); if (command == commands[0] || command == commands[2] ) { alarmState = false;

unit1State[0] = checkState(value[0]); unit1State[1] = checkState(value[3]); }

// Delete datastrings

stringKeyPos1 = ""; stringKeyPos2 = ""; clearMsg = ""; re-ceivedData = ""; crypted = ""; decrypted = "";

}

// Check sumalarm criteria, set HIGH if anything is true and re-set commandCount

if ( unitID != unit1ID || !unit1Area[0] || value[1] != 0 || !unit1Area[1] || value[4] != 0 || value[2] != unit1State[0] || value[5] != unit1State[1] || lostContactAlarm) { // Lägg ev till jämförelser mellan state i båda för extra koll

sumAlarmUnit1 = true; commandCount = 0; }

// Alarm: PIN 2

if (!sumAlarmUnit1) digitalWrite(digitalOut[0] , HIGH); // Pin 2 else digitalWrite(digitalOut[0], LOW);

// Set I/O for Unit 1 Area 1 and Area 2 HIGH or LOW depending on data

// Area 1: PIN 3 and Area 2: PIN 4

if (unit1State[0] == 1 && !lostContactAlarm) digitalWrite(dig-italOut[1], HIGH); // Pin3

else if (unit1State[0] != 1 || lostContactAlarm) digital-Write(digitalOut[1], LOW);

if (unit1State[1] == 1 && !lostContactAlarm) digitalWrite(dig-italOut[2], HIGH); // Pin4

else if (unit1State[1] != 1 || lostContactAlarm) digital-Write(digitalOut[2], LOW);

// Reset Watchdog timer wdt_reset();

//////////////////////////////////////// FUNCTIONS ////////////////////////////////////////

void resetFunction(int resetPin) { // Optional

// if (digitalRead(resetPin) == HIGH) alarm = false; // Restore alarm

}

String recieveFromUnit1() { String data = "";

EthernetClient client = server.available(); while (client) {

if ( client.available() > 0) { char tempChar = client.read(); data += tempChar; if (tempChar == '!') { server.write("!"); client.stop(); tempChar = ' '; } } } return data; }

String communicateWithUnit1(char command, String key, char termi-nate, IPAddress targetIP, int port) {

// This function is based on the Telnet-server example at www.arduino.cc

String dataToSend = String(command) + key + String(terminate); String targetAnswer = ""; char tempChar; if ( client.connect(targetIP, port) ) { while (client) { delay(1); if (tempChar != 'W') {

for (i = 0; i < dataToSend.length(); i++) { client.print(char(dataToSend[i])); delay(1); } } while (client.available()) { tempChar = char(client.read()); targetAnswer += tempChar; delay(1); if ( tempChar == 'W' ) { } if ( tempChar == '!' ) { server.write("!"); client.flush(); client.stop(); } delay(1); } } } return targetAnswer; }

String decryptString(String encryptedMsg, int key1, int key2) { int TOTAL_LETTERS = 93; int startASCIILetters = 34; int lastASCIILetters = 127; String temp; int k; for (k = 0; k < encryptedMsg.length() ; k++) {

int newCharacter = int(char(encryptedMsg[k])) - key1 - (key2 * k);

while (newCharacter < startASCIILetters) {

if (newCharacter >= lastASCIILetters ) newCharacter = new-Character - TOTAL_LETTERS;

else if (newCharacter < startASCIILetters) newCharacter = newCharacter + TOTAL_LETTERS; } temp += char(newCharacter); } return temp; }

boolean checkUnitData(char command, int value1, int value2) { boolean ok;

switch (command) { case 'A':

if (value1 != value2) ok = false; else ok = true;

break; case 'C':

if (value1 < 0 || value1 > 1024) ok = false; else ok = true;

break; case 'E':

if (value1 != value2) ok = false; else ok = true; break; default: ok = false; break; } return ok; }

int checkState(int ADCvalue) { // 0 V = cable cut – Sum-alarm

// 4 V = Normal state switch closed - I/O signal // 1,5 V = Switch open - I/O signal

// 5 V = Shortened – Sum-alarm float voltage;

int state;

voltage = float(ADCvalue * 5) / 1023;

if ( ( voltage > 3.9 ) && ( voltage < 4.1 ) ) state = 1; // Nor-mal

else if ( ( voltage > 1.4 ) && ( voltage < 1.6 ) ) state = 2; // Open

else state = 3; // Alarm return state;

Bilaga F

I denna bilaga i Fig. F1 – F8 återfinns de flödesscheman ur kapitel 3.3 och 3.4 som beskriver program och krypteringsprocess.

Figur F1 - Flödesschema över principen för hur programmet är uppbyggd med normalt- och onormalt tillstånd. Efter avläsning av I/O för område 1 och område 2 sker en kontroll av villkoren för normalt tillstånd. Uppfylls alla villkor agerar programmet efter normalt tillstånd annars agerar programmet efter onormalt tillstånd.

Figur F3 - Flödesschema över majoritetsvoteringsalgoritmen. Specialfallet där alla tre ingångar visar olika är utelämnad.

Figur F5 - Flödesschema som beskriver hur övervakningen av enhet 1 fungerar där fem misslyckade transaktionsförsök tillåts.

Figur F6 - Flödesschema som beskriver principen för enheternas kommunikation under då normaltillstånd råder.

Figur F7 - Flödesschema som beskriver principen för hur enheterna kommunicerar med varandra under normalt- och onormalt tillstånd.

Figur F8 - Flödesschema som beskriver krypteringen av en klartext K. Klartexten krypteras tecken för tecken i två steg. Resultatet blir den krypterade texten E.

Bilaga G

I Fig. G1 finns den ASCII-tabell som Arduino använder där tecken 34–126 även age-rar alfabet till den teckensubstitution som krypteringsalgoritmen använder.

Figur G1 - ASCI-tabell som används av Arduino UNO och där tecken 34–126 används som alfabet i

Related documents