/* * Arduino analoge modelbaan stuuring. * Nieuwe versie Bloksturingarduino v0.1 * * Writen by Paul Smits*/#include <Wire.h> // library voor I2C #include <LCD.h> // library voor een standaard LCD display. #include <LiquidCrystal_I2C.h> // library voor 12c LCD display/***** Global vars ***********************************************/// Define I2C Address where the PCF8574A is#define BACKLIGHT_PIN 3 // zet de backlight pen op 3LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7); // adressering lcd displaychar incomingByte; // Slaat een waarde op in incomingByte/****************************************************************************** * Definities ****************************************************************************** * Blok A en C is aangesloten op OUT1 en OUT2 van de motorsturing * Blok B en D is aangesloten op OUT3 en OUT4 van de motorsturing ******************************************************************************/// constants zullen niet veranderen.// Geef de output pinnen een naam.const int ledPin = 13; // Pin nummer LedPinconst int blok1Pin = 8; // Pin nummer Blok 1const int blok2Pin = 12; // Pin nummer Blok 2const int sein1rPin = 4; // sein 2 Roodconst int sein1gPin = 5; // sein 2 Groenconst int sein2rPin = 2; // sein 1 roodconst int sein2gPin = 3; // sein 1 Groenconst int wissel1rPin = 6; // Wissel 1 Rechtdoorconst int wissel1aPin = 7; // Wissel 1 Afbuigendint Interval = 500; // Tijdvertraging ter controlle of het programma nog loopt.//Trein 1int PWMA = 9; // Snelheids regeling trein 1int AIN1 = 10; // Rechtsom trein 1int AIN2 = 11; // Linksom trein 1int r = 0;boolean ledState = LOW;long previousMillis = 0; // slaat de laatste stand van de LED op.void setup() { lcd.begin (16, 2); // stelt de lcd driver in op 16 characters en twee regels. // lcd.begin(20,4); // Stelt de lcd driver in op 20 characters en vier regels. // set de backlight van het lcd display aan. lcd.setBacklightPin(BACKLIGHT_PIN, POSITIVE); lcd.setBacklight(HIGH); lcd.home (); // Ga naar de boventse regel en het eerste character. // Zet het onderstaande tekst op het lcd display lcd.setCursor(2, 0); // zet de cursor op het eerste character op de eerste regel lcd.print("Arduino Uno"); lcd.setCursor(1, 1); lcd.print("L298 M-Sturing"); pinMode(PWMA, OUTPUT); pinMode(AIN1, OUTPUT); pinMode(AIN2, OUTPUT); pinMode(blok1Pin, OUTPUT); pinMode(blok2Pin, OUTPUT); pinMode(sein1rPin, OUTPUT); pinMode(sein1gPin, OUTPUT); pinMode(sein2rPin, OUTPUT); pinMode(sein2gPin, OUTPUT); pinMode(ledPin, OUTPUT); pinMode(wissel1rPin, OUTPUT); pinMode(wissel1aPin, OUTPUT); pinMode(ledPin, OUTPUT); Serial.begin(9600); // Open een serial verbinding op 9600 baud. baanvak(0, 1); // Meld alle blokken bezet bij het starten. menu();}void loop() { // Controlle led om te zien of het programma nog werkt. unsigned long currentMillis = millis(); if (currentMillis - previousMillis > Interval) { // Sla de laatste stand van de Led waneer die nog knipperde previousMillis = currentMillis; // Als de Led uit is zet de Led aan en vice-versa: if (ledState == LOW) ledState = HIGH; else ledState = LOW; digitalWrite(ledPin, ledState); // Afhankelijk van de ledState is de Led aan of uit. } if (Serial.available() > 0) { // Kijk of de seriele verbinding beschikbaar is. int incomingByte = Serial.read(); // Lees een 'byte'. switch (incomingByte) { case 'A': // Blok 1 vrijgave Serial.println("Blok 1 : Vrij"); // Parameters : baanvak( blok, status) status, 0 vrij, 1 bezet. baanvak(1, 0); lcd.home (); lcd.setCursor(0, 0); lcd.print("Blok 1: Vrij"); menu(); break; case 'a': // Blok 1 bezet melding Serial.println("Blok 1 : Bezet"); baanvak(1, 1); lcd.home (); lcd.setCursor(0, 1); lcd.print("Blok 1: Bezet"); menu(); break; case 'b': // Blok 2 bezet melding. Serial.println("Blok 2: Bezet"); // Parameters : baanvak(blok, status) baanvak(2, 1); // Blok 2 is bezet melding. lcd.home (); lcd.setCursor(0, 1); lcd.print("Blok 2: Bezet"); menu(); break; case 'B':// Blok 2 vrijgave Serial.println("Blok 2: vrij"); baanvak(2, 0); // Blok 2 is vrij gegeven lcd.home (); lcd.setCursor(0, 1); lcd.print("Blok 2: vrij"); menu(); break; case '|': // Wissel word rechtdoor gesteld. wissel(1, 0); lcd.home (); lcd.setCursor(0, 1); lcd.print("Wissel 1 : Rechtdoor"); menu(); break; case '/': // Wissel word afbuigend gesteld. wissel(1, 1); lcd.home (); lcd.setCursor(0, 1); lcd.print("Wissel 1 : Afbuigend"); menu(); break; case '1': // Optrekken trein. Serial.println("Locomotief trekt op."); if (r == 0) { int cw = 1; // Richting locomotief is linksom optrekken. for (int t = 10; t <= 200; t++) { delay(40); locomotief (1, t, cw); } } else { if (r == 1) { int cw = 0; // Richting locomotief is rechtsom optrekken. for (int t = 10; t <= 200; t++) { delay(40); locomotief (1, t, cw); } } } menu(); break; case '0': // Afremmen trein. Serial.println(" Locomotief remt af."); if (r == 0) { int cw = 1; // Richting locomotief is linksom afremmen. for (int t = 200; t >= 10; t--) { delay(20); locomotief (1, t, cw); } } else { if (r == 1) { int cw = 0; // Richting locomotief is rechtsom afremmen. for (int t = 200; t >= 10; t--) { delay(20); locomotief (1, t, cw); } } } menu(); break; case'<': // De rijrichting van de locomotief is linksom r = 1; Serial.println("Rijrichting linksom."); break; case'>': // De rijrichting van de locomotief is rechtsom. r = 0; Serial.println("Rijrichting rechtsom."); break; case '9': //Trein linksom en rechtom noodstop. locomotief (1, 0, 0); locomotief (1, 0, 1); Serial.println("Noodstop geactiveerd"); menu(); break; case '#': baanvak(0, 0); menu(); break; case '*': baanvak(0, 1); menu(); break; } }}void menu() { Serial.println(); Serial.println("Arduino analoge modelbaan sturing: Motorsturingen en blok meldingen"); Serial.println(); Serial.println("Stuur comando's"); Serial.println(); Serial.println("A = Blok 1 vrijgeven a = Blok 1 bezet melden"); Serial.println("B = Blok 2 vrijgeven b = Blok 2 bezet melden"); Serial.println("< = Trein linksom > = Trein rechtsom"); Serial.println("1 = Trein 1 starten 0 = Trein 1 stoppen"); Serial.println("| = Wissel 1 rechtdoor / = Wissel 1 Afbuigend"); Serial.println(); Serial.println("9 = Noodstop"); Serial.println();}void locomotief(int loc, int snelheid, int richting) { // Zet de parameters van de functie locomotief (loc, snelheid, richting) // Loc: 1 output A op het motorshield // Snelheid: 0 is stop, 250 is maximale snelheid // Richting: 0 Rechtsom, 1 Linksom boolean inPin1 = LOW; boolean inPin2 = HIGH; if (richting == 1) { inPin1 = HIGH; inPin2 = LOW; } else { if (richting == 0) { inPin1 = LOW; inPin2 = HIGH; } } if (loc == 1) { digitalWrite(AIN1, inPin1); digitalWrite(AIN2, inPin2); analogWrite(PWMA, snelheid); }}void baanvak(int blok, int status) { // Zet de parameters van de functie baanvak (blok, status) // Blok: 1 waarde blok kan van 1 tot zoveel blokken nodig zijn worden gebruikt. // Voor elk blok moet een routine schrijven. // Status: 0 vrij, 1 bezet. if (blok == 1) { if (status == 1) { digitalWrite(blok1Pin, LOW); digitalWrite(sein1rPin, LOW); digitalWrite(sein1gPin, HIGH); } } if (blok == 1) { if (status == 0) { digitalWrite(blok1Pin, HIGH); digitalWrite(sein1rPin, HIGH); digitalWrite(sein1gPin, LOW); } } if (blok == 2) { if (status == 1) { digitalWrite(blok2Pin, LOW); digitalWrite(sein2rPin, LOW); digitalWrite(sein2gPin, HIGH); } } if (blok == 2) { if (status == 0) { digitalWrite(blok2Pin, HIGH); digitalWrite(sein2rPin, HIGH); digitalWrite(sein2gPin, LOW); } } if (blok == 0) { if (status == 1) { digitalWrite(blok2Pin, LOW); digitalWrite(blok1Pin, LOW); digitalWrite(sein1rPin, LOW); digitalWrite(sein2rPin, LOW); digitalWrite(sein1gPin, HIGH); digitalWrite(sein2gPin, HIGH); } } if (blok == 0) { if (status == 0) { digitalWrite(blok2Pin, HIGH); digitalWrite(blok1Pin, HIGH); digitalWrite(sein1rPin, LOW); digitalWrite(sein2rPin, LOW); digitalWrite(sein1gPin, HIGH); digitalWrite(sein2gPin, HIGH); } }}void wissel(int wnummer, int wrichting) { // Zet de parameters van de functie wissel (wnummer, wrichting) // wnummer : 1, deze waarde bevat het nummer van de wissel // wrichting : 0, deze waarde geeft de richting van de wissel, 1 rechtdoor, 0 afbuigend // Let op !, deze parameters moetten voor elke wissel worden ingesteld, de wissels worden in paar gesteld. // De wissels kunnen ook per wissel gesteld worden, de programeercode hoeft daar niet voor aangepast worden. if (wnummer == 1) { } if (wrichting == 0) { Serial.println("wissel 1 rechtdoor"); digitalWrite(wissel1rPin, HIGH); delay(750); digitalWrite(wissel1rPin, LOW); } if (wnummer == 1) { } if (wrichting == 1) { Serial.println("Wissel 1 afbuigend"); digitalWrite(wissel1aPin, HIGH); delay(750); digitalWrite(wissel1aPin, LOW); }}
1.: I2C communicatie tussen de verschillende blok sturingen.
3.: Wissel sturing voor zware belasting (schaduw station meerdere wissels tegelijk sturen)
4.: Bluetooth communicatie tussen pc en sturing
5. Barebone Arduinio, geen programma's uploaden wel communicatie tussen Arduino en pc.
const byte PinPwmA = 9;const byte PinAin1 = 10;const byte PinAin2 = 11;
// Voor elk blok moet een routine schrijven.
void setBaanvakStatus(byte blok, bool status) { // Zet de parameters van de functie baanvak (blok, status) // Blok: 1 waarde blok kan van 1 tot zoveel blokken nodig zijn worden gebruikt. // Status: 0 vrij, 1 bezet. //voor alle blokken if(blok == 0){ for(byte i = 0; i < sizeof(BlokPin); i++){ digitalWrite(BlokPin[i], !status); //zet blok goed //zet zein goed digitalWrite(SeinPinR[i], status); digitalWrite(SeinPinG[i], !status); } } //specifiek blok else{ digitalWrite(BlokPin[blok - 1], !status); //zet blok goed //zet zein goed digitalWrite(SeinPinR[blok - 1], status); digitalWrite(SeinPinG[blok - 1], !status); }}
switch(commando){ case 'b': //blok vrij Serial.print(F("Blok: ")); Serial.print(nummer); Serial.println(F(" : Vrij")); //update het baanvak setBaanvakStatus(nummer, VRIJ); lcd.home (); lcd.setCursor(0, 1); lcd.print(F("Blok ")); lcd.print(nummer); lcd.print(F(": Vrij")); break; case 'B': //blok vrij Serial.print(F("Blok: ")); Serial.print(nummer); Serial.println(F(" : Bezet")); //update het baanvak setBaanvakStatus(nummer, BEZET); lcd.home (); lcd.setCursor(0, 1); lcd.print(F("Blok ")); lcd.print(nummer); lcd.print(F(": Bezet")); break;
for (int t = 10; t <= 200; t++) { delay(40); locomotief (1, t, cw); }
if (wrichting == 0) { Serial.println("wissel 1 rechtdoor"); digitalWrite(wissel1rPin, HIGH); delay(750); digitalWrite(wissel1rPin, LOW);
unsigned int wisselMillis[sizeof(WisselAfbuigenPin)]; //Wanneer is de bekrachtiging begonnen?bool wisselActive[sizeof(WisselAfbuigenPin)]; //Is de wissel nu bekrachtigd?const unsigned int WisselInterval = 750; //Tijd in ms om wissel te bekrachtigen. Lijkt me al best langvoid setWissel(byte nummer, bool afbuigen){ digitalWrite(WisselRechtPin[nummer], !afbuigen); digitalWrite(WisselAfbuigenPin[nummer], afbuigen); wisselActive[nummer] = true; wisselMillis[nummer] = millis();}void updateWissel(){ unsigned int currentMillis = millis(); for(byte i = 0; i < sizeof(WisselAfbuigenPin); i++){ if(wisselActive[i]){ if(currentMillis - wisselMillis[i] >= WisselInterval){ digitalWrite(WisselRechtPin[i], LOW); digitalWrite(WisselAfbuigenPin[i], LOW); wisselActive[i] = false; } } }}
//i2c Master Code(UNO SMD)#include <Wire.h>#include <LCD.h>#include <LiquidCrystal_I2C.h> // library voor 12c lcd display#define BACKLIGHT_PIN 3LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7); // adressering lcd displayvoid setup(){ pinMode(8,OUTPUT); pinMode(9,OUTPUT); Serial.begin(9600); Serial.println("Arduino test programma : I2C communicatie"); Wire.begin(); delay(1000);}void loop(){ Wire.beginTransmission(5); Wire.write('H'); Serial.println("zend een H naar de Slave"); digitalWrite(8,HIGH); digitalWrite(9,LOW); Wire.endTransmission(); delay(2000); Wire.beginTransmission(5); Wire.write('L'); Serial.println("zend een L naar de Slave"); digitalWrite(8,LOW); digitalWrite(9,HIGH); Wire.endTransmission(); delay(2000); }
/i2c Slave Code(UNO 2)#include <Wire.h>#include <LCD.h>#include <LiquidCrystal_I2C.h> // library voor 12c lcd display#define BACKLIGHT_PIN 3LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7); // adressering lcd displayvoid setup(){ Wire.begin(5); Wire.onReceive(receiveEvent); pinMode(13,OUTPUT); digitalWrite(13,LOW); void loop(){}void receiveEvent(int howMany){ while(Wire.available()) { char c = Wire.read(); if(c == 'H') { digitalWrite(13,HIGH); } else if(c == 'L') { digitalWrite(13,LOW); } }}