Aiutino per Treno2 la vendetta :D

Approvo.

Non approvo, perché per rispettare il codice scritto da claudio ho dovuto mettere nel setup:

plFsm.setState(1);

A questo punto la run() non eseguirebbe correttamente la if:

void run() {
        m_onEnter = false;
        if (m_currentState != m_previousState) {
            m_previousState = m_currentState;
            timer = millis();
            m_onEnter = true;
        }
    }

Attenzione che non ho pensato di permettere di ereditare la classe, per cui tutte le variabili sono private e alcune invece potrebbero essere protected.

Mi viene in mente questo ragionamento:
Il cambio dell'auto non ha gli ingranaggi a vista, questi sono inseriti in un contenitore (la classe). Mi serve solo una interfaccia pubblica per cambiare marcia (lo stato).

Ciao.

  private:
    byte m_currentState = 0;
    byte m_previousState = 0;
    uint32_t timer;
    bool m_onEnter;
  public:
    void run() {
        m_onEnter = false;
        if (m_currentState != m_previousState) {
            m_previousState = m_currentState;
            timer = millis();
            m_onEnter = true;
        }
    }
    void setTimer() { timer = millis(); }
    uint32_t getTimer() const { return timer; }
    void setState(const byte newState) {
        m_currentState = newState;
        m_previousState = ~m_currentState;
    }

Ma anche così non è esente da possibili problemi: se si chiama setState passando lo stato attuale, lo stato rimane lo stesso ma il tempo e il on_enter si comportano come se fosse cambiato.

Ci vorrebbe una initState separata dalla setState.

Ci potrebbe pure essere, perché se ci fai caso non ho specificato alcun costruttore, un costruttore che prende come argomento lo stato, ma non saprei poi cosa assegnare a m_previousState.

Faccio diventare m_currentState int8_t e inizialmente m_previousState = -1, booh ora ho solo 127 stati leciti, che sono sempre sufficienti.

Ciao.

Stasera ho fatto di nuovo le ore piccole...

E domani sempre la sveglia alle 6:30 :frowning: Ma perchè ho fatto tardi? Ho provato a inserire un blocco Timer per la partenza in ritardo della partenza treno A... Della serie ho fatto un macello! Alla fine sono riuscito a dare un ritardo di 30 secondi ma poi mi inibiva tutti i servi... Lo lascio così che è meglio... Dopo le feste provo a riscrivere tutto... Sempre se non mi si " ingrippa il cervello!" [cit..] HAhahah!

E con questo "itagliano" vi dò la buonanotte. Marco

Nel tempo libero tra una scala maggiore e una minore ho giocato con il codice di claudio al fine di infilare la gestione del treno in un calsse.
Difatti ho una classe Treno della quale creo istanza così:

Treno trenoA(11);  // 11  è il pin PWM, occhio che il ctor non verifica se il pin ha la funzione PWM.

Stando al numero di pin PWM sulla nano posso creare 6 istanze di classe Treno, cioè avere 6 treni.

L'interfaccia della classe è di tipo a comando: true | false
true accelera fino a 255.
false decelera fino a 0.

Il metodo run è da eseguire nel loop, ad esempio:

void loop(void) 
{
    trenoA.run();
   
    trenoA.command(true);  // accelera fino a 255
    // trenoA.command(false) // decelera fino a 0
}

La classe Treno eredita la classe GenericFsm e grazie a questo si vede che GenericFsm non è stata pensata per essere ereditata, ma l'unico modo che conosco per aggiustare GenericFsm per essere ereditata è appunto ereditarla e poi apportare modifiche.

** La classe Treno **

class Treno : private GenericFSM {
    private:
        byte m_speed;
        byte m_pwmPin;
        typedef void (Treno::*FPtr)();
        FPtr fptr = nullptr;
        void start() {
                       
            // step accelerazione
            if (m_speed < 255) {
                if (millis() - getTimer() >= 10) {
                    Serial.println(m_speed);
                    m_speed += 5;
                    analogWrite(m_pwmPin, m_speed);
                    setTimer();
                } 
            } else {
                fptr =  nullptr;
                setState(2);
            }
        }
        void stop() {
            if (m_speed > 0) {
                if (millis() - getTimer() >= 10) {
                    m_speed -= 5;
                    analogWrite(m_pwmPin, m_speed);
                    setTimer();
                } 
            } else {
                fptr =  nullptr;
                setState(0);
            }
            

        }
    public:
        Treno(byte pwmPin) { 
            m_pwmPin = pwmPin; 
            pinMode(m_pwmPin, OUTPUT);
            
        }
        void command(bool cmd) {
            if (cmd == true && getState() == 0 ) {
                setState(1);
                fptr = &Treno::start;
            } else if (cmd == false && getState() == 2) {
                setState(1);
                fptr = &Treno::stop;
            }
        }
        
        void run() {
            GenericFSM::run();
            if (fptr != nullptr) {
                // chiamata a funzione
                (this->* ((Treno*)this)->Treno::fptr) ();
            }
        }

};

Anche se non si è interessati alla classe Treno, questa mostra la sintassi per i puntatori a funzione, che non è proprio intuitiva.

Ciao.

Ma va ? ... dammi cinque o sei minuti mesi (:stuck_out_tongue:), e forse riesco a capire come funziona (ma per capire il perche' funziona, mi servira' di piu :crazy_face:)

Ciao a tutti,

per ora funziona abbastanza bene, a memoria non ricordo se ho poi alla fine collegato il trenoA al pin 11... Verifico, comunque da mettere in serie una resistenza e il piccolo condensatore sul reed fà molta differenza...
Interessante poter far girare più treni ma sinceramente non ho capito molto di quello che hai scritto Maurotec. :sob:
A volte capita che uno dei due treni và a finire che si fà due o tre giri di seguito... Misteri dei trenini.... :rofl: Forse potessi mettere un piccolo delay tipo (50) , il difetto forse non si presenterebbe... C'ho provato ma mi si contorce il cervello! HAhaha!

P.S. Non è ancora Natale, se domani tra un cliente è un'altro riesco a finire il P.L. posto il video.
Notte Marco.

Buona notte, Marco
A domani! :slight_smile:

Diciamo che ho scritto così di getto e ho spiegato lo spiegabile, che tradotto significa che mi hanno capito solo quelli che conoscono il C++.

Ma il succo è simile agli altri oggetti di arduino, ad esempio la classe Servo che hai usato qui:

Servo myservoA;

Dove crei un oggetto di nome myservoA. Cioè è possibile perché hanno implementato una classe di nome Servo. Io invece ho implementato una classe di nome Treno. Ora dovrebbe essere meno oscuro ciò che ho scritto.

Dimenticavo: Di modellismo e treni ne so poco e allora ho cercato e ho trovato uno standard chiamato NMRA.
https://www.nmra.org/

La scoperta è nata dalla curiosità di fare partire un treno che arriva ad una stazione di smistamento e solo dopo farne partire un altro. L'idea era quella che hanno già implementato nello standard, ma anziché fare viaggiare le informazioni sui binari pensavo alle trasmissioni radio HC12 o bluetooth.

Ciao.

Rieccomi,
grazie per la chiarezza Maurotec...
Dalle mie esperienze i ferromodellisti hanno un grado di sordità elevato, perchè quando mi è capitato di parlare della potenzialità che poteva avere Arduino con il mondo "ferromodellistico" ho trovato molte persone riluttanti, ma per fortuna non tutti sono così...

Chiusa polemica,
per quello che ho capito la gestione del plastico in "digitale" si divide in due grosse categorie:

  1. automatizzare tutto e gestire il traffico ferroviario in automatico tramite il PC e programmi a video,
  2. gestire le varie locomotive e vagoni in digitale, con tutte le funzioni che potete immaginare, anche i ganci automatici tra i vari vagoni.

A chi piace il modellismo e l'elettronica suggerisco di andare sul tubo e cercare il famoso plastico di Amburgo.... Miniature wonderland... E li vedete anche video di come realizzano, elettronica, pc e notti perse a guardare i video! :heart_eyes:

Notte Marco

Buon Natale a tutti! Volevo postare i miei 4 Video dei treni in azione ma non saprei come inserirli su questo post... Li zippo e li metto quà?

Sono fatti con il cell e non saprei cambiare formato. :smiling_face:

Auguroni Marco

1 Like

Ciao, Marco
Grazie! Buon Natale anche a te!
Io per pubblicare qui i video li carico su un mio canale Youtube. Per esempio:
https://forum.arduino.cc/t/come-strutturare-un-programma-stroboscopio-a-led-da-100w/1062259/73

I trenini di Marco ArTex:

1 Like

Ciao Gianluca, sono Mario da Torino, questa è la prima domanda che faccio sul forum, sto procedendo con la costruzione di un plastico in scala N e ho visto con interesse le possibilità che potrei avere con Arduino. Premesso che non sono un esperto, vorrei sapere se esiste uno sketch già pronto per un passaggio a livello con sensori, luci e suoni. Se mi puoi dare qualche spiegazione in merito te ne sarei molto grato, ho visto i tuoi filmati, molto interessante... Buona serata

Ciao, Mario

Mi sembra che tu non ti sia ancora presentato: perciò, per cortesia, come da regolamento, presentati nell'apposita discussione spiegando bene quali esperienze hai in elettronica e programmazione, affinché possiamo conoscere la tua esperienza ed esprimerci con termini adeguati.

Poi leggi attentamente tutto il regolamento, in particolare leggi bene i punti 15.3 e 17.1, e impegnati a rispettarlo.

Come sempre, nessuno potrà risponderti prima che ti sia presentato.

Grazie
Gianluca

Grazie per le precisazioni, ho visto un argomento interessante e ho subito chiesto delle delucidazioni che mi interessano, mi spiace, ma mi sono iscritto senza approfondire il regolamento, scusate la mia inesperienza, non ho mai fatto parte di un forum e non conosco bene i meccanismi chi li regolano, ora mi leggo attentamente il regolamento. Buona serata. Mario

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.