GPS Ultimate alimenté par mosfet

Bonjour,

J'ai un problème avec mon code je pense, j'ai suivi les indications de ce topic :
http://forum.arduino.cc/index.php?topic=333509.0

Donc voilà vite fait le montage que j'utilise :

Donc le problème, en branchant la commande du Mosfet canal N sur le + le GPS est toujours allumé, rien à signaler. Le fona s'allume et envoie l'info, le sleep se fait bien et on recommence.

Par contre si je branche la commande sur la broche 5 de mon atmega c'est plus instable, le GPS ne s'allume pas toujours, occasionnant un reboot de l'atmega dans ces cas là. Donc c'est pas bien rose, je ne comprend pas bien le problème, ce doit être lié au fait que mon GPS n'est plus alimenté, mais je réinitialise tout à chaque fois donc bon.

Voilà mon code commenté :

#include <avr/sleep.h>
#include <avr/wdt.h>
#include <avr/power.h>
#include <avr/interrupt.h>

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

#include <SoftwareSerial.h>
#include <Adafruit_GPS.h>
#include <Adafruit_FONA.h>

#define FONA_RST 4
#define FONA_KEY 13
#define FONA_PS 12
#define PHONENUMBER_GATEWAY "06********"
// FONA
// SERIAL
// TX --> 0
// RX --> 1
// OTHER
// RST --> 4
// KEY --> 13
// PS --> 12
// PHONENUMBER OF GATEWAY --> 06********

#define GPS_RX 2
#define GPS_TX 3
#define GPS_VIN 5
// GPS
// SOFTWARE SERIAL
// TX --> 3
// RX --> 2
// OTHER
// VIN --> 5
// VIN USE A TRANSISTOR

#define SLEEP_FACTOR 3
// SLEEP (sleep lasts SLEEP_FACTOR * 4s )


char trameGPS[100];

// INIT OF FONA AND GPS
Adafruit_FONA fona = Adafruit_FONA(FONA_RST);
SoftwareSerial mySerial(GPS_TX, GPS_RX);
Adafruit_GPS GPS(&mySerial);

// WATCHDOG FLAG TIMER
volatile int f_wdt = 1;

// --- SETUP ----------------------------------------------------------------
void setup() {
	// POWER PARAMETERS
	// if FONA_KEY is HIGH at start : FONA is OFF
	// if GPS_VIN AND GPS_VINB is LOW : GPS is OFF
  pinMode(FONA_KEY, OUTPUT);
  pinMode(GPS_VIN, OUTPUT);
  pinMode(FONA_PS, INPUT);
  digitalWrite(FONA_KEY, HIGH);
  digitalWrite(GPS_VIN, LOW);
  
  // --- BROWN-OUT ----------------------------------------------------------
  // turn off brown-out enable in software (the voltage security is disabled)
  MCUCR = bit (BODS) | bit (BODSE);  // turn on brown-out enable select
  MCUCR = bit (BODS);  // this must be done within 4 clock cycles of above
 
  // --- FONA --------------------------------------------------------------
  // the FONA module is on hardware serial
  powerOnFONA(); // just start test
  powerOffFONA();

  // --- SLEEP -------------------------------------------------------------
  // this next section of code is timing critical, so interrupts are disabled.
  // see more details of how to change the watchdog in the ATmega328P datasheet
  // around page 50, Watchdog Timer.
  noInterrupts();
  
  setup_watchdog(8); // approximately 4s sleep
  
  // enable interrupts again.
  interrupts();
  }
  
// -- LOOP -----------------------------------------------------------------
void loop() {
	powerOnGPS(); // GPS ON
	while(getGPS() != 0); // waiting a module frame with all the data
	powerOffGPS(); // GPS OFF (power cut)
    
	powerOnFONA(); // FONA ON
	sendGPS(); // formats the data and sends SMS
	powerOffFONA(); // FONA OFF (sleep)
    
	// reset the watchdog flag
	f_wdt = 0;
	// sleep for (SLEEP_FACTOR * 4) seconds
	while(f_wdt < SLEEP_FACTOR) {system_sleep();}
	}

// --- GPS AND FONA FUNCTIONS ----------------------------------------------

void flushSerial() {
    while (Serial.available()) 
    Serial.read();
    }

int getGPS() {
  GPS.read();
		
  if (GPS.newNMEAreceived()) { // if new frame
    if (!GPS.parse(GPS.lastNMEA())) {   // if good parse, this also sets the newNMEAreceived() flag to false
    	// fail to parse
      return -2;
      }
      
    if (GPS.fix) { // if full data
      if(GPS.hour == 0) {return -4; /* fail in data recover */}
      // all is fine
      return 0;
      }
      
		// if don't work
    return -3; 
    }
    
  // no frame
  return -1;
  }
  
void sendGPS() {
	char lat[10], lon[10]; // temp strings for double to char* conversion  
	dtostrf(GPS.latitude, 4, 4, lat);  //4 is mininum width, 3 is precision; float value is copied onto buff
	dtostrf(GPS.longitude, 4, 4, lon);
    
	sprintf(trameGPS, "%d/%d/20%d %d:%d:%d %s%c %s%c\n", GPS.day, GPS.month, GPS.year, GPS.hour, GPS.minute, GPS.seconds, lat, GPS.lat, lon, GPS.lon);
    
	fona.sendSMS(PHONENUMBER_GATEWAY, trameGPS);
    
	delay(20000); // delay for sms sending, may be unnecessary
  }
  
// --- SENSORS FUNCTIONS (battery, temperature) ------------------------------------
    
float getTemp() {
  
  }
  
float getBat() {
  
  }
  
// --- POWER SAVING FUNCTIONS (GPS, FONA) ------------------------------------------
    
void powerOffGPS() {
  mySerial.println("$PMTK161,0*28"); // GPS go sleep
  digitalWrite(GPS_VIN, LOW); // GPS OFF
  delay(5000);
  }
  
void powerOnGPS() {
  digitalWrite(GPS_VIN, HIGH); // take the module ON
  
  delay(5000);
	// 9600 NMEA is the default baud rate for Adafruit MTK GPS's- some use 4800
	GPS.begin(9600);

  delay(1000);
	// to turn on only the "minimum recommended" data
	GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY);
	GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);   // 1 Hz update rate
	GPS.sendCommand(PGCMD_ANTENNA);

	delay(1000);
  
	// Ask for firmware version
	mySerial.println(PMTK_Q_RELEASE);
	}
  
void powerOffFONA() {
	if(digitalRead(FONA_PS)) { // check if FONA is OFF
		digitalWrite(FONA_KEY,LOW);
		unsigned long KeyPress = millis();
		while(KeyPress + 2000 >= millis()) {}
		digitalWrite(FONA_KEY,HIGH);
		delay(1000);
		}
	}
  
void powerOnFONA() {
 	if(! digitalRead(FONA_PS)) { // check if it's ON already. LOW is off, HIGH is ON.
		digitalWrite(FONA_KEY,LOW); // pull down power set pin
		unsigned long KeyPress = millis(); 
		while(KeyPress + 2000 >= millis()) {} // wait two seconds
		digitalWrite(FONA_KEY,HIGH); // pull it back up again
		delay(500); // wait 500ms
		Serial.begin(9600); // init (or init again) the serial hardware connection
		delay(500); // wait 500ms
		while (! fona.begin(Serial)) {} // awaits a response module
		}
	}
  
// --- POWER SAVING FUNCTIONS (atmega) ---------------------------------------------

// set system into the sleep state
// system wakes up when wtchdog is timed out

void system_sleep() {
  power_adc_disable(); // ADC OFF
  power_spi_disable();
  power_twi_disable();
  power_usart0_disable(); // USB OFF
  power_all_disable ();
  
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
  sleep_enable();
  sleep_mode(); // system sleeps here
  sleep_disable(); // system continues execution here when watchdog timed out
  
  power_all_enable ();
  power_adc_enable();
  power_spi_enable();
  power_twi_enable();
  }

// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
void setup_watchdog(int ii) {
  byte bb;
  int ww;
  if (ii > 9 ) ii=9;
  bb=ii & 7;
  if (ii > 7) bb|= (1<<5);
  bb|= (1<<WDCE);
  ww=bb;
  // Clear the reset flag
  MCUSR &= ~(1<<WDRF);
  // start timed sequence
  WDTCSR |= (1<<WDCE) | (1<<WDE);
  // set new watchdog timeout value
  WDTCSR = bb;
  WDTCSR |= _BV(WDIE);
  }

// Watchdog Interrupt Service / is executed when watchdog timed out
ISR(WDT_vect) {
  f_wdt++;  // set global flag
  }

J'ai un autre problème d'alimentation, actuellement mon proto tourne avec une petite batterie de 1000mAh, j'ai acheté une pile en 3.6V et 17Ah et je l'ai essayée et ça ne fonctionne pas très bien. Le GPS et le fona s’allument bien mais seulement quelques secondes et puis ils s'éteignent, ils ne réalisent donc pas leurs taches.

Voilà voilà, si vous avez une idée du pourquoi du comment, je me tiens à votre disposition.
Merci d'avance !

Re, je pense avoir trouvé la raison de mon second problème. En effet ma pile peut fournir un courant de 250mA max et le fona peut monter à plus d'un ampère lors de pic de courant, la pile ne pouvant pas fournir ça le fona plante. Il me faut un truc pour obtenir ce courant... Un condo qui servirait de tampon ?

Une deuxième pile (ou batterie) à même de fournir le courant voulu branchée en parallèle avec la pile ? Mais j'ai peur de causé des dommages à la pile si la batterie se décharge (ces piles ne se recharges pas), des diodes peuvent peut être aider ?

Enfin voilà c'est galère.

Pour le premier problème je vais tester demain de transformer mon objet GPS en pointeur que j'alourai à chaque powerOnGPS(); et que je détruirai à chaque powerOffGPS(); je pense que ça contrera le problème, ce sera comme rebooter le programme, on verra bien.

EDIT :

J'ai pallié au problème de l'allumage du GPS en changeant mon pin 5 par A0.
Par contre le GPS semble m'envoyer tout ce que je veux sauf l'heure. Embêtant.

Re bonjour,
Je me permet de triple posté premièrement pour vous rapporter mes fracassantes avancées et aussi un peut pour faire remonter le topic.

Alors, j'ai finalement remis l'objet GPS en allocation statique, ça causait le bug de l'heure, d'autre part en branchant la pin 5 et A0 sur la commande ça semble mieux fonctionner mais ce n'est pas encore parfait, alors que le système semblait bien fonctionner il s'est subitement mis à ne plus allumer le GPS et à ne plus rien faire. Le reboot à relancé le système mais pour combien de temps ?

Sinon pour la pile je pense pouvoir la brancher en parallèle avec ma batterie lithium moyennant une diode pour évité que la pile ne se charge. Voilà comment je comprends la chose :

Les charges et décharges de batteries en parallèle équilibrent leurs tensions (et donc leur ampérages), donc si je met une diode sur ma pile, elle ne pourra que se décharger et non plus se charger. Pas de risque d'explosion pour la pile donc.
Pour ce qui est de la batterie, si je comprend bien elle se charge quand la tension qui lui est envoyée est supérieur à sa tension propre. Sachant que ma pile à une tension max de 3.7V et la tension max de la pile étant de 4.2V elle ne devrait se charger que jusqu'à 3.7V ?

Sinon j'ai cette pile qui a l'air bien :