Hi. I'm trying to teach myself code by playing with code examples.
I've started a sketch by using part of Mikal Hart's TinyGPS DeviceExample and a post I picked up along the way written by Pico for the nrf24l01+. As I stated, I'm trying to learn and could use some pointers regarding the code, as I have some errors. I'm going around in circles, by having 1 error, so I edit, then get a whole doss of them.
My aim is to send GPS coordinates over nrf24l01+ units, to display at the receiver on serial monitor "basically a dog tracker".
I have seen Stanley Seow's code for doing this, but have had no success, so decided to have ago by read other code and writing my own.
So far I'm only working on the TX side. Linx RM GPS receiver, 2x Mega 2560 & nrf24l01+.
I would appreciate some advice, not the code writing for me.
My errors at the moment;
My_GPS.ino: In function 'void loop()':
My_GPS:52: error: 'displayInfo' was not declared in this scope
My_GPS:72: error: a function-definition is not allowed here before '{' token
My_GPS:90: error: expected `}' at end of input
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
#define CE_PIN 9 //Set pin for Mega 2560
#define CSN_PIN 53
/*
This sample sketch demonstrates the normal use of a TinyGPS++ (TinyGPSPlus) object.
It requires the use of SoftwareSerial, and assumes that you have a
4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/
static const int RXPin =10, TXPin =11; // Change pins for Mega 2560
static const uint32_t GPSBaud = 9600; // Change Baun to meet GPS
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };
// Define objects
TinyGPSPlus gps;
RF24 radio(CE_PIN, CSN_PIN);
// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);
void setup()
{
Serial.begin(115200);
ss.begin(GPSBaud);
radio.begin();
radio.openWritingPipe(pipes[0]);
radio.openReadingPipe(1,pipes[1]);
radio.enableDynamicPayloads() ;
radio.setAutoAck( true ) ;
//radio.setDataRate( RF24_250KBPS );
radio.setDataRate( RF24_1MBPS );
radio.powerUp() ;
Serial.println(F("DeviceExample.ino"));
Serial.println(F("A simple demonstration of TinyGPS++ with an attached GPS module"));
Serial.print(F("Testing TinyGPS++ library v. ")); Serial.println(TinyGPSPlus::libraryVersion());
Serial.println(F("by Mikal Hart"));
Serial.println();
}
void loop() {
// This sketch displays information every time a new sentence is correctly encoded.
while (ss.available() > 0)
if (gps.encode(ss.read()))
displayInfo();
if (millis() > 5000 && gps.charsProcessed() < 10)
{
Serial.println(F("No GPS: ."));
while(true);
while (Serial.available());
char c = Serial.read();
radio.write(&c, sizeof(char));
//delay(250);
Serial.write(c);
}
void displayInfo()
{
Serial.print(F("Location: "));
Serial.println();
if (gps.location.isValid())
{
Serial.print(F("Latd N: "));
Serial.print(gps.location.lat(), 6);
Serial.print(F(" , "));
Serial.print(F("Long W: "));
Serial.print(gps.location.lng(), 6);
}
}
else
{
Serial.print(F("INVALID"));
}
Serial.println();
}
}
/code]
Thank you If you have a look.
Hi @UKHeliBob.
Thank you for your reply, was starting to give up with the Arduino forum for advice.
As I'm teaching myself, I had to go to the help section to find "Auto Formatting".
Sorry if a pain in the rear, but learning.
It states;
Auto Format Canceled: Too many right curly braces.
This would be "}"???
I will have another look at the code regarding this.
With regards to your comments; "Where does my loop program end"?
I'm guessing that I need to put a statement in that states "End loop<>", "thats a human guess", but I don't know how to end this statement correctly, as you have brought It to my attention?
"while(true);". Would you be advising against this statement, or questioning It's reason?
Thanks HELiBob for some pointers, and feedback.
Appreciated.
I'm guessing that I need to put a statement in that states "End loop<>", "thats a human guess", but I don't know how to end this statement correctly, as you have brought It to my attention?
The "statement" that ends a function is "}". Yes, you need one.
"while(true);". Would you be advising against this statement, or questioning It's reason?
Auto Format has told you that you have too many right braces, the } character. Each { needs a corresponding } but they must be in the correct place such as the start and end of a function or a code block to be executed when a condition is true, for example. In the IDE put the cursor to the right of any bracket or brace and the IDE will indicate its corresponding partner, if it exists.
As towhile(true);What are you trying to do ? Will the statement ever be false and allow the program to continue ?
Thank you both for your comments and input.
Got shot of "while(true);"
Regarding the " { }'s ", I have gone through the sketch, found the issues and corrected accordingly "THANK YOU FOR THAT", although this then caused other errors, but worked them out.
The new sketch now compiles and prints GPS coordinates to the serial monitor.
I don't know at this point if, the coordinates are being sent over the radio "nrf24l01+", as I need to write a RX sketch to test.
I have put reference in the sketch with regards to, both your input "if you don't mind this"? Please advise If this Is ok.
With the sketch now working "less the radio test", I'm receiving GPS coordinates 2 or 3 times a second.
When I get the RX radio up and running, the end RX device will be mobile "RX to receive and display coordinates In serial monitor, Is for testing", thus will be displaying on an LCD.
With receiving this much info "coordinates updating so fast", on the RX, I would like the LCD to display/update every 10 or 20 seconds.
Would I be better to resolve this on the TX side, or resolve this on the RX side.
I ask this as I read parts of comments regarding "SoftwareSerial & overflow"?
Can you both please, give yourselves a pat on the back, as I'm so chuffed that "we", have got this to compile.
If you can't give yourself a pat on the back, I'll send some in a Jiffy bag. LOL.
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
#define CE_PIN 9 //Set pins for Mega 2560.
#define CSN_PIN 53
/*
This sample sketch is part of Two examples that i have manipulated with help from @UKHeliBob & @PaulS (Arduino forum), "THANK YOU".
The Two original codes are with thanks to @Mikal Hart (TinyGPS++, http://arduiniana.org/), & @Pico (nrf24l01+ Arduino forum), "THANK YOU".
This code is just for TX. Compiled and receiving GPS coordinates in serial monitor, but the radio link remains untested!
*/
static const int RXPin =10, TXPin =11; // Change pins for Mega 2560.
static const uint32_t GPSBaud = 9600; // Change Baun to meet GPS.
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL }; // Radio channels.
TinyGPSPlus gps; // Define objects, GPS & radio.
RF24 radio(CE_PIN, CSN_PIN);
SoftwareSerial ss(RXPin, TXPin); // The serial connection to the GPS device set above as pins 10 & 11.
void setup()
{
Serial.begin(115200); // Set serial monitor to view.
ss.begin(GPSBaud); // GPS is set above to 9600.
radio.begin();
radio.openWritingPipe(pipes[0]);
radio.openReadingPipe(1,pipes[1]);
radio.enableDynamicPayloads();
radio.setAutoAck( true );
radio.setDataRate( RF24_1MBPS ); // Set radio datarate to ( RF24_250KBPS ).
radio.powerUp();
Serial.println(F("DeviceExample.ino"));
Serial.println(F("A simple demonstration of TinyGPS++ with an attached GPS module"));
Serial.print(F("Testing TinyGPS++ library v. "));
Serial.println(TinyGPSPlus::libraryVersion());
Serial.println(F("by Mikal Hart"));
Serial.println();
}
void loop() {
while (ss.available() > 10) // This sketch displays information every time a new sentence is correctly encoded.
if (gps.encode(ss.read()))
displayInfo();
if (millis() > 5000 && gps.charsProcessed() < 0)
{
Serial.println(F("No GPS: ."));
while (Serial.available()); // Not tested yet, but hopfully, will send GPS coordinates over radio.
char c = Serial.read();
radio.write(&c, sizeof(char));
//delay(250);
Serial.write(c);
}}
void displayInfo(){
Serial.print(F("Location: ")); // GPS coordinates displayed in serial monitor.
Serial.println();
if (gps.location.isValid());
else
Serial.print(F("NO GPS."));
Serial.print(F("Latd N: "));
Serial.print(gps.location.lat(), 6);
Serial.print(F(" , "));
Serial.print(F("Long W: "));
Serial.print(gps.location.lng(), 6);
Serial.println();
}
/code]
Thanks for that.
I'll give It a go.
This Is on the RX side. Correct?
Dizzwold.
your loop() function calls to update the display every time it circles around.
displayInfo();
I modified the displayInfo() function to only execute when the timer reaches 20 seconds. Once that happens, it will update the serial display and then reset the timer for the next 20second update. This will be very useful for you when you convert to an LCD display later on.
inserted into your code:
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
#define CE_PIN 9 //Set pins for Mega 2560.
#define CSN_PIN 53
/*
This sample sketch is part of Two examples that i have manipulated with help from @UKHeliBob & @PaulS (Arduino forum), "THANK YOU".
The Two original codes are with thanks to @Mikal Hart (TinyGPS++, http://arduiniana.org/), & @Pico (nrf24l01+ Arduino forum), "THANK YOU".
This code is just for TX. Compiled and receiving GPS coordinates in serial monitor, but the radio link remains untested!
*/
static const int RXPin =10, TXPin =11; // Change pins for Mega 2560.
static const uint32_t GPSBaud = 9600; // Change Baun to meet GPS.
const uint64_t pipes[2] = {
0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL }; // Radio channels.
//
unsigned long startTime = millis();
unsigned long updateInterval = 20000UL; // equivalent of 20seconds in milliseconds.
//
TinyGPSPlus gps; // Define objects, GPS & radio.
RF24 radio(CE_PIN, CSN_PIN);
//
SoftwareSerial ss(RXPin, TXPin); // The serial connection to the GPS device set above as pins 10 & 11.
//
void setup()
{
Serial.begin(115200); // Set serial monitor to view.
ss.begin(GPSBaud); // GPS is set above to 9600.
radio.begin();
radio.openWritingPipe(pipes[0]);
radio.openReadingPipe(1,pipes[1]);
radio.enableDynamicPayloads();
radio.setAutoAck( true );
radio.setDataRate( RF24_1MBPS ); // Set radio datarate to ( RF24_250KBPS ).
radio.powerUp();
//
Serial.println(F("DeviceExample.ino"));
Serial.println(F("A simple demonstration of TinyGPS++ with an attached GPS module"));
Serial.print(F("Testing TinyGPS++ library v. "));
Serial.println(TinyGPSPlus::libraryVersion());
Serial.println(F("by Mikal Hart"));
Serial.println();
}
void loop()
{
while (ss.available() > 10) // This sketch displays information every time a new sentence is correctly encoded.
if (gps.encode(ss.read()))
displayInfo();
if (millis() > 5000 && gps.charsProcessed() < 0)
{
Serial.println(F("No GPS: ."));
while (Serial.available()); // Not tested yet, but hopfully, will send GPS coordinates over radio.
char c = Serial.read();
radio.write(&c, sizeof(char));
//delay(250);
Serial.write(c);
}
}
void displayInfo()
{
if (millis() - startTime >= updateInterval)
{
Serial.print(F("Location: "));
Serial.println();
if (gps.location.isValid())
{
Serial.print(F("Latd N: "));
Serial.print(gps.location.lat(), 6);
Serial.print(F(" , "));
Serial.print(F("Long W: "));
Serial.print(gps.location.lng(), 6);
}
else
{
Serial.print(F("INVALID"));
}
Serial.println();
startTime = millis();
}
}
Sorry, I got confused regarding the "quote used", which only states the RX.
I can see from your post that It's for the TX side of the sketch.
I thought, that the time/update was something to do with "millis", and played with the numbers, with no change.
I now see with your post, It's not just the numbers within "millis", but the extra code thats needed.
THANK YOU, for your input.
Learning slowly, but getting there.
Sorry, I got confused regarding the "quote used", which only states the RX.
I can see from your post that It's for the TX side of the sketch.
I thought, that the time/update was something to do with "millis", and played with the numbers, with no change.
I now see with your post, It's not just the numbers within "millis", but the extra code thats needed.
THANK YOU, for your input.
Learning slowly, but getting there.
Dizzwold
this part of the program 'sits and waits' for a complete transmission of data from the GPS module:
while (ss.available() > 10) // This sketch displays information every time a new sentence is correctly encoded.
if (gps.encode(ss.read()))
displayInfo();
and sends the program to displayInfo() to update the serial display...
The GPS is updating quickly as you pointed out, updating several times per second. Whilst a microprocessor can do a lot with that information (e.g. vector which direction the GPS is moving many times) that is too often to be useful for simple humans to process real time.
Selecting one RX of the updateDisplay() every 20seconds makes it easier for you to absorb the data. Note that you will still process the data as fast as you can receive it from the GPS module! You can try to experiment with it to calculate its direction (changes in lat/long) and process it into North, South, East or West vectors and display that value. Or, store values every few minutes and look to see how far it moved. Fun stuff with GPS.
Sorry for a slow update, as I was starting to think that I could have radio problems as I'm currently using a Mega 2560 and a Mega 2560 ADK and aware of others having issues.
I have spent all weekend playing with different test codes and capacitors to get a link between the Two sets. A good meter apart and a 1?f electrolytic on each radio power source did the trick.
Thank you to TMRh20 for the test code I used, commented in another NRF24L01 post in the forums.
The problem I know have and ask for some pointers, Is how to collect the GPS Information from pins 10/11 or the serial monitor on the TX and send and receive them to read In the RX serial monitor?
My code at the moment is using 2 pipes, yet the radio test code I used only has the 1 pipe. I'm thinking I could use parts of the test code, but unsure? With the test code below, Instead of;
unsigned int random_Number = random(0,255);
boolean ok = radio.write( &random_Number, sizeof(random_Number) ); //What would I call random number on the TX, gps, ss?
Also, what to call this on the RX?
The test code;
TX
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
RF24 radio(49,53);
const uint64_t pipe = 0xF0F0F0F0E1LL;
void setup(void) {
Serial.begin(57600);
radio.begin();
//radio.setRetries(15,15);
radio.openWritingPipe(pipe);
}
void loop () {
unsigned int random_Number = random(0,255);
Serial.print("Sending: ");
Serial.println(random_Number);
radio.stopListening();
boolean ok = radio.write( &random_Number, sizeof(random_Number) );
if (ok) Serial.println("ok...");
else Serial.println("failed.");
delay(1000);
}
/code]
[code]RX
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
RF24 radio(49,53);
const uint64_t pipe = 0xF0F0F0F0E1LL;
void setup(void) {
Serial.begin(57600);
radio.begin();
//radio.setRetries(15,15);
radio.openReadingPipe(1,pipe);
radio.openWritingPipe(pipe);
radio.startListening();
Serial.println("Ready!");
}
void loop () {
if ( radio.available() ) {
Serial.println("radio is available");
unsigned int data;
boolean done=false;
radio.read( &data, sizeof(data) );
Serial.print("Received: ");
Serial.println(data);
}
}/code]
If I could get some pointers on how to package the GPS Information, I'd be grateful.
Dizzwold.
I'm struggling with writing the code to collect the GPS coordinates from the serial monitor to transmit over the radio.
Do I need to float gps. put In to a char a sting or as data?
If someone could point me In the right direction.
I'm struggling with writing the code to collect the GPS coordinates from the serial monitor
What have you tried?
Do I need to float gps. put In to a char a sting or as data?
You need to collect the data in a char array, NULL terminating it after each character is added. Then you may need to use strtok() to tokenize the string, and stof(), atoi(), strtol(), or strtoul() depending on the type of the data from the actual GPS.
With the way my code is written, this is a demo of the results gained in the serial monitor, that I would like to send over the radio;
DeviceExample.ino
A simple demonstration of TinyGPS++ with an attached GPS module
Testing TinyGPS++ library v. 0.92
by Mikal Hart
Location:
Latd N: 52.456054 , Long W: -1.210840
Location:
Latd N: 52.456054 , Long W: -1.210840
Location:
Latd N: 52.456054 , Long W: -1.210840
Location:
Latd N: 52.456054 , Long W: -1.210840
Location:
Latd N: 52.456054 , Long W: -1.210838
I don't wish for the code to be written for me, as I'm trying to learn.
I just need a push In the right direction, of what I really need to send and receive over nrf24l01, then I can play around with the code learning by trial and error.
If you could advise on;
Then you may need to use strtok() to tokenize the string, and stof(), atoi(), strtol(), or strtoul() depending on the type of the data from the actual GPS.
dizzwold:
I don't wish for the code to be written for me, as I'm trying to learn.
I just need a push In the right direction, of what I really need to send and receive over nrf24l01, then I can play around with the code learning by trial and error.
If you could advise on;
Then you may need to use strtok() to tokenize the string, and stof(), atoi(), strtol(), or strtoul() depending on the type of the data from the actual GPS.
The GPS Is NMEA.
Dizzwold
You are dealing with a payload capacity of 32 bytes on that radio, FYI. i believe that would include any header that transmits as part of your library. Consider that when you encode your messages.
I take it that when your talking about 32 Bytes, this Is the radios capacity, and that I'm sending a lot of Info?
I will be cleaning It all up at some point so I only sent Latd: xx.xxxxxx , Long: x.xxxxxx, or something like that.
If you could advise on;
Then you may need to use strtok() to tokenize the string, and stof(), atoi(), strtol(), or strtoul() depending on the type of the data from the actual GPS.
You implies that you were trying to get data from the Serial Monitor application. That is not at all what you are wanting to do. You want to transmit the same data that you write to the Serial Monitor. THAT is nearly trivial. You have a byte array that is the payload. You put whatever you want in the payload, as binary data or as ASCII data.
Right, I kind of get you. Can you point me to an example, to read through so I fully understand?
What exactly am I looking at, to put In to the payload, "gps." "ss." "&&gps.charsProcessed9)" or am I missing the point?
The code less the radio Info;
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
#define CE_PIN 49 //Set pins for Mega 2560.
#define CSN_PIN 53
/*
This sample sketch is part of Two examples that i have manipulated with help from @UKHeliBob & @PaulS (Arduino forum), "THANK YOU".
The Two original codes are with thanks to @Mikal Hart (TinyGPS++, http://arduiniana.org/), & @Pico (nrf24l01+ Arduino forum), "THANK YOU".
This code is just for TX. Compiled and receiving GPS coordinates in serial monitor, but the radio link remains untested!
*/
static const int RXPin =10, TXPin =11; // Change pins for Mega 2560.
static const uint32_t GPSBaud = 9600; // Change Baun to meet GPS.
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL }; // Radio channels.
TinyGPSPlus gps; // Define objects, GPS & radio.
RF24 radio(CE_PIN, CSN_PIN);
SoftwareSerial ss(RXPin, TXPin); // The serial connection to the GPS device set above as pins 10 & 11.
void setup()
{
Serial.begin(115200); // Set serial monitor to view.
ss.begin(GPSBaud); // GPS is set above to 9600.
radio.begin();
radio.openWritingPipe(pipes[0]);
radio.openReadingPipe(1,pipes[1]);
radio.enableDynamicPayloads();
radio.setAutoAck( true );
radio.setDataRate( RF24_1MBPS ); // Set radio datarate to ( RF24_250KBPS ).
radio.powerUp();
Serial.println(F("DeviceExample.ino"));
Serial.println(F("A simple demonstration of TinyGPS++ with an attached GPS module"));
Serial.print(F("Testing TinyGPS++ library v. "));
Serial.println(TinyGPSPlus::libraryVersion());
Serial.println(F("by Mikal Hart"));
Serial.println();
}
void loop() {
while (ss.available() > 10) // This sketch displays information every time a new sentence is correctly encoded.
if (gps.encode(ss.read()))
displayInfo();
if (millis() > 5000 && gps.charsProcessed() < 0)
{
Serial.println(F("No GPS: ."));
while(true);
}
{
radio.stopListening();
}}
void displayInfo(){
Serial.print(F("Location: ")); // GPS coordinates displayed in serial monitor.
Serial.println();
if (gps.location.isValid());
Serial.print(F("Latd N: "));
Serial.print(gps.location.lat(), 6);
Serial.print(F(" , "));
Serial.print(F("Long W: "));
Serial.print(gps.location.lng(), 6);
Serial.println();
}/code]
Thank you for your reply.
More research to do.
Dizzwold