Discusión: Bricobarco Simulador de corredera usando 1 GPS
Ver mensaje
  #84  
Antiguo 29-09-2015, 08:13
Avatar de North Side
North Side North Side esta desconectado
Hermano de la costa
 
Registrado: 11-08-2013
Edad: 50
Mensajes: 2,118
Agradecimientos que ha otorgado: 887
Recibió 1,092 Agradecimientos en 551 Mensajes
Sexo:
Predeterminado Simulador de corredera usando 1 GPS

Cita:
Originalmente publicado por jiauka Ver mensaje
Hola:

Hace días que tenía pendiente 1 pequeño brico para sustituir el típico sensor airmar analógico que llevan muchos veleros (el típico con el cable de masa, rojo y verde). Lo que hace es simular los impulsos en función de la velocidad GPS (SOG), ya sé que no es muy ortodoxo, ya que no tiene en cuenta la corriente, pero no tengo ningún agujero en el casco y no quiero hacerlo.

He usado 1 placa de desarrollo arduino

http://arduino.cc/en/Main/ArduinoBoardNano

1 sensor GPS NMEA0183


y 1 poco de programación en C algo cutre.
Código:
  

#define F_CPU 16000000L
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>    // including the avr delay lib
#include "led.h"            // Header file for led
#include "usart.h"            // Header for Serial communication
#include "SoftwareSerial.h"

#define MYDEBUG(x)

// OBJECT CREATION
LED led1(0x05,5);            // Creates an object called led1 connected to PortB.5 (0x05 is the Special function register for PORTB)
LED output(0x0b,4);  //PPRTD, bit 4

SoftwareSerial mySerial(2, 3,false);
#include <avr/io.h>
#include <avr/interrupt.h>

#define FOSC F_CPU // Clock Speed
#define BAUD 115200      // Baud Rate
#define MYUBRR (((((FOSC * 10) / (16L * BAUD)) + 5) / 10) - 1)

// NMEA setences
#define NMEA_DISABLE_CGA "PSRF103,00,00,00,01"
#define NMEA_DISABLE_GLL "PSRF103,01,00,00,01"
#define NMEA_DISABLE_GSA "PSRF103,02,00,00,01"
#define NMEA_DISABLE_GSV "PSRF103,03,00,00,01"
#define NMEA_DISABLE_RMC "PSRF103,04,00,00,01"
#define NMEA_DISABLE_VTG "PSRF103,05,00,00,01"
#define NMEA_ENABLE_VTG_1HZ "PSRF103,05,00,05,01"
#define NMEA_QUERY_VTG "PSRF103,05,01,01,01"

char nmea_data[128];
char setnyb(unsigned char c)
{
  if(c<9) return c+'0';
  else return c-10+'A';
}

void send_nmea(const char *datagram) {
    int i;
    char *p=(char*)datagram;
    unsigned char checksum=0;
    i=0;
    nmea_data[i++]='$';
    while(*p) {
        nmea_data[i]=*p++;
        checksum=checksum^nmea_data[i];
        i++;
    }
    nmea_data[i++]='*';
    nmea_data[i++]=setnyb((checksum >> 4) &0x0f);
    nmea_data[i++]=setnyb(checksum &0x0f);
    nmea_data[i]=0x00;
    mySerial.println((const String &)nmea_data);
    
}
#define STAT_NMEA_NONE 0
#define STAT_NMEA_HEADER 1
#define STAT_NMEA_DATA 2
        
//    VTG-Course Over Ground and Ground Speed
//$GPVTG,309.62,T,,M,0.13,N,0.2,K
char nmea_header[5];
char nmea_field[32];    
int knots=1450,dotpos,tknots=10;

int int_counter = 0;
volatile int second = 0;
int oldSecond = 0;
long starttime = 0;
int on=0;
/* Timer2 reload value, globally available */  
unsigned int tcnt2;  
 
// Aruino runs at 16 Mhz, so we have 1000 Overflows per second...
// 1/ ((16000000 / 64) / 256) = 1 / 1000
ISR(TIMER2_OVF_vect) {
       /* Reload the timer */  
      TCNT2 = tcnt2;  
    int_counter++;
    if(tknots > 0 ) {
          if (int_counter >= tknots) {
             if(on) {
                 led1.on();
                output.on();
                on=0;
            }
               else {
                   led1.off();
                output.off();
                on=1;
            }
            int_counter = 0;
        }
    }
};
 
 void timer_setup() {  
  
  TIMSK2 &= ~(1<<TOIE2);  
  
  /* Configure timer2 in normal mode (pure counting, no PWM etc.) */  
  TCCR2A &= ~((1<<WGM21) | (1<<WGM20));  
  TCCR2B &= ~(1<<WGM22);  
  
  /* Select clock source: internal I/O clock */  
  ASSR &= ~(1<<AS2);  
  
  /* Disable Compare Match A interrupt enable (only want overflow) */  
  TIMSK2 &= ~(1<<OCIE2A);  
  
  /* Now configure the prescaler to CPU clock divided by 128 */  
  TCCR2B |= (1<<CS22)  | (1<<CS20); // Set bits  
  TCCR2B &= ~(1<<CS21);             // Clear bit  
  
  /* We need to calculate a proper value to load the timer counter. 
   * The following loads the value 131 into the Timer 2 counter register 
   * The math behind this is: 
   * (CPU frequency) / (prescaler value) = 125000 Hz = 8us. 
   * (desired period) / 8us = 125. 
   * MAX(uint8) + 1 - 125 = 131; 
   */  
  /* Save value globally for later reload in ISR */  
  tcnt2 = 131;   
  
  /* Finally load end enable the timer */  
  TCNT2 = tcnt2;  
  TIMSK2 |= (1<<TOIE2);  
}  

int main(void)
{
    char c,*p;
    unsigned char stat=STAT_NMEA_NONE;
    int i,head_counter,nmea_field_counter,nmea_field_data_counter;
    // INITIALIZATIONS
    DDRB = 0b00100000;    //B5 output: board LED
    USART_Init(MYUBRR); // Initializes the serial communication

    mySerial.begin(4800);
    mySerial.listen();
    tknots=10000/knots;
    timer_setup();
    _delay_ms(1000);
    sei();
    send_nmea(NMEA_DISABLE_CGA);
    send_nmea(NMEA_DISABLE_GLL);
    send_nmea(NMEA_DISABLE_GSA);
    send_nmea(NMEA_DISABLE_GSV);
    send_nmea(NMEA_DISABLE_RMC);
    send_nmea(NMEA_DISABLE_VTG);
    send_nmea(NMEA_ENABLE_VTG_1HZ);
    while(1)
    {
        sei();
        
         if (mySerial.available()) {
            c=mySerial.read();
            MYDEBUG(USART_Sendbyte(c));
            if( c < 0x20) {
                stat=STAT_NMEA_NONE;
            }
            if( c == 0x0a) {
                _delay_ms(100);
                send_nmea(NMEA_QUERY_VTG);
            }
            switch (stat) {

                case STAT_NMEA_HEADER:
                    if(head_counter < 5 ) {
                        nmea_header[head_counter++] = c;
                        if(head_counter==5) {
                            if(strncmp(nmea_header,"GPVTG",5) ==0) {
                                MYDEBUG(USART_Send_string("GPVTG\r\n"));
                                stat=STAT_NMEA_DATA;
                                nmea_field_counter=0;
                                head_counter=0;
                            } else {
                                stat=STAT_NMEA_NONE;
                            }                            
                        }
                    } else {
                        stat=STAT_NMEA_NONE;
                    }                            
            
                break;
                case STAT_NMEA_DATA:
                    if(c == ',') {
                        if(nmea_field_counter==5) {
                            p=nmea_field;
                            dotpos=0;
                            knots=0;
                            while(*p) {
                                if(*p >= '0' && *p <= '9') {
                                    knots=knots*10+*p-'0';
                                }
                                p++;
                            }
                            sprintf(nmea_field,"\r\nspeed=%d\n\r",knots);
                            USART_Send_string(nmea_field);
                            if(knots>0)
                                tknots=10000/knots;
                            else
                                tknots=0;
                        }                            
    
                        nmea_field_counter++;
                        nmea_field_data_counter=0;
                        nmea_field[0]=0;
                    }
                    if(nmea_field_counter==5) {
                        nmea_field[nmea_field_data_counter++]=c;
                        nmea_field[nmea_field_data_counter]=0;
                    }
                    break;
                case STAT_NMEA_NONE:
                default:
                    if(c=='$') {
                        stat=STAT_NMEA_HEADER;
                        head_counter=0;
                    }
                break;
            }
        }
    }
}
Si hay alguien interesado en esquema, etc... para hacerse 1 que me lo diga y miro de pasarlo a limpio.

Hola jiauka. Te he puesto un privado también, pero parece que no te llega o tienes la entrada llena. Me puedes orientar sobre esto:

Buenas, estoy intentando programar el Arduino con el Atmel Studio 6.2 pero no hay manera de compilar el código, me devuelve un error tal que así:

Código:
unrecognized command line option '-Wl'


¿Alguien sería tan amable de decirme que estoy haciendo mal?



Muchas gracias y un saludo
Citar y responder