{"id":2461,"date":"2024-03-20T12:09:20","date_gmt":"2024-03-20T11:09:20","guid":{"rendered":"https:\/\/www.rommelkist.nl\/elec\/?p=2461"},"modified":"2024-04-06T22:02:23","modified_gmt":"2024-04-06T20:02:23","slug":"n-spoor-deel-11-weistra-rijregelaar","status":"publish","type":"post","link":"https:\/\/www.rommelkist.nl\/elec\/elektronica\/n-spoor-deel-11-weistra-rijregelaar\/","title":{"rendered":"N-spoor &#8211; deel 21 &#8211; Weistra Rijregelaar"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Om de snelheid van de treintjes te kunnen veranderen is een rijregelaar nodig. Ergens heb ik de hier beschreven regelaar gevonden (<a href=\"https:\/\/train-science.com\/diy-pwm-rijregelaar\/\">hier dus<\/a>): maakt gebruik van PWM (zie ook <a href=\"https:\/\/www.rommelkist.nl\/elec\/elektronica\/pwm-pulsbreedte-modulatie\/\" data-type=\"post\" data-id=\"2410\">hier<\/a>) op de Weistra-manier. Dit principe wordt <a href=\"https:\/\/encyclopedie.beneluxspoor.net\/index.php\/Snelheidsregelaar_met_pulsbreedtemodulatie\">hier<\/a> goed uitgelegd. <br><\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"https:\/\/www.rommelkist.nl\/elec\/wp-content\/uploads\/2024\/03\/image-29.png\"><img loading=\"lazy\" decoding=\"async\" width=\"633\" height=\"657\" src=\"https:\/\/www.rommelkist.nl\/elec\/wp-content\/uploads\/2024\/03\/image-29.png\" alt=\"\" class=\"wp-image-2462\" style=\"width:400px\" srcset=\"https:\/\/www.rommelkist.nl\/wp-content\/uploads\/2024\/03\/image-29.png 633w, https:\/\/www.rommelkist.nl\/wp-content\/uploads\/2024\/03\/image-29-289x300.png 289w, https:\/\/www.rommelkist.nl\/wp-content\/uploads\/2024\/03\/image-29-425x441.png 425w\" sizes=\"auto, (max-width: 633px) 100vw, 633px\" \/><\/a><figcaption class=\"wp-element-caption\">Schema<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Een Arduino Nano wekt aan de hand van de stand van potmeter 1 een pwm-signaal met een hogere (harder) dan wel lagere (langzamer) frequentie op. Het signaal wordt via de L298-module (dubbele H-brug motor driver) naar de rails gevoerd.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"https:\/\/www.rommelkist.nl\/elec\/wp-content\/uploads\/2024\/03\/image-30.png\"><img loading=\"lazy\" decoding=\"async\" width=\"519\" height=\"495\" src=\"https:\/\/www.rommelkist.nl\/elec\/wp-content\/uploads\/2024\/03\/image-30.png\" alt=\"\" class=\"wp-image-2464\" style=\"width:400px\" srcset=\"https:\/\/www.rommelkist.nl\/wp-content\/uploads\/2024\/03\/image-30.png 519w, https:\/\/www.rommelkist.nl\/wp-content\/uploads\/2024\/03\/image-30-300x286.png 300w, https:\/\/www.rommelkist.nl\/wp-content\/uploads\/2024\/03\/image-30-425x405.png 425w\" sizes=\"auto, (max-width: 519px) 100vw, 519px\" \/><\/a><figcaption class=\"wp-element-caption\">L298 motor driver module<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Met potmeter 2 en 3 is de maximum en minimum snelheid aan te passen. Hieronder de door mij volledig gepikte Arduino sketch.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: arduino; title: ; notranslate\" title=\"\">\n#include &quot;src\/macros.h&quot;\n#include &quot;src\/weistra.h&quot;\n#include &quot;src\/stateMachineClass.h&quot;\n#include &quot;config.h&quot;\n\nint     setPoint ;\nint     prevSetPoint ;\nuint8_t brakeSensor ;\nuint8_t lastDir ;\nint8_t  brakeSpeed ;\nint8_t  currentSpeed ;\n\nStateMachine sm ;\nenum states\n{\n    runMode,\n    braking,\n    departing,\n} ;\n\nWeistra pwm( in1, in2, Fmin, Fmax ) ;\n\nuint8_t     hasMaxSpeedPot ;\nuint8_t     hasMinSpeedPot ;\nuint8_t     hasAccelPot ;\nuint8_t     hasWaitPot ;\nuint8_t     hasShuttleSerice ;\n\nvoid setup()\n{\n    pwm.begin() ;\n    pwm.setCurrentSense( currentSensePin, currentLimit ) ;\n    sm.setState(runMode);\n\n    Serial.begin(115200);\n    Serial.println(&quot;Weistra_pwmController.ino&quot;);\n\n\/\/ for following 3 pins, I enable pullups and I take a sample, if the sample is &lt; then 1023, I know a potentiometer is attached\n    pinMode( maxSpeedPin,       INPUT_PULLUP ) ;\n    pinMode( minSpeedPin,       INPUT_PULLUP ) ;\n    pinMode( accelFactorPin,    INPUT_PULLUP ) ;\n    pinMode( waitTimePin,       INPUT_PULLUP ) ;\n    delay(1);\n\n    int sample ;\n    sample = analogRead( maxSpeedPin ) ;\n    if( sample &lt; 1020 )\n    {\n        pinMode( maxSpeedPin, INPUT ) ;\n        hasMaxSpeedPot = 1 ;\n    } else Serial.println(&quot;no max speed pot&quot;);\n    delay(1);\n    sample = analogRead( minSpeedPin ) ;\n    if( sample &lt; 1020 )\n    {\n        pinMode( minSpeedPin, INPUT ) ;\n        hasMinSpeedPot = 1 ;\n    } else Serial.println(&quot;no min speed pot&quot;);\n    delay(1);\n    sample = analogRead( accelFactorPin ) ;\n    if( sample &lt; 1020 )\n    {\n        pinMode( accelFactorPin, INPUT ) ;\n        hasAccelPot = 1 ;\n    }else Serial.println(&quot;no accel\/brake pot&quot;);\n    delay(1);\n    sample = analogRead( waitTimePin ) ; \/\/ used for adjustable time delay.\n    if( sample &lt; 1020 )\n    {\n        pinMode( waitTimePin, INPUT ) ;\n        hasWaitPot = 1 ;\n        hasShuttleSerice = 1 ;\n    }  else Serial.println(&quot;no wait time pot&quot;);\n\n    pinMode( S1, INPUT_PULLUP ) ;\n    pinMode( S2, INPUT_PULLUP ) ;\n\n\n}\n\nvoid loop()\n{\n    pwm.update() ;\n    control() ;\n\n    \/\/ read main speed potentiometer\n    REPEAT_MS( accelerationFactor )\n    {\n        setPoint = analogRead( speedPin ) ;\n\n    \/\/ sample    0      512-50   512   512+50      1023\n    \/\/ speed  -100   &lt;-&gt;   0      0       0   &lt;-&gt;   100  \/\/ dead zone in middle\n        if(      setPoint &lt;= (512-50)) setPoint = map( setPoint,      0, 512-50, -maxSpeed,  minSpeed ) ; \/\/ test me\n        else if( setPoint &gt;= (512+50)) setPoint = map( setPoint, 512+50,   1023,  minSpeed,  maxSpeed ) ;\n        else                          setPoint = 0 ;\n\n            \/\/ if potentiometer changes, abort shuttle service at once (should discard sensors)?\n      if( setPoint != currentSpeed )\n      {\n          \n          if( currentSpeed &lt; setPoint ) currentSpeed ++ ;\n          if( currentSpeed &gt; setPoint ) currentSpeed -- ;\n\n          if( currentSpeed &gt; -minSpeed &amp;&amp; currentSpeed &lt; minSpeed )\n          {\n              pwm.setSpeed( 0 ) ; \n          }\n          else\n          {\n              pwm.setSpeed( currentSpeed ) ;\n          }\n          \n          sm.nextState( runMode, 3000 ) ; \/\/ go to runmode and lockout sensor for 3 seconds   \n      }\n    }\n    END_REPEAT\n\n    REPEAT_MS( 1000 ) \/\/ 1000ms sample rate suffices\n    {\n        int sample ;\n        if( hasMaxSpeedPot )\n        {\n            sample = analogRead( maxSpeedPin ) ;\n            maxSpeed = map( sample, 0, 1023, 20, 100 ) ;\n        } \n        if( hasMinSpeedPot )\n        {\n            sample = analogRead( minSpeedPin ) ;\n            minSpeed = map( sample, 0, 1023, 0, 30 ) ;\n        } \n        if( hasAccelPot )\n        {\n            sample = analogRead( accelFactorPin ) ;\n            accelerationFactor = map( sample, 0, 1023, 50, 5 ) ; \/\/ CHECK ME\n        }\n        if( hasWaitPot )\n        {\n            sample = analogRead( waitTimePin ) ;\n            waitTime = map( sample, 0, 1023, 5000, 60000 ) ; \/\/ 5-60 seconds\n        }\n    }\n    END_REPEAT\n}\n\nStateFunction( runMode )\n{\n    if( digitalRead( S1 ) == 0 || digitalRead( S2 ) == 0 ) return 1 ;\n    \n    return 0 ;\n}\n\nStateFunction( braking )\n{\n    if( sm.entryState() )\n    {\n        brakeSpeed = currentSpeed ;\n        if( brakeSpeed &lt; 0 ) lastDir = 1 ;\n        else                 lastDir = 0 ;\n    }\n    if( sm.onState() )\n    {\n        if( sm.repeat( accelerationFactor ) )\n        {\n            if(      brakeSpeed &lt; 0 ) brakeSpeed ++ ;\n            else if( brakeSpeed &gt; 0 ) brakeSpeed -- ;\n            else         sm.exit() ;   \/\/ when speed is 0 exit\n\n            pwm.setSpeed( brakeSpeed ) ;\n        }\n    }\n\n    return sm.endState() ;\n}\n\nStateFunction( departing )\n{\n    if( sm.repeat( accelerationFactor ) )\n    {\n        if( lastDir ) brakeSpeed -- ;\n        else          brakeSpeed ++ ;\n        pwm.setSpeed( brakeSpeed ) ;\n\n        if( brakeSpeed == -maxSpeed \n        ||  brakeSpeed ==  maxSpeed ) sm.exit() ;\n    }\n\n    return sm.endState() ;\n}\n\n\nuint8_t control()\n{\n    STATE_MACHINE_BEGIN( sm )\n    {\n        State( runMode ) {\n            sm.nextState( braking, 0 ) ; }\n    \n        State( braking ) {\n            sm.nextState( departing, waitTime ) ; }\n    \n        State( departing ) {\n            sm.nextState( runMode , 8000 ) ; } \/\/ 8 seconds lockout for sensors\n    }\n    STATE_MACHINE_END( sm )\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Naast bovenstaande .ino is er een config.h file waarin alle variabelen en constanten zijn opgenomen. Wel een overzichtelijke manier van werken!<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: arduino; title: ; notranslate\" title=\"\">\n#include &lt;Arduino.h&gt;\n\n\/\/ maximum current\nconst int currentLimit       =  10 ; \/\/ CHECK ME ADD CALCULATION\n\n\/\/ used IO PINs\nconst int speedPin           =  A0 ;\nconst int currentSensePin    =  A1 ;\nconst int minSpeedPin        =  A2 ;\nconst int maxSpeedPin        =  A3 ;\nconst int accelFactorPin     =  A4 ;\nconst int waitTimePin        =  A5 ;\nconst int in1                =  10 ; \/\/ h brug\nconst int in2                =  11 ; \/\/ h brug\nconst int S1                 =   3 ;\nconst int S2                 =   4 ;\n\n\/\/ PWM parameters\nconst int Fmin               =  50 ;\nconst int Fmax               = 100 ;\n      int accelerationFactor =  15 ;\n      int minSpeed           =  10 ; \/\/ minimum speed. Slow trains start driving at higher throttle levers\n      int maxSpeed           = 100 ; \/\/ may NOT be bigger than 100\n\n\/\/ shuttle service station wait time\nuint32_t    waitTime = 30000 ; \/\/ 30 seconds\n<\/pre><\/div>\n\n\n<figure class=\"wp-block-image size-large is-resized\"><a href=\"https:\/\/www.rommelkist.nl\/elec\/wp-content\/uploads\/2024\/03\/image-31.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"762\" src=\"https:\/\/www.rommelkist.nl\/elec\/wp-content\/uploads\/2024\/03\/image-31-1024x762.png\" alt=\"\" class=\"wp-image-2472\" style=\"width:500px\" srcset=\"https:\/\/www.rommelkist.nl\/wp-content\/uploads\/2024\/03\/image-31-1024x762.png 1024w, https:\/\/www.rommelkist.nl\/wp-content\/uploads\/2024\/03\/image-31-300x223.png 300w, https:\/\/www.rommelkist.nl\/wp-content\/uploads\/2024\/03\/image-31-768x571.png 768w, https:\/\/www.rommelkist.nl\/wp-content\/uploads\/2024\/03\/image-31-425x316.png 425w, https:\/\/www.rommelkist.nl\/wp-content\/uploads\/2024\/03\/image-31.png 1137w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">De regelaar<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"VID 20240320 110931282\" width=\"1260\" height=\"709\" src=\"https:\/\/www.youtube.com\/embed\/IDOeBCyiYb0?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><figcaption class=\"wp-element-caption\">Langzaam &#8230;<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"VID 20240320 110951751\" width=\"1260\" height=\"709\" src=\"https:\/\/www.youtube.com\/embed\/_G6Vq6lBroU?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><figcaption class=\"wp-element-caption\">wat sneller &#8230;<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"VID 20240320 111020016\" width=\"1260\" height=\"709\" src=\"https:\/\/www.youtube.com\/embed\/sTj8yF7HfyM?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><figcaption class=\"wp-element-caption\">en razend snel!<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Zelfs op de lage snelheid loopt het locje heel mooi! Met de in een vorig deel beschreven <a href=\"https:\/\/www.rommelkist.nl\/elec\/elektronica\/n-spoor-deel-10-snelheid\/\" data-type=\"post\" data-id=\"2436\">snelheidsmeter<\/a> gaan we in een volgend deel de snelheid meten! \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Om de snelheid van de treintjes te kunnen veranderen is een rijregelaar nodig. Ergens heb ik de hier beschreven regelaar gevonden (hier dus): maakt gebruik van PWM (zie ook hier) op de Weistra-manier. Dit principe wordt hier goed uitgelegd. Een Arduino Nano wekt aan de hand van de stand van potmeter 1 een pwm-signaal met een hogere (harder) dan wel lagere (langzamer) frequentie op. Het signaal wordt via de L298-module (dubbele H-brug motor driver) naar de rails gevoerd. Met potmeter 2 en 3 is de maximum en minimum snelheid aan te passen. Hieronder de door mij volledig gepikte Arduino sketch. Naast<span class=\"more-link\"><a href=\"https:\/\/www.rommelkist.nl\/elec\/elektronica\/n-spoor-deel-11-weistra-rijregelaar\/\">Read More &rarr;<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_crdt_document":"","footnotes":""},"categories":[6,3,104],"tags":[60,20,107,106],"class_list":["entry","author-admin","post-2461","post","type-post","status-publish","format-standard","category-arduino","category-elektronica","category-modeltreinbaan","tag-diy","tag-module","tag-n-spoor","tag-treintje"],"_links":{"self":[{"href":"https:\/\/www.rommelkist.nl\/elec\/wp-json\/wp\/v2\/posts\/2461","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rommelkist.nl\/elec\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rommelkist.nl\/elec\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rommelkist.nl\/elec\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rommelkist.nl\/elec\/wp-json\/wp\/v2\/comments?post=2461"}],"version-history":[{"count":0,"href":"https:\/\/www.rommelkist.nl\/elec\/wp-json\/wp\/v2\/posts\/2461\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.rommelkist.nl\/elec\/wp-json\/wp\/v2\/media?parent=2461"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rommelkist.nl\/elec\/wp-json\/wp\/v2\/categories?post=2461"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rommelkist.nl\/elec\/wp-json\/wp\/v2\/tags?post=2461"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}