Doel:€250.00
Donaties:€130.00

Per saldo:€-120.00

Steun ons nu!

Laatst bijgewerkt
op 24-04-2024

Vacature: secretaris bestuur
Algemeen

De stichting

Recente berichten

19 Toen door Keska
Vandaag om 18:39:45
Modelbaan schaal H0 niet geheel sluiten in pc prog door Ronnor
Vandaag om 18:26:10
Toon hier je nieuwe (model-) spooraanwinst(en)... door Cegielski
Vandaag om 18:16:38
20 en 21 april MobExpo door class 37
Vandaag om 18:16:26
Baan 'begroenen', hoe, wat en waarmee? door Frank 123
Vandaag om 17:50:26
Piko lok digitaal rijdt direct weg door bellejt
Vandaag om 17:48:47
Bouw van postrijtuig P 7911-7920 (plan C) van FRIE door Rob Bennis
Vandaag om 17:45:39
Al mijn goede ideeën... door maartenvdb
Vandaag om 17:22:59
Raadplaatje door Benelux795
Vandaag om 17:18:39
Aachenau West door Montanbahn
Vandaag om 16:32:57
Gewoon wat busfoto's door mass am see
Vandaag om 16:27:11
diorama, voor lange treinen. door Wim Vink
Vandaag om 16:12:37
18 t/m 21 april Intermodellbau '24 Dortmund door Ronald Halma
Vandaag om 15:58:27
Ervaringen met veilingsites enzo (Marktplaats, Ebay, Catawiki, etc). door bask185
Vandaag om 15:50:37
Station Roodeschool door Ronald Halma
Vandaag om 14:40:57
Toon hier je pas gereed gekomen (model-)spoorbouwsels ... door Hans Reints
Vandaag om 14:34:08
NS 6000 (in schaal 0) door FritsT
Vandaag om 14:24:44
BMB-Module: “Corfe Castle Station” door Hans van de Burgt
Vandaag om 14:14:55
Onlangs gespot - gefotografeerd, de foto's door mass am see
Vandaag om 14:07:41
Frans/Belgisch H0e baantje door NS264
Vandaag om 12:57:17
hoe diep is de kuil van een 23 meter draaischijf door AlbertG
Vandaag om 12:10:11
US diorama in H0 door Wim Vink
Vandaag om 11:20:49
2nd Dutch US Convention, DRU Ulft NL 6/7 april 2024 door RBlok
Vandaag om 10:23:55
Cranicher Altbahn door Eric v C
Vandaag om 10:09:34
Pfarrerwinkel bahn door Eric v C
Vandaag om 09:59:38
Bruikbare etsplaten voor NS4000 en NS4700 tenders, en NS slijptrein? door 3dbuildr
Vandaag om 09:55:45
Ijzeren Rijn: militair transport door ijzeren rijn
Vandaag om 09:45:09
Kleine Baan in H0 (≤ 0.5m²) door spoorijzer
Vandaag om 09:35:37
Hengelo in 1981-1982, maar dan anders: Kassenberg in N door spoorijzer
Vandaag om 09:33:32
Mijn eerste H0-modeltreinbaan in aanbouw door Frank 123
24 april 2024, 22:51:27
  

Auteur Topic: Arduino analoge(!) modelbaan sturing  (gelezen 139439 keer)

De Stoker

  • Offline Offline
  • Berichten: 783
  • H0 - TC - Digirails - KL 8.2 1920-1950
Re: Arduino analoge(!) modelbaan sturing
« Reactie #45 Gepost op: 26 juni 2014, 08:32:51 »
Sterkte met je vader.

Ik zit zelf ook te denken over te stappen van PIC naar Arduino, maar die twee el. motors zijn die voor testen of hebben ze een andere funtie?

smits66

  • Offline Offline
  • Berichten: 543
  • Schaal 1:160, Arduino
Re: Arduino analoge(!) modelbaan sturing
« Reactie #46 Gepost op: 29 juni 2014, 22:38:12 »
hoi

Bedankt!

De Arduino is een makkelijke manier om microcontrollers te leren gebruiken.
Ik heb zelf pic processor gebruikt maar vond de atmel processoren prettiger werken ook was er voor de atmel processor (een arduino is een atmel microprocessor type atmega328 met een arduino bootloader)

Op het internet kon ik veel meer projecten met programma's en duidelijke uitleg vinden , voor een pic processor waren er minder projecten te vinden met uitleg , en programma's.

Voor de Arduino zijn er zeer veel toepassingen, onderdelen en shields te vinden op internet.

Voor de kosten hoef je het niet te laten een Arduino Uno kost ongeveer 7 a 10 euro en de verzendkosten zijn gratis,
en een protoshield kost tussen de 2 en de 7 euro.

Bekijk deze links maar eens en zoek op arduino op deze sites

Http://www.banggood.com
http://www.dx.com

De motoren gebruik ik om te testen of dit ontwerp goed is,  deze motoren zijn 5 volt en kunnen rechtstreeks via de usb poort gevoed worden, zodra ik er 12 volt op zet hoef ik allen maar een jumper te verwijderen zodat de voeding van de usb-poort los word gekoppelt van de motorsturing.

Als je de foto bekijkt zie je rechts de Arduino met protoshield zitten, links daarvan zit de motor sturing, en links van de motorsturing zitten de relais voor de blokken in en uit te schakelen, midden onder zit een lcd display.

Het test programma ziet er als volg uit.


#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   "); 
}

Vragen over het Arduino programma, stel ze.

Mocht er interesse zijn wil ik deze code proberen uit te leggen.

Mvg Paul Smits
« Laatst bewerkt op: 29 juni 2014, 22:58:56 door smits66 »
Üdvözlet Paul Smits.


bouw draadje "Laubenstein"

tuurtje

  • Offline Offline
  • Berichten: 4525
Re: Arduino analoge(!) modelbaan sturing
« Reactie #47 Gepost op: 29 juni 2014, 22:54:56 »
Hi Paul,

Heel veel sterkte met je vader. Dat zijn inderdaad de dagelijkse zaken van het leven die voorgaan.
Stel ging zaken uit waar je later over denkt van had ik maar...

Maar ik heb zeker interesse in de uitleg van de code

Groetjes

Arthur
A live performance so the whole world will see
I'm aligning the stars
Universal in art
See the god in me

De Stoker

  • Offline Offline
  • Berichten: 783
  • H0 - TC - Digirails - KL 8.2 1920-1950
Re: Arduino analoge(!) modelbaan sturing
« Reactie #48 Gepost op: 30 juni 2014, 08:49:53 »
Hallo Paul,

Dank voor de mooie uitleg, ook ik ben zeker geintereseerd in de verdere uitleg. De reden die je geeft voor de overstap zijn ook mijn overwegingen. Alleen al hier op het forum zijn een aantal mensen die mooie dingen hebben gedaan met zo'n Arduino.
Helaas staat alleen de zomervakantie voor de deur en breng een hoop tijd op de camping door en moet nog eens kijken of ik de komende maanden tijd heb om me er in te verdiepen maar de belangstelling is er zeker

Alleen is mijn insteek niet het besturen van de baan zelf, ik rij digitaal tegenwoordig, maar het aansturen van ....* op de baan.

*) dit kan van alles zijn.
« Laatst bewerkt op: 30 juni 2014, 08:51:35 door De Stoker »

dimo1_dimo1

  • Offline Offline
  • Berichten: 3378
Re: Arduino analoge(!) modelbaan sturing
« Reactie #49 Gepost op: 30 juni 2014, 09:56:08 »
Paul,
duidelijke code, zit alleen nog een schoonheidsfoutje in:
  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..
if is true op alles wat hoger is als 0 dus als serial.available groter is als 0 kom je in die if.
vervolgens staat verderop dus een if die altijd true zal zijn op dat punt, die if kan dus weg ;)
groeten,
Auke

Timo

  • Team encyclopedie
  • Offline Offline
  • Berichten: 4656
Re: Arduino analoge(!) modelbaan sturing
« Reactie #50 Gepost op: 30 juni 2014, 13:05:17 »
Hoi Paul,

Je bent leuk bezig! Zou ik je toch nog een paar tips mogen geven? Het is geen kritiek, maar meer om je code leesbaarder te houden / fouten te voorkomen enz.

Je bent nogal inconsequent met hoofdlettergebruik. Je schrijft bijvoorbeeld "Blok" maar ook "ledState" en "interval". Wat je kiest is aan jou maar voor de leesbaarheid is het wel handig een soort systeem te hebben. Wat vaak gebruikt wordt is dat je een variabele altijd laat beginnen met een kleine letter en een hoofdletter gebruikt voor het nieuwe woord in de variabele. Zoals je dus gedaan hebt met "ledState" en dus "blok". Een define wordt vervolgens volledig in CAPS geschreven, kan je aan de code zien dat je daar niet een waarde aan kan toekennen in de code. Je zou hetzelfde kunnen doen voor const variabele, die kan je immers ook niet wijzigen. (Of je laat een const wel beginnen met een hoofdletter bijvoorbeeld.) Wat je kiest is aan jou maar alles volgens hetzelfde systeem houdt het leesbaar en voorkomt fouten met hoofdletters.

Verder is hoe je pinnen toe wijst aan een naam nogal verschillend. De ene keer doe je dat met een define, volgende keer met een constante en dan weer met een variabele. Aangezien je ze altijd vast gebruikt is het goed om geen variabele te gebruiken, je past ze immers (on the run) niet aan. Aangezien Arduino een const verkiest boven een define is dat de manier. Dus alle pinnen toewijzen met een const int  Rel1 = 6. Ik zou dan ook de define regels voor je LCD aanpassen naar const. (Overigens kan je een pin vrij maken voor de enable pin van je LCD gewoon aan de 5V te hangen ipv aan een Arduino pin.)

Voor de leesbaarheid kan je wat kopjes invoegen en de dingen iets meer groeperen. Dus een kopje "Pin toewijzing" en daar alle const neerzetten voor de pintoewijzingen. Nu heb je een blokje pintoewijzingen, dan weer een algemene variabele dan weer een pin toewijzing enz. Het zoekt nu wat lastig als je dat wilt aanpassen. Zelf vind ik dit een duidelijke manier voor kopjes:
/***** Global vars ***********************************************/Of zoals het in veel Arduino libraries gedaan wordt
/******************************************************************************
 * Definitions
 ******************************************************************************/

Dat brengt me naar instellingen of definitions. In de functie wacht heb je staan"long wacht = 7500". Dit is een instelling, je past hem in de functie zelf nooit aan. Je zou dit boven in je code (bijvoorbeeld onder het kopje definitions) kunnen declareren. Daar kan je het makkelijk aanpassen als je langer of korter wilt wachten zonder de hele code door te lezen. Ook is het iets dat niet wijzigt on the run, je kan er een const van maken, scheelt RAM en is iets sneller. Ook is een long wel erg groot voor het getal 7500, een int voldoet, zeker als je hem unsigned maakt (tot waarde 65.535). Dus iets als boven in je code "const unsigned int WachtTrein = 7500"

currentMillis en previousMillis. Je hebt nu ook versies met een 1. Allereerst, een foutje in de code, in de functie wacht staat  "unsigned long currentMillis 1 = millis();", met een spatie tussen het woord en de 1, dit zal dus een fout geven. Ook is het niet nodig om er een 1 aan toe te voegen, je kunt gewoon currentMillis gebruiken. De andere currentmillis is namelijk geen global variable dus zal in de functie wacht helemaal niet bestaan. previousMillis daarentegen wel. Maar een naam als priviousMillis1 zegt niet zo veel. Ik zou dus dingen gebruiken als "previousMillisWacht" en "previousMillisLed". Duidelijkere naam en je hoeft niet te denken, "was wacht nu "previousMillis1" of "previousMillis2"?

In de functie blok doe je wat met millis maar eigenlijk niet... Je hebt staan:
    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.

Waarom gebruik je in je code nog delay? Deze functie houdt de hele flow van je programma op, er kan tijdens een delay niets anders gebeuren (afgezien van een interrupt). De constructie met current en previous millis is veel beter, het programma blijft gewoon door gaan.

Ook voor de leesbaarheid, probeer een tab te gebruiken ipv een spatie om in te springen bij dingen als een if statement.

In je loop schijf je mooi van een case. Alleen gebruik je hier geen case maar een hoop if. Nu is dit niet fout maar dit zou juist DE plaats zijn waar je een case zou kunnen toepassen. Natuurlijk is dit niet verplicht en voldoet de if ook prima. Ik zou dan alleen wel alle if's vanaf case 2 vervangen in een else if. Op deze manier zal de Arduino stoppen met checken op de volgende cases zodra hij een kloppende heeft gevonden. Immers, als incommingByte als 2 is geweest kan hij niet ook 3, 4, 5 of 6 geweest zijn. Waarom zou je hier dan nog op checken? Met een else if voorkom je dit. Zodra er een kloppende (else) if gevonden is worden de rest van de else if's overgeslagen.

Nog één ding waar je op moet letter met gebruik van millis. Deze functie is niet eindig. Volgens de reference duurt het ongeveer 50 dagen voor de millis een overflow doet. Nu verwacht ik wel dat je in de tussentijd het systeem een keer uit gezet hebt maar het is toch wijs om in je achterhoofd te houden. Dingen als "if(currentMillis1 - previousMillis1 > wacht)" zullen dan opeens niet meer werken omdat millis weer gereset is naar 0 en dus wel een hele tijd kleiner is dan previous. Ipv lastige constructies om hier rekening meer te houden in de if check zou je kunnen kijken of het systeem al lang loopt (bijvoorbeeld langer dan 45 dagen) en een melding laten weergeven dat het wel eens tijd wordt om het systeem een reset te geven. Ook valt mij op dat je voor currentMillis wel netjes een unsigned long gebruikt maar dit voor previous niet doet. Millis geeft een unsigned long terug. Met een signed (de standaard als je er geen unsigned voor zet) heb je maar een half zo groot positief bereik als dat je met een unsigned hebt. Dus na 25 dagen kom je op deze manier al in de problemen. Alle variabele voor millis waardes zouden dus unsigned moeten zijn.

Het printen van tekst, of eigenlijk het onthouden van tekst, kost een Arduino veel geheugen. Nu gebruik je veel dezelfde stukken tekst. "motor B: Low speed" en "motor B: half speed" bestaat voor een groot deel uit dezelfde tekst. Deze twee teksten worden nu als twee losse strings in de Arduino opgeslagen en kosten zo 18 + 19 = 37 tekens (=bytes). Als je iets doet als
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.



Dan nog een voetnote van mij, dit alles is geen negatieve kritiek! ;) Snap dat het zo over kan komen omdat het nogal een lap tekst is geworden. Ik vind het leuk om te zien dat iemand zo fijn bezig is met nieuwe dingen bekijken en dingen te maken. Het is allemaal bedoelt om van te leren en vooral om te zorgen dat je geen onverklaarbare fouten krijgt in je code. Niets is zo vervelend als een hele avond debuggen door een stomme fout, ik spreek uit ervaring  ::)

Veel succes verder!

Timo
« Laatst bewerkt op: 30 juni 2014, 13:08:03 door Timo »
Verzonden vanaf mijn desktop met Firefox

smits66

  • Offline Offline
  • Berichten: 543
  • Schaal 1:160, Arduino
Re: Arduino analoge(!) modelbaan sturing
« Reactie #51 Gepost op: 10 juli 2014, 22:50:59 »
Hoi,

Het heeft even geduurd voor ik de kans had om het programma te verbeteren, alle suggesties voor verbetering zijn zeer welkom.

Het eerste programma bestond uit een aantal losse programma delen die ik op het internet vond, vandaar dat het programma er enigszins rommelig er uit zag, ik heb het ondertussen aangepast, het programma kan er hier en daar er nog wat rommelig uit zien. 

Ik heb alleen een probleem, een wacht cyclus programmeren met het millis() comando werk op de een of andere manier niet.

De eerste millis() comando  in de void loop(){  werk wel(led op poort 13 word aangestuurd door een korte puls) maar de rest werk niet.  ??? ???
Iemand enig idee, ook andere ideeën en oplossingen zijn welkom.

#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   "); 
}
     

Het programma werk als volgt :

De bediening van de treinbaan gaat via de serial monitor van het Arduino programma  of via een terminal programma, via de serial monitor/ terminal geef je een commando, deze commando's staan op het scherm.

Je kan in het vrije blok een trein laten in rijden en stoppen ,de trein komt het vrije blok binnen rijden en kan dan het blok bezet melden en na een x-aantal seconden komt de trein tot stilstand.(automatische mode nog niet ingebouwd)

Als eerst geef je het blok vrij.
                                                          commando 1:  blok 1 vrij
                                                          commando 5: blok 2 vrij

Dan kan je toestemming geven zodat de trein vertrekt.

                                                            commando 7: trein 1 kan vertrekken.
                                                            commando 3: trein 2 kan vertrekken.

Het is nu nog zo dat beide treinen tegelijk kunnen vertrekken als je beide blokken vrij geeft, dit is nu nog niet beveiligd, moet er nog worden ingebouwd (suggesties zijn welkom).

Trein laten stoppen (werk nog niet goed, de af rem tijd werk nog niet goed)

                                                            commando 4:  blok 1  trein 1 laten afremmen om te stoppen.
                                                            commando 8:  blok 2  trein 2 laten afremmen om te stoppen.
                                                           
Blok bezet melden  (werk nog niet goed, de wachttijd werk nog niet goed)

                                                             commando 2:  blok 1  bezet melden en trein laten wachten tot vertrek.
                                                             commando 6:  blok 2 bezet melden en trein latten wachten tot vertrek.

Algehele noodstop                         
                                                            commando 9: blok 1 en 2 bezet melden en trein 1 en 2 laten stoppen.

Deze opzet is alleen nog handbediening een automatische bediening word later ingebouwd (uitgebreide versie) , eerst dit gedeelte van het programma goed werkend krijgen.

Wat wil ik er op termijn nog bij bouwen:

- Blok bezet melding via reed-contacten.
- De seinen via dit programma tegelijk met de commando's laten werken. (bezet- rood en vrij- groen, worden alleen blokseinen gebruikt ook zichtbaar op het bedienings- paneel)
- Het programma ook via een bedienings- paneel kunnen bedienen.

Specificaties van het Arduino analoge modelbaan sturing :

* Test versie Arduino uno (atmega 328p) 16 digital i/o en 6 analoog IN waarvan twee analoog IN gebruikt worden voor I2C.

   1x   Motorsturing L298
   1x  Relais board 2 voudig
   1x  Relaisboard enkelvoudig
   1x   I2C lcd display 16x2

* Uitgebreide versie Arduino Atmega (2560)   53 i/o en 16 analoog in en aparte I2C

   4x Motorsturing L298 ( 8 blokken)
   2x Relaisboard 4 voudig of 1x 8 voudig relaisboard.
   1x Relaisboard enkelvoudig
   1x I2C lcd display 20x4
   1x Bluetooth verbinding met computer.
   2x Poort expander voor bedienings- paneel

Aan de uitgebreide versie ga ik pas beginnen als het programma in de test versie goed is.
De meeste onderdelen van de uitgebreide versie heb ik in mijn bezit (verzamelwoede ::) )

Mvg Paul  :)
« Laatst bewerkt op: 10 juli 2014, 23:00:20 door smits66 »
Üdvözlet Paul Smits.


bouw draadje "Laubenstein"

dimo1_dimo1

  • Offline Offline
  • Berichten: 3378
Re: Arduino analoge(!) modelbaan sturing
« Reactie #52 Gepost op: 10 juli 2014, 23:14:26 »
Volgens mij is het probleem dat je wacht functie nu niet meer blocked waardoor de rest van de code nog steeds wordt uitgevoerd..
Kan zijn dat ik het niet hoef heb gezien want heb vluchtig gekeken
groeten,
Auke

Timo

  • Team encyclopedie
  • Offline Offline
  • Berichten: 4656
Re: Arduino analoge(!) modelbaan sturing
« Reactie #53 Gepost op: 14 juli 2014, 16:15:16 »
Je probleem met je Millis zit er in dat inderdaad je programma doorloopt. Maar dat is nu juist de bedoeling, je wilt niet dat de Arduino de 5 seconde wacht uit zijn neus loopt te vreten zoals gebeurd bij een delay(). Je functie wacht() is dan ook net correct. Wat je wilt doen is net als bij de led toggle de hele tijd checken of het aantal millis al voorbij is.

Dus om een wacht op te roepen doe je iets als
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
)

In je loop roep je nu de hele tijd een check op om te kijken of je wachten en zo ja ben je klaar met wachten? Dat ziet er dan uit als
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
*/
}
}
}

Let wel op, per actie waar je op wilt wachten heb je dus een functie nodig. Dus wil je kunnen wachten op blok en en op blok 2 heb je deze functies twee keer nodig met ieder dus een previousMillisWacht en wachtTrein.

Omdat je al aardig begint te zien dat je nu dingen dubbel begint te doen (namelijk voor blok 1 en voor blok 2) zou je kunnen gaan kijken om dingen in classe te gaan schrijven. Dit is DE kracht van C++. Je kan dan een classe (= blauwdruk) van een blok maken. Vervolgens maak je voor elk blok dat je hebt een instantie van die blauwdruk met de juiste pinnen en settings.

Of, als dat nog even één stap te ver is (of je geen C++ wilt/kan gebruiken (ik schrijf zelf veel in C waar een classe niet mogelijk is)) kan je gebruik maken van array's voor dingen en functies maken waarin je aan geeft om welk blok het gaat. Een voorbeeld zou het wachten zijn. Je hebt denk ik maar één wacht functie per blok nodig. Waar je dan per blok op wacht is aan jou. Je zou de wacht functie schaalbaar kunnen maken door het volgende te doen:

Variable declaratie:
#DEFINE NRBLOKKEN 2 //Aantal blokken, nu dus maar twee
previousMillisWacht[NRBLOKKEN];
wachtState[NRBLOKKEN];
wachtTrein[NRBLOKKEN];

wacht()
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
)

wachtCheck() (dit dus in je main loop)
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
*/
}
}
}
}
}

Omdat je in het begin alle wachtState LOW wilt hebben en dus alle alle entries in je array LOW wilt hebben maak je hier een functie van:
//Maakt alle wachtState LOW
void initWachtState(){
for(unsigned int i = 0; x < NRBLOKKEN; i++){
wachtState[i] = LOW;
}
}

Ipv
wachtState = LOW;doe je nu
initWachtState()
Zoals je kunt zien niet heel veel meer code maar is het op te schalen tot zo veel blokken als je wilt zonder dat je enorm veel code extra moet maken. Daar ligt de hele kracht van functies. Als je twee keer bijna hetzelfde aan het opschrijven bent moet je bedenken of je hier niet één functie van kunt maken.

Nog weer een kleine opmerking over tekst. Je gebruikt in je prints heel veel tekst. Maar ook heel veel spaties! Dit neemt erg veel ruimte in op je Arduino. Ik kan nu even niet zien hoe vol je Arduino zit (heb niet de LCD I2C lib staan) maar de ruimte op een Arduino in eindig. Nu kom je er nog wel mee weg maar in de toekomst kan dit nog wel eens een probleem vormen.

Ook zou ik als ik jou was nog beter kijken naar hoe je opmaak van je code is. Gebruik een TAB om in te springen in je code, geen spatie. En vooral, spring consequent in. Laat ALLES wat binnen een if/fucntie/else/for/enz valt inspringen, ook commentaar. Maar ook, spring terug als iets eindigt. Een sluit } op dezelfde hoogte als de if/fucntie/else/for/enz die hem liet beginnen maakt snel duidelijk waar hij bij hoort (en of je er dus geen vergeet / teveel plaatst). Zo kan je sneller zien waar het bij hoort. Ik moest nu best zoeken waar iets begin en stopte enz.


Succes verder met puzzelen!

Timo

Disclaimer:  ;D
Ik hebt de code alleen zo geschreven en niet getest/gecompiled. Het moet dus worden gezien als pseudo code wat kan dienen als basis voor je eigen programma.

Verzonden vanaf mijn desktop met Firefox

smits66

  • Offline Offline
  • Berichten: 543
  • Schaal 1:160, Arduino
Re: Arduino analoge(!) modelbaan sturing
« Reactie #54 Gepost op: 14 juli 2014, 22:34:30 »
Hoi, volgers

@Timo

Bedankt voor je input (y)

Met de uitleg die gegeven hebt kan ik weer verder puzzelen :P ;D
De code is nu nog in ontwerp/puzzel fase, als ik zover ben dat de code redelijk goed is ga ik de code in een nieuwe sketch schrijven en ga het zo structureel mogelijk doen inclusief het gebruik van de TAB-toets, maar zover ben ik nog niet.
Er word nog veel veranderd in de code, zodat het wat lastig word om alle spaties te gaan omzetten naar TAB's.

Ik zit nog te bedenken of ik 16 blokken of 8 blokken wil gaan sturen, voor het schrijven van de software zal dat niet veel uitmaken.
Zoals jullie weten of niet weten worden de blokken aangestuurd door een  relais en worden de blokken  vooralsnog handmatig getuurd later wil ik dit  zowel handmatig als automatisch doen.

De treinen worden met een L298 motorsturing gestuurd voor het sturen van 16 blokken heb ik dan 8 motor sturingen  van het type L298 nodig, zou ik 8 blokken maken heb ik maar 4 motorsturingen van het type L298 nodig.
De blokken kan ik waarschijnlijk via een shift register aansturen met drie stuur lijnen kan ik 8 relais sturen of dat goed werk moet ik nog gaan uitproberen.
Ik moet mijn gedachten er maar eens over laten gaan of ik 16 of 8 blokken ga maken.

Ook wil ik wissels gaan sturen zowel handmatig als automatisch, hiervoor wil ik een ic van het type uln2003A gebruiken die via een shift register word aangestuurd.
Dit projectje ga ik binnenkort mee beginnen (word vervolgd), ook deze sturing moet in het Arduino analoge modelbaan sturing worden ingebouwd.

Om dat alles in goede banen te leiden zal nog niet meevallen.

Voor de hoofdsturing word een Arduino Mega gebruikt, deze heeft 53 digilale I/O poorten.

Mvg Paul  :)

 
Üdvözlet Paul Smits.


bouw draadje "Laubenstein"

Timo

  • Team encyclopedie
  • Offline Offline
  • Berichten: 4656
Re: Arduino analoge(!) modelbaan sturing
« Reactie #55 Gepost op: 15 juli 2014, 10:18:07 »
Hoi Paul,

Ik zou je dan wel aanraden bij wijzigingen wel goed op het gebruik van de tab te letten. De leesbaarheid is juist in de ontwerpfase erg belangrijk. Je zou niet de eerste zijne die daardoor niet ziet dat een regel code wel binnen een if valt  :P Zo uit me hoofd ondersteund de Arduino IDE ook het tab'en van een blok. Dus een paar regels code selecteren en dan op tab drukken, het hele blok wordt dan netjes ingetabd. Door de shift tegelijk in te drukke met de tab doe je het omgekeerde, zo haal je van een blok de tab weg. Erg handige functie als je code heen en weer verplaatst  ;D

Toch is me nog niet duidelijk hoe je de blokken wilt aansturen. Ben je nu van plan de motordriver te gebruiken of nu relais? Beide lijkt me niet nodig...

De ULN2003 is prima voor wissels en seinen. En hoe je deze aanstuurt is aan jou. Arduino pin, shift register of port extender zal allemaal werken. Wel zou ik twee uitgangen van de ULN combineren tot 1 uitgang van 1A voor de wissels. 500mA kan wat krap zijne voor wissels. Zijne er al kant en klare shields met de ULN verkrijgbaar of ga je hiervoor zelf aan de slag met de soldeerbout?


Timo
Verzonden vanaf mijn desktop met Firefox

smits66

  • Offline Offline
  • Berichten: 543
  • Schaal 1:160, Arduino
Re: Arduino analoge(!) modelbaan sturing
« Reactie #56 Gepost op: 20 juli 2014, 21:55:18 »
Hoi,

@Timo

Het is de bedoeling om de motordrivers en de relais beide te gebruiken, de relais zijn voor de stations/uitwijk sporen.
Deze sturing word alleen gebruikt als de baan in handbediening staat.

Als het niet duidelijk is.

De werking is als volgt :

De hoofdbaan heeft een eigen motordriver en is in twee blokken verdeeld  blok1 en blok 2, de stationssporen hebben een eigen motordriver blok 1a en blok 2a  deze blokken worden gestuurd door de relais, de treinen op de hoofdbaan kunnen doorrijden zonder dat het invloed  op de stationssporen heeft, daar deze afgeschakeld zijn door de relais, voor ik blok 1 kan oprijden moet ik de hoofdbaan in de juiste rij richting zetten voordat ik blok 1a kan verlaten, om eventuele kortsluiting te voorkomen gebruik ik deze blok relais.

Dit programma is specifiek voor handbediening , voor een automatische sturing moet ik nog veel uitzoeken.
Ik hoop dat het mogelijk is om in een programma zowel handbediening als automatische bediening te programmeren.

Zijn er routines om bij het starten van het Arduino programma te kiezen tussen twee functies binnen het programma, met behulp van een standaard tuimelschakelaar? ::)

Ik heb al een poging gewaagt maar het werk niet  ???

Omdat deze keuze maar een keer gemaakt hoeft gemaakt te worden heb ik de code voor de keuze in  void setup() gezet.

// 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);
}

Mvg Paul  :)
Üdvözlet Paul Smits.


bouw draadje "Laubenstein"

memen

  • Offline Offline
  • Berichten: 228
  • Märklin H0 - digitaal
    • LocoNet Bedieningspaneel
Re: Arduino analoge(!) modelbaan sturing
« Reactie #57 Gepost op: 20 juli 2014, 23:13:56 »
'if (keuze == high)' kan weggelaten worden toch?

En volgens mij moet de '}' die nu voor 'hand()' staat, achter 'hand()' komen. Dus:

If(keuze == LOW)
     {
         automatisch();
      }
Else
      {
        hand();
       }

Kan zijn dat ik het fout heb hoor, ik ben nog maar net begonnen met c programmeren.

Groeten,

Rauke


Verstuurd van mijn GT-S7500 met Tapatalk
DB 1970 - Esu Ecos I - S88 - Zelfbouw LocoNet Bedieningspaneel - DCC, RailCom, Motorola, mfx

smits66

  • Offline Offline
  • Berichten: 543
  • Schaal 1:160, Arduino
Re: Arduino analoge(!) modelbaan sturing
« Reactie #58 Gepost op: 20 juli 2014, 23:16:03 »
Hoi,
@ Rauke

Bedankt voor je reactie  (y)
Ik ga het nog even testen of het werk zoals jij schrijft.
Bedank voor je tip het werk nu wel goed (y)

@Allen

Ik ben nog even verder gegaan met testen, ik heb nu het case statement gebruikt.
Het werk nu wel, alleen vraag ik mij af of het kwaad kan als ik een poort lang 'HIGH' hou met behulp van een tuimel schakelaar ::)

Dan heb ik meteen een volgende vraag ik gebruik case 0 en case 1 is het mogelijk dat ik in case 0 de broncode set van de automatische sturing en in case 1 de broncode van de hand bediening zet, zonder dat het elkaar in de weg zit?


// 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;
  }   
}


Ik hoop dat er mensen zijn die mij een antwoord op mijn vragen kunnen geven ::)

Mvg Paul :)
« Laatst bewerkt op: 20 juli 2014, 23:31:01 door smits66. Reden: aanvulling reactie »
Üdvözlet Paul Smits.


bouw draadje "Laubenstein"

dimo1_dimo1

  • Offline Offline
  • Berichten: 3378
Re: Arduino analoge(!) modelbaan sturing
« Reactie #59 Gepost op: 21 juli 2014, 08:23:28 »
Ik zou een tuimelschakelaar aansluiten met twee pinnen, de een op de digitale poort, de andere naar ground..
Dan zet je in de code tijdens de set-up die pin hoog en kan je hem met de schakelaar laag trekken.. Dan hoef je namelijk geen weerstand te gebruiken..
Als je de pin hoog wil maken met een schakelaar zou je een 10k weerstand tussen de 5v en de schakelaar moeten doen om te voorkomen dat je de poort stuk maakt
groeten,
Auke