Extract last numbers of line in serial monitor

Hi,
How do I extract the last 3 numbers of a line in the serial monitor and make them a separate int.
This is an example of a line im talking about: Servo1 168Servo1 170Servo1 171Servo1 180Servo1 195Servo1 207, and I only want the last 3 numbers of it.
I would really appreciate if someone could help me with this problem.

Do you mean last three digits - "207" ?

int i = atoi(&text[strlen(text)-3]);

Untested, will only work for this #of digits and needs safety checks, but that should do it.

That line needs to save the text in a string, and that the number is the last thing in it. I have a different solution

char digits[3]={0,0,0};
byte i;
int nunber;
while (Serial.available())
{
if (isDigit(Seria.peek()))
{
if (i>2)
{
digits[0]=digits[1];
digits[1]=digits[2];
digits [2]=Serial.read();
//all the number is switched 1 back, because I have the new last digit
}
else
if (i==0)
digits [0]=digits [1]=digits [2]=0;
//all the number became 0, because it is restarted
digits [i++]=Serial.read();
}
else
{
i=0;
Serial.read();
}
}
number=atoi (digits);

The first question would be where that line comes from?

Did you type it in serial monitor and send it to arduino? In that case, reply #2 would be appropriate. I however would change the format so it's easier to parse; have a look at the updated serial input basics thread to get ideas.
2)
Or is the line generated by the arduino and send to the serial monitor? In that case, you know how the data is generated and you can simply save that part to a variable for later use.

This is my code:
#include <Servo.h>
int servo1PPos;
String fromAndroid = “”;
Servo servo1;
int servo1Pos;

void setup() {

Serial.begin(9600);
Serial.println(“Program Start…”);
servo1.attach(5);
}

void loop() {
if (Serial.available() > 0) {
fromAndroid = Serial.readString();

if (fromAndroid.startsWith("Servo1 ")) {
String fromAndroidS = fromAndroid.substring(2, fromAndroid.length());
servo1Pos = fromAndroid.toInt();
for ( int j = servo1PPos; j >= servo1Pos; j–) { // Run servo down
Serial.println(fromAndroid);
delay(20);
}
}

}
}

I have a slider on the mit app inventor and I want to spin the servo with the slider on my phone, but it sends the state of the slider after you stop touching the slider on your screen. So all the numbers you went past add up in long line. But I need it to send every number the slider went past separately.
I added a screenshot of the app inventor program.
Btw thanks for helping me out with this. :slight_smile:

So you want every number? Not justvthe last one?

It would be best to get every number but only the last number works too.

If you don’t know tje number of numbers is hard to get everyone. Is there a max number of numbers?

yeah its from 105 to 275

Not the max number, but the number of numbers. In a single line can they be (example) 4 or less (105, 201, 140, 167 or 106, 107, 200 or whatever) or they can be a random number (like max 100 numbers)
I ask you this because a way to have all the numbers is store than in a array of int, but it needs a size

I dont think theres a max amount of numbers it just shows you all the numbers you went past on the sliders on your phone.

Ok. But you tried it for some times, how many numbers are in the line, mediumly?

I gues 10

Isn't there just a way to get the last three numbers/characters of the string? Always the last 3 no matter how long it is.

Looking at your app inventor diagram, you join a text and a number. Looking at your text, you always have a fixed width. in that case you can make use of the fixed width by only reading 10 characters (ServoX nnn).

Disclaimer: I’ve never used MIT app inventor.
Will it be possible to add a newline character in the join after the number; something like

join | *Servo1 * |
     | round | get thumbposition |
     | *"\n"* |

No idea what it will actually look like. In that case, you can read up till the ‘\n’; see the earlier link that I posted, the example with endmarker

In both situations, you can split the text by looking for the space.

Below demo code for a fixed width text; make sure it’s always ServoXnnn

const uint8_t msgLength = 10;
char fromAndroid[msgLength + 1];
void setup()
{
  Serial.begin(9600);
  Serial.println("Program Start..");
}

void loop()
{
  // count number of received characters
  static uint16_t charCounter = 0;
  // when character was received
  static uint32_t startTime;

  // if nothing received
  if (charCounter == 0)
  {
    // clear the fromAndroid text
    memset(fromAndroid, 0, sizeof(fromAndroid));
  }

  // if something received
  if (Serial.available() > 0)
  {
    // read the character and stor in fromAndroid
    fromAndroid[charCounter] = Serial.read();
    // point to next position for next character
    charCounter++;
    // 'reset' the startTime
    startTime = millis();
  }

  // check timeout
  if (charCounter != 0 && millis() - startTime >= 1000)
  {
    // time out
    // reset counter
    charCounter = 0;
    // nothing else to do
    return;

  }

  // not completed yet; requires 10 characters
  if (charCounter < msgLength)
  {
    return;
  }

  // find the space
  char *ptr = strchr(fromAndroid, ' ');
  // space not found
  if (ptr == NULL)
  {
    // data does not contain a space
    // retry
    charCounter = 0;
    return;
  }

  // replace space by terminating null;
  *ptr = '\0';
  // buffer to store servo text
  char servo[10];
  // copy servo text
  strcpy(servo, fromAndroid);

  // point to the digits for the servo
  ptr++;
  int servoPos = atoi(ptr);

  Serial.print(servo);
  Serial.print(" to ");
  Serial.println(servoPos);

  // next time, fill fromAndroid from the start
  charCounter = 0;
}

I leave the further implementation to you.

Output for your input from the opening post

Servo1 to 168
Servo1 to 170
Servo1 to 171
Servo1 to 180
Servo1 to 195
Servo1 to 207

Do you mean like this?

As said, I've never used app inventor. So no idea if it's correct and/or if it does what you think it does?

It works but only if you touch the slider on the app and release it at the same spot. Other wise this happens.

OK, that does not work because it's the app inventor that puts the double quotes in.

And it will not work with the code that I presented.