Se trata de simular la velocidad con un modulo GPS y el arduino. El GPS da la posición, el arduino procesa esa posición y saca una señal, que con un transistor externo la convierto en valores 0v o 5v.
Es como si ese 0v o 5v lo diera una ruleta girando con un imán sobre un sensor hall fijo. Ese 0v o 5v lo necesita el display que me marca la velocidad.
Este es el código:
#define F_CPU 16000000L
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h> // including the average delay lib
#include <SoftwareSerial.h>
#include "led.h" // Header file for led
#include "usart.h" // Header for Serial communication
#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 sentences
#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,01,01"
#define NMEA_QUERY_VTG "PSRF103,05,01,01,01"
char nmea_data[128];
#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];
long knots=1000L,tknots;
int dotpos;
#define KNOT_FACTOR_H 2626000L
#define KNOT_FACTOR_L 164125L
#define KNOT_LOWER_THRESHOLD 300L //below 3 knots
#define KNOT_UPPER_THRESHOLD 500L //over 5 knots
#define INIT_TIMER_COUNT 6
#define RESET_TIMER2 TCNT2 = INIT_TIMER_COUNT
int ledPin = 13;
int int_counter = 0;
int on=0;
/* Timer2 reload value, globally available */
unsigned int tcnt2;
int pwm_high=-1;
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++]='
Gracias por la ayuda.
;
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);
}
void pwm_set(long OCRValue)
{
OCR1A = OCRValue; // set the counter
}
void pwm_start(int high_low)
{
if(high_low)
TCCR1B = _BV(WGM12)|_BV(CS11)|_BV(CS10); // // CTC mode - 64 prescale
else
TCCR1B = _BV(WGM12)|_BV(CS12)|_BV(CS10); // // CTC mode - 256 prescale
TCCR1A = _BV(COM1A0); // // Toggle mode 0C1A
pwm_high=high_low;
}
void pwm_stop(void)
{
TCCR1B &= ~(1<<CS12); // Clear bit
TCCR1B &= ~(1<<CS10); // Clear bit
}
void set_tknots(long knots)
{
if(knots > 0) {
if(pwm_high==1) {
if(knots > KNOT_LOWER_THRESHOLD) {
tknots=KNOT_FACTOR_H/knots;
pwm_set(tknots);
} else {
tknots=KNOT_FACTOR_L/knots;
pwm_start(0);
pwm_set(tknots);
}
}
else if(pwm_high==0) {
if(knots < KNOT_UPPER_THRESHOLD) {
tknots=KNOT_FACTOR_L/knots;
pwm_set(tknots);
} else {
tknots=KNOT_FACTOR_H/knots;
pwm_start(1);
pwm_set(tknots);
}
} else {
tknots=KNOT_FACTOR_L/knots;
pwm_start(0);
pwm_set(tknots);
}
}
else {
pwm_high=-1;
pwm_stop();
}
}
void restart_vtg(void)
{
led1.on();
_delay_ms(100);
send_nmea(NMEA_QUERY_VTG);
led1.off();
}
int main(void)
{
char c,*p;
unsigned char stat=STAT_NMEA_NONE;
int head_counter,nmea_field_counter,nmea_field_data_counter;
int delay_counter=0;
// INITIALIZATIONS
DDRB = 0b00100010; //B5 output: board LED B2 OC1 output
USART_Init(MYUBRR); // Initializes the serial communication
mySerial.begin(4800);
mySerial.listen();
set_tknots(knots);
_delay_ms(10000);
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_DISABLE_VTG);
restart_vtg();
while(1)
{
sei();
#if 0
for(knots=0; knots < 5000L; knots+=50){
led1.on();
set_tknots(knots);
_delay_ms(500);
led1.off();
}
#endif
if (mySerial.available()) {
c=mySerial.read();
MYDEBUG(USART_Sendbyte(c));
if( c < 0x20) {
stat=STAT_NMEA_NONE;
}
if( c == 0x0a) {
restart_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=knots10L+*p-'0';
}
p++;
}
// sprintf(nmea_field,"\r\nspeed=%d\n\r",(int)knots);
// USART_Send_string(nmea_field);
set_tknots(knots);
delay_counter=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:
delay_counter++;
_delay_ms(100);
if(delay_counter>100) { //10 seconds
delay_counter=0;
restart_vtg();
}
if(c=='
Gracias por la ayuda.
) {
stat=STAT_NMEA_HEADER;
head_counter=0;
}
break;
}
}
}
}
Gracias por la ayuda.