не работает toLowerCase

fusic
Offline
Зарегистрирован: 08.02.2017
Доброго дня!
связал ардуино мега с компом.
ардуина должна выполнять команды типа запись в PWM, чтение портов и т.д.
Передаю команду в виде строки, ардуино разбирает её на команду (cmd) и параметр\аргумент (prmStr)
В процессе рабора использую cmd.toLowerCase();
для отладки передаю выделенную команду обратно в комп.
Проблема в том что не все  буквы переводятся в нижний регистр.
Например строка QWERTYUIOPASDFGHJKLZXCVBNM после перевода в нижний регистр
вернётся строкой qwertYUioPASDfGHjKlZxcVBNM
В чем проблема, куда копать ?
Но это ещё не всё!
Выделяю из строки параметр (он заключен в квадратные скобки) и перевожу его в целое число prm
int prm = prmStr.toInt(); 
Эта функция то же воспринимает не все цифры
воспринимает 1, 2, ...
не воспринимает 0, 3, ...
поэтопу получаю не правильный параметр
например передаю PWM1[2202]
должен получить pwm1 и 2202
реально получаю PwM1 и 22 (доходит до первой 'невоспринимаемой цифры' и дпльше обрезает)
 
вот полный код\
 
 
 
String inStr = "";
void setup() {
  Serial.begin(9600);
  while (!Serial); // wait for serial port to connect. Needed for native USB port onl
}
void loop() {
  while (Serial.available()) {
    char inChar = Serial.read();
     if (inChar == '@')
     {
       int cmdEnd = inStr.indexOf('[');
       if (cmdEnd != -1) {
         Serial.println(cmdEnd);
         String cmd = inStr.substring(0,cmdEnd);
         cmd.toLowerCase();   
         Serial.print("Command: ");
         Serial.println(cmd);
       } else
         {
            Serial.println("ERROR");
            break;
         }
         
       int prmEnd = inStr.indexOf(']');
       if (prmEnd != -1) {
         Serial.println(prmEnd);
         String prmStr = inStr.substring(cmdEnd+1,prmEnd);
         int prm = prmStr.toInt();
         Serial.print("Param: ");
         Serial.println(prm);
       } else
         {
            Serial.println("ERROR");
            break;
         }
       
       inStr = "";
       break;
     } else
          {if (inChar != ' ')
            {
              inStr += inChar;
            }
          }
    }
}
 
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015
fusic
Offline
Зарегистрирован: 08.02.2017

поможет моей проблеме ?

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

fusic пишет:

поможет моей проблеме ?

Без нормальной вставки кода с нумерацией строк, его даже смотреть никто не будет.

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

Jeka_M пишет:

fusic пишет:

поможет моей проблеме ?

Без нормальной вставки кода с нумерацией строк, его даже смотреть никто не будет.

+1

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

fusic пишет:

поможет моей проблеме ?

Да, конечно. По двум причинам:

1) код в таком виде большинство людей смотреть просто не будут

2) даже те, кто будут, вынуждены будут писать Вам тексты типа "ошибка у Вас в строке № ХЗ".

Так что не надо стёба, просто уважайте правила форума.

fusic
Offline
Зарегистрирован: 08.02.2017

приношу свои извинения

 

String inStr = "";
void setup() {
  Serial.begin(9600);
  while (!Serial); // wait for serial port to connect. Needed for native USB port onl
}
void loop() {
  while (Serial.available()) {
    char inChar = Serial.read();
     if (inChar == '@')
     {
       int cmdEnd = inStr.indexOf('[');
       if (cmdEnd != -1) {
         Serial.println(cmdEnd);
         String cmd = inStr.substring(0,cmdEnd);
         cmd.toLowerCase();   
         Serial.print("Command: ");
         Serial.println(cmd);
       } else
         {
            Serial.println("ERROR");
            break;
         }
         
       int prmEnd = inStr.indexOf(']');
       if (prmEnd != -1) {
         Serial.println(prmEnd);
         String prmStr = inStr.substring(cmdEnd+1,prmEnd);
         int prm = prmStr.toInt();
         Serial.print("Param: ");
         Serial.println(prm);
       } else
         {
            Serial.println("ERROR");
            break;
         }
       
       inStr = "";
       break;
     } else
          {if (inChar != ' ')
            {
              inStr += inChar;
            }
          }
    }
}

 

fusic
Offline
Зарегистрирован: 08.02.2017

да...прога на компе в Delphi 7

за основу взял SimplePacket из демоса nrComm_Lib_Pro_v.9.27

 

AlexeySh
Offline
Зарегистрирован: 16.01.2017

Какая версия среды разработки Ардуино? Пробовали обновить до последней версии?

fusic
Offline
Зарегистрирован: 08.02.2017

версия думаю свежая так как устанавливал её месяц назад (когда взял в руки ардуинку) с этого же сайта (вроде)

выяснилось что если подавать команды не из дельфи-проги а из монитора порта то всё работает замечательно

и ещё один момент: даже если изначально передать в ардуино команду в нижнем регистре, например pwm1[134], ив процессе обработки переменная cmd примет значение "pwm1" то строка

if (cmd=="pwm1") {Serial.prontln("PWM1 OK")};

не трушная, не работает ... визуально строки одинаковые .... а в результате сравнения сообщения "PWM1 OK" нет

может с кодировками что то напутано (со стороны дельфи-проги) ?

AlexeySh
Offline
Зарегистрирован: 16.01.2017

Да, по видимому проблема с кодировкой у дельфи-проги. Но это похоже уж очень старинная дельфи-прога.

Идем дальше. inStr, куда вы собираете байты с порта. Где она сбрасывается в пустую строку? По вашей программе она все время удлиняется и после первой команды там будет уже их несколько. И вы думаете что после этого cmd будет содержать только одну команду?

Сорри. Не заметил, есть сброс строки.

А если убрать toLowerCase(), то условие выполняется?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

fusic пишет:

даже если изначально передать в ардуино команду в нижнем регистре, например pwm1[134], ив процессе обработки переменная cmd примет значение "pwm1" то строка

if (cmd=="pwm1") {Serial.prontln("PWM1 OK")};

не трушная, не работает ... визуально строки одинаковые .... а в результате сравнения сообщения "PWM1 OK" нет

И не будет. Строки так не сравниваются. Это сранвнение будет истинным только в том случает, если это одна и таже строка. Не одинаковые строки, а именно одна и та же.

AlexeySh
Offline
Зарегистрирован: 16.01.2017

ЕвгенийП пишет:

fusic пишет:

даже если изначально передать в ардуино команду в нижнем регистре, например pwm1[134], ив процессе обработки переменная cmd примет значение "pwm1" то строка

if (cmd=="pwm1") {Serial.prontln("PWM1 OK")};

не трушная, не работает ... визуально строки одинаковые .... а в результате сравнения сообщения "PWM1 OK" нет

И не будет. Строки так не сравниваются. Это сранвнение будет истинным только в том случает, если это одна и таже строка. Не одинаковые строки, а именно одна и та же.

Кто вам такое сказал? Писал программу управления станком с шаговыми двигателями. Весь разбор команд так написан. Все работает.

Вы наверное путаете объект String с указателями на строки. Во втором случае не будет работать. Но ТС пока о них знать не обязательно.

fusic
Offline
Зарегистрирован: 08.02.2017

если убрать toLowerCase то условие всё равно НЕ выполняется

fusic
Offline
Зарегистрирован: 08.02.2017

хотел было отказаться от символьных команд заменив их числами (хотя символьные команды были бы удобнее при написании управляющей  дельфи-проги) НО половина цифр тоже не воспринимаются

int prm = prmStr.toInt();

"220" превращается в целое 22 (0 не воспринимается)

"252" превращается в целое 2 (после невоспринимаемой цифры всё обрезается)

природа этой ошибки\проблемы одна

1. подскажите какая кодировка в ардуино иде (может не корректно вопрос ставлю ... ну как могу) ?

2. кодировка в дельфи-проге зависит от кодировки ОС (виндовз) ?

AlexeySh
Offline
Зарегистрирован: 16.01.2017

Вы сначала настройте без проги через порт. А потом уже с ней разбирайтесь.

По дельфи ничего подсказать не могу. Давно уже перешел на Microsoft Visual Studio C#, чего и вам советую. Будет проще с Ардуино, так как основа обоих одинакова - С / С++.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

AlexeySh пишет:

fusic пишет:

if (cmd=="pwm1") {Serial.prontln("PWM1 OK")};

Вы наверное путаете объект String с указателями на строки. 

Не только не путаю, а наоборот был уверен, что это именно указатель. В любом случае, это проблема ТС. Хочет получить ответ, пусть учится задавать вопрос - в скетче, приведённом ТС, никакого cmd нет вовсе, так что какой там у него тип не знает никто. Результат закономерен - вместо помощи ТС получает пачку неинформативных сообщений.

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

ЕвгенийП пишет:

AlexeySh пишет:

fusic пишет:

if (cmd=="pwm1") {Serial.prontln("PWM1 OK")};

Вы наверное путаете объект String с указателями на строки. 

Не только не путаю, а наоборот был уверен, что это именно указатель. В любом случае, это проблема ТС. Хочет получить ответ, пусть учится задавать вопрос - в скетче, приведённом ТС, никакого cmd нет вовсе, так что какой там у него тип не знает никто. Результат закономерен - вместо помощи ТС получает пачку неинформативных сообщений.

как нет, пост #6, строка 14.

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

неужели нельзя выполнить простейшик код

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

  String s = "QWERTYUIOPASDFGHJKLZXCVBNM";
  Serial.println(s);  
  s.toLowerCase();
  Serial.println(s);  
  
}

void loop() {
}

и понять что IDE  тут не причем, Delphi видимо вам строку в юникоде передает.

 

fusic
Offline
Зарегистрирован: 08.02.2017

cmd

строки 11...17

fusic
Offline
Зарегистрирован: 08.02.2017

такой код выполняется ПРАВИЛЬНО

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

  String s = "QWERTYUIOPASDFGHJKLZXCVBNM";
  Serial.println(s);  
  s.toLowerCase();
  Serial.println(s);  
  
}

void loop() {
}

 

fusic
Offline
Зарегистрирован: 08.02.2017

качнул другой компонент, BComPort и ...... вуаля

всё как по писанию

toLowerCase работает правильно

цифры все воспринимаются и не исчезают

fusic
Offline
Зарегистрирован: 08.02.2017

вариант на данный момент




String inStr = "";
int index = -1;
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(9600);
  Serial.setTimeout(1000);
  while (!Serial); // wait for serial port to connect. Needed for native USB port onl
}
void loop() {
  while (Serial.available()) {
    String inStr = Serial.readStringUntil('@');
    do {
      index = inStr.indexOf(" ");
      //Serial.print("index =  ");
      //Serial.println(index);
      inStr.remove(index,1);
    } while (index != -1);
    int pos1 = inStr.indexOf('[');
    //Serial.println(pos1);
    int pos2 = inStr.indexOf(']');
    //Serial.println(pos2);
    String cmd = inStr.substring(0, pos1);
    cmd.toLowerCase();
    //Serial.println("-------------------------------------------");
    //Serial.print("Command: ");
    Serial.println(cmd);
    String prmStr = inStr.substring(pos1 + 1, pos2);
    int prm = prmStr.toInt();
    //Serial.print("Param: ");
    Serial.println(prm);
    analogWrite(LED_BUILTIN, prm);
    inStr = "";

    if (cmd == "pwm1") {
      Serial.println("PWM1 command ok");
    }
    if (prm==22) {
      Serial.println("PRM=22");
    }
    
    switch (prm) {
      case 2: Serial.println("CASE 2"); break;
      case 22: Serial.println("CASE 22"); break;
      case 220: Serial.println("CASE 220"); break;
    }
  }

}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

xDriver пишет:

как нет, пост #6, строка 14.

Виноват - не заметил :(