veseo:
Ciao,
spero di non aver perso qualche pezzo per strada, ma entro nel discorso I2C e CAN.
Ciao Dario,
Innanzitutto complimenti per l'invervento, che giudico molto equilibrato, pulito e orientato verso un confronto costruttivo ai fini dell'evoluzione del mio progetto, che ho reso disponibile a tutti licenziandolo tramite Commons Creative (spero di averlo fatto in modo corretto).
Fatte queste doverose e giuste premesse, vengo a risponderti.
Se guardi l'idea di fondo, sono due protocolli elettricamente simili, sono entrabi basati su un bus pilotati in open-drain e per entrambi esistono microcontrollori che inglobano un controller in hardware
Al momento sto studiando il protocollo RS485, in quanto avevo progettato l'installazione nella mia ReleDuino di un MAX485 che però non avevo inserito in modo corretto. Astrobeed mi fece notare degli errori che sto provvedendo ad eliminare. Non sto studiando il protocollo CAN, ma viste le sue caratteristiche di immunità ai disturbi EMC e di elevata velocità anche su lunghe distanze, credo che sarà affrontato nei miei prossimi studi non appena avrò terminato quelli su RS485.
Da una ricerca fatta su WikiPedia ho letto che il CAN, a differenza di i2c, non è un protocollo completo, e questo mi obbligherebbe ad appogiarmi ad un protocollo che opera sui layer del CAN (tipo CanBus, CanOpen, ProfiBuf, DeviceNet, etc). Probabilmente lo farò, ma ci vorrà del tempo e spero di trovare persone che mi appoggeranno in questo lavoro. Per il momento la scelta rimane su i2c, che testerò sulle lunghe distanze tramite l'installazione degli amplificatori che ho adottato sulla scheda (PCA9600); io non sottovaluterei i2c, soprattutto perchè il mio sistema opera su livelli logici diversi da quelli classici (12 volts con capacità parassita tollerata fino a 4000 pF); appena torno a casa, a fine mese, posterò alcune foto della scheda e non appena possibile pubblicherò un video con 2 schede collegate con una piattina telefonica (cavo non schermato e non twistato) di circa 50 metri (secondo le specifiche NXP la mia configurazione potrebbe arrivare fino a 100 metri). Con il CAN credo che farei un bel balzo qualitativo ma prima di affrontare una modifica bisogna studiarla e ci vuole tempo nella scelta della configurazione migliore da adottare; spero che troverò collaboratori anche all'interno di questa community, sia nell'implementazione dell'hardware che del software. Rimanendo in ambito software, una soluzione ottimale sarebbe quella di creare una libreria "CAN" da associare all'ide arduino, proprio come la "wire", che possa facilitare anche un programmatore non esperto nell'uso dei GPIO (mcp23017 e pcf8574) contenuti nella ReleDuino. Ho scelto questi due integrati per la gestione degli input e degli output perchè sono molto utilizzati e ci sono molte guide e video dimostrativi in rete.
Ad esempio il micro ATMEGA64M1 ha un controller CAN in hardware (ma guarda caso, non I2C) ed è del tutto simile ad un ATmega328.
Ti risulta che l'atmega64m1 si possa programmare conl'ide arduino? Se fosse possibile, terminato l'ipotetico protocollo CAN-based, potrei implementarlo nella ReleDuino al posto del 328P.
I due protocolli nascono però con scopi diversi, come già è stato detto I2C è nato per collegare dispositivi sullo stesso PCB e nasce per funzionare in master/slave. Il protocollo CAN ha invece un'interessante funzione di collision avoidance e nasce per collegamenti su distanze interessanti (1Km a 50 kbit/s) quindi può funzionare anche in peer-to-peer.
Confermo che i2c nacque per operare all'interno di una stessa pcb o nella comunicazione di pcb molto vicine tra loro, tuttavia questo standard ha subito una notevole evoluzione nel tempo; a tal proposito, ti do il link di una presentazione su questo standard che pongo caldamente alla tua attenzione, soprattutto la parte relativa agli amplificatori di segnale per lunghe distanze contenuta nel capitolo "bus buffers": http://www.jjmb.nl/datasheets/i2c/presentation_i2c.pdf. Sul CAN non mi posso esprimere perchè non ho solide conoscenze a riguardo, pur sapendo "di fama" sulla sua immunità ai disturbi elettromagnetici. Entrambi i protocolli però, e non solo CAN, hanno una funzione di collision avoidance CSMA/CA dando priorità allo slave con indirizzo più basso, senza che i dati trasmessi da esso vengano danneggiati (come avviene invece sul collision detection CSMA/CD).
Proprio su questo aspetto vorrei soffermarmi, in un'applicazione che non richiede determinismo puntare sul master/slave comporta uno spreco di risorse o prestazioni pessime. Consideriamo un'installazione da 30 nodi (come citavi in precedenza) ed ammettiamo di effettuare un polling dei dati ogni secondo, nel peggiore dei casi (avendo un solo master) potresti aspettare fino a 30 secondi prima di ricevere il feedback ad un comando.
Il tutto interrogando le schede ogni secondo per eventi che accadranno poche decine di volte in una giornata.
La lettura dello stato dei pulsanti non avviene per polling ma per interrupt: alla pressione del pulsante un pin del pcf8574 manda un segnale ad Arduino, il quale SOLO in quel caso interroga tutti i pulsanti della sotto-rete (non di tutta la rete), che sono al massimo 64, agendo poi come da programmazione.
La gestione dei sensori presenti in una scheda ancora da progettare (la futura SensorDuino) probabilmente verrà gestita da un protocollo diverso: stavo pensando al protocollo 1-wire per l'occasione, ma ancora è presto per parlarne.
La soluzione da intraprendere è quella di un protocollo ad eventi, in cui la comunicazione non avviene per polling, questo ovviamente richiede un protocollo elettricamente in grado di rilevare o evitare le collisioni (o il alternativa ciò va realizzato in hardware). Se si utilizzano i transceiver per Ethernet, Wireless 802.15.4 e CAN questa gestione avviene in hardware.
Anche i2c, come detto prima, ha una gestione delle collisioni in hardware simile a CAN; ciò che non so, e su cui spero mi potranno dare delucidazioni in questa community, è se i2c ha la ritrasmissione dei dati nel caso ci sia una o più collisioni, o se devo prevederla nel software.