Era stagione di pin remoti....

gioscarab:
Ciao ragazzi, a me quello a cui state pensado sembra veramente quello che fa Firmata.

Spezzo una lancia perché sto cercando di capire cosa è più utile per le mie personali necessità.

Inizialmente si, c'era "solo" il comando dei singoli pin, poi è arrivata la lettura/scrittura su array remoti (simil Modbus?), ed infine l'esecuzione di callback remote (simil Pjon?), che come giustamente fai notare, avvia sull'unità remota funzioni specifiche (lanciate da un array di puntatori a funzione, e quindi senza necessità di parsing).

Ogni libreria ha una sua filosofia ben specifica, che la rende adatta per determinati casi e un overkill per altri. Credo che non possa esistere alcuna libreria universale che possa andare bene per tutto e per tutti.

Il particolare la filosofia di questa è espressa nei primi due post, e mi sembra sintetizzabile in: non occuparsi mai (a livello di applicazione finale) dei messaggi scambiati (a cui si può aggiungere accidentalmente un occupazione risorse minima), e non dover mai scrivere/codificare messaggi espliciti (anche se poi il richiamo di una callback tramite un indice rende quell'indice un messaggio implicito, ma è solo un numero, non qualcosa da codificare in partenza e parsare all'arrivo).

Detto ciò capisco che, essendo ogni comunicazione è un'operazione atomica specifica, gli utilissimi messaggi broadcast trovano difficile (se non impossibile) implementazione . Non ci possono essere "messaggi raw" che solo gli interessati prendono in considerazione, a meno di snaturare la filosofia detta prima, introducendo appunto i messaggi raw.

Un altro limite attuale (sto pensando all'aggiornamento di valori negli array remoti) è poter trattare un solo byte per trasmissione. Se, come nel Modbus, si potessero trasmettere/leggere N byte al colpo (vale anche per le callback), le potenzialità aumenterebbero di molto, e, credo, non si toccherebbe la filosofia iniziale.

Un'ultima cosa, che devo trovare il tempo di approfondire tra un impegno e l'altro, è vedere se il loop resta sempre libero anche durante le transazioni, questo per me sarebbe importante.


Infine, già che ci sono, il carattere di controllo lo renderei appena appena un po' più sicuro (limitando gli effetti negativi della proprietà commutativa della somma):

char remotocontrollo(char messaggio[])
{
    // restituisce il carattere di controllo per il messaggio in ingresso
    // una cosa semplice, non troppo elaborata
    byte appoggio = 0;
    byte index = 0;

    while (messaggio[index])
    {
        appoggio = ((appoggio >> 1) | (appoggio << 7)) ^ messaggio[index++];
    }

    return (char)(appoggio % 93) + 33;
}

Leggo con interesse i commenti
In effetti la filosofia era quella citata
Solo dopo ho aggiunto cose che la snaturano un po'
Forse era meglio se non mischiavo i due concetti
Cerebro perde giri dopo pranzo
Ci penso stasera
Ps naturalmente grazie, è un onore quello che mi fate, tra suggerimenti e critiche, ne sono ben consapevole

Standardoil:
Solo dopo ho aggiunto cose che la snaturano un po'

Finora mi sembra che la filosofia rimanga: si "fanno cose" (leggi/scrivi/imposta/avvia) sull'unità remota senza codificare alcun messaggio.

Ragazzi non volevo essere critico, si fa per imparare e voi fate benissimo a sperimentare.
Volevo solo risparmiarvi un po' di tempo, ho valutato questo approccio nel dettaglio e ho ottenuto risultati poco apprezzabili. Un'altra cosa che chiarificherei (se non si parla di un canale point-to-point) e' che questo sistema non e' soltanto bloccante, ma "macro-bloccante", in poche parole un solo device alla volta, solo se la connessione e' attiva, puo' effettivamente eseguire un algoritmo. Il fatto di embeddare la funzionalita' nella memoria target ti da il vantaggio di poter eseguire l'algoritmo anche se la connessione non e' disponibile, che secondo me e' di certo un metodo piu' flessibile (il termostato perde la connesione con il master ma contiene gli algoritmi per continuare a operare nominalmente, senza pero' essere comandato da remoto). Un esempio pratico, avete fatto dei conti di quanto ci vuole a incrementare una variabile o un elemento di un array 100 o 1000 volte alla velocita' massima da remoto? Sospetto ci vogliano piu' di 2 secondi per arrivare a 10000, occupando tutta la banda per quel dato periodo. Per avere un termine di paragone calcolerei la durata dello stesso numero di incrementi, effettuato pero' dal programma flashato nella memoria. Il risultato probabilmente dimostrera' essere sconveniente e in molti casi inapplicabile spedire ogni operazione da eseguire in successione.

Claudio_FF attento al carattere di controllo, non e' un aspetto da prendere sotto gamba, soprattutto se il meccanismo di funzionamento invia di continuo indirizzi di memoria e chiamate a funzioni che potrebbero essere corrotte, programma un arduino per mandare dati casuali e testalo ricevendo dati erronei, se passa qualcosa il controllo e' rotto.

gioscarab:
Un esempio pratico, avete fatto dei conti di quanto ci vuole a incrementare una variabile o un elemento di un array 100 o 1000 volte alla velocita' massima da remoto?

Certo, non mi sognerei di controllare nulla in real time remoto, e immagino non sia questo l'uso per cui è pensata, il target direi che è sensoristica sparsa con pochissimi aggiornamenti al secondo. Tra l'altro vedo che le funzioni di trasmissione sono appunto bloccanti (che a me non andrebbe bene, ma mi interessa comunque vedere dove porta l'idea).

Claudio_FF attento al carattere di controllo

Pienamente d'accordo, rigiro all'ammiraglio :slight_smile: Io su un canale potenzialmente disturbato non mi fiderei neppure di un CRC8. Ma un checksum volgare era proprio andarsi a cercare guai.

Non credo che sia unnpa cosa molto bloccante, perchè

  1. ogni macchina può fare quello che deve prima di leggere il canale, senza che un messaggio la blocchi necessariamente obligandola a leggere. Se passa troppo tempo da quando il master trasmette e quando lo salve riceve il master banalmente reinvierà il messaggio, che andrà a sostituirsi a quello vecchio, si che lo salve potrà leggerlo normalmente.
  2. qualora fossimo in un canale non point to point ogni macchina (se more quando richiesto dal programma proprio) leggerà il messaggio, e tutte meno una si accorgeranno che non è per loro e Po ignoreranno, facendo passare soltanto il tempo minimo per accorgersene, azione che in qualunque trasmissione point to point che è lo scopo della libreria) in un canale non point to point, è necessario compiere.
    3)Qualora il messaggio fosse per la macchina significa che un master vuole intervenire, quindi la macchina deve bloccare quello che sta facendo e modificarlo, in quanto è desiderato dall'alto
  3. la libreria può essere bloccante per il master, ma esso sta facendo esattamente quello che deve fare

Cosa non ho capito?

Altro che pochi aggiornamenti al secondo. Io la uso per cancello elettrico, e qualche cosa tipo irrigazione, luci remote, presenza auto in garage, interrogazione termostato, comando caldaia, in tutto forse 20 operazioni ora di giorno, meno di notte
E il tutto nel modellino, come ben spiegato all'inizio del tread, nulla di intensivo
Ma non è pensata per niente di più, ci sono più esigenze che teste di utente, io dico che su 10 (edit 10 persone, 10) persone ci sono 11 idee, perché uno che cambia idea lo trovo di certo
La mia libreria, nel suo piccolo risolve le mie esigenze
Dopo mi spiego meglio

Ciao Silente, purtroppo non ho modo trovare nessun link o dettaglio al sw, ma da quello che dice Standardoil

Io cerco un metodo per fare una cosa del tipo: scrivi(pin,stato), interroga (pin), leggianalogico(pin), scrivipwm (pin, valore), intercambiabili con le corrispondenti digitalread ( ecc ecc, dove però pin può essere sia locale che remoto, al momento della scrittura non mi interessa, semmai al momento della inizializzazione.

Intendo bloccante nel senso che, se vuoi attuare un pin di un device a uno stato particolare, occuperai una certa quantita' di banda, e nessun altro pin potra' essere settato in quel determinato periodo. Se la cosa supera operazioni estremamente semplici, come per esempio settare lo stato di una digitale molto raramente, il meccanismo diventa in molti casi inapplicabile proprio per la latenza, il tempo di trasmissione, ricezione e computazione del CRC se presente, non permettendo un'esecuzione veloce in sequenza delle chiamate a sistema richieste. In ogni caso, forse bloccante non e' il termine adatto :slight_smile:

Ciao Standardoil, non ho "detto pochi aggiornamenti al secondo", ho ipotizzato 10000 incrementi in 2 secondi a una variable o a un elemento di un array remoto, che sono 5000 aggiornamenti al secondo.

Ho trovato la source, vedo che mandi stringhe, sicuramente e' una buona soluzione per il framing, ma ha il grosso limite di essere enormemente limitata se c'e' necessita' di mandare dei numeri "1234" pesa 4 byte ma in realta' puo' essere rappresentato con un intero di 2, o dati aleatori, come i pixel di un immagine, se decidi di includere questa feature considera che senza definire un processo che se ne occupi, rischi di trovare un 128 o un 129 nel payload e rompere la separazione dei pacchetti, il che necessiterebbe l'uso del byte-stuffing, ecc.

Guardando meglio il controllo capisco perche' scali a 93 + 33 il risultato, ma cosi' stai riducendo enormemente le performance di una checksum che gia di suo e' un giocattolo EDIT: stai utilizzando solo il range (0-127) di 1 byte per controllare piu' caratteri, la sua performance credo sia bassissima. Se ti interessa ricerca riguardo al CRC7, potrebbe stare nel bound che hai a disposizione senza valere mai piu' di 128. Cosi' sei piu' tranquillo, in ogni caso personalmente non lo utilizzerei mai in produzione per controllare piu' di 1 byte.

Ultima cosa, un principio che ho imparato sulla mia pellaccia, non ha senso implementare un controllo per gli errori, se a monte non hai implementato un modo per valutarne le performance.

Tutto vero, però adesso qualcosa la dico anch'io, portando acqua al mio mulino
Non stiamo giocando ne a chi lo ha più veloce (il codice) ne ha chi lo ha più grosso (sempre il codice)
si tratta di capire quali sono le esigenze originali e come sono state soddisfatte dal software
ripeto, su 10 persone si trovano almeno 11 idee, quindi non ha senso dire "la mia fa di più o va meglio"

esigenze:

  1. comandare pin remoti SENZA preoccuparsi di codificare ad hoc tutte le volte, magari cambiando inavvertitamente qualcosa
  2. interrogarli, stessa solfa
  3. "seppellire", mi si passi il termine, il tutto dentro una libreria che non mi "desse noia" nel codice principale

queste più o meno le ho scritte all'inizio e queste sono state rispettate, se sono utili sono qui per dare ispirazione

poi, riguardo al " bloccante/ non bloccante":
sono bloccanti, ovvio che lo siano, anzi, PER FORTUNA lo sono
lo dimostro subito: proprio in questi giorni altre persone stanno combattendo in un altro tread con un canale intasato da trasmissioni continue, non essendo bloccante è possibile farlo, con deleteri risultati
ma comunque è ovvio che DEVONO essere bloccanti, anche questo lo dimostro subito:
se devo leggere lo stato di un pin non è che la funzione di lettura ritorna subito e lo stato lo avrò tra non è chiaro quanti cicli di loop()
le letture "devono" essere bloccanti, per avere il tempo di restituire il risultato
ma anche le scritture è necessario che lo siano, per due ragioni

  1. per evitare di andare avanti con la logica del programma PRIMA che sia avvenuto quello che abbiamo voluto comandare
  2. perchè la maniera più semplice per avere una conferma di avvenuta esecuzione è quella che ho descritto nella mia discussione "io ritorno sempre", io ritorno sempre, appunto, ritorno il "risultato" dell'azione, confermado quindi che l'azione è avvenuta realmente (non è proprio vero con la remoteanalogwrite) e permetteno un test del tipo
if (remotedigitalwrite('a', 2,HIGH))
{
// azione eseguita
}
else
{
//avviso di un problema
}

provate a farlo su funzioni non bloccanti
per quanto riguarda gli errori di trasmissione: banalmente non sono un problema mio, ma del canale di trassmissione, non per nulla alla libreria io passo un puntatore a oggetto stream, cavoli dell'oggetto stream far arrivare a destinazione i messaggi senza errori
in una forma più compiuta: ho seguito una regola semplice: "fai una cosa sola ma falla bene" (Ok ok, nel mio caso falla meglio che puoi)
ecco, io ho remotato i piedini, la comunicazione non fa parte del problema
non è che la ignoro, è che ci lavoro ad un livello che NON è quello del remotaggio
ci sto lavorando, in questi giorni ad esempio si sta parlando di cifratura dei dati, in un altro tread, e li ho messo quello che avrei messo nel capitolo "come ti sfumo il byte" che riguarda la "riservatezza" del canale
e sto penssando anche alla parte "affidabilità" del canale, ma NON sono problemi della PinRemoti
l'unica cosa che mi sento di condividere è che avrei potuto usare codifiche più efficenti, ma siccome sono partito copiando (non lo ho mai negato, anzi me ne vanto, è eattamente nello spisrito del forum trarre ispirazione da altri), dicevo, siccome sono partito copiando, ho pensato che una codifica sub-ottima non fosse un problema grave, e sono convinto non lo sia
Ho letto di popolare array di grandi dimensioni, di 100 o 1000 scritture
lasciatemelo dire, se si devono fare 100 o mille scrittura in pochi secondi ci sono GROSSI problemi di divisione del lavoro tra le varie macchine, io sono dell'idea che anche solo dover scrivere una volta sia "tanto": significa che l'intelligenza distribuita non copre tutti i casi, poi è scelta di magari non approfondire troppo l'analisi del lavoro di un satellite, per far fare di più alla centrale, come ho detto qui son scelte, che ho fatto anch'io, intendiamoci

Ciao Standardoil, guarda, mi spiace che un semplice contradditorio su questo forum in genere si debba sempre trasformare in una discussione spiacevole. Mi dispiace tu abbia percepito le mie risposte come traspare da cosa scrivi, ho solo cercato di esprimere la mia opinione e fare delle critiche costruttive riguardo a quello di cui state discutendo. Se decidi che sia lo stream a occuparsi del controllo dell'errore, dovresti essere sicuro che lo stream supporti questa funzionalita' (ie serial e' uno stream ma non ha il crc built in).

Semplicemente, il controllo degli errori e' una scienza a parte e si occupa di controllare una parte critica del processo di comunicazione, errori non filtrati possono creare dei grossi problemi se avvengono in produzione. Di conseguenza se e' responsabilita' del protocollo effettuare un controllo di questo tipo, e' responsabilita' di chi lo specifica e implementa di applicare la dovuta cura e essere cosciente della responsabilita' a cui si e' esposti. Per prevenire qualsiasi tipo di rischio a te o agli utenti interessati ho cercato di consigliarti costruttivamente di dare un'occhiata al CRC7, anche perche' sta in 7 bit che sono proprio quelli che hai a disposizione, se ho interpretato correttamente come hai predisposto l'encoding. Mi dispiace che tu abbia colto qualcosa che non volevo comunicarti e non ho scritto, piuttosto che un consiglio pratico diretto e un pointer a una tecnologia gia disponibile che potrebbe aiutarti.

In piu' se a te non interessa la parte di trasmissione, ma un layer superiore che definirei "encoding" non vedo alcuno overlap o possibile comparazione tra questo lavoro e PJON, anzi probabilmente il tuo protocollo potrebbe tranquillamente operare over PJON. Di conseguenza, non capisco molto il tuo sfogo e la voglia di trovare competizione dove non e' applicabile competere essendo le due cose profondamente diverse.

In ogni caso ti auguro di continuare a sperimentare e divertiti con questo progetto. E' sempre molto bello lasciarsi andare alla creativita' e al problem solving.

Ma il mio non è uno sfogo
sono solo considerazione un po' sparse, ispirate da quello che ho letto prima
io per me mi sento soddisfatto dal mio risultato, forse ho voluto un poco strafare aggiungendo anche array e funzioni, mi piace fare una cosa sola per volta e farla al meglio
non ho mai inteso che mi disinteresso dei possibili errori o simili, intendo solo dire che mi rifiuto di prendere in considerazione il problema quando parlo di remotaggio, lo sto prendendo in considerazione in separata sede
faccio un esempio stupido: se la tua emittente televisiva preferita stasera desse solo programmi stupidi, tu ti lamenteresti con l'antennista?
l'antennista è responsabile della buona qualità della ricezione (e col digitale diventa anche difficile dire cosa sia una buona qualità, ma facciam finta di essere ancora in analogca, dai)
della programmazione ne parli semmai col servizio relazioni col pubblico dell'emittente,
ecco: nella pinremoti io parto da presupposto che il canale sia pulito (ce l'antennista abbia lavorato bene), e anche aver aggiunto un controllo embrionale e una ritrasmissione lo considero concettualmente errato, ma lo ho fatto in attesa di finire gli altri 3 (sì, tre) layer: affidabilità, riservatezza e confidenza,
in prospettiva una prossima edizione della pinremoti potrebbe non avere più nemmeno qull'embrione che ho messo adesso
Te pensa, e non è una critica ma solo una considerazione, cha la prima volta che ho visto la tua PJON mi sono domandato perchè hai mescolato i vari livelli, tanto differente sono i nostri "concetti informatori"
e con questo non intendo fare valutazioni, che arebbero fuori luogo, mi rendo perfettamente conto che tu hai fatto un "lavorone" di anni, e io solo poche sere da amatore, non è concepibile un confronto, figuriamoci una graduatoria....

Mi dispiace tu abbia frainteso di nuovo, nessuno ha detto che il mio lavoro ha piu' valore di quanto possa averne pinremoti, dico che PJON si occupa proprio di quello che il tuo protocollo non si occupa e quindi trovo difficile un possibile confronto, anzi, ti ripeto di averti gia fatto notare che PJON potrebbe proprio occuparsi della parte di comunicazione e incapsulare una stringa della pinremoti e recapitarla a chi di dovere.

Che è esattamente quello che volevo fare in origine
poi mi sono accorto che per le mie esigenze bastava una Softwareserial e un po' di cavetto telefonico

Il cavetto telefonico e' un must sono d'accordo :slight_smile: . Se il tuo protocollo non si occupa di controllare gli errori o lo fa con la checksum che hai postato e sotto usi la softwareserial che sotto non fa alcun controllo, un nonnulla potrebbe cambiare in maniera errata lo stato dei tuoi relays connessi in giro per casa, stai attento soprattutto se c'e' di mezzo la 220! Buona sperimentazione.