train control project

Als U een gezamenlijk project wil starten of aan projecten van anderen mee wilt werken.
Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: train control project

Berichtdoor Koepel » 02 Okt 2016, 05:27

Tja, ik heb er toch gemengde gevoelens bij. De basis vind ik nog steeds niet in orde. Ik zou de state machine veel strakker en cleaner willen hebben.

Zou je ook kunnen doen wat ik en shooter al schreven ?
Dus een constructie zoals deze:
Code: Alles selecteren
  if (currentMillis - previous_Acc_Millis >= motor_Acc_Interval) {    // check interval timing
    previous_Acc_Millis = currentMillis;                    // because shooter and Koepel told me so.

    Speed = Speed + 1;                                                //add 1 to speed
    analogWrite(motor_Pin, Speed);                                    //send Speed to motor_Pin
    ...

Dat is mooier, duidelijker, beter, en het voegt een extra veiligheid toe.

Kijk hier eens naar, en scroll naar beneden waar staat "Option 1" en "Option 2".
http://playground.arduino.cc/Code/TimingRollover#arithmetic

Normaal word "previousMillis = currentMillis" gebruikt.
Ik heb een project waarbij ik een software timer met millis() heb voor seconden, minuten en uren. Ik wil graag dat het precies in de pas blijft met de tijd, ook als Ethernet druk bezig is voor een webpagina, of als er een groot bestand naar de SD kaart wordt geschreven. Dat is de enige plaats waarbij ik de "previousMillis" ophoog met de interval.

Advertisement

Gebruikers-avatar
Berichten: 31
Geregistreerd: 08 Sep 2016, 21:50

Re: train control project

Berichtdoor Kitemasters » 04 Okt 2016, 01:20

update,

- previous_Acc_Millis = currentMillis is nu ingevoegd.

- ipv de variable "direct" de waarde throu/false te geven en die in de regel
"digitalWrite(direction_Pin, HIGH);" te vertalen naar high/low.
nu de waarde high/low gegeven zodat de variable direct ingezet kan worden.
"digitalWrite(direction_Pin, direct);"

- state_IDLE eruit gehaald deze had verder geen functie

- geprobeerd de state switch op interval te zetten.
// Run the state machine at a fixed interval.
  if (currentMillis - previous_state_Millis >= state_interval) {

dit geeft het resultaat dat de trein gaat pulsen. (stukje rijden, stoppen, stukje rijden, stoppen. enz)
eerlijk gezegd zie ik het voordeel ook niet volgens mij verlaag je alleen de frequentie van de state switch.
(of ik snap je punt helemaal niet :oops: )

cpp code
/*
Train control
This code is developed to "test" drive
a model train between two gates made of a LED and LDR.

Parts required:
1 - arduino uno/mega or compatible
1 - arduino motor shield R3
2 - Led brite white (5mm)
2 - Ldr (A 9013 photo resistor 5mm)
2 - 10K resistor
2 - 220 Ohm resistor
1 - model train

Created 4 October 2016
by Kitemasters

This code is part of the public domain
*/
// --------CONSTANTS (won't change)---------------

int sens_L_Pin = A4; // the pin number for ldr L
int sens_R_Pin = A5; // the pin number for ldr R
int led_L_Pin = 4; // the pin number for the L LED
int led_R_Pin = 5; // the pin number for the R LED
int motor_Pin = 3; // the pin number for the motor speed
int brake_Pin = 9; // the pin number for the motor brake
int direction_Pin = 12; // the pin number for the motor direction
int current_sens_Pin = A0; // the pin number for the current sensor

int read_sens_Interval = 200; // millisecs between reading sensors
int motor_Acc_Interval = 100; // millisecs between acceleration steps
int motor_Dec_Interval = 10; // millisecs between deceleration steps

//------------ VARIABLES (will change)---------------------

unsigned long currentMillis = 0; // stores the value of millis() in each iteration of loop()
unsigned long previous_sens_Millis = 0; // will store the last time sensors are read
unsigned long previous_Acc_Millis = 0; // will store time of last acceleration step
unsigned long previous_Dec_Millis = 0; // will store time of last deceleration step

int sensLreading = 0; // declare variable and set value for left sensor reading
int sensRreading = 0; // declare variable and set value for right sensor reading
int max_Speed = 200; // declare variable and set value for maximum Speed (0 to 255)
int Speed = 0; // declare variable and set value for current Speed (0 to 255)
boolean direct = HIGH; // declare variable and set value for direction to HIGH (HIGH = left)

#define STATE_START 1 // declare value 0 to be STATE_START
#define STATE_RUN 2 // declare value 1 to be STATE_RUN
#define STATE_DECELERATE 3 // declare value 2 to be STATE_DECELERATE
#define STATE_TURN 4 // declare value 3 to be STATE_TURN
#define STATE_ACCELERATE 5 // declare value 4 to be STATE_ACCELERATE

int state = STATE_START; // declare variable "state" and set value to STATE_START

//========================================

void setup() {

Serial.begin(9600);

pinMode(led_L_Pin, OUTPUT); // set led_L_Pin as output
pinMode(led_R_Pin, OUTPUT); // set led_R_Pin as output
pinMode(motor_Pin, OUTPUT); // set motor_Pin as output
pinMode(brake_Pin, OUTPUT); // set brake_Pin as output
pinMode(direction_Pin, OUTPUT); // set direction_Pin as output
pinMode(sens_L_Pin, INPUT); // set sens_L_Pin as input
pinMode(sens_R_Pin, INPUT); // set sens_R_Pin as input
pinMode(current_sens_Pin, INPUT); // set current_sens_Pin as input

}
//========================================

void loop() {

currentMillis = millis(); // store the latest value of millis()
read_sens(); // read the sensors

switch (state) // state switch
{
case STATE_START:
Start();
break;

case STATE_ACCELERATE:
Accelerate();
break;

case STATE_DECELERATE:
Decelerate();
break;

case STATE_TURN:
Turn();
break;

case STATE_RUN:
break;
}
}
//========================================

void read_sens() {

if (currentMillis - previous_sens_Millis >= read_sens_Interval) { // time is up, so read sensors
previous_sens_Millis = currentMillis; // because shooter and Koepel told me so.// save the time we last read sensors
sensLreading = analogRead(sens_L_Pin); // read left ldr (high value means the light is off or blockt)
sensRreading = analogRead(sens_R_Pin); // read right ldr (high value means the light is off or blockt)

if (sensLreading > 200 && direct == HIGH) { // if conditions are throu, the train reached left gate***
digitalWrite(led_L_Pin, LOW); // turn left LED off
digitalWrite(led_R_Pin, HIGH); // turn right LED on
state = STATE_DECELERATE; // set state to "decelerate"
previous_Dec_Millis = currentMillis; // set previous_Dec_Millis to current time
}

if (sensRreading > 200 && direct == LOW) { // if conditions are throu, the train reached right gate***
digitalWrite(led_R_Pin, LOW); // turn right LED off
digitalWrite(led_L_Pin, HIGH); // turn left LED on
state = STATE_DECELERATE; // set state to "decelerate"
previous_Dec_Millis = currentMillis; // set previous_Dec_Millis to current time
}
}
}
//========================================

void Start() {

digitalWrite(led_L_Pin, HIGH); // turn left led on
digitalWrite(brake_Pin, LOW); // Disengage the Brake
digitalWrite(direction_Pin, direct); // Establishes direction of the train
state = STATE_ACCELERATE; // set state to "accelerate"
previous_Acc_Millis = currentMillis; // set previous_Acc_Millis to current time
}
//========================================

void Accelerate() {

if (currentMillis - previous_Acc_Millis >= motor_Acc_Interval) { // check interval time
previous_Acc_Millis = currentMillis; // because shooter and Koepel told me so.//last time of acceleration step
Speed = Speed + 1; // add 1 to speed
analogWrite(motor_Pin, Speed); // send Speed to motor_Pin
if (Speed == max_Speed) { // if speed reach max speed
state = STATE_RUN; // set state to "run"
}
}
}
//========================================

void Decelerate() {

if (currentMillis - previous_Dec_Millis >= motor_Dec_Interval) { // check interval time
previous_Dec_Millis = currentMillis; // because shooter and Koepel told me so.//last time of acceleration step
Speed = Speed - 1; // subtract 1 of speed
analogWrite(motor_Pin, Speed); // send Speed to motor_Pin
if (Speed == 0) { // if speed reach 0
state = STATE_TURN; // set state to "turn"
}
}
}
//========================================

void Turn() {

if (direct == HIGH) { // flip direction
direct = LOW;
digitalWrite(direction_Pin, direct); // establishes right direction of train
}
else {
direct = HIGH;
digitalWrite(direction_Pin, direct); // establishes left direction of train
}
state = STATE_ACCELERATE; // set state to "accelerate"
previous_Acc_Millis = currentMillis; // set previous_Acc_Millis to current time
}
//========================================END

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: train control project

Berichtdoor Koepel » 04 Okt 2016, 17:37

Mijn punt is om de hele state machine binnen één enkele software timer met millis() te maken. Dan hoef je verder nergens meer iets met millis() te doen binnen de state machine. Dan hoef je dus ook niet meer de previousMillis = currentMillis te doen als je de state wijzigt.
Maar ik ben er wat huiverig voor, om je hele sketch om te bouwen.

Als je achterover leunt, en niet aan programmeren denkt, en dan wil je iets maken dat sensoren leest en beslissingen maakt en dingen doet. Als je dat voor je ziet in afzonderlijke blokjes (of je tekent het op papier), en tussen de blokjes data stromen, dan krijg je een betere indeling. Dan is er dus een blokje voor de sensoren, en een blokje voor de state machine, en een blokje die de snelheid van de trein regelt. Vervolgens kun je ieder blokje apart in code gaan omzetten.

Als je meteen aan programmeren denkt, dan komen er al snel verschillende dingen door elkaar heen.

Gebruikers-avatar
Berichten: 31
Geregistreerd: 08 Sep 2016, 21:50

Re: train control project

Berichtdoor Kitemasters » 10 Okt 2016, 01:34

mja zit er nu al een paar dagen op te broeden maar ben er nog niet uit.

ik zou nog wel verder willen gaan voor de perfectie, ook omdat ik ooit bedacht had er een gui bij te maken zodat ik een paar dingen
via de pc zou kunnen manipuleren zoals max speed, starten en stoppen. dit zal naar ik verwacht nog meer een probleem
worden als de basis al niet goed is. En is dit wel zo? ik bedoel hebben we het hier over een schoonheidsfoutje of is dit iets dat
in een later stadium steeds meer problemen zal gaan geven. Ik heb wel gekeken naar JSP ofwel zo,n blokdiagram maar blijf naar een
leeg vel staren omdat ik vertaalslag naar code nog niet zie, ofwel wat is een apart blokje en wat niet. En alle voorbeeldjes
die ik zie lijken in mijn geval niet te passen.

Aan de andere kant, ik heb de afgelopen dagen ongeveer vier meter spoor kunnen bijleggen en het
treintje drie keer van binnen en buiten schoongemaakt zodat hij niet meer iedere keer stil blijft
staan. En nu staat het geheel al een half uur achter me te snorren als een poes 8-)

Voorlopig dus maar de code in de openbaarheid gegooid :roll:
https://create.arduino.cc/projecthub/Ma ... 3&offset=0

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: train control project

Berichtdoor Koepel » 10 Okt 2016, 07:15

Het is meer een schoonheidsfoutje, maar ik kan niet inschatten of dat problemen gaat opleveren.
Het belangrijkste is dat je loop() draait op millis(), dus daar kun je meer van die software timers met millis() aan toevoegen zonder de overige code te beïnvloeden. Des te meer je de verschillende programma onderdelen gescheiden houdt, des te eenvoudiger is het om later een onderdeel te verbeteren of te wijzigen.

Je schrijft over JSP. Zou je er dan een link bij willen geven ? Het kan namelijk meerdere dingen zijn.
Toch niet dit uit de jaren '80 : https://en.wikipedia.org/wiki/Jackson_structured_programming.
Maar welke JSP je ook bedoelt, het is een bepaalde methode, die weer tijd kost om dat te leren.

Mijn bedoeling was nu juist om niet aan programmeren te denken, en dus ook niet aan JSP ;)
Als je dingen in de echte wereld kunt indelen naar functionaliteit, dan ben je al voor 80% een goede programmeur.

Gebruikers-avatar
Berichten: 5043
Geregistreerd: 13 Mei 2013, 20:57
Woonplaats: Heemskerk

Re: train control project

Berichtdoor nicoverduin » 10 Okt 2016, 07:26

Koepel schreef:Je schrijft over JSP. Zou je er dan een link bij willen geven ? Het kan namelijk meerdere dingen zijn.
Toch niet dit uit de jaren '80 : https://en.wikipedia.org/wiki/Jackson_structured_programming.
Maar welke JSP je ook bedoelt, het is een bepaalde methode, die weer tijd kost om dat te leren.

Niets mis mee.... Ben er mee opgegroeid en pas het nog steeds toe om gedachten te ordenen. Maar ik ben wel met je eens dat de TS eerst zijn gedachten moet ordenen op functioneel gebied.
Docent HBO Technische Informatica, Embedded ontwikkelaar & elektronicus
http://www.verelec.nl

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: train control project

Berichtdoor Koepel » 10 Okt 2016, 07:35

nicoverduin schreef:Niets mis mee....

Behalve als je een JSP tool gebruikt die de code maakt, en een collega in de gegenereerde code wijzigingen gaat aanbrengen omdat hij snel even iets wilde wijzigen. Ha ha ha. :lol:

Gebruikers-avatar
Berichten: 5043
Geregistreerd: 13 Mei 2013, 20:57
Woonplaats: Heemskerk

Re: train control project

Berichtdoor nicoverduin » 10 Okt 2016, 08:35

Tja maar dat heeft niets met JSP te maken. Eerder de verkeerde persoon op de job.
Docent HBO Technische Informatica, Embedded ontwikkelaar & elektronicus
http://www.verelec.nl

Gebruikers-avatar
Berichten: 31
Geregistreerd: 08 Sep 2016, 21:50

Re: train control project

Berichtdoor Kitemasters » 23 Okt 2016, 11:51



ja die dus wel :oops: omdat hier steeds aangeraden wordt een blok diagram op papier te zetten
dacht ik dat dat bedoeld werd.

Gewoon een pak papier, potlood en een gummetje. Beste manier om het te leren.
Ff googelen op "structured programming with c++ pdf


maar omdat het geheel nu loopt als een trein heb ik besloten dit maar even te laten voor wat het is
en me te richten op het volgende sub-project de GUI.
uiteindelijk kwam ik terecht bij QT

om te leren hoe je met de seriele port werkt ben ik deze video gaan volgen
https://www.youtube.com/watch?v=s3QuNvYce1o
het stuurt een RGB led aan met drie sliders.

nu heb ik er een vraag bij.
omdat ik geen rgb led heb, heb ik gewoon drie leds gebruikt.
want dat is wat een rgb led feitelijk is dacht ik.
dan zijn er twee opties, er is een gezamenlijke - of een gezamenlijke +.
ik heb de leds aangesloten met een gezamenlijke - en elk een weerstand aan de + zijde.

nu laat de video niet zien hoe de rgb is aangesloten en bij mij werkt het natuurlijk weer
precies andersom. dat wil zeggen bij de waarde 255 is de led uit ipv aan.
de enige manier die ik kan bedenken is de leds om te draaien en de gezamenlijk - op + aan te sluiten.
maar daar ben ik wat bang voor want dat geeft naar mijn idee sluiting.
je voert dan 5v naar de digitale pin en dat kan alleen als je digitalread() gebruikt.
en in de code zet hij deze pins duidelijk in pinmode OUTPUT.
? :roll:

Gebruikers-avatar
Berichten: 5043
Geregistreerd: 13 Mei 2013, 20:57
Woonplaats: Heemskerk

Re: train control project

Berichtdoor nicoverduin » 23 Okt 2016, 12:26

Een LED moet altijd van de + naar de -. Dus de driehoek aan de + en het streepje naar de -.
Als je de waarde wilt omkeren, kun je hem gewoon inverteren zoals dat heet als volgt:
cpp code
const uint8_t LED = 3;       // bijvoorbeeld
uint8_t ledWaarde = 230; // bijvoorbeeld

analogWrite(LED, led_waarde; // de LED gaat fel oplichten als je de datapin naar de Anode hebt verbonden
ledWaarde = ~ledWaarde; // inverteer de waarde (wordt in dit geval 25) omdat elke 0 wordt "1"en omgekeerd
analogWrite(LED, ledWaarde); // de led zal nu nog een beetje oplichten


Dat tilde teken voor een variabele inverteerd dus. In dit geval staat er eerst '1110 0110' door deze te inverteren wordt het '0001 1001' en dat is gelijk aan 25 (16+9).
Mbt de LED, als de data pin aanstuurt (dus weerstand->LED anode en LED kathode->GND) noemen ze dat 'sourcing'. bij 'sinking' krijg je de + -> Weerstand-> LED anode en LED-kathode-> datapin.
Docent HBO Technische Informatica, Embedded ontwikkelaar & elektronicus
http://www.verelec.nl

VorigeVolgende

Terug naar Gezamenlijke projecten

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 5 gasten