چگونه بخش مختلف یک string ارسال شده از سریال را جدا کنم؟

3 سال قبل
2007 بازدید

1

سلام. من لیست موقعیت چند سروو رو از طریق سریال به آردوینو ارسال می کنم. با این فرمت:

1:90&2:80&3:180

که این الگو را دارد:

servoId : Position & servoId : Position & servoId : Position

سوال من این هست که چطور این مقادیر رو از هم جدا کنم و به integer تبدیل کنم؟

ممنون

29 آذر 00 در 08:10
askhorshid
13

افزودن دیدگاه

3 پاسخ ثبت شده است
0

سلام

با توجه نمونه کد شما

String value1 = splitter("1:90&2:80&3:180",'&',0);//output is 1:90 as String
String value2 = splitter("1:90&2:80&3:180",'&',1);//output is 2:80 as String
String value3 = splitter("1:90&2:80&3:180",'&',2);//output is 3:180 as String

int servo1 = value1.substring(2,value1.length()).toInt();//output is 90 as int
int servo2 = value2.substring(2,value2.length()).toInt();//output is 80 as int
int servo3 = value3.substring(2,value3.length()).toInt();//output is 180 as int

String splitter(String value, char splitChar, byte selection)
{
  value.trim();
  byte position[5] = {0, 0, 0, 0, value.length()};//if need more split add to this array
  byte j = 1;
  for (byte i = 0; i < value.length(); i++)
  {
    if (value.charAt(i) == Slipt_char)
    {
      position[j] = i+1;
      j++;
    }
  }
  return value.substring(position[selection], position[selection + 1]-1);
}

اطلاعات بیشتر در ریپو زیر

https://github.com/DMohammed/Arduino-String-splitter

29 آذر 00 در 10:12
محمد دمیرچی
4220

افزودن دیدگاه

2

برخلاف بسیار از افراد که از String استفاده می کنند (مثل جواب آقای دمیرچی)، من تا حد امکان از String دوری می کنم. به دو علت:

  • استفاده از حافظه داینامیک (Dynamic Memory) که می تواند منجر به پر شدن سریع حافظه شود
  • سرعت نسبتا کم آن

در میکروکنترلرهایی مثل آردوینو حتی آردوینو مگا، بدلیل کم بودن حافظه ترجیح من به استفاده از توابع استاندارد C هست:

  • strchr(): یک کاراکتر را در string پیدا می کند.
  • strtok(): یک string را بر اساس کارکاتر جدا کننده به چند رشته دیگر تبدیل می کند
  • atoi(): یک string را به int تبدیل می کند.

با استفاده از این توابع، به کد زیر میرسیم:

// Calculate based on max input size expected for one command
#define INPUT_SIZE 30
...

// Get next command from Serial (add 1 for final 0)
char input[INPUT_SIZE + 1];
byte size = Serial.readBytes(input, INPUT_SIZE);
// Add the final 0 to end the C string
input[size] = 0;

// Read each command pair 
char* command = strtok(input, "&");
while (command != 0)
{
    // Split the command in two values
    char* separator = strchr(command, ':');
    if (separator != 0)
    {
        // Actually split the string in 2: replace ':' with 0
        *separator = 0;
        int servoId = atoi(command);
        ++separator;
        int position = atoi(separator);

        // Do something with servoId and position
    }
    // Find the next command in input string
    command = strtok(0, "&");
}

مزیت این روش این است که هیچ dynamic memory allocation اتفاق نمی افتد. حتی می توانید input را هم در خود تابع بصورت یک متغیر لوکال تعریف کنید. پس از اینکه اجرای تابع تمام شد، فضای اشغال شده توسط input هم آزاد می شود.

29 آذر 00 در 11:25
asmzxak
81

افزودن دیدگاه

1

برای کار کردن با stringها، انواع توابع در آردوینو در نظر گرفته شده که کار با رشته هارو بسیار ساده میکنه.

فرض کنید یک رشته به صورت زیر تعریف کرده ایم:

String message;

از پر کاربردترین این تابع ها برای کار با این رشته میشه به موارد زیر اشاره کرد:

()trim: با استفاده از این تابع، message به اصطلاح هرس شده و n/ از ابتدا و انتهای آن حذف میشود و تنها خود متن اصلی رشته باقی می ماند. استفاده از این تابع به این صورته:

message.trim()

indexOf(const String): در این تابع یک کاراکتر و یا یک رشته به عنوان ورودی داده و ایندکس اون کاراکتر در اون رشته رو به عنوان یک integer برمیگردونه. استفاده از این تابع به این صورته:

x = message.indexOf("y")

با این خط کد، وجود حرف y در رشته message بررسی شده و در صورت وجود، ایندکس اون در متغیر x که یک integer هست، قرار میگیره. دقت کنید که در این حالت اگر بیش از یک y در رشته وجود داشته باشه، ایندکس اولین y، در x قرار میگیره.

lastIndexOf(const String): این تابع مشابه تابع بالا عمل میکنه و تنها فرقش اینه در صورت وجود کاراکتر مورد نظر ما، ایندکس آخرین کاراکتر مورد نظر ما برگردونده میشه. استفاده از این تابع به این صورته:

x = message.lastIndexOf("y")

()length: با استفاده از این تابع میتونید طول رشته رو بدست بیارید. استفاده از این تابع به این صورته:

message.length()

remove(unsigned int startIndex, unsigned int endIndex): این تابع دو integer به عنوان ورودی میگیره و از ایندکس startIndex تا ایندکس endIndex رو از رشته مورد نظر ما حذف میکنه. استفاده از این تابع به این شکله:

message.remove(a,b)

در این صورت از message به اندازه a حذف میشه.

startsWith(const String): این تابع بررسی میکنه که آیا message با یک رشته خاص شروع میشه یا خیر. خروجی این تابع true و یا false هست. استفاده از این تابع در یک مثال به این صورته:

message.startsWith("Hello")

با این خط کد، اینکه رشته message با Hello شروع میشه و یا خیر بررسی میشه.

substring(unsigned int startIndex, unsigned int endIndex): این تابع تقریبا مهم ترین تابعی هست که شما میتونید در کارتون استفاده کنید و با اون اطلاعات رو از دل یک رشته بیرون بکشید. این تابع دو integer مثل startIndex و endIndex به عنوان ورودی میگیره و از کاراکتر ایندکس startIndex تا کاراکتر ایندکس endIndex رشته رو به عنوان یک رشته جدید بهتون برمیگردونه. مثلا:

x = message.substring(3,5)

این خط کد از کاراکتر 3 تا کاراکتر 5 رشته message رو به عنوان یک رشته جدید در x ذخیره میکنه.

()toCharArray: این تابع رشته message رو به آرایه ای از کاراکترها تبدیل میکنه. مثلا:

x = message.toCharArray()

()toDouble: با استفاده از این تابع، میتونید یک عدد که در واقع به شکل رشته نوشته شده رو به شکل double دربیارید. مثلا:

x = message.toDouble()

در این صورت اگر message برابر با "5.34" بوده باشه، x برابر با 5.34 میشه.

()toFloat: این تابع هم مشابه تابع قبل عمل میکنه و تنها فرقش اینه که عدد نوشته شده در رشته رو به فرمت float در میاره. استفاده از این تابع هم به این صورت هست:

x = message.toDouble()

()toInt: این تابع هم شبیه دو تابع قبل عمل میکنه و این بار عددی که به شکل رشته نوشته شده به فرمت int در میاد. از این تابع میتونید به این صورت استفاده کنید:

x = message.toInt()

()toLowerCase: با استفاده از این تابع، تمامی حروفی که در رشته وجود داره به صورت lowerCase در میاد. استفاده از این تابع به این شکله:

message.toLowerCase()

با این کد، برای مثال اگر رشته message به صورت "aBcD" بوده باشه، به صورت "abcd" در میاد.

()toUpperCase: این تابع هم در واقع برعکس تابع بالا عمل میکنه. با استفاده از این تابع، تمامی حروفی که در رشته وجود داره به صورت upperCase در میاد. استفاده از این تابع به این شکله:

message.toUpperCase()

با این کد، برای مثال اگر رشته message به صورت "aBcD" بوده باشه، به صورت "ABCD" در میاد.

 

این تقریبا تمام توابعیه که میتونید برای کار کردن با String ها ازشون استفاده کنید. با ترکیب توابع بالا به سادگی میشه اطلاعات مورد نیازتون رو از Stringتون استخراج کرد. مثلا میتونید از کد زیر استفاده کنید:

void setup() {
  Serial.begin(9600);

  int position1, position2, position3;
  String message;
  message = "1:90&2:80&3:180";

  message.trim();
  
  position1 = (message.substring(message.indexOf(":")+1, message.indexOf("&"))).toInt();
  Serial.println(position1);
  
  message.remove(0,message.indexOf("&")+1);
  
  position2 = (message.substring(message.indexOf(":")+1, message.indexOf("&"))).toInt();
  Serial.println(position2);
  
  message.remove(0,message.indexOf("&")+1);

  position3 = (message.substring(message.indexOf(":")+1, message.length())).toInt();
  Serial.println(position3);
}

void loop() {
}
29 آذر 00 در 12:18
مهران ملکی
60

افزودن دیدگاه


انجمن کافه‌ربات © 1400