modeltrein besturing
Re: modeltrein besturing
Huh ? Kun je nog eens uitleggen wat je wilt ?
Een softwarematige timer met millis() heeft een interval, bijvoorbeeld iedere 3 seconden.
Een vertraging kan ook met millis(), bijvoorbeeld over 10 seconden iets doen.
Een inschakelvertraging en uitschakelvertraging kan ook. Maar dan is het belangrijk om de condities te beschrijven. Wat als de ene nog bezig is terwijl de andere aktief wordt.
Een softwarematige timer met millis() heeft een interval, bijvoorbeeld iedere 3 seconden.
Een vertraging kan ook met millis(), bijvoorbeeld over 10 seconden iets doen.
Een inschakelvertraging en uitschakelvertraging kan ook. Maar dan is het belangrijk om de condities te beschrijven. Wat als de ene nog bezig is terwijl de andere aktief wordt.
Advertisement
- maartentukker
- Berichten: 37
- Geregistreerd: 07 Okt 2016, 10:33
Re: modeltrein besturing
Ik wil dus alleen de delay's in het huidige programma vervangen door millis(). Om de servo de tijd te geven te activeren en zijn sweep te doorlopen. Dit met dus 2 verschillende tijden. Ik snap alleen niet hoe ik zo'n pauze in dit programma verwerk en deze dus op die momenten kan laten beginnen en eindigen.
Een boolean geeft toch alleen een high of low?
Een boolean geeft toch alleen een high of low?
Re: modeltrein besturing
Zal ik dan deze sketch nemen ? http://arduinoforum.nl/viewtopic.php?f=9&t=2038#p14986
Waarom is die detach() eigenlijk nodig ? Voor zover ik weet zijn er maar weinig servo motors die dan in standby gaan.
Om een seconde later de detach() te doen, en de leds anders te zetten, dat zou kunnen met één vertraging en één previousMillis.
Wil je ook die 15ms omzetten naar millis() ?
Dat wordt het al snel een state machine of een tabel uitvoeren.
Is de 15ms echt nodig ? Ik kan me niet voorstellen waarvoor Het servo signaal maakt dat de servo motor toch wel naar de juiste positie gaat.
Met een functie, zoals shooter schreef, lijkt me ook beter.
De condities goed beschrijven is erg belangrijk. Dus wat gebeurt er als op het verkeerde moment de verkeerde knop wordt ingedrukt ?
Als de nieuwe knop de oude 'override', dan kan ik inderdaad iets maken met één vertraging en één previousMillis.
Eerst maar even de eenvoudigste oplossing, waarbij de loop() toch nog redelijk snel gaat, voldoende om knoppen en sensors in de gaten te houden.
Hier de twee functies die shooter bedoelde:
Dan de globale variabelen.
Dan de vertraging starten met de knoppen.
Voor de andere knop hetzelfde, alleen de positie van 100 is dan 80.
Vervolgens ergens onderaan de loop() kijken of het al tijd is om de servo idle te maken.
Begrijp je de bedoeling ? Het moment waarop de vertraging begint, maak je een 'timestamp' van de tijd door millis() van dat moment te onthouden. Daarna kijken of de tijd al verlopen is. Maar wel met een variabele die aangeeft of de vertraging op dat moment actief is.
Alles is dus eenmalig. Daarom hoeft de 'previousMillis' niet opgehoogd te worden. Als de vertraging over is en ServoIdle() is uitgevoerd, dan is het klaar. Wat de waarde van 'previousMillis' dan is, dat maakt niet uit, want de 'servoDelayActive' heeft de vertraging disabled.
Waarom is die detach() eigenlijk nodig ? Voor zover ik weet zijn er maar weinig servo motors die dan in standby gaan.
Om een seconde later de detach() te doen, en de leds anders te zetten, dat zou kunnen met één vertraging en één previousMillis.
Wil je ook die 15ms omzetten naar millis() ?
Dat wordt het al snel een state machine of een tabel uitvoeren.
Is de 15ms echt nodig ? Ik kan me niet voorstellen waarvoor Het servo signaal maakt dat de servo motor toch wel naar de juiste positie gaat.
Met een functie, zoals shooter schreef, lijkt me ook beter.
De condities goed beschrijven is erg belangrijk. Dus wat gebeurt er als op het verkeerde moment de verkeerde knop wordt ingedrukt ?
Als de nieuwe knop de oude 'override', dan kan ik inderdaad iets maken met één vertraging en één previousMillis.
Eerst maar even de eenvoudigste oplossing, waarbij de loop() toch nog redelijk snel gaat, voldoende om knoppen en sensors in de gaten te houden.
Hier de twee functies die shooter bedoelde:
- Code: Alles selecteren
void ServoGoTo( int pin, int value)
{
myservo.attach( pin); // attaches the servo on pin 9 to the servo object
delay(15);
myservo.write( value); // sets the servo position according to the scaled value
}
void ServoIdle()
{
myservo.detach(); //de-energizes servo
digitalWrite(straightled, HIGH); //indication led turnover straight pos
digitalWrite(turnled, LOW);
}
Dan de globale variabelen.
- Code: Alles selecteren
unsigned long previousMillis;
boolean servoDelayActive = false;
const unsigned long delaydetach = 1000; // mag ook een 'int' zijn.
Dan de vertraging starten met de knoppen.
- Code: Alles selecteren
// if button is pressed, turnover switches to straight
if (openButtonState == LOW) {
ServoGoTo( 9, 100);
previousMillis = millis(); // timestamp this moment
servoDelayActive = true; // enable the delay
}
Voor de andere knop hetzelfde, alleen de positie van 100 is dan 80.
Vervolgens ergens onderaan de loop() kijken of het al tijd is om de servo idle te maken.
- Code: Alles selecteren
void loop() {
unsigned long currentMillis = millis(); // just one currentMillis for the whole loop()
...
...
...
// Check if the delay is active and the time has finished.
if( servoDelayActive)
{
if( currentMillis - previousMillis >= delaydetach)
{
ServoIdle();
servoDelayActive = false; // disable this delay, we don't need it after this.
}
}
}
Begrijp je de bedoeling ? Het moment waarop de vertraging begint, maak je een 'timestamp' van de tijd door millis() van dat moment te onthouden. Daarna kijken of de tijd al verlopen is. Maar wel met een variabele die aangeeft of de vertraging op dat moment actief is.
Alles is dus eenmalig. Daarom hoeft de 'previousMillis' niet opgehoogd te worden. Als de vertraging over is en ServoIdle() is uitgevoerd, dan is het klaar. Wat de waarde van 'previousMillis' dan is, dat maakt niet uit, want de 'servoDelayActive' heeft de vertraging disabled.
- maartentukker
- Berichten: 37
- Geregistreerd: 07 Okt 2016, 10:33
Re: modeltrein besturing
Elke keer als ik de arduino opnieuw aan zet gaan de settings naar default, zoals aangegeven in de setup.
Is het mogelijk om de laatste servo, LED, relais standen te onthouden en deze bij opnieuw aanzetten meteen in de juiste positie te laten en weer te geven (led) waar nodig?
Nu gaan bv bij de servo programmering tbv de wissels de led's niet aan, tot ik op een knop druk en dus de servo naar die stand gaat en daarmee de desbetreffende led ook gaat branden. Daarvoor blijft de servo dan ook tsjitteren omdat deze nog geen detach opdracht gehad heeft.
Het zou mooi zijn als ik de stroom aan zet voor de treinbesturing, ik niet eerst alle wissels handmatig moet aansturen en daarmee een begin positie krijg. Dit geldt dan natuurlijk ook voor de trein detektie met reed modules, mits de trein recht boven een reed staat.
Is het mogelijk om de laatste servo, LED, relais standen te onthouden en deze bij opnieuw aanzetten meteen in de juiste positie te laten en weer te geven (led) waar nodig?
Nu gaan bv bij de servo programmering tbv de wissels de led's niet aan, tot ik op een knop druk en dus de servo naar die stand gaat en daarmee de desbetreffende led ook gaat branden. Daarvoor blijft de servo dan ook tsjitteren omdat deze nog geen detach opdracht gehad heeft.
Het zou mooi zijn als ik de stroom aan zet voor de treinbesturing, ik niet eerst alle wissels handmatig moet aansturen en daarmee een begin positie krijg. Dit geldt dan natuurlijk ook voor de trein detektie met reed modules, mits de trein recht boven een reed staat.
- maartentukker
- Berichten: 37
- Geregistreerd: 07 Okt 2016, 10:33
Re: modeltrein besturing
Die uitleg over millis, maakt alles een stuk duidelijker . Bedankt! Ik ga het straks aanpassen en proberen!!
Re: modeltrein besturing
Je kunt het in EEPROM opslaan.
Bijvoorbeeld bij een Arduino Uno kun je de interne EEPROM 100000 (100k) keer schrijven voordat een geheugentje van het EEPROM stuk is.
Bij de nieuwere processoren is er geen interne EEPROM. De externe EEPROMs zijn goedkoop, 32kbyte voor 50 cent.
Er zijn verschillende manier om het EEPROM te gebruiken : https://www.arduino.cc/en/Reference/EEPROM
Wat gebeurt er als de stroom van de Arduino uit viel, terwijl die naar EEPROM aan het schrijven was ?
Daarom schrijf ik op hoe het EEPROM is ingedeeld, en ik voeg daar een checksum aan toe.
Je kunt een 'struct' maken met allerlei variabelen, en die via een EEPROM.update() schrijven, dan wordt de waarden die niet wijzigen ook niet opnieuw geschreven.
Bijvoorbeeld bij een Arduino Uno kun je de interne EEPROM 100000 (100k) keer schrijven voordat een geheugentje van het EEPROM stuk is.
Bij de nieuwere processoren is er geen interne EEPROM. De externe EEPROMs zijn goedkoop, 32kbyte voor 50 cent.
- Code: Alles selecteren
void ServoGoTo( int pin, int value)
{
myservo.attach( pin); // attaches the servo on pin 9 to the servo object
delay(15);
myservo.write( value); // sets the servo position according to the scaled value
EEPROM.write( 0, (byte) value); // store last value of servo in eeprom location 0
}
- Code: Alles selecteren
void setup() {
int lastServoValue = EEPROM.read( 0); // read byte from location 0
...
Er zijn verschillende manier om het EEPROM te gebruiken : https://www.arduino.cc/en/Reference/EEPROM
Wat gebeurt er als de stroom van de Arduino uit viel, terwijl die naar EEPROM aan het schrijven was ?
Daarom schrijf ik op hoe het EEPROM is ingedeeld, en ik voeg daar een checksum aan toe.
Je kunt een 'struct' maken met allerlei variabelen, en die via een EEPROM.update() schrijven, dan wordt de waarden die niet wijzigen ook niet opnieuw geschreven.
Re: modeltrein besturing
eeprom alleen doen als de spanning minder wordtm dus een simpele elco is eigelijk al genoeg.
als spanning wegvalt heb je toch een probleem, want alle servos bewegen als je de voeding aansluit
en als er een as op de wissel staat gaat deze eraf.
denk ook aan een tegenveer voor het openrijden.
als spanning wegvalt heb je toch een probleem, want alle servos bewegen als je de voeding aansluit
en als er een as op de wissel staat gaat deze eraf.
denk ook aan een tegenveer voor het openrijden.
paul deelen
shooter@home.nl
shooter@home.nl
- maartentukker
- Berichten: 37
- Geregistreerd: 07 Okt 2016, 10:33
Re: modeltrein besturing
Ik heb de code herschreven volgens onderstaand concept, maar ik krijg steeds de volgende foutmelding:
ldr_en_servo_combinatie_millis_2.ino:113:1: error: expected declaration before '}' token
Fout bij compileren.
Maar ik kom er maar niet achter waar het hem in zit, ik heb al van alles geprobeerd, hebben jullie enig idee?
cpp code
ldr_en_servo_combinatie_millis_2.ino:113:1: error: expected declaration before '}' token
Fout bij compileren.
Maar ik kom er maar niet achter waar het hem in zit, ik heb al van alles geprobeerd, hebben jullie enig idee?
cpp code
// LDR data
// set pin numbers:
const int LDRPin[] = {2,3}; // the number of the LDR pins
const int ledPin1 = 4; // the number of ledPin block in
const int ledPin2 = 5; // the number of ledPin block out
// variables will change:
int LDRState = 1; // variable for reading the LDR status
// __________________________________________________________
// servo data
#include <Servo.h>
Servo myservo; // create servo object to control a servo
// constants
int openButtonPin = 10;
int closeButtonPin = 11;
int servoPin = 9;
int straightled = 6;
int turnled = 7;
// millis for servo instead of delay
unsigned long previousMillis;
boolean servoDelayActive = false;
const unsigned long delaydetach = 1000; // mag ook een int zijn
//variables
int servoPos = 80; // the current server position. Change it to whatever position you want your claw to start out at.
int openButtonState = 0;
int closeButtonState = 0;
void setup() {
Serial.begin(9600);
Serial.print("ldr en servo combinatie millis");
// LDR setup
// initialize the LED pin as an output:
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
// initialize the pushbutton pin as an input:
for(int x=0; x<2; x++)
{
pinMode(LDRPin[x], INPUT);
}
// servo setup
// setup the input pins on the Arduino
pinMode(openButtonPin, INPUT);
pinMode(closeButtonPin, INPUT);
pinMode(straightled, OUTPUT);
pinMode(turnled, OUTPUT);
// create the servo object
myservo.attach(servoPin); // attaches the servo to the servo object
myservo.write(servoPos);
}
void loop(){
unsigned long currentMillis = millis(); // just one currentMillis for the whole loop ()
// read the state of the LDR value one by one (2 in total in this case):
for(int x=0; x<2; x++)
{
LDRState = digitalRead(LDRPin[x]);
// check if the LDR is activated.
// if it is, the LDRState is LOW.
if (LDRState == LOW && LDRPin[x] == 2) { // x == 2 means the first LDR in line at begin of block
// turn occupation LED on:
digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin2, LOW);
}
if (LDRState == LOW && LDRPin[x] == 3) { // x == 3 means the second LDR (at pin 3) in line at the end of block
// turn block free LED on:
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, HIGH);
}
}
// servo loop
// read the state of the buttons
openButtonState = digitalRead(openButtonPin);
closeButtonState = digitalRead(closeButtonPin);
}
void ServoGoTo (int pin, int value)
{
myservo.attach(pin); // attaches the servo control on pin 9 to the servo object
delay (15);
myservo.write(value); // sets the servo position according to the scaled value
}
void ServoIdle ()
{
myservo.detach(); //de-energizes servo control
}
}
}
if (openButtonState == LOW) { //if button is pressed turnover switches to bend
ServoGoTo (9, 100);
previousMillis = millis(); // timestamp at this moment
servoDelayActive = true; // enable the delay
digitalWrite (straightled, LOW);
digitalWrite (turnled, HIGH);
}
if (closeButtonstate == LOW) {
ServoGoTo (9, 80);
previousMillis = millis();
servoDelayActive = true;
digitalWrite (straightled, HIGH);
digitalWrite (turnled, LOW);
}
// Check if the delay is active and the time has finished.
if (servoDelayActive) {
if (currentMillis - previousMillis >= delaydetach) {
ServIdle();
servoDelayActive = false; // disable this delay, we don't need it after this
}
}
// print the servo position to the serial console
Serial.println(servoPos);
}
Re: modeltrein besturing
De compiler zegt dat je bij regel 113 een rommeltje van de haakjes hebt gemaakt.
Druk op Ctrl+T en zorg dat code in een functie ook code in een functie is, en dat een functie ook een functie is.
De setup() en loop() zijn functies. Als je zelf een functie maakt, dan staat die op hetzelfde niveau als setup() en loop(). Dus niet binnen een andere functie.
Druk op Ctrl+T en zorg dat code in een functie ook code in een functie is, en dat een functie ook een functie is.
De setup() en loop() zijn functies. Als je zelf een functie maakt, dan staat die op hetzelfde niveau als setup() en loop(). Dus niet binnen een andere functie.
- Code: Alles selecteren
void setup()
{
...
}
void loop()
{
...
myFirstFunction( 112); // aanroep
...
}
void myFirstFunction( int level) // definitie van de functie
{
...
}
Re: modeltrein besturing
bij sommige moeten de functies eerst en dan pas de setup en loop.
paul deelen
shooter@home.nl
shooter@home.nl
Wie is er online?
Gebruikers in dit forum: Geen geregistreerde gebruikers en 40 gasten