Reading ints from serial port Arduino - c

I've done a C program that writes an integer array into the Arduino:
// ...
FILE* file;
file = fopen("/dev/ttyuSB0","w");
for (int i = 0; i < 3; i++) {
fprintf(file, "%d ", rgb[i]);
}
fclose(file);
// ...
How can I do from my arduino code (.ino) to catch the three integers from the file?
while (Serial.available() > 0) {
// What can I do here ???
}

You need to read the data and put it into a buffer. After you encounter a ' ' character you terminate the string inside the buffer and convert it into an int.
When you do this three times you have read all three ints.
const uint8_t buff_len = 7; // buffer size
char buff[buff_len]; // buffer
uint8_t buff_i = 0; // buffer index
int arr[3] = {0,0,0}; // number array
uint8_t arr_i = 0; // number array index
void loop() {
while (Serial.available() > 0) {
char c = Serial.read();
if (buff_i < buff_len-1) { // check if buffer is full
if (c == ' ') { // check if got number terminator
buff[buff_i++] = 0; // terminate the string
buff_i = 0; // reset the buffer index
arr[arr_i++] = atoi(buff); // convert the string to int
if (arr_i == 3) { // if got all three numbers
arr_i = 0; // reset the number array index
// do something with the three integers
}
}
else if (c == '-' || ('0' <= c && c <= '9')) // if negative sign or valid digit
buff[buff_i++] = c; // put the char into the buffer
}
}
// maybe do some other stuff
}
Or if you don't mind blocking code[1] you can use builtin ParseInt.
void loop() {
while (Serial.available() > 0) {
arr[0] = Serial.parseInt();
arr[1] = Serial.parseInt();
arr[2] = Serial.parseInt();
Serial.read(); // read off the last space
// do something with the three integers
}
// maybe do some other stuff, but might be blocked by serial read
}
[1] If your computer has a hiccup and doesn't send all the data at once, your Arduino code will just wait for data and won't be doing anything else. Read more here.

Related

How to Convert the last digit of a number to a char and display it on LCD?

I recently got a STM8 MCU and it has the built in function LCD_GLASS_DisplayString("STRING")
The problem with that function is, as you can see below, that I cannot directly display an integer on it:
void LCD_GLASS_DisplayString(uint8_t* ptr)
{
uint8_t i = 0x01;
LCD_GLASS_Clear();
/* Send the string character by character on lCD */
while ((*ptr != 0) & (i < 8))
{
/* Display one character on LCD */
LCD_GLASS_WriteChar(ptr, FALSE, FALSE, i);
/* Point on the next character */
ptr++;
/* Increment the character counter */
i++;
}
}
How could I modify it so I could send integers directly? Also, I'm not sure I can use any libraries, so just pure C would help.
I was thinking of something like this, but it didn't work:
void LCD_GLASS_DisplayINT(uint16_t integer)
{
uint8_t i = 0x01;
LCD_GLASS_Clear();
/* Send the string character by character on lCD */
while ((integer != 0) & (i < 8))
{
/* Display one number on LCD */
LCD_GLASS_WriteChar("0" + integer%10, FALSE, FALSE, i);
/* Point on the next number*/
integer=integer/10;
/* Increment the character counter */
i++;
}
}
Any idea on how to make it work? I need to either make a function to display the integers or a way to convert them to strings before I send them over to the LCD. The code is pure C, as what I'm programming are pure drivers right now.
You're not far off with "0" + integer%10 - but you need to treat it as a character - '0' + integer%10 - and you need to pass LCD_GLASS_WriteChar a pointer to this character.
One way to do this is:
char* digits = "0123456789";
LCD_GLASS_WriteChar(&digits[integer % 10], FALSE, FALSE, i);
Also, your loop condition - while ((integer != 0) & (i < 8)) should not use bitwise and (&), but rather logical and (&&).
while ((integer != 0) && (i < 8))
You'll want to store the digits in a buffer to get the left-to-right order. On a microcontroller you'll probably want to allocate that buffer in .bss so that it doesn't take up stack. Use static to make that happen. For a 16 bit number you'll have at most 5 digits + null term, so:
static char buf[5+1] = {0};
The conversion is essentially the code you've written, except you mixed up '0' and "0":
for(uint8_t i=0; i<5; i++)
{
buf[5-i-1] = val%10 + '0';
val/=10;
}
Note that this code always leaves item buf[5] untouched and leaves a zero null terminator there.
Complete code with tests in standard C. Obviously drop puts for your custom LCD routine.
#include <stdio.h>
#include <stdint.h>
void display_int (uint16_t val)
{
static char buf[5+1] = {0};
char* p;
for(uint8_t i=0; i<5; i++)
{
buf[5-i-1] = val%10 + '0';
val/=10;
}
// trim leading zeroes
for(p=buf; *p!='\0'; p++)
{
if(*p!='0' || // stop looking at first non zero or
p[1]=='\0') // in case there is only one zero character
break;
}
puts(p); // use whatever string printing routine you got
}
int main (void)
{
display_int(0);
display_int(5);
display_int(666);
display_int(12345);
}
Division on STM8 is very expensive. We can optimize the code a bit by not filling up the whole buffer if we don't have to. This saves us several DIV calls. Optimized version, faster but harder to read:
void display_int (uint16_t val)
{
static char buf[5+1] = {0};
char* p;
char* start;
for(uint8_t i=0;;i++)
{
buf[5-i-1] = val%10 + '0';
val/=10;
if(val==0)
{
start = &buf[5-i-1];
break;
}
}
// trim leading zeroes
for(p=start; *p!='\0'; p++)
{
if(*p!='0' || // stop looking at first non zero or
p[1]=='\0') // in case there is only one zero character
break;
}
puts(p); // use whatever string printing routine you got
}

How can I send the first and second ascii characters as NULL character in a string and not as "" an empty string?

I am currently dealing with a problem that especially has something to do with the first and second ASCII characters, the NULL Character and SOH Character.
The goal of this code is to send some characters and save them in a Tag, which contains 32 Bits/4 Bytes Blocks where Data can be saved in.
I know that there are better ways to achieve this. My Code functions nearly properly except in one single case:
When the Character equals the first ASCII character NULL. Which means when I view the value of the character: c_Char="", when this get sent to the Tag, it doesnt count as an ascii character and gets skipped.
Which means when I check which Characters are sent, the Buffer does not return the character with the 0 decimal value since it was not saved and got skipped.
Is there any If-Condition that I can use to make my program count the NULL ascii character?
This is part of the main Code:
// Splitting the 32 bits from B0 to 4 Bytes
Daten_EEPROM_Byte_VERTEILER(B0);
// Converting The four 32 Bits/4 Bytes Variables into 4 different decimal numbers
Data_Converting_binary_decimal(cFirst_Byte,&i_Char1);
Data_Converting_binary_decimal(cSecond_Byte,&i_Char2);
Data_Converting_binary_decimal(cThird_Byte,&i_Char3);
Data_Converting_binary_decimal(cFourth_Byte,&i_Char4);
//Converting the 4 decimal numbers into 4 ascii Chars.
Fmt(c_Char1,"%c<%i", i_Char1);
Fmt(c_Char2,"%c<%i",i_Char2);
Fmt(c_Char3,"%c<%i",i_Char3);
Fmt(c_Char4,"%c<%i",i_Char4);
//Converting Ascii characters into hexadecimal numbers.
DATEN_Umwandlungsfunktion_Char_hex (c_Char1, x_char1, &iSeriennummer);
DATEN_Umwandlungsfunktion_Char_hex (c_Char2, x_char2, &iSeriennummer);
DATEN_Umwandlungsfunktion_Char_hex (c_Char3, x_char3, &iSeriennummer);
DATEN_Umwandlungsfunktion_Char_hex (c_Char4, x_char4, &iSeriennummer);
//Putting the 4 hex numbers into the one variable:
Fmt(x_Result_B0,"%s<%s%s%s%s",x_char1,x_char2,x_char3,x_char4);
//Showing the 4 hex numbers in a panel:
SetCtrlAttribute(sPanels.P_Hauptmenue, P_MAIN_WB0, ATTR_CTRL_VAL, x_Result_B0);
memset(x_char1,0,sizeof(x_char1));
memset(x_char2,0,sizeof(x_char2));
memset(x_char3,0,sizeof(x_char3));
memset(x_char4,0,sizeof(x_char4));
//Sending the 4 characters into a MSP430 Port to save them in a tag through an antenna
Fmt(Result_Block0,"%s<%s%s%s%s",c_Char1,c_Char2,c_Char3,c_Char4);
Fmt(cCommand,"%s<%s%s%s%s",WRITE_BLOCK,"0_",Result_Block0,ENDE);
// Write and Read Data in and from Block 0
iResult = Befehl_Senden(cCommand,cAnswer);
Fmt(cCommand,"%s<%s%s%s",READ_BLOCK,"0",ENDE);
iResult = Befehl_Senden(cCommand,cAnswer);
CopyBytes(cRead_Block_0,0,cAnswer,23,8);
SetCtrlAttribute(sPanels.P_Hauptmenue, P_MAIN_BR0, ATTR_CTRL_VAL, cRead_Block_0);
These are the following functions that are used to convert the variables:
char *decimal_to_binary(int n)
{
int c, d, t;
char *p;
t = 0;
p = (char*)malloc(32+1);
if (p == NULL)
exit(EXIT_FAILURE);
for (c = 31 ; c >= 0 ; c--)
{
d = n >> c;
if (d & 1)
*(p+t) = 1 + '0';
else
*(p+t) = 0 + '0';
t++;
}
*(p+t) = '\0';
return p;
}
void Daten_HILFSFUNKTION_binary_decimal (char *cEingang, int *iAusgang)
{
int multiplier = 0;
int i;
int sum = 0;
int length;
char cMonth[10] = {0};
int iMonth;
length = StringLength (cEingang);
for (i=length-1; i>=0; i--)
{
CopyBytes (cMonth, 0, cEingang, i, 1);
Fmt (&iMonth, "%x<%s", cMonth);
sum = sum +(iMonth*pow(2, multiplier));
multiplier = multiplier + 1;
}
Fmt (iAusgang, "%i<%i", sum);
}
void Daten_EEPROM_Byte_VERTEILER(char *B)
{
CopyBytes(cFirst_Byte, 0,B,0,8);
CopyBytes(cSecond_Byte, 0,B,8,8);
CopyBytes(cThird_Byte, 0,B,16,8);
CopyBytes(cFourth_Byte, 0,B,24,8);
}
char *Daten_EEPROM_HILFSFUNKTION(char *Char_in_Bits, char *c_8Bits)
{
int Decimal = 0;
char c_Character[5] = {0};
CopyString(Char_in_Bits, 0,c_8Bits,0,8);
Daten_HILFSFUNKTION_binary_decimal (Char_in_Bits, &Decimal);
int B_1_dec = Decimal;
Fmt(c_Character,"%c<%i",B_1_dec);
memset(Char_in_Bits,0,sizeof(Char_in_Bits));
return c_Character;
}
void DATEN_alle_Char_uerbergabe_Funktion (char *Byte_Block,char *c_Char1, char *c_Char2, char *c_Char3,char * c_Char4)
{
DATEN_erster_Char_uebergabe_Funktion(Byte_Block, c_Char1);
DATEN_zweiter_Char_uebergabe_Funktion(Byte_Block, c_Char2);
DATEN_dritter_Char_uebergabe_Funktion(Byte_Block, c_Char3);
DATEN_vierter_Char_uebergabe_Funktion(Byte_Block, c_Char4);
}
char DATEN_erster_Char_uebergabe_Funktion (char *Byte_Block,char *c_Char1)
{
return* c_Char1 = *Daten_EEPROM_HILFSFUNKTION(Byte_Block, cFirst_Byte);
}
char DATEN_zweiter_Char_uebergabe_Funktion(char *Byte_Block,char *c_Char2)
{
return *c_Char2 = *Daten_EEPROM_HILFSFUNKTION(Byte_Block, cSecond_Byte);
}
char DATEN_dritter_Char_uebergabe_Funktion(char *Byte_Block,char *c_Char3)
{
return *c_Char3 = *Daten_EEPROM_HILFSFUNKTION(Byte_Block, cThird_Byte);
}
char DATEN_vierter_Char_uebergabe_Funktion(char *Byte_Block,char *c_Char4)
{
return *c_Char4 = *Daten_EEPROM_HILFSFUNKTION(Byte_Block, cSecond_Byte);
}
void char_Umwandeln (char *cEingang,char *cAusgang)
{
int ilaenge;
int idez_Wert;
int iPos;
char cZwischenspeicher [5] = {0};
ilaenge = StringLength(cEingang);
for (iPos = 0; iPos <=ilaenge - 1; iPos++)
{
idez_Wert = 0;
//CopyBytes (cZwishcenspeicher, 0, cEingang, ilaenge-iPos,1);
CopyBytes (cZwischenspeicher,0,cEingang,iPos,1);
Scan (cZwischenspeicher,"%s>%i[r256]",&idez_Wert);
if (idez_Wert == 0)
{
CopyBytes (cAusgang, 0,"00",0,2);
}
else if (idez_Wert <16)
{
Fmt(cAusgang,"%s<%s%s%i[r16]",cAusgang,"0",idez_Wert);
}
else
{
Fmt(cAusgang,"%s<%s%i[r16]",cAusgang,idez_Wert);
}
}
StringUpperCase(cAusgang);
}
void DATEN_Umwandlungsfunktion_Char_hex (char *Char, char *hex_Char, int *dec_Nummer)
{
char_Umwandeln (Char,hex_Char);
Scan(&hex_Char,"%s>%x",&dec_Nummer);
}
If anyone has already had this problem and knows a solution for this issue, I would be so thankful. Thanks a lot in advance.

c string: put ' ' if a word found in the sentence

I made a code and my target is to put spacewhere the input word was found in a sentence.
i neet to replece the small word with space
like:
Three witches watched three watches
tch
output:
Three wi es wa ed three wa es
I made this code:
#include<stdio.h>
#define S 8
#define B 50
void main() {
char small[S] = {"ol"};
char big[B] = {"my older gradmom see my older sister"};
int i = 0, j = 0;
for (i = 0; i < B; i++)
{
for(j=0;j<S;j++)
{
if(small[j]!=big[i])
{
j=0;
break;
}
if(small[j]=='\0')
{
while (i-(j-1)!=i)
{
i = i - j;
big[i] = '\n';
i++;
}
}
}
}
puts(big);
}
First of all, in your exemple you work with newline '\n' and not with space.
Consider this simple example:
#include<stdio.h>
#define S 8
#define B 50
void main() {
char small[S] = {"ol"};
char big[B] = {"my older gradmom see my older sister"};
int i = 0, j = 0;
int cpt = 0;
int smallSize = 0;
// loop to retrieve smallSize
for (i = 0; i < S; i++)
{
if (small[i] != '\0')
smallSize++;
}
// main loop
for (i = 0; i < B; i++)
{
// stop if we hit the end of the string
if (big[i] == '\0')
break;
// increment the cpt and small index while the content of big and small are equal
if (big[i] == small[j])
{
cpt++;
j++;
}
// we didn't found the full small word
else
{
j = 0;
cpt = 0;
}
// test if we found the full word, if yes replace char in big by space
if (cpt == smallSize)
{
for (int k = 0; k < smallSize; k++)
{
big[i-k] = ' ';
}
j = 0;
cpt = 0;
}
}
puts(big);
}
You need first to retrieve the real size of the small array.
Once done, next step is to look inside "big" if there is the word small inside. If we find it, then replace all those char by spaces.
If you want to replace the whole small word with a single space, then you'll need to adapt this example !
I hope this help !
A possible way is to use to pointers to the string, one for reading and one for writing. This will allow to replace an arbitrary number of chars (the ones from small) with a single space. And you do not really want to nest loops but une only one to process every char from big.
Last but not least, void main() should never be used except in stand alone environment (kernel or embedded development). Code could become:
#include <stdio.h>
#define S 8
#define B 50
int main() { // void main is deprecated...
char small[S] = {"ol"};
char big[B] = {"my older gradmom see my older sister"};
int i = 0, j = 0;
int k = 0; // pointer to written back big
for (i = 0; i < B; i++)
{
if (big[i] == 0) break; // do not process beyond end of string
if(small[j]!=big[i])
{
for(int l=0; l<j; l++) big[k++] = small[l]; // copy an eventual partial small
big[k++] = big[i]; // copy the incoming character
j=0; // reset pointer to small
continue;
}
else if(small[++j] == 0) // reached end of small
{
big[k++] = ' '; // replace chars from small with a single space
j = 0; // reset pointer to small
}
}
big[k] = '\0';
puts(big);
return 0;
}
or even better (no need for fixed sizes of strings):
#include <stdio.h>
int main() { // void main is deprecated...
char small[] = {"ol"};
char big[] = {"my older gradmom see my older sister"};
int i = 0, j = 0;
int k = 0; // pointer to written back big
for (i = 0; i < sizeof(big); i++)
{
if(small[j]!=big[i])
...
In C strings are terminated with a null character '\0'. Your code defines a somehow random number at the beginning (B and S) and iterates over that much characters instead of the exact number of characters, the strings actually contain. You can use the fact that the string is terminated by testing the content of the string in a while loop.
i = 0;
while (str[i]) {
...
i = i + 1;
}
If you prefer for loops you can write it also as a for loop.
for (i = 0; str[i]; i++) {
...
}
Your code does not move the contents of the remaining string to the left. If you replace two characters ol with one character , you have to move the remaining characters to the left by one character. Otherwise you would have a hole in the string.
#include <stdio.h>
int main() {
char small[] = "ol";
char big[] = "my older gradmom see my older sister";
int s; // index, which loops through the small string
int b; // index, which loops through the big string
int m; // index, which loops through the characters to be modified
// The following loops through the big string up to the terminating
// null character in the big string.
b = 0;
while (big[b]) {
// The following loops through the small string up to the
// terminating null character, if the character in the small
// string matches the corresponding character in the big string.
s = 0;
while (small[s] && big[b+s] == small[s]) {
// In case of a match, continue with the next character in the
// small string.
s = s + 1;
}
// If we are at the end of the small string, we found in the
// big string.
if (small[s] == '\0') {
// Now we have to modify the big string. The modification
// starts at the current position in the big string.
m = b;
// First we have to put the space at the current position in the
// big string.
big[m] = ' ';
// And next the rest of the big string has to be moved left. The
// rest of the big string starts, where the match has ended.
while (big[b+s]) {
m = m + 1;
big[m] = big[b+s];
s = s + 1;
}
// Finally the big string has to be terminated by a null
// character.
big[m+1] = '\0';
}
// Continue at next character in big string.
b = b + 1;
}
puts(big);
return 0;
}

Fread - large amount of integers

i need to read large amount of integers from stdin. Speed is very important here, for example getchar_unlocked is too slow for me(hundredths of a second really matters)
My code works with getchar_unlocked, but now I'm trying to read wholle line of unknown number of integers to buffer with fread. What is wrong down there?
code below:
inline int fastRead_int(int *sum) {
char buffer[sizeof(int)*sizeof(int)];
register int i = 0;
fread(buffer,sizeof(buffer),1,stdin);
register int c = buffer[0];
int x = 0;
while(c != NULL)
{
c = buffer[++i];
for(; ((c<48 || c>57) && c != ' '); c = buffer[++i]);
for(; c>47 && c<58 && c != ' ' ; c = buffer[++i]) {
x = (x<<1) + (x<<3) + c - 48;
}
*sum = *sum+x;
}
// what exactly does the input look like?
// I doubt that the input is a series of single digit numbers.
// and for multidigit numbers, the following will not work
// the posted code fails to compile for several reasons,
// including that the 'int' return value is never set
// and the code is much to big for inlining
inline int fastRead_int(int *sum)
{
char buffer[sizeof(int)*sizeof(int)]; //<-- = 64bytes = 16 binary ints
// but as little as 4 character ints
register int i = 0;
fread(buffer,sizeof(buffer),1,stdin);
// <-- should check/save the returned value
// as that would be the number of characters actually read
// and fread() does not NUL terminate the input
// should also check for and handle read failures
register int c = buffer[0]; // <-- this gets one byte/char only,
// however, unless the input is a binary file
// this will only get the first byte
// of a numeric char string.
int x = 0;
// <-- suggest the following code block be:
// for( i=0; i<(returned value from fread(); i++)
// {
// if( isdigit(c) )
// {
// x += (c-48);
// }
// c = buffer[++i];
// } // end for
// *sum += x;
while(c != NULL) // <-- 'c' is a integer in the range 0...255
// but NULL is a 4 byte pointer to 0
// perhaps you meant: 'while(c)'
{
c = buffer[++i]; // <-- see my comment about reading buffer, above
// step by non-numeric characters
// what if the input does not end in a numeric character?
// then would be reading past the end of the buffer[]
// resulting in undefined behaviour leading to a seg fault event
for(; ((c<48 || c>57) && c != ' '); c = buffer[++i]);
//<-- much better/clearer to #include ctype.h and then
// for( ; !isdigit(c); c = buffer[++i] ;)
// <-- see above comments
for(; c>47 && c<58 && c != ' ' ; c = buffer[++i])
{
x = (x<<1) + (x<<3) + c - 48;
}
*sum = *sum+x;
} // end while

Split String into String array

I have been playing around with programming for arduino but today i've come across a problem that i can't solve with my very limited C knowledge.
Here's how it goes.
I'm creating a pc application that sends serial input to the arduino (deviceID, command, commandparameters). This arduino will transmit that command over RF to other arduino's. depending on the deviceID the correct arduino will perform the command.
To be able to determine the deviceID i want to split that string on the ",".
this is my problem, i know how to do this easily in java (even by not using the standard split function), however in C it's a totally different story.
Can any of you guys tell me how to get this working?
thanks
/*
Serial Event example
When new serial data arrives, this sketch adds it to a String.
When a newline is received, the loop prints the string and
clears it.
A good test for this is to try it with a GPS receiver
that sends out NMEA 0183 sentences.
Created 9 May 2011
by Tom Igoe
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/SerialEvent
*/
String inputString; // a string to hold incoming data
boolean stringComplete = false; // whether the string is complete
String[] receivedData;
void setup() {
// initialize serial:
Serial.begin(9600);
// reserve 200 bytes for the inputString:
inputString.reserve(200);
}
void loop() {
// print the string when a newline arrives:
if (stringComplete) {
Serial.println(inputString);
// clear the string:
inputString = "";
stringComplete = false;
}
}
/*
SerialEvent occurs whenever a new data comes in the
hardware serial RX. This routine is run between each
time loop() runs, so using delay inside loop can delay
response. Multiple bytes of data may be available.
*/
void serialEvent() {
while (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
if (inChar == '\n') {
stringComplete = true;
}
// add it to the inputString:
if(stringComplete == false) {
inputString += inChar;
}
// if the incoming character is a newline, set a flag
// so the main loop can do something about it:
}
}
String[] splitCommand(String text, char splitChar) {
int splitCount = countSplitCharacters(text, splitChar);
String returnValue[splitCount];
int index = -1;
int index2;
for(int i = 0; i < splitCount - 1; i++) {
index = text.indexOf(splitChar, index + 1);
index2 = text.indexOf(splitChar, index + 1);
if(index2 < 0) index2 = text.length() - 1;
returnValue[i] = text.substring(index, index2);
}
return returnValue;
}
int countSplitCharacters(String text, char splitChar) {
int returnValue = 0;
int index = -1;
while (index > -1) {
index = text.indexOf(splitChar, index + 1);
if(index > -1) returnValue+=1;
}
return returnValue;
}
I have decided I'm going to use the strtok function.
I'm running into another problem now. The error happened is
SerialEvent.cpp: In function 'void splitCommand(String, char)':
SerialEvent:68: error: cannot convert 'String' to 'char*' for argument '1' to 'char* strtok(char*, const char*)'
SerialEvent:68: error: 'null' was not declared in this scope
Code is like,
String inputString; // a string to hold incoming data
void splitCommand(String text, char splitChar) {
String temp;
int index = -1;
int index2;
for(temp = strtok(text, splitChar); temp; temp = strtok(null, splitChar)) {
Serial.println(temp);
}
for(int i = 0; i < 3; i++) {
Serial.println(command[i]);
}
}
This is an old question, but i have created some piece of code that may help:
String getValue(String data, char separator, int index)
{
int found = 0;
int strIndex[] = {0, -1};
int maxIndex = data.length()-1;
for(int i=0; i<=maxIndex && found<=index; i++){
if(data.charAt(i)==separator || i==maxIndex){
found++;
strIndex[0] = strIndex[1]+1;
strIndex[1] = (i == maxIndex) ? i+1 : i;
}
}
return found>index ? data.substring(strIndex[0], strIndex[1]) : "";
}
This function returns a single string separated by a predefined character at a given index. For example:
String split = "hi this is a split test";
String word3 = getValue(split, ' ', 2);
Serial.println(word3);
Should print 'is'. You also can try with index 0 returning 'hi' or safely trying index 5 returning 'test'.
Hope this help!
Implementation:
int sa[4], r=0, t=0;
String oneLine = "123;456;789;999;";
for (int i=0; i < oneLine.length(); i++)
{
if(oneLine.charAt(i) == ';')
{
sa[t] = oneLine.substring(r, i).toInt();
r=(i+1);
t++;
}
}
Result:
// sa[0] = 123
// sa[1] = 456
// sa[2] = 789
// sa[3] = 999
For dynamic allocation of memory, you will need to use malloc, ie:
String returnvalue[splitcount];
for(int i=0; i< splitcount; i++)
{
String returnvalue[i] = malloc(maxsizeofstring * sizeof(char));
}
You will also need the maximum string length.
The C way to split a string based on a delimiter is to use strtok (or strtok_r).
See also this question.
I think your idea is a good start point. Here is a code that i use (to parse HTTP GET REST requests with an Ethernet shield).
The idea is to use a while loop and lastIndexOf of and store the strings into an array (but your could do something else).
"request" is the string you want to parse (for me it was called request because.. it was).
int goOn = 1;
int count = -1;
int pos1;
int pos2 = request.length();
while( goOn == 1 ) {
pos1 = request.lastIndexOf("/", pos2);
pos2 = request.lastIndexOf("/", pos1 - 1);
if( pos2 <= 0 ) goOn = 0;
String tmp = request.substring(pos2 + 1, pos1);
count++;
params[count] = tmp;
// Serial.println( params[count] );
if( goOn != 1) break;
}
// At the end you can know how many items the array will have: count + 1 !
I have used this code successfully, but i thing their is an encoding problem when i try to print params[x]... i'm alos a beginner so i don't master chars vs string...
Hope it helps.
I believe this is the most straight forward and quickest way:
String strings[10]; // Max amount of strings anticipated
void setup() {
Serial.begin(9600);
int count = split("L,-1,0,1023,0", ',');
for (int j = 0; j < count; ++j)
{
if (strings[j].length() > 0)
Serial.println(strings[j]);
}
}
void loop() {
delay(1000);
}
// string: string to parse
// c: delimiter
// returns number of items parsed
int split(String string, char c)
{
String data = "";
int bufferIndex = 0;
for (int i = 0; i < string.length(); ++i)
{
char c = string[i];
if (c != ',')
{
data += c;
}
else
{
data += '\0';
strings[bufferIndex++] = data;
data = "";
}
}
return bufferIndex;
}

Resources