Aiutino per Treno2 la vendetta :D

Ciao a tutti,
dato che sono un testone sto cercando di superare i miei limiti... Altro che scalate Alpine!
Sto cercado di modificare uno Sketch di DATAMAN, volevo realizzare un'animazione ferroviaria con 2 treni... Treno A parte dopo X min. muove il servo P.L. accende i 2 led e dopo X min spegne i led e servo. Arrivo in stazione sollecita Reed1 e parte il trenoB con "stessa animazione" arriva in stazione sollecita Reed2 e ricomincia.
Tutto questo con fantastico entusiasmo, quando vado a compilare la parte del treno B e mi si incrociano tutte le mie sicurezze in non riuscire ad andare avanti... Così come compilato sembra che nella parte B dello Sketch ci sia un nodo che non mi fà nemmeno lampeggiare i 2 led del P.L.

Se qualcuno può dirmi perchè non funziona vince il premio Gentilezza di Natale.

Grazie Marco
Treno_Prova_12_4.ino (5.4 KB)

/* Descrizione:
- Parte il treno e dopo X secondi si abbassa il PL e lampeggia la croce di S. Andrea, finché il treno arriva in stazione.
- In stazione, con il servo B scambia i deviatoio e parte il treno B chiude il contatto reed e il treno si ferma. Si spegne la croce di S. Andrea.
- Dopo 2 minuti, riprende a lampeggiare la croce di S. Andrea e il treno riparte.
*/
#include<Servo.h>
const int servoPinA = 4;
const int servoPinB = 7; // non voglio complicare lo shetck uso direttamente nel 
                         // Loop i igradi che mi servono, da 0 a 45 gradi per i deviatoi
                         // da 0 a 90gradi per il passaggio a livello
Servo myservoA;
int posA=5;

Servo myservoB;
int posB=50;
int posC=95;

const byte TEST = 8; // led di test per debug

const byte  REED = 2;  // pin di input a cui è collegato il contatto reed verso massa.
const byte  REEDB = 3;
const byte LED_A = 13; // led A della croce di S. Andrea
                                    // N.B.: Il pin 13 lampeggia all'accensione per la presenza del bootloader.
const byte LED_B = 12; // led B della croce di S. Andrea
const byte TRENO = 10; // Treno pilotato dal pin digitale 10
const byte TRENOB = 11;

byte statoReedPrec = 0; // stato precedente del contatto reed
byte marcia=1;     // Stato del treno. Il treno partirà nel loop accelerando.
byte marciaPrec=0; // Stato precedente del treno.

byte statoReedPrecB = 0; // stato precedente del contatto reed
byte marciaPrecB=0;

unsigned long t1;  // annota millis() per i 2 minuti di attesa TRENOA
unsigned long t2;  // annota millis() per l'accelerazione e la frenatura del treno.
unsigned long t3;
unsigned long t1B;// annota millis() per i 2 minuti di attesa TRENOB
unsigned long t2B;// annota millis() per l'accelerazione e la frenatura del treno.
unsigned long t4;
byte vel=5;    // Velocità del treno durante l'avviamento e la frenatura.
byte velB=5;

void setup()
{
myservoA.attach(4);
myservoB.attach(7);  

myservoA.write(posA);
myservoB.write(posB);

pinMode(TEST, OUTPUT);

pinMode(LED_A, OUTPUT);
pinMode(LED_B, OUTPUT);
pinMode(TRENO, OUTPUT);
pinMode(TRENOB, OUTPUT);

pinMode(REEDB, INPUT);
pinMode(REEDB, INPUT_PULLUP);

pinMode(REED, INPUT);
pinMode(REED, INPUT_PULLUP); // Resistenza di pullup interna per mettere il pulsante verso massa.
            // Il contatto reed verso massa è anche comodo perché non devi portare fuori il +V.
            // Metti un condensatore da 1uF (meglio se con 100 ohm in serie) tra il pin di ingresso e
            // massa come antirimbalzo (un contatto reed fa meno rimbalzi).
delay(12); // Per evitare che millis() sia minore di 11.
}

void loop()
{
if(marcia==1) // Se marcia=1 accelera fino a 255.
  {
  if(marciaPrec==0) {t2=millis()-11; marciaPrec=1;}
  if(vel<=245 && millis()-t2>10)
    {vel+=10; analogWrite(TRENO,vel); t2=millis();}
   if(millis()-t3>10000) { myservoA.write(posC);}
   //passaggio a livello si chiude
  }
else          // Se marcia=0 rallenta fino a 5 e ferma il treno. 
  {
  if(marciaPrec==1) {t2=millis(); marciaPrec=0; } 
  if(vel>=15 && millis()-t2>10)
  {vel-=10; t2=millis(); if(vel>5) analogWrite(TRENO,vel); else analogWrite(TRENO,0);}
  }

// ----- Croce di S. Andrea -----
if(vel>5)           //myservoA Passaggio a livello chiuso dopo il tempo millis
if(millis()-t3>10000)// Se il treno cammina, lampeggiano alternativamente a 1Hz.
  {
  if(millis()%1000<500) {digitalWrite(LED_B, LOW); digitalWrite(LED_A, HIGH);} // spegne il LED B e accende il LED A.
  else                  {digitalWrite(LED_A, LOW); digitalWrite(LED_B, HIGH);} // spegne il LED A e accende il LED B.
                     
  }

if(millis()-t3>20000) {digitalWrite(LED_A, LOW); digitalWrite(LED_B, LOW);myservoA.write(posA);} // Se il treno è fermo, spegne entrambe.
delay(15);
// ------------------------------------------------------------//myservoA Passaggio a livello aperto
  
if(!digitalRead(REED) && statoReedPrec==1) // Nel momento in cui il treno arriva sul reed
  {
  statoReedPrec=0;
  marcia=0; // Ferma il treno.
  
  }
if(digitalRead(REED)) statoReedPrec=1;


//BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB

if(marcia==0) // Se marcia=0 TRENO B accelera fino a 255.
  {
  if(marciaPrecB==0) {t2B=millis()-11; marciaPrecB=1;}
  if(velB<=245 && millis()-t2B>10)
    {velB+=10; analogWrite(TRENOB,velB); t2B=millis();}
  }
else          // Se marcia=0 rallenta fino a 5 e ferma il treno. 
  {
  if(marciaPrecB==1) {t2B=millis(); marciaPrecB=0;}
  if(velB>=15 && millis()-t2B>10)
  {velB-=10; t2B=millis(); if(velB>5) analogWrite(TRENOB,velB); 
  else analogWrite(TRENOB,0);}
  }

// ----- Croce di S. Andrea -----
if(velB>5){
if(millis()-t4>20000) //Non riesco a mettere un timer per questo evento???
// Se il treno cammina, lampeggiano alternativamente a 1Hz.
   if(millis()%1000<500) {digitalWrite(LED_B, LOW); digitalWrite(LED_A, HIGH);} // spegne il LED B e accende il LED A.
  else                   {digitalWrite(LED_A, LOW); digitalWrite(LED_B, HIGH);} // spegne il LED A e accende il LED B.
  }
if(millis()-t3>30000) {digitalWrite(LED_A, LOW); digitalWrite(LED_B, LOW);} // Se il treno è fermo, spegne entrambe.
// ------------------------------  
if(!digitalRead(REEDB) && statoReedPrecB==1)
{
statoReedPrecB=0;
delay(50);
marcia=1;
  }
if(digitalRead(REEDB)) statoReedPrecB=1;
} // END loop()

Ci sono troppi punti sotto condizione in cui vengono comandati gli stessi PIN di uscita.

Qui:

if (vel > 5)        //myservoA Passaggio a livello chiuso dopo il tempo millis
    if (millis() - t3 > 10000) // Se il treno cammina, lampeggiano alternativamente a 1Hz.
    {
        if (millis() % 1000 < 500) {
            digitalWrite(LED_B, LOW);    // spegne il LED B e accende il LED A.
            digitalWrite(LED_A, HIGH);
        }
        else                  {
            digitalWrite(LED_A, LOW);    // spegne il LED A e accende il LED B.
            digitalWrite(LED_B, HIGH);
        }

    }

qui:

if (velB > 5) {
    if (millis() - t4 > 20000) //Non riesco a mettere un timer per questo evento???
        // Se il treno cammina, lampeggiano alternativamente a 1Hz.
        if (millis() % 1000 < 500) {
            digitalWrite(LED_B, LOW);    // spegne il LED B e accende il LED A.
            digitalWrite(LED_A, HIGH);
        }
        else                   {
            digitalWrite(LED_A, LOW);    // spegne il LED A e accende il LED B.
            digitalWrite(LED_B, HIGH);
        }
}

e qui:

if (millis() - t3 > 30000) {
    digitalWrite(LED_A, LOW);    // Se il treno è fermo, spegne entrambe.
    digitalWrite(LED_B, LOW);
}

Evidentemente queste condizioni interferiscono tra loro. Va rivista la logica. magari iniziando a semplificare, trasformando il comando dei LED in una sola condizione di lampeggio abilitato o meno:

if (lampeggioAbilitato) {
    bool sl = (millis() % 1000  <  500); 
    digitalWrite(LED_B, sl);
    digitalWrite(LED_A, !sl);
}
else {
    digitalWrite(LED_A, LOW);   // entrambi spenti
    digitalWrite(LED_B, LOW);
}

Nel resto del programma dovrai solo mettere la variabile 'lampeggioAbilitato' a uno o zero quando vuoi.

Grazie Claudio_FF !

Nel primo Sketch originale di DATAMAN con i soli LED funzionava alla grande, e non mi ero preoccupato della ripetizione, della serie anche se "brutto" funzionarà...

Mi metto a fare un pò di prove e vediamo se ci riesco.

Saluti Marco

Buonasera,

ho provato la modifica ma funziona solo il ritardo P.L. alla partenza del primo treno A, nel secondo ciclo treno B non vede la sequenza con il ritardo millis, ho provato anche a dare alla fine del primo ciclo il valore alla t3 = 0 ma non mi considera... Ho anche provato a usare delay al posto dei millis per semplificare ma niente da fare... Sembra come al solito che faccio "casini" con le parentesi eppure alla fine è un pò come l'esercizio del semaforo...
Ma non è che con la libreria servo ci sono dei problemi con certe funzioni?
Ciao Marco
P.S. La descrizione dentro lo sketch non è giusta comunque è un derivato da quella di DATAMAN ;D
Treno_DelForum.ino (3.7 KB)

Che è sbagliato. Non va azzerato, ma portato al valore attuale di millis, in modo che solo dopo altri cinque secondi la condizione:

if (millis() - t3 > 5000)

ritornerà vera.

Grazie Claudio_FF,

ho provato comunque, ma lo sketch, rimane "imballato" lo stesso la seconda parte rimane con la "parte" passaggio a livello che si attiva alla partenza del trenoB...

Le ho provate tutte, non sò che pesci prendere.
Marco

Io non lo vinco di sicuro e fossi in te non perderei ancora tempo a modificare lo sketch.

Riscrivilo da zero, usando le funzioni anziché tutto quel macello di if, che non se ne capisce nulla.

C'è un solo treno per il momento, che deve fare sto benedetto treno?

Penso che debba avviarsi e mi pare di capire che non deve partire a razzo, ma una partenza morbida, quindi gradatamente (quanto) deve accelerare e diciamo che basta qui, che già la vedo complicata.

Se può essere utile qui c'è un qualcosa di simile ad un passaggio a livello.

Qui lo sketch al simulatore online:

Ciao.

Ciao Maurotec,
i treni sono due, si alternano in stazione e dopo la partenza, x min lo sketch mi dovrebbe far abbassare il P.L. alternare i led e poi tornare allo stato di partenza con il treno ancora in movimento.
Avevo fatto funzionare già tutto senza le pause, ovvero se il P.L. e i Led si accendono alla partenza
del treno non c'è problema invece inserendo le pause... Ciao non và, oppure l'evento TrenoA funziona e l'evento trenoB non mi funziona ne i led ne il P.L. ;(

Comunque ci metterò le mani domani, dato che non devo vincere un premio ma solo soddisfazione personale continuerò a studiarci su.
Saluti da Marco e grazie.

Fai un po come di pare, ma con questo approccio non esci.
Io mi concentrerei sulla partenza, accelerazione e decelerazione fino allo stop, ovviamente userei le funzioni, in modo che sia modulare così da permettermi di introdurre altre funzioni (caratteristiche come il passaggio a livello ecc) senza compromettere le attuali funzionalità. Sono cosciente che parlo Arabo, ma non sono capace di scrivere un algoritmo senza scomporre il codice in funzioni.

Gia il codice che ha postato @Claudio_FF è un inizio di scomposizione e non ci vuole molto a metterlo in una funzione di nome "lampeggiante", anzi:

void lampeggiante() {
    if (lampeggioAbilitato) {
        bool sl = (millis() % 1000  <  500); 
        digitalWrite(LED_B, sl);
        digitalWrite(LED_A, !sl);
    }  else {
        digitalWrite(LED_A, LOW);   // entrambi spenti
        digitalWrite(LED_B, LOW);
    }
}

ah già, la funzione la devi chiamare continuamente nel loop() e basta scrivere:

void loop() {
    lampeggiante();
    // ecc
}

Devi anche dichiarare la variabile lampeggioAbilitato globale.
Quando vuoi il lampeggio gli assegni true, per spegnerlo gli assegni a false.

Farei qualcosa di simile con l'accelerazione e decedelerazione.

Ciao.

Ciao.

Un altro errore è usare la stessa variabile interruttore 'marcia' per entrambi i treni, e anche la stessa variabile temporale 't2'.

I problemi sono due, il primo è che le fasi di funzionamento non sono ben esplicite, il secondo è che ci sono quattro processi che devono avanzare in parallelo senza interferire l'uno con l'altro. Non avere fasi esplicite (ad esempio formalizzate tramite macchine a stati) rende le modifiche complicate.

Ho scomposto il programma in funzioni per renderlo più ordinato e leggibile. Dovrebbe solo partire il treno A (perché la variabile 'marcia' è inizialmente impostata a 1) e fermarsi. Ogni altra condizione/comportamento è da aggiungere. La parte gestione passaggio a livello (funzione 'gestionePL') è da scrivere.

In particolare sono da scrivere:

  • la condizione di partenza del treno B
  • la condizione di riavvio del treno A
  • la condizione di avvio del lampeggio
  • la condizione di stop del lampeggio
  • le temporizzazioni del passaggio a livello
  • il comando del servomotore?
/*  Descrizione: (non più valida)
    - Parte il treno e lampeggia la croce di S. Andrea, finché il treno entra nella galleria.
    - In galleria, il treno chiude il contatto reed e il treno si ferma. Si spegne la croce di S. Andrea.
    - Dopo 2 minuti, riprende a lampeggiare la croce di S. Andrea e il treno riparte.
*/

const byte  REED = 2;    // pin di input con contatto reed verso massa.
const byte  REEDB = 3;
const byte LED_A = 13;   // led A della croce di S. Andrea
// N.B.: Il pin 13 lampeggia all'accensione per la presenza del bootloader.
const byte LED_B = 12;   // led B della croce di S. Andrea
const byte TRENO = 10;   // Treno A pilotato dal pin digitale 10
const byte TRENOB = 11;

byte statoReedPrec = 0;  // stato precedente del contatto reed treno A
byte statoReedPrecB = 0; // stato precedente del contatto reed treno B
byte marcia = 1;         // Stato del trenoA. Il treno partirà nel loop accelerando.
byte marciaPrec = 0;     // Stato precedente del treno.
byte marciaB = 0;        // Stato del trenoB. Il treno partirà nel loop accelerando.
byte marciaPrecB = 0;

byte lampeggioAbilitato = 0;

unsigned long now; // tempo attuale ad ogni ciclo
unsigned long t2;  // annota millis() per l'accelerazione e la frenatura del treno A
unsigned long t2b; // annota millis() per l'accelerazione e la frenatura del treno B

//unsigned long t1;  // annota millis() per i 2 minuti di attesa.
//unsigned long t3;  // Timer Evento P.L.

byte vel = 0;            // Velocità treno
byte velB = 0;

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

void setup()
{
    pinMode(LED_A, OUTPUT);
    pinMode(LED_B, OUTPUT);
    pinMode(TRENO, OUTPUT);
    pinMode(TRENOB, OUTPUT);
    pinMode(REEDB, INPUT_PULLUP);
    pinMode(REED, INPUT_PULLUP);
    // Resistenza di pullup interna per mettere il pulsante verso massa.
    // Il contatto reed verso massa è anche comodo perché non devi portare fuori il +V.
    // Metti un condensatore da 1uF (meglio se con 100 ohm in serie) tra il pin di ingresso e
    // massa come antirimbalzo (un contatto reed fa meno rimbalzi).
    // delay(100); // Per evitare che millis() iniziale sia minore di 11.
}

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

void loop()
{
    now = millis();
    gestioneTrenoA();
    gestioneTrenoB();
    gestionePL();
    lampeggio();


    // condizione di arresto treno A
    if (digitalRead(REED) == 0  &&  statoReedPrec == 1)
    {
        statoReedPrec = 0;
        marcia = 0; // Ferma il treno A
    }
    if (digitalRead(REED) == 1) statoReedPrec = 1;  // riabilita reed treno A


    // condizione di arresto treno B
    if (digitalRead(REEDB) == 0  &&  statoReedPrecB == 1)
    {
        statoReedPrecB = 0;
        marciaB = 0; // ferma treno B
    }
    if (digitalRead(REEDB) == 1) statoReedPrecB = 1;  // riabilita reed treno B
}

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

void gestioneTrenoA()
{
    if (marcia == 1)  // Se marcia=1 accelera fino a 255.
    {
        // se appena attivato
        if (marciaPrec == 0) { t2 = now;  marciaPrec = 1; }

        // step accelerazione
        if (vel < 255  &&  now-t2 >= 10)
        {
            vel += 5;
            analogWrite(TRENO, vel);
            t2 = now;
        }
    }
    else // Se marcia=0 rallenta fino a 5 e ferma il treno.
    {
        // se appena disattivato
        if (marciaPrec == 1) { t2 = now;  marciaPrec = 0; }

        // step decelerazione
        if (vel > 0  &&  now-t2 >= 10)
        {
            vel -= 5;
            t2 = now;
            analogWrite(TRENO, vel);
        }
    }
}

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

void gestioneTrenoB()
{
    if (marciaB == 1) // Se marciaB=1 TRENO B accelera fino a 255.
    {
        // se appena attivato
        if (marciaPrecB == 0) { t2b = now;  marciaPrecB = 1; }

        // step accelerazione
        if (velB < 255  &&  now-t2b >= 10)
        {
            velB += 5;
            analogWrite(TRENOB, velB);
            t2b = now;
        }
    }
    else  // Se marciaB=0 rallenta fino a 5 e ferma il treno.
    {
        // se appena disattivato
        if (marciaPrecB == 1) { t2b = now;  marciaPrecB = 0; }

        // step decelerazione
        if (velB > 0  &&  now-t2b >= 10)
        {
            velB -= 5;
            t2b = now;
            analogWrite(TRENOB, velB);
        }
    }
}

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

void lampeggio()
{
    if (lampeggioAbilitato==1) {
        bool sl = (now % 1000  <  500);
        digitalWrite(LED_B, sl);
        digitalWrite(LED_A, !sl);
    }
    else {
        digitalWrite(LED_A, LOW);   // entrambi spenti
        digitalWrite(LED_B, LOW);
    }
}

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

void gestionePL()
{
    
}

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

Ciao, Marco
Bentornato! :slight_smile:

@Claudio_FF , now è in millisecondi...

        if (marciaPrec == 0) { t2 = now - 11;  marciaPrec = 1; }
        // step accelerazione
        if (vel <= 245  &&  now-t2 > 10)

Non ricordo a che servisse, ma ora mi rendo conto che sicuramente è qualcosa di brutto, critico e rende critiche le modifiche!

Da quanto intuisco serviva, oltre che come indispensabile riconoscimento dei fronti per la variabile di controllo 'marcia', anche per effettuare subito il primo step di accelerazione/decelerazione. Cosa praticamente inutile visto che non mettere il -11 comporta solamente un centesimo di secondo di ritardo nella partenza o arresto :wink: C'erano un po' di altre cosette da ordinare e ho aggiornato il codice togliendo quel -11.

Ri-edito ho provato lo sketch e ho notato che il treno (pin10) parte e si ferma con il (REED) e poi il trenoB non parte rimane tutto fermo.

Rieccomi,

grazie Claudio_FF, ora mi metto un pò a studiare per farlo funzionare...

Ciao Dataman! Hai visto non demordo, a parte che questo modo di programmare non lo avevo mai visto... :upside_down_face:

P.S. Ci tengo a precisare che la prima parte (commento) dello sketch è sbaglaiata il commento giusto è quello scritto nel primo post.

Saluti Marco

No mettiti a studiare su come mai il trenoA si avvia, mentre il trenoB resta fermo. Non deve fare altro per adesso, devi capire tu come mai il codice lavora.

Ecco appunto, prendi confidenza con questo modo di programmare, che poi è il modo minimale, infatti non ci sono array, strutture, classi ecc. Invece credo che ti riferisca al fatto che si è concentrato a fare una funzione ad es. gestioneTrenoA(), poi visto che trenoA e trenoB hanno in comune il fatto che accelerano e decelerano allo stesso modo, fatta la funzione trenoA, per trenoB è bastato copiare e incollare il codice in un altra funzione e difetti analizzale le funzioni gestioneTrenoA e gestioneTrenoB sono identiche tranne il fatto che una agisce sul pin 10 e l'altra sul 11.

Cosa interessante è il fatto che l'implementazione di claudio oltre a funzionare torna utile per l'evoluzione del codice. Ad esempio il problema della ripetizione di codice nelle due funzioni gestioneTrenoA e trenoB è facilmente risolvibile, ma per adesso è bene lasciare questa ripetizione.

Già da questa implementazione è facile (almeno per me) derivare una classe Treno della quale dovrai creare due istanze.

Ciao.

Beh io non ho modificato minimamente la logica (che deriva dal codice originale di datman), ho solo scomposto in funzioni, corretto i nomi di variabili errate, tolto refusi o "fronzoli" non rilevanti, indentato. Il problema è che non è stata progettata a stati espliciti, ma "ad interazioni" tra diverse parti (più simile a una logica a relé) da cui gli stati "emergono" durante il funzionamento. Questo rende ogni modifica complicata.

Dal primo post un po' riarrangiato:

volevo realizzare un'animazione ferroviaria con 2 treni...

  • Treno A parte dopo X min.
  • (contemporaneamente) muove il servo P.L. accende i 2 led (lampeggianti che) dopo Y min si spegneranno e il servo tornerà a riposo.
  • Arrivo in stazione sollecita Reed1 e parte il trenoB con "stessa animazione", arriva in stazione sollecita Reed2 e ricomincia.

Per me la prima cosa da fare in assoluto è disegnare il diagramma delle fasi di funzionamento, come prima traduzione della descrizione in italiano:

La doppia barra orizzontale indica che da li bisogna partire insieme (in parallelo) ad eseguire le sequenze sottostanti.

Ora la prima domanda è: questo diagramma rappresenta oppure no la sequenza che si vuole realizzare? Se la risposta è si, allora si procede con il dettaglio delle operazioni da svolgere in ogni fase (solo successivamente da tradurre in istruzioni). Ma ogni modifica di funzionamento si fa partendo prima di tutto dal diagramma degli stati. Ad esempio i treni potrebbero muoversi contemporaneamente, a velocità diverse, fare pause ecc, ma tutto questo deve essere disegnato in chiaro sul diagramma prima di ogni altra cosa.

Ti pare niente, già il fatto che capisco cosa fa senza bisogno di eseguirlo al simulatore dovrebbe fare riflettere.

Certo si dovrebbe (anzi si deve) ma io non lo faccio quasi mai, o meglio lo faccio quando mi rendo conto che il codice che ho scritto è sbagliato, e il codice stesso non mi aiuta, allora mi rendo conto che devo disegnare, scrivere, scomporre ecc. Solitamente procedo dal basso verso l'alto, ma passo spesso alla visione dall'alto verso il basso, mi viene ormai naturale, e così via passo passo si aggiungono le funzionalità a patto però che le funzioni che scrivo non si influenzino casualmente. Nell'implementazione cerco di creare dei pezzi di puzzle flessibili e riutilizzabile.

In altri post ho visto che hai la tendenza a scrivere le if con le azioni sullo stesso rigo, ma quanto lo odio. Cioè scrivi codice bellissimo è poi mi ci metti un poco di cacchina, rovinando il tutto. :grinning:

PS: che belli i trenini, ciuf ciuf, ne ho ancora uno (la sola locomotiva è rimasta) dove ci metti l'acqua è fa il fumo.

Ciao.

Ora ho messo tutti a dormire,
la moglie è d'accordo che non devo più sistemare nulla in casa...

Quindi ora, dal mio bricolege di tentoni e incroci mentali... Decuco che il grafico fatto torna al 100%
fantastico, adesso devo vedere perchè lavora solo il trenoA... Era più facile pagare il macchinista del trenoB ! :laughing:

Saluti Marco

Sì, purtroppo quel programma è nato un pezzetto per volta, cercando di capire progressivamente che cosa volesse fare esattamente, e inoltre io avevo 4 anni di esperienza in meno rispetto agli attuali 7... :slight_smile:

Perché prima impari a fare il fuoco senza dare fuoco alla casa (con la legna intendo) e poi impari a cucinare. A parte gli scherzi, rileggi il suo post

La qualità del codice si vede anche dal fatto che rimuovendo una sola chiamata a funzione disabiliti uno dei treni, oppure se avessi 3 treni basterebbe aggiungere una chiamata a funzione. La modularità porta a questi vantaggi, una volta imparato a scomporre e rendere modulare le funzionalità, le puoi abilitare o disabilitare e il resto del codice continua a funzionare.

PS: quella del fuoco a legna non è una battuta, prova a cucinare 2 uova fritte senza che prenda fuoco l'olio. :grinning:

Ciao.

Rieccomi,

sto elaborando... Comunque a quest'ora mi era sfuggita la "byte marcia = 1; " che faceva partire il trenoA c'ho messo un'ora ma alla fine... :laughing:
Ora sono riuscito a far partire TrenoA, farlo fermare e subito ripartire TrenoB, ma così non mi piace ancora voglio inserire delle pause in più e ora son dolori... :nerd_face:

Marco