GPS en combinación con el servo en Arduino

2

Mis amigos y yo estamos construyendo un barco que debe dirigirse hacia ciertas coordenadas. Tenemos un GPS y una brújula a bordo. Hemos escrito un código que calcula la dirección que tiene que navegar el barco.

Cuando conectamos nuestro GPS junto con la brújula, el sistema funciona. Cuando agregamos el servo al circuito, el servo se balancea hacia adelante y hacia atrás continuamente (incluso cuando en el código solo adjuntamos el servo y no lo controlamos). Si desenchufamos el GPS, el servo dejará de oscilar.

¿Por qué el GPS y el servo no funcionan bien en el mismo circuito de Arduino?

Edit: Lo siento chicos, por no ser lo suficientemente específicos. Déjame darle otra oportunidad:

Hice un pequeño diagrama del circuito que construimos:

Supongoqueelcódigoquecreamosesdemasiadolargoparaapareceraquí(másde300líneasdecódigo),porloquesolosaquélapartegpsdelcódigo(queeslamayorpartedelcódigo).

#include<SoftwareSerial.h>#include<Servo.h>#include<TinyGPS.h>TinyGPSgps;SoftwareSerialss(1,0);staticvoidsmartdelay(unsignedlongms);staticvoidprint_float(floatval,floatinvalid,intlen,intprec);staticvoidprint_int(unsignedlongval,unsignedlonginvalid,intlen);staticvoidprint_date(TinyGPS&gps);staticvoidprint_str(constchar*str,intlen);voidsetup(){Serial.print("Testing TinyGPS library v. "); Serial.println(TinyGPS::library_version());
  Serial.println("by Mikal Hart");
  Serial.println();
  Serial.println("Sats HDOP Latitude  Longitude  Fix  Date       Time     Date Alt    Course Speed Card  Distance Course Card  Chars Sentences Checksum");
  Serial.println("          (deg)     (deg)      Age                      Age  (m)    --- from GPS ----  ---- to London  ----  RX    RX        Fail");
  Serial.println("-------------------------------------------------------------------------------------------------------------------------------------");


  ss.begin(9600);

}

void loop()
{
  float flat, flon;
  unsigned long age, date, time, chars = 0;
  unsigned short sentences = 0, failed = 0;
  static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;

  print_int(gps.satellites(), TinyGPS::GPS_INVALID_SATELLITES, 5);
  print_int(gps.hdop(), TinyGPS::GPS_INVALID_HDOP, 5);
  gps.f_get_position(&flat, &flon, &age);
  print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 10, 6);
  print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 11, 6);
  print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
  print_date(gps);
  print_float(gps.f_altitude(), TinyGPS::GPS_INVALID_F_ALTITUDE, 7, 2);
  print_float(gps.f_course(), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
  print_float(gps.f_speed_kmph(), TinyGPS::GPS_INVALID_F_SPEED, 6, 2);
  print_str(gps.f_course() == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(gps.f_course()), 6);
  print_int(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0xFFFFFFFF : (unsigned long)TinyGPS::distance_between(flat, flon, LONDON_LAT, LONDON_LON) / 1000, 0xFFFFFFFF, 9);
  print_float(flat == TinyGPS::GPS_INVALID_F_ANGLE ? TinyGPS::GPS_INVALID_F_ANGLE : TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
  print_str(flat == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON)), 6);

  gps.stats(&chars, &sentences, &failed);
  print_int(chars, 0xFFFFFFFF, 6);
  print_int(sentences, 0xFFFFFFFF, 10);
  print_int(failed, 0xFFFFFFFF, 9);
  //Serial.println();

  smartdelay(1000);

}


 static void smartdelay(unsigned long ms)
{
  unsigned long start = millis();
  do 
  {
    while (ss.available())
      gps.encode(ss.read());
  } while (millis() - start < ms);
}

static void print_float(float val, float invalid, int len, int prec)
{
  if (val == invalid)
  {
    while (len-- > 1)
      Serial.print('*');
    Serial.print(' ');
  }
  else
  {
    Serial.print(val, prec);
    int vi = abs((int)val);
    int flen = prec + (val < 0.0 ? 2 : 1); // . and -
    flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
    for (int i=flen; i<len; ++i)
      Serial.print(' ');
  }
  smartdelay(0);
}

static void print_int(unsigned long val, unsigned long invalid, int len)
{
  char sz[32];
  if (val == invalid)
    strcpy(sz, "*******");
  else
    sprintf(sz, "%ld", val);
  sz[len] = 0;
  for (int i=strlen(sz); i<len; ++i)
    sz[i] = ' ';
  if (len > 0) 
    sz[len-1] = ' ';
  Serial.print(sz);
  smartdelay(0);
}

static void print_date(TinyGPS &gps)
{
  int year;
  byte month, day, hour, minute, second, hundredths;
  unsigned long age;
  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  if (age == TinyGPS::GPS_INVALID_AGE)
    Serial.print("********** ******** ");
  else
  {
    char sz[32];
    sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d ",
        month, day, year, hour, minute, second);
    Serial.print(sz);
  }
  print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
  smartdelay(0);
}

static void print_str(const char *str, int len)
{
  int slen = strlen(str);
  for (int i=0; i<len; ++i)
    Serial.print(i<slen ? str[i] : ' ');
  smartdelay(0);
}
    
pregunta Just van Til

2 respuestas

3

A pesar de todos los demás comentarios (sobre su lógica de dirección, etc.), el problema específico que está teniendo es un conflicto entre las bibliotecas de SoftwareSerial y Servo. Tuve la misma cosa (para el mismo tipo de proyecto, irónicamente):

enlace

Parafraseando desde el hilo

  

El problema parece haber sido que ambas bibliotecas usan el mismo   Temporizador de hardware, y terminan en conflicto. Usted puede usar   HardwareSerial (si tiene un puerto de repuesto), o use el ServoTimer2   biblioteca, en su lugar.

Por cierto, mi proyecto que hace lo mismo vive aquí: enlace

    
respondido por el kolosy
0

El piloto automático de mi embarcación usa tanto el GPS como una brújula magnética.

Cuando lo dirijo para que dirija hacia un punto de ruta de GPS, el piloto primero toma el rumbo del punto de ruta desde el GPS, luego dirige el barco hacia ese rumbo como lo indica la brújula. Una vez que la embarcación apunta hacia el destino, el piloto automático luego dirige su atención al Error de seguimiento cruzado desde el GPS, y realiza pequeñas correcciones en el rumbo magnético para minimizar el error de seguimiento cruzado. Una vez en el rumbo, el piloto automático ignora el rumbo del GPS al punto de referencia (y nunca mira el curso del curso GPS Bueno).

La corrección de la dirección debe hacerse en pasos pequeños, lo que permite que la embarcación reaccione entre correcciones.

    
respondido por el Peter Bennett

Lea otras preguntas en las etiquetas