Freeze casuali del programma: può generarli una connessione I2C troppo lunga?

Ciao a tutti, sono settimane che sto tentando di capire come mai mi succeda ma non riesco proprio ad arrivare al motivo: utilizzo un programma per la gestione di due canali pwm portati tramite transistor a 0-10v con qualche sonda di temperature db18b20 ed un rtc... in più di un anno non mi ha mai dato problemi, mai un freeze... poi, da quando ho cambiato display e provato a pilotarlo in I2C con un pcf8475 sono iniziati i problemi: si blocca ad orari casuali (me ne accorgo perchè l'ora sul display non viene aggiornata) ma la cosa strana è che capita una volta ogni 2 giorni, poi la volta successiva dopo 1h dal riavvio, ed ancora magari dopo 9h....

Capisco che detto così possa non essere abbastanza esauriente con le spiegazioni ma lo sketch non posso inserirlo poichè è troppo lungo e non posso nemmeno mettere in evidenza la parte di codice che genera il problema poichè non ho idea di quale sia....

premetto che il programma è rimasto tale e quale a quello di un anno fa... l'unica modifica è stata appunto quella del display

il primo dubbio che mi è venuto e su cui vi chiedo un primo riscontro è questo:
il pcf8475 è installato su basetta ramata direttamente sui connettori del display --> ciò significa che i due cavi dell'I2C sono lunghi circa 170cm per connettere i pin A4 e A5 all'integrato. come cavi ho utilizzato degli rj45 (ethernet)... potrebbe essere questa configurazione dei cavi (troppo lunghi) a mandarmi in freeze il programma?
ho anche notato che ogni tanto sul display l'ora cambia in numeri assurdi... ad esempio se sono le 9:45, può capitare che qualche volta per un secondo segni 45:56 per poi tornare all'ora giusta.... io credo che questo possa essere un errore abbastanza serio da poter bloccare tutto il codice perchè l'orologio viene interrogato ogni 2 secondi circa per poter dal un lato aggiornare l'ora sul display e dall'altro per regolare le uscite pwm a certi orari della giornata..

è l'unica cosa che a me viene in mente... perchè il programma prima ha sempre funzionato e di conseguenza non può certo trattarsi di un'errata o cattiva struttura delle connessioni, anche perché tutta la parte hardware è stampata su basetta ramata ed innestata su Arduino.

spero che qualcuno mi possa aiutare prima che impazzisca e ritorni a pilotare il display tramite shift register (dovendo però ridisegnare e ristampare tutto il circuito)

La connessione I2C è nata per collegare alla CPU perifiche molto vicine, di solito sullo stesso PCB.

Nel tuo caso 170cm non sono molti, ma dipende dalla capacità parassita del cavo (un cat5 ha circa 52 pF per metro): prova ad usare un cavo più corto (tipo patch da 30 cm) oppure non intrecciato.

Puoi anche provare a diminuire un po' i due resistori presenti sulle linee SDA ed SCL (la libreria attiva per ognuna il resistore da 20k interno) mettendo un resistore esterno da 10k sino a 2k.

Ettore Massimo Albani

è vero, mi era venuto in mente ieri sera di provare a cambiare le resistenze... nel frattempo sto già testando un'altra soluzione che prevede una piccola modifica ai file twi.h e twi.c situati nella cartella libraries\wire\utility... sembra che uno dei possibili motivi per cui arduino subisce un freeze totale a causa di comunicazioni i2c corrotte fosse dovuto ad un while infinito che poteva essere risolto soltanto con un reset del controllore...

http://arduino.cc/forum/index.php/topic,19624.0.html

luca56:
è vero, mi era venuto in mente ieri sera di provare a cambiare le resistenze... nel frattempo sto già testando un'altra soluzione che prevede una piccola modifica ai file twi.h e twi.c situati nella cartella libraries\wire\utility... sembra che uno dei possibili motivi per cui arduino subisce un freeze totale a causa di comunicazioni i2c corrotte fosse dovuto ad un while infinito che poteva essere risolto soltanto con un reset del controllore...

http://arduino.cc/forum/index.php/topic,19624.0.html

potresti prevedere un watchdog

Ciao... la comunicazione I2C non prevede distanze così lunghe.
Eventualmente puoi mettere un extender per bus I2C oppure abbassare la velocità del bus.
Importante è avere un cavo schermato che ti possa ridurre tutte i rumori che potrebbe prendere. Io ho un progetto in cui nello stesso bus ho un display lcd, un sensore luce e un real time clock ma la lunchezza massima del bus non supera i 40 cm (cavi compresi).
Per le resistenze, il calcolo è un po' complesso per trovare il giusto valore, ma quelle che ti hanno suggerito vanno bene.

ciao

ecco, quella del watchdog è una delle funzioni che fino a 30 sec fa mi erano ignote... potrebbe rivelarsi un ottimo nodo di sicurezza... grazie mille

nel frattempo vediamo se con il cambio dei due file twi qualcosa cambia oppure no... per il momento non si è ancora bloccato..

Puó anche essere un problema di troppa ram usata.
Cerca di mettere le strighe nella flash con progmem.
Lo sketch puoi allegarlo come file con "additiona options"
Ciao Uwe

le librerie Wire di arduino in caso di errore di comunicazione sono bloccanti. Una lunga comunicazione vuol dire una alta possiblità di errore...

grazie uwe per il suggerimento sulle additional options... vi allego lo sketch, io utilizo la IDE 23 poichè con la 1.0.1 non mi prendeva la modifica alle cartelle TWI.c e TWI.h

se lo aprite con l'1.0.1 vi darà sicuramente come errori il wire.write e wire.receive che non accetta più

FUNZIONANTETESTtwi.pde (16.1 KB)

luca56:
non mi prendeva la modifica alle cartelle TWI.c e TWI.h

devi riavviare l'ide oppure cancellare la cartella temporanea in cui avviene la compilazione.

edit: già altre volte ci son stati problemi di RAM con le librerie per gli LCD. se cerchi nel playground trovi un pò di funzioni con cui controllare la ram libera rimanente

Luca, ti consiglio di passare alla versione 1.0.1.
Dovrai mettere mano al codice poiché sono stati modificati alcuni comandi, ma ti avvantaggi delle nuove funzioni integrare nel codice di Arduino.
Tra questa la funzione F() che ti permette di preservare la ram del micro.