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

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!!*******
}

Related

Sending Strings from arduino to Processing

I want to get Processing to read Strings from Arduino.
I send two Strings massages from the arduino and I want to store them in two different variables on Processing.
I tried to do it, but the two Strings are passed to the first variable and the second variable remains empty. I don't understand why this is the case. Can someone help?
Regards
Arduino Code
void setup() {
Serial.begin(9600);
delay(1000);
Serial.println("1.first message");
Serial.println("2.second message");
delay(100);
}
void loop() {
}
Processing Code
import processing.serial.*;
Serial myPort;
void setup() {
myPort=new Serial(this, "COM3", 9600);
}
void draw() {
String s1=myPort.readStringUntil('\n');
String s2=myPort.readStringUntil('\n');
// printing variables
if(s1!=null){
print("s1:",s1);
}
if(s2!=null){
println("s2:",s2);
}
}
The following works on my Mac system. The incoming strings are placed in a string array as they arrive. The string at index[0] then becomes s1 and the string at index[1] is s2. I also added a delay(100); between the two strings on the Arduino side, but this may not be necessary; you can try it both ways.
import processing.serial.*;
Serial myPort;
String[] s; // Array to hold two strings.
int counter = 0;
void setup() {
printArray(Serial.list()); // List of serial ports
// Enter appropriate number for your system
myPort = new Serial(this, Serial.list()[2], 9600);
s = new String[2];
println("===========");
}
void draw() {
String str = myPort.readStringUntil('\n');
if(str != null) {
s[counter] = str;
if(counter == 0){
println("s1 = ",s[0]);
} else {
println("s2 = ",s[1]);
}
counter++;
}
}

GPS Communication with Arduino

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

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 = "";
}

Cast from int to String on android

I'm developing an app where I need to send the values of 3 seekbars via bluetooth. All the bluetooth method I've developed is based on the bluetoothChat example. The app communicates well sending characters, but as i said, i need to send the value of 3 seekbars.
So, I'm creating a sending function to send these 3 values in one string, but i think that i'm doing wrong the cast because i'm getting an error and the logcat refers my to this point.
This is the code, need to mention that the "savedProgressX" values are int type and have the current value of the seekbar, and the "sendX" values are textview type that I've created only to save these values:
public void sendValues() {
send1 = Integer.toString(savedProgress1);
send2 = Integer.toString(savedProgress2);
send3 = Integer.toString(savedProgress3);
/**Set the seekbars values into a string*/
String message = send1+":"+send2+":"+send3+"\n";
//String[] values = message.split(":");
//for (String value : values) {
//int number = Integer.valueOf(value);
//}
/**Check that we're actually connected before trying anything*/
if (GlobalVar.mTransmission.getState() != GlobalVar.STATE_CONNECTED) {
Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show();
return;
}
/**Get the message bytes and tell the Transmission to write*/
byte[] send = message.getBytes();
GlobalVar.mTransmission.write(send);
/**Reset out string buffer to zero*/
GlobalVar.mOutStringBuffer.setLength(0);
}

JList updating with live captured packets info (using jNetPcap) is causing list blanking

I am coding app which is capturing packet from 2 NI Cards at the same time in specific thread for them.
I am using jnetPcap and I am getting captured packet in jpackethanler's method nextPacket i need to show info from the current packet in JList but when I use simply defaultListModel and i write model1.addElement(packetinfo) then JList randomly goes in blank.
My code :
new Thread(){
#Override
public void run(){
StringBuilder errbuf = new StringBuilder(); // For any error msgs
int snaplen = 64 * 1024; // Capture all packets, no trucation
int flags = Pcap.MODE_PROMISCUOUS; // capture all packets
int timeout = 10 * 1000; // 10 seconds in millis
Pcap pcap1 =
Pcap.openLive(Variables.getDevice1().getName(), snaplen, flags, timeout, errbuf);
if (pcap1 == null) {
System.err.printf("Error while opening device for capture: "
+ errbuf.toString());
return;
}
PcapPacketHandler<String> jpacketHandler1 = new PcapPacketHandler<String>() {
int count = 1;
#Override
public void nextPacket(PcapPacket packet, String user) {
// ALL PACKETS FROM DEVICE 1 HERE
int packetSize = packet.size();
int packetCount = count++;
String desc = String.format("No.: %15d | HDRSize : %-4d", packetCount,packetSize);
device1Model.addElement(desc); // this adds desc to JLIST
}
};
pcap1.loop(Pcap.LOOP_INFINITE, jpacketHandler1, "");
pcap1.close();
}
}.start();
What do change to be more smooth and at the same time there will be no packet looses. Because i need to catch every packet for right function of app.
Thank You.

Resources