![]() |
|
|
|
| VHF: Canal 77 |    | ![]() |
![]() |
![]() |
![]() |
![]() |
|
#1
|
||||
|
||||
|
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;
}
}
}
}
|
| 41 Cofrades agradecieron a jiauka este mensaje: | ||
adri_cubs (31-05-2018), Akakus (14-05-2012), alarones (11-05-2012), alcapar (16-08-2019), Alux (16-09-2019), arcanos (25-04-2016), BlueMoon (14-05-2013), Camelot (03-07-2016), Capicua (05-04-2013), Capitanlanmar (27-01-2014), Chemaximus (14-09-2019), corsariomad (25-12-2014), duendevelas (10-08-2013), genoves (01-12-2014), Islanautica (14-05-2012), iven (27-07-2015), Jarcio (24-09-2014), jesmal (31-07-2018), JMPUIG (19-07-2013), Jony-- (07-08-2013), Juan de Nova (03-12-2017), Juanitu (09-10-2012), Mariñel (30-09-2014), Mescalino (10-10-2012), Nick (14-05-2012), nombrote (04-09-2018), olaje (09-10-2012), PANTU289 (25-05-2018), pato (09-10-2012), PEDRO >K (31-08-2016), Pipika (08-09-2019), RASTABAN (21-07-2013), Rebellin (20-08-2014), Rony (10-05-2012), Rotito (04-10-2016), Tabeirón Coruña (31-12-2021), tarifafun (07-04-2013), teteluis (25-09-2015), tio_ambeto (01-12-2017), topovespa (07-08-2013), Ventoleras (11-05-2012) | ||
|
|