String = Null

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

Добрый вечер, прошу подсказать.

Есть переменная типа String. В нее мы считываем данные с GSM модуля. Максимум по умолчанию задано 160 символов. Данные 160 символов не всегда заполняются полностью, может быть как 20, так и 80. 

Как задать програмно определение, что следующий байт информации пришедший с модуля пустой?

String readGSM () {
  String rdGSM="";
  byte o = 160;
  for (byte i=1; i<60; i++) {
    char currSymb = gprsSerial.read();
    if ( currSymb != "") {
      rdGSM += String(currSymb);
    } else {
         o =i-1;
      } 
  }
  return rdGSM;
}

 

Допустима ли следующая конструкция?

__Alexander
Offline
Зарегистрирован: 24.10.2012

что значит байт "пустой"?

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

__Alexander пишет:

что значит байт "пустой"?

значит нет в нем информации.

__Alexander
Offline
Зарегистрирован: 24.10.2012

таких не бывает. в байте всегда есть число из диапазона 0 - 255.

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

__Alexander пишет:

таких не бывает. в байте всегда есть число из диапазона 0 - 255.

В данном случае я читаю данные в char (смотри код). Как проверить переменную char на отсутствие данных?

 

ПыСы прошу не цепляться к словам, "байт" здесь употреблен как общее название.

__Alexander
Offline
Зарегистрирован: 24.10.2012

посмотреть что возвращает функция read по умолчанию. скорее всего ноль. тогда сравнивать надо с нулем. кстати, для работы с символами используются одинарные кавычки.

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Serial.read() возвращает -1 если нечего читать.

Зачем читать того что нет? Может проще Serial.available посмотреть.

И как Вы хотите считать 160 "символов" если у Вас цикл 60 итераций и на каждой считывается 1 "символ"

__Alexander
Offline
Зарегистрирован: 24.10.2012

думаю что available делает именно тоже самое.

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

Penni пишет:

Serial.read() возвращает -1 если нечего читать.

Зачем читать того что нет? Может проще Serial.available посмотреть.

И как Вы хотите считать 160 "символов" если у Вас цикл 60 итераций и на каждой считывается 1 "символ"

String readGSM () {
  String rdGSM="";
  byte o = 160;
  for (byte i=1; i<o; i++) {
    char currSymb = gprsSerial.read();
    if ( currSymb != "") {
      rdGSM += String(currSymb);
    } else {
         o =i-1;
      } 
  }
  return rdGSM;
}

Опечатку исправил

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Ну если Вы прям так хотите с циклами, то currSymb надо проверять не на "" а на -1. Когда -1 значит всё что было в буфере считали, читать нечего.

При этом буффер по умолчанию в HardwareSerial.cpp определен в 64 "символа", об этом надо помнить.

А когда вызывается readGSM ?

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

Penni пишет:

Ну если Вы прям так хотите с циклами, то currSymb надо проверять не на "" а на -1. Когда -1 значит всё что было в буфере считали, читать нечего.

При этом буффер по умолчанию в HardwareSerial.cpp определен в 64 "символа", об этом надо помнить.

А когда вызывается readGSM ?

В моменты считывания СМС сообщений, номеров с сим карты и времени/даты с GSM шилда.

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

Penni пишет:

При этом буффер по умолчанию в HardwareSerial.cpp определен в 64 "символа", об этом надо помнить.

т.е. смысла ставить o > 64 нет?

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Просто надо успевать буфер обрабатывать, ведь каждый вызов read() освобождает 1 байт в буфере.

Для стандартного шиелда есть же библиотека и примеры, или шиелд не стандартный?

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

Penni пишет:

Просто надо успевать буфер обрабатывать, ведь каждый вызов read() освобождает 1 байт в буфере.

Для стандартного шиелда есть же библиотека и примеры, или шиелд не стандартный?


Работаю без GSM библиотеки. Шилд стандартный.

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Ну тогда либо available и читать пока есть что читать, либо цикл как выше и можно "о" убрать, если ограничить 160 символами то просто цикл сделать до i<=160 а внутри цикла когда считанный байт -1 то break и всё

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

Penni пишет:

Ну тогда либо available и читать пока есть что читать, либо цикл как выше и можно "о" убрать, если ограничить 160 символами то просто цикл сделать до i<=160 а внутри цикла когда считанный байт -1 то break и всё


Ок. Спасибо.
Может быть еще подскажите?
Не компилирует скетчс переменной типа String в теле уиклаПеременная имеет вид String name[i], где i это byte цикла.
Как складывать стринги в цикле?

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Ну если именно String (с большой буквы) то concat либо просто str += char(Serial.read()); где str типа String.

может Вам использовать string (с маленькой буквы) по сути обычный массив символов с 0 на конце.

Объявляете string name[160] ну и читаете пока есть что читать в name[i] а дальше уже делать с полученным набором что угодно.

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

Penni пишет:

Ну если именно String (с большой буквы) то concat либо просто str += char(Serial.read()); где str типа String.

может Вам использовать string (с маленькой буквы) по сути обычный массив символов с 0 на конце.

Объявляете string name[160] ну и читаете пока есть что читать в name[i] а дальше уже делать с полученным набором что угодно.

Писал с телефона, толком что я хочу объяснить не смог. Сейчас исправлюсь.

String name [11];
String nomer [11] = "1234567890";
for ( byte i=1; i<11; i++) {
  name [i] = nomer [i] + nomer [i];
}

примитивно, как то так хочу.

 

 

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Ну насколько я понял задачу, то можно так

String name;
String nomer = "1234567890";
for (byte i=0; i<11; i++)
{
  //name += (String(nomer[i]) + String(nomer[i]));
  name += (String(nomer[i]).toInt() + String(nomer[i]).toInt());
}

после выполнения кода в name будет либо 11223344556677889900 либо 2468101214161800 в зависимости от того какая строка закоментирована

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

Penni пишет:

Ну насколько я понял задачу, то можно так

String name;
String nomer = "1234567890";
for (byte i=0; i<11; i++)
{
  //name += (String(nomer[i]) + String(nomer[i]));
  name += (String(nomer[i]).toInt() + String(nomer[i]).toInt());
}

после выполнения кода в name будет либо 11223344556677889900 либо 2468101214161800 в зависимости от того какая строка закоментирована


Ну а если у меня там не цифvasyamasha и masha?

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Если там masha то раскоментируем 5 строку закоментируем 6 и на выходе получим mmaasshhaa. Вы ж сами писали nomer [i] + nomer [i];

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

Не компилирует такой скетч, вот в чем проблема.

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

То что я писал выше компилируется, скопировано с ардуинки которая на столе лежит у меня.

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

Penni пишет:

То что я писал выше компилируется, скопировано с ардуинки которая на столе лежит у меня.

Ок. Тогда что здесь не так?

void loadnumber () {
  String writeSMS = String ("Phone book." )+ String ("\n");
  gprsSerial.flush ();
  String x [10]; // сюда пишем номера
  String z [10]; // сюда пишем имена
  for (byte i = 1; i < 11; i++) {
    gprsSerial.println("AT+CPBR=" + String(i, DEC));
    delay (300);
    String p = readGSM ();
    x [i] = p.substring (23, 35);
    z [i] = p.substring (42, 58);
    writeSMS = x[i] + String ("\n") + z[i] + String ("\n");
    p="";
  }
  Serial.println (writeSMS);
  sendSMS ();
}

не компелируется, и выдает ошибку именно на строке: writeSMS = x[i] + String ("\n") + z[i] + String ("\n");

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Потому что нельзя так обяъвлять String и нельзя так его складывать х[i] это один "символ" строки, один байт, а Вы пытаетесь ему присвоить строку из "кучи символов". Естественно работать не будет.

В 4 и 5 строке уберите [10] В 10 и 11 строке уберите [i] В 12 строке так же уберите [i] и всё заработает при условии, что readGSM правильно написана.

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

Penni пишет:

Потому что нельзя так обяъвлять String и нельзя так его складывать х[i] это один "символ" строки, один байт, а Вы пытаетесь ему присвоить строку из "кучи символов". Естественно работать не будет.

В 4 и 5 строке уберите [10] В 10 и 11 строке уберите [i] В 12 строке так же уберите [i] и всё заработает при условии, что readGSM правильно написана.

Но таким образом я не получу в writeSMS список из 10 номеров и 10 имен соответствующих им.

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Вы получите строку вида имя-телефон и если это выведите в терминал или куда-то еще то строки будут разделены \n и вы увидите это как

имя1-телефон1
имя2-телефон2
имя3-телефон3

Если Вам надо именно массив то и надо объявлять массив вида char* для удобства работы. Всё зависит от того что дальше с этим списком делать

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

Penni пишет:

Вы получите строку вида имя-телефон и если это выведите в терминал или куда-то еще то строки будут разделены \n и вы увидите это как

имя1-телефон1 имя2-телефон2 имя3-телефон3

Если Вам надо именно массив то и надо объявлять массив вида char* для удобства работы. Всё зависит от того что дальше с этим списком делать

Дальше этот список отправить SMS сообщением.

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

Список СМС передать удалось.

Может еще раз поможете?

Нужна AT команда для удаления номеров с SIM карты.

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Вот такого я не знаю... Можно конечно попробовать AT+CPBW указав номер записи и пустые параметры :) но это так предположение.

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

Penni пишет:
Вот такого я не знаю... Можно конечно попробовать AT+CPBW указав номер записи и пустые параметры :) но это так предположение.

Нашел: AT+CPBW= 3

Примечание: стереть ячейку 3