#include // Zum Ansteuern der Servos #include // Für den I2C Bus #include "TimerOne.h" // Für den Interrupt Timer Servo servoHLL; // So heißt der Servo für die Hauptluftleitung Servo servoHLB; // So heißt der Servo für den Hauptluftbehälter Servo servoBZD; // So heißt der Servo für den Bremszylinderdruck char inputChar[2]; // [0] gibt das Ziel, [1] den Wert an char puffer1; char puffer2; byte inputByte[2]; // [0] gibt das Ziel, [1] den Wert an byte saa1064 = 0x70 >> 1; // Definieren der Uhr - Adresse am I2C Bus int INa=0, INb=0, INc=0, INd=0; int Ziffern[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; int h0,h1,m0,m1,z1,z2,z3,z4; int r[64] = {64,70,76,83,88,94,100,105,109,113,117,120,123,125,127,128,128,128,127,125,123,120,117,113,109,105,100,94,88,83,76,70,64,58,52,45,40,34,28,23,19,15,11,8,5,3,1,0,0,0,1,3,5,8,11,15,19,23,28,34,40,45,52,58}; // Extern berechneter Sinus mit 16 Werten int s[64] = {119,116,112,108,103,98,92,87,81,74,68,62,56,49,43,38,32,27,22,17,13,10,7,4,2,1,0,0,1,2,3,6,9,12,16,20,25,30,36,41,47,54,60,66,72,79,85,90,96,101,106,111,115,118,121,124,126,127,128,128,127,126,125,122}; // Sinus um 120° Phasenverschoben int t[64] = {9,6,3,2,1,0,0,1,2,4,7,10,13,17,22,27,32,38,43,49,56,62,68,74,81,87,92,98,103,108,112,116,119,122,125,126,127,128,128,127,126,124,121,118,115,111,106,101,96,90,85,79,72,66,60,54,47,41,36,30,25,20,16,12}; // Sinus um 240° Phasenverschoben int periode=5500; int zeit=1; int HLsoll; int FS; int speed[150]={5500,4500,4375,3600,2800,2500,2290,2150,2090,1960,1850,1760,1620,1480,1340,1200,1140,1080,1020,960,900,855,810,773,737,700,675,650,625,600,583,567,550,533,517,500,488,475,463,450,438,425,413,400,390,380,370,360,350,344,339,333,328,322,317,311,306,300,293,287,280,276,273,269,265,261,258,254,250,246,243,239,235,233,230,228,225,223,220,218,215,213,210,208,205,203,200,198,195,193,190,188,185,183,180,178,177,175,173,172,170,168,167,165,163,162,160,159,158,156,155,154,153,151,150,149,148,146,145,144,143,141,140,139,138,137,136,134,133,132,131,130,129,128,128,127,126,125,124,123,123,122,121,120,119,118,118,117,116,115}; int rpin = 6; int spin = 7; int tpin = 8; //Pins für den Synchronmotor float scale = 1; int x = 0; int y = 0; int n = 0; int i = 0; //Diverse Zähler void setup() // Initialisierung { servoHLB.attach(10); // Den 3 Servos wird der Pin zugewiesen, an dem sie angeschlossen sind TCCR4B = (TCCR4B & 0xF8) | 0x03 ; // PWM Frequenz einstellen Serial.begin(9600); // Der serial port soll mit 9600 bps starten pinMode(rpin, INPUT); // Die drei Pins für den Synchronmotor werden als Output gesetzt pinMode(spin, INPUT); pinMode(tpin, INPUT); for(i=28;i<40;i++) pinMode(i, OUTPUT); // Alle Pins für Ausgänge werden als Output gesetzt for(i=22;i<28;i++) // Die PULL-UP Widerstände für die Inputs werden aktiviert, da gegen Masse geschaltet wird. {pinMode(i, OUTPUT); digitalWrite(i, HIGH); } Timer1.initialize(zeit*100); Timer1.attachInterrupt(motor); //Initialisieren und aktivieren des Interrupts für die Ausgabe der Motor - PWM Wire.begin(); // Starten des I2C Bus delay(500); initDisplay(); analogWrite(rpin, 0); analogWrite(spin, 0); analogWrite(tpin, 0); // Ausgänge für den Motor werden 0 gesetzt } void initDisplay() // Aktiviert den Dynamic mode der Digitaluhr und stellt dessen Leuchtkraft ein. { Wire.beginTransmission(saa1064); Wire.write(B00000000); // Instruction Byte Wire.write(B01000111); // Control Byte (Dynamic Mode und LED-Strom) Wire.endTransmission(); } void motor() { // Interruptroutine für den Motor if(y>=periode/4) // Je schneller der Motor laufen soll, desto öfter wird das Programm durchlaufen und gibt eine Sinusschwingung verschiedener Frequenz aus. { y=0; if(x>=64) x=0; if(periode<5000) { analogWrite(rpin, 1.5*r[x]); analogWrite(spin, 1.5*s[x]); analogWrite(tpin, 1.5*t[x]); x=x+2; } else { analogWrite(rpin,0); analogWrite(spin,0); analogWrite(tpin,0); } } y++; } void displayDigits() //Anzeigen der Ziffern { for (int z=0; z<16; z++) { Wire.beginTransmission(saa1064); Wire.write(1); // Instruction Byte Wire.write(~Ziffern[h0]); // Stunde Ziffer 1 Wire.write(~Ziffern[h1]+128); // Stunde Ziffer 2 Wire.write(~Ziffern[m0]); // Minute Ziffer 1 Wire.write(~Ziffern[m1]); // Minute Ziffer 2 Wire.endTransmission(); } } void loop() { if (inputChar[0]=='w'){ // Wenn wir an erster Stelle ein "w" empfangen, möchte der PC wissen, ob wir wirklich Serial.println("I am a drivers desk"); // der Arduino für das Fahrpult sind. Das bestätigen wir mit "I am a drivers desk"" if (inputChar[1]=='w'){ // Wenn an zweiter Stelle ebenfalls ein "w" kommt, sollen wir akustisch quitieren tone(5, 1000, 100); delay(200); tone(5, 1000, 100); } } if (inputChar[0]=='o'){ // Wenn wir an erster Stelle ein "w" empfangen, möchte der PC wissen, ob wir wirklich Serial.println("ready"); if (inputChar[1]=='o') { if (inputChar[0] == 'V'){ // "V" für Geschwindigkeit n=2*inputChar[1]; periode=speed[n]; // Aus dem Array "speed" wird die entsprechende Periodendauer für die aktuelle Geschwindigkeit gewählt } if (inputChar[0] == 'P'){ // "P" für PZB, stellvertretend für alle Leuchtmelder LmPZB(inputChar[1]); // Funktion siehe unten } if (inputChar[0] == 'H'){ // "H" für Hauptluftbehälter servoHLB.write(127-inputChar[1]); // Wir weisen dem entsprechenden Servoobjekt seinen Wert zu } if (inputChar[0] == 'M'){ // "M" für Motorstrom analogWrite(2,255-(2*inputChar[1])); // Wir geben den Wert von 0 - 255 PWM an Pin 2,3 aus analogWrite(3,255-(2*inputChar[1])); } if (inputChar[0] == 'N'){ // "N" für Primärstrom analogWrite(9,255-(2*inputChar[1])); // Wir geben den Wert von 0 - 255 PWM an Pin 4 aus } if (inputChar[0] == 'X') // "X" - Stunde { h0 = inputChar[1]/10; // Aufspalten in 2 Ziffern h1 = inputChar[1]%10; } if (inputChar[0] == 'Y') // "Y" - Minute { m0 = inputChar[1]/10; // Aufspalten in 2 Ziffern m1 = inputChar[1]%10; } //displayDigits(); } } if (inputChar[0]=='i'){ // Wenn wir an erster Stelle ein "w" empfangen, möchte der PC wissen, ob wir wirklich Serial.println("readytosend"); if (inputChar[1]=='i') {Input(); } } } void serialEvent() { // Es sind Daten vom PC zugespielt worden for (byte i=0; i<2;i++){ inputChar[i]=Serial.read(); // inputChar[0] Ziel und inputChar[1] Wert zuweisen delay(2); // Da es seine Zeit braucht, bis der PC alles sendet, wird zwischen den Bytes etwas abgewartet } Serial.flush(); // Falls aus irgend einem Grund nun noch Daten im Lesepuffer sind, wird dieser gelöscht } void Input() { Serial.write(INa); // Übertragen der Bytes Serial.write(INb); Serial.write(INc); Serial.write(INd); // Nach der Übertragung werden die Byges 0 gesetzt und neu "befüllt": INa=0; if (digitalRead(22)==LOW)INa|=1; //Lüfter if (digitalRead(23)==LOW)INa|=2; //PZB Befehl if (digitalRead(24)==LOW)INa|=4; //PZB Frei if (digitalRead(25)==LOW)INa|=8; //PZB Wachsam if (digitalRead(26)==LOW)INa|=16; //HSein if (digitalRead(27)==LOW)INa|=32; //HSaus if (digitalRead(28)==LOW)INa|=64; //Horn if (digitalRead(32)==LOW)INa|=128; //SSIFANEU INb=0; if (digitalRead(32)==LOW)INb|=1; // Bit 1.0 Stromabnehmer if (digitalRead(33)==LOW)INb|=2; // Bit 1.1 Stabnehmer if (digitalRead(34)==LOW)INb|=4; // Bit 1.2 Sifa if (digitalRead(35)==LOW)INb|=8; // Bit 1.3 Lokbremse anlegen if (digitalRead(36)==LOW)INb|=16; // Bit 1.4 Lokbremse lösen if (digitalRead(37)==LOW)INb|=32; // Bit 1.5 Pause if (digitalRead(38)==LOW)INb|=64; // Bit 1.6 Zeitraffer if (digitalRead(39)==LOW)INb|=128; // Bit 1.7 Zeitsprung HLsoll = round(1100-1.4*analogRead(13)); //Sollbremsdruck vom FbV wird berechnet if(HLsoll>506)HLsoll=506; INc=HLsoll/4; if(FS>50)FS=0; FS=1024-analogRead(14); //Stellung des Fahrschalter wird berechnet INd=round(FS/20.9)+2; //(0-49) } void LmPZB(byte LM){ // Leuchtmelder vom PC werden empfangen if ((LM&1) > 0){digitalWrite(28, HIGH);} //O (=P) if ((LM&1) == 0){digitalWrite(28, LOW);} if ((LM&2) > 0){digitalWrite(29, HIGH);} //U (=G) if ((LM&2) == 0){digitalWrite(29, LOW);} if ((LM&4) > 0){digitalWrite(30, HIGH);} //1000 if ((LM&4) == 0){digitalWrite(30, LOW);} if ((LM&8) > 0){digitalWrite(31, HIGH);} //LM Hauptschalter aus if ((LM&8) == 0){digitalWrite(31, LOW);} if (n<1){digitalWrite(32, HIGH);} //LM Lokomotive steht else{digitalWrite(32,LOW);} if ((LM&16) > 0){digitalWrite(33, HIGH);} //LM Türen I if ((LM&16) == 0){digitalWrite(33, LOW);} if ((LM&32) > 0){digitalWrite(34, HIGH);} //LM Elelktrische Bremse if ((LM&32) == 0){digitalWrite(34, LOW);} }