arduino fio v3, GPS NMEA reading error, crazy output - c++

Hello I have a GP20U7 GPS that transmits in NMEA. I am currently reading in that character by character. But it seems to give me two somewhat reasonable NMEA formatted strings and then just goes silly, any help?
I have all my code attached below. I am also outside, so i shouldn't have any connection errors. I also have waited over two minutes for a connection and it still outputs the same mess.
also below is what the character output looks like in my serial monitor.
$GPRMC,233720.00,V,,,,,,,251016,,,N*7B
$GPVTG,,,,-‰‰‰ÉJi‚j
$GP$4$G$G6$G$GP$G
$G$GG$G$G$$G$GP$G0$G$A*$G$G,$G0$T$G7$1$G,$R$G,$GÒ,$G
$6$G5$1$G,$1$G7$7$G,$G$G,$G$G,$GA$1$G3$
#include <XBee.h>
#include <Wire.h>
#include <SparkFunMPL3115A2.h>
#include <SPI.h>
#include <SparkFunLSM9DS1.h>
#include <SoftwareSerial.h> //XBEE Comms
#include <SD.h>
SoftwareSerial XBee(0, 1); // RX, TX (0 and 1 are the TX/RX pins
SoftwareSerial gps(9, 10);
MPL3115A2 altimeter;
LSM9DS1 accelerometer;
#define LSM9DS1_M 0x1E //I2C addresses of the LSM9DS1
#define LSM9DS1_AG 0x6B
#define PRINT_CALCULATED
const int chipSelect = 10;
void setup()
{
accelerometer.settings.device.commInterface = IMU_MODE_I2C;
accelerometer.settings.device.mAddress = LSM9DS1_M;
accelerometer.settings.device.agAddress = LSM9DS1_AG;
gps.begin(9600);
XBee.begin(9600);
accelerometer.begin();
altimeter.begin();
altimeter.setModeAltimeter();
altimeter.setOversampleRate(7);
altimeter.enableEventFlags();
XBee.println("start");
}
void loop()
{
File dataFile = SD.open("datalog.txt", FILE_WRITE);
char rc;
if(gps.available())
{
rc = gps.read();
Serial.print(rc);
}
else
{
Serial.println("NOT Available");
}
float altitude = altimeter.readAltitudeFt();
float temperature = altimeter.readTempF();
XBee.println("Altitude");
XBee.println(altitude);
XBee.println("Temperature");
XBee.println(temperature);
XBee.println("Next");
delay(100);
dataFile.close();
}
The data looks like it should be correct, but displays weird
characters.
After removing the delay this is what my output looks like:
$GPRMC,183714.00,V,,,,,,,,,,N*75 $GPVTG,,,,,,,,,N*30
$GPGGA,1ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ$ÿGÿPÿRÿMÿCÿ,ÿ1ÿ8ÿ3ÿ7ÿ1ÿ8ÿ.ÿ00ÿÿ,Vÿÿ,,ÿÿ,,ÿ,ÿ,ÿ,ÿ,ÿ,ÿ,ÿNÿÿ7ÿ9ÿ
$GÿÿPVÿÿTGÿÿ,,ÿ,ÿ,ÿ,ÿ,ÿ,ÿ,ÿ,ÿNÿÿ3ÿ0ÿ
$ÿÿGPÿÿGGÿÿA,ÿ1ÿ8ÿ3ÿ7ÿ1ÿ8ÿ.ÿ0ÿ0ÿ,,ÿÿ,,ÿ,ÿ0ÿ,ÿ0ÿ0ÿ,ÿ9ÿ9ÿ.ÿ9ÿ9ÿ,ÿ,ÿ,
$ÿGÿPÿGÿSÿAÿ,ÿAÿ,ÿ1ÿ,ÿ,ÿ,ÿ,ÿ,ÿ,ÿ,ÿ,ÿ,ÿ,ÿ,ÿ,,ÿ9ÿ9ÿ.ÿ9ÿ9ÿ,ÿ9ÿ9ÿ.ÿ9ÿ9ÿ,ÿ
$ÿGÿPÿGÿLÿLÿ,ÿ,ÿ,ÿ,ÿ,1ÿÿ83ÿÿ71ÿÿ8.ÿ0ÿ0ÿ,ÿVÿ,ÿNÿÿ4ÿEÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ$ÿGÿPÿRÿMÿCÿ,ÿ1ÿ8ÿ3ÿ7ÿ1ÿ9ÿ.ÿ0ÿ0,ÿVÿ,ÿ,ÿ,ÿ,ÿ,ÿ,ÿ,ÿ,ÿ,ÿ,ÿNÿÿ78ÿÿ
$GÿPÿVÿTÿGÿ,ÿ,ÿ,ÿ,ÿ,ÿ,ÿ,ÿ,ÿ,Nÿÿ*3ÿÿ0
$ÿGÿPÿGÿGÿAÿ,ÿ1ÿ8ÿ3ÿ7ÿ1ÿ9ÿ.0ÿÿ0,ÿÿ,,ÿÿ,,ÿ0ÿ,ÿ0ÿ0ÿ,ÿ9ÿ9ÿ.ÿ9ÿ9ÿ,ÿ,ÿ,$ÿGÿPÿGÿSÿAÿ,ÿAÿ,ÿ1ÿ,ÿ,ÿ,ÿ,ÿ,ÿ,ÿ,,,ÿ,ÿ,ÿ,ÿ,ÿ9ÿ9ÿ.ÿ9ÿ9ÿ,ÿ9ÿ9.ÿÿ99ÿÿ,9ÿ
$GÿÿPGÿÿLLÿ,ÿ,ÿ,ÿ,ÿ,ÿ1ÿ8ÿ3ÿ7ÿ1ÿ9ÿ.ÿ0ÿ0ÿ,Vÿÿ,Nÿÿ*4ÿFÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ$ÿÿGPÿÿRMÿCÿ,ÿ1ÿ8ÿ3ÿ7ÿ2ÿ0ÿ.ÿ0ÿ0ÿ,ÿVÿ,ÿ,,ÿÿ,,ÿÿ,,ÿ,ÿ,ÿ,ÿNÿÿ7ÿ2ÿ
$ÿGÿPÿVÿTÿGÿ,ÿ,,ÿ,ÿ,ÿ,ÿ,ÿ,ÿ,ÿNÿÿ3ÿ0ÿ
$ÿGÿPÿGÿGÿAÿ,ÿ1ÿ8ÿ37ÿÿ20ÿ.ÿ0ÿ0ÿ,ÿ,ÿ,ÿ,ÿ,ÿ0ÿ,ÿ0ÿ0ÿ,ÿ9ÿ9ÿ.ÿ99ÿÿ,,ÿÿ,$GÿÿPGÿÿSAÿÿ,Aÿ,ÿ1ÿ,ÿ,ÿ,ÿ,ÿ,ÿ,ÿ,ÿ,ÿ,ÿ,ÿ,,ÿÿ,9ÿÿ9.ÿÿ99ÿ,ÿ9ÿ9ÿ.ÿ9ÿ9ÿ,ÿ9
$ÿÿGPÿGÿLÿLÿ,ÿ,ÿ,ÿ,ÿ,ÿ1ÿ8ÿ3ÿ7ÿ2ÿ0ÿ.ÿ0ÿ0ÿ,Vÿ,ÿNÿ*ÿ4ÿ5ÿ

As we discussed on the Arduino forum, remove the delay(100).
Update 1:
The next problem is that you are printing 15 characters every time you don't receive a GPS character. So... you're printing that message a lot. And then you send a new XBee message, regardless of whether you received one character. Aaaand you're opening and closing the SD file on every iteration of loop. That's a lot. All of those things keep loop from reading the GPS characters. Again, those characters stack up in the input buffer until its full and they start getting dropped.
I would suggest looking at the examples for my GPS library, NeoGPS. They are all structured around the GPS update interval. The Installation instructions suggest a few sketches to try. The Troubleshooting section may help you understand the interaction between the GPS interval and printing (too much!).
It's important to understand that the GPS devices sends several hundred characters each second (i.e., "interval"). NeoGPS parses those characters into a fix structure, and makes it available, once per second. After a fix becomes available, the GPS device is "quiet" until the next interval begins (maybe in 0.4s). That's the perfect time to do something else, like send an XBee message.
Also, SoftwareSerial is very inefficient, so it could also be causing problems. AltSoftSerial is a better choice if you can put the GPS on pins 8 & 9.
BTW, the lower-case y with umlaut is character 255. I suspect you called gps.read() without first testing if (gps.available()). When no characters available, read() will return -1, which is printed as a 255. You probably modified something that we can't see.
The Arduino forum would be a better place for this kind of "conversation". (I'm replying to your comment below... :P ) It will take several iterations before your sketch works. When it does, we can come back here with a summary answer. Here's your post if you don't mind working over there.

Related

QSerialPort continuous reading accumulative delay

I am trying to do communication from QT Application to Arduino. The flow is like this: QT Application sends a '1' and Arduino is expected to respond with some data(the data String length is huge, around 300). QT Application is sending '1' at the rate of around 5Hz(every 200ms).
The problem I am facing is, there is an accumulative delay between the Arduino to QT communication. That is, the data I receive from Arduino is not recent data but the frequency of data coming of Arduino is 5Hz only(which is as expected), just the data coming is not recent. This delay keeps on increasing with time. I believe there is some problem with buffer or something.
What I tried:
QSerialPort serialPort; is my device port
serialPort.clear()
serialPort.flush()
Increasing and decreasing Baud Rate from both ends.
Reduce character length from Arduino, here delay reduces significantly but the accumulated delay is observed after a long time.
to clear serial communication buffer, but the issue still persists.
Here is my code snippet:
connect(timer_getdat, SIGNAL(timeout()), this, SLOT(Rec()));
timer_getdat->start(200);
where Rec() is the function where I do communication part.
In Rec():
serialPort.write("1", 2);
// serialPort.waitForBytesWritten(100);
long long bytes_available = serialPort.bytesAvailable();
if (bytes_available >= 1)
{
serialPort.readLine(temp, 500);
serialPort.flush(); // no change
serialPort.clear(); // no change by .clear() also
}
I have been stuck on this issue for a quite long time. The above code snippet is what I think is necessary but if anyone needs more clarification, I may reveal more of the code.
I also encountered with the same issue, and yes QSerialPort.clear() and QSerialPort.flush() doesn't help. Try doing readAll()
So change the part in your Rec() function to something like this:
serialPort.write("1", 2);
long long bytes_available = serialPort.bytesAvailable();
if (bytes_available >= 1)
{
serialPort.readLine(temp, 500);
serialPort.readAll(); // This reads all the data in buffer at once and clears the queue.
}
Even on QT forums, I didn't find the answer to this, was playing with all functions available with QSerialPort class and readAll() seems to work.
About readAll(), Qt documentation says:
Reads all remaining data from the device, and returns it as a byte
array.
My explanation for the resolution is that readAll captures all of the data from the communication buffer and empties it.
This should be the job of clear() function but apparently readAll() seems to work.

My esp32 print weird characters but I do anything

I only want to print simple text but it print unilimited weird character and never stop, (when I remove Serial.print() it continues to print weird characters).
This is the weird text that loop
-*⸮ql⸮7⸮$⸮
*!8P⸮⸮⸮V⸮)3 ⸮;⸮ 1⸮zY⸮b⸮ڔ!⸮⸮$q⸮,*⸮ı⸮N
⸮a!u⸮ 1⸮zY⸮b⸮⸮⸮⸮⸮⸮!⸮ 1⸮zY⸮W(⸮⸮⸮xI⸮
,*-⸮l⸮N
⸮a!u⸮,*⸮⸮⸮nbb⸮H⸮⸮⸮⸮,*⸮⸮⸮nbb⸮H$⸮
1⸮zY⸮b⸮ڔ!X⸮⸮⸮⸮,*⸮⸮⸮nbb⸮H$⸮
*!8Pt⸮
My code :
void setup() {
}
void loop() {
}
I hope you can help me, thanks :)
UPDATE
I completely removed Serial.begin(9600) and Serial.print() and I still have the problem O_o
If you are using arduino IDE ( you probably are ) you can try changing the baud rates. That's what happened to me in arduino some time ago
I just changed the Flash memory speed to 40MHz instead of 80MHz
You need to make sure that the baud rate in the code and baud rate of the serial monitor are the same.
Example:
if your code has : Serial.begin(115200);
then change the baud rate of serial monitor to 115200, this can be done by accessing the baud as shown in the pictureimage below

How to communicate with sim800c using Raspberry pi 3 in c++

My end goal is to try and send some simple data that's stored on my Raspberry pi 3 to an external server/website using a sim800c from a c++ program. I believe the easiest way to do this is to issue "AT commands" to the sim/modem however I'm struggling to do this. I can't figure out how I'm actually suppose to issue AT commands or how I can check if they're working. For testing purposes I've written some code which should send a text message to a phone number once I've gotten this working it should be fairly straight forward to figure out the AT commands to communicate with a server.
Below is an image of how I've wired everything up which I'm fairly confident is correct.
https://i.imgur.com/zysmNXE.jpg
Below is the basic c++ code that I've written using various guides, it compiles and runs in terminal however I don't get any response from the AT commands and more importantly as far as I can tell their not actually being executed. I've tried changing the fake number to my personal one but it didn't make a difference.
#include <stdio.h>
#include <string.h>
#include <wiringPi.h>
#include <wiringSerial.h>
int main ()
{
int connection;
printf("Opening connection \n");
connection = serialOpen("/dev/ttyAMA0", 9600);
delay(1000);
printf("Connection: %d\n", connection);
printf("\n");
//Set gsm to text mode
serialPuts(connection,"AT+CMGF \r\n");
delay(1000);
//Number that the message should be sent to
serialPuts(connection,"AT+CMGS=\"12345678900\"\r\n");
delay(1000);
//The message
serialPuts(connection,"Hello World");
delay(1000);
//Print ctrl+x
serialPuts(connection,"\x1A");
delay(1000);
printf("Done \n");
return 0 ;
}
As far as I can tell there are 3 likely reasons why it's not working;
A possible config/settings issue with the pi
I've wired it up incorrectly
The sim/module isn't working
I'm just not sure how to go about testing/finding what is causing the issue. If I could get my code to output the response of the AT commands after doing "serialPuts" that might help me figure out whats going on but I haven't made much luck doing that. Alternatively If anyone has an idea why the commands don't appear to be working or can provide me some ways to debug/test them that would be great.
The issue turned out just to be a simple wiring mistake.
I had wired the txd pin of the sim module to the txd pin on the raspberry pie as I was under the impression you just needed to match the pins however I didn't think/realize that the txd pin needed to go to the rxd pin instead. Changing these around allowed me to see the commands & responses being returned from the module.
To actually get the gprs working I also needed to temporarily set the pwr pin to low then high.

Sending ASCII Control Characters to Serial Device using libserial on Linux

I have a very basic device with which I am trying to interact via a serial connection on Linux. I am on the steep part of the learning curve here, still, so please be gentle!
One of the functions involves sending data to an attached printer. You send a command to the device, which then relays the data you input to the printer attached to the device. The command looks like this:
Send "EXEX*". The device echoes back "EXEX" (the '*' is not echoed yet)
Send a single byte indicating the length of the data you will send, including a LF at the end.
Send the data (the device will now echo back the *).
Send "#". The device will now be ready for another command.
I have a small C++ program to communicate with the device, and I can successfully send single characters and such, but when I try to send this command, I do not get the expected results.
Using Hyperterminal in Windows, it is particularly easy, using alt-key combinations to send ASCII control codes. Just connect and:
Type "EXEX*"
Type Alt+010 to send a LF character, indicating that you are sending 10 bytes to the printer (nine characters and a LF).
Type the data you wish to send: "123456789" (nine bytes in length).
Type Alt+010 again to send a final LF character to the printer.
Type "#" to finish.
Here is what I cobbled together to try in C++:
#include <SerialStream.h>
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
using namespace LibSerial;
int main(){
char buffer [50];
int n;
n=sprintf (buffer, "EXEX*%c123456789%c#",10,10);
printf("Variable buffer was set to a %d character string: %s\n",n,buffer);
SerialStream my_serial_stream;
my_serial_stream.Open("/dev/ttyS0") ;
my_serial_stream.SetBaudRate( SerialStreamBuf::BAUD_19200 ) ;
my_serial_stream.SetCharSize( SerialStreamBuf::CHAR_SIZE_8 ) ;
my_serial_stream.SetFlowControl( SerialStreamBuf::FLOW_CONTROL_NONE ) ;
my_serial_stream.SetParity( SerialStreamBuf::PARITY_NONE ) ;
my_serial_stream.SetNumOfStopBits(1) ;
my_serial_stream.SetVTime(1);
my_serial_stream.SetVMin(100);
cout<<"Sending Command:\n";
my_serial_stream << buffer;
//my_serial_stream << printf("%s",buffer);
//my_serial_stream << "EXEX*\n123456789\n#";
my_serial_stream.read(next_char,100);
cout<<"Result: "<<next_char<<"\n";
my_serial_stream.Close();
return 0;
}
I also tried both of the commented out lines, and neither worked. The device does not receive the proper characters on the other end.'
I'm certain that this is pretty basic, perhaps something is grabbing the control characters in the middle? If anyone has any ideas on a better way to do this, I would really appreciate it. Specifically, I might need to send a byte with a value anywhere between 1 and 40, depending on the length of the data I wish to send to the printer.
My apologies for being unclear, please let me know if I need to break this down farther.
Many thanks,
Tom
The line you send doesn't include the # that you mention in the character sequence.
Have you checked serial comms works on /dev/ttyS0 using gtkterm / cutecom etc?
To test your interface you could read back the serial port. If you have a second port or computer, you could do that by connecting to another port via a null modem. Otherwise you could short pins 2 and 3 of your serial port and check that you are receiving back the characters you send.
You may want to check the return values of the calls to make to the serial library, to see if any errors are returned.
Perhaps there are timing requirements on the printer, and you may need to wait between sending some characters.
I compiled the code and checked the output on another serial port with gtkterm, it does receive the string you would expect:
45 58 45 58 2A 0A 31 32 - 33 34 35 36 37 38 39 0A EXEX*.12 3456789.
It won't affect the sending part of the code, but the receiving looks suspicious. If the read() member function is like the system call and if next_char is a character array, then it won't null terminate the string. Instead you have to look at the return value to get the size, and then null terminate if you are going to use it as a null-terminated C string.

RS-232 confusion under C++

What's the problem in given code? Why it is not showing the output for rs232 when we connect it by the d-9 connector with the short of pin number 2 & 3 in that?
#include <bios.h>
#include <conio.h>
#define COM1 0
#define DATA_READY 0x100
#define SETTINGS ( 0x80 | 0x02 | 0x00 | 0x00)
int main(void)
{
int in, out, status;
bioscom(0, SETTINGS, COM1); /*initialize the port*/
cprintf("Data sent to you: ");
while (1)
{
status = bioscom(3, 0, COM1); /*wait until get a data*/
if (status & DATA_READY)
if ((out = bioscom(2, 0, COM1) & 0x7F) != 0) /*input a data*/
putch(out);
if (kbhit())
{
if ((in = getch()) == 27) /* ASCII of Esc*/
break;
bioscom(1, in, COM1); /*output a data*/
}
}
return 0;
}
Well, the code looks alright. Have you really connected the remaining pins correctly in the plug, see serial and pin connections.
Nothing obvious stands out from your code as the cause. Check all your bases as you are dealing with hardware/software. The following Microsoft article has a different implementation using _bios_serialcom (from bios.h) which might be a good reference point for you.
http://support.microsoft.com/kb/39501
Suggestions for where to go from here:
I would also suggest replacing the literals (eg 0x08) using the constants predefined for Baud rate, Parity (eg _COM_NOPARITY) to make the code more readable in your question.
Check that the Com port is actually open, as its a assumption which is unchecked in your code example above.
Also check up on the pin connections for the DB9. To connect two computers/devices you will need to null modem it, eg pin 2 to pin 3 at the other end, plus the Signal Ground. Make sure you are disabling/not looking for DTR.
If the other computer/device is setup then I would suggest first running HyperTerminal (Programs->Accessories->Communication) and connect to your COM 1 and check you can see characters from the other device. If not its most likely related to your cable.
Hope that helps.
Before checking with your code always check your serial communication with a terminal program. I don't have much experience with Windows environment but in Linux you have programs like cutecom or gtkterm where you can send/receive data from serial port. We extensively used these programs for serial communication in Linux, they are great for debugging potential problems with serial port interface (both h/w & s/w as well). So, before suspecting your code check with a terminal emulator program.
Hey, I am not an expert on Win32, but it seems to be easier to use another article as a source (the one mentioned here before looks outdated):
http://msdn.microsoft.com/en-us/library/ms810467
This is old too, dated around 1995, but it looks still effective. The NT architecture is very restrictive when it comes to grant access to hardware, for example, to send bytes to a PC paralell port one needs to rely on workarounds dll written by open source developers.
I'm assuming from your comment about "pin 2 & 3" that you've connected a loopback cable, so you're expecting to see anything you type come up on the screen (and stop doing so when you disconnect the cable).
I think there's a bug in the code: the if (kbhit()) is inside the if (status & DATA_READY).
That means you only check the keyboard if there is some input ready to receive from the serial port - which there won't be, because you haven't sent it anything yet! Try moving the test and see if it improves matters.
(Here is some similar serial port code that puts the if (kbhit()) test outside the DATA_READY check. It doesn't claim to work, but provides some evidence that this might be the source of the problem...)