I have been trying to get GPS data for a quadcopter project. It needs to be very fast and not use SoftwareSerial.h because this interferes with my Wire.h usage.
Basically, I want a way to use a hardware serial to get data in from my GPS (which can then be parsed by TinyGPS library, unless you know of a faster alternative), but using the Arduino UNO, I only have one Serial port (I think), so this method would block communication with my PC.
I can upload my current code, but I don't think it would be very helpful. Does anyone have any ideas on how to get GPS data without SoftwareSerial or Serial?
Thanks in advance, and let me know if you need more information.
EDIT: Perhaps this would make things more clear: I essentially want to set my Arduino UNO serial RX and TX pins to Digital Pins 2 and 3. Is this possible? Right now, I am simply unplugging my GPS, uploading code, then plugging the GPS back in. This works, but is really a pain and seems really stupid.
EDIT #2: After more research, I now understand that SoftwareSerial is the way to do what I request in "EDIT #1". Unfortunately I am using the Wire library, and I have done research on how to stop the interference between Wire and SoftwareSerial but still don't really understand how to stop it or why it is happening.
You could use an Arduino Leonardo. That won't get you two serial ports but you can use Serial1 (Pin 0 and Pin 1) for your GPS without getting in the way of Serial (the USB port).
You could use an Arduino Mega 2560. That has four hardware serial ports and is less than 50% bigger than the UNO.
There are other software serial libraries that might solve the problem
+1
Read more about the choices here. All these libraries, including NeoGPS, are available from the Ardino IDE Library Manager, under the menu Sketch -> Include Library -> Manage Libraries.
If you'd like to see what it looks like with NeoGPS, post your code. It will be smaller, faster, more reliable and more accurate.
I tried using those libraries, and the only one which didn't interfere with my "previous declaration of __vector3" (not even really sure what that means) was AltSoftSerial. This would have worked beautifully for my application, but it requires pins 8 and 9 for Rx and Tx. Thanks for all the help, it looks like there is not a very simple solution to my problem.
the only one which didn't interfere with my "previous declaration of __vector3" (not even really sure what that means) was AltSoftSerial.
You didn't post your code, so we don't know what other libraries you are using. SoftwareSerial will manifest this problem when you try to use it with a Pin Change Interrupt library. NeoSWSerial will do that too, but it has a way to avoid the error.
Thanks for all the help, it looks like there is not a very simple solution to my problem.
Yeah, we really can't help you, I guess... Or you could post your code and get an answer toot sweet. -_-
-dev: That is super helpful! I am using PCINT for my interrupts, so it looks like your solution will completely fix my issue! Also, I was being serious when I said thanks before
I have overlap between this declaration and the EnableInterrupt library. Do you know of any way that I could simply call the function "enableInterrupt(pin, nssPortISR, CHANGE)" without using the library? Can I do it through a hardware command or is this impossible?
Why won't you post your complete sketch? That snippet tells me nothing about how you are setting up the ISR(s) and/or how you are using the EnableInterrupt library.
johnwasser:
You could use an Arduino Leonardo. That won't get you two serial ports but you can use Serial1 (Pin 0 and Pin 1) for your GPS without getting in the way of Serial (the USB port).
You could use an Arduino Mega 2560. That has four hardware serial ports and is less than 50% bigger than the UNO.
Lots of other boards have multiple Hardware Serial ports too. Any product in the Teensy 3.x family for example. And, you'd get a much more powerful 32-bit processor.
Here, I am simply getting GPS data in from the hardware serial port, not using NeoSWSerial because of the conflict, but it would be simple to change a few lines and substitute a NeoSWSerial if I could avoid the interrupt conflict.
Here, I am simply getting GPS data in from the hardware serial port, not using NeoSWSerial because of the conflict, but it would be simple to change a few lines and substitute a NeoSWSerial if I could avoid the interrupt conflict.
Don't bother switching to NeoSWSerial. If you have it working with HardwareSerial (i.e., GPS on Serial), that is the absolute best way... as I said in the "Choosing a Serial Connection" link (reply #3). NeoSWSerial is less reliable than AltSoftSerial, and both are 200x-500x more CPU intensive than HardwareSerial. :o
I'll post a NeoGPS version of your sketch later... Since you are only using lat/lon, the sketch will be quite a bit smaller.
It doesn't look like you are using the GPS info for anything. Is that correct? Why do you need GPS?
The original sketch uses 19876 bytes of program space and 1026 bytes of RAM.
The NeoGPS version uses 20642 bytes of program space and 806 bytes of RAM.
Surprisingly, the NeoGPS version is a little larger. I think it is due to the high-precision distance calculation (32-bit integer math). Without the distance calculation, the NeoGPS program size is 19134 bytes. BTW, the NeoGPS distance calculation is very accurate at small distances. The single-precision float calculations performed by other libraries can be off by 10%-50% (worse at smaller distances).
20% less RAM is a significant savings, though. If you'd like to try it, NeoGPS is available from the Ardino IDE Library Manager, under the menu Sketch -> Include Library -> Manage Libraries.
Thanks! I agree, keeping the hardware port is easier, but it is quite annoying to have to unplug my GPS every time I want to upload new code to the Arduino. This is why I was hoping for a quick fix and wasn't too disappointed when there didn't seem to be one.
stbuebel:
it is quite annoying to have to unplug my GPS every time
Some people put a switch in that connection to avoid plugging and unplugging for uploads. At least one commercial GPS shield has an on-board switch for the same purpose.
/dev:
Surprisingly, the NeoGPS version is a little larger. I think it is due to the high-precision distance calculation (32-bit integer math).
Confirmed. Additional 32-bit integer math routines are linked in that are not used by other libraries. There is also a little extra code for converting the high-precision integer lat/lon to the float values you are printing. There are ways to avoid that; see NMEAloc.ino for a utility that prints the integer lat/lon as if they were double. Double-precision floats are not available on 8-bit Arduinos).
stbuebel:
Wow, NMEA has a muchhhh better GPS library. Thanks for pointing it out!
You're welcome! If you have any questions, please ask.
Dev, I have been reading more about the NeoGPS library (trying to figure out how much functionality etc), and I stumbled upon the fact that you wrote it! Is this true? (if so, I am very impressed)
One last question, do you know of any reliable way to get heading. I am open to using GPS output, and was thinking about a combination of GPS output with MPU gyro output (to approximate yaw/heading at any time). Is there something built into the NeoGPS library to find heading so that this is not necessary?
Thanks in advance, and let me know if you have any other ideas on how to track heading - unfortunately I don't have a compass on my quad.
Alternatively, is there any way to autonomously navigate through GPS waypoints without knowing heading? I can't think of a simple solution, but, if anyone has one that would be awesome.
do you know of any reliable way to get heading? ...was thinking about a combination of GPS output with MPU gyro output (to approximate yaw/heading at any time). Is there something built into the NeoGPS library to find heading so that this is not necessary?
NeoGPS does not provide anything like that. The GPS heading is really "direction of travel", not "orientation of platform".
It is very common to combine multiple sensors' outputs to reduce the total errors in the estimated "state" (location, altitude, speed, heading, etc.). There are several techniques... Madgwick filter seems popular. Kalman isn't as good, and might be more computationally intensive, IIRC.
unfortunately I don't have a compass on my quad.
That sort of sensor is best for many situations, because it provides an (almost) absolute orientation. You have to be careful about the frame and the environment.
I'm not a sensor fusion/autonomous vehicle expert, so I can only guess that the heading derived from the GPS and IMU might be improved by feeding the displacement (apparent heading) back into the filters. Someone else will have to help you with that. Some reading here and here, among many others...