GPS data with Arduino - arduino

I am using CRIUS Neo-6 GPS module and I would like to send data from GPS via GSM module every 10 seconds. The piece of code I have looks like this:
if (Serial1.available() > 0)
if (gps.encode(Serial1.read()))
{
double hour = gps.time.hour();
double minute = gps.time.minute();
double second = gps.time.second();
Serial.println("Sending SMS:");
GPRS.print("AT+CMGF=1\r");
delay(100);
GPRS.println("AT+CMGS= \"00*********\"");
delay(100);
GPRS.print("HOUR=");
GPRS.print(hour);
GPRS.print(" MINUTE=");
GPRS.println(minute);
GPRS.print(" SECOND=");
GPRS.println(second);
delay(100);
GPRS.print((char)26);
delay(100);
GPRS.println();
Serial.println("Text sent.");
Serial.println();
delay(10000);
}
Serial1 is a SoftwareSerial instance for communication with GPS module.
Now this sends an SMS every 10 seconds but the data is messed up, it is like the time doesnt refresh always. I get something like:
HOUR=6.00 MINUTE=37.00 SECOND=54.00
HOUR=6.00 MINUTE=37.00 SECOND=54.00
HOUR=6.00 MINUTE=37.00 SECOND=54.00
HOUR=6.00 MINUTE=38.00 SECOND=15.00
and so on.. Its like always two or three identical SMS-es and then next one with 30 seconds gap. What should I change to always send latest gps time?

1) Tell us what Arduino you are using. It looks like it might be a Mega.
2) Post your entire sketch and identify what libraries you are using. It looks like it might be TinyGPS++.
5) Don't use double. It's the same as float on the Arduino. But don't use float either. Just use int or unsigned char.
Now then. Did the example programs work? That would confirm that you have good satellite reception.
Next, did you know that your GPS sends several different kinds of messages each second? Not all messages contain a time field (see this table of messages vs. fields).
And finally, these lines will cause a lot of trouble:
delay(100);
...
delay(100);
...
delay(100);
...
delay(100);
...
delay(10000);[/code]
While the sketch is stopped at these delays, no GPS characters are being processed. But then you wait for just one message to get parsed with "if (gps.encode", and you send another SMS. The only message that got parsed probably did not have a time field, so you send the same time.
You should research ways to avoid using delay. Take a look at some posts on the Arduino forum, "Serial Input Basics" and "How to do several things at a time" in Useful Links.
Also, I wrote a better GPS library, called NeoGPS. It is much smaller and faster than TinyGPS++. The examples are structured better, too. NMEAtimezone.ino is closest to what you are doing. If you'd like to try it, be sure to follow the Installation instructions. You should try several programs as described, in this order: NMEA, NMEAdiagnostic and NMEAorder if necessary, and NMEAfused. Then try NMEAtimezone, and modify it for what you are doing.

Related

I2C communication between pic32 and MPL3115A2 Altitude/Pressure Sensor

I'm trying to do something really simple and I'm having a bit of trouble getting it to work. I'm working with the MPL3115A2 Altitude/Pressure Sensor and a pic32 uC32 board, and I'm trying to communicate between the two using I2C. (uC32 board is similar enough to arduino that it's practically the same in terms of coding).
I'm using the wire library and I'm simply trying to read register 0x0C from the MPL3115A2, which should give me the device ID.
Here's a code snippet (the define is at the top of the code and the rest is in the main loop):
#define barAddress 0x60
Wire.beginTransmission(barAddress);
Wire.send(0x0C);
Wire.endTransmission();
Wire.requestFrom(barAddress, 1);
uint8_t a = Wire.receive();
Serial.println(a, HEX);
So I start the transmission with address 0x60 (From the datasheet: The standard 7-bit I2C slave address is 0x60 or 1100000. 8-bit read is 0xC1, 8-bit write is 0xC0.). Then I send 0x0C because that's the register I want to access. I then end transmission, and request 1 byte from address 0x60, receive that bit into a 8-bit variable, then print it.
The problem I run into is that when I print it, I just get 0. I don't get the device ID, just 0. No matter what register I try to read, I get 0.
I've been banging my head against a wall for the past few days trying to get this to work. I've attached something I've captured with a logic analyzer, as well as a list of registers from the datasheet of the MPL3115A2 that I've been trying to access.
Using a logic analyzer I can see the clock and data lines. The clock seems normal and the data line gives me the following:
START
Write['192'] + ACK
'12' + ACK
STOP
START
Read['193'] + ACK
'0' + NAK
STOP
This all seems correct to me (192 and 193 come from 8-bit write and read being 0xC0 and 0xC1), except for the '0'. I should be getting the device ID, not 0.
Thanks for any help with this!
You should look at Freescale's app note AN4481, which is referred to by the datasheet. Page 5 shows the single-byte read operation which is what you are doing, except that the register address write must not be followed by a STOP but instead uses a REPEATED-START.
I'm not familiar with the Wire library but it look like all you need to do is remove the Wire.endTransmission(); between the send and requestFrom.
Hopefully, this will solve your problem.

Arduino Uno - Light Switch

The function of the program I am writing is to stream incoming analog data from a sensor to a program on my computer across the USB port. For a little fun, I've decided to add a button to the program that will turn on/off a lamp. The lamp will be connected to a relay, which is connected to the arduino. I know how to go about programming it, but I want to know if this will interrupt the sensor data transfer?
I will get the current state of the light (HIGH(1) or LOW(0)) from the arduino when the button is pressed, then write to the arduino (HIGH(1) or LOW(0)) depending on the current state. I have a 5 second delay between each loop of the arduino program, for reasons related to the sensor output; however, I think I'm going to have to change this so that when the button is pressed, it is not missed by the arduino loop, or is that not possible?
I thought I read somewhere that you can't transmit/receive streaming data on the same serial line...in which case, I will need the Mega.
You have to remember and think of the Arduino as a single threaded device. While it is doing anything it is not able to do anything else. Period! In regard to the serial port however, the buffer will still accept incoming data on RX, however if an overflow situation occurs whilst blocked, management is impossible.
See the following taken directly from the Arduino reference
Certain things do go on while the delay() function is controlling the Atmega chip however, because the delay function does not disable interrupts. Serial communication that appears at the RX pin is recorded, PWM (analogWrite) values and pin states are maintained, and interrupts will work as they should. Reference
Now in saying that when you are setting the delay to 5 seconds between loops ( delay(5000) ) you are essentially blocking it from doing anything else almost full stop.
The Arduino framework exposes a a counter ( millis() ) that basically runs from the moment of boot for roughly 50 days in increments of one (1) millisecond. See Arduino - millis()
In your application you would define (remember) what loop you were due to run & when the said loop had finished so to not allow the other loop to run until the millis() counter was a defined amount more than your count. (Remember to define the count as a long)
Then what you do is move your loops out into separate functions that will only execute if the if statement return true...
for example...
long interval = 5000; // Define interval outside of the main loop
long previousCount = 0; // Used to store milli count when finished
int loopPosition = 1;
void loop()
{
if ((long)millis() - previousCount >= 5000 )
// This if statement will only return true every 5 seconds (5000ms)
{
if (loopPosition == 1)
{
function_One();
previousCount = millis(); // Redefine previousCount to now
loopPosition++; // Increment loop position
}
else if (loopPosition == 2)
{
function_Two();
previousCount = millis();
loopPosition--; // Decrement loop position
}
}
// Do Anything Here You Want
// - While ever the if statement above returns false
// the loop will move to this without hesitation so
// you can do things like monitor a pin low / high scenario.
}
void function_One()
{
// Do Your First Loop
}
void function_Two()
{
// Do Your Second Loop
}
The above will stop any delay you are using from blocking awesomeness, and to more of a point, almost make delay obsolete if implemented correctly under the right scenarios.
In regard to your serial data comment, like i said at the top of this article, the Arduino can only do one thing at a time. Transmitting and receiving at exactly the same time is impossible even with the Mega. In saying that a board like the 'Uno' for example is only capable of one serial interface, where as the 'Mega' is capable of four.
Best of luck....
NB- For a beginner reading this, the following tutorial / example covers what i have above in fairly simple terms and is a great building block for further awesomeness! Arduino - Blink Without Delay

Sending output from arduino to picaxe

I am doing a class project involving an Arduino Uno and a Picaxe 14m2.
I am in the middle of attempting to code a program for the Arduino Uno that will allow me to send and output value to the input on the Picaxe.
So in layman's, this is what I wish to achieve:
I want the Arduino to check a sensor, and if the sensor returns a specific value. (- I know this part, but not the next.) I then want the Arduino to send a value (HIGH, or 1 .. something like that) as an output to one of the Picaxe input pins. I then need the Picaxe to notice a value has been sent, and then do something else.
Any help would be appreciated.
Thanks.
If you are looking for that, you may want to specify what kind of PICAXE you have.
Since there is a difference in the types of these chips.
After that you may wanna look over the datasheet of the PICAXE so that you can find the instructions set and the type of program memory you have, "EEPROM....".
After that:
List your Is/Os, inputs and outputs.
Set your source code editor.
Write the source code and burn it to the PICAXE program
memory.(C, Assembly...)
Write your Arduino code, setting the Is/Os and telling the
Arduino how to deal with the signals in and out.(C language)
Make a circuit diagram for the hardware you are going to connect
between both chips.
Don't forget to see the loading effects on both the Arduino and
the PICAXE, because you don't want to burn your project hardware
after all.
Test your project and note that you will have to troubleshoot
both software and hardware whenever a problem occurs.
I suggest that you use the Oscilloscope to test the signals going in or coming out of both circuits + the sensor's signal.
For any extra thing you need the PICAXE to do, use If statements, because they are not so technical to implement and they are easy to write and troubleshoot.
For your scheme, you are actually making the Arduino give instructions to the PICAXE through a variable signal coming from a sensor.
^send me feedback and I will help more.
You will probably want to look into using UART (aka Serial) or i2c communication.
Serial communication should work with any PICAXE and Arduino, While i2c Will only work if you are using the X2 Series PICAXE Chips. i2c's main advantage is when using multiple slave devices (plus the master device, i.e. more than just 2 devices total) in which you can use the same two wires for up to around 128 devices. Serial (UART) communication is simpler, and only needs one wire (plus a common ground) to send data one way, it is what i'll show for the rest of this answer
Here is the manual entry for serial input for the PICAXE, and Here's the entry for serial output from the Arduino. The code you will need given your question will be something like the following:
For the arduino:
void setup(){
Serial.begin(9600);
}
void loop(){
if (conditionMet){ //whatever the condition is in your code
int bytesSent = Serial.write(“HIGH”); //send the string “HIGH"
}
}
and for the PICAXE:
main:
serin 6, T9600, ("HIGH") 'uses qualifier to look for exact message "HIGH"
'do whatever when criteria met
goto main

Re-entrant code?

I am using the Wire library to move some data from a shield to the Arduino.
The shield always puts out exactly 36 bytes (GPS device), but the Arduino sees two data transfers that together add up to 36 bytes. Not always the same count in each of the transfers, but always 36 bytes total. The setup() routine is re-run every time the data comes in.
It's as if the library is re-entering the Arduino application and screwing it royally.
Is this possible?
If setUp() is being run every time data comes in (and are you sure about this?) then this means that the Arduino is resetting/restarting for some reason. How are you powering the GPS shield? If it is glitching the power to the Arduino (drawing too much current perhaps) then that could cause a reset. It could also be something with your code using up too much memory. I'd look at the power issue first.
If you are using Wire.available, note that it does not guarantee that it will return the number of bytes sent. You will need to call it repeatedly until it returns zero.
See an example in the Arduino documentation.

Arduino communication in wireless IR system

I have two Arduinos that I want to put in a wireless system to relay an IR code from a hand held remote in one room of the house, to a settop box located in another room. One Arduino has an IR decoder which decodes the key from a hand held remote, and sends it to the other Arduino parked in front of the box with an IR emitter. The system, in parts, works fine. When I get the code from the detector (to my PC) and send it manually (from my PC) to the emitting Arduino, it controls the box properly. But when I try to send the code wirelessly directly between the Arduinos, it doesn't work quite right. The commands do not appear to be relayed correctly and the emitting Arduino can't control the bx.
Here is what the decoding Arduino code looks like. "myNumber" holds the 4 byte key:
myNumber.UL = results->value;
Serial.write(&myNumber.B,4);
When the decoder detects the IR pattern, it posts the following to the Serial port whether I use the emitter or depress the on/off key on the remote. The key in question is 61A0F00F (power on/off):
Hex Field ASCII
0000 0F F0 A0 61 ...a
The decoder puts out this same response when I direct the actual remote towards the detector, or when I am driving my emitter with the code 61A0F00F. So it can't tell the difference between the actual remote and the Arduino-driven emitter. The problem is that this output is not understood correctly by the Arduino on the emitting end of the system.
Here is what the emitting code looks like:
void loop() {
int x = 0;
while (x < 4) {
if (Serial.available()) myNumber.B[x++] = Serial.read();
}
Serial.print(myNumber.UL, HEX);
if (x==3) irsend.sendNEC(myNumber.UL, 32); //drive IR emitter with NEC code
delay(10000);
And the serial output looks like this:
HEX field ASCII Field
0000 36 31 41 30 46 30 30 46 61A0F00F
When I put this hex code in manually, i.e. via CoolTerm, inverted (so 0FF0A061) the settop box responds (by turning on). When I link the Arduinos wirelessly, it does not.
Can anyone see what is wrong with the communication above? The numbers in the hex fields don't look quite right, the hex field from the decoder does look like hex, but the hex field from the emitter looks like ASCII? So is the emitter expecting an ASCII number but getting hex instead? I would have thought that the Serial.read and Serial. write would work the same way.
This is highly frustrating, as it appears that the system almost, almost works, BUT NOT QUITE!!
Any help/insight would be appreciated.
First a disclaimer: I haven't coded my arduino for several years.
At first glance it would appear you are being bitten by a conversion bug. I see a lot of conversions from byte to long etc. The key here would be to break things down to their simplest level and verify each level works.
First off I would verify the number of bytes being sent by checking the return value from Serial.write is indeed 4. Something as simple as flashing an led if Serial.write returns 4.
On the receiving end I think I would use ReadBytesUntil as this seems to be designed to do what you want and builds in some error checking (time outs and only 4 bytes).
I hope this helps. If not follow the golden rule: when in doubt - post more code!
Hope the late response helps.
The output data from the emitting end is correct. In your case, myNumber.UL = 0x61A0F00F. When executing the code "Serial.print(myNumber.UL, HEX);", the print class actually sent out the char sequence as '6''1''A''0''F''0''0''F'. So in your serial monitor the ACII data is "61A0F00F", and the corresponding HEX data is "36 31 41 30 46 30 30 46". You are confused about transferring data via text and binary format.
The problem of your code is at line "if (x==3) irsend.sendNEC(myNumber.UL, 32);". After receiving the four bytes data, the x is 4 other than 3. Changing the condition x==3 to be x==4 can fix your issue.

Resources