I am trying to figure out how to extract the numbers I get from the Geiger Counter via SoftwareSerial so that I combine it with other info like for example an analog read from a light sensor.
I am guessing it implies using strings but I don't know how I should use them.
If I use the code below, I get for example "CPM: 16 CPS: 1" with a return at the end (CPM stand for counts per minute and CPS for counts per second).
But in the end I would like to send a string like this via Serial.print:
sensor1, 16
sensor2, 1
sensor3, 126
#include "SoftwareSerial.h"
SoftwareSerial GeigerCounter (3, 2);
void setup() {
Serial.begin(9600);
//connection to Xbee shield
GeigerCounter.begin(9600);
}
void loop()
{
if (GeigerCounter.available()) {
Serial.print((char)GeigerCounter.read()); //grab avail data from Geiger and send to host pc
}
}
If I use the code below, I get for example "CPM: 16 CPS: 1"
So the Geiger counter is outputting that string, if you want something different then you have to parse the string that is split it up.
Start by gathering in all the string into a char array until you encounter the line feed. Then add a zero to the next space in the array and you have a string.
You can then extract elements from it, like the count, it will always start at the same point and continue until there is a space (ASCII 0x20 )
When you have extracted the elements you want you can either print out the values as numbers or turn them into strings and print that out.
Thank you for looking into this. I know a lil bit about the logic but I can't figure out how to actually implement it. I am stuck at gathering all the data into a string.
I did the following but it does not work. Does someone know how I should fix this?
#include <SoftwareSerial.h>
SoftwareSerial GeigerSerial (3, 2);
char inData[20]; // Allocate some space for the string
char inChar=-1; // Where to store the character read
byte index = 0; // Index into array; where to store the character
void setup() {
Serial.begin(9600); //connection to host computer
Serial.println("Geiger ready");
GeigerSerial.begin(9600); //connection to Geiger shield
}
void loop() {
if (GeigerSerial.available() > 0) // Don't read unless
// you know there is data
if(index < 19){
inChar = GeigerSerial.read();
inData[index] = inChar;
index++;
inData[index] = '\0'; // Null terminate the string
Serial.print(inData[20]);
}
}
You never put index back to zero once you have gathered in the string.
There is no { and } following the
if (GeigerSerial.available() > 0) // Don't read unless
so the condition is only the first instruction
After each character has been read in you do
Serial.print(inData[20]);
Which prints out the ASCII value of the 20th position in the array, which is beyond the array. Plus why do it anyway?
This line:- char inData[20]; // Allocate some space for the string
Tells the computer to reserve spaces for an array with indexes from 0 to 19
You need to terminate the string gathering when you see a line feed or carriage return, that defines the end of the string from your instrument. Then you need to move the code on to do something with your string.
I managed to modify some code I found that would hopefully help me solve this.
In order to manage this project better, I have now the following. What I want to achieve is in a sense the same as previous, but easier for people to get into.
Consider I use 2 XBees. One is sending data, the other one is receiving. The thing is I don't know how to modify the first sketch (the sender) so that it sends CR to terminate the string, or better yet modify the second sketch (the receiver) so that I use something else (not char 13) that I receive via serial to terminate the string or just add something to terminate it properly.
This code goes to the Arduino+XBee 1 that sends the data:
int SensorPin = 0; //analog sensor for detecting light
#include <SoftwareSerial.h>
SoftwareSerial XBeeSerial (3, 2);
void setup() {
Serial.begin(9600);
XBeeSerial.begin(9600); //connection to Xbee shield
}
void loop() {
int value = analogRead(temt6000Pin);
String XBeeString = "Light: "; // I added this to the string in order to have something similar to the first example to process
XBeeString += value;
Serial.println(XBeeString);
XBeeSerial.println(XBeeString);
delay(100); //only here to slow down the output so it is easier to read
}
and this code goes to the Arduino+XBee 2 that receives the data:
#include <SoftwareSerial.h>
SoftwareSerial XBeeSerial (3, 2);
void setup() {
Serial.begin(9600); // Initialize serial port
XBeeSerial.begin(9600);
}
void loop()
{
serialReader();
}
void serialReader(){
int makeSerialStringPosition;
int inByte;
char serialReadString[50];
const int terminatingChar = 13; //Terminate lines with CR
inByte = XBeeSerial.read();
makeSerialStringPosition=0;
if (inByte > 0 && inByte != terminatingChar) { //If we see data (inByte > 0) and that data isn't a carriage return
delay(100); //Allow serial data time to collect (I think. All I know is it doesn't work without this.)
while (inByte != terminatingChar && XBeeSerial.available() > 0){ // As long as EOL not found and there's more to read, keep reading
serialReadString[makeSerialStringPosition] = inByte; // Save the data in a character array
makeSerialStringPosition++; //Increment position in array
//if (inByte > 0) Serial.println(inByte); // Debug line that prints the charcodes one per line for everything recieved over serial
inByte = XBeeSerial.read(); // Read next byte
}
if (inByte == terminatingChar) //If we terminated properly
{
serialReadString[makeSerialStringPosition] = 0; //Null terminate the serialReadString (Overwrites last position char (terminating char) with 0
Serial.println(serialReadString);
}
}
}