watchdog per GPS locator TK102 v3

Buonasera a tutti, dunque nuova sfida per me ...e per voi.
Ho un tracker GPS TK102 che fa il suo dovere pur essendo un clone. Per chi non lo conosce lavora con una SIM ed un chipset GPS per cui riesce ad inviare via SMS - dietro richiesta SMS - le coordinate del punto in cui si trova oltre ad avere altre possibilità.
Sembra...dico sembra che quando il dispositivo si trova in assenza di segnale oltre un certo tempo vada automaticamente su OFF. Questo ovviamente non va bene. Sul web ho visto che un tizio
(link video: TK102-v02 Mini GPS Auto Power Off bug Fix / Hack. tk102b - YouTube )
ha realizzato con un attiny un watchdog che verifica che il dispositivo funzioni e diversamente lo riattiva ristabilendo l'alimentazione. Devo ancora curiosare sulla PCB del dispositivo per cercare di capire qualcosa dello schema elettrico.
Non credo si tratti semplicemente di verificare la presenza della tensione batteria in entrata ma piuttosto di verificare se il modulo GSM sia alimentato e sel del caso ristabilire l'alimentazione.
l'idea di base che ho è questa...
1 il tracker ha un led che quando il tracker funziona lampeggia ogni 5 secondi;
2. monitorando che il led lampeggi ogni 5 secondi conosco lo stato del dispositivo;
3. se il led si spegne, il dispositivo è andato su off e devo accenderlo di nuovo;
4. per accenderlo devo premere il bottone fino a quando il led si accende di nuovo;
5. da qui devo ripartire con il monitoraggio del led.
Che vi sembra di questo "approccio"?

Ciò premesso mi serve qualche indicazione su dove studiare (grazie Gug) per questo nuovo argomento.
Grazie a tutti.

CIAO .io uso il tracker in camper .
non mie mai successo che si sia bloccato .......

...ciao Calasci. Graaie, prendo atto...è un TK102 Xenun (che versione?) o un clone?

Cmq sia voglio modificarlo nel senso esposto.

...la logica che vorrei seguire per il codice:

  • verifica che il led lampeggi (segnale prelevato dal led) in un certo lasso di tempo;
  • se non lampeggia;
  • attendi un certo tempo;
  • tieni premuto il bottone (pin in parallelo sul bottone di accensione)
  • appena il led si accende rilascia il bottone
  • verifica che il led lampeggi.

Che ve ne pare?

Gug come mi conviene partire per la verifica del lampeggio di un led?
tipo:

  • pin su input
  • legge input
  • aspetta tempo (credo si potrebbe evitare)
    oppure
  • misura tempo fino al lampeggio successivo
  • se tempèo maggiore di ...

...fa tutto il resto.

Cio sta?

... direi che leggi il LED, quando lo stato diventa "spento" acquisisci millis(), se entro, che so io, 10 secondi lo stato non è tornato "acceso" vuol dire che il LED non sta più lampeggiando e puoi resettare il device. Se invece si accende, torni ad aspettare il prossimo "spegnimento" ed il ciclo si ripete ... ::slight_smile:

Guglielmo

Grazie Gug, butto giù il codice e aggiorno.
Appena ho di nuovo il device sottomano sperimento.

bsera....dunque dunque rimetto mano al progett.ino.
Ho provato a buttare giù un codice...
Gug...che voto mi dai?
La logica che vorrei seguire è nelle prime righe del codice e la richiamo velocemente qui:

  • leggo lo stato di un led che lampeggia ogni 5 sec;
  • appena si accende parte il conteggio del tempo;
  • se il tempo è superiore a 6 secondi DEVO RESETTARE il dispositivo pigiando un tasto finchè il led si accende di nuovo...quindi;
  • pigio il tasto chiudendo il circuito;
  • monitoro il led;
  • appena si accende rilascio il tasto aprendo il circuito;
/*
logica:
leggere il led;
appena si accende (segnale su rising), acquisire/cominciare conteggio tempo in millis(),
se entro x (6?) secondi:
1. il led SI ACCENDE -> tutto ok. Si aspetta il ciclo successivo;
2. il led NON SI ACCENDE  -> si deve resettare/riaccendere:
...premere il tasto accensione (chiudere su gnd o vcc) leggendo CONTEMPORANEaMENTE il led fino all'accensione dello stesso;
...appena lo stato diventa "ACCESO";
...rilasciare il tasto e...
...tornare a monitorare il led.
*/

volatile byte state = LOW;
volatile unsigned long curBlinkTime = 0;
static unsigned long lastBlinkTime = 0;
long intervallo = 6000; // intervallo di 6 secondi

void setup()
{
  pinMode(3, OUTPUT);         // comanda il tasto accension GPS
  digitalWrite(3, HIGH);      // assicura che il piedino del tasto sia aperto

  attachInterrupt(digitalPinToInterrupt(2), ledBlink, RISING); // segnale dal led sul pin 2
}

void ledBlink()
{
  curBlinkTime = millis();
  //state = HIGH;
}

void loop()
{
  //if ( state == HIGH )
  if (curBlinkTime - lastBlinkTime > intervallo) // se il tempo è superiore a 6 sec
  {
    // state = LOW;
    curBlinkTime = lastBlinkTime;
    digitalWrite(3, LOW);      // chiude su GND il piedino del tasto
    // ...QUANDO il led (deve leggerlo di nuovo? come?) si accende
    if (digitalRead(3))
    {
      //... rilascia il tasto
      digitalWrite(3, HIGH);
    }
  }
}

La cosa migliore è provare sul* banco* e vedere se funziona .. dopo di che tornare qui e dire cosa NON funziona :smiley:

Guglielmo

Ciao Gug,

grazie dell'(inutile :smiling_imp: :smiling_imp: :smiling_imp: :smiling_imp: ) aiuto :grin: :grin: :grin: :grin: .

Ok prendo il giochino, testo al banco e riferisco.
Alcune domande, prima di procedere:

  • con l'Attiny85 posso usare l'interrupt allo stesso modo di Arduino? Esiste un pin prefissato..mi sembra sia il pin 5...PCINT0
  • per rilevare lo stato (accensione) del led, una volta che il "codice" chiude il contatto DEVO/POSSO utilizzare sempre lo stesso interrupt (...non so se mi spiego)?

Grazie davvero

TVB ;D

Per l'ATtiny fai riferiemnto al pdf allegato :wink:

Guglielmo

attinypdfv3_0.pdf (360 KB)

Bsera,

ho scritto un codice moooolto elementare per monitorare, non più lo stato del led che cmq lampeggia a sufficenza per essere letto con un digitalRead(), ma un punto del dispositivo dove ho il +VCC a dispositivo acceso e zero a dispositivo spento.
Riesco quindi a simulare la pressione del pulsante di reset (quando manca +VCC, stato LOW e si spegne il dispositivo) ma non capisco come far cessare la pressione quando torna +VCC (dispositivo acceso, stato HIGH).
Dove sbaglio?

byte statoTK = 0;

void setup()
{
  pinMode(2, INPUT);             // setta il pin 0 dell'ATtiny (sensore voltaggio) come input
  pinMode(13, OUTPUT);            // pin 1 parallelo del pulsante che chiudera su GND
  digitalWrite(13, HIGH);         // pin 1 aperto
}
void loop()
{
  statoTK = digitalRead (2);    // legge il segnale +VCC dal pin del TK
  if (statoTK == LOW)          // se manca il VCC sul piedino
  {
    digitalWrite (13, LOW);      // chiude su GND il pulsante...
   
 //...finchè il segnale su statoTK diventa di nuovo HIGH   
    
  }
  if (statoTK == HIGH)
  {
    digitalWrite (13, HIGH);
  }

Scusa, se lo stato è LOW to premi il pulsante, e lo tieni premuto ... sicuro che in questa condizione il pin ritorni poi HIGH? Perché se tieni premuto costantemente il pulsante di "reset", come fa il dispositivo a riaccendersi? Hai verificato manualmente questa cosa?

Guglielmo

Bgiorno Gug,

errore mio di descrizione. Il pulsante da me definito reset in realtà non è un reset ma accensione che avviene, appunto, premendolo(chiude su GND) finchè il dispositivo si accende con conseguente illuminazione del led che rimane acceso per un pò (3-4 sec) e poi lampeggia una volta ogni 4 sec.
Avendo il dispositivo sottomano ho trovato un punto dove monitorare tensione (presente se acceso e assente se spento) ed ho quindi deciso di prelevare da qui il segnale.
Quindi ho necessità di tenere premuto (chiudere su GND) finchè arriva tensione e poi staccare.
Ho provato in vari modi (anche con il while) ma mi blocco all'istruzione per rilasciare il tasto quando arriva tensione....eppure ho realizzato codici più complessi... :frowning:

... il problema NON è solo che tu devi rilevare se è acceso o spento, ma devi rilevare che sia spento per più di 4 secondi, altrimenti, mentre lampeggia, continui a fare "reset" ad ogni lampeggio (quando il led si spegne)!

Guglielmo

Si Gug,

infatti, nel primo codice, ero anche riuscito a far si che fosse verificata una pausa di x secondi dopodichè passavo ad una altra istruzione.
Però, come ripeto, ora la situazione è più semplice avendo "abbandonato" il led a favore di un punto dove devo verificare SOLO la presenza/assenza di VCC e NON più lampeggio.
Il mio problema ora è che non riesco a definire il codice per rilasciare il pulsante (pin su HIGH) QUANDO la tensione torna sulla piazzola (pin di rilevamento).
Ho provato con il while ma forse l'ho costruito male...hai qualche indicazione?

Beh, in tal caso è ancora più banale ...
... partendo da quanto avevi scritto, si può pensare un semplice while() che ...

#define pinInVCC 2
#define pinOutBottone 13

void setup()
{
  pinMode(pinInVCC, INPUT);
  pinMode(pinOutBottone, OUTPUT);
  digitalWrite(pinOutBottone, HIGH);
}

void loop()
{
   while(!digitalread(pinInVCC)) {        // se il pinInVCC è LOW rimane nel while, altrimenti esce
      digitalWrite (pinOutBottone, LOW);  // chiude su GND il pulsante
   }
   digitalWrite (pinOutBottone, HIGH);    // Rilascia il pulsante
}

Guglielmo

...non ci crederai ma ho appena buttato giù su carta proprio quel while leggendo la dispensa di Marsella e Lombardi...forse ieri lo avevo costruito male.
Si funziona, il codice gira in simulazione...ed ho trovato anche le due trappole da te messe :sunglasses: ...PRIMA di caricare il codice!!!

Ora lo testo sul device programmando l'ATtiny

PS: faccio anche qualche prova leggendo il led.

Thanks

Gug, forum bsera,

sembrava fatta invece no.
La piazzola non mi fornisce un segnale adeguato e sembra si innneschi una sorta di rimbalzo per cui l'output non è stabile.
Devo tornare sul led...devo, quindi:

  • rilevare il segnale sul led (pinInVCC HIGH ..e ci siamo)
  • misurare il tempo di SPEGNIMENTO.
    Ora considerando che il dispositivo quando si accende illumina (una volta sola) il led per 6 sec, poi fa una pausa di 4 sec, blink, pausa di 4 sec, blink e cosi via.
    Ho pensato quindi di basare il ciclo sul rilevamento di una pausa maggiore di 6 secondi (misura lo startTime ed il finishTime e li sottrae) al verificarsi della quale devo...
  • pigiare il tasto (pinOutBottone LOW...e ci siamo)
  • tornare a rilevare il segnale sul led (pinInVCC HIGH)
  • rilasciare il tasto (pinOutBottone HIGH..).
    Da qui sorgono le domande:
  1. Secondo te si riesce a fare?...
  2. hai qualche percorso logico più semplice?
  3. Il dispositivo rimarrà acceso almeno 5 giorni si va in overflow?
  4. come è opportuno organizzare i "blocchi" di codice?

Io veramente lo avevo già abbozzato in tempi NON sospetti ... :smiling_imp:

#define pinInLED 2
#define pinOutBottone 13
#define timeout 5000

uint32_t ultimaAccensione;

void setup()
{
  pinMode(pinInLED, INPUT);
  pinMode(pinOutBottone, OUTPUT);
  digitalWrite(pinOutBottone, HIGH);
}

void loop()
{
   if ( digitalRead(pinInLED) ) ultimaAccensione = millis();
   
   if (mills() - ultimaAccensione > timout) {
      while( !digitalread(pinInLED) ) {        // se il pinInLED è LOW rimane nel while, altrimenti esce
         digitalWrite(pinOutBottone, LOW);     // chiude su GND il pulsante
      }
      digitalWrite(pinOutBottone, HIGH);       // Rilascia il pulsante
      ultimaAccensione = millis();
   }
}

... a te ora verificarlo, correggerlo, sistemarlo :wink:

Guglielmo