Problema di memoria o altro - arduino nano con GSM, GPS, wire library [RISOLTO]

... se la seriale è già impegnata dovrai creare una seriale virtuale con la SoftwareSerial e mandare i messaggi di debug su di essa.

Ti ricordo che, mentre in "ricezione" solo UNA SoftwareSerial può essere attiva, in trasmissione non hai questo problema ...

Guglielmo

gpb01:
... se la seriale è già impegnata dovrai creare una seriale virtuale con la SoftwareSerial e mandare i messaggi di debug su di essa.

Ti ricordo che, mentre in "ricezione" solo UNA SoftwareSerial può essere attiva, in trasmissione non hai questo problema ...

Guglielmo

lo lho scritto nel primo post mi pare, ho il softserial impegnato sul GSM ed il serial sul GPS...

comunque stacco il GPS e faccio il check con il monitor...

ad ogni modo HO RISOLTO!!!!!!! riducendo la memoria utilizzando il char() al posto delle stringhe ho ridotto la memoria al 39%. Adesso il prossimo passo e non usare la tinygps per il GPS ma scrivermi una routine che legge direttamente le coordinate e risparmio un altro bel 10%.... comunque è giusto per divertimento.

Ad ogni modo rimane un problema piuttosto serio che non comprendo. Come ho scritto nel primo post i tre arduino sono collegati via I2C. Il più vicino (SLAVE), circa 10 cm di filo non ha alcun problema a ricevere i comandi (numeri) via wire. Il più lontato circa 1.5 m (SLAVE) funziona durante le fasi di test (utilizzando gli esempi della libreria wire) ma poi nel mio sketch dopo il primo comando si pianta..... ovvero invia il numero, lo slave lo riceve ed esegue il comando però il master si pianta....

jo usato delle reistenze di pull up da 2.47 kOhm e un cavo a basissima impedenza. Infatti nei test funziona.... però qualcosa va storto.....nel mio sketch...

Sai cosa significa la sigla I2C ? ? ? :smiling_imp: ... Inter Integrated Circuit ... ovvero un bus per comunicazione tra integrati sulla stessa scheda, a pochi cm l'uno dall'altro !

10/15 cm sono normalmente il massimo a cui puoi allontanarti, po devi cominciare a giocare con le resistenze di pull-up, con il tipo di cavi per ridurre la capacità e, per distanze maggiori, devi usare degli I2C bus extender.

Guglielmo

gpb01:
Sai cosa significa la sigla I2C ? ? ? :smiling_imp: ... Inter Integrated Circuit ... ovvero un bus per comunicazione tra integrati sulla stessa scheda, a pochi cm l'uno dall'altro !

10/15 cm sono normalmente il massimo a cui puoi allontanarti, po devi cominciare a giocare con le resistenze di pull-up, con il tipo di cavi per ridurre la capacità e, per distanze maggiori, devi usare degli I2C bus extender.

Guglielmo

Sai come si costruisce un reattore di pirolisi da 150M€?..... :slight_smile: scherzo...

Si so cosa sia ed io non ho voluto utilizzare i bus extender mi sono limitato a scegliere un cavo da 55 pF/metro ed ho calcolato le resistenze di pull-up utilizzando la guida sul bus IC2.

Oggi ho fatto qualche test e mi sono accorto che tutti i comandi inviati dal master allo slave funzionano senza bloccare il master, l'unico che non funziona è questo:

 if(temp.substring(5, 7)=="11" && !Exit) {
               
                if(temp.substring(7, 8)=="1") {
                // Comando per alzare il windscreen
                    Wire.beginTransmission(Device_Windshield);
                    cmd=10;
                    Wire.write(cmd);           
                    Wire.endTransmission();       
                }
                if(temp.substring(7, 8)=="0") {
                // Comando per abbassare il windscreen
                    Wire.beginTransmission(Device_Windshield);
                    cmd=11;
                    Wire.write(cmd);         
                    Wire.endTransmission();       
                }
                num[20]="";
                temp="";
                Exit=true;
              }

Ho meglio, si blocca dopo l'11 - 1 o il 11 - 0. Lo slave riceve il cmd 10 o 11 che sia e fa quello che deve fare poi il master si blocca. Mentre lo slave continua a funzionare.

Quindi il Wire.write(cmd); dovrebbe funzionare...
Mentre il Wire.endTransmission(); si blocca? Qualche consiglio su come individuare un baco nel codice che non riesco a capire?

tutti gli altri comandi inviati allo stesso slave qui sotto riportati funzionano... non capisco...

 if(temp.substring(5, 7)=="09" && !Exit) {
                  /* 
                   *  Viene eseguito il comando 09. Il comando 09 imposta la modalità 
                   *  del windscreen. I parametri sono: 
                   *  0 - attiva modalità automatica per il setup del windscreen quando si spegne e si accende la moto
                   *  1 - disattiva l'automatismo, il parabrezza rimane nella posizione in cui si trova
                   *  2 - attiva il limite di velocità a 100 km/h;
                   *  3 - disattiva il limite di velocità;
                   *  4 - attiva modalità automatica City;
                   *  5 - attiva modalità automatica Touring;
                   *  6 - attiva modalità automatica Autostrada;
                   *  7 - disattiva la modalità automatica;
                   */
                   if(temp.substring(7, 8)=="0") {
                    Wire.beginTransmission(Device_Windshield);
                    cmd=2;
                    Wire.write(cmd);            
                    Wire.endTransmission(); 
                    EEPROM.write(66, 0);
                   }
                   if(temp.substring(7, 8)=="1") {
                    Wire.beginTransmission(Device_Windshield);
                    cmd=3;
                    Wire.write(cmd);            
                    Wire.endTransmission(); 
                    EEPROM.write(66, 1);
                   }
                   if(temp.substring(7, 8)=="2") {
                    Wire.beginTransmission(Device_Windshield);
                    cmd=4;
                    Wire.write(cmd);            
                    Wire.endTransmission(); 
                    EEPROM.write(67, 1);                    
                   }
                   if(temp.substring(7, 8)=="3") {
                    Wire.beginTransmission(Device_Windshield);
                    cmd=5;
                    Wire.write(cmd);            
                    Wire.endTransmission(); 
                    EEPROM.write(67, 0);
                   }
                   if(temp.substring(7, 8)=="4") {
                    Wire.beginTransmission(Device_Windshield);
                    cmd=6;
                    Wire.write(cmd);            
                    Wire.endTransmission(); 
                    EEPROM.write(68, 1); 
                   }
                   if(temp.substring(7, 8)=="5") {
                    Wire.beginTransmission(Device_Windshield);
                    cmd=7;
                    Wire.write(cmd);            
                    Wire.endTransmission(); 
                    EEPROM.write(68, 2); 
                   }
                   if(temp.substring(7, 8)=="6") {
                    Wire.beginTransmission(Device_Windshield);
                    cmd=8;
                    Wire.write(cmd);            
                    Wire.endTransmission(); 
                    EEPROM.write(68, 3); 
                   }
                   if(temp.substring(7, 8)=="7") {
                    Wire.beginTransmission(Device_Windshield);
                    cmd=9;
                    Wire.write(cmd);            
                    Wire.endTransmission(); 
                    EEPROM.write(68, 0); 
                   }
                   num[20]="";
                   temp="";
                   Exit=true;
              }

Hai un'analizzatore di stati logici o almeno un DSO con tale capacità ? Perché, se sei convito che il bus sia elettricamente a posto, l'unica è analizzare con un analizzatore il protocollo e guardare cosa succede.

Guglielmo

gpb01:
Hai un'analizzatore di stati logici o almeno un DSO con tale capacità ? Perché, se sei convito che il bus sia elettricamente a posto, l'unica è analizzare con un analizzatore il protocollo e guardare cosa succede.

Guglielmo

Io no, ma ho un mio amico un pò più esperto di me che mi ha aiutato nella selezione del cavo, credo abbia usato uno oscilloscopio, o almeno così mi ha spiegato. Tuttavia ho continuato a fare prove e funziona perfettamente tutto tranne quei due comandi quindi mi sento di escluderlo.

Ormai sono a lavoro e più tardi proverò con una libreria non bloccante così come tu hai indicato in un altro post ad un altro utente che ha risolto (meno male che esiste google....)

Mi è venuta una idea... l'unica differenza tra le due parti di routine è il numero inviato. Ovvero quando invio un numero ad una cifra 0-9 funziona perfettamente, quando invio 10 o 11 si blocca.

Proverò ad invertire i comandi e inviare 0 o 1 al posto di 10 e 11 e vediamo cosa succede.

Altro non saprei che fare. Adesso cerco info sull'analizzatore di protocollo, ma in sintesi cosa sarebbe?

Ma cmd immagino sia un campo numerico (da come fai le assegnazioni) ... quindi ... 0, 1, 2, ecc, sempre lo stesso campo numerico usano ed il dato è sempre rappresentato in forma binaria ... ::slight_smile:

folagana:
Adesso cerco info sull'analizzatore di protocollo, ma in sintesi cosa sarebbe?

Questo (... in questo caso è per un messaggio SPI non I2C, ma il concetto è lo stesso) ...


Guglielmo

P.S.: Apri l'immagine in una nuova finestra per vederla meglio ...

Aggiornamento.

forse ho trovato il DSO nel frattempo ho fatto alcune prove e mentre mi accingevo a farle ho trovato nel codice un errore proprio nel punto in cui si bloccava. Praticamente mancava un break; nel case 11 del codice dell'arduino che riceve il comando 11. Ho pensato... e vai.... (chissà perché il compilatore non mi dava errore)

Poi facendo le prove non ha funzionato e si bloccano i due arduino chi manda il segnale e chi lo riceve....
Ho provato a utilizzare un comando con una cifra modificando il codice ma niente.

Allora di buzzo buono ho messo dei serial.print per verificare che cosa succede.

In questo codice:

      case 11:
      
      Serial.print ("Comando UP: ");  // restituisce solo Co
      TIN=millis();
      Windshield(false, false); // Questo comando viene eseguito con certezza...
      Serial.println("OK"); 
      do {
        // do nothing
      }
      while ((millis()-TIN)<(Tempo_windscreen));
      Serial.print("Comando stop..."); // non scrive nulla...
      Windshield(false, true);
      Serial.prinln("OK"); // non scrive nulla
      break;

il primo serial restituisce Co sul monitor seriale e null'altro ed comando windshield(false, false); viene eseguito con certezza.. il resto no.....

credo che si blocchi la wire ma per verficarlo debbo smontare un modulo nella moto .... e mi serve un pò più di tempo.

Guglielmo che ne pensi?

folagana:
... credo che si blocchi la wire ma per verficarlo debbo smontare un modulo nella moto .... e mi serve un pò più di tempo.

Si, ma perché ? Cosa cambia rispetto alle altre che funzionano ? Che "effetti pratici" produce che potrebbero disturbare la trasmissione ?

Guglielmo

L'unica differenza sta nel fatto che le altre semplicemente modificano dei valori nella EEPROM in determinate posizioni mentre questa avvia dei relè che fanno alzare il parabrezza. Sicuramente il relè (quello che avvia il motore) parte ma non sono posso essere certo del fatto che si ferma perché l'arduino si è già bloccato (ci sono dei fine corsa che interrompono la corrente al motore per sicurezza se l'arduino si bloccasse...).

Il relè fa circolare corrente a 12v per far girare un motorino. La scheda relè è questa (http://www.ebay.it/itm/222007974685?_trksid=p2057872.m2749.l2649&ssPageName=STRK%3AMEBIDX%3AIT) dovrebbe essere optosilata.

In effetti nella prima stesura del codice il relè veniva pilotato con un delay, mi spiego meglio..

winshield(UP); // attiva il relè per far salire il windscreen
delay(7000); // aspetta finchè non è salito
winshield(stop); // disattiva il relè di salita

purtroppo registravo che il relè si attivava, il delay durava qualche decimo di secondo e poi il relè si disattivava. Per superare questo problema che ho attribuito all'interrrupt (c'è un sensore che misura la velocità della ruota con interrupts... che però è ferma) ho modificato il codice mettendo un while. A questo punto potrebbe essere il while si blocchi.... o si pianta l'arduino, il codice è semplice

TIN=millis();
Windshield(false, false); 
      do {
        // do nothing
      }
      while ((millis()-TIN)<(Tempo_windscreen));
Windshield(false, true);

io propendo per il blocco perché non scrive neanchè più sulla seriale.

Potrebbero essere i transitori del motore a disturbare la trasmissione?

... bé ... è chiaramente un problema di disturbi o dal relé o dal motore. Ho idea che devi andare di filtri RC/LC e cerrcare di sopprimere il più possibile tutti i disturbi.

Un buon oscilloscopio potrebbe aiutarti ... ::slight_smile:

Guglielmo

Sto pensando se si può risolvere mettendo un delay dopo aver chiuso la comunicazione lato slave in modo da dare il tempo ai due di chiudere la comunicazione dopo che è stato passato il dato e poi attivare il relè

potrebbe funzionare?

Non credo, se è un disturbo va sicuramente a creare dei problemi alla MCU ed alla corretta esecuzione del programma (es. I2C che si blocca) .... ritengo che "l'intervento" debba essere sull'HW per eliminare i disturbi e non con dei "palliativi" che potrebbero una volta andare ed una no, poi ... vedi tu ... ::slight_smile:

Guglielmo

Però occorre capire dove e che tipo di disturbo corretto? E per questo mi hai suggerito l'oscilloscopio

folagana:
Però occorre capire dove e che tipo di disturbo corretto? E per questo mi hai suggerito l'oscilloscopio

SI, ma, di sicuro, sono sulla linea relè/motore, quindi ... inizia a piazzare dei soppressori su quella e vedi che succede.

Guglielmo

Gugliemo ci hai preso in pieno

l'attivazione del relè genera dei segnali spuri e arduino va in panne per qualche millisecondo ma è sufficiente a far saltare il delay o a bloccare il ciclo...

abbiamo fatto delle prove con dei filtri ma non funziona, mi sa che occorre una alimentazione curata e su una moto non è possibile....

comunque il comando non era uno di quelli critici ne posso fare a meno. Gli altri funzionano benissimo ma solo con moto alimentata dalla batteria. Quando si accende il motore l'alternatore e tutto il resto fanno saltare la comunicazione ma non importa tanto non posso guidare e contemporaneamente mandare SMS ..

sono comunque soddisfatto del lavoro.

... i diodi in antiparallelo sulla bobina del relé ci sono ? snubber sui contatti del relé ? un filtro LC sul segnale di comando del relé ? :wink:

Guglielmo

gpb01:
... i diodi in antiparallelo sulla bobina del relé ci sono ? snubber sui contatti del relé ? un filtro LC sul segnale di comando del relé ? :wink:

Guglielmo

il problema a detto del mio esperto "oscilloscopista" proviene dall'alimentazione che è in comune (ovviamente) del motore (12V) e di arduino che proviene da un convertitore DC/DC. L'uscita di questo convertitore è a 5V e da qui ho ricavato la tensione per "alimentare" le resistenze di pull-up

ecco lo schema

IMG_4662.JPG

Prova a dare una letta alle sei pagine di QUESTO thread ... la cosa era stata esaminata piuttosto bene ... ::slight_smile:

Guglielmo