04-20-2012 10:28 PM
Hey everybody, I am looking for some advice with respect to using labview to display GPS data and eventually log that data on an SD card using the CAN / Bus shield. http://www.sparkfun.com/products/10039 Schematic:http://www.sparkfun.com/datasheets/DevTools/Arduino/canbus_shield-v12.pdf
I can already talk to an my serial monitor without labview using C code (Ill post below) that displays the following:
$GPRMC,031136.000,A,4304.5263,N,08753.4315,W,0.99,310.28,210412,,,A*7D
Date: 04/21/12 Time: 9:11:36
Latitude: N 43' 04.52" Longitude: W 087' 53.43"
Speed Over Ground mph: 1.13 kmh: 1.83
Course Over Ground (degrees): 310.28
Works great, I just have no clue how to send this string using LVIFA (once I do I can figure out how to parse this string, probably easier than using C) I am using a EM406A GPS which uses digital pins 4 and 5 (TX and RX). I think I have to flash the Arduino with some sort of serial variable as I would in C but I am not sure, I am really lost at this point. Additionally it would be nice to talk to my SD card using SPI, which I know there are VI's in the package but again am lost here (id like to start with displying GPS info first, take one step at a time)
Any insight or tutorials would be nice, really what I'm looking for is if I have to modify the LFIFA_BASE what do I have to do? and once I do that I'm guessing I can modify the basic Seral Read / Write VI, but again i'm just throwing out my thoughts with no solid knowledge on how to intgrate this concept.
Below is my Arduino code (without using labview) that displays the info in the serial monitor as posted above: Thanks for your help!
PS. this code is available online but I did have to make many modification to make it work the way I want, I could never come up with the following code myself, but after playing with it I actually have learned a lot. I want to apply this same concept to interfacing with labview.... just a side note.
#include <ctype.h>
#include <string.h>
#include <SoftwareSerial.h>
#define txPin 6
#define bit9600Delay 84
#define halfBit9600Delay 42
#define bit4800Delay 188
#define halfBit4800Delay 94
//JoyStick Setup
const int up = A1;
const int right = A2;
const int down = A3;
const int click = A4;
const int left = A5;
int upVal = 1;
int leftVal = 1;
int downVal = 1;
int clickVal = 1;
int rightVal = 1;
unsigned long time1;
unsigned long time;
SoftwareSerial LCD = SoftwareSerial(0, txPin); // since the LCD does not send data back to the Arduino, we should only define the txPin
byte rx = 4;
byte tx = 5;
byte SWval;
char dataformat[7] = "$GPRMC";
char messageline[80] = "";
int i= 0;
char buffer[80];
char *parseptr;
char buffidx;
uint8_t hour, minute, second, anz=0;
uint16_t latitude, longitude, groundspeed, trackangle, track, mph, gs, tmp;
char latdir, longdir, lat0, lat1, lat2, lat3, lat4, lat5, lon0, lon1, lon2, lon3, lon4, lon5, lon6;
char year0, year1, month, month0, month1, date0, date1;
char minutes[2];
char hours[2];
char seconds[2];
char status;
int k=0;
void setup() {
pinMode(rx,INPUT);
pinMode(tx,OUTPUT);
digitalWrite(tx,HIGH);
SWprint('h'); //debugging hello
SWprint('i');
SWprint(10); //carriage return
Serial.begin(9600);
Serial.write("Started");
pinMode(txPin, OUTPUT);
LCD.begin(9600);
clearLCD();
LCD.print("Mike's GPS Setup");
delay(2000);
clearLCD();
Serial.begin(9600);
}
void SWprint(int data)
{
byte mask;
//startbit
digitalWrite(tx,LOW);
delayMicroseconds(bit4800Delay);
for (mask = 0x01; mask>0; mask <<= 1) {
if (data & mask){ // choose bit
digitalWrite(tx,HIGH); // send 1
}
else{
digitalWrite(tx,LOW); // send 0
}
delayMicroseconds(bit4800Delay);
}
//stop bit
digitalWrite(tx, HIGH);
delayMicroseconds(bit4800Delay);
}
char SWread()
{
byte val = 0;
while (digitalRead(rx));
//wait for start bit
if (digitalRead(rx) == LOW) {
delayMicroseconds(halfBit4800Delay);
for (int offset = 0; offset < 8; offset++) {
delayMicroseconds(bit4800Delay);
val |= digitalRead(rx) << offset;
}
//wait for stop bit + extra
delayMicroseconds(bit4800Delay);
delayMicroseconds(bit4800Delay);
return val;
}
}
void char2string(){
i = 0;
buffer[0] = SWread();
if (buffer[0] == 36) //string starts with $
{
i++;
buffer = SWread();
while(buffer != 13 & i<80) //carriage return or max size
{
i++;
buffer = SWread();
}
buffer[i+1] = 0; //make end to string
}
}
void loop(){
digitalWrite(13,HIGH);
//only print string with the right dataformat
char2string();
if (strncmp(buffer, dataformat, 6) == 0 & i>4)
{
for (int i=0;i<strlen(buffer);i++)
// {
Serial.print(buffer);
parseptr = buffer+7; // hhmmss time
tmp = parsedecimal(parseptr);
hour = (tmp / 10000) + 6;
minute = (tmp / 100) % 100;
second = tmp % 100;
// Latitude
parseptr = strchr(parseptr, ',') + 1;
lat0 = parseptr[2];
lat1 = parseptr[3];
lat2 = parseptr[4];
lat3 = parseptr[5];
parseptr = strchr(parseptr, '.') + 1;
lat4 = parseptr[0];
lat5 = parseptr[1];
// Latitude N/S
parseptr = strchr(parseptr, ',') + 1;
if (parseptr[0] != ',')
{
latdir = parseptr[0];
}
// Longitude
parseptr = strchr(parseptr, ',')+1;
lon0 = parseptr[0];
lon1 = parseptr[1];
lon2 = parseptr[2];
lon3 = parseptr[3];
lon4 = parseptr[4];
parseptr = strchr(parseptr, '.') + 1;
lon5 = parseptr[0];
lon6 = parseptr[1];
// Longitude E/W
parseptr = strchr(parseptr, ',')+1;
if (parseptr[0] != ',')
{
longdir = parseptr[0];
}
// Ground Speed Conversion
parseptr = strchr(parseptr, ',')+1;
tmp = parsedecimal(parseptr);
parseptr = strchr(parseptr, '.')+1;
groundspeed = parsedecimal(parseptr);
if(tmp != 0)
{
tmp *= 100;
groundspeed += tmp;
mph=groundspeed * 1.151;
groundspeed *= 1.852;
}
else
{
mph=groundspeed * 1.151;
groundspeed *= 1.852;
}
// Course Over Ground
parseptr = strchr(parseptr, ',')+1;
trackangle = parsedecimal(parseptr);
parseptr = strchr(parseptr, '.')+1;
track = parsedecimal(parseptr);
// Date
parseptr = strchr(parseptr, ',')+1; // date + time
date0 = parseptr[0];
date1 = parseptr[1];
month0 = parseptr[2];
month1 = parseptr[3];
year0 = parseptr[4];
year1 = parseptr[5];
Serial.print("Date: ");
Serial.print(month0); Serial.print(month1);
Serial.print('/');
Serial.print(date0); Serial.print(date1);
Serial.print('/');
Serial.print(year0); Serial.print(year1);
Serial.print(" Time: ");
Serial.print(hour);
Serial.print(':');
Serial.print(minute);
Serial.print(':');
Serial.println(second);
// LCD.write("Date: ");
LCD.write(" ");
LCD.write(month0); LCD.write(month1);
LCD.write('/');
LCD.write(date0); LCD.write(date1);
LCD.write('/');
LCD.write(year0); LCD.write(year1);
LCD.write(" ");
//LCD.write(" Time: ");
LCD.write(" ");
itoa(hour, hours, 10);
LCD.write(hours);
LCD.write(':');
itoa(minute, minutes, 10);
LCD.write(minutes);
LCD.write(':');
itoa(second, seconds, 10);
LCD.write(seconds);
LCD.write(" ");
delay(3000);
clearLCD();
Serial.print("Latitude: ");
Serial.print(latdir);
Serial.print(' ');
Serial.print(lat0); Serial.print(lat1);
Serial.print('\''); Serial.print(' ');
Serial.print(lat2); Serial.print(lat3);
Serial.print('.');
Serial.print(lat4);
Serial.print(lat5);
Serial.print('"'); Serial.print(' ');
LCD.write("Lat ");
LCD.write(latdir);
LCD.write(' ');
LCD.write(lat0); LCD.write(lat1);
LCD.write('\''); //LCD.write(' ');
LCD.write(lat2); LCD.write(lat3);
LCD.write('.');
LCD.write(lat4);
LCD.write(lat5);
LCD.write('"');
LCD.write(' ');
Serial.print("Longitude: ");
Serial.print(longdir);
Serial.print(' ');
Serial.print(lon0); Serial.print(lon1); Serial.print(lon2);
Serial.print('\''); Serial.print(' ');
Serial.print(lon3); Serial.print(lon4);
Serial.print('.');
Serial.print(lon5);
Serial.print(lon6);
Serial.println('"');
LCD.write("Lng ");
LCD.write(longdir);
LCD.write(' ');
LCD.write(lon0); LCD.write(lon1); LCD.write(lon2);
LCD.write('\''); //LCD.write(' ');
LCD.write(lon3); LCD.write(lon4);
LCD.write('.');
LCD.write(lon5);
LCD.write(lon6);
LCD.write('"');
delay(3000);
clearLCD();
Serial.print("Speed Over Ground mph: ");
gs=mph;
tempo(gs);
Serial.print(" kmh: ");
gs=groundspeed;
tempo(gs);
Serial.println(" ");
Serial.print("Course Over Ground (degrees): ");
Serial.print(trackangle);Serial.print(".");
Serial.println(track);
Serial.print(SWread()); Serial.println(); //use this to get all GPS output, comment out from char2string till here
}
}
uint32_t parsedecimal(char *str)
{
uint32_t d = 0;
while (str[0] != 0)
{
if ((str[0] > '9') || (str[0] < '0'))
return d;
d *= 10;
d += str[0] - '0';
str++;
}
return d;
}
void tempo(uint16_t gs){
if(gs <=99) // speed output conversion
{
Serial.print("0.");
Serial.print(gs);
}
else
{
Serial.print(gs/100, DEC); Serial.print(".");
tmp = gs % 100;
if(tmp <=9) Serial.print("0");
Serial.print(tmp);
}
}
void clearLCD(){
LCD.write(0xFE); //command flag
LCD.write(0x01); //clear command.
delay(10);
return;
}
04-20-2012 11:12 PM
In addition I understand and have emulated the C code setup stage by creating my int, pinmode, and digital write VI's.. basics... Where I am stumped is using a state machine, for / while loops to call and emulate the char2string and SWread "calls" which are called right away in the C code loop.
04-24-2012 11:48 PM
Okay
I have been playing around with this which some "sucess"; I am able to recieve bytes and convert them to an ASCII string, however the string only outputs 2^n bytes which obviously will never correspond to the correct output string (ex. 36 == $, 77 == G, etc) need for the / any GPS string.
I will attach my code and screenshot of my output array and string output. Any advice would be appricated!!!
Thanks,
Mike
04-24-2012 11:52 PM
heres the code