Doel:€250.00
Donaties:€50.00

Per saldo:€-200.00

Steun ons nu!

Laatst bijgewerkt
op 03-01-2024

Vacature: secretaris bestuur
Algemeen

De stichting

Recente berichten

Geluid NS Mat'46 vs NS Mat'54 door Rob Bennis
Vandaag om 21:54:12
Engelse wagon uit 1930 opgegraven in Antwerpen door willem2
Vandaag om 21:52:45
NS GLY omspuiten en opschriften door Rob Ellerman
Vandaag om 21:45:55
De Hondsrugbaan door cor_b
Vandaag om 21:40:07
welk jaar ging Marklin OVP voor wagons van blauw naar wit door Railman
Vandaag om 21:36:50
Mallnitzer Tauernbahnstrecke ÖBB N Spoor door Schachbrett
Vandaag om 21:22:18
Mijn eerste H0-modeltreinbaan in aanbouw door puntenglijder
Vandaag om 21:15:13
LokSound 4 decoders, files verbeteren (voor Roco b.v. TEE RAm, NS2400, etc) door mamory
Vandaag om 21:13:06
Bouw van materieel 40 treinstellen door Rob Bennis
Vandaag om 21:09:04
Gebruik je Arduino zonder te "programmeren" ;) door Menno
Vandaag om 20:58:29
30 maart Modelspoorbeurs Houten & HCC Kennisdag door basjuh1981
Vandaag om 20:54:43
US diorama in H0 door basjuh1981
Vandaag om 20:52:48
Raadplaatje door eemstede
Vandaag om 20:43:38
Hengelo in 1981-1982, maar dan anders: Kassenberg in N door 1200blauw
Vandaag om 20:32:41
Onlangs gespot - gefotografeerd, de foto's door eemstede
Vandaag om 20:31:17
Welke Vallejo kleur voor drijfstangen van een DB stoomlocomotief? door Ronald69
Vandaag om 20:00:39
Toon hier je nieuwe (model-) spooraanwinst(en)... door arnout
Vandaag om 19:53:27
Punt- en hartstukken door Klaas Zondervan
Vandaag om 19:41:21
MARDEC, de Multifunctionele ARduino dcc DECoder. door bord4kop
Vandaag om 19:34:37
De (3d) knutsels van Ronald. door gdh
Vandaag om 19:22:56
Piko NS 2015 stroomafname probleem door Ben
Vandaag om 19:08:30
Bauarbeiten im gange door ruudns
Vandaag om 18:50:26
HSM D1715 door vpeters1984
Vandaag om 17:34:25
Beekdaelen in H0 door Stieven76
Vandaag om 17:17:41
Al mijn goede ideeën... door Monobrachius
Vandaag om 17:10:33
Ombouw/Pimpen Bolle neuzen door bollen neus
Vandaag om 15:58:15
Kleine Baan in H0 (≤ 0.5m²) door Jack Black (NS1220)
Vandaag om 15:06:14
U-vorm beperkte ruimte (H0 C-rails) door Jelmer
Vandaag om 14:58:04
Onlangs gespot - gefotografeerd, de links door Jeroen Water
Vandaag om 14:33:00
N spur scenery elementen maken van gips of klei? door Dave.......
Vandaag om 14:30:06
  

Auteur Topic: Tonen daadwerkelijke snelheid.  (gelezen 36490 keer)

peterha

  • Offline Offline
  • Berichten: 1100
Re: Tonen daadwerkelijke snelheid.
« Reactie #150 Gepost op: 27 mei 2015, 22:58:27 »
@Max,
Bedankt voor het aanpassen, zal morgen de afstand aanpassen en het testen.
Dat blank laten verward zou kunnen worden met defect, realiseerde ik me ook.
Misschien is dan een optie om maar twee (middelste) streepjes te laten zien " -- ", al dan niet knipperend.

@Timo,
Het grootste deel van mijn blokken -en dan praat ik over de hoofdbaan met doorgaande sporen- hebben maar één melder. De stations- en opstelsporen hebben twee melders, maar die worden niet gebruikt voor deze meting.
Daarvoor gebruik ik blokken in de hoofdbaan, omdat daar de treinen op hun maximale snelheid (kunnen) rijden.
Behalve natuurlijk als er direct in het volgende blok nog een trein rijdt.  ;D

Gr. Peter
Met vriendelijke groet,
Peter

peterha

  • Offline Offline
  • Berichten: 1100
Re: Tonen daadwerkelijke snelheid.
« Reactie #151 Gepost op: 28 mei 2015, 09:52:17 »
Max,

Vanmorgen even een eerste testje gedaan en dat zag er goed uit.
Je hebt nu de displaytijd aangepast zodat deze de snelheid toont, zolang de 2e bezetmelder actief is?

Moet nog testen wat er gebeurt als trein het meetblok al heeft verlaten en een trein al wel dat blok binnenrijdt.
Ook nog geen "    " display kunnen simuleren.

Echter, vandaag heb ik mijn kleinzoontje om op te passen, dus niet veel tijd om rustig en uitgebreid te testen.
Zal pas weer in de loop van de middag kunnen  :(

Met vriendelijke groet,
Peter

Max Roodveldt

  • Offline Offline
  • Berichten: 258
  • 't is maar 'n spelletje...
Re: Tonen daadwerkelijke snelheid.
« Reactie #152 Gepost op: 28 mei 2015, 10:05:01 »
Je hebt nu de displaytijd aangepast zodat deze de snelheid toont, zolang de 2e bezetmelder actief is?
Inderdaad...  8)

Citaat
Echter, vandaag heb ik mijn kleinzoontje om op te passen, dus niet veel tijd om rustig en uitgebreid te testen.
Zal pas weer in de loop van de middag kunnen  :(
;D Je bent opa of je bent 't niet... ;D

mvg
"And these visions of Johanna are now all that remain" - Bob Dylan (1966)

gvandersel

  • HCC!m maar toch Selectrix (RMX)
  • Offline Offline
  • Berichten: 3602
  • Als het maar elektrisch is.
    • Homepage Gerard van der Sel
Re: Tonen daadwerkelijke snelheid.
« Reactie #153 Gepost op: 28 mei 2015, 14:50:48 »
@Timo,

DEFINE definieert TEST, maar kan geen waarde toekennen. Dus als je zoiets als jij wilt doen, doe het dan alsvolgt:

#DEFINE TEST1
;#DEFINE TEST2

#if (TEST1)
  ; Doe iets voor TEST1
#endif
#if (TEST2)
  ; Doe iets voor TEST2
#endif

Groet,

Gerard van der Sel.
Holzburg (IIIb/IVa) schaal N.
Kijk ook eens bij de bouw en lees de avonturen.

spock

  • Offline Offline
  • Berichten: 652
Re: Tonen daadwerkelijke snelheid.
« Reactie #154 Gepost op: 28 mei 2015, 15:45:07 »
Ik gebruik hiervoor het #ifdef directive

#DEFINE TEST1    1
;#DEFINE TEST2    1

#ifdef TEST1
  ; Doe iets voor TEST1
#endif
#ifdef TEST2
  ; Doe iets voor TEST2
#endif
« Laatst bewerkt op: 29 mei 2015, 00:00:26 door spock. Reden: fout in voorbeeld »

gvandersel

  • HCC!m maar toch Selectrix (RMX)
  • Offline Offline
  • Berichten: 3602
  • Als het maar elektrisch is.
    • Homepage Gerard van der Sel
Re: Tonen daadwerkelijke snelheid.
« Reactie #155 Gepost op: 28 mei 2015, 19:24:22 »
Spock,

Je hebt helemaal gelijk. Doe ik in de codefiles ook :-[

Groet,

Gerard van der Sel.
Holzburg (IIIb/IVa) schaal N.
Kijk ook eens bij de bouw en lees de avonturen.

peterha

  • Offline Offline
  • Berichten: 1100
Re: Tonen daadwerkelijke snelheid.
« Reactie #156 Gepost op: 28 mei 2015, 19:31:56 »
Hallo Max,

Daarnet even een uurtje getest, maar ik denk dat we 'm nu wel hebben.  (y)
De metingen met een losse loc, een korte trein en een lange trein gingen allemaal goed.

Het enige is -vooralsnog- dat, wanneer 2 treinen achter elkaar rijden met verschillende topsnelheden en de langzamere rijdt voor, dat dan de snellere trein moet afremmen. Als dit gebeurt wanneer voor trein 1 een meting plaatsvindt en de snellere trein moet afremmen en gaat versnellen wanneer sector 2 vrijkomt (en trein 2 dus niet met volle snelheid het blok/meettraject kan berijden), is het dan even opletten.

Daarentegen zijn er genoeg momenten waarop de metingen wel goed gedaan zullen worden.

Heb ook geconstateerd dat als trein A nog in sector 2 rijdt en trein B gaat al sector 1 binnen, dat dan ook een geldige meting plaatsvindt, al zal de gemeten snelheid dan niet correct zijn. Maar dat is dan maar zo.

Alternatief is: korter meettraject met IR of LDR.
Maar voorlopig ben ik met deze oplossing zeer tevreden.  :)

De waarden van valSect1 en valSect 2 schommelen tussen 999 en 1011, met een gemiddelde van 1003. Zijn toch mooie waarden?

Ik heb er nu 47k weerstanden tussen zitten. Dit is nog steeds een goede waarde?

Nogmaals: tot nu toe gaan de metingen goed en ben ik zeer tevreden.
Alvast erg bedankt voor het vele werk dat je tot nu toe (ook voor mij) gedaan hebt.  (y) (y)
Moet er nu nog meer gebeuren?

Gr. Peter
Met vriendelijke groet,
Peter

Max Roodveldt

  • Offline Offline
  • Berichten: 258
  • 't is maar 'n spelletje...
Re: Tonen daadwerkelijke snelheid.
« Reactie #157 Gepost op: 28 mei 2015, 20:05:39 »
Daarnet even een uurtje getest, maar ik denk dat we 'm nu wel hebben.  (y)
De metingen met een losse loc, een korte trein en een lange trein gingen allemaal goed.
Dat is mooi - om niet te zeggen heel mooi.  (y)

Citaat
Het enige is -vooralsnog- dat, wanneer 2 treinen achter elkaar rijden met verschillende topsnelheden en de langzamere rijdt voor, dat dan de snellere trein moet afremmen. Als dit gebeurt wanneer voor trein 1 een meting plaatsvindt en de snellere trein moet afremmen en gaat versnellen wanneer sector 2 vrijkomt (en trein 2 dus niet met volle snelheid het blok/meettraject kan berijden), is het dan even opletten.
Dat is logisch: om goed te kunnen meten moet de snelheid wel constant zijn. 8)

Citaat
Heb ook geconstateerd dat als trein A nog in sector 2 rijdt en trein B gaat al sector 1 binnen, dat dan ook een geldige meting plaatsvindt, al zal de gemeten snelheid dan niet correct zijn. Maar dat is dan maar zo.
Dat is dan fout - dat zal ik nakijken. ???

Citaat
De waarden van valSect1 en valSect 2 schommelen tussen 999 en 1011, met een gemiddelde van 1003. Zijn toch mooie waarden?
Ik heb er nu 47k weerstanden tussen zitten. Dit is nog steeds een goede waarde?
Dat is perfect - niets meer aan veranderen.

Citaat
Moet er nu nog meer gebeuren?
Ja. Als het gaat zoals ik hoop dat het gaat hebben we straks diverse stukjes schakeling en software voor verschillende situaties. Die moeten dan in elkaar geschoven worden tot een groot geheel - en daarna getest. Het zou plezierig zijn als je daar dan mee zou willen helpen. Mocht je in de tussentijd nog meer op- en aanmerkingen hebben - graag. Experimentjes als dit zijn heel leerzaam.
Het is een genoegen om met je samen te werken...  (y)

Met vriendelijke groet

ps - vergeet niet dat er met een Arduino nog veel meer leuke dingen kunnen...
"And these visions of Johanna are now all that remain" - Bob Dylan (1966)

Timo

  • Team encyclopedie
  • Offline Offline
  • Berichten: 4656
Re: Tonen daadwerkelijke snelheid.
« Reactie #158 Gepost op: 28 mei 2015, 21:04:22 »
@Gerard, dat is niet correct  ;) Define is oorspronkelijk bedoelt om iets te definen, dit mag een waarde zijn. Dus:
#define DIT_IS_EEN_DEFINE_MET_WAARDE_3 3
Zet je er niets echter is het gewoon 0. Hier kan je dus ook echt tests mee doen zoals ik wilde. (Een bekende is het testen op de Arduino versie met #if ARDUINO > 100 voor hoger dan versie 1.00.) Ook als ik het deed zoals Spock ging het fout. De reden dat ik voor een waarde ging is dat je dan niet per ongeluk tegenstrijdige defines kan doen (ook al zou ik dit kunnen opvangen door #ifdef TEST1 #elif defined(TEST2) #endif maar is meer werk :D ) Alleen schijnbaar zit er een "bug" in de IDE omdat deze door de war raakt. Dit omdat setup() en loop() eigenlijk 2 functies zijn die leven in main() en de IDE dus een nieuwe cpp file maakt. Zie hiervoor het Arduino forum waar ik een topic had geopend. Nu gelukkig opgelost (en zeer eenvoudig eigenlijk  ::) ).

Peter, leuk dat het nu werkt! Ik ben ondertussen ook weer verder gaan en werkt weer normaal. Zou je misschien mijn code ook eens willen testen?  ;D Ik heb nu ondersteuning voor twee schermen ingebouwd. Het Adafruit I2C 7-seg display dat jij gebruikt en een (goedkoop) I2C OLED scherm. Dit is het schermpje in het YouTube filmpje. Daarmee komt er ook extra informatie beschikbaar nu (gemiddelde snelheid, min en max). Het goedkope 7-segment scherm moet nog volgen.

Het enige is -vooralsnog- dat, wanneer 2 treinen achter elkaar rijden met verschillende topsnelheden en de langzamere rijdt voor, dat dan de snellere trein moet afremmen. Als dit gebeurt wanneer voor trein 1 een meting plaatsvindt en de snellere trein moet afremmen en gaat versnellen wanneer sector 2 vrijkomt (en trein 2 dus niet met volle snelheid het blok/meettraject kan berijden), is het dan even opletten.
Tja, als een trein afremt geeft het niet wat je wil nee :p Er is geen andere plaats waar je kunt meten? Je zou ook een extra sectie kunnen maken (stroomdetectie) en deze gebruiken. Als je dan wel een stuk hebt waar de trein altijd snel gaat.

@Max, je weet dat je ook het scherm zelf kan laten knipperen? Dit kan met 2Hz, 1Hz of 0,5Hz. En in mijn code heb ik (als ik het goed heb gedaan) gekozen voor "____" (streepjes laag) als hij idle (aan het wachten op een melding) is. En knippert hij "|----" of "----|" als er een meting gaande is, al naar gelang de richting. (Streep geeft locatie van de eerste melding aan.) Zou jij dit ook kunnen testen?

Goed, hierbij de code. Deze is ook (inclusief de libraries) hier te downloaden. Loop wel even de configuratie na. (Bedenk me nu dat hij op de verkeerde pinnen staat te letten. Even aanpassen naar A0 en A1.)
/***************************************************
SpeedOmeter v1.0 - Speedometer for modelrailroad
  Created by Timo Engelgeer (Septillion), May 28, 2015
Based on Speedometer bij Max Roodveldt
 
  Calculates the (scale) speed of a (model) train based on two
  detections on the layout. This can be any kind you like.

****************************************************/
#define SPEEDOMETER_VERSION "v1.0"
/***** Configuration *******************************
The Speedometer is made very versatile. So in order to make it work with your setup
you have to configure it. The next few blocks will guide you to the configuration.

-- Display --
Because you can use different display's with Speedometer you have to select the correct one.
1 SSD1306 128x64 OLED display (I2C, default adress 0x3C)
  2 Adafruit 7-segment display (I2C, default adress is 0x70)

****************************************************/
#define LCD_TYPE 2

/**-- Sensor --
  It doesn't matter what kind of sensor you use. This can be an active low (signal goes
  low when train passes) or active high (signal goes high when train passes).
 
  #define ACTIVE_LOW    for active low  (uncommented)
  //#define ACTIVE_LOW  for active high (commented)
 
  Analoog komt nog ;)
**/
#define ACTIVE_LOW

/**-- Pins --
  To which pins are the sensors connected? Left and Right respectively
**/
const byte InputL = 9;
const byte InputR = 10;

/**-- Settings --
  Distance =>     Distance between start of the first detector and
                  the start of the second (in mm)
  Scale =>        Scale of the layout
  TimeShowSpeed =>Time to show the speed after finishing the measurement (in ms)
  TimeOut =>      Time to ignore re-triggering the detector after
                  finishing measurement (in ms)
**/
unsigned int distance = 5000;
unsigned int scale = 87;

const unsigned int TimeShowSpeed = 5000;
const unsigned int TimeOut = 3000;

/**-- Done! --
  You are done. Upload the sketch!
**/

//SSD1306 based OLED display
#if (LCD_TYPE == 1)
  #include <SPI.h>
  #include <Wire.h>
  #include <Adafruit_GFX.h>
  #include <Adafruit_SSD1306.h>

  Adafruit_SSD1306 display(255);
  const byte I2CAdress = 0x3C;
 
  #define INFO_EXTEND

//Adafruit 7-segment I2C
#else if (LCD_TYPE == 2)
  #include <Wire.h>
  #include "Adafruit_LEDBackpack.h"
  #include "Adafruit_GFX.h"

  Adafruit_7segment display = Adafruit_7segment();
  const byte I2CAdress = 0x70;
  const byte DisplayBrightness = 7; // 0..15
#endif

/***** Global vars *********************************/
bool timerRuns = false; //Does the timer run?
bool direction = false; //In which direction? (false = to left, true = to right
bool ready = true;      //ready to start the clock?
byte displayScreen = 0; //Which screen is displayed last?

unsigned long startTime;      //Saved start time
unsigned long endTime;        //Saved end time
unsigned long showTimer =  -1;//Time when display started showing something

//Speed stats
unsigned int speed, maxSpeed, minSpeed, avgSpeed = 0;

/***** Default functions ***************************/

void setup() {
//Initialize the display
  displayInit();

  //Set the input acording to the setting
#if defined(ACTIVE_LOW)
pinMode(InputL, INPUT_PULLUP);
pinMode(InputR, INPUT_PULLUP);
#else
pinMode(InputL, INPUT);
pinMode(InputR, INPUT);
#endif
}

void loop(){
  //Check for a finished measurement
if(checkInput()){
    //If so, calculate the speed and display it
    speed = calcSpeed(endTime - startTime);
displaySpeed(speed);
   
    //Set timer to display it
showTimer = millis();
   
    //Calc and store stats, skip for small displays
    #ifdef INFO_EXTEND
      if(speed > maxSpeed){
        maxSpeed = speed;
      }
      if(speed < minSpeed || minSpeed == 0){
        minSpeed = speed;
      }
      if(avgSpeed == 0){
        avgSpeed = speed;
      }
      else{
        avgSpeed += speed + 1;
        avgSpeed /= 2;
      }
    #endif
}

  //As long as display timer runs we don't update the screen
if(millis() - showTimer > TimeShowSpeed){
    //If timer runs, busy display
if(timerRuns){
displayBusy();
}
    //or the idle display
else{
displayIdle();
}
}
}

/***** SpeedOmeter functions ***********************/

//Calculates the speed as a fixed point int (1 decimal), with correct rounding
unsigned int calcSpeed(unsigned long time){
return (unsigned int)((36UL * distance * scale + (time / 2)) / time );
}

//Checks the inputs, returns true if a measurement is done, false otherwise
bool checkInput(){
  //state of the input, HIGH for detect (no matter the setting)
  bool lVal, rVal;
 
  //Set depending the setting
#if defined(ACTIVE_LOW)
lVal = !digitalRead(InputL);
rVal = !digitalRead(InputR);
#else
lVal = digitalRead(InputL);
rVal = digitalRead(InputR);
#endif

//Busy with timing
if(timerRuns){
    //End when the other detector is reached
    //Save endTime, remove flag, return true because of end
if(direction && lVal || !direction && rVal){
endTime = millis();
timerRuns = false;
return true;
}
}
  //Not busy
else{
    //We are ready and there is an input
if((lVal || rVal) && ready){
startTime = millis();
timerRuns = true;
ready = false;
direction = rVal;
}
   
    //Probably not ready,
    //make ready if no input at least TimeOut after ending timer
else if(!lVal && !rVal && (millis() - endTime > TimeOut)){
ready = true;
}
}

  //As long as it's not the end of the timer
return false;
}

/***** Display functions ***************************/

//Set up the display
void displayInit(){
//SSD1306 based OLED display
#if (LCD_TYPE == 1)
    //Setup, clear and welkom
display.begin(SSD1306_SWITCHCAPVCC, I2CAdress);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
    display.print("SpeedOmeter ");
display.println(SPEEDOMETER_VERSION);
display.println("Model railroad speed");
    display.println("By Timo Engelgeer");
    display.println("Septillion");
    display.print("Scale: ");
    display.println(scale);
    display.print("Dist: ");
    display.print(distance);
display.display();
delay(1000);

//Adafruit 7-segment I2C
#else if (LCD_TYPE == 2)
// set display
display.begin(I2CAdress);
display.setBrightness((DisplayBrightness > 15 ? 15 : DisplayBrightness)); // 0..15
   
    //Start up animation
    for(byte i = 0; i < 4; i++){
      byte icons[] = {0x5C, 0x63};
      for(byte y = 0; y < 4; y++){
        display.writeDigitRaw(y + (y > 2 ? 1 : 0), icons[y % 2] || (y == i ? 0x80 : 0x00));
      }
      display.writeDisplay();
      delay(500);
    }
#endif
}

//Displays the speed
void displaySpeed(unsigned int speed){
  //SSD1306 based OLED display
#if (LCD_TYPE == 1)
    byte position = 2; //to allign the speed right
 
    displayScreen = 2; //so we do this once
   
    //Clear etc
    display.clearDisplay();
    display.stopscroll();
    display.setTextColor(WHITE);
    display.setTextSize(2);
    display.setCursor(0,0);
   
    //Calculate the position so it's aligned to the right
    for(unsigned int test = (speed / 100); test; test /= 10){
      position--;
    }
   
    //Print speed
    display.print("Speed:");
    display.setTextSize(4);
    display.setCursor(position * 24,16);
    display.print(speed/10);
    display.print(",");
    display.print(speed % 10);
    display.setCursor(80, 48);
    display.setTextSize(2);
    display.print("km/h");
   
    display.display();
   
  //Adafruit 7-segment I2C
#else if (LCD_TYPE == 2)
    byte displayPos = 4; //Position on the screen

displayScreen = 2;//so we do this once

    //Disable blink
display.blinkRate(0);
   
    //But it speed is out of reach...
if(speed > 9999){
      //Make speed 9999 and blink
speed = 9999;
display.blinkRate(1);
}

    //Print speed
if(speed){  //if speed is not 0
      for(byte i = 0; speed && i <= 4; ++i) {
        display.writeDigitNum(displayPos--, speed % 10, i == 1);
        if(displayPos == 2) display.writeDigitRaw(displayPos--, 0x00);
        speed /= 10;
      }
    }
    else {
      display.writeDigitNum(displayPos--, 0, false);
    }
   
    //Fill rest with 0
    while(displayPos >= 0) display.writeDigitRaw(displayPos--, 0x00);
    display.writeDisplay();
  #endif
}

//Display when the timer is started
void displayBusy(){
//SSD1306 based OLED display
#if (LCD_TYPE == 1)
if(displayScreen != 3){
displayScreen = 3; //so we do this once
     
      //Clear etc
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0,0);
     
      //If from right to left, scroll <--
if(direction){
        for(byte i = 0; i < 2; i++){
          display.print("<--- ");
        }
display.startscrollleft(0x00, 0x01);
}
      //If from left to right, scroll -->
else{
        for(byte i = 0; i < 2; i++){
          display.print("---> ");
        }
display.startscrollright(0x00, 0x01);
}
     
      //Display the info below
      displayInfo();
display.display();
}

//Adafruit 7-segment I2C
#else if (LCD_TYPE == 2)
if(displayScreen != 3){
displayScreen = 3; //so we do this once
     
      // |---- for from left, ----| for from right
for(byte i = 0; i < 5; i++){
        if(i == 2) display.writeDigitRaw(i++, 0x00);
        if(i == 0 && !direction){
          display.writeDigitRaw(i, 0x70);
        }
        else if(i == 5 && direction){
          display.writeDigitRaw(i, 0x46);
        }
        else{
          display.writeDigitRaw(i, 0x40);
        }
      }
      //and blink 1Hz
display.blinkRate(2);
display.writeDisplay();
}
#endif
}

//Screen to display when waiting for input
void displayIdle(){
//SSD1306 based OLED display
#if (LCD_TYPE == 1)
if(displayScreen != 4){
displayScreen = 4; //so we do this once
     
      //Clear, don't scroll, set size, set cursor, write
display.clearDisplay();
      display.stopscroll();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.print("Wachten...");
     
      //And add info
      displayInfo();
     
display.display();
}


//Adafruit 7-segment I2C
#else if (LCD_TYPE == 2)
if(displayScreen != 4){
displayScreen = 4; //so we do this once
display.blinkRate(0); //Don't blink
     
      // Write "____"
for(byte i = 0; i < 5; i++){
        if(i == 2) display.writeDigitRaw(i++, 0x00);
        display.writeDigitRaw(i, 0x08);
      }
display.writeDisplay();
}
#endif
}

void displayError(){

displayScreen = 5;

}

//Display's the stats (min, max, avg, last)
void displayInfo(){
  #if (LCD_TYPE == 1)
    //Print last speed, max speed, min speed and average
    display.setTextSize(1);
    display.print("Lst: ");
    display.print(speed / 10);
    display.print(",");
    display.print(speed % 10);
    display.println("km/h");
    display.print("Max: ");
    display.print(maxSpeed / 10);
    display.print(",");
    display.print(maxSpeed % 10);
    display.println("km/h");
    display.print("Min: ");
    display.print(minSpeed / 10);
    display.print(",");
    display.print(minSpeed % 10);
    display.println("km/h");
    display.print("Avg: ");
    display.print(avgSpeed / 10);
    display.print(",");
    display.print(avgSpeed % 10);
    display.println("km/h");
  #endif
}


Timo
Verzonden vanaf mijn desktop met Firefox

Max Roodveldt

  • Offline Offline
  • Berichten: 258
  • 't is maar 'n spelletje...
Re: Tonen daadwerkelijke snelheid.
« Reactie #159 Gepost op: 28 mei 2015, 22:53:05 »
Timo,

zal de code met plezier bestuderen en testen.

Ik heb trouwens nog een ander - mogelijk interessant - display liggen: http://hobbycomponents.com/displays/74-i2c-serial-lcd-1602-module

mvg
"And these visions of Johanna are now all that remain" - Bob Dylan (1966)

spock

  • Offline Offline
  • Berichten: 652
Re: Tonen daadwerkelijke snelheid.
« Reactie #160 Gepost op: 28 mei 2015, 23:59:34 »
mea culpa, ik zal het voorbeeld aanpassen   :-[

peterha

  • Offline Offline
  • Berichten: 1100
Re: Tonen daadwerkelijke snelheid.
« Reactie #161 Gepost op: 29 mei 2015, 09:14:15 »
Timo,

Heb de code gedownload, de Adafruit library had ik al dus die heb ik niet opnieuw geïnstalleerd.

In de tekstsectie onder #define LCD_TYPE 2 staan twee define's; allebei ACTIVE_LOW. De eerste zonder //, de tweede met //.
Omdat het toch allemaal tekst is, heb ik de 2e // weggehaald, maar ook ACTIVE_LOW in ACTIVE_HIGH veranderd.

Voor mijn situatie heb ik de variabelen 'InputL' en 'InputR' veranderd van 9 en 10 in A0 en A1, #define ACTIVE_LOW in #define ACTIVE_HIGH en de 'distance' heb ik aangepast naar 3660 mm.

Vervolgens de sketch geladen. Na een (voor alle zekerheid) reset van de Arduino, kreeg ik 4 streepjes onderin. Tijdens de meting veranderde dat in |---- knipperend en na de meting vernaderde dat in |---- vast! Er kwam geen melding van de gemeten snelheid.

Kennelijk wordt de meting niet 'vrij' gegeven, want het display bleef vast staan en bij volgende doorgangen van de meetsectie veranderde er niets.

Volgens mij heb ik het juiste aangepast of ben ik wat vergeten?
Kun je wat met deze opmerkingen?

Gr. Peter
Met vriendelijke groet,
Peter

Max Roodveldt

  • Offline Offline
  • Berichten: 258
  • 't is maar 'n spelletje...
Re: Tonen daadwerkelijke snelheid.
« Reactie #162 Gepost op: 29 mei 2015, 18:06:47 »
En hier is het resultaat hetzelfde met de aanvulling dat in de tegenovergestelde richting het display alleen "----" toont. Het verticale streepje mankeert.

mvg
"And these visions of Johanna are now all that remain" - Bob Dylan (1966)

Timo

  • Team encyclopedie
  • Offline Offline
  • Berichten: 4656
Re: Tonen daadwerkelijke snelheid.
« Reactie #163 Gepost op: 30 mei 2015, 19:37:53 »
Hoi Peter en Max,

Bedankt voor het testen! :D

In de configuratie, het klopt dat er twee regels met #define ACTIVE_LOW in de comments staan. Het idee was dat je de define comment (dus eigenlijk weg haalt) om naar active high te schakelen. Dus wel definiëren voor active low (#define ACTIVE_LOW) of niet definiëren voor active high (//#define ACTIVE LOW). Het is op zich niet fout om het aan te passen naar #define ACTIVE_HIGH aangezien hiermee ACTIVE_LOW niet gedefinieerd wordt  ;D (Ook al wordt er nergens gekeken naar ACTIVE_HIGH :p ) Zou dit eigenlijk duidelijker zijn?

@Max, dat scherm is zeker ook te gebruiken. Het moet ook niet zo moeilijk zijn dit scherm toe te voegen aan de code. Zelf heb ik alleen een niet I2C versie maar de "normale". Ik zal kijken of ik beide toe kan voegen.  ;)

Ik heb net even de code doorgekeken en er inderdaad 3 fouten uit gehaald  :-X Beide bedankt, dat jullie twee opmerkingen wezen beide op een andere fout.

Eerst de belangrijkste, het niet printen van de snelheid en dan hangen. Het feit dat het display wel stopte met knipperen gaf aan dat de functie voor snelheid printen wel werd aangeroepen en dat hij daar bleef hangen in een loop voordat display.writeDisplay() werd aangeroepen. Wat bleek, ik heb een stukje code uit de library gekopieerd
while(displayPos >= 0) display.writeDigitRaw(displayPos--, 0x00);
Op zich niet fout maar in het originele code was displayPos een int, ik heb hem als byte gedefinieerd. En een byte kleiner dan 0 is niet mogelijk  ::) Nu vervangen door displayPos < 100 omdat er nu een rollover naar 255 plaats vindt. Dit zou het moeten oplossen.

Voor de andere richting werd geen streepje getoond. Dit kwam omdat ik had geschreven
else if(i == 5 && direction){
Terwijl het meest rechter karakter wel het 5e karakter is dit dan natuurlijk nummer 4 (== 4). Het meest linker karakter is dan ook nummer 0. Nu zou er dus wel een streepje moeten komen.

En dan nog een domme fout waar jullie niets gemerkt hebben.  ;D Ik had een simpele opstart animatie gemaakt voor het display. Hierin staat een regel met een bitwise OR van twee waarde. Ik had alleen ipv a | b geschreven a || b. Aangezien dit altijd waar is leverde dit dus de waarde 1 op ipv het gewenste getal. Als het goed is toonde het display bij het opstarten dus even 4 streepje bovenaan, klopt dat? In de nieuwe versie is dit de gewenste animatie (hopelijk :p).

[Edit]En omdat de IDE van Arduino nog steeds niet normaal met tabs om kan gaan de boel even in spaces omgezet.


Timo

De nieuwe code als download (v1.1) en als post:
/***************************************************
  SpeedOmeter v1.1 - Speedometer for modelrailroad
  Created by Timo Engelgeer (Septillion), May 30, 2015
  Based on Speedometer bij Max Roodveldt
 
  Calculates the (scale) speed of a (model) train based on two
  detections on the layout. This can be any kind you like.
 
****************************************************/
#define SPEEDOMETER_VERSION "v1.0"
/***** Configuration *******************************
  The Speedometer is made very versatile. So in order to make it work with
  your setup you have to configure it. The next few blocks will guide you to
  the configuration.
 
  -- Display --
  Because you can use different display's with Speedometer you have to select
  the correct one.
  1 SSD1306 128x64 OLED display (I2C, default adress 0x3C)
  2 Adafruit 7-segment display (I2C, default adress is 0x70)

****************************************************/
#define LCD_TYPE 1

/**-- Sensor --
  It doesn't matter what kind of sensor you use. This can be an active low
  (signal goes low when train passes) or active high (signal goes high when
  train passes).
 
  Comment the line below for active low.
  #define ACTIVE_LOW    for active low  (uncommented)
  //#define ACTIVE_LOW  for active high (commented => not defined)
 
  Analoog komt nog ;)
**/
#define ACTIVE_LOW

/**-- Pins --
  To which pins are the sensors connected? Left and Right respectively
**/
const byte InputL = 9;
const byte InputR = 10;

/**-- Settings --
  Distance =>     Distance between start of the first detector and
                  the start of the second (in mm)
  Scale =>        Scale of the layout
  TimeShowSpeed =>Time to show the speed after finishing the measurement (in ms)
  TimeOut =>      Time to ignore re-triggering the detector after
                  finishing measurement (in ms)
**/
unsigned int distance = 5000;
unsigned int scale = 87;

const unsigned int TimeShowSpeed = 5000;
const unsigned int TimeOut = 3000;

/**-- Done! --
  You are done. Upload the sketch!
**/

//SSD1306 based OLED display
#if (LCD_TYPE == 1)
  #include <SPI.h>
  #include <Wire.h>
  #include <Adafruit_GFX.h>
  #include <Adafruit_SSD1306.h>

  Adafruit_SSD1306 display(255);
  const byte I2CAdress = 0x3C;
 
  #define INFO_EXTEND

//Adafruit 7-segment I2C
#else if (LCD_TYPE == 2)
  #include <Wire.h>
  #include "Adafruit_LEDBackpack.h"
  #include "Adafruit_GFX.h"

  Adafruit_7segment display = Adafruit_7segment();
  const byte I2CAdress = 0x70;
  const byte DisplayBrightness = 7; // 0..15
#endif

/***** Global vars *********************************/
bool timerRuns = false; //Does the timer run?
bool direction = false; //In which direction? (false = to left, true = to right
bool ready = true;      //ready to start the clock?
byte displayScreen = 0; //Which screen is displayed last?

unsigned long startTime;      //Saved start time
unsigned long endTime;        //Saved end time
unsigned long showTimer =  -1;//Time when display started showing something

//Speed stats
unsigned int speed, maxSpeed, minSpeed, avgSpeed = 0;

/***** Default functions ***************************/

void setup() {
  //Initialize the display
  displayInit();
 
  //Set the input acording to the setting
  #if defined(ACTIVE_LOW)
    pinMode(InputL, INPUT_PULLUP);
    pinMode(InputR, INPUT_PULLUP);
  #else
    pinMode(InputL, INPUT);
    pinMode(InputR, INPUT);
  #endif
}

void loop(){
  //Check for a finished measurement
  if(checkInput()){
    //If so, calculate the speed and display it
    speed = calcSpeed(endTime - startTime);
    displaySpeed(speed);
   
    //Set timer to display it
    showTimer = millis();
   
    //Calc and store stats, skip for small displays
    #ifdef INFO_EXTEND
      if(speed > maxSpeed){
        maxSpeed = speed;
      }
      if(speed < minSpeed || minSpeed == 0){
        minSpeed = speed;
      }
      if(avgSpeed == 0){
        avgSpeed = speed;
      }
      else{
        avgSpeed += speed + 1;
        avgSpeed /= 2;
      }
    #endif
  }
 
  //As long as display timer runs we don't update the screen
  if(millis() - showTimer > TimeShowSpeed){
    //If timer runs, busy display
    if(timerRuns){
      displayBusy();
    }
    //or the idle display
    else{
      displayIdle();
    }
  }
}

/***** SpeedOmeter functions ***********************/

//Calculates the speed as a fixed point int (1 decimal), with correct rounding
unsigned int calcSpeed(unsigned long time){
  return (unsigned int)((36UL * distance * scale + (time / 2)) / time );
}

//Checks the inputs, returns true if a measurement is done, false otherwise
bool checkInput(){
  //state of the input, HIGH for detect (no matter the setting)
  bool lVal, rVal;
 
  //Set depending the setting
  #if defined(ACTIVE_LOW)
    lVal = !digitalRead(InputL);
    rVal = !digitalRead(InputR);
  #else
    lVal = digitalRead(InputL);
    rVal = digitalRead(InputR);
  #endif
 
  //Busy with timing
  if(timerRuns){
    //End when the other detector is reached
    //Save endTime, remove flag, return true because of end
    if(direction && lVal || !direction && rVal){
      endTime = millis();
      timerRuns = false;
      return true;
    }
  }
  //Not busy
  else{
    //We are ready and there is an input
    if((lVal || rVal) && ready){
      startTime = millis();
      timerRuns = true;
      ready = false;
      direction = rVal;
    }
   
    //Probably not ready,
    //make ready if no input at least TimeOut after ending timer
    else if(!lVal && !rVal && (millis() - endTime > TimeOut)){
      ready = true;
    }
  }
 
  //As long as it's not the end of the timer
  return false;
}

/***** Display functions ***************************/

//Set up the display
void displayInit(){
  //SSD1306 based OLED display
  #if (LCD_TYPE == 1)
    //Setup, clear and welkom
    display.begin(SSD1306_SWITCHCAPVCC, I2CAdress);
    display.clearDisplay();
    display.setTextSize(1);
    display.setTextColor(WHITE);
    display.setCursor(0,0);
    display.print("SpeedOmeter ");
    display.println(SPEEDOMETER_VERSION);
    display.println("Model railroad speed");
    display.println("By Timo Engelgeer");
    display.println("Septillion");
    display.print("Scale: ");
    display.println(scale);
    display.print("Dist: ");
    display.print(distance);
    display.display();
    delay(1000);

  //Adafruit 7-segment I2C
  #else if (LCD_TYPE == 2)
    byte icons[] = {0x5C, 0x63};
 
    // set display
    display.begin(I2CAdress);
    display.setBrightness((DisplayBrightness > 15 ? 15 : DisplayBrightness)); // 0..15
   
    //Start up animation
    for(byte i = 0; i < 4; i++){
      for(byte y = 0; y < 4; y++){
        display.writeDigitRaw(y + (y >= 2 ? 1 : 0), icons[(y + i) % 2] | (y == i ? 0x80 : 0x00));
      }
      display.writeDisplay();
      delay(500);
    }
  #endif
}

//Displays the speed
void displaySpeed(unsigned int speed){
  //SSD1306 based OLED display
  #if (LCD_TYPE == 1)
    byte position = 2; //to allign the speed right
 
    displayScreen = 2; //so we do this once
   
    //Clear etc
    display.clearDisplay();
    display.stopscroll();
    display.setTextColor(WHITE);
    display.setTextSize(2);
    display.setCursor(0,0);
   
    //Calculate the position so it's aligned to the right
    for(unsigned int test = (speed / 100); test; test /= 10){
      position--;
    }
   
    //Print speed
    display.print("Speed:");
    display.setTextSize(4);
    display.setCursor(position * 24,16);
    display.print(speed/10);
    display.print(",");
    display.print(speed % 10);
    display.setCursor(80, 48);
    display.setTextSize(2);
    display.print("km/h");
   
    display.display();
   
  //Adafruit 7-segment I2C
  #else if (LCD_TYPE == 2)
    byte displayPos = 4; //Position on the screen
   
    displayScreen = 2;//so we do this once
   
    //Disable blink
    display.blinkRate(0);
   
    //But it speed is out of reach...
    if(speed > 9999){
      //Make speed 9999 and blink
      speed = 9999;
      display.blinkRate(1);
    }
   
    //Print speed
    if(speed){  //if speed is not 0
      for(byte i = 0; speed && i <= 4; ++i) {
        display.writeDigitNum(displayPos--, speed % 10, i == 1);
        if(displayPos == 2) display.writeDigitRaw(displayPos--, 0x00);
        speed /= 10;
      }
    }
    else {
      display.writeDigitNum(displayPos--, 0, false);
    }
   
    //Fill rest with 0
    while(displayPos < 100) display.writeDigitRaw(displayPos--, 0x00);
    display.writeDisplay();
  #endif
}

//Display when the timer is started
void displayBusy(){
  //SSD1306 based OLED display
  #if (LCD_TYPE == 1)
    if(displayScreen != 3){
      displayScreen = 3; //so we do this once
     
      //Clear etc
      display.clearDisplay();
      display.setTextSize(2);
      display.setTextColor(WHITE);
      display.setCursor(0,0);
     
      //If from right to left, scroll <--
      if(direction){
        for(byte i = 0; i < 2; i++){
          display.print("<--- ");
        }
        display.startscrollleft(0x00, 0x01);
      }
      //If from left to right, scroll -->
      else{
        for(byte i = 0; i < 2; i++){
          display.print("---> ");
        }
        display.startscrollright(0x00, 0x01);
      }
     
      //Display the info below
      displayInfo();
      display.display();
    }
   
  //Adafruit 7-segment I2C
  #else if (LCD_TYPE == 2)
    if(displayScreen != 3){
      displayScreen = 3; //so we do this once
     
      // |---- for from left, ----| for from right
      for(byte i = 0; i < 5; i++){
        if(i == 2) display.writeDigitRaw(i++, 0x00);
        if(i == 0 && !direction){
          display.writeDigitRaw(i, 0x70);
        }
        else if(i == 4 && direction){
          display.writeDigitRaw(i, 0x46);
        }
        else{
          display.writeDigitRaw(i, 0x40);
        }
      }
      //and blink 1Hz
      display.blinkRate(2);
      display.writeDisplay();
    }
  #endif
}

//Screen to display when waiting for input
void displayIdle(){
  //SSD1306 based OLED display
  #if (LCD_TYPE == 1)
    if(displayScreen != 4){
      displayScreen = 4; //so we do this once
     
      //Clear, don't scroll, set size, set cursor, write
      display.clearDisplay();
      display.stopscroll();
      display.setTextSize(2);
      display.setTextColor(WHITE);
      display.setCursor(0,0);
      display.print("Wachten...");
     
      //And add info
      displayInfo();
     
      display.display();
    }
 
 
  //Adafruit 7-segment I2C
  #else if (LCD_TYPE == 2)
    if(displayScreen != 4){
      displayScreen = 4; //so we do this once
      display.blinkRate(0); //Don't blink
     
      // Write "____"
      for(byte i = 0; i < 5; i++){
        if(i == 2) display.writeDigitRaw(i++, 0x00);
        display.writeDigitRaw(i, 0x08);
      }
      display.writeDisplay();
    }
  #endif
}

void displayError(){
 
  displayScreen = 5;
 
}

//Display's the stats (min, max, avg, last)
void displayInfo(){
  #if (LCD_TYPE == 1)
    //Print last speed, max speed, min speed and average
    display.setTextSize(1);
    display.print("Lst: ");
    display.print(speed / 10);
    display.print(",");
    display.print(speed % 10);
    display.println("km/h");
    display.print("Max: ");
    display.print(maxSpeed / 10);
    display.print(",");
    display.print(maxSpeed % 10);
    display.println("km/h");
    display.print("Min: ");
    display.print(minSpeed / 10);
    display.print(",");
    display.print(minSpeed % 10);
    display.println("km/h");
    display.print("Avg: ");
    display.print(avgSpeed / 10);
    display.print(",");
    display.print(avgSpeed % 10);
    display.println("km/h");
  #endif
}
« Laatst bewerkt op: 30 mei 2015, 19:44:53 door Timo. Reden: Nu met spaces ipv tabs »
Verzonden vanaf mijn desktop met Firefox

Max Roodveldt

  • Offline Offline
  • Berichten: 258
  • 't is maar 'n spelletje...
Re: Tonen daadwerkelijke snelheid.
« Reactie #164 Gepost op: 30 mei 2015, 20:46:00 »
Timo, deze versie werkt hier goed. (y)


In de configuratie, het klopt dat er twee regels met #define ACTIVE_LOW in de comments staan. Het idee was dat je de define comment (dus eigenlijk weg haalt) om naar active high te schakelen. Dus wel definiëren voor active low (#define ACTIVE_LOW) of niet definiëren voor active high (//#define ACTIVE LOW). Het is op zich niet fout om het aan te passen naar #define ACTIVE_HIGH aangezien hiermee ACTIVE_LOW niet gedefinieerd wordt  ;D (Ook al wordt er nergens gekeken naar ACTIVE_HIGH :p ) Zou dit eigenlijk duidelijker zijn?
Ben benieuwd hoe je dit uit gaat leggen aan iemand zonder veel programmeer ervaring ???  Kiezen tussen LOW en HIGH is misschien toch makkelijker...

Citaat
En dan nog een domme fout waar jullie niets gemerkt hebben.  ;D Ik had een simpele opstart animatie gemaakt voor het display. Hierin staat een regel met een bitwise OR van twee waarde. Ik had alleen ipv a | b geschreven a || b. Aangezien dit altijd waar is leverde dit dus de waarde 1 op ipv het gewenste getal. Als het goed is toonde het display bij het opstarten dus even 4 streepje bovenaan, klopt dat?
;D Nee - er waren slechts drie streepjes; het derde cijfer was zwart...

mvg
"And these visions of Johanna are now all that remain" - Bob Dylan (1966)