Ik vraag me alleen nu af wat je precies wilt gaan sturen...
De wissels worden voorlopig nog met de hand (elektrische) omgezet. (kan overigens prima met een Arduino gestuurd worden.)
Later wil ik pwm, voor het rijden gaan gebruiken.
Of wil je zelf ook een programma maken?Een Arduino kan alleen werken als er een programma in zit. ;)
soort cab controle ofzo?kun je me uitleggen wat dat is. :o
#include <AFMotor.h>
AF_DCMotor motor(2, MOTOR12_64KHZ); // create motor #2, 64KHz pwm
void setup() {
Serial.begin(9600); // set up Serial library at 9600 bps
Serial.println("Motor test!");
motor.setSpeed(100); // set the speed to 100/255
}
void loop() {
Serial.print("motor linksom");
motor.run(FORWARD); // turn it on going forward
delay(5000);
Serial.print("Stop motor");
motor.run(RELEASE); // stopped
delay(4000);
Serial.print("motor rechtsom");
motor.run(BACKWARD); // the other way
delay(5000);
Serial.print("Stop motor");
motor.run(RELEASE); // stopped
delay(1000);
}
Een Arduino kan alleen werken als er een programma in zit. ;)Dat snap ik. 8) Maar ik doelde vooral op een programma op een PC die het denkwerk gaat doen.
_ _ _ _ ________ _ _
_| |______| |______| |______| |______| |______| |______| |
De lange pulsen zijn de 80Hz 9% pulsen tegen kleef en de korte pulsen zijn de te regelen PWM pulsen voor de snelheid. Het is wel wat lastig uit te leggen zo. Ik zou een voorbeeld kunnen schrijven door de arduino als het moet maar ik heb nog weinig gewerkt met de timers op een Arduino ::)1,5 uur :o :PTja, je wilt toch een beetje een begrijpelijk verhaal neerzetten...
Mijn eerste idee was om een aantal relais te gebruiken om sporen spanningsloos te maken zodat de treinen zouden stoppen, hiervoor wilde ik de Arduino gebruiken, dit om eens te experimenteren met de Arduino (heb er vier ;D)Dit kan natuurlijk prima. Maar de mogelijkheden zijn dan natuurlijk beperkt.
Ik kwam later nog een motorshield tegen in mijn elektronica bak, zodoende ben ik daar eens mee gaan stoeien en kwam tot de conclusie dat een motorshield prima toe te passen is voor bloksturing.En toen werd het leuk ;D Daarmee heb je wel een heel stuk meer mogelijkheden. Maar automatisch natuurlijk een stuk meer uitdagingen ;D Ik zou gewoon lekker die motor drivers gebruiken in full H-brug en dan PWM sturen op de enable. Heb je geen relais nodig en free running is mogelijk.
Het is de bedoeling dat de diverse arduino's in een centrale kast zitten en met de baan verbonden worden met sub-d 9 polige of 24 polige connectoren.Zelf ben ik wel fan van een gedecentraliseerde opstelling (modules op de plek waar het nodig is, niet in een centrale kast). In een centrale kast lijkt erg overzichtelijk, je hebt immers alles bij elkaar. De hoeveelheid draden die je vervolgens alleen naar die kast moet gaan trekken ::) Vroeger wat het een voordeel. Zo konden verschillende modules onderdelen delen om kosten te besparen. Maar met de komst van betaalbare uC's is dat voordeel een beetje verdwenen. Kijk ook maar naar de telefoon. Vroeger had een stad één grote telefooncentrale waar alle kabels van alle losse telefoons bij elkaar kwamen. Maar met de komst van digitale techniek en vooral goedkopere techniek wordt die juist uit elkaar getrokken. De kabels komen nu in de wijk bij elkaar waar een soort mini centrale staat. Vanaf daar gaat het dan verder als (digitaal) netwerk. Bespaard een hele hoop kabels en doordat alles digitaal is kan het makkelijk aangepast worden. Ik zeg dus niet dat het niet kan of slecht is, maar ik weet niet of het systeem daarmee zo simpel/overzichtelijk mogelijk blijft.
Wat ik begrepen heb, is een zaagtand sturing beter voor de elektromotor dan pwm, minder slijtage.Ik zou niet weten waarom. Slijtage aan het elektronische deel van de motor bestaat eigenlijk niet. En de motor zelf is een beste spoel die als laag doorlaat filter werkt voor het signaal. De motor kan dus niet echt onderscheid maken tussen hele snelle PWM en een gelijkspanning. De regeling wordt er wel een stuk makkelijker van ;D PWM sturing wordt dan ook breed toegepast in de wereld.
De meeste van mijn locomotieven hebben geen vliegwiel.Ondanks dat ze geen vliegwiel hebben zetten ze wel massa in beweging. En het is best zonde om dat echt te gaan remmen als het ons eignelijk niet uitmaakt, zolang het niet versneld. Zie het als het gas los laten of de koppeling indrukken. (Okay, niet op een te moderne auto, die past namelijk ook allemaal trucjes toe. Denk even aan een oud diesel busje ;D) Als je het gas even los gaat zal de auto gaan afremmen op de motor. Terwijl als je de koppeling even indruk en het gas los laat de boel prima even lekker kan rollen. Omdat je dit met PWM eigenlijk heel veel keer per seconde doet is het zonde om steeds te remmen.
Het is niet de bedoeling om op de pc een programma te hebben draaien om de Arduino's aan te sturen, alleen word er data zoals sein standen, wisselstanden, blok bezet meldingen enz en misschien wat comando's naar de pc gestuurd het denkwerk doet de Arduino mega in combinatie met de Arduino uno's.Dit kan met een uC super leuk, maar hoe modulair tegen hoe baan specifiek maakt ligt wel hoe bruikbaar het is op een andere baan. Modulairder is eigenlijk altijd complexer=lastiger, je moet dan rekening houden met alle mogelijke toepassingen. Ik denk dat het voor jou vooral leuk is hoe je jou baan zo leuk mogelijk kunt aansturen.
const int Stijd = 10 * 1000; // Stoptijd stopblok
const int Wtijd = 10 * 1000; // Wachttijd wachtblok
//const int Noodstop = 1; // Noodstop actief hoog
//const int Sda = 20; // I2C bus serial data
// const int Scl = 21; // I2C bus serial clock
// initialisatie noodstop
const int LED = 52; // Stoppen Arduino Mega modelspoor sturing.
const int LED1 = 53; // Vrijgave Arduino Mega modelspoor sturing.
const int LEDN = 50; // Noodstop geactiveerd
const int LEDV = 51; // Noodstop Opgeheven
// initialisatie poorten blokken
const int Blok1 = 22; // Inkomende spoor
const int Blok2 = 23; // Uitgaande spoor
const int Blok3 = 24; // Schaduwstation spoor 1
const int Blok4 = 44; // Schaduwstation spoor 2
const int Blok5 = 26; // Stationspoor spoor 1
const int Blok6 = 27; // Stationspoor spoor 2
const int Blok7 = 28; // Wachtspoor
const int Blok8 = 29; // Goederenspoor
const int Blok9 = 5; // Wisselblok 1
const int Blok10 = 6; // Wisselblok 2
// initialisatie poorten voor wissel sturing
const int Wis1 = 30; // wissel 1
const int Wis2 = 31; // wissel 2
const int Wis3 = 32; // wissel 3
const int Wis4 = 33; // wissel 4
const int Wis5 = 34; // wissel 5
const int Wis6 = 35; // wissel 6
const int Wis7 = 36; // wissel 7
const int Wis8 = 37; // wissel 8
const int Wis9 = 38; // wissel 9
const int Wis10 = 39; // wissel 10
const int Wis11 = 40; // wissel 11
const int Wis12 = 41; // wissel 12
@ Tukker
Bedankt voor je reactie.
Ik word een beetje nieuwsgierig waarom je alle Arduino topics volgt, heb je interesse om ook iets met de Arduino te gaan doen? ;)
Peter (die vastliep in het voorwoord bij "Programmeren voor Dummies)
/* Modelbaan sturing met een Arduino Mega processorboard.
station en schaduwstation sturing modelbaan.
Programma ontwikkeld door Paul Smits.
Deze software mag vrij aangepast worden alleen als er een bron vermelding in de kop staat
Deze sofrware word gebruikt om met een Arduino Mega een modelspoorbaan aan te sturen,
dit is de eerste versie van de software.
Dit programma is copyright by Paul Smits.
*/
#include <Wire.h>
//#include <AFMotor.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address
char incomingByte;
// char BZ = "Bezet"; // String Bezet
//char VR = Vrij; // String Vrij
//char RD = Rechtdoor; // wissel rechtdoor
//char AF = Afbuigend; // wissel afbuigend
// initialisatie poort defenieties
const int Stijd = 10 * 1000; // Stoptijd stopblok
const int Wtijd = 10 * 1000; // Wachttijd wachtblok
//const int Noodstop = 1; // Noodstop actief hoog
//const int Sda = 20; // I2C bus serial data
// const int Scl = 21; // I2C bus serial clock
// initialisatie noodstop
//const int LED = 27; // Stoppen Arduino Mega modelspoor sturing.
const int LED1 = 24; // Vrijgave Arduino Mega modelspoor sturing.
const int LEDV = 25; // Noodstop geactiveerd
//const int LEDN = 31; // Noodstop Opgeheven
// initialisatie poorten blokken
const int Blok1 = 41; // Inkomende spoor
const int Blok2 = 42; // Uitgaande spoor
const int Blok3 = 43; // Schaduwstation spoor 1
const int Blok4 = 44; // Schaduwstation spoor 2
const int Blok5 = 45; // Stationspoor spoor 1
const int Blok6 = 46; // Stationspoor spoor 2
const int Blok7 = 47; // Wachtspoor
const int Blok8 = 48; // Goederenspoor
const int Blok9 = 49; // Wisselblok 1
const int Blok10 = 50; // Wisselblok 2
// initialisatie poorten voor wissel sturing
const int Wis1 = 29; // wissel 1
const int Wis2 = 30; // wissel 2
const int Wis3 = 31; // wissel 3
const int Wis4 = 32; // wissel 4
const int Wis5 = 33; // wissel 5
const int Wis6 = 34; // wissel 6
const int Wis7 = 35; // wissel 7
const int Wis8 = 36; // wissel 8
const int Wis9 = 37; // wissel 9
const int Wis10 = 38; // wissel 10
const int Wis11 = 39; // wissel 11
const int Wis12 = 40; // wissel 12
void setup(){
Serial.begin(9600);
Serial.println(" Arduino modelbaan sturing.");
Serial.println(" Station / schaduwstation sturing");
lcd.begin(16,2); // initialize the lcd for 16 chars 2 lines and turn on backlight
lcd.backlight(); // finish with backlight on
lcd.setCursor(2,0); //Start at character 0 on line 0
lcd.print("Arduino Mega");
lcd.setCursor(0,1);
lcd.print("modelbaan sturing");
// Zet de poorten bloksturing als output
pinMode(Blok1, OUTPUT); // Inkomende spoor
pinMode(Blok2, OUTPUT); // Uitgaande spoor
pinMode(Blok3, OUTPUT); // schaduwstation spoor 1
pinMode(Blok4, OUTPUT); // schaduwstation spoor 2
pinMode(Blok5, OUTPUT); // Stationspoor spoor 1
pinMode(Blok6, OUTPUT); // Stationspoor spoor 2
pinMode(Blok7, OUTPUT); // Wachtspoor
pinMode(Blok8, OUTPUT); // Goederenspoor
// Poorten wissel sturing (test modes)
pinMode(Wis1, OUTPUT); // Wissel 1
pinMode(Wis2, OUTPUT); // Wissel 2
pinMode(Wis3, OUTPUT); // Wissel 3
pinMode(Wis4, OUTPUT); // Wissel 4
pinMode(Wis5, OUTPUT); // Wissel 5
pinMode(Wis6, OUTPUT); // Wissel 6
pinMode(Wis7, OUTPUT); // Wissel 7
pinMode(Wis8, OUTPUT); // Wissel 8
pinMode(Wis9, OUTPUT); // Wissel 9
pinMode(Wis10, OUTPUT); // Wissel 10
pinMode(Wis11, OUTPUT); // Wissel 11
pinMode(Wis12, OUTPUT); // Wissel 12
}
void loop()
{
// Print a message to the LCD.
if (Serial.available() > 0) { // kijk of de seriele verbinding beschikbaar is.
incomingByte = Serial.read(); // Lees een 'byte'.
// Vrijgave of stop comando, Arduino Mega modelspoor sturing.
if(incomingByte == 'V') {
digitalWrite(LED1,LOW); // Stop led uit.
//digitalWrite(LED, HIGH); // Vrijgave Arduino Mega modelspoor sturing.
Serial.println("Vrijgave Arduino Mega modelspoor sturing");
lcd.setCursor(0,1);
lcd.println("Vrijgave sturing");
}
if(incomingByte =='v'){
//digitalWrite (LED, LOW); // Vrijgave led uit.
digitalWrite(LED1, HIGH); // Stoppen Arduino Mega modelspoor sturing.
Serial.println("Stoppen Arduino Mega modelspoor sturing");
lcd.setCursor(0,1);
lcd.println("Stoppen sturing");
}
// Bloksturing Arduino Mega
if(incomingByte == 'a') {
digitalWrite(Blok1, HIGH); // inkomend spoor vrij
Serial.println("Inkomend spoor : Vrij");
lcd.setCursor(0,1);
lcd.println("Inkomend Vrij");
}
if(incomingByte == 'A'){
digitalWrite(Blok1, LOW); // Inkomend spoor bezet
Serial.println("Inkomend spoor : Bezet");
lcd.setCursor(0,1);
lcd.println("Inkomend Bezet");
}
if(incomingByte == 'b') {
digitalWrite(Blok2, HIGH); // Uitgaande spoor vrij
Serial.println("Uitgaande spoor : Vrij");
lcd.setCursor(0,1);
lcd.println("Uitgaande Vrij");
}
if(incomingByte == 'B'){
digitalWrite(Blok2, LOW); // Uitgaande spoor bezet
Serial.println("Uitgaande spoor : Bezet");
lcd.setCursor(0,1);
lcd.println("Uitgaande Bezet");
}
if(incomingByte == 'c') {
digitalWrite(Blok3, HIGH); // Schaduw station spoor 1 vrij
Serial.println("Schaduw station spoor 1 : Vrij");
lcd.setCursor(0,1);
lcd.println("Ss spoor 1 Vrij");
}
if(incomingByte == 'C'){
digitalWrite(Blok3, LOW); // Schaduw station spoor 1 bezet
Serial.println("Schaduw station spoor 1 : Bezet");
lcd.setCursor(0,1);
lcd.println("Ss spoor 1 Bezet");
}
if(incomingByte == 'd') {
digitalWrite(Blok4, HIGH); // Schaduw station spoor 2 vrij
Serial.println("Schaduw station spoor 2 : Vrij");
lcd.setCursor(0,1);
lcd.println("Ss spoor 2 Vrij");
}
if(incomingByte == 'D'){
digitalWrite(Blok4, LOW); // Schaduw station spoor 2 bezet
Serial.println("Schaduw station spoor 2 : Bezet");
lcd.setCursor(0,1);
lcd.println("Ss spoor 2 Bezet");
}
if(incomingByte == 'e') {
digitalWrite(Blok5, HIGH); // Station spoor 1 vrij
Serial.println("Station spoor 1 : Vrij");
lcd.setCursor(0,1);
lcd.println("S spoor 1 Vrij");
}
if(incomingByte == 'E'){
digitalWrite(Blok5, LOW); // Station spoor 1 bezet
Serial.println("Station spoor 1 : Bezet");
lcd.setCursor(0,1);
lcd.println("S spoor 1 Bezet");
}
if(incomingByte == 'f') {
digitalWrite(Blok6, HIGH); // Station spoor 2 vrij
Serial.println("Station spoor 2 : Vrij");
lcd.setCursor(0,1);
lcd.println("S spoor 2 Vrij");
}
if(incomingByte == 'F'){
digitalWrite(Blok6, LOW); // Station spoor 2 bezet
Serial.println("Station spoor 2 : Bezet");
lcd.setCursor(0,1);
lcd.println("S spoor 2 Bezet");
}
if(incomingByte == 'g') {
digitalWrite(Blok7, HIGH); // Wacht spoor vrij
Serial.println("Wacht spoor : Vrij");
lcd.setCursor(0,1);
lcd.println("Wachtspoor Vrij");
}
if(incomingByte == 'G'){
digitalWrite(Blok7, LOW); // Wacht spoor bezet
Serial.println("Wacht spoor : Bezet");
lcd.setCursor(0,1);
lcd.println("Wachtspoor Bezet");
}
if(incomingByte == 'h') {
digitalWrite(Blok8, HIGH); // Goederen spoor vrij
Serial.println("Goederen spoor : Vrij");
lcd.setCursor(0,1);
lcd.println("G spoor Bezet");
}
if(incomingByte == 'H'){
digitalWrite(Blok8, LOW); // Goederen spoor bezet
Serial.println("Goederen spoor : Bezet");
lcd.setCursor(0,1);
lcd.println("G spoor Vrij");
}
// Wisselsturing Arduino Mega
if(incomingByte == '1') {
digitalWrite(Wis1, HIGH); // wissel 1 afbuigend
Serial.println("Wissel 1 : Afbuigend");
}
if(incomingByte == '!'){
digitalWrite(Wis1, LOW); // Wissel 1 rechtdoor
Serial.println("Wissel 1 : Rechtdoor");
}
if(incomingByte == '2') {
digitalWrite(Wis2, HIGH); // Wissel 2 afbuigend
Serial.println("Wissel 2 : Afbuigend");
}
if(incomingByte == '@'){
digitalWrite(Wis2, LOW); // Wissel 2 rechtdoor
Serial.println("Wissel 2 : Rechtdoor");
}
if(incomingByte == '3') {
digitalWrite(Wis3, HIGH); // Wissel 3 afbuigend
Serial.println("Wissel 3 : Afbuigend");
}
if(incomingByte == '#'){
digitalWrite(Wis3, LOW); // Wissel 3 rechtdoor
Serial.println("Wissel 3 : Rechtdoor");
}
if(incomingByte == '4') {
digitalWrite(Wis4, HIGH); // wissel 4 afbuigend
Serial.println("Wissel 4 : Afbuigend");
}
if(incomingByte == '$'){
digitalWrite(Wis4, LOW); // Wissel 4 rechtdoor
Serial.println("Wissel 4 : Rechtdoor");
}
if(incomingByte == '5') {
digitalWrite(Wis5, HIGH); // Wissel 5 afbuigend
Serial.println("Wissel 5 : Afbuigend");
}
if(incomingByte == '%'){
digitalWrite(Wis5, LOW); // Wissel 5 rechtdoor
Serial.println("Wissel 5 : Rechtdoor");
}
if(incomingByte == '6') {
digitalWrite(Wis6, HIGH); // Wissel 6 afbuigend
Serial.println("Wissel 6 : Afbuigend");
}
if(incomingByte == '^'){
digitalWrite(Wis6, LOW); // Wissel 6 rechtdoor
Serial.println("Wissel 6 : Rechtdoor");
}
if(incomingByte == '7') {
digitalWrite(Wis7, HIGH); // wissel 7 afbuigend
Serial.println("wissel 7 : Afbuigend");
}
if(incomingByte == '&'){
digitalWrite(Wis7, LOW); // Wissel 7 rechtdoor
Serial.println("Wissel 7 : Rechtdoor");
}
if(incomingByte == '8') {
digitalWrite(Wis8, HIGH); // Wissel 8 afbuigend
Serial.println("Wissel 8 : Afbuigend");
}
if(incomingByte == '*'){
digitalWrite(Wis8, LOW); // Wissel 8 rechtdoor
Serial.println("Wissel 8 : Rechtdoor");
}
if(incomingByte == '9') {
digitalWrite(Wis9, HIGH); // Wissel 9 afbuigend
Serial.println("Wissel 9 : Afbuigend");
}
if(incomingByte == '('){
digitalWrite(Wis9, LOW); // Wissel 3 rechtdoor
Serial.println("Wissel 9 : Rechtdoor");
}
if(incomingByte == '0') {
digitalWrite(Wis10, HIGH); // Wissel 10 afbuigend
Serial.println("Wissel 10 : Afbuigend");
}
if(incomingByte == ')'){
digitalWrite(Wis10, LOW); // Wissel 3 rechtdoor
Serial.println("Wissel 10 : Rechtdoor");
}
// Noodstop of vrijgave Arduino Mega modelspoor sturing.
if(incomingByte == 'N') {
digitalWrite(LEDV, HIGH);
Serial.println("Noodstop alle treinen stoppen !");
lcd.setCursor(0,1);
lcd.println("Noodstop in ");
}
if(incomingByte == 'n') {
digitalWrite(LEDV, LOW);
Serial.println("Noodstop alle treinen opgeheven !");
lcd.setCursor(0,1);
lcd.println("Noodstop vrij ");
}
}
Imports System.IO
Imports System.IO.Ports
Imports System.Threading
Public Class Form1
Shared _continue As Boolean
Shared _serialPort As SerialPort
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
SerialPort1.Close()
SerialPort1.PortName = "com7" 'change com port to match your Arduino port
SerialPort1.BaudRate = 9600
SerialPort1.DataBits = 8
SerialPort1.Parity = Parity.None
SerialPort1.StopBits = StopBits.One
SerialPort1.Handshake = Handshake.None
SerialPort1.Encoding = System.Text.Encoding.Default 'very important!
End Sub
Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs)
'This sub gets called automatically when the com port recieves some data
'Pause while all data is read
'Move recieved data into the buffer
If SerialPort1.IsOpen = True Then
Read()
End If
End Sub
Private Sub Read()
If SerialPort1.IsOpen Then
Dim data As String = SerialPort1.ReadLine()
TextBox1.Text = data
End If
End Sub
Private Sub RadioButton1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton1.CheckedChanged
blok1On.Visible = True
SerialPort1.Open()
SerialPort1.DiscardInBuffer()
SerialPort1.Write("a")
If SerialPort1.IsOpen = True Then
Read()
End If
SerialPort1.Close()
End Sub
Private Sub RadioButton2_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton2.CheckedChanged
blok1On.Visible = False
SerialPort1.Open()
SerialPort1.DiscardInBuffer()
SerialPort1.Write("A")
If SerialPort1.IsOpen = True Then
Read()
End If
SerialPort1.Close()
End Sub
Private Sub RadioButton3_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton3.CheckedChanged
blok2On.Visible = True
SerialPort1.Open()
SerialPort1.DiscardInBuffer()
SerialPort1.Write("b")
If SerialPort1.IsOpen = True Then
Read()
End If
SerialPort1.Close()
End Sub
Private Sub RadioButton4_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton4.CheckedChanged
blok2On.Visible = False
SerialPort1.Open()
SerialPort1.DiscardInBuffer()
SerialPort1.Write("B")
If SerialPort1.IsOpen = True Then
Read()
End If
SerialPort1.Close()
End Sub
Private Sub RadioButton5_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton5.CheckedChanged
blok3On.Visible = True
SerialPort1.Open()
SerialPort1.DiscardInBuffer()
SerialPort1.Write("c")
If SerialPort1.IsOpen = True Then
Read()
End If
SerialPort1.Close()
End Sub
Private Sub RadioButton6_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton6.CheckedChanged
blok3On.Visible = False
SerialPort1.Open()
SerialPort1.DiscardInBuffer()
SerialPort1.Write("C")
If SerialPort1.IsOpen = True Then
Read()
End If
SerialPort1.Close()
End Sub
Private Sub RadioButton7_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton7.CheckedChanged
blok4On.Visible = True
SerialPort1.Open()
SerialPort1.DiscardInBuffer()
SerialPort1.Write("d")
If SerialPort1.IsOpen = True Then
Read()
End If
SerialPort1.Close()
End Sub
Private Sub RadioButton8_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton8.CheckedChanged
blok4On.Visible = False
SerialPort1.Open()
SerialPort1.DiscardInBuffer()
SerialPort1.Write("D")
If SerialPort1.IsOpen = True Then
Read()
End If
SerialPort1.Close()
End Sub
Private Sub RadioButton9_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton12.CheckedChanged
blok5On.Visible = True
SerialPort1.Open()
SerialPort1.DiscardInBuffer()
SerialPort1.Write("e")
If SerialPort1.IsOpen = True Then
Read()
End If
SerialPort1.Close()
End Sub
Private Sub RadioButton10_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton13.CheckedChanged
blok5On.Visible = False
SerialPort1.Open()
SerialPort1.DiscardInBuffer()
SerialPort1.Write("E")
If SerialPort1.IsOpen = True Then
Read()
End If
SerialPort1.Close()
End Sub
Private Sub RadioButton11_CheckedChanged_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton10.CheckedChanged
blok6On.Visible = True
SerialPort1.Open()
SerialPort1.DiscardInBuffer()
SerialPort1.Write("f")
If SerialPort1.IsOpen = True Then
Read()
End If
SerialPort1.Close()
End Sub
Private Sub RadioButton12_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton11.CheckedChanged
blok6On.Visible = False
SerialPort1.Open()
SerialPort1.DiscardInBuffer()
SerialPort1.Write("F")
If SerialPort1.IsOpen = True Then
Read()
End If
SerialPort1.Close()
End Sub
Private Sub RadioButton14_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton14.CheckedChanged
blok7On.Visible = True
SerialPort1.Open()
SerialPort1.DiscardInBuffer()
SerialPort1.Write("g")
If SerialPort1.IsOpen = True Then
Read()
End If
SerialPort1.Close()
End Sub
Private Sub RadioButton15_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton15.CheckedChanged
blok7On.Visible = False
SerialPort1.Open()
SerialPort1.DiscardInBuffer()
SerialPort1.Write("G")
If SerialPort1.IsOpen = True Then
Read()
End If
SerialPort1.Close()
End Sub
Private Sub RadioButton16_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton16.CheckedChanged
blok8On.Visible = True
SerialPort1.Open()
SerialPort1.DiscardInBuffer()
SerialPort1.Write("h")
If SerialPort1.IsOpen = True Then
Read()
End If
SerialPort1.Close()
End Sub
Private Sub RadioButton17_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton17.CheckedChanged
blok8On.Visible = False
SerialPort1.Open()
SerialPort1.DiscardInBuffer()
SerialPort1.Write("H")
If SerialPort1.IsOpen = True Then
Read()
End If
SerialPort1.Close()
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Close()
End Sub
Private Sub RadioButton20_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton20.CheckedChanged
wis1On.Visible = True
SerialPort1.Open()
SerialPort1.DiscardInBuffer()
SerialPort1.Write("!")
If SerialPort1.IsOpen = True Then
Read()
End If
SerialPort1.Close()
End Sub
Private Sub RadioButton19_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton19.CheckedChanged
wis1On.Visible = False
SerialPort1.Open()
SerialPort1.DiscardInBuffer()
SerialPort1.Write("1")
If SerialPort1.IsOpen = True Then
Read()
End If
SerialPort1.Close()
End Sub
Private Sub RadioButton18_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton18.CheckedChanged
End Sub
Private Sub RadioButton21_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton21.CheckedChanged
wis7On.Visible = True
SerialPort1.Open()
SerialPort1.DiscardInBuffer()
SerialPort1.Write("&")
If SerialPort1.IsOpen = True Then
Read()
End If
SerialPort1.Close()
End Sub
Private Sub RadioButton22_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton22.CheckedChanged
wis7On.Visible = False
SerialPort1.Open()
SerialPort1.DiscardInBuffer()
SerialPort1.Write("7")
If SerialPort1.IsOpen = True Then
Read()
End If
SerialPort1.Close()
End Sub
Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
SerialPort1.ReadByte()
End Sub
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
stopOn.Visible = True
SerialPort1.Open()
SerialPort1.DiscardInBuffer()
SerialPort1.Write("N")
If SerialPort1.IsOpen = True Then
Read()
End If
SerialPort1.Close()
End Sub
Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
stopOn.Visible = True
SerialPort1.Open()
SerialPort1.DiscardInBuffer()
SerialPort1.Write("v")
If SerialPort1.IsOpen = True Then
Read()
End If
SerialPort1.Close()
End Sub
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
stopOn.Visible = False
SerialPort1.Open()
SerialPort1.DiscardInBuffer()
SerialPort1.Write("V")
If SerialPort1.IsOpen = True Then
Read()
End If
SerialPort1.Close()
End Sub
Private Sub Button2_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
stopOn.Visible = False
SerialPort1.Open()
SerialPort1.DiscardInBuffer()
SerialPort1.Write("n")
If SerialPort1.IsOpen = True Then
Read()
End If
SerialPort1.Close()
End Sub
End Class
ik dacht dat S88 een speciaal protocol voor de dcc sturing was,s88 is onafhankelijk van het systeem. Het is "gewoon" een schuifregister waarmee de bezetmeldingen worden opgehaald.
Waarom wil ik analoog blijven rijden
Ik heb een twintigtal analoge locomotieven die ook nog zo'n tien a twintig jaar.......
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#define I2C_ADDR 0x27 // Define I2C Address where the PCF8574A is
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
//typedef struct {
//unsigned int Start: 1; / / Using only one bit if possible
//unsigned int Counter: / / and 'counter that is incremented with millis ()
//unsigned int Preset; / / Is set to choose the period of the timer
//unsigned int Done: 1; / / Result when the timer counter and '> = preset
//timer};
//extern Timer timer [N_timers];
int n = 1;
LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);
char incomingByte;
//motor A connected between OUT1 and OUT2
//motor B connected between OUT3 and OUT4
//Motor A
int PWMA = 3; //Speed control
int AIN1 = 9; //Direction
int AIN2 = 8; //Direction
//Motor B
int PWMB = 5; //Speed control
int BIN1 = 11; //Direction
int BIN2 = 12; //Direction
// Relais
int Rel1 = 6;
int Rel2 = 7;
// constants won't change. Used here to
// set pin numbers:
const int ledPin = 13; // the number of the LED pin
// Variables will change:
int ledState = LOW; // ledState used to set the LED
long previousMillis = 0; // will store last time LED was updated
long previousMillis1 = 0;
long previousMillis2 = 0;
// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 500; // interval at which to blink (milliseconds)
long Blok = 10000; // interval at which to blink (milliseconds)
long Wacht = 5000; // interval at which to blink (milliseconds)
void setup(){
lcd.begin (16,2);
// Switch on the backlight
lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
lcd.setBacklight(HIGH);
lcd.home (); // go home
// Print a message to the LCD.
lcd.setCursor(2,0); //Start at character 2 on line 0
lcd.print("Arduino Uno");
lcd.setCursor(1,1);
lcd.print("L298 M-Sturing");
Serial.begin(9600);
Serial.println("Arduino test programma : Motorsturingen en blok meldingen");
Serial.println();
Serial.println("Stuur comando's");
Serial.println();
Serial.println("1 = Blok 1 vrijgeven 5 = Blok 2 vrijgeven");
Serial.println("2 = Blok 1 bezet melden 6 = Blok 2 bezet melden");
Serial.println("3 = Motor B starten 7 = Motor A starten");
Serial.println("4 = Motor B stoppen 8 = Motor A stoppen");
Serial.println();
Serial.println("9 = Motoren A en B stoppen en blok 1 en 2 bezet melden");
Serial.println();
Serial.print(">");
//Set all the pins we need to output pins
// pinMode(STBY, OUTPUT);
pinMode(PWMA, OUTPUT);
pinMode(AIN1, OUTPUT);
pinMode(AIN2, OUTPUT);
pinMode(PWMB, OUTPUT);
pinMode(BIN1, OUTPUT);
pinMode(BIN2, OUTPUT);
pinMode(2, OUTPUT);
pinMode(4, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(10, OUTPUT);
pinMode(ledPin, OUTPUT);
}
void loop (){
// Controlle led om te zien of het programma nog werkt.
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
if (Serial.available()) {
//read serial as a character
//char ser = Serial.read();
if (Serial.available() > 0) { // kijk of de seriele verbinding beschikbaar is.
incomingByte = Serial.read(); // Lees een 'byte'.
}
// Begin Case 1: Blok1 vrij
if(incomingByte == '1') {
Serial.println("Case 1: Blok 1 : Vrij");
digitalWrite(Rel2, HIGH);
tekst();
// Einde Case 1: Blok1 vrij
}
// Begin Case 2: Blok 1 bezet
if(incomingByte == '2') {
Serial.println("Case 2: Blok 1 : Bezet");
digitalWrite(Rel2, LOW);
tekst();
// Einde Case 2: Blok 1 Bezet
}
// Begin Case 3: Motor B on
if(incomingByte == '3') {
Serial.println("motor B: Low speed");
move(0, 64, 1); //motor B, full speed, left
low();
wacht();
Serial.println("motor B: half speed");
move(0, 128, 1); //motor B, half speed, left
half();
wacht();
Serial.println("motor B: full speed");
move(0, 255, 1); //motor B, low speed, left
full();
Serial.println("Case 3: Motor B draait op full speed totdat er een stop comando komt.");
//stop();
tekst();
// Einde Case 3: Motor B on
}
// Begin Case 4: Motor B off
if(incomingByte == '4') {
Serial.println("motor B: Full speed");
move(0, 255, 1); //motor B, full speed
full();
wacht();
Serial.println("motor B: Half speed");
move(0, 128, 1); //motor B, half speed
half();
wacht();
Serial.println("motor B: Low speed");
move(0, 64, 1); //motor B, low speed
low();
wacht();
Serial.println("motor B: Stop");
move(0, 0, 0); //motor B, stop
Serial.println("Case 4: Motor B staat stil omdat er een stop comando gegeven is.");
tekst();
// Einde Case 4: Motor B off
}
// Begin Case 5 : Blok 2 On
if(incomingByte =='5'){
Serial.println("Case 5: Blok 2 : Vrij");
digitalWrite(Rel1, HIGH);
tekst();
// Einde Case 5 : Blok On
}
// Begin Case 6: Blok 2 Off
if(incomingByte == '6') {
Serial.println("Case 6: Blok 2 : Bezet");
digitalWrite(Rel1, LOW);
tekst();
}
// Begin Case 7: Motor A On
if(incomingByte == '7') {
Serial.println("motor A: low speed");
move(1, 64, 1); //motor A, full speed, left
low();
wacht();
Serial.println("motor A: half speed");
move(1, 128, 1); //motor A, half speed, left
half();
wacht();
Serial.println("motor A: full speed");
move(1, 255, 1); //motor A, low speed, left
full();
Serial.println("Case 7: Motor A draait op full speed totdat er een stop comando komt.");
tekst();
// Einde Case 7: Motor A on
}
// Begin Case 8: Motor A Off
if(incomingByte == '8') {
Serial.println("motor A: Full speed");
move(1, 255, 1); //motor A, full speed
full();
wacht();
Serial.println("motor A: Half speed");
move(1, 128, 1); //motor A, half speed
half();
wacht();
Serial.println("motor A: Low speed");
move(1, 64, 1); //motor A, low speed
low(); // sub-routine low
wacht();// sub-routine wacht
Serial.println("motor A: Stop");
move(1, 0, 0); //motor A, stop
Serial.println("Case 8: Motor A staat stil omdat er een stop comando gegeven is.");
tekst();
}
// Einde Case 8: Motor B off
// Begin Case 9 : Noodstop
if(incomingByte == '9') {
Serial.println("Case 9 Noodstop :Motoren A+B stop en blok 1+2 bezet");
stop();
digitalWrite(Rel1, LOW);
Serial.println("Blok 1: Bezet");
digitalWrite(Rel2, LOW);
Serial.println("Blok 2: Bezet");
lcd.home (); // go home
lcd.setCursor(0,1);
lcd.print("Noodstop gemaakt");
tekst();
}
// Einde Case 9 : Noodstop
}
}
void move(int motor, int speed, int direction){
//Move specific motor at speed and direction
//motor: 0 for B 1 for A
//speed: 0 is off, and 255 is full speed
//direction: 0 clockwise, 1 counter-clockwise
//digitalWrite(STBY, HIGH); //disable standby
boolean inPin1 = LOW;
boolean inPin2 = HIGH;
if(direction == 1){
inPin1 = HIGH;
inPin2 = LOW;
}
if(motor == 1){
digitalWrite(AIN1, inPin1);
digitalWrite(AIN2, inPin2);
analogWrite(PWMA, speed);
}
else{
digitalWrite(BIN1, inPin1);
digitalWrite(BIN2, inPin2);
analogWrite(PWMB, speed);
}
}
void stop(){
//Motor A en B stoppen
move(0, 0, 0);// motor A stop
move(1, 0, 0);// motor B stop
}
void wacht(){
unsigned long currentMillis1 = millis();
long wacht = 7500; // Wacht 7.5 Seconden
if(currentMillis1 - previousMillis1 > wacht) {
previousMillis1 = currentMillis1;
}
lcd.home (); // go home
lcd.setCursor(0,1);
//lcd.print("Wacht 5 seconden");
Serial.println("Wacht 5 seconden");
delay(5000);
}
void blok(){
unsigned long currentMillis2 = millis();
long blok = 7500; // Wacht 10 Seconden
if(currentMillis2 - previousMillis2 > blok) {
previousMillis2 = currentMillis2;
}
lcd.home (); // go home
lcd.setCursor(0,1);
lcd.print("Wacht :Blok vrij");
Serial.println("Wacht tot blok vrij is.");
delay(10000);
}
void tekst(){
lcd.home (); // go home
lcd.setCursor(0,1);
lcd.print(">");
Serial.print(">");
}
void low(){
lcd.home (); // go home
lcd.setCursor(0,1);
lcd.print(" Speed low ");
}
void half(){
lcd.home (); // go home
lcd.setCursor(0,1);
lcd.print(" Speed half ");
}
void full(){
lcd.home (); // go home
lcd.setCursor(0,1);
lcd.print(" Speed full ");
}
if (Serial.available()) {
//read serial as a character
//char ser = Serial.read();
if (Serial.available() > 0) { // kijk of de seriele verbinding beschikbaar is.
incomingByte = Serial.read(); // Lees een 'byte'.
}
De methode Serial.available() geeft het aantal beschikbare bytes (of characters) terug die gelezen kunnen worden, daar komt de waarde 0 tot x uit../***** Global vars ***********************************************/
Of zoals het in veel Arduino libraries gedaan wordt/******************************************************************************
* Definitions
******************************************************************************/
unsigned long currentMillis2 = millis();
long blok = 7500; // Wacht 10 Seconden
if(currentMillis2 - previousMillis2 > blok) {
previousMillis2 = currentMillis2;
}
Je checkt op of een bepaalde tijd om is en zo ja, sla je deze op, maar dat is ook echt het enige wat je nu doet. Er hangt verder geen enkele actie aan. const char StringMotorB[] = "motor B: ";
const char StringHalf[] = "half";
const char StringLow[] = "low";
const char StringSpeed[] = " speed";
void printMotorLowSpeed(){
Serial.print(StringMotorB);
Serial.print(StringLow);
Serial.println(StringSpeed);
}
void printMotorHalfSpeed(){
Serial.print(StringMotorB);
Serial.print(StringHalf);
Serial.println(StringSpeed);
}
Op deze manier gebruik je 9 + 4 + 3 + 6 = 19 bytes en laat je deze ook nog een staan in flashmemory ipv ze ram in te laten nemen. (Laatste kun je ook al opvangen door de F() function.) Je zou dit in een handige functie kunnen stoppen maar is voor voor jou om te besluiten en te maken :p Ook zou je Motor en B nog los kunnen doen, handig als je veel motoren (of blokken enz) krijgt.#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
/***** Global vars ***********************************************/
#define BACKLIGHT_PIN 3
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7); // adressering lcd display
char incomingByte;
/******************************************************************************
* Definitions
******************************************************************************
*motor A is aangesloten op OUT1 en OUT2 van de motorsturing
*motor B is aangesloten op OUT3 en OUT4 van de motorsturing
******************************************************************************/
const char StringMotorA[] = "motor A: ";
const char StringMotorB[] = "motor B: ";
const char StringFull[] = "full";
const char StringHalf[] = "half";
const char StringLow[] = "low";
const char StringSpeed[] = " speed";
// constants won't change. Used here to
// set pin numbers:
const int ledPin = 13; // Pin nummer LedPin
const int blok1Pin = 6; // Pin nummer Blok 1
const int blok2Pin = 7; // Pin nummer Blok 2
const unsigned int Interval = 500;
const unsigned int WachtTrein = 7500;
const unsigned int BlokVrij = 10000;
// Variables will change:
//Motor A
int PWMA = 3; //Speed control
int AIN1 = 9; //Direction
int AIN2 = 8; //Direction
//Motor B
int PWMB = 5; //Speed control
int BIN1 = 11; //Direction
int BIN2 = 12; //Direction
int ledState = LOW; // ledState used to set the LED
int wachtState = LOW;
int blokState = LOW;
long previousMillis = 0; // will store last time LED was updated
long previousMillisWacht = 0;
long previousMillisBlok = 0;
// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
//long interval = 500; // interval at which to blink (milliseconds)
void setup(){
lcd.begin (16,2); // Een 16 characters en twee regels display comando
//lcd.begin (20,4); // Voor een 20 characters en vier regelelig display.
// Switch on the backlight
lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
lcd.setBacklight(HIGH);
lcd.home (); // go home
// Print a message to the LCD.
lcd.setCursor(2,0); //Start at character 2 on line 0
lcd.print("Arduino Uno");
lcd.setCursor(1,1);
lcd.print("L298 M-Sturing");
Serial.begin(9600);
// Deze tekst is alleen op een terminal programma te zien of met het serial monitor van het arduino programma.
Serial.println("Arduino test programma : Motorsturingen en blok meldingen");
Serial.println();
Serial.println("Stuur comando's");
Serial.println();
Serial.println("1 = Blok 1 vrijgeven 5 = Blok 2 vrijgeven");
Serial.println("2 = Blok 1 bezet melden 6 = Blok 2 bezet melden");
Serial.println("3 = Motor B starten 7 = Motor A starten");
Serial.println("4 = Motor B stoppen 8 = Motor A stoppen");
Serial.println();
Serial.println("9 = Motoren A en B stoppen en blok 1 en 2 bezet melden");
Serial.println();
Serial.print(">");
//Set all the pins we need to output pins
// pinMode(STBY, OUTPUT);
pinMode(PWMA, OUTPUT);
pinMode(AIN1, OUTPUT);
pinMode(AIN2, OUTPUT);
pinMode(PWMB, OUTPUT);
pinMode(BIN1, OUTPUT);
pinMode(BIN2, OUTPUT);
pinMode(2, OUTPUT);
pinMode(4, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(10, OUTPUT);
pinMode(ledPin, OUTPUT);
}
void loop (){
// Controlle led om te zien of het programma nog werkt.
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > Interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
if (Serial.available()) {
//read serial as a character
//char ser = Serial.read();
if (Serial.available() > 0) { // kijk of de seriele verbinding beschikbaar is.
incomingByte = Serial.read(); // Lees een 'byte'.
}
// Begin Taak 1: Blok1 vrij
if(incomingByte == '1') {
Serial.println("Taak 1: Blok 1 : Vrij");
digitalWrite(blok2Pin, HIGH);
tekst();
// Einde Taak 1: Blok1 vrij
}
// Begin Taak 2: Blok 1 bezet
if(incomingByte == '2') {
Serial.println("Taak 2: Blok 1 : Bezet");
digitalWrite(blok2Pin, LOW);
tekst();
// Einde Taak 2: Blok 1 Bezet
}
// Begin Taak 3: Motor B on
if(incomingByte == '3') {
Serial.println("motor B: Low speed");
move(0, 64, 1); //motor B, full speed, left
low();
wacht();
Serial.println("motor B: half speed");
move(0, 128, 1); //motor B, half speed, left
half();
wacht();
Serial.println("motor B: full speed");
move(0, 255, 1); //motor B, low speed, left
full();
Serial.println("Taak 3: Motor B draait op full speed totdat er een stop comando komt.");
//stop();
tekst();
// Einde Taak 3: Motor B on
}
// Begin Taak 4: Motor B off
if(incomingByte == '4') {
Serial.println("motor B: Full speed");
move(0, 255, 1); //motor B, full speed
full();
wacht();
Serial.println("motor B: Half speed");
move(0, 128, 1); //motor B, half speed
half();
wacht();
Serial.println("motor B: Low speed");
move(0, 64, 1); //motor B, low speed
low();
wacht();
Serial.println("motor B: Stop");
move(0, 0, 0); //motor B, stop
Serial.println("Taak 4: Motor B staat stil omdat er een stop comando gegeven is.");
tekst();
// Einde Taak 4: Motor B off
}
// Begin Taak 5 : Blok 2 On
if(incomingByte =='5'){
Serial.println("Taak 5: Blok 2 Vrij");
digitalWrite(blok1Pin, HIGH);
tekst();
// Einde Taak 5 : Blok On
}
// Begin Taak 6: Blok 2 Off
if(incomingByte == '6') {
Serial.println("Taak 6: Blok 2 Bezet");
digitalWrite(blok1Pin, LOW);
tekst();
// Einde Taak 6: Blok 2 bezet
}
// Begin Taak 7: Motor A On
if(incomingByte == '7') {
Serial.println("motor A: low speed");
move(1, 64, 1); //motor A, full speed, left
low();
wacht();
Serial.println("motor A: half speed");
move(1, 128, 1); //motor A, half speed, left
half();
wacht();
Serial.println("motor A: full speed");
move(1, 255, 1); //motor A, low speed, left
full();
Serial.println("Taak 7: Motor A draait op full speed totdat er een stop comando komt.");
tekst();
// Einde Taak 7: Motor A on
}
// Begin Taak 8: Motor A Off
if(incomingByte == '8') {
Serial.println("motor A: Full speed");
move(1, 255, 1); //motor A, full speed
full();
wacht();
Serial.println("motor A: Half speed");
move(1, 128, 1); //motor A, half speed
half();
wacht();
Serial.println("motor A: Low speed");
move(1, 64, 1); //motor A, low speed
low(); // sub-routine low
wacht();// sub-routine wacht
Serial.println("motor A: Stop");
move(1, 0, 0); //motor A, stop
Serial.println("Taak 8: Motor A staat stil omdat er een stop comando gegeven is.");
tekst();
}
// Einde Taak 8: Motor B off
// Begin Taak 9 : Noodstop
if(incomingByte == '9') {
Serial.println("Taak 9 Noodstop :Motoren A+B stop en blok 1+2 bezet");
stop();
digitalWrite(blok1Pin, LOW);
Serial.println("Blok 1: Bezet");
digitalWrite(blok2Pin, LOW);
Serial.println("Blok 2: Bezet");
lcd.home (); // Home postitie cursor
lcd.setCursor(0,1);
lcd.print("Noodstop gemaakt");
tekst();
}
// Einde Taak 9 : Noodstop
}
}
void move(int motor, int speed, int direction){
//Move specific motor at speed and direction
//motor: 0 for B 1 for A
//speed: 0 is off, and 255 is full speed
//direction: 0 clockwise, 1 counter-clockwise
//digitalWrite(STBY, HIGH); //disable standby
boolean inPin1 = LOW;
boolean inPin2 = HIGH;
if(direction == 1){
inPin1 = HIGH;
inPin2 = LOW;
}
if(motor == 1){
digitalWrite(AIN1, inPin1);
digitalWrite(AIN2, inPin2);
analogWrite(PWMA, speed);
}
else{
digitalWrite(BIN1, inPin1);
digitalWrite(BIN2, inPin2);
analogWrite(PWMB, speed);
}
}
void stop(){
//Motor A en B stoppen
move(0, 0, 0);// motor A stop
move(1, 0, 0);// motor B stop
}
void wacht(){
unsigned long currentMillis = millis();
// long wacht = 7500; // Wacht 7.5 Seconden
if(currentMillis - previousMillisWacht > WachtTrein) {
previousMillisWacht = currentMillis;
}
if (wachtState == LOW)
wachtState = HIGH;
else
wachtState = LOW;
lcd.home (); // go home
lcd.setCursor(0,1);
//lcd.print("Wacht 5 seconden");
Serial.println("Wacht 5 seconden");
}
void blok(){
unsigned long currentMillis = millis();
if(currentMillis - previousMillisBlok > BlokVrij) {
previousMillisBlok = currentMillis;
}
if (blokState == LOW)
blokState = HIGH;
else
blokState = LOW;
lcd.home (); // go home
lcd.setCursor(0,1);
lcd.print("Wacht :Blok vrij");
Serial.println("Wacht tot blok vrij is.");
digitalWrite(blok1Pin, LOW);
}
void tekst(){
lcd.home (); // go home
lcd.setCursor(0,1);
lcd.print(">");
Serial.print(">");
}
void low(){
lcd.home (); // go home
lcd.setCursor(0,1);
lcd.print(" Speed low ");
}
void half(){
lcd.home (); // go home
lcd.setCursor(0,1);
lcd.print(" Speed half ");
}
void full(){
lcd.home (); // go home
lcd.setCursor(0,1);
lcd.print(" Speed full ");
}
void wacht(int time){
previousMillisWacht = millis(); //Wacht vanaf dit moment
wachtState = HIGH; //Zet een flag dat we inderdaad aan het wachten zijn
wachtTrein = time; //dit hoeft niet maar zo is het mogelijk variabele tijden te wachten, zo lang willen we wachten
)
void wachtCheck(){\
//Alleen bekijken als we wachten, anders kunnen we gelijk door
if(wachtState == HIGH){
//We wachten tot er echt wat gedaan moet worden
if(millis() - previousMillisWacht > wachtTrein) {
wachtState = LOW; //Laat zien dat we niet meer wachten
/*
Doe hier alles wat je wilt doen als je klaar bent met wachten
Bla
bla
bla
*/
}
}
}
#DEFINE NRBLOKKEN 2 //Aantal blokken, nu dus maar twee
previousMillisWacht[NRBLOKKEN];
wachtState[NRBLOKKEN];
wachtTrein[NRBLOKKEN];
void wacht(int blok, int time){
previousMillisWacht[blok] = millis(); //Wacht vanaf dit moment
wachtState[blok] = HIGH; //Zet een flag dat we inderdaad aan het wachten zijn
wachtTrein[blok] = time; //dit hoeft niet maar zo is het mogelijk variabele tijden te wachten
)
void wachtCheck(){
//Nu moeten we dit gaan door voor alle blokken
for(unsigned int i = 0; x < NRBLOKKEN; i++){
//Alleen bekijken als we wachten, anders kunnen we gelijk door
if(wachtState[i] == HIGH){
//We wachten tot er echt wat gedaan moet worden
if(millis() - previousMillisWacht[i] > wachtTrein[i]) {
wachtState[i] = LOW; //Stop met wachten
switch(i){
case(0):
/*
Doe hier alles wat je wilt doen als je klaar bent met wachten voor blok 0
(dat is dus het EERSTE blok, beginnen bij 0
Bla
bla
bla
*/
break;
case(1):
/*
Doe hier alles wat je wilt doen als je klaar bent met wachten voor blok 1
Bla
bla
bla
*/
break;
/*
case(x) enz voor meer blokken
*/
}
}
}
}
}
//Maakt alle wachtState LOW
void initWachtState(){
for(unsigned int i = 0; x < NRBLOKKEN; i++){
wachtState[i] = LOW;
}
}
wachtState = LOW;
doe je nu initWachtState()
// test programma keuze hand auto
int keuzePin = 2;
int ledPin = 3;
int led1Pin = 4;
int keuze = 0;
void setup(){
pinMode(2, INPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
Serial.begin(9600);
Serial.print("Arduino uno test programma");
keuze = digitalRead(keuzePin);
if (keuze == LOW){
//digitalWrite(ledPin,HIGH);
automatisch();
}
else
if (keuze == HIGH){
//digitalWrite(led1Pin,HIGH);
}
hand();
}
void loop()
{
}
void automatisch(){
Serial.println("Automatische gekozen");
digitalWrite(led1Pin, LOW);
digitalWrite(ledPin, HIGH);
delay(2000);
}
void hand(){
Serial.println("Handbediening gekozen");
digitalWrite(led1Pin, HIGH);
digitalWrite(ledPin, LOW);
}
// test programma keuze hand auto met behulp van het : Switch(), case statement
int keuzePin = 2;
int ledPin = 3;
int led1Pin = 4;
int keuze = 0;
void setup(){
pinMode(2, INPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
Serial.begin(9600);
Serial.print("Arduino uno test programma");
}
void loop(){
keuze = digitalRead(keuzePin);
switch (keuze) {
case 0:
digitalWrite(led1Pin, HIGH);
delay(2000);
digitalWrite(led1Pin, LOW);
Serial.println("Keuze staat op handbediening");
break;
case 1:
digitalWrite(ledPin, HIGH);
delay(2000);
digitalWrite(ledPin, LOW);
Serial.println("Keuze staat op automatisch");
break;
}
}
pinMode(pin, INPUT); // set pin to input
digitalWrite(pin, HIGH); // turn on pullup resistors
// test programma keuze hand auto
const int KeuzePin = 2;
const int LedPin = 3;
const int Led1Pin = 4;
int keuze = 0;
void setup(){
pinMode(KeuzePin, INPUT);
pinMode(LedPin, OUTPUT);
pinMode(Led1Pin, OUTPUT);
En voor je leesbaarheid en om onze sneller fouten te laten vinden, gebruik duidelijkere namen. Een naam als Led1Pin zegt niet zo veel.// test programma keuze hand auto met behulp van het : Switch(), case statement
//Leesbare namen voor de bedrijfsmodi
#DEFINE AUTO 1
#DEFINE HANDMATIG 0
const int KeuzePin = 2;
const int LedPin = 3;
const int Led1Pin = 4;
int modus = 0;
void setup(){
pinMode(KeuzePin, INPUT);
pinMode(LedPin, OUTPUT);
pinMode(Led1Pin, OUTPUT);
Serial.begin(9600);
Serial.print("Arduino uno switch test programma");
}
void loop(){
modus = digitalRead(keuzePin);
switch (modus) {
case HANDMATIG:
handmatigLoop();
break;
case AUTO:
autoLoop();
break;
}
}
handmatigLoop() en autoLoop() zijn nu te gebruiken als dat je nu loop() gebruikt alleen afhankelijke van de schakelaar.//Loop functie voor handmatig gebruik
void handmatigLoop(){
//Hier alle code die je in loop wilt hebben in handmatig bedrijfsnaam
}
//Loop functie voor automatisch gebruik
void autoLoop(){
//Hier alle code die je in loop wilt hebben in automatisch bedrijfsnaam
}
Ik weet niet of dit de bedoeling is
De ingangsstroom kan je dan met gemak kleiner dan 10mA laten zijn terwijl de uitgang met gemak 50mA schakelt.Maar dan moet de opto wel een CTR hebben van gegarandeerd 500%. Bij de PC817 kan die liggen tussen 50% en 600%. Je kan dus ook behoorlijk pech hebben als je een slechte treft.
De 1N4148 is namelijk een high speed diode en kan dus sneller ingrijpen bij een piekspanning door de spoel.Hier is toch sprake van een misverstand. Als een stroomvoerende spoel wordt afgeschakeld, dan wil de opgeslagen magnetische energie de stroom in stand houden. Als er geen blusdiode aan zit, dan kan die stroom nergens naar toe, en zal een piekspanning veroorzaken. Maar een blusdiode zorgt er voor dat de stroom wel een pad vindt, en de spanning over de spoel wordt dan niet groter dan de drempelspanning van de diode. En die is voor de 1N4001 en de 1N4148 hetzelfde.
Met een relais kost het veel minder poorten...Nee hoor, zorg voor redelijke transistors (bijvoorbeeld dubbele ULN2003 ofzo, zitten ook mooi in een array => maakt simpele printen) en plaats ipv het monostabiel relais (jij noemt ze unpolaire) gelijk de wisselspoel. Zo spaar je al die 40 monostabiele relais uit. Is toch mooi 40 x 70 cent = 28 euro! Je bistabiele relais hou je gewoon parallel aan de wisselspoelen en je gebruikt maar twee pinnen per wissel.
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
/***** Global vars ***********************************************/
// Define I2C Address where the PCF8574A is
#define BACKLIGHT_PIN 3
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7); // adressering lcd display
char incomingByte;
/******************************************************************************
* Definitions
******************************************************************************
*motor A is aangesloten op OUT1 en OUT2 van de motorsturing
*motor B is aangesloten op OUT3 en OUT4 van de motorsturing
******************************************************************************/
const char StringMotorA[] = "motor A: ";
const char StringMotorB[] = "motor B: ";
const char StringFull[] = "full";
const char StringHalf[] = "half";
const char StringLow[] = "low";
const char StringSpeed[] = " speed";
// constants won't change. Used here to
// set pin numbers:
const int ledPin = 13; // Pin nummer LedPin
const int blok1Pin = 6; // Pin nummer Blok 1
const int blok2Pin = 7; // Pin nummer Blok 2
int Interval = 500;
//int wachtTrein = 3000;
//int BlokVrij = 10000; //automatische mode 10 seconden voor het blok vrij gegeven word.
int tijd = 2000;
// Variables will change:
//Motor A
int PWMA = 3; //Speed control
int AIN1 = 9; //Direction
int AIN2 = 8; //Direction
//Motor B
int PWMB = 5; //Speed control
int BIN1 = 11; //Direction
int BIN2 = 12; //Direction
int ledState = LOW; // ledState used to set the LED
int wachtState = LOW;
int blokState = LOW;
long previousMillis = 0; // will store last time LED was updated
//long previousMillisWacht = 0;
//long previousMillisBlok = 0;
// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
//long interval = 500; // interval at which to blink (milliseconds)
void setup(){
lcd.begin (16,2);
// Switch on the backlight
lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
lcd.setBacklight(HIGH);
lcd.home (); // go home
// Print a message to the LCD.
lcd.setCursor(2,0); //Start at character 2 on line 0
lcd.print("Arduino Uno");
lcd.setCursor(1,1);
lcd.print("L298 M-Sturing");
Serial.begin(9600);
Serial.println("Arduino test programma : Motorsturingen en blok meldingen");
menu();
// Set all the pins we need to output pins
// pinMode(STBY, OUTPUT);
pinMode(PWMA, OUTPUT);
pinMode(AIN1, OUTPUT);
pinMode(AIN2, OUTPUT);
pinMode(PWMB, OUTPUT);
pinMode(BIN1, OUTPUT);
pinMode(BIN2, OUTPUT);
pinMode(2, OUTPUT);
pinMode(4, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(10, OUTPUT);
pinMode(ledPin, OUTPUT);
}
void loop (){
// Controlle led om te zien of het programma nog werkt.
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > Interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
if (Serial.available()) {
//read serial as a character
//char ser = Serial.read();
if (Serial.available() > 0) { // kijk of de seriele verbinding beschikbaar is.
incomingByte = Serial.read(); // Lees een 'byte'.
}
// Begin Taak 1: Blok1 vrij
if(incomingByte == '1') {
lcd.home ();
lcd.setCursor(0,1);
lcd.print("Blok 1: vrijgave");
Serial.println("Blok 1 : Vrij");
digitalWrite(blok2Pin, HIGH);
menu();
prompt();
}
// Einde Taak 1: Blok1 vrij
// Begin Taak 2: Blok 1 bezet
if(incomingByte == '2') {
lcd.print("Blok 1: vrijgave");
Serial.println("Blok 1 : Bezet");
digitalWrite(blok2Pin, LOW);
menu();
prompt();
}
// Einde Taak 2: Blok 1 Bezet
// Begin Taak 3: Motor B aan
if(incomingByte == '3') {
lcd.home ();
lcd.setCursor(1,1);
lcd.print(" Speed low ");
Serial.println("Trein B: Low speed");
move(1, 120, 1); //motor B, low speed, links
schakeltijd();
lcd.home ();
lcd.setCursor(1,1);
lcd.print(" Speed half ");
Serial.println("Trein B: Half speed");
move(1, 150, 1); //motor B, half speed, links
schakeltijd();
lcd.home ();
lcd.setCursor(1,1);
lcd.print(" Speed full ");
Serial.println("Trein B: Full speed");
move(1, 200, 1); //motor B, full speed, left
Serial.println("Trein B rijd op full speed totdat er een stop comando komt.");
menu();
prompt();
}
// Einde Taak 3: Motor B on
// Begin Taak 4: Motor B off
if(incomingByte == '4') {
Serial.println("Trein B: Half speed");
displ();
lcd.print(" Speed half ");
move(1, 150, 1); //motor B, half speed, links
schakeltijd();
Serial.println("Trein B: Low speed");
displ();
lcd.print(" Speed low ");
move(1, 120, 1); //motor B, low speed, links
schakeltijd();
Serial.println("Trein B: Stop");
move(1, 0, 0); //motor B, stop
Serial.println("Motor B staat stil omdat er een stop comando gegeven is.");
displ();
lcd.print(" trein stopt ");
schakeltijd();
lcd.print(" Arduino trein ");
menu();
prompt();
}
// Einde Taak 4: Motor B off
// Begin Taak 5 : Blok 2 On
if(incomingByte =='5'){
Serial.println("Blok 2 Vrij");
digitalWrite(blok1Pin, HIGH);
menu();
prompt();
}
// Einde Taak 5 : Blok On
// Begin Taak 6: Blok 2 Off
if(incomingByte == '6') {
Serial.println("Blok 2 Bezet");
digitalWrite(blok1Pin, LOW);
menu();
prompt();
}
// Einde Taak 6: Blok 2 bezet
// Begin Taak 7: Motor A On
if(incomingByte == '7') {
Serial.println("Trein A gaat vertrekken");
Serial.println();
Serial.println("Trein A: Low speed");
lcd.print(" Speed low ");
move(0, 120, 1); //motor A, low speed, rechts
schakeltijd();
Serial.println("Trein A: Half speed");
lcd.print(" Speed half ");
move(0, 150, 1); //motor A, half speed, rechts
schakeltijd();
Serial.println("Trein A: Full speed");
lcd.print(" Speed full ");
move(0, 200, 1); //motor A, full speed, rechts
Serial.println("Trein A rijd op full speed totdat er een stop comando komt.");
menu();
prompt();
}
// Einde Taak 7: Motor A on
// Begin Taak 8: Motor A Off
if(incomingByte == '8') {
Serial.println("Trein gaat stoppen");
Serial.println("Trein A: Half speed");
lcd.print(" Speed half ");
move(0, 170, 1); //motor A, half speed, rechts
schakeltijd();
Serial.println("Trein A: Low speed");
lcd.print(" Speed low ");
move(0, 120, 1); //motor A, low speed, rechts
schakeltijd();
Serial.println("Trein A: Stop");
Serial.println("Trein A is gestopt omdat er een stop comando gegeven is.");
move(0, 0, 0); //motor A, stop
menu();
prompt();
}
// Einde Taak 8: Motor B off
// Begin Taak 9 : Noodstop
if(incomingByte == '9') {
Serial.println("Noodstop :Treinen A+B stop en blok 1+2 bezet");
menu();
noodstop();
prompt();
Serial.println("Trein 1 noodstop");
Serial.println("Trein 2 noodstop");
digitalWrite(blok1Pin, LOW);
Serial.println("Blok 1: Bezet");
digitalWrite(blok2Pin, LOW);
Serial.println("Blok 2: Bezet");
displ();
lcd.print("Noodstop gemaakt");
// Einde Taak 9 : Noodstop
}
}
}
void move(int motor, int speed, int direction){
//Move specific motor at speed and direction
//motor: 0 for B 1 for A
//speed: 0 is off, and 255 is full speed
//direction: 0 clockwise, 1 counter-clockwise
boolean inPin1 = LOW;
boolean inPin2 = HIGH;
if(direction == 1){
inPin1 = HIGH;
inPin2 = LOW;
}
else{
if(direction == 0)
inPin1 = LOW;
inPin2 = HIGH;
}
if(motor == 1){
digitalWrite(AIN1, inPin1);
digitalWrite(AIN2, inPin2);
analogWrite(PWMA, speed);
}
else{
digitalWrite(BIN1, inPin1);
digitalWrite(BIN2, inPin2);
analogWrite(PWMB, speed);
}
}
void noodstop(){
//Motor A en B stoppen
move(1, 0, 0);// motor A stop
move(0, 0, 0);// motor B stop
}
void displ(){
lcd.home (); // go home
lcd.setCursor(1,1);
}
void schakeltijd(){
delay(tijd);
}
void menu(){
Serial.println();
Serial.println("Stuur comando's");
Serial.println();
Serial.println("1 = Blok 1 vrijgeven 5 = Blok 2 vrijgeven");
Serial.println("2 = Blok 1 bezet melden 6 = Blok 2 bezet melden");
Serial.println("3 = Motor A starten 7 = Motor B starten");
Serial.println("4 = Motor A stoppen 8 = Motor B stoppen");
Serial.println("< = Motor linksom > = Motor rechtsom");
Serial.println();
Serial.println("9 = Motoren A en B stoppen en blok 1 en 2 bezet melden");
Serial.println();
}
void prompt(){
Serial.println();
Serial.println("Volgende comando >");
Serial.println();
}
/* Arduino analoge modelbaan sturing.
Auteur : Paul Smits
Versie 4.6 (is nog in testfase)
Nieuwe functie sturing(trein,snelheid,richting)
Vervangt de functie move(motor,speed,direction)
Zijn feitelijk dezelfde functie alleen omgezet naar de modelbaansturing.
Het in stappen optrekken en afremmen is er uit gehaald.
De trein trekt nu langzaam op of remt nu langzaam af zonder stappen.
Deze software is vrij aanpasbaar en kan door iedereen gebruikt worden,
voor zijn eigen modelbaan of eigen project.
LET OP !:Het gebruik van het programma geschied op eigen risico.
*/
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h> // library voor 12c lcd display
/***** Global vars ***********************************************/
// Define I2C Address where the PCF8574A is
#define BACKLIGHT_PIN 3
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7); // adressering lcd display
char incomingByte;
/******************************************************************************
* Definitions
******************************************************************************
*motor A is aangesloten op OUT1 en OUT2 van de motorsturing
*motor B is aangesloten op OUT3 en OUT4 van de motorsturing
******************************************************************************/
// constants won't change. Used here to
// set pin numbers:
const int ledPin = 13; // Pin nummer LedPin
const int blok1Pin = 6; // Pin nummer Blok 1
const int blok2Pin = 7; // Pin nummer Blok 2
int Interval = 500;
// Variables will change:
//Motor A
int PWMA = 3; //Speed control
int AIN1 = 9; //Direction
int AIN2 = 8; //Direction
//Motor B
int PWMB = 5; //Speed control
int BIN1 = 11; //Direction
int BIN2 = 12; //Direction
int ledState = LOW; // ledState used to set the LED
long previousMillis = 0; // will store last time LED was updated
// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
void setup(){
lcd.begin (16,2);
// Switch on the backlight
lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
lcd.setBacklight(HIGH);
lcd.home (); // go home
// Print a message to the LCD.
lcd.setCursor(2,0); //Start at character 2 on line 0
lcd.print("Arduino Uno");
lcd.setCursor(1,1);
lcd.print("L298 M-Sturing");
Serial.begin(9600);
Serial.println("Arduino test programma : Motorsturingen en blok meldingen");
menu();
// Set all the pins we need to output pins
// pinMode(STBY, OUTPUT);
pinMode(PWMA, OUTPUT);
pinMode(AIN1, OUTPUT);
pinMode(AIN2, OUTPUT);
pinMode(PWMB, OUTPUT);
pinMode(BIN1, OUTPUT);
pinMode(BIN2, OUTPUT);
pinMode(2, OUTPUT);
pinMode(4, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(10, OUTPUT);
pinMode(ledPin, OUTPUT);
}
void loop (){
// Controlle led om te zien of het programma nog werkt.
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > Interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
if (Serial.available()) {
//read serial as a character
//char ser = Serial.read();
if (Serial.available() > 0) { // kijk of de seriele verbinding beschikbaar is.
incomingByte = Serial.read(); // Lees een 'byte'.
}
// Begin Taak 1: Blok1 vrij
if(incomingByte == '1') {
lcd.home ();
lcd.setCursor(0,1);
lcd.print("Blok 1: Vrijgave");
Serial.println("Blok 1 : Vrij");
digitalWrite(blok2Pin, HIGH);
menu();
}
// Einde Taak 1: Blok1 vrij
// Begin Taak 2: Blok 1 bezet
if(incomingByte == '2') {
lcd.home ();
lcd.setCursor(1,1);
lcd.print("Blok 1: Bezet ");
Serial.println("Blok 1: Bezet");
digitalWrite(blok2Pin, LOW);
menu();
}
// Einde Taak 2: Blok 1 Bezet
// Begin Taak 3: Motor B aan
if(incomingByte == '3') {
lcd.home ();
lcd.setCursor(0,1);
lcd.print("Trein 1: Rijdt ");
int value;
for(value = 60 ; value <= 250; value++)
{
sturing(1,value,1);
delay(60);
}
Serial.println("Trein 1: Rijdt linksom");
Serial.println("Trein 1: Rijd op maximale snelheid, totdat er een stop commando komt.");
menu();
}
// Einde Taak 3: Motor B on
// Begin Taak 4: Motor B off
if(incomingByte == '4') {
lcd.home ();
lcd.setCursor(0,1);
lcd.print("Trein 1: Gestopt");
int value;
for(value = 250 ; value >= 0; value--)
{
sturing(1, value, 1);
delay(30);
}
Serial.println("Trein 1: Linksom, is gestopt");
Serial.println("Trein 1: Staat stil omdat er een stop commando gegeven is.");
menu();
}
// Einde Taak 4: Motor B off
// Begin Taak 5 : Blok 2 On
if(incomingByte =='5'){
lcd.home ();
lcd.setCursor(0,1);
lcd.print("Blok 2: Vrijgave");
Serial.println("Blok 2: Vrij");
digitalWrite(blok1Pin, HIGH);
menu();
}
// Einde Taak 5 : Blok On
// Begin Taak 6: Blok 2 Off
if(incomingByte == '6') {
lcd.home ();
lcd.setCursor(0,1);
lcd.print("Blok 2: Bezet ");
Serial.println("Blok 2: Bezet");
digitalWrite(blok1Pin, LOW);
menu();
}
// Einde Taak 6: Blok 2 bezet
// Begin Taak 7: Motor A On
if(incomingByte == '7') {
int value;
for(value = 60 ; value <= 250; value++)
{
sturing(1,value,0);
delay(60);
}
Serial.println("Trein 1 : Rijdt rechtsom");
Serial.println("Trein 1 : Rijdt op maximale snelheid, totdat er een stop commando komt.");
menu();
}
// Einde Taak 7: Motor A on
// Begin Taak 8: Motor A Off
if(incomingByte == '8') {
int value;
for(value = 250 ; value >= 0; value--)
{
sturing(1, value, 0);
delay(30);
}
Serial.println("Trein 1: Rechtom, gaat stoppen");
Serial.println("Trein 1: Is gestopt omdat er een stop commando gegeven is.");
menu();
}
// Einde Taak 8: Motor B off
// Begin Taak 9 : Noodstop
if(incomingByte == '9') {
lcd.home ();
lcd.setCursor(0,1);
lcd.print("Noodstop trein");
Serial.println("Noodstop :Treinen A+B stop en blok 1+2 bezet");
menu();
sturing(1, 0, 0);// Trein 1 stop
Serial.println("Trein 1 noodstop");
sturing(0, 0, 0);// Trein 2 stop
Serial.println("Trein 2 noodstop");
digitalWrite(blok1Pin, LOW);
Serial.println("Blok 1: Bezet");
digitalWrite(blok2Pin, LOW);
Serial.println("Blok 2: Bezet");
// Einde Taak 9 : Noodstop
}
}
}
void sturing(int trein, int snelheid, int richting){
//Move specific motor at speed and direction
//motor: 0 for B 1 for A
//speed: 0 is off, and 255 is full speed
//direction: 0 clockwise, 1 counter-clockwise
boolean inPin1 = LOW;
boolean inPin2 = HIGH;
if(richting == 1){
inPin1 = HIGH;
inPin2 = LOW;
}
else{
if(richting == 0)
inPin1 = LOW;
inPin2 = HIGH;
}
if(trein == 1){
digitalWrite(AIN1, inPin1);
digitalWrite(AIN2, inPin2);
analogWrite(PWMA, snelheid);
}
else{
digitalWrite(BIN1, inPin1);
digitalWrite(BIN2, inPin2);
analogWrite(PWMB, snelheid);
}
}
void menu(){
Serial.println();
Serial.println("Stuur comando's");
Serial.println();
Serial.println("1 = Blok 1 vrijgeven 5 = Blok 2 vrijgeven");
Serial.println("2 = Blok 1 bezet melden 6 = Blok 2 bezet melden");
Serial.println("3 = Trein linksom starten 7 = Trein rechtsom starten");
Serial.println("4 = Trein linksom stoppen 8 = Trein rechtsom stoppen");
Serial.println("9 = Trein noodstop");
Serial.println();
Serial.println("Volgende comando >");
Serial.println();
}
if (ledState == LOW)dit kan een stuk eenvoudiger.. het kan ook zo:
ledState = HIGH;
else
ledState = LOW;
ledState!=ledState;
Ik heb het niet op met de Arduino pro mini( ik heb daar nog geen ervaring mee, wel de specificaties bekeken), er zit daar geen usb aansluiting op zodat ik hem iedere keer uit de print moet verwijderen om het programma evt. te updaten, wil ik de pro mini gebruiken voor de sturing met de computer / of smartphone ,zal ik daar een bluetooth seriele verbinding bij moet maken, en het lukt helaas niet om met bluetooth een programma te downloaden naar de pro mini.
De delay(30) had ik er in gezet voor test doeleinden.Maar het doet nu wel iets belangrijks, het rampen van de snelheid. Ik denk dat je het het makkelijkste op kunt lossen door twee speed functies te maken. Laten we zeggen speedSet(int motor, int speed) waarmee je de snelheid voor een spoor instelt (direction kan je achterwegen laten, achteruit is dan gewoon een negatieve waarde, vooruit max = 255, achteruit max = -255). En speedCheck(), een functie die je in de loop opneemt en die checkt wat de huidige snelheid is, wat de set snelheid is en of het tijd is om de snelheid te verhogen/verlagen (van beide motoren).
De terminal bediening heb ik nodig om er mee te kunnen werken.Snap ik, maar probeer alleen korte data heen en weer te sturen. Zou hou je veel ruimte en tijd in de Arduino over. Op dit moment staat de Arduino zich nog stierlijk te vervelen maar dat zal anders zijn als je het programma uitbreid.
Ik ben inderdaad nog bezig met het programma, ik heb geen Windows meer op de computer staan, ik heb tegenwoordig linux op de computer staan.
Er zal wel nog meer worden aangepast maar dat komt wel, voor nu werk het goed.Leuk begin :) Ik zou alleen de baud rate opvoeren. De Arduino doet de UART toch met hardware en dan is de data alleen maar sneller bij de PC. 115200 baud zou geen probleem moeten zijn. Ook zou je als extra check parity aan kunnen zetten om foute overdrachten af te vangen. Je krijgt dan Serial.begin(115200, SERIAL_8E1) voor 115200 baud met even parity en 1 stop bit.
Waar zijn pin 2, 4, 6, 7 en 10 voor?Pin 6 en 7 zijn gebruikt voor de blokken (blok 1 en 2).
Je hebt het over het rampen, zou niet weten wat het is.Ik bedoel hier het Engelse woord ramp, een helling. Dus in dit geval het opvoeren of afnemen van de snelheid (optrek en afremvertraging). Hiervoor wil je geen delay functie voor gebruiken, of dit nu 10us, 30us of variabel is. Sterker nog, je wil zelden de delay gebruiken. Je blokkeert hiermee het hele programma. In de tijd dat je in de delay zit kun je nergens op reageren. Lees het stuk op Arduino nog maar eens door, Blink without delay (http://arduino.cc/en/Tutorial/BlinkWithoutDelay).
Nog even een antwoord op je vraag :Pin 6 en 7 zijn gebruikt voor de blokken (blok 1 en 2).Okay, duidelijk. Blokken met relais aansturen is prima. Geef ze alleen een duidelijke naam in je code als je er mee gaat werken. ;)
Pin 2, 4, 10 zijn nu nog niet in gebruik maar worden voor nieuw te maken blokken gebruikt.
van de ASCII zal ik waarschijnlijk niet afstappenIs ook niet nodig, gaf alleen wat mogelijkheden aan. Ondanks dat het wel mogelijk is zou ik niet hele boeken uitwisselen tussen de PC en de Arduino. Dit kost erg veel ruimte en maakt je programma erg traag.
ook met het Arduino-IDE de kan ik de snelheid niet hoger zettenOnder Windows wel eens gehad dat hij onder Windows (bij apparaatbeheer) de COM poort maar op een lagere snelheid stond. Hoe dit onder Linux zit weet ik even niet uit mee hoofd. Misschien al wel duidelijk, maar je moet zowel in de COM als in het programma (of dit nu je zelf geschreven programma is of een terminal) de juiste snelheid (en parity) instellen.
//i2c Master Code(UNO)
#include <Wire.h>
void setup()
{
Wire.begin();
delay(2000);
}
void loop()
{
Wire.beginTransmission(5);
Wire.write('H');
digitalWrite(8,HIGH);
Wire.endTransmission();
delay(3000);
Wire.beginTransmission(5);
Wire.write('L');
digitalWrite(8,LOW);
Wire.endTransmission();
delay(3000);
}
//i2c Slave Code(UNO 2)
#include <Wire.h>
void setup()
{
Wire.begin(5);
Wire.onReceive(receiveEvent);
pinMode(8,OUTPUT);
digitalWrite(8,LOW);
}
void loop()
{
}
void receiveEvent(int howMany)
{
while(Wire.available())
{
char c = Wire.read();
if(c == 'H')
{
digitalWrite(8,HIGH);
}
else if(c == 'L')
{
digitalWrite(8,LOW);
}
}
}
/* Seinsturing test programma.
*/
int sein1 = 9;
int sein2 = 10;
void setup(){
pinMode(sein1,OUTPUT);
pinMode(sein2,OUTPUT);
Serial.begin(9600);
Serial.println("Arduino analoge modelbaan sturing : Sein beelden");
}
void loop(){
digitalWrite(sein1, LOW);
digitalWrite(sein2, HIGH);
Serial.println("Blok2 vrij -> Blok1 bezet");
delay(2000);
digitalWrite(sein1, HIGH);
digitalWrite(sein2, LOW);
Serial.println("Blok1 vrij -> Blok2 bezet");
delay(2000);
}
ULN2803 uitgangen parallel schakelen klinkt leuk, maar de Common pen kan maar 1.5A totaal voeren.Ik heb net weer erg me best gedaan en de datasheet doorgekeken maar kan dit niet vinden. Kan je me er op wijzen? Enige wat ik kan vinden is dat de chip in totaal 2,25W mag verstoken. Dit beperkt het wel aangezien je (per poort) een Vce hebt van 1,75V bij 500mA. Dit krijg je al bijna niet weg per poort. Maar dat is wel bijna de volle last en continue! Ik denk dat het voeding technisch ook erg verstandig is wissels na elkaar te schakelen. Op die manier hoeft de voeding niet idioot hoog, ga je niet over de power dissipation en ga je ook niet over de 1,5A. Alleen maar voordelen dus 8)
Ik zit aan twee protocollen te denken I2C of RS485 beide protocollen hebben voordelen.Dit zijn absoluut geen protocollen! Het zijn bussen. Het protocol moet jij verzinnen.
....En denk (nooit open gemaakt, dus weet het echt niet zeker) dat een Digikeijs decoder ook wel eens ervan gebruik maakt. Per wissel twee transistoren tikt al wel snel aan anders....
... En ik zie dat je een 100ohm weerstand voor de ledjes hebt, dit vind ik echt heel weinig. Je knalt dan zo'n 30mA door het ledje!...
Nog even een vraagje je schreef dat je libraries voor de Arduino kon schrijven, hoe doe je dat ::)
Om het Arduino programma wat overzichtelijk te houden wil ik graag het onderstaand stukje programma in libraries zetten, of werk dat niet ?
Er zullen wel meer "const int" en andere variablen er bij gezet worden als ik verder ben met dit project.Code: [Selecteer]const int Stijd = 10 * 1000; // Stoptijd stopblok
const int Wtijd = 10 * 1000; // Wachttijd wachtblok
//const int Noodstop = 1; // Noodstop actief hoog
//const int Sda = 20; // I2C bus serial data
// const int Scl = 21; // I2C bus serial clock
// initialisatie noodstop
const int LED = 52; // Stoppen Arduino Mega modelspoor sturing.
const int LED1 = 53; // Vrijgave Arduino Mega modelspoor sturing.
const int LEDN = 50; // Noodstop geactiveerd
const int LEDV = 51; // Noodstop Opgeheven
// initialisatie poorten blokken
const int Blok1 = 22; // Inkomende spoor
const int Blok2 = 23; // Uitgaande spoor
const int Blok3 = 24; // Schaduwstation spoor 1
const int Blok4 = 44; // Schaduwstation spoor 2
const int Blok5 = 26; // Stationspoor spoor 1
const int Blok6 = 27; // Stationspoor spoor 2
const int Blok7 = 28; // Wachtspoor
const int Blok8 = 29; // Goederenspoor
const int Blok9 = 5; // Wisselblok 1
const int Blok10 = 6; // Wisselblok 2
// initialisatie poorten voor wissel sturing
const int Wis1 = 30; // wissel 1
const int Wis2 = 31; // wissel 2
const int Wis3 = 32; // wissel 3
const int Wis4 = 33; // wissel 4
const int Wis5 = 34; // wissel 5
const int Wis6 = 35; // wissel 6
const int Wis7 = 36; // wissel 7
const int Wis8 = 37; // wissel 8
const int Wis9 = 38; // wissel 9
const int Wis10 = 39; // wissel 10
const int Wis11 = 40; // wissel 11
const int Wis12 = 41; // wissel 12
Zijn er programma's waarmee je libraries kunt schrijven. ::)
const byte turnouts[] = {30, 31, 32, 33, 34, enz };
void setTurnout(byte turnout, byte state){
digitalWrite(turnouts[turnout], state);
}
Onderste is dan genoeg om elke wissel te zetten. Wel beetje eenvoudig gemaakt, doe nu net even of AAN en UIT een richting vormen voor een wissel. Komt omdat je maar één poort per wissel definieert...En dan nog over je printjes op zich, ja ze gaan werken. Maar de layout is wel heel ruim opgezet, zonde van alle vrij ruimte. Ook heb je een dubbelzijdig ontwerp gemaakt. Ik snap dat het geen moer uitmaakt als je ze laat maken in China maar zoiets simpels krijg je denk ik ook nog wel op een zijde. Zou de print ook makkelijk zelf etsbaar maken.
Port nr Functie 0 TX 1 RX 2 Blok 1 3 Blok 2 4 Sein kleur Rood 5 Sein kleur Groen 6 Wissel Rechtdoor 7 Wissel Afbuigend 8 Vrij 9 Vrij 10 ------------------------------ 11 Rij richting en snelheid 12 ------------------------------- 13 Controle of het programma nog loopt |
Het is mij ook niet helemaal duidelijk hoe ik een libray met een klasse moet maken, heb je misschien een klein voorbeeld voor mij, om het wat begrijpelijker te maken. ::)
Klasse "elektrisch apparaat"
* void zetAan()
* void zetUit()
* int leesVerbruik()
Klasse "elektrisch apparaat met temperatuurinstelling": afgeleid van klasse "elektrisch apparaat"
* void stelTemperatuurIn( int temperatuur )
* int leesTemperatuur
Klasse "wasmachine": afgeleid van klasse "elektrisch apparaat met temperatuurinstelling"
* void stelAantalToerenIn( int aantalToeren )
* int leesAantalToeren()
Klasse "koelkast": afgeleid van klasse "elektrisch apparaat met temperatuurinstelling"
* void ontdooi()
Ik denk dat je het verhaal een beetje verkeerd hebt begrepen, het is absoluut niet de bedoeling om een nieuw digitaal systeem te ontwerpen, het is de bedoeling dat ik de Arduino ga gebruiken, om een Arduino blok gestuurde modelbaan te maken, die ik met de computer kan bedienen.
Al mijn locomotieven zijn analoog (ongeveer 30 stuks),
Dinamo is mij veel te duur, als ik zie wat het de treinenclub heeft gekost om de clubbaan om te bouwen naar Dinamo en de clubbaan is nog niet rij vaardig, laat dan maar.
Ik heb wat gesurft om het een en het ander uit te zoeken over verschillende mosfet 's , er zijn mij twee types opgevallen die mij geschikt lijken (IRF 720 en IRF 820) de max stroom continu van de IRF 720 is 3.3 A en van de IRF 820 2.5 A, deze mosfet's lijken mij geschikt voor mijn wissels.Ik kan je vertellen, dat wordt aardig krap. Op het eerste gezicht lijken ze aardig geschikt maar kijk je beter kom je er achter dat het niet zo is. Laten we beginnen met de IRF720, deze heeft een Ron van 1,8ohm. Bij 1A stookt de transistor al 1,8W, bij 2A is dat al 7,2A! Omdat je de transistor niet continue aan hebt is dit niet zo'n probleem maar toch zonde. En een continue last schakelen met dezelfde print gaat alleen lukken met flinke koellichamen. Bij de IRF820 is de Ron alleen maar erger met 3,0ohm.
Ik heb deze printjes juist ruimer gemaakt, dat maak het solderen van de printjes een stuk makkelijker, ook als er een onderdeel kapot gaat is het makkelijk te vervangen.Haha, klopt. Kleiner is nu eenmaal goedkoper! En dat vervangen is een beetje ruimte wel handig maar jij hebt zeeën! En voor vervangen is het vooral van belang dat je ruime gaten maakt. Een gat waar een component precies in past soldeert het makkelijkste maar desoldeert het lastigst, hoe veel ruimte je er ook omheen hebt.
Het lijkt tegenwoordig mode te zijn om de printen zo compact mogelijk te ontwerpen. ???
Ik ga thuis niet zitten kliederen met chemische stoffen om printjes te maken, de printjes in China laten maken is een stuk goedkoper( ik hoef geen aparte kamer met exotische apparaten, lichtbak, etsbak, spoelbak enz., te kopen) en een stuk schoner. ;DTja, ik doe het zelf ook niet. Voor complexe printen is het het niet waard en je krijgt mooi soldermask en silkscreen enz. Maar voor simpele printjes als deze zou ik het nog wel eens willen gaan doen. (maar dan met een laserprinter, niet een lichtbak). Alleen nog niet van gekomen.
Sorry, maar ik begrijp de code niet helemaalSchaam!!! :-[ :-[ :-[ Er miste een belangrijk stuk in de code. Het had moeten zijn
const byte turnouts[] = {30, 31, 32, 33, 34, enz };
void setTurnout(byte turnout, byte state){
digitalWrite(turnouts[turnout], state);
}
Is het nu logischer?Het is mij ook niet helemaal duidelijk hoe ik een libray met een klasse moet maken, heb je misschien een klein voorbeeld voor mij, om het wat begrijpelijker te maken. ::)Yep, dat gaf ik aan het einde van de vorige post: Writing a Library for Arduino (http://arduino.cc/en/Hacking/LibraryTutorial)
Ik maak soms gebruik van bestaande code en pas die aan aan mijn eigen eisen, op deze manier heb ik de basisopzet van de modelbaan sturing ontworpen.Helemaal niet mis mee :) Maar een vuistregel bij code is, als je heel vaak hetzelfde aan het typen bent doe je iets fout en is er een makkelijkere manier 8)
alleen wissels worden wat lastiger, daar zou een aparte Arduino voor nodig zijn.Hoe bedoel je dit?
Wat wil ik per blok sturen allereerst de rijrichting en snelheid, blok vrij/bezet melding, blokseinen, wissel (max 2 wissels parallel), verlichting (extra), ga uitzoeken of dat mogelijk is om met 1 Arduino te sturen.Doet een Arduino met twee vingers in zijn neus ;D
voor de kleinere blokken ga ik een Arduino Nano met shield gebruikenDenk, als je toch aan de slag gaat met printen maken, dat het mooiste is als je gewoon een print maakt. En waarom gebruik je hier een Nano en voor de RGB wel een mini?
De rgb driver is een onafhankelijk systeem en word niet gekoppeld aan de Arduino blok sturing.Waarom? Voor hetzelfde geld hang je deze ook aan het netwerk en laat je de PC deze ook aansturen. Knopje wordt dag, knopje wordt nacht, klaar. Eventueel later uitgebreid met één (of meer) Arduino('s) voor straatverlichting enz.
De communicatie tussen de Arduino's is een andere uitdaging om te ontwerpen, er zijn namelijk meerdere opties, I2C -bus, RS485 -bus, de rx/tx -bus functie op de Arduino.I2C voor korte afstanden en als je ze onder de baan wil spreiden zou ik voor RS485 gaan. Je zou zelfs de "Arduino aan de computer" kunnen schrappen (want echt, wat zal zijn taak zijn?) en de PC gewoon direct aan de RS485 bus hangen.
De indeling van de Arduino, zoals ik in gedachte heb.Een blok moet makkelijk passen dus. Ga je toch elk blok voorzien van een motordriver?
/*
Arduino analoge modelbaan stuuring.
Auteur : Paul Smits
Versie 1.0 (is nog in testfase)
Nieuwe functie sturing(trein,snelheid,richting)
Vervangt de functie move(motor,speed,direction)
Zijn feitelijk dezelfde funcie alleen omgezet naar de modelbaansturing.
Het in stappen optrekken en afremmen is er uit gehaald.
De trein trekt nu langzaam op of remt nu langzaam af zonder stappen.
Deze software is vrij aanpasbaar en kan door iedereen gebruikt worden,
voor zijn eigen modelbaan of eigen project.
LET OP !:Het gebruik van het programma geschied op eigen risico.
*/
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h> // library voor 12c lcd display
/***** Global vars ***********************************************/
// Define I2C Address where the PCF8574A is
#define BACKLIGHT_PIN 3
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7); // adressering lcd display
char incomingByte;
/******************************************************************************
* Definitions
******************************************************************************
*motor A is aangesloten op OUT1 en OUT2 van de motorsturing
*motor B is aangesloten op OUT3 en OUT4 van de motorsturing
******************************************************************************/
// Set pin numbers als constanten, deze waardes zullen niet veranderen.
const int seinR1 = 2; // sein 1 Rood = stop blok 1
const int seinG1 = 3; // sein 1 Groen = vrijgave blok 1
const int seinG2 = 5; // sein 2 Rood = stop blok 2
const int seinR2 = 4; // sein 2 Groen = vrijgave blok 2
const int wisselR = 6; // Wissel stand Rechtdoor
const int wisselA = 7; // Wissel stand Afbuigend
const int AIN1 = 8; // Richting Rechtom
const int AIN2 = 9; // Richting Linksom
const int PWMA = 10; // Snelheids regeling trein
const int blok1 = 11; // Blok 1
const int blok2 = 12; // Blok 2
const int ledPin = 13; // Controlle of het programma nog loopt.
// Analoge porten toewijzen.
const int ldrBlok1 = A0; // Detectie Blok1
const int ldrBlok1s = A1; // Detectie Blok1 sectie 1
const int ldrBlok2 = A2; // Detectie Blok 2
const int ldrBlok2s = A3; // Detectie Blok 2 sectie 1
int ledState = LOW;
int seinR1State = LOW;
int seinG1State = HIGH;
int seinR2State = LOW;
int seinG2State = HIGH;
int blok1State = HIGH;
int blok2State = HIGH;
int wisselRState = HIGH;
int wisselAState = HIGH;
int Interval = 500; // Tijd vertraging van 0.5 seconden
// Drempelwaarde van de LDR-sensors moeten induvueel ingesteld worden.
int Drempelwaarde = 300;
int Drempelwaarde1 = 150;
int Drempelwaarde2 = 300;
int Drempelwaarde3 = 150;
long previousMillis = 0;
void setup()
{
pinMode(seinR1,OUTPUT);
pinMode(seinG1,OUTPUT);
pinMode(seinR2,OUTPUT);
pinMode(seinG2,OUTPUT);
pinMode(blok1,OUTPUT);
pinMode(blok2,OUTPUT);
pinMode(wisselR,OUTPUT);
pinMode(wisselA,OUTPUT);
pinMode(PWMA,OUTPUT);
pinMode(AIN1,OUTPUT);
pinMode(AIN2,OUTPUT);
pinMode(ledPin,OUTPUT);
// Beginstand porten defineren
digitalWrite(seinR1,HIGH);
digitalWrite(seinG2,HIGH);
digitalWrite(seinG1,LOW);
digitalWrite(seinR2,LOW);
digitalWrite(wisselR,HIGH);
digitalWrite(wisselA,HIGH);
digitalWrite(blok1,HIGH);
digitalWrite(blok2,HIGH);
lcd.begin (16,2);
// Zet de backlight aan.
lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
lcd.setBacklight(HIGH);
lcd.home (); // go home
// Print a message to the LCD.
lcd.setCursor(2,0); //Start at character 2 on line 0
lcd.print("Arduino Nano");
lcd.setCursor(1,1);
lcd.print("AAMS V1.0");
Serial.begin(9600);
Wire.begin();
Serial.println("Arduino Nano test programma : Motorsturing, bloksturing, seinsturing");
}
void loop()
{
// Controlle led om te zien of het programma nog werkt.
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > Interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
ledState = !ledState;
// set the LED with the ledState of the variable:
digitalWrite(ledPin,ledState);
}
if (Serial.available() > 0) { // kijk of de seriele verbinding beschikbaar is.
incomingByte = Serial.read(); // Lees een 'byte'.
}
if(incomingByte == '1') {
Wire.beginTransmission(5);
Wire.write('H');
Wire.endTransmission();
int ldrBlok1Waarde = analogRead(ldrBlok1);
int ldrBlok1sWaarde = analogRead(ldrBlok1s);
int ldrBlok2Waarde = analogRead(ldrBlok2);
int ldrBlok2sWaarde = analogRead(ldrBlok2s);
digitalWrite(blok2, LOW);
Serial.println("Blok 2 : Vrij");
if (ldrBlok1Waarde < Drempelwaarde){
digitalWrite(seinR1,LOW);
digitalWrite(seinG1,HIGH);
digitalWrite(seinR2,HIGH);
digitalWrite(seinG2,LOW);
sturing(1,150,1);
}
if (ldrBlok2Waarde < Drempelwaarde){
digitalWrite(seinR1,HIGH);
digitalWrite(seinG1,LOW);
digitalWrite(seinR2,LOW);
digitalWrite(seinG2,HIGH);
sturing(1,125,1);
}
}
if(incomingByte == '2') {
int ldrBlok1Waarde = analogRead(ldrBlok1);
int ldrBlok1sWaarde = analogRead(ldrBlok1s);
int ldrBlok2Waarde = analogRead(ldrBlok2);
int ldrBlok2sWaarde = analogRead(ldrBlok2s);
digitalWrite(blok2, LOW);
if (ldrBlok1Waarde < Drempelwaarde){
blok(1,1);
sturing(1,150,1);
}
if (ldrBlok2Waarde < Drempelwaarde){
blok(0,1);
sturing(1,125,1);
}
}
if(incomingByte == '0') {
Wire.beginTransmission(5);
Wire.write('L');
Wire.endTransmission();
sturing(1,0,1);
digitalWrite(blok2, HIGH);
digitalWrite(seinR1,LOW);
digitalWrite(seinG1,HIGH);
digitalWrite(seinR2,HIGH);
digitalWrite(seinG2,LOW);
}
} // einde loop
void sturing(int trein, int snelheid, int richting){
// Zet de parameters van de functie sturing(trein, snelheid, richting)
// Trein 1: linksom en Trein 2 output B op het motorshield
// Snelheid: 0 is stop, 255 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(trein == 1){
digitalWrite(AIN1, inPin1);
digitalWrite(AIN2, inPin2);
analogWrite(PWMA, snelheid);
}
//else{
//digitalWrite(BIN1, inPin1);
//digitalWrite(BIN2, inPin2);
// analogWrite(PWMB, snelheid);
// }
}
void blok(int sein, int blokState){
boolean sPin1 = LOW;
boolean sPin2 = HIGH;
boolean bPin1 = LOW;
boolean bPin2 = HIGH;
if (sein == 1){
digitalWrite(seinR1,sPin1);
digitalWrite(seinG1,sPin2);
digitalWrite(seinR2,sPin2);
digitalWrite(seinG2,sPin1);
}
//else{
//digitalWrite(seinR1,sPin2);
//digitalWrite(seinG1,sPin1);
//digitalWrite(seinR2,sPin2);
//digitalWrite(seinG2,sPin1);
//}
if (sein == 0){
digitalWrite(seinR1,sPin2);
digitalWrite(seinG1,sPin1);
digitalWrite(seinR2,sPin2);
digitalWrite(seinG2,sPin1);
}
//else{
//digitalWrite(seinR1,sPin1);
//digitalWrite(seinG1,sPin2);
//digitalWrite(seinR2,sPin2);
//digitalWrite(seinG2,sPin1);
// }
if (blokState == 1){
digitalWrite(blok1,bPin2);
digitalWrite(blok2,bPin1);
Serial.println("Blok 1: vrij --> Blok 2 bezet");
}
//else {
//digitalWrite(blok1,bPin1);
//digitalWrite(blok2,bPin2);
// Serial.println("Blok 1: bezet --> Blok 2: vrij");
//}
if (blokState == 0){
digitalWrite(blok1,bPin1);
digitalWrite(blok2,bPin2);
Serial.println("Blok 1: bezet --> Blok 2: vrij");
}
//else {
//digitalWrite(blok1,bPin1);
//digitalWrite(blok2,bPin2);
// Serial.println("Blok 1: bezet --> Blok 2: vrij");
//}
}
const int DitIsDusEenConst;
int ditIsGeenConst;
Dit zodat je aan de naam kunt zien of je hem nu kunt beschrijven of niet. unsigned long currentMillis = millis();
if(currentMillis - previousMillis > Interval) {
Het wegschrijven van millis() naar een var is hier overigens een beetje nutteloos. Je kan gewoon if(millis() - previousMillis > Interval) {
Huidige millis() wegschrijven is alleen nuttig als je op meerdere intervals gaat controleren en je zeker wilt zijn dat het check moment voor alle intervallen gelijk is./*
AamBlok.h v1 - Library to iets
Created by Timo Engelgeer (Septillion), February 2, 2015
*/
#ifndef AamBlok_h
#define AamBlok_h
#include "Arduino.h"
#define AAM_GROEN 1
#define AAM_ROOD 0
class AamBlok{
public:
AamBlok(byte pinBlok, byte pinSein, byte pinLdr, byte pinLdrS, int ldrDrempel);
void bezet();
void vrij();
void sein(byte state);
bool checkBezet();
bool isBezet();
void checkStop();
void update();
protected:
bool bezetState;
byte pinBlok;
byte pinSein;
byte pinLdr;
byte pinLdrS;
int drempel;
};
#endif
/*
AamBlok.h v1 - Library to iets
Created by Timo Engelgeer (Septillion), February 2, 2015
*/
/*
Blaa, dit doet iets :p
*/
#include "Arduino.h"
#include "AamBlok.h"
AamBlok::AamBlok(byte pinBlok, byte pinSein, byte pinLdr, byte pinLdrS, int ldrDrempel){
this->pinBlok = pinBlok;
this->pinSein = pinSein;
this->pinLdr = pinLdr;
this->pinLdrS = pinLdrS;
this->drempel = drempel;
pinMode(this->pinBlok, OUTPUT);
pinMode(this->pinSein, OUTPUT);
pinMode(this->pinLdr, INPUT);
pinMode(this->pinLdrS, INPUT);
digitalWrite(this->pinBlok, HIGH);
digitalWrite(this->pinSein, HIGH);
}
//maak blok bezet
void AamBlok::bezet(){
this->bezetState = true;
}
//maak blok vrij
void AamBlok::vrij(){
this->bezetState = false;
}
//zet sein op rood of groen.
void AamBlok::sein(byte state){
digitalWrite(pinSein, state);
}
//Check of LDR een trein ziet en pas bezet aan. return bezet.
bool AamBlok::checkBezet(){
if(analogRead(this->pinLdr) < this->drempel){
this->bezetState = true;
}
else{
this->bezetState = false;
}
return this->bezetState;
}
//return is blok is bezet
bool AamBlok::isBezet(){
return this->bezetState;
}
void AamBlok::checkStop(){
if(analogRead(this->pinLdrS) < this->drempel && digitalRead(this->pinSein) == AAM_ROOD){
digitalWrite(this->pinBlok, LOW);
}
}
void AamBlok::update(){
this->checkBezet();
this->checkStop();
}
#include <AamBlok.h>
//AamBlok(pinBlok, pinSein, pinLdr, pinLdrS, drempelwaarde)
AamBlok blok1 = AamBlok(0, 1, A0, A1, 300);
AamBlok blok2 = AamBlok(2, 3, A2, A3, 300);
void setup(){
}
void loop(){
blok1.sein(AAM_ROOD);
}
#include <AamBlok.h>
//AamBlok(pinBlok, pinSein, pinLdr, pinLdrS, drempelwaarde)
AamBlok blokken[] = {AamBlok(0, 1, A0, A1, 300), AamBlok(2, 3, A2, A3, 300)};
#define NR_BLOKKEN sizeof(blokken)/sizeof(blokken[0]) //Geeft aantal blokken
void setup(){
}
void loop(){
blokken[1].sein(AAM_ROOD); //Zet sein tweede blok op rood
blokken[0].sein(!blokken[1].isBezet()); //Maakt sein van 1e blok rood als 2e blok bezet is.
//alle blokken langs lopen
for(byte i = 0; i < NR_BLOKKEN; i++){
blokken[i].update();
}
}
Zoals je ziet kan je dan makkelijk iets bij alle blokken doen zonder dat je deze dus zelf allemaal moet nalopen. Of je er nu 2 of 5 hebt ;D Library is nog erg basic maar denk dat het op zich goed uit te breiden is :)/* IR blok bezet melder voor de AAMS sturing
Dit is de eerste versie van deze sturing,
moet nog in het AAMS programma worden gebouwd.
*/
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h> // library voor 12c lcd display
#define BACKLIGHT_PIN 3
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7); // adressering lcd display
const int IRblok1 = A0;
const int IRblok2 = A1;
const int rood = 4;
const int geel = 3;
const int groen = 2;
int drempelWaarde1 = 750;
int drempelWaarde2 = 500;
int drempelWaarde3 = 250;
void setup(){
lcd.begin (20,4);
lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
lcd.setBacklight(HIGH);
lcd.home (); // go home
// Print a message to the LCD.
lcd.setCursor(3,0); //Start at character 2 on line 0
lcd.print("Arduino UNO R3");
lcd.setCursor(6,1);
lcd.print("AAMS V1.0");
pinMode(rood,OUTPUT);
pinMode(geel,OUTPUT);
pinMode(groen,OUTPUT);
Serial.begin(9600);
}
void loop(){
int irblok1Waarde = analogRead(IRblok1);
if (irblok1Waarde < drempelWaarde1){
digitalWrite(groen,LOW);
}
else {
digitalWrite(groen,HIGH);
}
if (irblok1Waarde < drempelWaarde2){
digitalWrite(geel,LOW);
}
else {
digitalWrite(geel,HIGH);
}
if (irblok1Waarde < drempelWaarde3){
digitalWrite(rood,LOW);
}
else {
digitalWrite(rood,HIGH);
}
Serial.print(irblok1Waarde);
lcd.setCursor(3,2);
lcd.print(irblok1Waarde);
}
Hoewel er in de schema's niet een directe verbinding getekend is, is deze gnd er wel in het schema aangegeven als +5v GND deze gaan naar de Arduino
de sturing voor de wissels wil ik galvanische gescheiden houden van de Arduino, de snelheids regeling van de motorschield is wel via de GND gekoppeld met de Arduino.Okay, dan moet je dus nog een ander schema hiervoor maken. Met de huidige MOSFET / BJT schakelingen is dit niet het geval. Maar waarom wil je dit?
/*
HMC pendelautomaat met een Arduino
Haagse Modelbouw Club 2014
Aangepast door Paul Smits
oginele versie door Alfred Hol
*/
// Keuze in- en uitgangen Arduino
int pwmA = 10;
int aIn1 = 9;
int aIn2 = 8;
int irSensor1 = 2; //digital in pin waarop Sensor1 wordt aangesloten
int irSensor2 = 3; //digital in pin waarop Sensor2 wordt aangesloten
//digitale pin waarop Sensor2 wordt aangesloten
// Beginwaarden rijrichting en snelheid
int pwmAval = 0;
int progStep = 1;
int waitTime = 10000; // wachttijd op eindpunten in milliseconden
int ASCSPD = 30; // versnellingscurve (totale tijd van versnellen in milliseconden is waarde ASCSPD x 256)
int DSCSPD = 20; // vertragingscurve (totale tijd van vertragen in milliseconden is waarde DSCSPD x 256)
void setup() {
// Instellen in- en uitgangen Arduino
pinMode(pwmA, OUTPUT);
pinMode(aIn1, OUTPUT);
pinMode(aIn2, OUTPUT);
pinMode(irSensor1, INPUT);
pinMode(irSensor2, INPUT);
//analogWrite(pwmA, pwmAval);
// open seriele poort tbv logging
Serial.begin(9600);
Serial.println("Start log:");
Serial.println("Pendelautomaat voor de Arduino");
Serial.println("Haagse Modelbouw Club 2014");
Serial.println(" ");
}
void loop() {
//na het dooorlopen van alle acht programmastappen weer beginnen bij stap 1
if (progStep == 9) {
progStep = 1;
} //na het dooorlopen van alle acht programmastappen weer beginnen bij stap 1
//uitlezen sensoren
Serial.print("wacht op sensor ");
Serial.print("1 ");
Serial.println(digitalRead(irSensor1));
Serial.print("2 ");
Serial.println(digitalRead(irSensor2));
if (progStep == 2) {
if (digitalRead(irSensor2) == 1) {
progStep = 3;
};
};
if (progStep == 6) {
if (digitalRead(irSensor1) == 1) {
progStep = 7;
};
};
// naar specieke actie die hoort bij programmastatus
while (progStep == 1) {
versnellen();
}
while (progStep == 3) {
vertragen();
}
while (progStep == 4) {
wachtenompolen();
}
while (progStep == 5) {
versnellen();
}
while (progStep == 7) {
vertragen();
}
while (progStep == 8) {
wachtenompolen();
}
}
void versnellen () {
Serial.print("Programmastap ");
Serial.println(progStep);
Serial.print(" accelereren in ");
Serial.print(255*ASCSPD/1000);
Serial.println( " seconden");
for(int pwmAval=60; pwmAval <= 255; pwmAval++){
analogWrite(pwmA,pwmAval);
delay(ASCSPD);
Serial.println(pwmAval);
}
Serial.println(" maximale snelheid bereikt ");
Serial.println("");
progStep =progStep+ 1;
Serial.print("Programmastap ");
Serial.println(progStep);
Serial.print(" wacht op input op sensor ");
if (progStep == 2) {
Serial.println("2");
};
if (progStep == 6) {
Serial.println("1");
};
Serial.println("");
}
void vertragen () {
Serial.print("Programmastap ");
Serial.println(progStep);
Serial.print(" afremmen in ");
Serial.print(255*DSCSPD/1000);
Serial.println( " seconden");
for (int pwmAval=255; pwmAval > 0; pwmAval--){
analogWrite(pwmA,pwmAval);
delay(DSCSPD);
Serial.println(pwmAval);
}
Serial.println(" trein staat stil ");
Serial.println("");
progStep =progStep+ 1;
}
void wachtenompolen (){
Serial.print("Programmastap ");
Serial.println(progStep);
Serial.print(" Wachttijd tot ompolen: ");
Serial.print((waitTime)/1000);
Serial.println(" seconden");
delay(waitTime);
if (progStep == 4) {
//digitalWrite(aIn1, HIGH);
//digitalWrite(aIn2, LOW);
sturing(1,0,1);
};
if (progStep == 8) {
//digitalWrite(aIn1, LOW);
//digitalWrite(aIn2, HIGH);
sturing(1,0,0);
};
Serial.println(" Ompolen ");
Serial.println("");
progStep =progStep+ 1;
}
void sturing(int trein, int snelheid, int richting){
// Zet de parameters van de functie sturing(trein, snelheid, richting)
// Trein 1: linksom en Trein 2 output B op het motorshield
// Snelheid: 0 is stop, 255 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(trein == 1){
digitalWrite(aIn1, inPin1);
digitalWrite(aIn2, inPin2);
analogWrite(pwmA, snelheid);
}
/* else{
digitalWrite(BIN1, inPin1);
digitalWrite(BIN2, inPin2);
analogWrite(PWMB, snelheid);
}*/
}
Het ontwerp wat je er bij heb gemaakt werkt helaas niet
Diodes kunnen prima gebruikt worden voor de keerlus
/*
Aams.h v1 - Library voor Arduino Analoge Modelbaan Sturing
Met dank aan Timo Engelgeer (Septillion) voor de eerste opzet
*/
/*
Blaa, dit doet iets :p
*/
#include "Arduino.h"
#include "Aams.h"
Aams::Aams(byte pinBlok, byte pinSein, byte pinLdr, byte pinLdrS, int ldrDrempel){
this->pinBlok = pinBlok;
this->pinSein = pinSein;
this->pinLdr = pinLdr;
this->pinLdrS = pinLdrS;
this->drempel = drempel;
pinMode(this->pinBlok, OUTPUT);
pinMode(this->pinSein, OUTPUT);
pinMode(this->pinLdr, INPUT);
pinMode(this->pinLdrS, INPUT);
digitalWrite(this->pinBlok, HIGH);
digitalWrite(this->pinSein, HIGH);
}
Sturing::Sturing(byte pinPWMA, byte pinAin1, byte pinAin2, byte pinPWMB, byte pinBin1, byte pinBin2){
this-> pinPWMA = pinPWMA; // Arduino pin 5~
this-> pinAin1 = pinAin1; // Arduino pin 6
this-> pinAin2 = pinAin2; // Arduino pin 7
this-> pinPWMB = pinPWMB; // Arduino pin 9~
this-> pinBin1 = pinBin1; // Arduino pin 10
this-> pinBin2 = pinBin2; // Arduino pin 11
pinMode(this->pinPWMA, OUTPUT);
pinMode(this->pinAin1, OUTPUT);
pinMode(this->pinAin2, OUTPUT);
pinMode(this->pinPWMB, OUTPUT);
pinMode(this->pinBin1, OUTPUT);
pinMode(this->pinBin2, OUTPUT);
}
void Sturing::Sturing(byte Trein, byte Snelheid, byte Richting){
// Zet de parameters van de functie sturing(trein, snelheid, richting)
// Trein 1: linksom en Trein 2 output B op het motorshield
// Snelheid: 0 is stop, 255 is maximale snelheid
// Richting: 0 Rechtsom, 1 Linksom
bool inPin1 = LOW;
bool inPin2 = HIGH;
if(Richting == 1){
inPin1 = HIGH;
inPin2 = LOW;
}
else{
if(Richting == 0)
inPin1 = LOW;
inPin2 = HIGH;
}
if(Trein == 1){
digitalWrite(AIN1, inPin1);
digitalWrite(AIN2, inPin2);
analogWrite(PWMA, snelheid);
}
else{
digitalWrite(BIN1, inPin1);
digitalWrite(BIN2, inPin2);
analogWrite(PWMB, snelheid);
}
}
//maak blok bezet
void Aams::bezet(){
this->bezetState = true;
}
//maak blok vrij
void Aams::vrij(){
this->bezetState = false;
}
//zet sein op rood of groen.
void Aams::sein(byte state){
digitalWrite(pinSein, state);
}
//Check of LDR een trein ziet en pas bezet aan. return bezet.
bool Aams::checkBezet(){
if(analogRead(this->pinLdr) < this->drempel){
this->bezetState = true;
}
else{
this->bezetState = false;
}
return this->bezetState;
}
//return is blok is bezet
bool Aams::isBezet(){
return this->bezetState;
}
void Aams::checkStop(){
if(analogRead(this->pinLdrS) < this->drempel && digitalRead(this->pinSein) == AAM_ROOD){
digitalWrite(this->pinBlok, LOW);
}
}
void Aams::update(){
this->checkBezet();
this->checkStop();
}
/*
Aams.h v1 - Library to iets
Created by Timo Engelgeer (Septillion), February 2, 2015
*/
#ifndef Aams_h
#define Aams_h
#include "Arduino.h"
#define AAM_GROEN 1
#define AAM_ROOD 0
class Aams {
public:
Aams(byte pinBlok, byte pinSein, byte pinLdr, byte pinLdrS, int ldrDrempel);
void bezet();
void vrij();
void sein(byte state);
bool checkBezet();
bool isBezet();
void checkStop();
void update();
protected:
bool bezetState;
byte pinBlok;
byte pinSein;
byte pinLdr;
byte pinLdrS;
int drempel;
};
class Sturing {
public:
Sturing(byte pinPWMA, byte pinAin1, byte pinAin2, byte pinPWMB, byte pinBin1, byte pinBin2);
void Trein(byte);
void Richting(byte);
void Snelheid(byte);
protected:
bool inPin1;
bool inPin2;
byte pinPWMA;
byte pinAin1;
byte pinAin2;
byte pinPWMB;
byte pinBin1;
byte pinBin2;
};
#endif
else{
if(Richting == 0)
inPin1 = LOW;
inPin2 = HIGH;
}
heb je een paar accolades vergeten. Of beter, de accolade achter de else zou achter de if moeten.Het zou wel handig zijn om de foutmeldingen erbij te vermelden.nu bij deze mag je wel wat duidelijker zijn.
Los daarvan, hierCode: [Selecteer]else{
heb je een paar accolades vergeten. Of beter, de accolade achter de else zou achter de if moeten.
if(Richting == 0)
inPin1 = LOW;
inPin2 = HIGH;
}
- Peter
/*
Aams.h v1 - Library to iets
Created by Timo Engelgeer (Septillion), February 2, 2015
*/
#ifndef Aams_h
#define Aams_h
#include "Arduino.h"
#define AAM_GROEN 1
#define AAM_ROOD 0
class Aams {
public:
Aams(byte pinBlok, byte pinSein, byte pinLdr, byte pinLdrS, int ldrDrempel);
void bezet();
void vrij();
void sein(byte state);
bool checkBezet();
bool isBezet();
void checkStop();
void update();
protected:
bool bezetState;
byte pinBlok;
byte pinSein;
byte pinLdr;
byte pinLdrS;
int drempel;
};
class Sturing {
public:
Sturing(byte pinPwmA, byte pinAin1, byte pinAin2, byte pinPwmB, byte pinBin1, byte pinBin2);
void Start(int Trein, int Snelheid, int Richting);
int Value = 0;
protected:
bool inPin1;
bool inPin2;
byte pinPwmA;
byte pinAin1;
byte pinAin2;
byte pinPwmB;
byte pinBin1;
byte pinBin2;
};
#endif
/*
Aams.h v1 - Library voor Arduino Analoge Modelbaan Sturing
Met dank aan Timo Engelgeer (Septillion) voor de eerste opzet
*/
/*
Blaa, dit doet iets :p
*/
#include "Arduino.h"
#include "Aams.h"
Aams::Aams(byte pinBlok, byte pinSein, byte pinLdr, byte pinLdrS, int ldrDrempel){
this->pinBlok = pinBlok;
this->pinSein = pinSein;
this->pinLdr = pinLdr;
this->pinLdrS = pinLdrS;
this->drempel = drempel;
pinMode(this->pinBlok, OUTPUT);
pinMode(this->pinSein, OUTPUT);
pinMode(this->pinLdr, INPUT);
pinMode(this->pinLdrS, INPUT);
digitalWrite(this->pinBlok, HIGH);
digitalWrite(this->pinSein, HIGH);
}
Sturing::Sturing(byte pinPWMA, byte pinAin1, byte pinAin2, byte pinPWMB, byte pinBin1, byte pinBin2){
this-> pinPwmA = pinPwmA; // Arduino pin 5~
this-> pinAin1 = pinAin1; // Arduino pin 6
this-> pinAin2 = pinAin2; // Arduino pin 7
this-> pinPwmB = pinPwmB; // Arduino pin 9~
this-> pinBin1 = pinBin1; // Arduino pin 10
this-> pinBin2 = pinBin2; // Arduino pin 11
pinMode(this->pinPwmA, OUTPUT);
pinMode(this->pinAin1, OUTPUT);
pinMode(this->pinAin2, OUTPUT);
pinMode(this->pinPwmB, OUTPUT);
pinMode(this->pinBin1, OUTPUT);
pinMode(this->pinBin2, OUTPUT);
}
void Sturing::Start(int Trein, int Snelheid, int Richting){
// Zet de parameters van de functie sturing(trein, snelheid, richting)
// Trein 1: linksom en Trein 2 output B op het motorshield
// Snelheid: 0 is stop, 255 is maximale snelheid
// Richting: 0 Rechtsom, 1 Linksom
Value = Snelheid;
bool inPin1 = LOW;
bool inPin2 = HIGH;
if(Richting == 1){
inPin1 = HIGH;
inPin2 = LOW;
}
else{
if(Richting == 0)
inPin1 = LOW;
inPin2 = HIGH;
}
if(Trein == 1){
digitalWrite(Ain1, inPin1);
digitalWrite(Ain2, inPin2);
analogWrite(PwmA, Snelheid);
}
else{
digitalWrite(Bin1, inPin1);
digitalWrite(Bin2, inPin2);
analogWrite(PwmB, Snelheid);
}
}
//maak blok bezet
void Aams::bezet(){
this->bezetState = true;
}
//maak blok vrij
void Aams::vrij(){
this->bezetState = false;
}
//zet sein op rood of groen.
void Aams::sein(byte state){
digitalWrite(pinSein, state);
}
//Check of LDR een trein ziet en pas bezet aan. return bezet.
bool Aams::checkBezet(){
if(analogRead(this->pinLdr) < this->drempel){
this->bezetState = true;
}
else{
this->bezetState = false;
}
return this->bezetState;
}
//return is blok is bezet
bool Aams::isBezet(){
return this->bezetState;
}
void Aams::checkStop(){
if(analogRead(this->pinLdrS) < this->drempel && digitalRead(this->pinSein) == AAM_ROOD){
digitalWrite(this->pinBlok, LOW);
}
}
void Aams::update(){
this->checkBezet();
this->checkStop();
}
#include <Start.h>
Start sturing (2, 3, 4, 5, 6, 7, 10, 11);
void setup(){
Serial.begin(9600);
Serial.println("Arduino Analoge Modelbaan sturing, test programma");
}
void loop(){
// Wissel( nummer, stand) stand = 0 = Rechtdoor 1 = Afbuigend
sturing.wissel(1,0);
delay(100);
sturing.wissel(1,1);
int value;
for(int value = 0; value <= 250; value++){
// Trein (uitgang, richting, snelheid) uitgang 0 = poort A, 1 = poort B, richting 0 = linksom, 1 = rechtsom
sturing.trein(1,1,value);
delay(20);
Serial.print(value);
}
for(int value = 250; value >= 0; value--){
// Trein (uitgang, richting, snelheid) uitgang 0 = poort A, 1 = poort B, richting 0 = linksom, 1 = rechtsom
sturing.trein(1,0,value);
delay(20);
}
}
/*
Start.h v1 - Library voor Arduino Analoge Modelbaan Sturing of kortweg AAMS.
Writen by Paul Smits
*/
/*
Blaa, dit doet iets :p
*/
#ifndef Start_h
#define Start_h
#include "Arduino.h"
class Start {
public:
Start(byte pinPwmA, byte pinAin1, byte pinAin2, byte pinPwmB, byte pinBin1, byte pinBin2, byte pinWisR, byte pinWisA);
void trein(byte uitgang, byte richting, int snelheid);
void wissel(int nummer, byte stand);
int value;
private:
bool inPin1;
bool inPin2;
byte pinPwmA;
byte pinAin1;
byte pinAin2;
byte pinPwmB;
byte pinBin1;
byte pinBin2;
byte pinWisR;
byte pinWisA;
int inPinwisL;
int inPinwisH;
};
#endif
/*
Start.cpp v1 - Library voor Arduino Analoge Modelbaan Sturing of kortweg AAMS.
Writen by Paul Smits
*/
/*
Blaa, dit doet iets :p
*/
#include "Start.h"
Start::Start(byte pinPwmA, byte pinAin1, byte pinAin2, byte pinPwmB, byte pinBin1, byte pinBin2, byte pinWisR, byte pinWisA){
this-> pinPwmA = pinPwmA; // Arduino pin 3~
this-> pinAin1 = pinAin1; // Arduino pin 2
this-> pinAin2 = pinAin2; // Arduino pin 4
this-> pinPwmB = pinPwmB; // Arduino pin 6~
this-> pinBin1 = pinBin1; // Arduino pin 5
this-> pinBin2 = pinBin2; // Arduino pin 7
this-> pinWisR = pinWisR; // Arduino pin 11
this-> pinWisA = pinWisA; // Arduino pin 12
pinMode(this-> pinPwmA, OUTPUT);
pinMode(this-> pinAin1, OUTPUT);
pinMode(this-> pinAin2, OUTPUT);
pinMode(this-> pinPwmB, OUTPUT);
pinMode(this-> pinBin1, OUTPUT);
pinMode(this-> pinBin2, OUTPUT);
pinMode(this-> pinWisR, OUTPUT);
pinMode(this-> pinWisA, OUTPUT);
}
void Start::trein(byte uitgang, byte richting, int snelheid)
{
bool inPin1 = LOW;
bool inPin2 = HIGH;
if(richting == 0){
inPin1 = HIGH;
inPin2 = LOW;
}
else if(richting == 1){
inPin1 = LOW;
inPin2 = HIGH;
}
if(uitgang == 0){
digitalWrite(this-> pinAin1, inPin1);
digitalWrite(this-> pinAin2, inPin2);
analogWrite(this-> pinPwmA, snelheid);
}
else if(uitgang == 1){
digitalWrite(this-> pinBin1, inPin1);
digitalWrite(this-> pinBin2, inPin2);
analogWrite(this-> pinPwmB, snelheid);
}
}
void Start::wissel(int nummer, byte stand)
{
if(nummer ==0){
nummer = 1;
}
else if (nummer == 1){
nummer =0;
}
if(stand == 0){
digitalWrite(this-> pinWisR,inPinwisH);
delay(5000);
digitalWrite(this-> pinWisR,inPinwisL);
}
if(stand ==1){
digitalWrite(this-> pinWisA,inPinwisH);
delay(500);
digitalWrite(this-> pinWisA,inPinwisL);
}
}
Debugen vond ik toch even te veel van het goede, de library files zijn goed met compileren van het programma kreeg ik geen foutmeldingen, het bleek dat ik twee integers in de verkeerde file stonden.
Na lang zoeken en veel testen heb ik mijn eigen library goed werkend gekregen, het doet precies wat ik in gedachte had.
Ik kan nu de sturing gaan testen en uitbreiden naar meer functies in de library.
Ik heb nu twee functies, sturing.trein en sturing.wissel er moet nog een functie sturing.blok, sturing.keerlus, sturing.stroomdetectie, sturing.rgb (dag nacht simulatie) en sturing.verlichting., bijkomen.
schrijfBit( 16, 1 );
schrijfBit( 17, 1 );
schrijfBit( 18, 1 );
schrijfBit( 19, 1 );
void zetWissel( int nummer )
{
schrijfBit( 15 + nummer, 1 );
}
int i;
for( i = 1; i <= 4; i++ )
zetWissel( i );
/*
AamsTrein.h v1 - Library voor Arduino Analoge Modelbaan Sturing of kortweg AAMS.
Writen by Paul Smits
*/
/*
Deze library stuurt de motordriver L298 voor de Arduino Analoge Modelbaan sturing.
*/
#ifndef AamsTrein_h
#define AamsTrein_h
#include "Arduino.h"
class AamsTrein {
public:
AamsTrein(byte pinPwmA, byte pinAin1, byte pinAin2, byte pinPwmB, byte pinBin1, byte pinBin2);
int value;
void start(byte train, byte direction);
void stop(byte train);
void vertrek(byte train, byte direction);
void remmen(byte train, byte direction);
void noodstop(byte train, int speed);
void richting(byte direction);
void snelheid(byte speed);
void on(byte train);
private:
bool inPin1;
bool inPin2;
byte pinPwmA;
byte pinAin1;
byte pinAin2;
byte pinPwmB;
byte pinBin1;
byte pinBin2;
};
#endif
/*
AamsTrein.cpp v1 - Library voor Arduino Analoge Modelbaan Sturing of kortweg AAMS.
Writen by Paul Smits
/*
Deze library is, voor het sturen van de verschillende treinen.
*/
#include "AamsTrein.h"
AamsTrein::AamsTrein(byte pinPwmA, byte pinAin1, byte pinAin2, byte pinPwmB, byte pinBin1, byte pinBin2){
this-> pinPwmA = pinPwmA; // Arduino pin 3~
this-> pinAin1 = pinAin1; // Arduino pin 2
this-> pinAin2 = pinAin2; // Arduino pin 4
this-> pinPwmB = pinPwmB; // Arduino pin 6~
this-> pinBin1 = pinBin1; // Arduino pin 5
this-> pinBin2 = pinBin2; // Arduino pin 7
pinMode(this-> pinPwmA, OUTPUT);
pinMode(this-> pinAin1, OUTPUT);
pinMode(this-> pinAin2, OUTPUT);
pinMode(this-> pinPwmB, OUTPUT);
pinMode(this-> pinBin1, OUTPUT);
pinMode(this-> pinBin2, OUTPUT);
}
void AamsTrein::start(byte train, byte direction)
{
bool inPin1 = LOW;
bool inPin2 = HIGH;
if(train == 0)
{
digitalWrite(this-> pinAin1, inPin1);
digitalWrite(this-> pinAin2, inPin2);
analogWrite(this-> pinPwmA, 120);
}
if(train == 1)
{
digitalWrite(this-> pinBin1, inPin1);
digitalWrite(this-> pinBin2, inPin2);
analogWrite(this-> pinPwmB, 120);
}
if(direction == 0)
{
inPin1 = HIGH;
inPin2 = LOW;
}
if(direction == 1)
{
inPin1 = LOW;
inPin2 = HIGH;
}
}
void AamsTrein::stop(byte train)
{
if(train == 0)
{
analogWrite(this-> pinPwmA, 0);
}
if(train == 1)
{
analogWrite(this-> pinPwmB, 0);
}
}
void AamsTrein::vertrek(byte train, byte direction)
{
bool inPin1 = LOW;
bool inPin2 = HIGH;
int value;
if(direction == 0)
{
inPin1 = HIGH;
inPin2 = LOW;
}
if(direction == 1)
{
inPin1 = LOW;
inPin2 = HIGH;
}
if(train == 0)
{
digitalWrite(this-> pinAin1, inPin1);
digitalWrite(this-> pinAin2, inPin2);
for(value = 60 ; value <= 250; value++)
{
analogWrite(this-> pinPwmA, value);
}
}
if(train == 1)
{
digitalWrite(this-> pinBin1, inPin1);
digitalWrite(this-> pinBin2, inPin2);
for(value = 60 ; value <= 250; value++)
{
analogWrite(this-> pinPwmB, value);
}
}
}
void AamsTrein::remmen(byte train, byte direction)
{
bool inPin1 = LOW;
bool inPin2 = HIGH;
int value;
if(direction == 0)
{
inPin1 = HIGH;
inPin2 = LOW;
}
if(direction == 1)
{
inPin1 = LOW;
inPin2 = HIGH;
}
if(train == 0)
{
digitalWrite(this-> pinAin1, inPin1);
digitalWrite(this-> pinAin2, inPin2);
for(value = 250 ; value >= 50; value--)
{
analogWrite(this-> pinPwmA, value);
}
}
if(train == 1)
{
digitalWrite(this-> pinBin1, inPin1);
digitalWrite(this-> pinBin2, inPin2);
for(value = 250 ; value >= 50; value--)
{
analogWrite(this-> pinPwmB, value);
}
}
}
void AamsTrein::snelheid(byte speed)
{
//Er word nog aan functie snelheid gewerkt! (deze functie is bedoeld voor Handbediening)
}
void AamsTrein::richting(byte direction)
{
// Er word nog aan functie richting gewerkt! (deze functie is bedoeld voor Handbediening)
}
void AamsTrein::on(byte train)
{
// Er word nog aan functie on gewerkt! (deze functie is bedoeld voor Handbediening)
}
void AamsTrein::noodstop(byte train, int speed)
{
// Er word nog aan functie noodstop gewerkt! (deze functie is bedoeld voor Handbediening)
}
if(train == 0){
int value;
for(value = 0 ; value <= 250; value++){
digitalWrite(this-> pinAin1, inPin1);
digitalWrite(this-> pinAin2, inPin2);
analogWrite(this-> pinPwmA, value);
}
}
Dit is een klein gedeelte van de library code. if(train == 0){
int value;
for(value = 0 ; value <= 250; value++){
digitalWrite(this-> pinAin1, inPin1);
digitalWrite(this-> pinAin2, inPin2);
analogWrite(this-> pinPwmA, value);
delay(60);
}
}
/*
AamsTrein.cpp v1 - Library voor Arduino Analoge Modelbaan Sturing of kortweg AAMS.
Writen by Paul Smits
/*
Deze library is, voor het sturen van de verschillende treinen.
*/
#include "AamsTrein.h"
AamsTrein::AamsTrein(byte pinPwmA, byte pinAin1, byte pinAin2, byte pinPwmB, byte pinBin1, byte pinBin2){
this-> pinPwmA = pinPwmA; // Arduino pin 3~
this-> pinAin1 = pinAin1; // Arduino pin 2
this-> pinAin2 = pinAin2; // Arduino pin 4
this-> pinPwmB = pinPwmB; // Arduino pin 6~
this-> pinBin1 = pinBin1; // Arduino pin 5
this-> pinBin2 = pinBin2; // Arduino pin 7
pinMode(this-> pinPwmA, OUTPUT);
pinMode(this-> pinAin1, OUTPUT);
pinMode(this-> pinAin2, OUTPUT);
pinMode(this-> pinPwmB, OUTPUT);
pinMode(this-> pinBin1, OUTPUT);
pinMode(this-> pinBin2, OUTPUT);
}
void AamsTrein::start(byte train, byte direction)
{
bool inPin1 = LOW;
bool inPin2 = HIGH;
if(train == 0)
{
digitalWrite(this-> pinAin1, inPin1);
digitalWrite(this-> pinAin2, inPin2);
analogWrite(this-> pinPwmA, 120);
delay(25);
}
else if(train == 1)
{
digitalWrite(this-> pinBin1, inPin1);
digitalWrite(this-> pinBin2, inPin2);
analogWrite(this-> pinPwmB, 120);
delay(25);
}
if(direction == 0)
{
inPin1 = HIGH;
inPin2 = LOW;
}
else if(direction == 1)
{
inPin1 = LOW;
inPin2 = HIGH;
}
}
void AamsTrein::stop(byte train)
{
if(train == 0)
{
analogWrite(this-> pinPwmA, 0);
}
else if(train == 1)
{
analogWrite(this-> pinPwmB, 0);
}
}
void AamsTrein::vertrek(byte train, byte direction)
{
bool inPin1 = LOW;
bool inPin2 = HIGH;
if(direction == 0)
{
inPin1 = HIGH;
inPin2 = LOW;
}
else if(direction == 1)
{
inPin1 = LOW;
inPin2 = HIGH;
}
if(train == 0){
int value;
for(value = 0 ; value <= 250; value++){
digitalWrite(this-> pinAin1, inPin1);
digitalWrite(this-> pinAin2, inPin2);
analogWrite(this-> pinPwmA, value);
delay(60);
}
}
else if(train == 1){
int value;
for(value = 0 ; value <= 250; value++){
digitalWrite(this-> pinBin1, inPin1);
digitalWrite(this-> pinBin2, inPin2);
analogWrite(this-> pinPwmB, value);
delay(60);
}
}
}
void AamsTrein::remmen(byte train, byte direction){
bool inPin1 = LOW;
bool inPin2 = HIGH;
int value;
if(direction == 0)
{
inPin1 = HIGH;
inPin2 = LOW;
}
else if(direction == 1)
{
inPin1 = LOW;
inPin2 = HIGH;
}
if(train == 0){
for(value = 250 ; value >= 0; value--){
digitalWrite(this-> pinAin1, inPin1);
digitalWrite(this-> pinAin2, inPin2);
analogWrite(this-> pinPwmA, value);
delay(25);
}
}
else if(train == 1){
for(value = 250 ; value >= 0; value--){
digitalWrite(this-> pinBin1, inPin1);
digitalWrite(this-> pinBin2, inPin2);
analogWrite(this-> pinPwmB, value);
delay(25);
}
}
}
void AamsTrein::snelheid(byte speed)
{
//Er word nog aan functie snelheid gewerkt! (deze functie is bedoeld voor Handbediening)
}
void AamsTrein::richting(byte direction)
{
// Er word nog aan functie richting gewerkt! (deze functie is bedoeld voor Handbediening)
}
void AamsTrein::on(byte train)
{
// Er word nog aan functie on gewerkt! (deze functie is bedoeld voor Handbediening)
}
void AamsTrein::noodstop(int speed)
{
// Er word nog aan functie noodstop gewerkt!
if (speed == 0){
analogWrite(this-> pinPwmA, 0);
analogWrite(this-> pinPwmB, 0);
}
}
Het gebruik van de functie delay is ten zeerste af te raden. In het voorbeeld (voor het op tellen) werd een delay van 60ms gebruikt in een loop van 250. Dit is 15 seconden. Ik weet dat het een voorbeeld is, maar al breng je het terug naar 1 seconde (per blok), dan is het nog lang.
Als ik het verkeerd denk hoor ik dat graag. ::)Bij deze dan ;D De delay zorgt er (onnodig) voor dat je hele Arduino hangt. In die tijd (die het eigenlijk uit zijn neus staat te vreten) reageert hij nergens meer op. Ook niet meer op bijvoorbeeld een noodstop! Als ik jou was zou ik toch echt de BlonkWithoutDelay eens een keer aan de gang krijgen. Dit is in mijn ogen echt wel een basis begrip dat je onder de knie moet hebben wil je meer gaan doen met de Arduino.
/*
AamsTrein.cpp v2 - Library voor Arduino Analoge Modelbaan Sturing of kortweg AAMS.
Writen by Paul Smits
Edit by Timo Engelgeer ;)
*/
/*
Deze library stuurt de motordriver L298 voor de Arduino Analoge Modelbaan sturing.
*/
#ifndef AamsTrein_h
#define AamsTrein_h
#include "Arduino.h"
class AamsTrein {
public:
AamsTrein(byte pinPwm, byte pinIn1, byte pinIn2);
void snelheid(int speed);
int getSnelheid();
void update();
void setVertraging(unsigned int vertraging);
unsigned int getVertraging();
void noodstop();
void start(byte direction);
void stop();
protected:
void setSnelheid(int speed);
int setSpeed; //Snelheid die we willen gaan rijden
int curSpeed; //Snelheid waarop de PWM werkelijk is ingesteld.
unsigned int vertraging;
unsigned long millisLast;
byte pinPwm;
byte pinIn1;
byte pinIn2;
};
#endif
/*
AamsTrein.cpp v2 - Library voor Arduino Analoge Modelbaan Sturing of kortweg AAMS.
Writen by Paul Smits
Edit by Timo Engelgeer ;)
/*
Deze library is, voor het sturen van de verschillende treinen.
*/
#include "AamsTrein.h"
AamsTrein::AamsTrein(byte pinPwm, byte pinIn1, byte pinIn2){
//Save the pins to use
this->pinPwm = pinPwm;
this->pinIn1 = pinIn1;
this->pinIn2 = pinIn2;
//Make them output
pinMode(this->pinPwm, OUTPUT);
pinMode(this->pinIn1, OUTPUT);
pinMode(this->pinIn2, OUTPUT);
vertraging = 0; //Standaard geen vertraging
}
void AamsTrein::snelheid(int speed){
//Snelheid begrenzen tot max 255 in beide richtingen
if(speed > 255){
speed = 255;
}
else if(speed < -255){
speed = -255;
}
setSpeed = speed;
if(vertraging == 0){
this->setSnelheid(setSpeed);
}
}
//Geeft de ingestelde snelheid
int AamsTrein::getSnelheid(){
return this->setSpeed;
}
//Protected functie, niet van buiten de classe te benaderen.
//Stelt werkelijk de hardware in op de juiste snelheid
void AamsTrein::setSnelheid(int speed){
if(curSpeed != speed){
curSpeed = speed;
if(speed < 0){
digitalWrite(this->pinIn1, HIGH);
digitalWrite(this->pinIn2, LOW);
analogWrite(this-> pinPwm, -speed);
}
else{
digitalWrite(this->pinIn1, LOW);
digitalWrite(this->pinIn2, HIGH);
analogWrite(this-> pinPwm, speed);
}
}
}
//Checkt of de snelheid aangepast moet worden (optrekken/afremmen) en doet dit
//Aanroepen in de loop
void AamsTrein::update(){
//Kijken of het tijd is om een update te doen
if(millis() - this->millisLast > this->vertraging) {
this->millisLast = millis(); //opslaan dat we nu een update doen
if(setSpeed > curSpeed){ //moeten dus sneller
this->setSnelheid(curSpeed + 1);
}
else if(setSpeed < curSpeed){ //moeten langzamer
this->setSnelheid(curSpeed - 1);
}
}
}
//Stelt de vertraging tussen het aanpassen van de snelheid in (in ms)
void AamsTrein::setVertraging(unsigned int vertraging){
this->vertraging = vertraging;
}
//Geeft de ingestelde vertraging
unsigned int AamsTrein::getVertraging(){
return this->vertraging;
}
//Triggert de noodstop
void AamsTrein::noodstop(){
//Door beide in-pinnen laag te maken en de PWM pin hoog is er een "Fast Motor Stop"
digitalWrite(this->pinIn1, LOW);
digitalWrite(this->pinIn2, LOW);
digitalWrite(this->pinPwm, HIGH);
//En even de snelheden updaten
setSpeed = 0;
curSpeed = 0;
}
// Volgende functies erin gehouden omdat deze er waren
//Gewoon starten met snelheid 120 met mogelijkheid om richting op te geven
//Houdt rekening met de ingestelde vertraging
void AamsTrein::start(byte direction){
if(direction){
this->snelheid(120);
}
else{
this->snelheid(-120);
}
}
//Stop de treinen
//Houdt rekening met ingestelde vertraging
void AamsTrein::stop(){
this->snelheid(0);
}
#include <AamsTrein.h>
#define AANTAL_BLOKKEN 2
AamsTrein treinen[AANTAL_BLOKKEN] = {
{3, 2, 4}, //Eerste motordriver
{6, 5, 7} //Tweede motordriver
};
void setup() {
//Geef de eerste driver een 60ms vertraging tussen iedere snelheidsstap
treinen[0].setVertraging(60);
//Geeft tweede motordriver dezelfde vertraging als de eerste
treinen[1].setVertraging( treinen[0].getVertraging() );
}
void loop() {
//Dit blok moet altijd in je loop staan (=vaak aangeroepen worden)
//om te zorgen dat de blokken de juiste snelheid hebben
//Gebruik GEEN delay in de loop, dit zal de optrek/afrem vertraging in de war schoppen
for (byte i = 0; i < AANTAL_BLOKKEN; i++) {
treinen[i].update();
}
//trek op naar "-200" (achteruit dus)
treinen[0].snelheid(-200);
}
#define AANTAL_BLOKKEN 2is dit een functie binnen de Arduino ide of kan ik het als volgt definiëren
#define AANTAL_TREINEN 2ik hou graag dezelfde definitie van de library aan.
Als ik dat met de ascii code's moet doen ben ik snel door mijn ascii codes heen.Nee hoor. Het hoeft geen uniek ascii karakter te zijn voor elke optie. Je zou iedere trein kunnen aansturen door een bericht als:
int speed;
speed = 0x80; //Plaats linker deel erin
speed <<= 8; //Schuif erin (naar links)
speed &= 0x54; //Voer rest toe
//Zijn maar random voorbeeld getallen/adressen
#define AANTAL_TREINEN 2
#define AANTAL_WISSELS 4
const byte TreinAdres 0;
const byte WisselAdres 8;
void loop() {
if(bytesIn[0] == "T"){ //begint het met een T?
if(bytesIn[1] >= TreinAdres && bytesIn[1] < (TreinAdres + AANTAL_TREINEN){
//Dit adres zit op deze Arduino
//Selecteer juiste trein
//Maak van de twee bytes een int
//Zet snelheid
treinen[bytesIn[1] - TreinAdres].snelheid( byteToInt(bytesIn[2], bytesIn[3]) );
}
}
else if(bytesIn[0] == "w" || bytesIn[0] == "W"){ //begint het met een w of W?
if(bytesIn[1] >= WisselAdres && bytesIn[1] < (WisselAdres + AANTAL_WISSELS){
if(bytesIn[0] == "W"){
wissels[bytesIn[1] - WisselAdres].rechtdoor();
}
else{
wissels[bytesIn[1] - WisselAdres].afbuigen();
}
}
}
}
int byteToInt(byte msb, byte lsb){
int out;
out = 0x80; //Plaats linker deel erin
out <<= 8; //Schuif erin (naar links)
out &= 0x54; //Voer rest toe
return out;
}
Geen 100% code, maar bytesIn is wat de module op serial of I2C of weet ik wat binnen heeft gekregen.(Sorry, kon het niet laten een voorbeeldje te schrijven. Zeg maar als je het vervelend vindt.)Dat vind ik absoluut niet vervelend, mijn kennis van de de Arduino programmeertaal is nog niet ruim te noemen.
Dat vind ik absoluut niet vervelend, mijn kennis van de de Arduino programmeertaal is nog niet ruim te noemen.Gelukkig ;D Ik blijf het namelijk super leuk vinden om de vorderingen hier te lezen en hoop dat ik dan met de voorbeelden kan bijdragen.
Ik begin er meer inzicht in te krijgen, van de programmeer voorbeelden kan ik veel leren.
//Checkt of de snelheid aangepast moet worden (optrekken/afremmen) en doet dit
//Aanroepen in de loop
void AamsTrein::update(){
//Kijken of het tijd is om een update te doen
if(millis() - this->millisLast > this->vertraging) {
this->millisLast = millis(); //opslaan dat we nu een update doen
if(setSpeed > curSpeed){ //moeten dus sneller
this->curSpeed += 1;
}
else if(setSpeed < curSpeed){ //moeten langzamer
this->curSpeed -= 1;
}
}
//Als er een bup gaande is
if(this->bumpFlag){
//Bump afgelopen, terug naar normaal
if(millis() - this->lastBump > BumpDuration){
this->setSnelheid(); //Zet de snelheid weer op curSpeed
this->bumpFlag = false;
}
}
//Er is geen bump gaande
else{
//Check of snelheid laag genoeg is dat er een bump (software PWM) nodig is tegen kleef
//en tijd is voor nieuwe bump
if(abs(this->curSpeed) < this->MaxBumpSpeed && this->curSpeed != 0 && (millis() - this->lastBump) > BumpInterval){
this->lastBump = millis();
this->setSnelheid((this->curSpeed < 0 ? -255 : 255)); //Zet snelheid op 255, zelfde richting als curSpeed
this->bumpFlag = true;
}
else{
this->setSnelheid();
}
}
}
De SX-bus wordt Alleen gebruikt voor de processor(80C48C) in de Functie decoder, er is geen koppeling met de outputs 3 tm 14 met de SX-bus, dit loop via een eigen voeding (1 en 2).
/*
* 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 3
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7); // adressering lcd display
char 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 LedPin
const int blok1Pin = 8; // Pin nummer Blok 1
const int blok2Pin = 12; // Pin nummer Blok 2
const int sein1rPin = 4; // sein 2 Rood
const int sein1gPin = 5; // sein 2 Groen
const int sein2rPin = 2; // sein 1 rood
const int sein2gPin = 3; // sein 1 Groen
const int wissel1rPin = 6; // Wissel 1 Rechtdoor
const int wissel1aPin = 7; // Wissel 1 Afbuigend
int Interval = 500; // Tijdvertraging ter controlle of het programma nog loopt.
//Trein 1
int PWMA = 9; // Snelheids regeling trein 1
int AIN1 = 10; // Rechtsom trein 1
int AIN2 = 11; // Linksom trein 1
int 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.Nu je een display aan de module hangt is dat wel wat lastiger. Of krijgt niet elke module een display? Staat me iets van bij dat je graag had dat je één Adruino tussen PC en rest wilde die ook als interface zou dienen. Dan kan het wel makkelijk. Maar dan zou ik nu al beginnen met de boel op te splitsen. Hoe meer je er nu bij maakt hoe lastiger...
3.: Wissel sturing voor zware belasting (schaduw station meerdere wissels tegelijk sturen)Gelijk ook terug komende op je foto's, hoe stuur je nu de wissels? Via de relais? En zie ik dat goed, schakel je de relais gelijk door de Arduino? Zo ja, welke relais zijn het? (Zoveel vermogen kan de Arduino niet leveren op een pin.) En ik lijk geen back EMF diodes te zien...
4.: Bluetooth communicatie tussen pc en sturingMag ik vragen waarom je dit zou willen?
5. Barebone Arduinio, geen programma's uploaden wel communicatie tussen Arduino en pc.Wat bedoel je met barebone? Als je bedoelt een losse ATmega chip zou ik zeggen, pak een Arduino Pro Mini. Voor het geld van een Arduino Pro Mini kan ik het zelf aan losse onderdelen echt niet maken. Losse chip kost +-€1,30 en een complete Arduino Pro Mini €1,50...
const byte PinPwmA = 9;
const byte PinAin1 = 10;
const byte PinAin2 = 11;
// Voor elk blok moet een routine schrijven.Mm, als je dat soort dingen op schrijf moet je je gaan bedenken of dat niet makkelijker kan. En dat kan super eenvouding! Gebruik arrays ;D Als je voor alles waar je er meer dan één van hebt een array aan maakt wordt het leven echt een stuk eenvoudiger. Dus SeinPinR[], SeinPinG[] en BlokPin enz. Hele functie (tot oneindig aantal blokken) is dan:
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;
En tada, klaar voor 255 blokken... ;)for (int t = 10; t <= 200; t++) {
delay(40);
locomotief (1, t, cw);
}
Kan je nog van een koude kermis thuis laten komen als je meer dan 1 trein tegelijk wilt laten rijden. Dat kan nu namelijk niet... Met delay reageert de Arduino even nergens op, dus ook niet op een noodstop bijvoorbeeld. Ook kan je geen twee treinen tegelijk laten optrekken enz. Maar goed, misschien staat dit nog op de planning? Is namelijk niet de eerste keer dat ik het je laat weten ;D if (wrichting == 0) {
Serial.println("wissel 1 rechtdoor");
digitalWrite(wissel1rPin, HIGH);
delay(750);
digitalWrite(wissel1rPin, LOW);
Je wil de delay gewoon nooit gebruiken...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 lang
void 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 3
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7); // adressering lcd display
void 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 3
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7); // adressering lcd display
void 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);
}
}
}
als extra kun je er bv wissels mee schakelen, daar wil ik een aparte sturing voor maken.Wat bedoel je daarmee? Wil je losse wisselkaarten maken? Of wil je dat als onderdeel van de blokkaart? Of wil je soms 1 of soms 2 en soms 3 wissels met één blokkaart kunnen schakelen?
De twee seinen heb ik bewust als 4 aparte sturingen uitgevoerd zodat ik de seinen apart kan bedienen of via het blok sturen.Dat is toch prima? Of vat je uit mijn tekst iets anders op?
Wat wel van belang is dat ikzelf de richting van de trein kan kiezen, hiervoor gebruik ik dus de case functie case'<' ,case'>'Dat snap ik. Maar hoe ga je dat dan doen als je straks meerdere blokken hebt? Waarom niet de snelheid als signed getal zien? Dus positief voor vooruit en negatief voor achteruit? Dan kan je snelheid en richting gewoon in één commando geven!
Het is de bedoeling dat ik, voor ik de trein een vertrek comando geeft, ik eerst de richting moet aangeven.
//I2C Master Code(Arduino Nano)
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h> // library voor 12c lcd display
#define BACKLIGHT_PIN 3
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7); // adressering lcd display
const byte SlavePin1 = 2;
const byte SlavePin2 = 3;
const byte SlavePin3 = 4;
const byte SlavePin4 = 5;
const byte MasterSendPin = 6;
const byte MasterRecivePin = 7;
const byte ControllePin = 13;
int Interval = 500; // Tijdvertraging ter controlle of het programma nog loopt.
boolean LedState = LOW;
unsigned long LedMillis = 0; // slaat de laatste stand van de LED op.
char I2CByte; // Slaat een waarde op in I2CByte
void setup()
{
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.
pinMode(SlavePin1, OUTPUT);
pinMode(SlavePin2, OUTPUT);
pinMode(SlavePin3, OUTPUT);
pinMode(SlavePin4, OUTPUT);
pinMode(MasterSendPin, OUTPUT);
pinMode(MasterRecivePin, OUTPUT);
pinMode(ControllePin, OUTPUT);
Serial.begin(9600);
Serial.println("Arduino test programma : I2C communicatie");
lcd.home ();
lcd.setCursor(0, 1);
lcd.println("Arduino Bloksturing");
Wire.begin();
delay(1000);
}
void loop()
{
// Controlle led om te zien of het programma nog werkt.
unsigned long currentMillis = millis();
if (currentMillis - LedMillis > Interval) {
// Sla de laatste stand van de Led waneer die nog knipperde
LedMillis = currentMillis;
// Als de Led uit is zet de Led aan en vice-versa:
if (LedState == LOW)
LedState = HIGH;
else
LedState = LOW;
digitalWrite(ControllePin, LedState); // Afhankelijk van de ledState is de Led aan of uit.
}
if (Serial.available() > 0) { // Kijk of de seriele verbinding beschikbaar is.
int I2CByte = Serial.read(); // Lees een 'byte'.
switch (I2CByte) {
case'A': // Blok 1 Vrij
Wire.beginTransmission(2);
Wire.write('A'); // Stuur een A naar slave 2, Blok1, HIGH
Serial.println("Stuur een A naar de Slave 2");
digitalWrite(MasterSendPin, HIGH);
Wire.endTransmission();
delay(20);
Printmenu();
break;
case'a': // Blok 1 Bezet
Wire.beginTransmission(2);
Wire.write('a'); // Stuur een a naar slave 2, Blok1,LOW
Serial.println("Stuur een a naar de Slave 2");
digitalWrite(MasterSendPin, HIGH);
Wire.endTransmission();
delay(20);
break;
case'B': // Blok 2 Vrij
Wire.beginTransmission(2);
Wire.write('B'); // Stuur een B naar slave 2, Blok2, HIGH
Serial.println("Stuur een B naar de Slave 2");
digitalWrite(MasterSendPin, HIGH);
Wire.endTransmission();
delay(20);
Printmenu();
break;
case'b': // Blok 2 Bezet
Wire.beginTransmission(2);
Wire.write('b'); // Stuur een b naar slave 2, Blok2,LOW
Serial.println("Stuur een b naar de Slave 2");
digitalWrite(MasterSendPin, HIGH);
Wire.endTransmission();
delay(20);
Printmenu();
break;
case'C': // Blok 3 Vrij
Wire.beginTransmission(3);
Wire.write('C'); // Stuur een C naar slave 3, Blok3,HIGH
Serial.println("Stuur een C naar de Slave 3");
digitalWrite(MasterSendPin, HIGH);
Wire.endTransmission();
delay(20);
Printmenu();
break;
case'c': // Blok 3 Bezet
Wire.beginTransmission(3);
Wire.write('c'); // Stuur een c naar slave 3, Blok3,LOW
Serial.println("Stuur een c naar de Slave 3");
digitalWrite(MasterSendPin, HIGH);
Wire.endTransmission();
delay(20);
Printmenu();
break;
case'D': // Blok 4 Vrij
Wire.beginTransmission(3);
Wire.write('D'); // Stuur een D naar slave 3, Blok4,HIGH
Serial.println("Stuur een D naar de Slave 3");
digitalWrite(MasterSendPin, HIGH);
Wire.endTransmission();
delay(20);
Printmenu();
break;
case'd': // Blok 4 Bezet
Wire.beginTransmission(3);
Wire.write('d'); // Stuur een d naar slave 3, Blok4,LOW
Serial.println("Stuur een d naar de Slave 3");
digitalWrite(MasterSendPin, HIGH);
Wire.endTransmission();
delay(20);
Printmenu();
break;
}
}
}
void Printmenu() {
Serial.println();
Serial.println(F("Arduino analoge modelbaan sturing: Motorsturingen en blok meldingen"));
Serial.println();
Serial.println(F("Stuur comando's"));
Serial.println();
Serial.println(F("A = Blok 1 vrijgeven a = Blok 1 bezet melden"));
Serial.println(F("B = Blok 2 vrijgeven b = Blok 2 bezet melden"));
Serial.println(F("C = Blok 3 vrijgeven c = Blok 3 bezet melden"));
Serial.println(F("D = Blok 4 vrijgeven d = Blok 4 bezet melden"));
Serial.println(F("< = Trein linksom > = Trein rechtsom"));
Serial.println(F("1 = Trein 1 starten 0 = Trein 1 stoppen"));
Serial.println(F("| = Wissel 1 rechtdoor / = Wissel 1 Afbuigend"));
Serial.println();
Serial.println(F("9 = Noodstop"));
Serial.println();
}
//i2c Slave Code(NANO slave 2)
#include <Wire.h>
//char I2CByte; // 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 byte LedPin = 13; // Pin nummer LedPin
const byte blok1Pin = 8; // Pin nummer Blok 1
const byte blok2Pin = 12; // Pin nummer Blok 2
const byte sein1rPin = 4; // sein 2 Rood
const byte sein1gPin = 5; // sein 2 Groen
const byte sein2rPin = 2; // sein 1 rood
const byte sein2gPin = 3; // sein 1 Groen
const byte wissel1rPin = 6; // Wissel 1 Rechtdoor
const byte wissel1aPin = 7; // Wissel 1 Afbuigend
int Interval = 500; // Tijdvertraging ter controlle of het programma nog loopt.
//Trein 1
const byte PinPwmA = 9; // Snelheids regeling trein 1
const byte PinAin1 = 10; // Rechtsom trein 1
const byte PinAin2 = 11; // Linksom trein 1
boolean Cw = false; // clockwise
boolean Ccw = false; // counter clockwise
boolean ledState = LOW;
unsigned long ledMillis = 0; // slaat de laatste stand van de LED op.
void setup()
{
Wire.begin(2);
// Stelt de comminicatie met de master in.
Wire.onReceive(receiveBlok1);
Wire.onReceive(receiveBlok2);
Wire.onReceive(receiveWissel1r);
Wire.onReceive(receiveWissel1a);
Wire.onReceive(receiveVooruit);
Wire.onReceive(receiveAchteruit);
Wire.onReceive(receiveOptrekken);
Wire.onReceive(receiveAfremmen);
}
void loop()
{
// Controlle led om te zien of het programma nog werkt.
unsigned long currentMillis = millis();
if (currentMillis - ledMillis > Interval) {
// Sla de laatste stand van de Led waneer die nog knipperde
ledMillis = 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.
}
}
void receiveBlok1(int howMany)
{
while (Wire.available())
{
char I2CByte = Wire.read();
if (I2CByte == 'A')
{
baanvak(1, 0);
}
else if ( I2CByte == 'a')
{
baanvak(1, 1);
}
}
}
void receiveBlok2(int howMany) {
while (Wire.available())
{
char I2CByte = Wire.read();
if (I2CByte == 'B')
{
baanvak(2, 0);
}
else if ( I2CByte == 'b')
{
baanvak(2, 1);
}
}
}
void receiveWissel1r(int howMany) {
}
void receiveWissel1a(int HowMany) {
}
void receiveVooruit(int HowMany) {
}
void receiveAchteruit(int howMany) {
}
void receiveOptrekken(int howMany) {
}
void receiveAfremmen(int howMany) {
}
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(PinAin1, inPin1);
digitalWrite(PinAin2, inPin2);
analogWrite(PinPwmA, 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) {
digitalWrite(wissel1rPin, HIGH);
delay(500);
digitalWrite(wissel1rPin, LOW);
}
if (wnummer == 1) {
}
if (wrichting == 1) {
digitalWrite(wissel1aPin, HIGH);
delay(500);
digitalWrite(wissel1aPin, LOW);
}
}
// I2C Mastercode (NANO)
#include<Wire.h>
void setup()
{
Serial.begin(9600);
//Serial.println("Arduino i2c sturing tussen twee of meer arduino's");
Wire.begin();
//Printmenu();
}
void loop()
{
if (Serial.available());
{
char c = Serial.read();
if (c == 'A')
{
Wire.beginTransmission(5); // Adres eerste slave unit
Wire.write('A');
Wire.endTransmission();
Serial.println("Blok 1 Vrij geven.");
Printmenu();
}
if (c == 'a')
{
Wire.beginTransmission(5);
Wire.write('a');
Wire.endTransmission();
Serial.println("Blok 1 Bezet melden.");
}
if (c == 'B')
{
Wire.beginTransmission(5);
Wire.write('B');
Wire.endTransmission();
Serial.println("Blok 2 Vrij geven.");
}
if (c == 'b')
{
Wire.beginTransmission(5);
Wire.write('b');
Wire.endTransmission();
Serial.println("Blok 2 Bezet melden.");
}
if (c == '|')
{
Wire.beginTransmission(5);
Wire.write('|');
Wire.endTransmission();
Serial.println("Wissel 1 Rechtdoor.");
}
if (c == '/')
{
Wire.beginTransmission(5);
Wire.write('/');
Wire.endTransmission();
Serial.println("Wissel 1 Afbuigend");
}
if (c == 'C')
{
Wire.beginTransmission(6); // Adres tweede slave unit.
Wire.write('C');
Wire.endTransmission();
Serial.println("Blok 3 Vrij geven.");
}
if (c == 'c')
{
Wire.beginTransmission(6);
Wire.write('c');
Wire.endTransmission();
Serial.println("Blok 3 Bezet melden.");
}
if (c == 'D')
{
Wire.beginTransmission(6);
Wire.write('D');
Wire.endTransmission();
Serial.println("Blok 4 Vrij geven.");
}
if (c == 'd')
{
Wire.beginTransmission(6);
Wire.write('d');
Wire.endTransmission();
Serial.println("Blok 4 Bezet melden.");
}
}
}
void Printmenu() {
Serial.println();
Serial.println(F("Arduino analoge modelbaan sturing: Motorsturingen en blok meldingen"));
Serial.println();
Serial.println(F("Stuur comando's"));
Serial.println();
Serial.println(F("A = Blok 1 vrijgeven a = Blok 1 bezet melden"));
Serial.println(F("B = Blok 2 vrijgeven b = Blok 2 bezet melden"));
Serial.println(F("C = Blok 3 vrijgeven c = Blok 3 bezet melden"));
Serial.println(F("D = Blok 4 vrijgeven d = Blok 4 bezet melden"));
Serial.println(F("< = Trein linksom > = Trein rechtsom"));
Serial.println(F("1 = Trein 1 starten 0 = Trein 1 stoppen"));
Serial.println(F("| = Wissel 1 rechtdoor / = Wissel 1 Afbuigend"));
Serial.println();
Serial.println(F("9 = Noodstop"));
Serial.println();
}
// I2C Slave code (NANO)
#include <Wire.h>
void setup()
{
Wire.begin(5);
Wire.onReceive(receiveEvent);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
}
void loop()
{
}
void receiveEvent(int howMany)
{
while (Wire.available())
{
char c = Wire.read();
if (c == 'A')
{
digitalWrite(8, HIGH); // BloK 1 Vrij geven.
}
if (c == 'a')
{
digitalWrite(8, LOW); // Blok 1 Bezet melden.
}
if (c == 'B')
{
digitalWrite(12, HIGH); // Blok 2 Vrij geven.
}
if (c == 'b')
{
digitalWrite(12, LOW); // Blok 2 bezet melden.
}
if (c == '|')
{
// Wissel 1 Rechtdoor.
digitalWrite(6, HIGH);
delay(750); // bekrachtigings- tijd wisselspoel.
digitalWrite(6, LOW);
}
if (c == '/')
{
// Wissel 1 Afbuigend.
digitalWrite(7, HIGH);
delay(750); // bekrachtigings- tijd wisselspoel.
digitalWrite(7, LOW);
}
}
}
Nu je een display aan de module hangt is dat wel wat lastiger. Of krijgt niet elke module een display? Staat me iets van bij dat je graag had dat je één Adruino tussen PC en rest wilde die ook als interface zou dienen. Dan kan het wel makkelijk. Maar dan zou ik nu al beginnen met de boel op te splitsen. Hoe meer je er nu bij maakt hoe lastiger...
Gelijk ook terug komende op je foto's, hoe stuur je nu de wissels? Via de relais? En zie ik dat goed, schakel je de relais gelijk door de Arduino? Zo ja, welke relais zijn het? (Zoveel vermogen kan de Arduino niet leveren op een pin.) En ik lijk geen back EMF diodes te zien...
//I2C Master Code(Arduino Nano)
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h> // library voor 12c lcd display
#define BACKLIGHT_PIN 3
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7); // adressering lcd display
const byte SlavePin1 = 2;
const byte SlavePin2 = 3;
const byte SlavePin3 = 4;
const byte SlavePin4 = 5;
const byte MasterSendPin = 6;
const byte MasterRecivePin = 7;
const byte ControllePin = 13;
char Slave;
char I2CByte; // Slaat een waarde op in I2CByte
void setup()
{
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.
pinMode(SlavePin1, OUTPUT);
pinMode(SlavePin2, OUTPUT);
pinMode(SlavePin3, OUTPUT);
pinMode(SlavePin4, OUTPUT);
pinMode(MasterSendPin, OUTPUT);
pinMode(MasterRecivePin, OUTPUT);
pinMode(ControllePin, OUTPUT);
Serial.begin(9600);
Printmenu();
Wire.begin();
lcd.home ();
lcd.setCursor(0, 1);
lcd.println("Arduino Bloksturing");
}
void loop()
{
Wire.requestFrom(5, 1); // request
//Wire.requestFrom(6, 1);
if (Wire.available()) { // slave may send less than requested
char Slave = Wire.read(); // receive a byte as character
if (Slave == 5)
{
digitalWrite(SlavePin1, HIGH);
digitalWrite(MasterSendPin, HIGH);
}
else
{
digitalWrite(SlavePin1, LOW);
digitalWrite(MasterSendPin, HIGH);
}
//if (Slave == '6')
//{
// digitalWrite(SlavePin2, HIGH);
// digitalWrite(MasterSendPin, HIGH);
//}
//else
//{
//digitalWrite(SlavePin2, LOW);
//digitalWrite(MasterSendPin, HIGH);
//}
}
if (Serial.available()) { // Kijk of de seriele verbinding beschikbaar is.
char I2CByte = Serial.read(); // Lees een 'byte'.
switch (I2CByte) {
case'A': // Blok 1 Vrij
Wire.beginTransmission(5);
Wire.write('A'); // Stuur een A naar slave 2, Blok1, HIGH
Wire.endTransmission();
Serial.println("Blok 1 Vrij");
digitalWrite(MasterSendPin, LOW);
digitalWrite(SlavePin1, LOW);
Printmenu();
break;
case'a': // Blok 1 Bezet
Wire.beginTransmission(5);
Wire.write('a'); // Stuur een a naar slave 2, Blok1,LOW
Wire.endTransmission();
Serial.println("Blok 1 Bezet");
digitalWrite(MasterSendPin, LOW);
digitalWrite(SlavePin1, LOW);
Printmenu();
break;
case'B': // Blok 2 Vrij
Wire.beginTransmission(5);
Wire.write('B'); // Stuur een B naar slave 2, Blok2, HIGH
Wire.endTransmission();
Serial.println("Blok 2 Vrij");
digitalWrite(MasterSendPin, LOW);
digitalWrite(SlavePin1, LOW);
Printmenu();
break;
case'b': // Blok 2 Bezet
Wire.beginTransmission(5);
Wire.write('b'); // Stuur een b naar slave 2, Blok2,LOW
Wire.endTransmission();
Serial.println("Blok 2 Bezet");
digitalWrite(MasterSendPin, LOW);
digitalWrite(SlavePin1, LOW);
Printmenu();
break;
case'C': // Blok 3 Vrij
Wire.beginTransmission(6);
Wire.write('C'); // Stuur een C naar slave 3, Blok3,HIGH
Wire.endTransmission();
Serial.println("Blok 3 Vrij");
digitalWrite(MasterSendPin, LOW);
digitalWrite(SlavePin2, LOW);
Printmenu();
break;
case'c': // Blok 3 Bezet
Wire.beginTransmission(6);
Wire.write('c'); // Stuur een c naar slave 3, Blok3,LOW
Wire.endTransmission();
Serial.println("Blok 3 Bezet");
digitalWrite(MasterSendPin, LOW);
digitalWrite(SlavePin2, LOW);
Printmenu();
break;
case'D': // Blok 4 Vrij
Wire.beginTransmission(6);
Wire.write('D'); // Stuur een D naar slave 3, Blok4,HIGH
Wire.endTransmission();
Serial.println("Blok 4 vrij");
digitalWrite(MasterSendPin, LOW);
digitalWrite(SlavePin2, LOW);
Printmenu();
break;
case'd': // Blok 4 Bezet
Wire.beginTransmission(6);
Wire.write('d'); // Stuur een d naar slave 3, Blok4,LOW
Wire.endTransmission();
Serial.println("Blok 4 Bezet.");
digitalWrite(MasterSendPin, LOW);
digitalWrite(SlavePin2, LOW);
Printmenu();
break;
case'|': // wissel 1 rechtdoor
Wire.beginTransmission(5);
Wire.write('|');
Wire.endTransmission();
Serial.println("Wissel 1 Rechtdoor.");
digitalWrite(MasterSendPin, LOW);
digitalWrite(SlavePin1, LOW);
Printmenu();
break;
case'/': // wissel 1 afbuigend
Wire.beginTransmission(5);
Wire.write('/');
Wire.endTransmission();
Serial.println("Wissel 1 Afbuigend.");
digitalWrite(MasterSendPin, LOW);
digitalWrite(SlavePin1, LOW);
Printmenu();
break;
}
}
}
void Printmenu() {
Serial.println();
Serial.println(F("Arduino analoge modelbaan sturing: Motorsturingen en blok meldingen"));
Serial.println();
Serial.println(F("Stuur comando's"));
Serial.println();
Serial.println(F("A = Blok 1 vrijgeven a = Blok 1 bezet melden"));
Serial.println(F("B = Blok 2 vrijgeven b = Blok 2 bezet melden"));
Serial.println(F("C = Blok 3 vrijgeven c = Blok 3 bezet melden"));
Serial.println(F("D = Blok 4 vrijgeven d = Blok 4 bezet melden"));
Serial.println(F("< = Trein linksom > = Trein rechtsom"));
Serial.println(F("1 = Trein 1 starten 0 = Trein 1 stoppen"));
Serial.println(F("| = Wissel 1 rechtdoor / = Wissel 1 Afbuigend"));
Serial.println();
Serial.println(F("9 = Noodstop"));
Serial.println();
}
// I2C Slave code (NANO)
#include <Wire.h>
char I2CByte;
const byte Blok1Pin = 8; // Blok 1
const byte Blok2Pin = 12; // Blok 2
const byte Sein1rPin = 4; // Sein 1 rood
const byte Sein1gPin = 5; // Sein 1 groen
const byte Sein2rPin = 2; // Sein 2 rood
const byte Sein2gPin = 3; // Sein 2 groen
const byte Wissel1rPin = 6; // Wissel 1 rechtdoor
const byte Wissel1aPin = 7; // Wissel 1 afbuigend
const byte PinPwm = 9; // Snelheids regeling pwm
const byte PinIn1 = 10; // Trein cw
const byte PinIn2 = 11; // Trein ccw
boolean Cw = false;
boolean Ccw = false;
void setup()
{
pinMode(Wissel1rPin, OUTPUT);
pinMode(Wissel1aPin, OUTPUT);
pinMode(Blok1Pin, OUTPUT);
pinMode(Blok2Pin, OUTPUT);
pinMode(Sein1rPin, OUTPUT);
pinMode(Sein1gPin, OUTPUT);
pinMode(Sein2rPin, OUTPUT);
pinMode(Sein2gPin, OUTPUT);
pinMode(PinPwm, OUTPUT);
pinMode(PinIn1, OUTPUT);
pinMode(PinIn2, OUTPUT);
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
Wire.begin(5); // Stelt de communicatie met de master in.
Wire.onReceive(receiveEvent); // Iets ontvangen van de Master.
Wire.onRequest(requestEvent); // Stuur een 5 naar de Master.
}
void loop()
{
}
void receiveEvent(int howMany)
{
while (Wire.available())
{
char I2CByte = Wire.read();
if (I2CByte == 'A')
{
digitalWrite(Blok1Pin, HIGH); // BloK 1 Vrij geven.
}
if (I2CByte == 'a')
{
digitalWrite(Blok1Pin, LOW); // Blok 1 Bezet melden.
}
if (I2CByte == 'B')
{
digitalWrite(Blok2Pin, HIGH); // Blok 2 Vrij geven.
}
if (I2CByte == 'b')
{
digitalWrite(Blok2Pin, LOW); // Blok 2 bezet melden.
}
if (I2CByte == '|')
{
// Wissel 1 Rechtdoor.
digitalWrite(Wissel1rPin, HIGH);
delay(750); // bekrachtigings tijd wisselspoel.
digitalWrite(Wissel1rPin, LOW);
}
if (I2CByte == '/')
{
// Wissel 1 Afbuigend.
digitalWrite(Wissel1aPin, HIGH);
delay(750); // bekrachtigings tijd wisselspoel.
digitalWrite(Wissel1aPin, LOW);
}
}
}
void requestEvent() {
Wire.write(5); // Stuur een 5 naar de Master.
}
Ik heb gisteravond de raw code gepost, ik was nog bezig om de goede code met goede variable namen te maken, om snel test code te programmeren gebruik ik geen variable namen, ik hoef dan ook op dat moment niet aan variable namen te denken.Dat is eigenlijk best wel gek. Variabele namen zijn juist bedacht omdat die makkelijker zijn dan de pinnamen... En als je het pinnummer makkelijker vindt dan de pinnaam gebruik je misschien niet de juiste naam... Niet om betweterig te doen ofzo maar ik denk dat het makkelijker is om gelijk vanaf het begin gewoon namen te gebruiken. Vind het ook makkelijker om jou Paul te noemen dan 8883 (je forum id (http://forum.beneluxspoor.net/index.php?action=profile;u=8883) ;) ).
De slave hoeft geen ander adres te krijgen, eenmaal geprogrammeerd, zal het adres van de slave niet meer veranderen, het kan dat het programma in de slave nog wat aangepast word maar geenszins het adres.Ik snap dat een slave tijdens normaal gebruik geen ander adres hoeft te krijgen. Maar wat als je later (als je al 10+ slave modules hebt) opeens toch nog een aanpassing maakt aan de software? Ga je dan:
#include <EEPROM.h>
byte moduleAdres = 2; //Dit adres zal worden opgeslagen in EEPROM als dit de eerste keer programmeren is of als je FORCEER_NIEUW_ADRES defined (adres 255 niet teogestaan)
//#define FORCEER_NIEUW_ADRES //Uncomment als je de module geforceerd een nieuw adres wilt geven.
const byte AdresEE = 0; //Adres van het eeprom waar het module adres staat opgeslagen
void setup(){
#ifdef FORCEER_NIEUW_ADRES
//We passen adres aan. Alleen als deze niet al juist is.
if(EEPROM.read(AdresEE) != moduleAdres){
EEPROM.write(AdresEE, moduleAdres);
}
#else
//Is adres niet ingesteld? Nooit ingesteld heeft een waarde van 255 ofwel 0xFF
if(EEPROM.read(AdresEE) == 0xFF){
EEPROM.write(AdresEE, moduleAdres);
}
else{
moduleAdres = EEPROM.read(AdresEE); //haal adres uit EEPROM
}
#endif
}
void loop(){
//gebruik hier het moduleAdres
}
De eerste keer moet je de variabele moduleAdres zelf de gewenste waarde geven. Deze komt dan in EEPROM. Pas je nu het programma aan en wil je het weer uploaden naar de Arduino zal het module adres gewoon uit EEPROM gehaald worden. Wat je op dat moment hebt staan achter moduleAdres maakt niet uit. Je kunt dus gerust alle modules updaten terwijl je daar hetzelfde adres hebt staan, het wordt niet aangepast. Tenzij je #define FORCEER_NIEUW_ADRES gebruikt.Misschien een uitleg van het Millis commando in het Nederlands) :-X ;)Goed, komt hij dan he. Misschien wat kort maar dit is een veel gebruikt voorbeeld.
unsigned long vorigeMillis = 0; //Wanneer is de laatste keer dat we iets gedaan hebben?
const unsigned int Interval = 60 * 1000; //Om de hoeveel tijd (met welk interval) willen we de taak doen?
void loop(){
//We kijken hoe laat het is,
//we halen hier vanaf hoe laat het de vorige keer was
//en kijken of dit al langer dan interval geleden is
if(millis() - vorigeMillis >= interval){
//sla de tijd van nu op als laatste keer dat we iets gedaan hebben
vorigeMillis = millis();
//doe hier wat je eens per minuut wilde doen
}
}
#include <Bounce2.h>
unsigned long ledjeAanMillis = 0; //De tijd dat we het ledje aan gezet hebben
const unsigned long LedjeAanTijd = 10 * 60 * 1000; //Voor 10 minuten aan
const byte LedjePin = 13; //Pin waar het ledje aan hangt
const byte KnopjePin = 9; //Pin waar het knopje aan hangt (naar GND)
Bounce knopje; //Het object (door de library) van het knopje
void setup(){
pinMode(LedjePin, OUTPUT); //We willen het ledje laten branden dus een output
knopje.attach(LedjePin, INPUT_PULLUP); //Geven aan aan welke pi het knopje zit en dat voor deze pin de pull up aan moet
}
void loop(){
ledjeUpdate(); //Controleren of we het ledje aan of uit moeten zetten
/*
En hier kan nog veel meer gebeuren
interessanteFunctie();
nogIets();
ditKanOokwelGebeuren(true);
enz
*/
}
void ledjeUpdate(){
//Beginnen we met kijken of het knopje is ingedrukt want ja, dan moet het ledje aan
knopje.update(); //Lees het knopje
//Is het knopje ingedrukt?
if(knopje.fell()){
digitalWrite(LedjePin, HIGH); //zet het ledje aan
ledjeAanMillis = millis(); //sla op wanneer je it gedaan hebt
}
//nu we dat gedaan hebben, is het misschien tijd om het ledje uit te zetten? Moet hij wel aan staan natuurlijk!
//Staat ledje aan? (Ja, je kan gewoon een digitalRead op een output doen, geen probleem :) )
if(digitalRead(LedjePin)){
//Ledje is dus aan, maar moet hij al uit?
if(millis() - ledjeAanMillis >= LedjeAanTijd){
digitalWrite(LedPin, LOW);
}
}
}
@Reinout,
Ik weet niet wat je probeert te doen met servo's maar die kan je standaard (out of the box) al gewoon aansturen. Tenzij je een goede reden hebt lijkt mij micro() niet nodig...
Of zie ik iets enorm over het hoofd?Yep, het feit dat de interne regelloop van een servo absoluut die nauwkeurigheid niet heeft. Het is alsof je een TGV wilt aansturen op 0,0000001km/h. Compleet nutteloos dus ;) Een standard SG90 servo doet er bijvoorbeeld al 360ms over om van 0 naar 180 graden te draaien als je hem van het ene op het andere moment van 1ms puls naar 2ms puls stuurt. Ook wordt maar eens in de +-20ms een puls van de Arduino (of elke andere controller) naar de servo gestuurd. Dit is dus maar 50 keer per seconde! Jij kan dan wel mooi elke 500us je positie aanpassen maar dat is compleet nutteloos. De servo ziet nog steeds maar elke 20ms een nieuwe waarde.
Stel nu dat we in code iedere minuut iets willen doen. Dan wordt dat ik code:
Code: [Selecteer]unsigned long vorigeMillis = 0; //Wanneer is de laatste keer dat we iets gedaan hebben?
const unsigned int Interval = 1000; //Om de hoeveel tijd (met welk interval) willen we de taak doen?
Of begrijp ik het verkeerd.Oeps, nee, je begrijpt het prima! ;D Heb de code in de voorbeelden aangepast met een factor 60 ::)
Maar ik ga er wel van uit dat de servo library dan zelf degene is die elke 20ms de laatste actuele waarde doorgeeft.Dat klopt. Je schrijft nu gewoon vaak naar een variabele en de servo lib lees/gebruikt deze maar eens per 20ms. Die 20ms komt van een timer interrupt.
Als ik maar één maal per 20ms één waarde aan de servo zou geven zou dat dus soepeler gaan?Nee, zou hetzelfde moeten gaan. Immers stuurt de servo library de servo nog steeds naar de zelfde posities elke 20ms. Maar je geeft de Arduino een stuk minder te doen. Met stapjes in de us range is het best wel lastig om twee of meer servo's tegelijk te laten bewegen. Het uitvoeren van de taak (updaten van de servo) begint namelijk al aardig in de range van je interval te lopen.
// I2C AAMS Blokkaart code (NANO)
#include <Wire.h>
char I2CByte;
const byte Blok1Pin = 8; // Blok 1
const byte Blok2Pin = 12; // Blok 2
const byte Sein1rPin = 4; // Sein 1 rood
const byte Sein1gPin = 5; // Sein 1 groen
const byte Sein2rPin = 2; // Sein 2 rood
const byte Sein2gPin = 3; // Sein 2 groen
const byte Wissel1rPin = 6; // Wissel 1 rechtdoor
const byte Wissel1aPin = 7; // Wissel 1 afbuigend
const byte PinPwm = 9; // Snelheids regeling pwm
const byte PinIn1 = 10; // Trein cw
const byte PinIn2 = 11; // Trein ccw
boolean CwRichting = 0;
boolean CcwRichting = 1;
void setup()
{
pinMode(Wissel1rPin, OUTPUT);
pinMode(Wissel1aPin, OUTPUT);
pinMode(Blok1Pin, OUTPUT);
pinMode(Blok2Pin, OUTPUT);
pinMode(Sein1rPin, OUTPUT);
pinMode(Sein1gPin, OUTPUT);
pinMode(Sein2rPin, OUTPUT);
pinMode(Sein2gPin, OUTPUT);
pinMode(PinPwm, OUTPUT);
pinMode(PinIn1, OUTPUT);
pinMode(PinIn2, OUTPUT);
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
Wire.begin(5); // Stelt de communicatie met de master in.
Wire.onReceive(receiveEvent); // Iets ontvangen van de Master. // <<<<<<<<<
Wire.onRequest(requestEvent); // Stuur een 5 naar de Master.
setBaanvakStatus(0,1);
}
void loop()
{ // De loop word niet gebruikt, in plaats daarvan word een Event gebruikt.
}
void receiveEvent(int howMany)
{
while (Wire.available())
{
char I2CByte = Wire.read();
if (I2CByte == 'A')
{
setBaanvakStatus(1, 0); // BloK 1 Vrij geven.
}
if (I2CByte == 'a')
{
setBaanvakStatus(1, 1); // Blok 1 Bezet melden.
}
if (I2CByte == 'B')
{
setBaanvakStatus(2, 0); // Blok 2 Vrij geven.
}
if (I2CByte == 'b')
{
setBaanvakStatus(2, 1); // Blok 2 bezet melden.
}
if (I2CByte == '|')
{
setWissel(1, 0); // Wissel 1 Rechtdoor.
}
if (I2CByte == '/')
{
setWissel(1, 1); // Wissel 1 Afbuigend.
}
// snelheds regeling voor de baanspanning Pwm
if (I2CByte == '0') {
if (CwRichting == 0) {
for (int t = 200; t >= 10; t--) {
delay(600);
setLocSpeed(1, t, CwRichting);
}
}
if (CwRichting == 1) {
for (int t = 200; t >= 10; t--) {
delay(600);
setLocSpeed(1, t, !CwRichting);
}
}
}
if (I2CByte == '1') {
if (CwRichting == 0) {
for (int t = 10; t <= 200; t++) {
delay(750);
setLocSpeed(1, t, CwRichting);
}
}
if (CwRichting == 1) {
for (int t = 10; t <= 200; t++) {
delay(750);
setLocSpeed(1, t, !CwRichting);
}
}
}
}
}
void requestEvent() {
Wire.write(5); // Stuur een 5 naar de Master.
}
void setLocSpeed(byte loc, byte Snelheid, bool Richting) {
boolean inPin1 = LOW;
boolean inPin2 = HIGH;
if (Richting == 1) {
inPin1 = LOW;
inPin2 = HIGH;
}
else {
if (Richting == 0) {
inPin1 = HIGH;
inPin2 = LOW;
}
}
if (loc == 1) {
digitalWrite(PinIn1, inPin1);
digitalWrite(PinIn2, inPin2);
analogWrite(PinPwm, Snelheid);
}
} // Einde functie setLocSpeed
void setBaanvakStatus(byte Blok, bool Status) {
if (Blok == 1) {
if (Status == 1) {
digitalWrite(Blok1Pin, LOW); // Blok 1 Bezet.
// Zet de seinen goed
digitalWrite(Sein1rPin, HIGH);
digitalWrite(Sein1gPin, LOW);
}
}
if (Blok == 1) {
if (Status == 0) {
digitalWrite(Blok1Pin, HIGH); // Blok 1 Vrij.
// Zet de seinen goed
digitalWrite(Sein1rPin, LOW);
digitalWrite(Sein1gPin, HIGH);
}
}
if (Blok == 2) {
if (Status == 1) {
digitalWrite(Blok2Pin, LOW); // Blok 2 Bezet.
// Zet de seinen goed
digitalWrite(Sein2rPin, HIGH);
digitalWrite(Sein2gPin, LOW);
}
}
if (Blok == 2) {
if (Status == 0) {
digitalWrite(Blok2Pin, HIGH); // Blok 2 Vrij.
// Zet de seinen goed
digitalWrite(Sein2rPin, LOW);
digitalWrite(Sein2gPin, HIGH);
}
}
if (Blok == 0) {
if (Status == 1) {
digitalWrite(Blok1Pin, LOW);
digitalWrite(Blok2Pin, LOW);
// Zet de seinen goed
digitalWrite(Sein1rPin, LOW);
digitalWrite(Sein1gPin, HIGH);
digitalWrite(Sein2rPin, LOW);
digitalWrite(Sein2gPin, HIGH);
}
}
if (Blok == 0) {
if (Status == 0) {
digitalWrite(Blok1Pin, HIGH);
digitalWrite(Blok2Pin, HIGH);
// Zet de seinen goed
digitalWrite(Sein1rPin, LOW);
digitalWrite(Sein1gPin, HIGH);
digitalWrite(Sein2rPin, LOW);
digitalWrite(Sein2gPin, HIGH);
}
}
} // einde functie setBaanvakStatus
void setWissel(byte Wnummer, bool Wrichting) {
if (Wnummer == 1) {
if (Wrichting == 0) {
digitalWrite(Wissel1rPin, HIGH);
delay(750); // Normaal staat de waarde op 500)
digitalWrite(Wissel1rPin, LOW);
}
}
if (Wnummer == 1) {
if (Wrichting == 1) {
digitalWrite(Wissel1aPin, HIGH);
delay(750); // Normaal staat de waarde op 500)
digitalWrite(Wissel1aPin, LOW);
}
}
} // einde functie setWissel
En nu we het over pin namen hebben, wat is de taak van SlavePinx ?
Ik snap dat een slave tijdens normaal gebruik geen ander adres hoeft te krijgen. Maar wat als je later (als je al 10+ slave modules hebt) opeens toch nog een aanpassing maakt aan de software? Ga je dan:
Wire.begin(5); // Stelt de communicatie met de AAMS centrale in.
Wire.onReceive(receiveEvent); // Iets ontvangen van de AAMS centrale.
Wire.onRequest(requestEvent); // Stuur een Adres(5) naar de AAMS centrale en maak dat zichtbaar door een LED.
void requestEvent() {
Wire.write(5); // Stuur een adres(5) naar de AAMS centrale.
}
setBaanvakStatus(0,0);
}
void loop()
{
}
void receiveEvent(int howMany)
{
Voor het serial data tussen PC en master gedoe (en dit kan je dan eigenlijk ook gebruiken op de slaves...)
#include <Bounce2.h>
const byte LedPins[] = {13, 12}; //Pinnen voor de knipper ledjes (even lang aan als uit)
const byte FlasherPin = 10; //Pin voor de flasher, andere aan dan uit tijd
const byte KnopjePin = 9; //Pin voor het drukknopjes (tussen de pin en GND)
const byte TimedLedPin = 8; //Pin voor het ledje wat je an kunt doen met het knopje
const unsigned int LedIntervals[] = {500, 1200}; //aan/uit interval voor led1, led 2 enz
const unsigned int FlasherIntervals[] = {1900, 100}; //1900ms uit, 100ms aan
const unsigned int TimedLedInterval = 30000; //uit na zoveel ms
Bounce knopje;
void setup(){
//Alle pins met ledjes moeten natuurlijk output zijn
for(byte i = 0; i < sizeof(LedPins); i++){
pinMode(LedPins[i], OUTPUT);
}
pinMode(FlasherPin, OUTPUT); //Flasher ook output
pinMode(TimedLedPin, OUTPUT);//en deze ook
knopje.attach(KnopjePin, INPUT_PULLUP); //Verbind de pin met het object en zet pull up aan
}
void loop(){
updateLed(0); //Een ledje laten knipperen
updateLed(1); //En nog één!
updateFlasher(); //En nu nog eentje laten met verschillende aan en uit tijden
timedLedUpdate(); //En nog een ledje (maar zou net zo goed een wissel kunnen zijn ;) ), aan met knop, vanzelf uit
}
//Laat ledjes knipperen. Even lang aan als uit. Werkt voor hoevel ledjes je in LedPins en LedIntervals definieert
void updateLed(byte ledNummer){
static unsigned long vorigeMillis[sizeof(LedPins)]; //om de laatste keer te onthouden (wanneer keek ik op de klok?)
//Controleer of interval om is. MOET op deze manier
if(millis() - vorigeMillis[ledNummer] >= LedIntervals[ledNummer]){
vorigeMillis[ledNummer] = millis(); //sla op dat we weer iets doen
digitalToggle(LedPins[ledNummer]); //Wissel led (HIGH <-> LOW)
}
}
//functie om een pin te wisselen (LOW <-> HIGH)
void digitalToggle(byte pin){
digitalWrite(pin, !digitalRead(pin));
}
void updateFlasher(){
static unsigned long vorigeMillis = 0; //Laate keer iets gedaan, ondertussen bekende variabele ;)
//Checken of het interval om is. We gebruiken een interval voor uit (FlasherIntervals[0]) en een voor aan FlasherIntervals[1]
//Door dus digitalRead() te bruiken komt hier al 0 of 1 uit al naar gelang of de flasher aan of uit is
if(millis() - vorigeMillis >= FlasherIntervals[digitalRead(FlasherPin)]){
vorigeMillis = millis(); //Sla op dat we eits doen
digitalToggle(FlasherPin); //wissel led(HIGH <-> LOW)
}
}
//Timed ledje, gaat aan met knopje en weer uit na een ingestelde tijd
void timedLedUpdate(){
static unsigned long ledjeAanMillis = 0;
//Beginnen we met kijken of het knopje is ingedrukt want ja, dan moet het ledje aan
knopje.update(); //Lees het knopje
//Is het knopje ingedrukt?
if(knopje.fell() ){
digitalWrite(TimedLedPin, HIGH); //zet het ledje aan
ledjeAanMillis = millis(); //sla op wanneer je it gedaan hebt
}
//nu we dat gedaan hebben, is het misschien tijd om het ledje uit te zetten? Moet hij wel aan staan natuurlijk!
//Staat ledje aan? (Ja, je kan gewoon een digitalRead op een output doen, geen probleem :) )
if(digitalRead(TimedLedPin)){
//Ledje is dus aan, maar moet hij al uit?
if(millis() - ledjeAanMillis >= TimedLedInterval){
digitalWrite(TimedLedPin, LOW);
}
}
}
void setWissel(byte Wnummer, bool Wrichting) {
if (Wnummer == 1) {
if (Wrichting == 0) {
digitalWrite(Wissel1rPin, HIGH);
delay(750); // Normaal staat de waarde op 500)
digitalWrite(Wissel1rPin, LOW);
}
}
if (Wnummer == 1) {
if (Wrichting == 1) {
digitalWrite(Wissel1aPin, HIGH);
delay(750); // Normaal staat de waarde op 500)
digitalWrite(Wissel1aPin, LOW);
}
}
} // einde functie setWissel
De check Wrichting == 1 is nogal overbodig. Als het niet 0 is zoals al gecontroleerd dan moet wel 1 zijn ;) De tweede Wnummer == 1 is ook niet nodig.void setWissel(byte Wnummer, bool Wrichting) {
if (Wnummer == 1) {
if (Wrichting == 0) {
digitalWrite(Wissel1rPin, HIGH);
delay(750); // Normaal staat de waarde op 500) <--------------- Dit is dus typisch iets om een const variabele voor aan te maken!
digitalWrite(Wissel1rPin, LOW);
}
else{
digitalWrite(Wissel1aPin, HIGH);
delay(750); // Normaal staat de waarde op 500)
digitalWrite(Wissel1aPin, LOW);
}
}
} // einde functie setWissel
En nu nog zonder delay ;D char Slave = Wire.read(); // receive a byte as character
Hiermee maak je gewoon een lokale variabele Slave aan. In je code heb je dus twee verschillende variabele die beide Slave heten maar verschillende waardes hebben! Alleen wordt bij het aanroepen steeds eerst gekeken of een variabele lokaal gevonden kan worden, zo niet wordt global gekeken. int myVar = 1;
void setup(){
Serial.begin(115200);
}
void loop(){
int myVar = 50;
Serial.println(myVar); //print de lokale variabele
Serial.println(::myVar); //print de global variabele (geef je aan met de :: )
delay(1000);
}
Dit zal elke seconde Als ik het goed heb kan ik 127 slave units met de I2C gebruiken.Klopt, het adres van een I2C is 7 bits lang en 0 mag niet gebuikt worden => houd je 127 over. Let wel dat je LCD hier dus ook al een adres van inpikt.
Wire.begin(5); // Stelt de communicatie met de AAMS centrale in.
Waarom is dit niet een variabele? Want later wil je die 5 weer gebruiken.Het lijkt er sterk op dat een delay(200) zonder dat de Arduino moet wachten tot de delay(200) is afgelopen andere commando's kan uitvoeren,Ik zie even niet welke delay je bedoelt (zie geen delay(200) ). Maar ja, de library zal je volgende commando wel afvangen (heeft niet voor niet een buffer van 32 bytes) maar zal deze pas uitvoeren als de delay over is.
byte BlokPin[] = {11, 10, 9, 8};
byte State;
//int current;
void setup() {
pinMode(BlokPin[0], OUTPUT);
pinMode(BlokPin[1], OUTPUT);
pinMode(BlokPin[2], OUTPUT);
pinMode(BlokPin[3], OUTPUT);
Serial.begin(9600);
}
void loop() {
if (Serial.available() > 0) {
if (Serial.peek() == 'A') {
Serial.read();
State = Serial.parseInt();
Serial.read();
digitalWrite(BlokPin[0], State);
}
if (Serial.peek() == 'B') {
Serial.read();
State = Serial.parseInt();
digitalWrite(BlokPin[1], State);
}
if (Serial.peek() == 'C') {
Serial.read();
State = Serial.parseInt();
digitalWrite(BlokPin[2], State);
}
if (Serial.peek() == 'D') {
Serial.read();
State = Serial.parseInt();
digitalWrite(BlokPin[3], State);
}
while (Serial.available() > 0 ) {
Serial.read();
}
}
}
byte BlokPins[] = {11, 10, 9, 8};
void setup() {
for(byte i = 0; i < sizeof(BlokPins); i++){
pinMode(BlokPins[i], OUTPUT);
}
Serial.begin(9600); //tijd voor 115200?
}
void loop() {
checkIngekomenSerial();
}
void checkIngekomenSerial(){
// Ga dan uit dat de serial commando's eruit zien als
// [commando letter] [adres]
// Waarbij ieder [] één byte is. Dus geen adressen in ASCII zenden ;)
if (Serial.available() >= 2) {
switch(Serial.read()){
case 'W':
//Schakel een wissel recht
//Ga even uit dat de functie schakeWissel(wisselnummer, richting) bestaat
schakelWissel(Serial.read(), RECHT);
break;
//schakel een wissel afbuigend
case 'w':
schakelWissel(Serial.read(), AFBUIGEN);
break;
//Maak blok vrij
case 'b':
setBlok(Serial.read(), VRIJ);
break;
case 'B':
setBlok(Serial.read(), BEZET);
break;
}
}
}
byte BlokPins[] = {11, 10, 9, 8};
const unsigned int SerialInterval = 200;
void setup() {
for(byte i = 0; i < sizeof(BlokPins); i++){
pinMode(BlokPins[i], OUTPUT);
}
Serial.begin(9600); //tijd voor 115200?
}
void loop() {
checkIngekomenSerial();
}
void checkIngekomenSerial(){
static unsigned int lastCommandMillis = 0;
unsigned int nowMillis = millis();
// Ga dan uit dat de serial commando's eruit zien als
// [commando letter] [module adres] [device adres]
// Waarbij ieder [] één byte is. Dus geen adressen in ASCII zenden ;)
//Kijk of er een commando is binnen gekomen
if(Serial.available() >= 3){
//Okay, 3 byte dus een commando, update de tijd dat er een geldig commando was
lastCommandMillis = millis();
//Eerst commando van 3 bytes even opslaan
for(byte i = 0; i < 3; i++){
laatsteCommando[i] = Serial.read();
}
//Nu over I2C versturen
Wire.beginTransmission(laatsteCommando[1]); //bevat het adres
Wire.write(laatsteCommando[0]); //type commando
Wire.write(laatsteCommando[2]); //device adres
Wire.endTransmission(); //En de bus sluiten
}
//Is het anders tijd voor het legen van de buffer?
//Gebeurd als er SerialInterval lang geen geldig commando is ontvangen
else if(Serial.available() && (nowMillis - lastCommandMillis >= SerialInterval){
while(Serial.available()){
Serial.read();
}
}
//Om te zorgen dat de buffer niet geleegd word als we na een lange tijd weer beginnen met het zenden van een commando
//updaten we de tijd ook als de buffer gewoon leeg is. Kan ook gezien worden als geldig
//commando voor do niets ;)
else if(!Serial.available()){
lastCommandMillis = millis();
}
}
byte BlokPins[] = {11, 10, 9, 8};
void setup() {
for(byte i = 0; i < sizeof(BlokPins); i++){
pinMode(BlokPins, OUTPUT);
}
Serial.begin(9600); //tijd voor 115200?
}
void loop() {
checkIngekomenSerial();
}
void checkIngekomenSerial(){
// Ga dan uit dat de serial commando's eruit zien als
// [commando letter] [adres]
// Waarbij ieder [] één byte is. Dus geen adressen in ASCII zenden ;)
if (Serial.available() >= 2) {
switch(Serial.read()){
case 'W':
//Schakel een wissel recht
//Ga even uit dat de functie schakeWissel(wisselnummer, richting) bestaat
schakelWissel(Serial.read(), RECHT);
break;
//schakel een wissel afbuigend
case 'w':
schakelWissel(Serial.read(), AFBUIGEN);
break;
//Maak blok vrij
case 'b':
setBlok(Serial.read(), VRIJ);
break;
case 'B':
setBlok(Serial.read(), BEZET);
break;
}
}
}
byte BlokPins[] = {11, 10, 9, 8};
#define RECHT 0
#define AFBUIGEN 1
#define VRIJ 0
#define BEZET 1
void setup() {
for(byte i = 0; i < sizeof(BlokPins); i++){
pinMode(BlokPins[i], OUTPUT);
}
Serial.begin(115200); //tijd voor 115200?
}
void loop() {
checkIngekomenSerial();
}
void checkIngekomenSerial(){
// Ga dan uit dat de serial commando's eruit zien als
// [commando letter] [adres]
// Waarbij ieder [] één byte is. Dus geen adressen in ASCII zenden ;)
if (Serial.available() >= 2) {
switch(Serial.read()){
case 'W':
//Schakel een wissel recht
//Ga even uit dat de functie schakeWissel(wisselnummer, richting) bestaat
schakelWissel(Serial.read(), RECHT);
break;
//schakel een wissel afbuigend
case 'w':
schakelWissel(Serial.read(), AFBUIGEN);
break;
//Maak blok vrij
case 'b':
setBlok(Serial.read(), VRIJ);
break;
case 'B':
setBlok(Serial.read(), BEZET);
break;
}
}
}
void schakelWissel(byte address, bool state){
Serial.print("Wissel ");
Serial.print(address);
if(state){
Serial.println(" afbuigen");
}
else{
Serial.println(" recht");
}
}
void setBlok(byte address, bool state){
Serial.print("Blok ");
Serial.print(address);
if(state){
Serial.println(" bezet");
}
else{
Serial.println(" vrij");
}
}
byte BlokPins[] = {11, 10, 9, 8};//worden voor testen gebruikt voor blok en wissels
#define Recht 0
#define Afbuigen 1
#define Vrij 0
#define Bezet 1
//char MyString;
void setup() {
for (byte i = 0; i < sizeof(BlokPins); i++) {
pinMode(BlokPins[i], OUTPUT);
}
Serial.begin(115200); //tijd voor 115200?
}
void loop() {
checkIngekomenSerial();
}
void checkIngekomenSerial() {
// Ga dan uit dat de serial commando's eruit zien als
// [commando letter] [adres]
// Waarbij ieder [] één byte is. Dus geen adressen in ASCII zenden ;)
//while (Serial.available() >= 2) {
if (Serial.available() >= 2) {
//char MyString = Serial.read();
//if(MyString == 'W1') {
// setWissel(MyString, Recht);
// }
// if(MyString == 'w1'){
// setWissel(MyString, Afbuigen);
// }
//}
switch (Serial.read()) {
//switch (MyString) {
//schakel een wissel recht
case 'W':
//case 'W1':
setWissel(Serial.read(), Recht);
//setWissel(MyString, Recht);
break;
//schakel een wissel afbuigend
case 'w':
//case 'w1':
setWissel(Serial.read(), Afbuigen);
//setWissel(MyString, Afbuigen);
break;
//Maak blok vrij
case 'b':
setBlok(Serial.read(), Vrij);
break;
case 'B':
setBlok(Serial.read(), Bezet);
break;
}
}
}
void setWissel(byte address, bool state) {
//char MyString = Serial.read();
//for(byte i = 0; i< sizeof(BlokPins); i++){ // ik gebruik BlokPins ook voor de wissels om makkelijk te testen.
Serial.print("Wissel ");
Serial.print(address);
if (state) {
Serial.println(" Afbuigen");
digitalWrite(Serial.read(), state);
//digitalWrite(MyString, state);
//digitalWrite(address,state);// Deze werkt niet
}
else {
Serial.println(" Rechtdoor");
digitalWrite(Serial.read(), state);
//digitalWrite(MyString, state);
//digitalWrite(address,state);// Deze werkt niet
}
}
//}
void setBlok(byte address, bool state) {
Serial.print("Blok ");
Serial.print(address);
if (state) {
Serial.println(" bezet");
}
else {
Serial.println(" vrij");
}
}
;Dgezet, het was alweer een tijd geleden dat jij dit geschreven had, wisten we waar het over ging. ;D
const byte BlokPins[] = {11, 10, 9, 8};//worden voor testen gebruikt voor blok en wissels
const byte WisselPins[][2] = {{13, 14}, {15, 16}}; //wissel pinnen
#define Recht 0
#define Afbuigen 1
#define Vrij 0
#define Bezet 1
void setup() {
for (byte i = 0; i < sizeof(BlokPins); i++) {
pinMode(BlokPins[i], OUTPUT);
}
for(byte i = 0; i < sizeof(WisselPins); i++){
pinMode(WisselPins[i][Recht], OUTPUT);
pinMode(WisselPins[i][Afbuigen], OUTPUT);
}
Serial.begin(115200); //tijd voor 115200?
}
void loop() {
checkIngekomenSerial();
}
void checkIngekomenSerial() {
// Ga dan uit dat de serial commando's eruit zien als
// [commando letter] [adres]
// Waarbij ieder [] één byte is. Dus geen adressen in ASCII zenden ;)
if (Serial.available() >= 2) {
switch (Serial.read()) {
//schakel een wissel recht
case 'W':
//case 'W1':
setWissel(Serial.read(), Recht);
break;
//schakel een wissel afbuigend
case 'w':
//case 'w1':
setWissel(Serial.read(), Afbuigen);
break;
//Maak blok vrij
case 'b':
setBlok(Serial.read(), Vrij);
break;
case 'B':
setBlok(Serial.read(), Bezet);
break;
}
}
}
void setWissel(byte address, bool state) {
/*
Hier doe je niets meer met serial. Alle gegeven die je nodig hebt zijn al uit serial gehaald
en als parameter meegegeven aan deze functie.
*/
//Even compenseren voor ASCII. Werkt alleen voor 1 t/m 9.
//GEEN oplossing dus. Beter en simpeler om een echte byte te sturen maar dat doet de serial monitor niet
address -= '1';
Serial.print("Wissel ");
Serial.print(address);
if (state) {
Serial.println(" Afbuigen");
digitalWrite(WisselPins[address][0], state);
}
else {
Serial.println(" Rechtdoor");
digitalWrite(WisselPins[address][0], state);
}
}
void setBlok(byte address, bool state) {
Serial.print("Blok ");
Serial.print(address);
if (state) {
Serial.println(" bezet");
}
else {
Serial.println(" vrij");
}
}
Dit geeft al een beetje aan hoe je dus de data kunt gebruiken. Hiermee kun je dus met "w1" en "W1" het ledje op pin 13 aan en uit zetten. (En met 2 die op pin 15.) digitalWrite(22, 1); // Blok 1 Bezet
digitalWrite(23, 0); // Blok 2 Vrij
digitalWrite(24, 0); // Blok 3 Vrij
digitalWrite(25, 0); // Blok 4 Vrij
digitalWrite(26, 0); // Blok 5 Vrij
digitalWrite(27, 0); // Blok 6 Vrij
digitalWrite(28, 0); // Blok 7 Vrij
digitalWrite(29, 1); // Blok 8 Bezet
Commentaar bij hebt gezet maar anders had ik geen flauw idee wat je deed. Terwijl //Maak juiste blokken bezet, rest vrij
for(byte i = 0; i < sizeof(BlokPins); i++){
if(i == 0 || i == 7){
digitalWrite(BlokPins[i], Bezet);
}
else{
digitalWrite(BlokPins[i], Vrij);
}
}
of met minder code ;)//Maak juiste blokken bezet, rest vrij
for(byte i = 0; i < sizeof(BlokPins); i++){
digitalWrite(BlokPins[i], (i == 0 || i == 7));
}
al duidelijk is met één regel commentaar. En ik vermijd hier om de bloknummers te noemen in het commentaar. Zou ik deze namelijk later wijzigen heb ik makkelijk code en commentaar die iets anders vertellen. Dit terwijl al makkelijk uit de code af te leiden is welke blokken vrij/bezet moeten zijn. Overigens doet deze code niet wat de print naar serial doet vermoeden ::)ga ik twee bi-polaire relais gebruiken, in dat geval kost dat vier uitgangen
Werkt mijn gedachten kronkel dan zet ik de nummers om in namen, ik zie door de bomen het bos niet meer door alle tekst,de code word voller en voller met tekst.Okay, vandaar. Ook al is het denk ik ook een vorm van gewenning. Mijn vriendin is ook zo dyslectisch als een deur maar variabele namen vindt ze duidelijker dan nummer. Wat enorm kan helpen is geen namen kiezen die op elkaar lijken. (volgendeWisselInvoer en volgendeWisselUitvoer is dan niet handig ;D)
voor mij is het makkelijker om in de code zo min mogelijk tekst te gebruiken als ik in de code digitalWrite (28,1) zet weet ik meteen wat er gebeurd als ik digitalWrite (Sein1Pin,Bezet) raak ik op een gegeven moment het overzicht kwijt ( Dyslexie ,leesblind) vandaar.
Het klopt wat Timo schrijft , alleen zou ik geen pro mini's gebruiken deze processor boardjes hebben geen usb aansluiting, je zult een usb-adapter erbij moeten kopen, ik gebruik zelf de Arduino nano (deze is niet veel duurder dan een pro mini), dit boardje heeft iets meer i/o 8 Analog in (pro mini 6) en 13 digital out/in en heeft standaard een usb aansluiting.Ze schelen nog steeds een factor 2 hoor ;) ;D Voor testen ben ik het wel met je eens dat de Nano dan erg gemakkelijk is. Maar als iets vorm gekregen heeft kan je ook een Pro Mini pakken. Eigenlijk hebben zo'n beetje alle Pro Mini's alle aansluitingen van een Nano. Alleen A6 en A7 wil nog wel eens ontbreken. (Waarbij je op moet letten, A7 is analoog in only)) En het feit dat de Pro Mini kleiner is kan in een permanente opstelling vaak een net iets compactere print opleveren :) Dus ik gebruik ze lekker door elkaar.
De relais boardjes zijn er in verschillend uitvoeringen als shield met 4 relais , of als 1,2,4,8,16 voudige uitvoering en daar zijn ook nog verschillende uitvoeringen van "actief hoog" of "actief laag" gestuurd, het verschil zit in de schakeltrap met of zonder Optocoupler.Naar mijn idee zijn de boardjes met opto coupler redelijk zinloos. Tenzij je echt een reden hebt om het relais los te voeden is die met transistor net zo makkelijk.
Een andere manier is het gebruik van solid-state relais, heb daar nog geen ervaring mee.Die zijn zo goed als nutteloos op de modelbaan omdat ze alleen geschikt zijn voor AC.
Ik ben nog bezig met een keerlus schakeling voor mijn baan ,daarvoor ga ik twee bi-polaire relais gebruiken, in dat geval kost dat vier uitgangen van de Arduino en moet het geheel op een shield of losse print gebouwd worden.Is dat voor de Arduino gestuurde baan? En waarom wil je met twee relais werken? En waarom bi-stabiel? Misschien heb je er een goeie reden voor hoor :) Maar ik mis het, zeker in het licht van de Arduino baan, nog even.
Je kunt ook de Rx/Tx van de Arduino gebruiken om met verschillende Arduino's te communiceren Rx Arduino 1 op Tx arduino 2 en Tx Arduino 1 op Rx Arduino 2, in dat geval kun je beter de AT Mega 2650 gebruiken deze heeft vier hardwarematige RX/TX poorten waardoor het makkelijker is om Arduino's te koppelen.Om alleen daarvoor de Mega te gebruiken is misschien wat overkill. Op 1 serial bus kunnen makkelijk meerdere arduino's hangen. Als je alleen één master hebt die naar meerdere slaves moet zenden knoop je simpelweg alle RX van de slaves aan de TX van de master. Wil je ook terug kunnen sturen dan een pull up weerstand aan de RX van de master. En elke slave via een diode verbinden (kathode naar slave). Maar ook dit is vooral voor korte afstand.
Wat de I2C betreft, kun je zonder problemen 1 a 2 mtr. kabel tussen de units gebruiken UTP kabel dan werk het nog goed, deze informatie heb ik van het internet gehaald via Youtube, daar staat een filmpje van deze oplossing. Ben allen de link naar het filmpje kwijt.I2C lengte is sterk afhankelijk van de kabel en de pull ups die gebruikt worden. 1 a 2 meter zou ik echt als max zien. Eigenlijk zou ik zelf onder de modelspoorbaan (= storinggevoelige omgeving) niet verder gaan dan 1 meter.
Dat maakt me duidelijk hoe het werkt. Voor rijden/niet-rijden gebruik je de monostabiele relais, voor wissels bistabiele relais. De monostabiele zitten op prefab kaartjes, de bistabiele niet.
Je signalering (reedcontact) verbruikt ingangen, het signaal gaat naar de arduino, en die stuurt (via script) de relais aan. Dus stel je vervangt het reedcontact door een lichtsluis, dan gaat het signaal (of signalen) van die lichtsluis ook naar de aduino. M.a.w. de arduino vormt een extra tussenlaag binnen de bestaande schakelingen, tussen input en output?
Ze schelen nog steeds een factor 2 hoor ;) ;D
Is dat voor de Arduino gestuurde baan? En waarom wil je met twee relais werken? En waarom bi-stabiel? Misschien heb je er een goeie reden voor hoor :) Maar ik mis het, zeker in het licht van de Arduino baan.
SLX852, daaraan hangt inderdaad een ander prijskaartje.SLX852 is inderdaad een andere catagorie, maar een Arduino als SX-bus master zou met 6 weerstanden een afstand van een meter of 10 kunnen overbruggen in modeltreinland. Helaas is de software voor de Arduino nog niet openbaar.
Beter is het om de wissels te schakelen met vermogens transistoren.Mee eens (y) Transistors zijn goedkoop, makkelijk en niet mechanisch. Voor een blok is een standaard monostabiele prima.
De blokken worden door monostabiele relais gestuurd dat kost een relais per blok.
De signalering van de blokken kan door : reed-relais, ldr, ir lichtsluis, ir reflectie sensoren of via stroom detectie er zijn vast meer componenten te gebruiken voor signalering.De mogelijkheden zijn inderdaad eindeloos en de meeste methodes resulteren gewoon in een puls dus zijn gewoon dwars door elkaar te gebruiken.
De sensoren (lees signalering) worden door mijn systeem via de analogepoort gelezen, zodoende hou ik meer digitale I/O over.Dat is een drogreden Paul ;) Alle analoge poorten (met uitzondering van A7) zijn prima gewoon als digitale poort te gebruiken! Ze hebben alleen als extra functie dat ze analoog kunnen lezen.
Voor rijden/niet rijden van de locomotief gebruik je motordrivers, deze regelen het optrekken/ afremmen of stoppen van de trein, tenzij je voor elk blok een eigen motordriver gebruikt, dan kun je de blokrelais weglaten, anders heb je de blokrelais nodig om bepaalde blokken spanningsloos te maken.Prima te combineren inderdaad (y) Maar zullen we voor het gemak eens termen afspreken om onderscheid te maken? Voorstel, blokken voor alles achter een motordriver en subblok voor alles achter een relais? Is namelijk al een paar keer verwarrend geweest in dit draadje ;D
De Arduino regelt zelf de sturing van de baan met behulp van sensoren en motordrivers zelfstandig of als blok gestuurd systeem, in beide gevallen zorgt het programma voor de uitvoering van de sturing.Hoe ingewikkeld je de sturing maakt bepaal je dus zelf (en zit eigenlijk de meeste uitdaging). ;D
Dat valt erg mee, voor een Arduino pro mini betaal ik euro 2,56 en voor een Arduino nano betaal ik euro 2,80.Dan heb je dure Pro Mini's ;D Ik koop ze voor €1,25 (http://www.aliexpress.com/item/Pro-Mini-Module-Atmega328-5V-16M-For-Arduino-Compatible-With-Nano/2021666535.html?ws_ab_test=searchweb201556_9,searchweb201644_2_10001_10002_10005_10006_10003_10004_62,searchweb201560_8,searchweb1451318400_6150)... Niet om het gebruik van de Nano af te kraken maar puur om aan te geven dat ze echt nog goedkoper zijn. En dan kun je denken "ach, wat scheelt dat nu?". Maar als Roco dat ook had gedacht kostte de z21 wel iets meer ;D
Ik gebruik de biploaire relais om de baanspanning voor een gedeelte van de baan om te polen, zodat de trein zonder stoppen door de keerlus kan rijden.Duidelijk. :) Maar weet dat een bistabiel relais in een Arduino blok gestuurde baan wel een beetje zinloos is... Als je gewoon zorgt dat de lus een eigen motordriver heeft ben je ook klaar ;)
De tweede relais is voor het bedienings-paneel om de toestand van de keerlus/baan weergeven.
In mijn visie is een keerlus een soort blok (met afgeleide eigenschappen en methoden). Dat betekent dat ik dit type blok van een methode zou voorzien om de rijrichting om te schakelen van een naastliggend (volgend) blok.Daarmee is het toch eigenlijk niet anders dan een normaal blok ;)
In een arduino aanpak, begrijp ik nu, zou ik dat principe los moeten laten, want de motordriver vervangt het blok-relais.Als je mee gaat in mijn eerdere blok en subblok structuur, ja. Maar je zou dus, om motor controllers te besparen, dus meerdere subblokken achter één driver kunnen hangen. Bijvoorbeeld handig voor stationsporen of lange opstelsporen enzo. Maar idee is dan wel dat er maar één trein rijdt per driver. Rest mag natuurlijk wel stilstaan in een subblok maar voor rijden zit je met het probleem dat treinen nogal verschillende snelheden hebben bij verschillende spanning enzo. Zitten ze op één driver kan je ze niet meer individueel regelen.
Daarom zou ik in C, C++, VB (mij een biet) blokken zo coderen dat met een minimum aan ballast (een cijferreeks of string) alle toestanden (eigenschappen) en methoden per blok opgeslagen kunnen worden.Ook daar ben je natuurlijk vrij. Maar waar wil je dit opslaan? Op een centrale plaats (bijvoorbeeld PC, (Raspberry) Pi of centrale Arduino (met SD-kaart ofzo)? Of wil je dit op de Arduino doen die het blok beheert?
Ondertussen heb ik me gelijk maar eens verdiept in Arduino compatibele lichtsluizen, want als ik ze toch zelf moet maken kan ik ook wel wat geschikte specs meenemen.Schema wat ik ook vond (op gewezen door Frits) is dit schema met de LM567 (http://forum.beneluxspoor.net/index.php/topic,64858.msg3221572204.html#msg3221572204). Andere optie is met de IS471F (http://www.floodland.nl/aim/info_lichtsluis_1.htm) maar deze is iets duurder, wel simpeler. Beide moduleren de IR led waardoor ze geen last hebben van lampen en zonlicht.
De link met de LM567 werkt niet.Probeer nog eens. Link werkt hier prima (op twee andere apparaten dan gepost) dus denk dat Benelux Rail gewoon de hik had.
En dat wit ik niet.Uhm, wat denk je allemaal moeilijk! ;D Dat kan je toch gewoon allemaal bekijken op de Arduino? Hoog actief, laag actief, zo aan te passen. Iets doen als bezet wordt, makkie. enz Als je een microcontroller gebruikt is dat allemaal maar software.
Wat ik wel wil is dat...
Terug naar de motor-driver. Stel je hebt 30 treinen die kunnen rijden op 20 standaard blokken, plus een aantal afgeleide bloktype blokken. Heb je dan 30 motordrivers nodig?Je hebt minimaal zoveel motor drivers nodig als dat je individueel de snelheid van rijdende wilt kunnen instellen. Dus als je met 10 treinen wilt rijden en de rest staat stil kan je op papier af met 10 motorcontrollers. Maar goed, dan zijn alle blokken altijd bezet, dus je hebt meer marge nodig. Beter is te bedenken dat je (om iedere trein individueel te sturen) net zo veel motorcontrollers nodig hebt als dat je secties waar 1 trein tegelijk ik moet kunnen rijden.
Uhm, wat denk je allemaal moeilijk! ;D Dat kan je toch gewoon allemaal bekijken op de Arduino?
(vanwege de ingebouwde timer, neem ik aan).Niet zo zeer door de timer. Maar je kan states opslaan en daarmee dus een soort monostabiele / flipfop nabootsen.
De motordriver kun je apart voeden als de motor meer stroom vraagt dan de arduino intern kan leveren.Yep, (de meeste) motordrivers hebben een ingang voor de logische signalen voor de sturing en een ingang voor de spanning om voor de uitgang te gebruiken. Laatste mag dan gewoon 18V zijn.
Handig bij 12-16 vDC rijstroom.Zullen we dat vanaf nu maar rijspanning noemen ;) Bij modelspoor is het makkelijker om met spanningssturing te werken dan met stroomsturing.
Manier voor 2-3 rail aanpak per blok. Met arduino enerzijds software, anderzijds omleiding van de uitvoer van motordriver naar de spoorstaven van een blok of blokreeks via een extra relais (mono of bi naar keuze).Dat is natuurlijk een redelijk makkelijke aanvulling. Gewoon een relais per blok (dus hoeft niet per subblok) toevoegen. Een monostabiele lijkt me prima. Kost minder pinnen dus wel zo makkelijk / goedkoop. Zou ik wel 3-rail aan het NC hangen omdat dat de fail save positie is.
De permanente opslag van gegevens is kennelijk wel een probleem om nog even in te duiken.Niet zo zeer een probleem, alles is mogelijk. Je moet alleen bedenken hoe je het wilt doen ;)
Niet zo zeer een probleem, alles is mogelijk. Je moet alleen bedenken hoe je het wilt doen ;)
Zou ik wel 3-rail aan het NC hangen omdat dat de fail save positie is.Dat is een doordenkertje.
Deze wordt dan ook omgedraaid in de lus terwijl de trein in de lus is. Maar bij analoog kan je niet zomaar de polariteit om draaien.Misschien heb ik de mogelijkheden overschat. Ik meende dat, door dit ding anders aan te sluiten dan op de tekening en in de uitleg staat, het relais de stroom kan ompolen buiten de lus in plaats van erbinnen. Ervan uit gaand dat het principe (dus wat het ding doet) gelijk blijft.
Zelf beschik ik over goedkope bistabiele (2xom) en monostabiele (4xom) relais van minder dan € 1,- per stuk (die Chinezen toch!),Dat je monostabiele voor een habbekrats kan krijgen in China wist ik maar ik ben nog nooit bi-stabiele tegen gekomen. Heb je een linkje?
en vergelijk ik dat met de kosten van zo'n floodland-torentje arduino's, dan ziet dat eruit als een kanon op een mug afvuren. Er moet dus ook een goedkopere arduino aanpak mogelijk zijn, zelfs als dat 4 pinnen kost.Zo heel erg complex is die Floodland oplossing niet. Enige is dat hij 3 relais schakelt ipv 1 zodat je eventueel 3 keer stroomdetectie kunt aanleggen in de lus.. Twee relais zou je dus weg kunnen laten. Maar weer, dit is een oplossing voor een digitale baan. Maw, de lus wordt omgeschakeld ipv het volgende blok. Analoog dus niet nuttig.
De stapel hardware bij floodland lijkt inderdaad tamelijk overdone, als je het vergelijkt met deze analoge oplossing van F. Geering (http://k.f.geering.info/modellbahn/technik/kehrschleife.htm). En zelfs die kan goedkoper als je andere aannames doet.Wat is al zei, eigenlijk zit er geen drol op die print. Enige reden dat hij zo groot is omdat hij de Arduino Uno shield maat heeft gebruikt. Zou je het doen met een Pro Mini of Nano kan je met een veel kleiner printje af waarvan ik zou zeggen, doen! Handig!
Het derde aspect wordt nergens genoemd: het voortraject van de lus (inrit-uitrit).Maar net wat je wilt. Als je pal voor de lus een station ofzo hebt dan zou het best nog kunnen. Trein 1 komt door het station/inrit de lus in, wacht daar (waarschijnlijk uit het zicht want lussen liggen zelden in het zicht). Trein 2 (een treinstel) komt naar station en na even gewacht te hebben vertrekt deze weer in de richting waar hij vandaan kwam. Nu kan je trein 1 weer tevoorschijn toveren uit de lus.
Je kunt de inrit-uitrit beschouwen als onderdeel van een enkel keerlus-blok. Immers, zodra de inrit bezet, kan er geen tweede trein meer in.
Maar wat ik er wel uit geleerd heb, is dat reedcontacten als sensor hun beperking hebben, met name bij trek-duw combinaties.Dat klopt. Eigenlijk heeft elke vorm van detectie voor en nadelen. Bij een reedcontact is het voordeel dat het goedkoop en simpel is maar je moet de trein voorzien van magneten. En inderdaad, het moment van magneet moet consistent zijn. Kan iets keren/achteruit rijden dan zal hij voorzien moeten worden van een magneet voor en achter (en een systeem wat daarvan niet door de war raakt). Stroomdetectie heeft als voordeel dat je er niets van ziet maar dat er altijd een verbruiker voorop moet zijn. Ook is dit wat lastiger op een analoge baan (want geen detectie mogelijk als je geen spanning op de rails zet). Lichtsluizen hebben als voordeel dat ze de trein zelf detecteren dus en niets extra's nodig is. Wel moet de beam dus door het pad van de trein schijnen dus lastiger te verstoppen. Vandaar dat analoog een IR reflectie populair is. Deze detecteert ook de trein (dus niets erop nodig) alleen kan tussen de rails gemaakt worden.
en een shield om de wissel te bedienen.Ben zelf dus geen fan van shields. Zijn zo groot en lomp. Print waar je een Pro Mini op kan prikken is vaak kleiner, makkelijker en goedkoper.
De motordrivers bedienen ook de functionele bovenleiding.Functionele bovenleiding zou ik niet aan beginnen, dat heeft geen enkele meerwaarde en alleen nadelen. Zo is de stroomafname slechter dan via de wielen en is een keerlus zo goed als onmogelijk. Immers, na het keren wil de loc de verkeerde spoorstaaf gebruiken om de motor te voeden. Zou je kunnen oplossen door ieder blok de bovenleiding weer schakelbaar te maken maarja, waar doe je het eigenlijk voor? Gewoon spanning van de rails afnemen is dan net zo makkelijk...
Wat te doen met alle extra's van de keerlus-varianten? Op het zelfde shield bijplaatsen?Wat ik al zei, in een door Arduino gestuurd bloksysteem is een keerlus niet anders dan elk ander blok... De Arduino moet gewoon zorgen dat het volgende blok dezelfde snelheid en richting heeft waarmee de trein door kan rijden. Dat dit toevallig ook hetzelfde blok is waar hij uit kwam maar deze nu van rechts naar links (dus richting andersom) wilt berijden is eigenlijk bijzaak...
Zijn arduino shields stapelbaar?In de basis, ja. Maar het ligt wel aan het shield. Deze moet wel voorzien zijn van weer een header. Die van Floodland is dat niet. Een ook al is het stapelbaar zegt dat natuurlijk niets over het eventueel dubbel gebruiken van pinnen op de Arduino.
Functionele bovenleiding zou ik niet aan beginnen, dat heeft geen enkele meerwaarde en alleen nadelen. Zo is de stroomafname slechter dan via de wielen en is een keerlus zo goed als onmogelijk.
De totale baan word door 2 motordrivers aangestuurd, twee in de bochten en 1 in het schaduw station en 1 bij het station.Ah, ik dacht eerst, 2 lijkt me wat weinig. Maar je bedoelt dus 2 IC's met dus 4 H-bruggen. Begrijp ik je goed als ik zeg dat de indeling is:
Dit alles wil ik met 1 a 2 Arduino' s mega 2650 gaan sturen.Lijkt me prima mogelijk met 1 Mega. Wil je toch meer dan één uC (en dat zou het een stuk modulairder maken) zou ik zelf gaan voor een Pro Mini of Nano. Maar voor nu moet één Mega prima gaan. Maar als je het dus later wilt uitbreiden hoeft dat niet de makkelijkste weg te zijn....
Het is al meteen duidelijk dat ik te weinig i/o lijnen hebt , dit wil ik gaan oplossen door een shiftregister te gaan gebruiken, een shift-register heeft maar drie poorten nodig om acht uitgangen te maken, door de shift register te multiplexenDaisy chaining is het woord wat je zoekt ;) Multiplexen is weer wat anders. Dit zou eventueel ook kunnen (hierbij sluit je de latch van ieder shift register op een aparte pin op de Arduino aan) maar kost meer pinnen (maar zou programmeren wel makkelijker kunnen maken omdat je niet verplicht ieder register elke keer hoeft te schrijven).
matrix {0,0,0,0,0,0,0,0} alle seinen staan uit [knip]Ja, en dat "matrix" kan gewoon een array van bytes zijn. Waarbij iedere byte een heel shift register is. Voor 3 shift registers dus genoeg aan een byte shiftRegisterData[3].
Het schema van het shiftregister:Drie opmerkingen. Waarschijnlijk is een shift register zelf al meer dan krachtig genoeg voor seinen. 5mA geeft met moderne ledjes al meer licht dan je zou willen voor een sein... Dus gewoon rechtstreeks aan het shift register zou dus ook mogelijk zijn.
Schema LDR sensor.Dit gaat zeker niet werken ;) Maar is denk ik gewoon teken foutje ;D Alle analoge pinnen zien op deze manier allemaal alleen maar GND. Denk dat je het GND-punt en analogin-pint wilt omdraaien 8)
De blus diodes komen bij de spoelen van de wissels te zitten, of kan ik ze beter er op de print bij solderen?Waarom niet op de print? Alle ruimte en zit je niet te stoeien bij de spoel en heb je niet de mogelijkheid dat je ze vergeet.
Na veel test en onderzoek werk heb ik besloten om voor de Arduino Nano te kiezen, prijs technische de beste keuze,Nano en Pro Mini zijn niet alleen prijsvriendelijker, ze zijn ook veel print vriendelijker.
om het AAMS systeem te gaan bouwen, ook word de indeling van de sturing veranderd naar een bloksturing, dwz. dat ik een Arduino Nano inzet per blok en de motordriver( tweevoudig ) verdeel over twee blokken,waarom dan niet überhaupt één Nano per twee blokken?
op deze manier kan ik de twee blokken synchroniseren zodat er geen sluiting kan ontstaan tussen de twee blokken,Sluiting heb je (bij zelfde rijrichting) nooit. Het probleem met synchronisatie is dat de twee motor bruggen precies aan staan in elkaars uit gebied waardoor er dus langer spanning op de train staat met als gevolg harder gaan rijden.
hoe ik dat ga doen met de rest van de blokken moet ik nog verder uitzoeken.Denk wel dat dit iets waar je mee moet gaan beginnen wil je dit mooi oplossen. Het regelen van snelheid is namelijk wel iets waar je hele systeem op leunt en later slechter in te bakken is. Twee mogelijke oplossingen:
IK ben er al bezig mee geweest maar het lukt mij nog niet om het werkend te krijgen ???, zo moeilijk kan dat niet zijn, ik zal wel weer wat over het hoofd zienAfgezien van onverbonden GND's (in ieder geval op de tekening) zie ik nietsfout en zou het zo moeten werken. Alleen ook hier geldt, lange draden (10cm+) zijn een no-go. Dit zou je al wat kunnen rekken door filtering van het signaal en een externe pull up weerstand (of pull down, maar in ieder geval stuk sterker dan de interne pull up an de Arduino).
In de pen zit nog een bedienings-paneel waarmee ik ook de AAMS sturing kan bedienen, dit wil ik gaan doen dmv or-poorten, dit project moet nog verder uitgewerkt worden.Mag ik vragen wat je precies van plan bent met die or-poorten? Klinkt mij niet heel specifiek bedieningspaneel.
Schema (kan nog een foutje in zitten)Het schema is überhaupt al wat lastig leesbaar maar zie ook wat rare dingen.
#include <SPI.h>
const byte LatchPin = 10;
//Volgende zijn vanzelf door hardware SPI
//Clock = 13
//dataInPin = 12
//dataOutPin = 11
byte dataIn;
byte dataOut;
void setup(){
SPI.begin(); //configureer de SPI uitgangen
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0)); //stel in
pinMode(LatchPin, OUTPUT);
}
void loop(){
updateShiftRegisters();
}
void updateShiftRegisters(){
digitalWrite(LatchPin, HIGH); //Latch alle regsters
//Gebruik SPI ahrdware.
dataIn = SPI.transfer(dataOut);
digitalWrite(LatchPin, LOW); //Reset voor volgende keer.
}
Het 74HC165 ic heb ik eerst moeten ontwerpen voor Fritzing, staat niet in de onderdelen lijst van Fritzing.Vind je ook niet dat ze dat veeeeeeeel lastiger hebben gemaakt dan nodig zou moeten zijn? Het is verdorie makkelijker een footprint te maken in KiCad dan het is om een simpel DIP IC toe te voegen aan Fritzing...
Ik gebruik BD681 NPN Power Darlington transistor voor de aansturing van mijn wissels, als ik het goed in de datasheet heb gekeken zie ik tussen de C->E een blus diode zitten, vandaar dat ik in eerste instantie geen blusdiode heb zitten.Daar mag dan inderdaad wel een diode zitten maar dit is geenszins een blusdiode! Daarvoor zit hij simpelweg op de verkeerde plaats. De blusdiode moet over de spoel staan. Dat houdt hier dus in dat hij tussen de C en de V+ (voedingsspanning) moet. De diode in de transistor doet hier niets.
Het moet een flexibel bloksysteem worden, en als het nodig is kan ik het blok makkelijker uitbreiden.Dat kan ook prima als je twee blokken op één Arduino hebt. De Nano is meer dan krachtig genoeg om twee blokken volledig los van elkaar aan te sturen. Dan maakt het in gebruik niet uit dat ze op dezelfde Arduino draaien of niet.
Ik ga dat systeem niet gebruiken, ik blijf bij I2C voor de communicatie tussen de blokken.Zou ik wel kijken om zwaardere I2C pull up weerstanden te gaan gebruiken.
Het is de bedoeling om de baan zowel met de Arduino en het bedienings-paneel te sturen en dat tegelijkertijd, ik wil de Arduino en de handbediening van elkaar scheiden, als per ongeluk, tegelijk de handbediening als de Arduino dezelfde wissel stuurt er geen rare dingen kunnen gebeuren. Overigens moet het een Xor gate zijn die ik daarvoor gebruik.Met alle respect maar hierbij zijn de XOR's echt nutteloos. Wil je ook de wissels bedienen met een schakelaar, sluit deze dan gewoon aan over je huidige wisseldriver. Bereik je precies hetzelfde. En in beide gevallen zorg je er niet voor dat handbediening automatisch blokkeert of andersom. En de lijnen van de schakelaars naar de XOR zijn ook enorm storing gevoelig door de hoge impedantie.
Q7' is de uitgang naar de volgende shiftregister.Maar Q7' is echt niet de uitgang naar het volgende shiftregister ;) Dat is Q7 (pin 9).
Ik ben al een tijdje niet aan het programmeren, omdat ik het AAMS systeem eerst wil ontwerpen en proef printen gebouwd wil hebben, deze printen kan ik namelijk ook zonder Arduino testen.Eerst goed voor ogen hebben wat je wilt is de basis voor het maken van een passende oplossing. (y) En subsystemen zijn al prima te testen los of eventueel al met de Arduino. Ook code, zolang je non-blocking code schrijft (zonder delay() ) is combineren van losse programmeeraspecten ook prima te doen.
Als ik daar mee klaar ben, ga ik me buigen over het programmeer werk.
Ik ben met teveel verschillende dingen bezig, met betrekking tot het AAMS systeem bezig geweest, zodat ik het spoor even bijster was.
Het viel achteraf wel mee, in plaats van het schema/ breadboard/ icon symbool met inktscape aan te passen, lees ik in de svg file in, in een tekst editor en pas daar de teksten aan, interesse ;D dan zet ik de tekst versie van een svg file in dit draadje.Dan heb je het achteraf nog moeilijk gedaan ::) Na veel zoeken kwam ik er achter dat er voor DIP achtige dingen gewoon een kale DIP beschikbaar is die je kunt aanpassen en nummeren. Maar ook dat was best omslachtig. Vind het toch wel het slechtste punt van Fritzing :(
vr3 :
Het moet een flexibel bloksysteem worden, en als het nodig is kan ik het blok makkelijker uitbreiden.
(...)
de AAMS sturing word nu ontworpen als bloksysteem, waarbij elke Arduino(NANO) een blok is.
Is het flexibeler als elk blok apart een schakeleenheid vormt, of is dat zo omdat een shield per NANO niet meer tegelijk kan afhandelen, of heeft dat er niets mee te maken?Ik ben dan geen Paul en kan niet zijn exacte idee weergeven maar één Nano is meer dan krachtig genoeg om best wat blokken te doen. Maar dan heb je bijvoorbeeld ook te maken met alle bekabeling van al die blokken die naar één punt moet.
Je stelt je voor dat je per 2 blokken motordrivers hebt, waarom niet 1 per blok?De gebruikte motordrivers (die inderdaad een prima oplossing zijn) hebben al twee kanalen. Je kan er dus al twee motoren mee aansturen. Vandaar dat het mij logisch lijkt me Arduino ook twee (of een meervoud, maar twee is mooi modulair) aan blokken te laten doen.
Ik begrijp dat Timo voorstelt om de motordrivers per NANO (of pro mini) te rangschikken, en blokken per twee (of meer) per NANO onder te brengen. Dat is ongetwijfeld veel goedkoper.
Zouden er ook 6 blokken op een NANO kunnen? Wat vormt de inperking?Dat zou prima mogelijk zijn. De Arduino heeft standaard ook 6 PWM poorten dus dat komt goed uit. (Vergeet ik alleen even het feit dat je niet aan de frequentie van twee daarvan wilt zitten.) Alleen vormt alle IO die je nodig hebt dan ook al wel een enorme bottleneck. Twee blokken hebben nog beperkt aantal IO nodig waardoor je, eventueel met één of twee shiftregisters, wel klaar bent. Complexiteit neemt enorm toe terwijl een extra Nano eigenlijk niets kost.
Ik mompel ook maar wat, maar ja, ik zit met 20-30 blokken, en wat daarmee te doen.Met €1,75 per Nano of €1,20 voor een Pro Mini is dat ook best te overzien.
En een NANO per blok wordt dan ook weer begrotelijk (en hoe overzie je dat dan weer).
Als ik de schema's volg, dan rijg je de NANO's aan elkaar tot een soort netwerk. Daarbij is er eentje master, en de rest is slave. Lijkt mij dat de master ook de bezetmeldingen verwerkt en de seinen kleurt, waardoor de slaafjes uitvoerend werk verrichten op blokniveau.Dat is maar net hoe je het wilt. Je zou er voor kunnen kiezen alle slimmigheid in de master te bakken maar dat is niet heel modulair. Je kan ook voor multi-master gaan waarbij iedere node iedere andere node kan aanspreken. Of je laat de slaves alles afhandelen en laat een master berichten tussen slaves verzenden als blokken iets moeten uitwisselen. Laatste twee lijken me een stuk modulairder.
Je stelt je voor dat je per 2 blokken motordrivers hebt, waarom niet 1 per blok?
Ik begrijp dat Timo voorstelt om de motordrivers per NANO (of pro mini) te rangschikken, en blokken per twee (of meer) per NANO onder te brengen.
Dat is ongetwijfeld veel goedkoper.Zouden er ook 6 blokken op een NANO kunnen? Wat vormt de inperking?
Voor het schakelen van een relais heb je inderdaad een goeie voeding nodig. Maar ook genoeg ontkoppeling op de voeding. Een extra condensator kan helpen om de inschakelpuls op te vangen. Ook moet je nooit de on-board 5V regulator van de Arduino om andere dingen dan chips en een paar ledjes te voeden. Daarvoor is hij simpelweg te licht. Gebruik hiervoor een externe (DC-DC converter) regulator.Ikzelf heb 8 relais tegelijk gestuurd (Eerste testen met AAMS) ,de Arduino gaf geen krimp ook als ik alle 8 de relais tegelijk schakelde, het kan misschien wel van de Arduino uitvoering afhangen of het werk, ik heb de Arduino uitvoering gebruikt met de 28 pollig ATmega 328 in dil uitvoering, het kan zijn dat de Arduino's met de smd ATmega 328 chips dat niet kunnen.
Als voorbeeld neem ik even de schakeling "LM311 analog to digital converter" door de output van de print op een, laten we zeggen: Or of Xor poort te zetten kunnen we al een via een transistor op de uitgang van de Or of Xor poort een relais aansturen (even simpel gezien, het werk echter wel), het werkt zelfs al door een transistor type PNP op deze uitgang te zetten.
LET OP! dit is even simpel gedacht, maar het werk wel, probeer het maar eens uit als je het niet geloofd. (je kunt het ook testen met twee elektromotoren, wel even een transistor type PNP gebruiken! )
8x Analog in oa blokbezet melding (kan ook als digital in gebruikt worden)De Arduino heeft 14 digitale i/o ;) En als je er geen computer aan hangt kan je pin0 en pin1 ook prima voor andere zaken gebruiken. Maar natuurlijk zijn ze wel erg handig tijdens het debuggen maar eventueel zou je ze daarna ook gewoon als extra uitgang kunnen gebruiken.
13 digital i/o waarvan er twee nodig zijn voor de communicatie tussen de computer en Arduino
Er word in hetzelfde draadje beweerd dat de Arduino te weinig vermogen levert, om de uitgangen met meerdere relais te belasten, dat klopt niet,Sorry Paul om je uit je droom te helpen, dit klopt echt wel. En het heeft absoluut niets te maken met de gebruikte ATmega328 maar laat wel zien dat het je gebrek aan kennis is die hier praat. Natuurlijk hoef je niet overal het fijne van te weten, maar zomaar statements onderuit halen slaat dan natuurlijk nergens op. :-X
Ook werd er in dat topic geopperd dat je een Arduino gebruikt omdat je weinig kennis hebt van electronica.Paul, hier draai jij oorzaak en gevolg om waardoor het een drogreden is geworden. Wat Menno zeg dat de Arduino door veel mensen met minder verstand van Arduino wordt gebruikt is zeker waar. Daarvoor is de hele Arduino ook bedacht, om het laagdrempelig te maken. Maar dan mag je de stelling nog niet omdraaien, natuurlijk geeft het gebruik van Arduino niet aan dat je weinig verstand hebt van electronica. Maar een grote groep (en dat is de doelgroep) geldt dit natuurlijk wel voor. Zelf laat je ook af en toe zien dat je niet alle kennis van elektronica hebt ;) Maar is dit erg, nee, tuurlijk niet! We doen het toch ook deels om iets te leren? Daarvoor is iets als een forum juist zo mooi! Maar is het dan handig om ongenuanceerd uitspraken van mensen (met meer kennis) onderuit te schoppen, nee, zeker niet. ;)
[knip] alsof je de Arduino gebruikt omdat je minder verstand van electronica hebt, deze uitspraak slaat nergens op. :(