I'm not understanding why I'm unable to convert the Liters/Minute to a numberical value.
7.320,4.734,284.057
4.7340 Liters/Minute
0 in HEX
if (sensor_stringcomplete){ //if a string from the Atlas Scientific product has been received in its entirety
Serial.println(sensorstring); //use the hardware serial port to send that data to the PC
for (int i=6; i<11; i++) {
Serial.print(sensorstring[i]); //print each string character to verify
float flowLong = (sensorstring[i] - '0');
}
Serial.print(flowLong);Serial.println(" Liters/Minute");
if (flowLong < 4.5) {
Serial.println("FLOW WARNING!!!");
}
Serial.print(flowLong,HEX);Serial.println(" in HEX");
sensorstring = ""; //clear the string buffer:
sensor_stringcomplete = false; //reset the flag used to tell if we have received a completed string from the Atlas Scientific product
}
So loop through 5 characters in a string, creating a new float variable, assigning it a variable, and discarding it.
When you declare a variable like you are doing here, it is only valid inside the innermost curly braces. So the flowLong you create here isn't the same as the flowLong as you are printing to the screen. Not that fixing the scope issue will fix your issue; the algorithm you are using make absolutely no sense and will only result in floatLong containing the numeric value of the last digit.
Drop the String object. Use c style strings and atof().
Simple servo code that takes a numerical string from the serial monitor and converts it into a number for controlling a servo.
//zoomkat 3-5-12 simple delimited ',' string parce
//from serial port input (via serial monitor)
//and print result out serial port
// CR/LF could also be a delimiter
String readString;
#include <Servo.h>
Servo myservo; // create servo object to control a servo
void setup() {
Serial.begin(9600);
myservo.writeMicroseconds(1500); //set initial servo position if desired
myservo.attach(7); //the pin for the servo control
Serial.println("servo-delomit-test-22-dual-input"); // so I can keep track of what is loaded
}
void loop() {
//expect a string like 700, or 1500, or 2000,
//or like 30, or 90, or 180,
if (Serial.available()) {
char c = Serial.read(); //gets one byte from serial buffer
if (c == ',') {
if (readString.length() >1) {
Serial.println(readString); //prints string to serial port out
int n = readString.toInt(); //convert readString into a number
// auto select appropriate value, copied from someone elses code.
if(n >= 500)
{
Serial.print("writing Microseconds: ");
Serial.println(n);
myservo.writeMicroseconds(n);
}
else
{
Serial.print("writing Angle: ");
Serial.println(n);
myservo.write(n);
}
//do stuff with the captured readString
readString=""; //clears variable for new input
}
}
else {
readString += c; //makes the string readString
}
}
}
I took a look at the references you mention explaining strings but it still does not explain how to read strings coming in from the serial port.
On a good note, I was able to isolate the variables of interest (after the second comma)
135.846,4.712,282.736
4.71
For now I am willing to settle to convert the second string in to a integer. The problem I ran in to is I'm unable to save the string of digits in to an array for later use.
if (sensor_stringcomplete) //if a string from the Atlas Scientific product has been received in its entirety
{
Serial.println(sensorstring); //use the hardware serial port to send that data to the PC
for (int i=6; i<11; i++)
{
Serial.print(sensorstring[i]);
int f = sensorstring[i].toInt();
}
Serial.println(" this is the string of interest");
sensorstring = ""; //clear the string buffer:
sensor_stringcomplete = false; //reset the flag used to tell if we have received a completed string from the Atlas Scientific product
}
Unfortunately int f = sensorstring[i].toInt(); does not work. I would also assume it would be out of the scope to use this value outside the brackets.
If I simply use int f = sensorstring.toInt(); it compiles but that is only the first string before the first comma.
chiques:
Hi Arrrch,
Does this mean its not possible to convert a string to float in Arduino?
Consider it a sign to stop using Strings and take a few minutes to learn about strings.
If it only takes a few minutes to learn the strings answer, how about posting up the needed code.
I don't usually write code for people; not part of my philosophy on teaching. I realize your philosophy differs greatly from that.
Luckily I happen to have simple example sitting on my computer:
/*
* Example for Serial2Int
* When reading from the serial monitor, there are two important things to note:
* (1) Bytes are read one at a time. So when sending "246", will be read by your
* code as '2', then '4', then '6'. If you want to identify them as related in some
* way, you need a way to determine that. This example uses start and stop bytes.
* (2) Sending a number through the monitor sends it's ASCII representation, not
* the value itself. So typing 3 and hitting enter would send '3' or 51 as per the
* ascii table. To account for this, we will be using atoi(), which takes a null
* terminated array of chars, also known as a string, and produces the int equivalent.
*/
// To send a number through the serial monitor, put it between brackets
const char startByte = '<';
const char stopByte = '>';
// Maximum characters in an int + null terminated character
const byte maxBuffer = 6;
void setup() {
Serial.begin(57600);
Serial.println("[Serial2Int]");
}
void loop() {
// Stores the characters between the start and stop bytes
static char buffer[maxBuffer];
// Keeps track of spot in buffer
static byte index=0;
if (Serial.available() > 0 ) {
char inChar = Serial.read();
if (inChar==startByte) { // If start byte is received
index=0; // then reset buffer and start fresh
} else if (inChar==stopByte) { // If stop byte is received
processData(buffer); // and process the data
index=0; // this isn't necessary, but helps limit overflow
} else { // otherwise
buffer[index] = inChar; // put the character into our array
index++; // and move to the next key in the array
buffer[index] = '\0'; // then null terminate
}
/* Overflow occurs when there are more than 5 characters in between
* the start and stop bytes. This has to do with having limited space
* in our array. We chose to limit our array to 5 (+1 for null terminator)
* because an int will never be above 5 characters */
if (index>=maxBuffer) {
index=0;
Serial.println("Overflow occured, next value is unreliable");
}
}
}
void processData(char buffer[]) {
unsigned int value = atoi(buffer); // convert string to int
Serial.print("Value: ");
Serial.println(value);
}
Hi Arrrch,
I never meant to cause frustration or the obligation for a hand out. I chose Arduino because of the vast amount of sample code I can read and practice with along with the awesome support by so many vendors (including this forum). Yes, my philosophy to learn is to try (actual hands on); and keep trying until it works. I exhaust all literature that I can understand. I avoid inconveniencing those around me until I am too "lost in the woods". Right now I feel like I'm in the Amazon by some ancient undiscovered Mayan village.
That being said, thank you for the example. I will use it as a study example along with the rest of the recommendations on this thread to try to understand this functionality as much as possible.
chiques:
Hi Arrrch,
I never meant to cause frustration or the obligation for a hand out. I chose Arduino because of the vast amount of sample code I can read and practice with along with the awesome support by so many vendors (including this forum). Yes, my philosophy to learn is to try (actual hands on); and keep trying until it works. I exhaust all literature that I can understand. I avoid inconveniencing those around me until I am too "lost in the woods". Right now I feel like I'm in the Amazon by some ancient undiscovered Mayan village.
If your system does not have a direct way of converting a number with a decimal point
from a character to a numerical representation, you can always do it the hard way.
Read the digits before the decimal point (on the left of it), as an integer.
Read the digits on the right of the decimal point, and count them.
Create a float, and divide the second number you read by ten several times
Add the first number you read.
Example: read 1234.567 in characters
Get 1234 from this
Get 567 from this. There are three digits
Convert 567 to a floating point number and divide by ten, three times.
You get .567
Now add 1234 to this. You got 1234.567
michinyon:
If your system does not have a direct way of converting a number with a decimal point
from a character to a numerical representation, you can always do it the hard way.
Read the digits before the decimal point (on the left of it), as an integer.
Read the digits on the right of the decimal point, and count them.
Create a float, and divide the second number you read by ten several times
Add the first number you read.
Example: read 1234.567 in characters
Get 1234 from this
Get 567 from this. There are three digits
Convert 567 to a floating point number and divide by ten, three times.
You get .567
Now add 1234 to this. You got 1234.567
I'm going to try this approach. None of the other functions mentioned in this post are working for me. I don't mind the practice.