How to split a bunch of text - Page 1
Forum section: electronics / beginners

author: skillz21
author_rank: Frequent Contributor
timestamp: April 09, 2017, 10:50:20 am
content: Hi!At the moment I am trying to build an RGB LED that can be controlled from my phone via Bluetooth. I want to send the RGB led control data in a string like this: 134, 36, 122. Each number is supposed to signify the amount of brightness for each colour. My problem right now, is I don't know how to split each set of digits so that I am left with an individual number for each colour. How do I do this, Google has let me down so I turned to the forum.Thx

author: Avacee
author_rank: Unknown
timestamp: April 09, 2017, 10:55:29 am
content: The answer rather depends on what platform you are sending the data to and the language ...

author: skillz21
author_rank: Frequent Contributor
timestamp: April 09, 2017, 10:56:29 am
content: Oh sorry, Arduino...

author: janoc
author_rank: Super Contributor
timestamp: April 09, 2017, 10:56:42 am
content: Isn't this, like, programming 101?Scan the string until you find a comma, storing the characters as you go? That will give you the 3 strings you can convert to numbers.Some libraries/languages have a string Split() function where you can specify the delimiter that automates the above.In C you have strtok() function.You can even use a regular expression if you want (and are lazy & masochist).If you are really lazy, replace the comma with space. Then you can use normal stream reading functions - e.g. scanf(), of Arduino's parseInt() - those read until they hit whitespace, so calling parseInt() 3x will give the 3 numbers directly.Googling for "how to split a string" will give you tons of links with examples in various languages.

author: Avacee
author_rank: Unknown
timestamp: April 09, 2017, 11:04:04 am
content: https://www.arduino.cc/en/Tutorial/ReadASCIIStringThere's a standard tutorial on the Arduino site that details exactly what to do

author: mariush
author_rank: Super Contributor
timestamp: April 09, 2017, 01:05:07 pm
content: Skillz, since each channel can only have values between 0 and 255 , you should simply send one byte for each color. So you get 3 bytes and you set the color of each led. Super simple.If you want it to be more user friendly, maybe you could use Hexadecimal notation ... you send six characters between 0 and f and your arduino code splits the six characters in 3 sets of two... you'll just have to be careful to accept either lowercase or uppercase for each byte of the six bytes, and then it's a simple issue of converting each [0..9 a..f] to [0..15] and then you'd do a simple value = 16* byte1 + byte2;If you want to be so literal, you'd have to program your code to ignore spaces and to consider the end of a number when the "," is detected, or the end of a string. If this string is something the user could enter ( in a terminal window or something like that, you'd also have to be careful to ignore values larger than 255 or series of digits higher than 3 characters in a row and so on.

author: amyk
author_rank: Super Contributor
timestamp: April 09, 2017, 03:15:03 pm
content: What mariush said. The receiver code can be extremely simple in that case.Seeing as you're a beginner, you should probably go read more about data representation and binary too.

author: Ian.M
author_rank: Super Contributor
timestamp: April 09, 2017, 05:06:08 pm
content: +1 for hex. Accept the next six digits after the character bytes '#', or '0','x' or '0','X' (that's zero, not letter O) as hex. Use the same RRGGBB ordering as HTML colour code. It keeps it really simple on both ends as on the sending end, you can repurpose a HTML colour picker and the receiving end doesn't really need a command parser, it only has to wait for one of three possible trigger codes then grab the next six bytes and decode each as a single nibble then re-pack them in the three output bytes.

author: helius
author_rank: Super Contributor
timestamp: April 09, 2017, 06:40:28 pm
content: Or simply use the C library functionstrtouland use the value directly (the RGB led will probably use the same format).

author: skillz21
author_rank: Frequent Contributor
timestamp: April 10, 2017, 03:21:26 am
content: Does anyone know a good place where I can learn the basics of Arduino then? I'm pretty horrible at coding

author: skillz21
author_rank: Frequent Contributor
timestamp: April 10, 2017, 05:21:09 am
content: Also, I'm in the process of making an android app in MIT App Inventor. Does anyone know how to keep repeating a procedure? So I need to repeat the instructions to send slider position data to my Bluetooth module (which is connected to the Arduino). I can't seem to find a block to do this

author: hamster_nz
author_rank: Super Contributor
timestamp: April 10, 2017, 09:49:10 am
content: Here's how I would do it, ignoring you can use atoi(), sscanf(), ctype.h and other standard functions and features:Write down the definition of 'an acceptable string - one that will be accepted'. Here is what I think you are saying:Code:- any number of spaces- either-- a zero character- or-- one or more digits- any number of spaces- a comma- any number of spaces- either-- a single '0' character- or-- one or more digits '0' to '9'- any number of spaces- a comma- any number of spaces- either-- a zero character- or-- one or more digits- any number of spaces- Either a new line, a carriage return, or a NULL to terminate the string.That gives you the structure for what you are trying to parse. Then just convert that to code to a function, but you also need to extract the numbers from the digits:Code:int p1,p2,p3;int split_string(char *s) {/* Check that a pointer has been passed into the function */if(s == NULL)return 0;p1 = p2 = p3 = 0;/* Skip leading spaces */while(*s == ' ')s++;/* Check for a digit */if(*s < '0' || *s > '9')return 0;/* Extract value for P1 */if(*s == '0') {s++; /* Skip any zero - two zeros in a row will fail validation */} else while(*s >= '0' && *s <= '9') {p1 = p1 * 10 + *s - '0';s++;}/* Skip spaces */while(*s == ' ')s++;/* Check for a comma */if(*s != ',') return 0;s++;/* Skip spaces */while(*s == ' ')s++;/* Check for a digit */if(*s < '0' || *s >'9')return 0;/* Extract value for P2 */if(*s == '0') {s++;} else while(*s >= '0' && *s <= '9') {p2 = p2 * 10 + *s - '0';s++;}/* Skip spaces */while(*s == ' ')s++;/* CHeck for a comma */if(*s != ',') return 0;s++;/* Skip spaces */while(*s == ' ')s++;/* Check for a digit */if(*s < '0' || *s >'9')return 0;/* Extract value for P3 */if(*s == '0') {s++;} else while(*s >= '0' && *s <= '9') {p3 = p3 * 10 + *s - '0';s++;}/* Skip spaces */while(*s == ' ')s++;/* IF we have a CR or New Line character then we have succeeded */if(*s == '\r' || *s == '\n' || *s == '\0')return 1;/* Failed */return 0;}and then you can use that function:Code:if(split_string(" 3, 0, 123\n")) {printf("Success - values were %i, %i and %i\n",p1,p2,p3);} else {printf("Failed - invalid input\n");}

author: Avacee
author_rank: Unknown
timestamp: April 10, 2017, 10:05:10 am
content: Quote from: skillz21 on April 10, 2017, 03:21:26 amThere are many online resources for learning Arduino from scratch.The Arduino website itself has a whole section dedicated to learning:https://www.arduino.cc/en/Guide/HomePageOnline Educational providers such as Udemy, Lynda and PluralSight have structured courses as well as there being one-off lessons on Instructables, LadyAda, Sparkfun, etcAnd there are countless Blogs and programming sites for C and C++ on an arduino.If your inner Google-Fu fails just ask and someone will be able to point you in the right direction.Googling for coding stuff without knowing the correct keywords can be very frustrating.

author: skillz21
author_rank: Frequent Contributor
timestamp: April 10, 2017, 10:50:42 am
content: Quote from: Avacee on April 10, 2017, 10:05:10 amOh my god yes!

author: skillz21
author_rank: Frequent Contributor
timestamp: April 10, 2017, 10:58:31 am
content: Ohh-kay so I managed to get the app working. Turns out that I am much better at using App Inventor than Arduino. So, I am still facing the problem of getting the Arduino side of things working. What do you guys think is the simplest way to split a string like this: 124, 43, 86? Also, what did mariush mean by saying send one byte for each colour?

author: skillz21
author_rank: Frequent Contributor
timestamp: April 10, 2017, 11:02:11 am
content: Also, please try to include a small example so I can at least try to understand what's going on.

author: skillz21
author_rank: Frequent Contributor
timestamp: April 10, 2017, 11:38:18 am
content: This may look stupid:int redval = 0;int blueval = 0;int greenval = 0;const int redPin = A7;const int bluePin = A5;const int greenPin = A6;void setup() {Serial.begin(9600);pinMode(redPin, OUTPUT);pinMode(bluePin, OUTPUT);pinMode(greenPin, OUTPUT);}void loop() {while(Serial.available () > 0) {String red = Serial.readStringUntil(',');Serial.read();String green = Serial.readStringUntil(',');Serial.read();String blue = Serial.readStringUntil('\0');red.toInt(redval);green.toInt(greenval);blue.toInt(blueval);analogWrite(greenPin, greenval);analogWrite(bluePin, blueval);analogWrite(redPin, redval);}}I looked around on the internet and put together this code, what am I doing wrong, it gives me an error saying, "no matching function for call to 'String::toInt(int&)' " please help

author: Avacee
author_rank: Unknown
timestamp: April 10, 2017, 11:47:25 am
content: It means there's no function called String::toInt(int&) <-- the compiler is trying to find a function called "toInt" that has an "int" as a parameter - such a function doesn't exist and therefore wasn't found.The correct usage isredval = red.toInt(); <-- note no parameter is passed in the () and it returns alongvalue so you may get an overflow with the declaration of redval beinginthttps://www.arduino.cc/en/Reference/StringToInthttps://www.arduino.cc/en/Tutorial/StringToIntExample

author: skillz21
author_rank: Frequent Contributor
timestamp: April 10, 2017, 11:58:52 am
content: Quote from: Avacee on April 10, 2017, 11:47:25 amThanks so much! I looked at the tutorials, but i couldn't make sense of them.