GPS Communication with Arduino - bluetooth

I have been actively trying to connect the 'Ultimate Breakout GPS v3' with an Ardunio UNO & have the BLYNK application running at the same time. I have a fully functional GPS module working in its own sketch and I also have a fully functional BLYNK app working in its own sketch. However, when I try to combine the code to have the GPS and BLYNK app working together, my GPS code gets stuck in a while loop. I think that it may have something to do with the Software Serial communication I am using for both the app and GPS module, but I am in college right now still new to learning these concepts. I can only think to attach the whole code so that you can see what is going on.
//Bluetooth/Blynk Definitions
#define BLYNK_USE_DIRECT_CONNECT
#define BLUETOOTH_TX_PIN 10
#define BLUETOOTH_RX_PIN 11
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
//#include <BlynkSimpleStream.h>
#include <BlynkSimpleSerialBLE.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_HMC5883_U.h>
//Cart GPS Definitions
#define GPS_TX_PIN 4
#define GPS_RX_PIN 5
char auth[] = "ruf1xsvCA3b-YPsR8CTGT2CgYwEYj78t";
//Serial Setups
SoftwareSerial bluetoothSerial(BLUETOOTH_TX_PIN, BLUETOOTH_RX_PIN); //(10,11)
SoftwareSerial cartSerial(GPS_TX_PIN, GPS_RX_PIN); //(4,5)
//Global Varibles
int x, y; //X,Y for Joystick Data
String NMEA1; //variable for first NMEA sentence
String NMEA2; //variable for second NMEA sentence
double cartLat, cartLon;
char c; //to read characters coming from GPS
struct GeoLoc {
float lat;
float lon;
};
GeoLoc cartLoc;
//Joystick
BLYNK_WRITE(V10) {
x = param[0].asInt(); // It extracts the x value of the Joystick inlcuded in the Mobile APP Blynk
y = param[1].asInt(); // It extracts the y value of the Joystick inlcuded in the Mobile APP Blynk
Serial.print("JoyX:"); Serial.println(x);
Serial.print("JoyY:"); Serial.println(y);
}
//User GPS
double userLon, userLat, userAlt, userSpeed;
BLYNK_WRITE(V11) {
GpsParam gps(param);
userLon = gps.getLon();
userLat = gps.getLat();
userAlt = gps.getAltitude();
userSpeed = gps.getSpeed();
Serial.print("userLat: "); Serial.println(userLat, 7);
Serial.print("userLon: "); Serial.println(userLon, 7);
cartLoc = getLocation();
Serial.print("cartLat: "); Serial.println(cartLoc.lat, 7);
Serial.print("cartLon: "); Serial.println(cartLoc.lon, 7);
}
//cartGPS
Adafruit_GPS cartGPS(&cartSerial);
void readCartGPS(){
Serial.print("Start of readCartGPS");
clearCartGPS();
Serial.print("Start of Whileloop");
while(!cartGPS.newNMEAreceived()){ //loop until we have a good NMEA sentence
c = cartGPS.read();
Serial.print("Inside");
}
cartGPS.parse(cartGPS.lastNMEA()); //parse last good NMEA sentence
NMEA1 = cartGPS.lastNMEA();
while(!cartGPS.newNMEAreceived()){ //loop until we have a good NMEA sentence
c = cartGPS.read();
}
cartGPS.parse(cartGPS.lastNMEA()); //parse last good NMEA sentence
NMEA2 = cartGPS.lastNMEA();
Serial.print("NMEA1:"); Serial.print(NMEA1);
Serial.print("NMEA2:"); Serial.println(NMEA2);
}
void clearCartGPS(){ //Clear old and corrupt data from Serial Port
Serial.print("Start of clearCartGPS");
while(!cartGPS.newNMEAreceived()){ //loop until we have a good NMEA sentence
c = cartGPS.read();
Serial.println("DEBUG: INSIDE WHILE");
}
cartGPS.parse(cartGPS.lastNMEA()); //parse last good NMEA sentence
while(!cartGPS.newNMEAreceived()){ //loop until we have a good NMEA sentence
c = cartGPS.read();
}
cartGPS.parse(cartGPS.lastNMEA()); //parse last good NMEA sentence
while(!cartGPS.newNMEAreceived()){ //loop until we have a good NMEA sentence
c = cartGPS.read();
}
cartGPS.parse(cartGPS.lastNMEA()); //parse last good NMEA sentence
}
GeoLoc getLocation(){
Serial.print("Start of GetLocation");
readCartGPS();
Serial.print("After readCartGPS is run");
delay(300);
cartLat = cartGPS.latitude;
char latDirection = cartGPS.lat;
if(latDirection == 'S'){
cartLat = -1 * cartLat;
}
cartLon = cartGPS.longitude;
char lonDirection = cartGPS.lon;
if(lonDirection == 'W'){
cartLon = -1 * cartLon;
}
cartLoc.lat = cartLat;
cartLoc.lon = cartLon;
// Serial.print("Cart Latitude: "); Serial.println(cartLat, 7);
// Serial.print("");
//
// Serial.print("Cart Longitude: "); Serial.println(cartLon, 7);
// Serial.print("");
return(cartLoc);
}
void setup() {
Serial.begin(4800);
cartGPS.begin(9600);
cartGPS.sendCommand("$PGCMD,33,0*6D"); //Turn off antenna update message
cartGPS.sendCommand(PMTK_SET_NMEA_UPDATE_10HZ); //Set update rate to 10Hz
cartGPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); //Request RMC and GGA sentences only
bluetoothSerial.begin(9600);
Blynk.begin(bluetoothSerial, auth);
Serial.println("Test_Setup");
}
void loop() {
Blynk.run();
delay(100);
}
If I run this code on the Arduino, then my serial monitor will read the following:
(Note that the BLYNK_WRITE(V11) is an interupt triggered when the GPS 'widget' in the BLYNK app updates)
Test_Setup
userLat: 42.1978645
userLon: -83.1744308
Start of GetLocation
Start of readCartGPS
Start of clearCartGPS
DEBUG: INSIDE WHILE
DEBUG: INSIDE WHILE
DEBUG: INSIDE WHILE
DEBUG: INSIDE WHILE
DEBUG: INSIDE WHILE
DEBUG: INSIDE WHILE
DEBUG: INSIDE WHILE
DEBUG: INSIDE WHILE
DEBUG: INSIDE WHILE
DEBUG: INSIDE WHILE
DEBUG: INSIDE WHILE
DEBUG: INSIDE WHILE
However, if I isolate only the code relating to the cartGPS, then the Serial Monitor will read:
NMEA1:$GPRMC,232347.000,A,4211.8708,N,08310.4676,W,0.08,78.84,091119,,,A*4D
NMEA2:$GPGGA,232348.000,4211.8708,N,08310.4675,W,1,08,1.06,171.9,M,-33.9,M,,*5C
Cart Latitude: 4211.8706054
Cart Longitude: -8310.4677734
NMEA1:$GPRMC,232350.000,A,4211.8707,N,08310.4676,W,0.06,164.81,091119,,,A*73
NMEA2:$GPGGA,232351.000,4211.8707,N,08310.4675,W,1,08,1.06,171.9,M,-33.9,M,,*5B
Cart Latitude: 4211.8706054
Cart Longitude: -8310.4677734
Which is expected.

Just a quick comment - you may want to take the delay command out of your void loop. You can create a timer event for it and put the timer.run in the void loop

Related

Serial Data Read and parse to variables from continuous string (Arduino)

I have 2 Arduino and 2 xbee. I send 2 sensor data from Arduino 1 (router) to Arduino to (coordinator):
On coordinator, I receive wireless data from this 2 sensors(from router) perfectly.
The data stream is something like this:
20.1324325452924 divided in: -first sensor(temperature): 20.1324325452 -second sensor(gas):924
My goal is to have these 2 values as 2 variables that get updated constantly and then pass these values on to the rest of the program to make something like print on LCD or something else:
temperature=20.1324325452 gas=924
I managed to divide that initial string that I receive on serial (20.1324325452924) in 2 variables but values from this 2 variables not updating like in the initial string (when sensor values are changed):
My code:
LiquidCrystal lcd(12,11,10,9,8,7);
String temperature;
String gas;
String readString;
char IncomingData[13];
void setup() {
Serial.begin(9600);
}
void loop() {
while (Serial.available() > 0)
{
char IncomingData = Serial.read();
readString += IncomingData ;
temperature = readString.substring(0, 13); //get the first 13 characters
gas = readString.substring(13, 16); //get the last 3 characters
Serial.print(IncomingData); //here I have my string: 20.1324325452924 which is updating properly when I have sensor values changes
// Process message when new line character is DatePrimite
if (IncomingData == '\n')
{
Serial.println(temperature);
lcd.begin(16, 2);
lcd.setCursor(0,0);
lcd.write("T:");
lcd.print(temperature);
delay(500);
temperature = ""; // Clear DatePrimite buffer
Serial.println(gaz);
lcd.begin(16, 2);
lcd.setCursor(0,1);
lcd.write("G:");
lcd.print(gas);
delay(500);
gaz = ""; // Clear DatePrimite buffer
}
}
}
Output from serial: 20.1324325452924
20.1324325452 924
First string it's updating when I receive new sensor data but the next 2 remains the same every time. I'm stuck for days I don't know to do this work. All I need to do is to divide the initial string which contains the data from 2 sensors in 2 variables that get updated constantly and then pass these values on to the rest of the program to make something like print on LCD.
Does anyone have any idea how to make this work?
Split the data after you receive the complete string.
void loop() {
while(!Serial.available()); // wait till data to be filled in serial buffer
String incommingStr = Serial.readStringUntil('\n'); // read the complete string
String temperature = incommingStr.substring(0, 13);
String gas = incommingStr.substring(13, 16);
Serial.print(incommingStr);
Serial.println(temperature);
Serial.println(gas);
lcd.setCursor(0,0);
lcd.print(temperature);
lcd.setCursor(0,1);
lcd.print(gas);
delay(500);
}
You only need to call lcd.begin() once. Calling it from the setup() function.
you have to modify the program like this: (do an action on readString in loop)
// Process message when new line character is DatePrimite
if (IncomingData == '\n')
{
Serial.println(temperature);
lcd.begin(16, 2);
lcd.setCursor(0,0);
lcd.write("T:");
lcd.print(temperature);
delay(500);
temperature = ""; // Clear DatePrimite buffer
Serial.println(gaz);
lcd.begin(16, 2);
lcd.setCursor(0,1);
lcd.write("G:");
lcd.print(gas);
delay(500);
gaz = ""; // Clear DatePrimite buffer
readString = ""; //clear either you concatenate at each loop!!*******
}

JUCE - play audio input back

I am learning JUCE and I am writing a program that just reads the input from the audio card and plays it back. Obviously this is just for learning purposes. I am using the audio application template. This is the code inside the getNextAudioBlock() function:
void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) override
{
if(true) // this is going to be replaced by checking the value of a button
{
const int channel = 0;
if(true) // this is going to be replaced too
{
const float* inBuffer = bufferToFill.buffer->getReadPointer(channel, bufferToFill.startSample);
float* outBuffer = bufferToFill.buffer->getWritePointer(channel, bufferToFill.startSample);
for(int sample = 0; sample < bufferToFill.numSamples; ++sample)
outBuffer[sample] = inBuffer[sample];
}
else
{
bufferToFill.buffer->clear(0, bufferToFill.startSample, bufferToFill.numSamples);
}
}
else
{
bufferToFill.buffer->clear(0, bufferToFill.startSample, bufferToFill.numSamples);
}
}
The code is really simple: the content from the input buffer is copied directly to the output buffer. However, I am not hearing anything. What am I doing wrong?

Send json from arduino and esp8266 to node.js socket server

I've been trying to send JSON data from arduino mega by using ESP8266 as a wifi shield, and I've used node.js as a socket server. The problem is it seems that a server didn't receive any data. here is my code
#include <ArduinoJson.h>
#include "SoftwareSerial.h"
String ssid ="ssid";
String password="pwd";
//SoftwareSerial esp(22,23);// RX, TX
String data;
String server = "server ip";
byte objlength;
String url = "";
String temp,hum,weight;
StaticJsonBuffer<200> jsonBuffer;
JsonObject& root = jsonBuffer.createObject();
//String uri = "yourURI";
void reset() {
Serial2.println("AT+RST");
delay(1000);
if(Serial2.find("OK") ) Serial.println("Module Reset");
}
void connectWifi() {
String cmd = "AT+CWJAP=\"" +ssid+"\",\"" + password + "\"";
Serial2.println(cmd);
delay(4000);
if(Serial2.find("OK")) {
Serial.println("Connected!");
Serial2.println("AT+CIPSTATUS");
delay(300);
while(Serial2.available()){Serial.print(Serial2.read());}
}
else {
connectWifi();
Serial.println("Cannot connect to wifi"); }
}
void setup() {
delay(5000);
// put your setup code here, to run once:
Serial2.begin(115200);
Serial.begin(115200);
reset();
connectWifi();
}
void loop() {
temp = 25.60;
hum = 65.3;
weight = 65.3;
root["weight"] = weight;
root["light"] = temp;
root["humid"] = hum;
objlength = root.measureLength();
senddata();
delay(10000);
}
void senddata()
{
int objlength = root.measureLength();
Serial2.println("AT+CIPSTART=\"TCP\",\"" + server + "\",1336");//start a TCP connection.
delay(500);
if( Serial2.find("OK")) {
Serial.println("TCP connection ready");
}
else
{
Serial.println("can't establish TCP connection");
}
String sendCmd = "AT+CIPSEND=";//determine the number of caracters to be sent.
Serial2.println(sendCmd);
delay(200);
Serial2.println(objlength);
delay(500);
if(Serial2.find(">"))
{
Serial.println("Sending..");
root.printTo(Serial2);
root.printTo(Serial);
//Serial.println(postRequest);
delay(2000);
if( Serial2.find("SEND OK"))
{
Serial.println("Packet sent");
delay(200);
while (Serial2.available()) {
String tmpResp = Serial2.readString();
Serial.println(tmpResp);
}
// close the connection
}
//delay(1000);
Serial2.print("+++");
delay(1200);
Serial2.println("AT+CIPCLOSE");
delay(50);
Serial.println("Closed");
}
}
Here's my node.js
var net = require('net');
var server = net.createServer(function(socket){
socket.write('SEND OK');
//
socket.pipe(socket);
socket.on('data',function(data){
//if(typeof data != 'string'){
var jsontest = JSON.parse(data);
console.log('Received: ' + data);
console.log(jsontest.weight);
console.log(jsontest.light);
console.log(jsontest.humid);
//}
});
socket.on('listening',function(){
console.log(listen);
});
});
/*server.getConnections(function(err,count){
console.log(count);
});*/
server.listen(1336, '10.42.0.1');
I think that esp8266 can establish a connection with a server , but I don't know why the data won't show. Maybe it's about esp8266 respond time?
screenshot
As you can see from this screenshot, I run node.js server and arduino ,but data won't show on server side. Due to this,I'm not sure where are the problems that cause this.
I'm not an expert. I'm just learning how to do it but i'd say you are not giving enough time through connections. You are relying on delays rather than timeouts while waiting for a true response. There is a difference.
Add much more time or change your strategy by using serial.available() and read in a loop that last a prudential amount of time, and exit when you got data.
Sorry no pasting some code, but i hope you got the idea.
Also i'm facing a power problem. 3,3v pin in arduino uno could be weak in clone boards. But i dont think that's the case.

Sending strings over Serial to Arduino

I'm currently experimenting with sending a string to my Arduino Yun and trying to get it to reply back depending on what I send it.
I picked up a framework of some code here and have been experimenting with it but apart from the serial monitor displaying 'ready' I can't make it go any further.
The code is:
//declace a String to hold what we're inputting
String incomingString;
void setup() {
//initialise Serial communication on 9600 baud
Serial.begin(9600);
while(!Serial);
//delay(4000);
Serial.println("Ready!");
// The incoming String built up one byte at a time.
incomingString = "";
}
void loop () {
// Check if there's incoming serial data.
if (Serial.available() > 0) {
// Read a byte from the serial buffer.
char incomingByte = (char)Serial.read();
incomingString += incomingByte;
// Checks for null termination of the string.
if (incomingByte == '\0') {
// ...do something with String...
if(incomingString == "hello") {
Serial.println("Hello World!");
}
incomingString = "";
}
}
}
Can anyone point me in the right direction?
Thanks
I suspect the problem is that you're adding the null terminator onto the end of your string when you do: incomingString += incomingByte. When you're working with string objects (as opposed to raw char * strings) you don't need to do that. The object will take care of termination on its own.
The result is that your if condition is effectively doing this: if ("hello\0" == "hello") .... Obviously they're not equal, so the condition always fails.
I believe the solution is just to make sure you don't append the byte if it's null.
Try This:
String IncomingData = "";
String Temp = "";
char = var;
void setup()
{
Serial.begin(9600);
//you dont have to use it but if you want
// if(Serial)
{
Serial.println("Ready");
}
//or
while(!Serial)
{delay(5);}
Serial.println("Ready");
void loop()
{
while(Serial.available())
{
var = Serial.read();
Temp = String(var);
IncomingData+= Temp;
//or
IncomingData.concat(Temp);
// you can try
IncomindData += String(var);
}
Serial.println(IncomingData);
IncomingData = "";
}

Simplest way to capture raw audio from audio input for real time processing on a mac

What is the simplest way to capture audio from the built in audio input and be able to read the raw sampled values (as in a .wav) in real time as they come in when requested, like reading from a socket.
Hopefully code that uses one of Apple's frameworks (Audio Queues). Documentation is not very clear, and what I need is very basic.
Try the AudioQueue Framework for this. You mainly have to perform 3 steps:
setup an audio format how to sample the incoming analog audio
start a new recording AudioQueue with AudioQueueNewInput()
Register a callback routine which handles the incoming audio data packages
In step 3 you have a chance to analyze the incoming audio data with AudioQueueGetProperty()
It's roughly like this:
static void HandleAudioCallback (void *aqData,
AudioQueueRef inAQ,
AudioQueueBufferRef inBuffer,
const AudioTimeStamp *inStartTime,
UInt32 inNumPackets,
const AudioStreamPacketDescription *inPacketDesc) {
// Here you examine your audio data
}
static void StartRecording() {
// now let's start the recording
AudioQueueNewInput (&aqData.mDataFormat, // The sampling format how to record
HandleAudioCallback, // Your callback routine
&aqData, // e.g. AudioStreamBasicDescription
NULL,
kCFRunLoopCommonModes,
0,
&aqData.mQueue); // Your fresh created AudioQueue
AudioQueueStart(aqData.mQueue,
NULL);
}
I suggest the Apple AudioQueue Services Programming Guide for detailled information about how to start and stop the AudioQueue and how to setup correctly all ther required objects.
You may also have a closer look into Apple's demo prog SpeakHere. But this is IMHO a bit confusing to start with.
It depends how ' real-time ' you need it
if you need it very crisp, go down right at the bottom level and use audio units. that means setting up an INPUT callback. remember, when this fires you need to allocate your own buffers and then request the audio from the microphone.
ie don't get fooled by the presence of a buffer pointer in the parameters... it is only there because Apple are using the same function declaration for the input and render callbacks.
here is a paste out of one of my projects:
OSStatus dataArrivedFromMic(
void * inRefCon,
AudioUnitRenderActionFlags * ioActionFlags,
const AudioTimeStamp * inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList * dummy_notused )
{
OSStatus status;
RemoteIOAudioUnit* unitClass = (RemoteIOAudioUnit *)inRefCon;
AudioComponentInstance myUnit = unitClass.myAudioUnit;
AudioBufferList ioData;
{
int kNumChannels = 1; // one channel...
enum {
kMono = 1,
kStereo = 2
};
ioData.mNumberBuffers = kNumChannels;
for (int i = 0; i < kNumChannels; i++)
{
int bytesNeeded = inNumberFrames * sizeof( Float32 );
ioData.mBuffers[i].mNumberChannels = kMono;
ioData.mBuffers[i].mDataByteSize = bytesNeeded;
ioData.mBuffers[i].mData = malloc( bytesNeeded );
}
}
// actually GET the data that arrived
status = AudioUnitRender( (void *)myUnit,
ioActionFlags,
inTimeStamp,
inBusNumber,
inNumberFrames,
& ioData );
// take MONO from mic
const int channel = 0;
Float32 * outBuffer = (Float32 *) ioData.mBuffers[channel].mData;
// get a handle to our game object
static KPRing* kpRing = nil;
if ( ! kpRing )
{
//AppDelegate * appDelegate = [UIApplication sharedApplication].delegate;
kpRing = [Game singleton].kpRing;
assert( kpRing );
}
// ... and send it the data we just got from the mic
[ kpRing floatsArrivedFromMic: outBuffer
count: inNumberFrames ];
return status;
}

Resources