как работать с массивами?

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

Здравствуйте, перечитал кучу информации, как работать с массивами, но не могу никак разобраться, сможет кт о нибудь объяснить на прмере?

я допустим хочу сделать следующее:

засунуть в массив последовательно приходящие числа, их 24, 0-ей и 1-иц, приходят они с RC приемника 433Mhz

и потом считать их что бы зажечь светодиод, мне накидывали уже примеры, и готовые коды, но как работает это понять не могу.

допустим отдельные 0 и 1 приходящие через какое то время записать в переменную(но именно работая с массивом) и на выходе получить допустим переменную code_read = 111111111111111111111111

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

unsigned long или что-то еще 4х байтовое и сдвиг влево при приеме. В итоге сразу будет переменная с нужными битами, потом либо сразу в порт либо побитово смотреть и зажигать светодиоды.

xoyushka
Offline
Зарегистрирован: 02.10.2017
void mig_znach() {
  for (int i = 0; i < 9; i++) {
    leds[i] = dataFromPort[i] - '0';
  }

  for (int i = 0; i < 9; i++) {
    leds[i] = dataFromPort[i] - '0';

  }

 

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

xoyushka, это что у Вас такое написано?

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

Penni пишет:

unsigned long или что-то еще 4х байтовое и сдвиг влево при приеме. В итоге сразу будет переменная с нужными битами, потом либо сразу в порт либо побитово смотреть и зажигать светодиоды.

да так разобрался, но хочу разобраться и с массивами

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

Массив это просто кусок памяти. Можно складывать все в массив, а потом переменной unsigned long переопределить адрес, указав начало массива и тогда этот кусок памяти будет уже восприниматься как unsigned long.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

d13lider пишет:
да так разобрался, но хочу разобраться и с массивами

А вы что такое переменная разобрались? . Так массив это и есть переменная, а точнее группа одинаковых переменных отличающихся  индексом в [] . И да для Си массивы используются редко. Есть более развитые системы для хранения информации.

b707
Offline
Зарегистрирован: 26.05.2017

qwone пишет:

 И да для Си массивы используются редко. Есть более развитые системы для хранения информации.

смелое замечание. Это какие же "развитые системы" имеются в виду?

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

в общем пробемма записать в массив все и потом прочитать из него. переменная да разобрался

qwone пишет:

Так массив это и есть переменная, а точнее группа одинаковых переменных отличающихся  индексом в [] . 

а так еще больше запутали... я что то уже вообще перестал понимать что такое массив, думал это как по типу с EEPROM записал символ под таким то индаксом, только не используя ЕЕПРОМ, я близко уже? или вообще не в ту степь полез?

b707
Offline
Зарегистрирован: 26.05.2017

d13lider пишет:

а так еще больше запутали... я что то уже вообще перестал понимать что такое массив, думал это как по типу с EEPROM записал символ под таким то индаксом, только не используя ЕЕПРОМ, я близко уже? или вообще не в ту степь полез?

Ну смотря какие выводы вы сделаете из "похожести" массивов и епром. В чем-то похожи, в чем-то нет.

Главная суть массива - то что это цепочка одинаковых по смыслу переменных, которые можно перебирать в цикле.

Например, положим у вас пять светодиодов и вы хотите их зажечь.

Можно каждому присвоить имя led1 led2 led3 led4 и led5( печатать устал. а ведь их всего пять) Тогда код для зажигания будет

const byte led1 = 4;
const byte led2 = 7;
const byte led3 = 9;
const byte led4 = 11;
const byte led5 = 13;
digitalWrite(led1, HIGH);
digitalWrite(led2, HIGH);
digitalWrite(led3, HIGH);
digitalWrite(led4, HIGH);
digitalWrite(led5, HIGH);

Длинно , правда? Пока у вас отдельные переменные - нет другого способа, кроме как повторять одну и ту же строчку снова и снова. Если вы запишете их массив, можно будет сделать проще:

const byte leds[5] = {4,7,9,11,13};
for (int i=0; i<5; i++) {
  digitalWrite(leds[i], HIGH);
}

Заметно короче? А если переменных 20?

 

 

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

b707 пишет:

 

Ну смотря какие выводы вы сделаете из "похожести" массивов и епром. В чем-то похожи, в чем-то нет.

Главная суть массива - то что это цепочка одинаковых по смыслу переменных, которые можно перебирать в цикле.

Например, положим у вас пять светодиодов и вы хотите их зажечь.

Можно каждому присвоить имя led1 led2 led3 led4 и led5( печатать устал. а ведь их всего пять) Тогда код для зажигания будет

const byte led1 = 4;
const byte led2 = 7;
const byte led3 = 9;
const byte led4 = 11;
const byte led5 = 13;
digitalWrite(led1, HIGH);
digitalWrite(led2, HIGH);
digitalWrite(led3, HIGH);
digitalWrite(led4, HIGH);
digitalWrite(led5, HIGH);

Длинно , правда? Пока у вас отдельные переменные - нет другого способа, кроме как повторять одну и ту же строчку снова и снова. Если вы запишете их массив, можно будет сделать проще:

const byte leds[5] = {4,7,9,11,13};
for (int i=0; i<5; i++) {
  digitalWrite(leds[i], HIGH);
}

Заметно короче? А если переменных 20?

 

 

наконец то я это понял, спасибо огромное, а можно вместо {4,7,9,11,13} записать туда данные с EEPROM? допустим я сделал пермененную 

for (byte i = 0; i < 12; i++) //Чтение Разрешонного номера из EEPROM
      {
        data = EEPROM.read(i);
        nomber_Phone += data;
      }
      Serial.println(nomber_Phone);
      return;

переменная типа string и содержит строку "+70123456789"

вторая nomber_Phone1 содержит уже другой номер,

и возможно будет это объяваить одной строкой в массиве? что бы в итоге у меня получилось 

 {+70123456789,+7987654321,.....,.....,.....};
sadman41
Offline
Зарегистрирован: 19.10.2016

b707 пишет:

qwone пишет:

 И да для Си массивы используются редко. Есть более развитые системы для хранения информации.

смелое замечание. Это какие же "развитые системы" имеются в виду?

Судя по тому, что квон давно уже залип на классах в частности и абстракциях в целом, можно предположить, что это структуры и связные списки. А их уж можно так в классах обвалять, что мама не горюй.

b707
Offline
Зарегистрирован: 26.05.2017

sadman41 пишет:

Судя по тому, что квон давно уже залип на классах в частности и абстракциях в целом, можно предположить, что это структуры и связные списки. А их уж можно так в классах обвалять, что мама не горюй.

Заметьте - он пишет про Си, а не С++... Так что классы отпадают.

А что касается структур... а уж тем более связанных списков... - пусть откроет любой Си-код из какого-нить серьезного проекта и сравнит частоту использования массивов и списков, к примеру :)

b707
Offline
Зарегистрирован: 26.05.2017

d13lider пишет:

переменная типа string и содержит строку "+70123456789"

вторая nomber_Phone1 содержит уже другой номер,

и возможно будет это объяваить одной строкой в массиве? что бы в итоге у меня получилось

Если рассмотреть это только как пример - то можно. Создайте массив String Phones[]   и замените обращение к number_Phone на Phones с индексом.

Почему "только как пример" - потому что вообще использование переменных типа String в ардуине крайне не рекомендуется из-за очень неэффективного расходования памяти. А уж массив String - это верный способ получить проблемы с сколько-нибудь серьезном скетче.

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

b707 пишет:

Если рассмотреть это только как пример - то можно. Создайте массив String Phones[]   и замените обращение к number_Phone на Phones с индексом.

Почему "только как пример" - потому что вообще использование переменных типа String в ардуине крайне не рекомендуется из-за очень неэффективного расходования памяти. А уж массив String - это верный способ получить проблемы с сколько-нибудь серьезном скетче.

а как мне тогда лучше прочитать номер? если в последовательный порт приходит сообщение типа +CMT +70123456879

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

b707 пишет:
смелое замечание. Это какие же "развитые системы" имеются в виду?
  стеки очереди списки и прочее.

d13lider.  У каждой переменной есть формат. (Это тот слон который почему-то в упор новички не видят). Есть встроенные форматы - char, int, long.  Но можно сделать новые через структуры и классы. Что дают программистам формат. Это сколько байт переменая занимает и как ее прочитать.  Массив это то же место для переменой размещеное в памяти. Но для этого надо объвить эту переменную(массив) ,  то есть выделить место. А дальше адресс вычисляется по адресу начала+размер переменной* индекс переменной. Но в Си нельзя поменять размер массива. Вот по этой причине идут другими путями.

b707
Offline
Зарегистрирован: 26.05.2017

Это лучше делать через символьные массивы. Но, наверно, вам все же будет легче для начала освоится с массивами типа String. Боюсь, что двойную абстракцию (массив массивов) вы пока не осилите. Ну или я просто не сумею понятно обьяснить. Может кто другой. более сильный педагогическим талантом :)

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

b707 пишет:

Это лучше делать через символьные массивы. Но, наверно, вам все же будет легче для начала освоится с массивами типа String. Боюсь, что двойную абстракцию (массив массивов) вы пока не осилите. Ну или я просто не сумею понятно обьяснить. Может кто другой. более сильный педагогическим талантом :)

да я тоже про это думал, массив в массиве, но как реализовывается пока не в курсе, думаю это проще конечно будет и там string не надо будет

 

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

qwone пишет:

И да для Си массивы используются редко. Есть более развитые системы для хранения информации.

......

стеки очереди списки и прочее.

.......

У каждой переменной есть формат. (Это тот слон который почему-то в упор новички не видят). Есть встроенные форматы - char, int, long. 

........

в Си нельзя поменять размер массива. Вот по этой причине идут другими путями.

Вы бредите. Прекращайте курить эту дрянь. Ваш бред с каждым днём становится всё более бессвязным.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

d13lider пишет:
засунуть в массив последовательно приходящие числа, их 24, 0-ей и 1-иц, приходят они с RC приемника 433Mhz

Вот нафиг здесь масив . Хватит тут unsigned long http://arduino.ru/Reference/UnsignedLong 

Baks
Baks аватар
Offline
Зарегистрирован: 11.01.2016

даю вам подсказку, вот в этой теме уже сделано получение номера телефона и запись его в EEPROM,

http://arduino.ru/forum/proekty/gsm-signalizatsiya-m590arduino?page=10#comment-313412

можно пдсмотреть как сохраняются номера телефонов.....

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

Baks пишет:

даю вам подсказку, вот в этой теме уже сделано получение номера телефона и запись его в EEPROM,

http://arduino.ru/forum/proekty/gsm-signalizatsiya-m590arduino?page=10#comment-313412

можно пдсмотреть как сохраняются номера телефонов.....

да смысл разобраться и понять а не скопировать и вставить

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

qwone пишет:

 

Вот нафиг здесь масив . Хватит тут unsigned long http://arduino.ru/Reference/UnsignedLong 

я просто привел пример

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

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

в общем из сериал надо выдернуть любую строку длинной 130 символов и обработать, и что бы этот массив оставался для следующей обработки(чтения)

b707
Offline
Зарегистрирован: 26.05.2017

d13lider пишет:

в общем из сериал надо выдернуть любую строку длинной 130 символов и обработать, и что бы этот массив оставался для следующей обработки(чтения)

как-то так (сделано из вашего же кода из соседней ветки, никких проверок)

const int buflen = 131; // длина вашей строки + 1 байт терминатор
char buf[buflen];            // символьный массив 
byte i =0;                          // счетчик полученных символов

while ((Serial.available() > 0)  && ( i<buflen))
  {
    buf[i]= Serial.read();
    i++;
}
buf[i] = '\0';

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Тоже но без массива

const int buflen = 131;      // длина вашей строки + 1 байт терминатор
char *buf=new char [buflen]; // выделить место в куче
byte i =0;                   // счетчик полученных символов

while ((Serial.available() > 0)  && ( i<buflen))
  {
    buf[i]= Serial.read();
    i++;
}
buf[i] = '\0';

 

b707
Offline
Зарегистрирован: 26.05.2017

qwone пишет:

Тоже но без массива

Такой же массив, как у меня. Даже может быть идентичный с точки зрения компилятора - я же нигде не указывал, был ли мой массив глобальным или локальным.

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

b707 пишет:
Такой же массив, как у меня. Даже может быть идентичный с точки зрения компилятора - я же нигде не указывал, был ли мой массив глобальным или локальным.
А вот и нет. По вашему коду вы не сможете изменить размеры массива, а я смогу. И не надо путать массивы с операцией *(buf+i)  иначе buf[i] .

b707
Offline
Зарегистрирован: 26.05.2017

qwone пишет:

А вот и нет. По вашему коду вы не сможете изменить размеры массива, а я смогу. И не надо путать массивы с операцией *(buf+i)  иначе buf[i] .

Мне кажется первая фраза противоречит второй :)

Кстати, как называется то, что у вас?  Вектор? Очередь? Ссылочный список? :)

 

С учетом того, что и в вашем коде buflen - константа, ничего вы изменить не сможете.  Использовать динамиченское выделение памяти для простых типов данных имеет смысл только в том случае. если вы в программе контролируете обьем кучи и принимаете решения прямо в режиме исполнения. А так, как тут - через константы да без контроля результата исполнения оператора new - это абсолютно аналогично моему жестко закодированному буферу. NEW в этом случае - чистое позерство. (как. впрочем, процентов 80 вашего кода в последние месяцы...)

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

b707,если вы мне хотите сказать гадости, то это не значит что вы от этого станете умнее. В Си массив и выделение в куче это все же разные понятия, хотя механизм похожий. Но это не одно и тоже.

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

вот, закусились) а мне то как быть?))) наговорили кучу, а верить то кому)

 

 

b707
Offline
Зарегистрирован: 26.05.2017

qwone пишет:

b707,если вы мне хотите сказать гадости, то это не значит что вы от этого станете умнее. В Си массив и выделение в куче это все же разные понятия, хотя механизм похожий. Но это не одно и тоже.

я написал выше (до гадостей) - при каких условиях это будет не одно и тоже. Да, потенциально ваш код гибче моего.  Но так, как это использовано у вас в вашем конкретном коде - не дает никаких преимуществ.

Все что сказано выше - относится к механизму выделения памяти. Результат же в обоих случаях одинаков и по сути и форме - это символьный массив buf, абсолютно идентичный в обоих случаях по "характеристикам" и методам работы.

b707
Offline
Зарегистрирован: 26.05.2017

d13lider пишет:

вот, закусились) а мне то как быть?))) наговорили кучу, а верить то кому)

Обоим :)

И там и там массив, отличия только в строчке инициализации, остальной код одинаков. Если интересно, можете даже для самообразования погуглить, чем отличаются два варианта - там все не так уж сложно, "не бином ньютона".

2qwone - вы, кстати, еще забыли delete(), представляете веселье, если ваш код вызвать в цикле? :)

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

b707 пишет:

 

Обоим :)

И там и там массив, отличия только в строчке инициализации, остальной код одинаков. Если интересно, можете даже для самообразования погуглить, чем отличаются два варианта - там все не так уж сложно, "не бином ньютона".

2qwone - вы, кстати, еще забыли delete(), без него неопытные умы могут вашим кодом "сломать ардуину" :)

смоотрите, может что то не так делаю? у меня получается вношу строку через сериал, читаю 2 бит, вношу другую строку а там та же информация

 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Для массивов заранее неизвестной переменной длины и неизвестного типа юзаю простенький шаблонный класс: https://github.com/Porokhnya/GreenhouseProject/blob/master/Main/TinyVector.h

И волосы всегда мягкие и шелковистые :)

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

d13lider пишет:

а верить то кому)

Если Вы помните, как мы делали часы, и всё ещё доверяете мне, то ответ: "не Квону". Он явно чего-то обкурился и его несёт.

sadman41
Offline
Зарегистрирован: 19.10.2016

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

Если Вы помните, как мы делали часы, и всё ещё доверяете мне, то ответ: "не Квону". Он явно чего-то обкурился и его несёт.

Страуструпа контрафактным "Моментом" подклеивал и уснул на книге.

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

пробовал, пробовал, и так до конца не понял... 


String nomber_Phone = "";
String nomber_conect = "";
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  const int buflen = 131; // длина вашей строки + 1 байт терминатор
  char buf[buflen];            // символьный массив
  byte i = 0;                         // счетчик полученных символов
  if (Serial.available() > 0)
  {
    i = 0;
    while ((Serial.available() > 0)  && ( i < buflen))
    {
      buf[i] = Serial.read();
      // Serial.println(i);
      nomber_Phone += (buf[i]);
      i++;
    }
    delay(10);
    if (Serial.available() < 1)
    {
      buf[i] = '\0';
      // Serial.println("0 OK");
      //Serial.println(nomber_Phone);
    }
  }
  if (nomber_Phone.indexOf("clear") > -1)
  {
    i = 2;
    while ( i < 50)
    {
      nomber_conect += (buf[i]);
      Serial.println(i);
      i++;
    }
    Serial.println(nomber_Phone);
    nomber_Phone = "";
  }
  if (nomber_Phone.indexOf("skan") > -1)
  {
    Serial.println(nomber_conect);
  }
  if (nomber_Phone.indexOf("delete") > -1)
  {
    nomber_conect = "";
    nomber_Phone = "";
  }
  if (nomber_Phone.indexOf("read") > -1)
  {
    Serial.println(nomber_Phone);
  }
}

ну уже кучу в коде нагородил, но все команды работают нормально, просто тестирую, так вот проблемма, когда записываю  массив в 

nomber_Phone

все отлично записывает, потом пытаюсь другой командой(в надежде что массив еще хранит данные, записать снова в другую переменную

nomber_conect

и уже там лезут кракозябры, почему так и не пойму

думал так что buf[2] будет хранить всегда один и тот же символ, пока не запишу другой, а выходит что то недопонимаю.... 

P.S. в 33 строке делаю отсчет со 2-го символа потому что надо пропустить первые несколько символов(это я понял что можно сделать так)

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

понимаю что щас будут говорить что вообще не так пошел и  можно сделать проще, но я хочу разобраться почему именно этот код не работатет

 

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

проблемма решилась вставив задержку 

const int buflen = 131; // длина вашей строки + 1 байт терминатор
char buf[buflen];            // символьный массив
byte i = 0;                         // счетчик полученных символов
String nomber_Phone = "";
String nomber_conect = "";
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  digitalWrite(3, HIGH);
  digitalWrite(4, HIGH);
  digitalWrite(5, HIGH);
  digitalWrite(6, HIGH);
}

void loop() {
  // put your main code here, to run repeatedly:

  if (Serial.available() > 0)
  {
    nomber_Phone = "";
    i = 0;
    while ((Serial.available() > 0)  && ( i < buflen))
    {
      buf[i] = Serial.read();
      delay(10);
      nomber_Phone += (buf[i]);
      i++;
    }
    delay(10);
    if (Serial.available() < 1)
    {
      Serial.println(i);
      // Serial.println("0 OK");
      Serial.println(nomber_Phone);

    }
  }
  if (digitalRead(3) == LOW)
  {
    Serial.println("pin3_OK");
    i = 2;
    while ( i < 50)
    {
      delay(50);
      nomber_conect += (buf[i]);
      Serial.println(i);
      i++;
    }
  }
  if (digitalRead(4) == LOW)
  {
       Serial.println("pin4_OK");
    Serial.println(nomber_conect);
  }
  if (digitalRead(5) == LOW)
  {
       Serial.println("pin5_OK");
    nomber_conect = "";
    nomber_Phone = "";
  }
  if (digitalRead(6) == LOW)
  {
       Serial.println("pin6_OK");
    Serial.println(nomber_Phone);
  }
}

в 25 строку... но ЕвгенийП говорил что это не правильно, и как то надо не читать пустые и ложные символы, так как это сделать?

 

b707
Offline
Зарегистрирован: 26.05.2017

d13lider, вы смешали два разных подхода. Если вы пользуетесь String, то char массив вам не нужен. Если решились отказаться от String - оставьте только массивы.

Во-втором коде вы потеряли добавление терминатора в конец строки     buf[i] = '\0';  Без этого оператора будут глюки.

Кроме того, нашел свою ошибку в том коде, что мы обсуждали с qwone (и qwone ее не заметил :) - условие цикла поправьте так:

 while ((Serial.available() > 0)  && ( i < buflen-1))

 

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

b707 пишет:

d13lider, вы смешали два разных подхода. Если вы пользуетесь String, то char массив вам не нужен. Если решились отказаться от String - оставьте только массивы.

Во-втором коде вы потеряли добавление терминатора в конец строки     buf[i] = '\0';  Без этого оператора будут глюки.

Кроме того, нашел свою ошибку в том коде, что мы обсуждали с qwone (и qwone ее не заметил :) - условие цикла поправьте так:

 while ((Serial.available() > 0)  && ( i < buflen-1))

 

я String оставлял что бы наглядно потестить, в скетч который уже готовый, вставляю все чисто массивами. это условие я немного подправил(пришлось в скетче главном)

 if (Serial.available())   {       //есть данные от GSM модуля
    delay(200);
    while (Serial.available()) {
      ch = Serial.read();
      if ( i < buflen-1)
      {
        buf[i] = ch;
        i++;
      }
}
}

модуль немного тормоз, поэтому не обращайте внимение на задержку.... а вот оператор buf[i] = '\0'; думаю не нужне, так как модуль GSM сам раздает каретку всегда

ЗЫ: за i++ не переживайте, далльше в скетче где надо он меняется на 0 и происходит запись после всех обработок данных от модуля gsm

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

спасибо вам огромное, я разобрался с простыми массивами! понял изнутри как это работает

а не просто зубрил..

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

не понял как обнуляется массив? что бы там лишнего небыло... char buf[buflen];? просто я щас делаю так: 

i = 0;
    while (i < 131)
    {
      buf[i] = 0;
      i++;
    }
    i = 0;

 

sadman41
Offline
Зарегистрирован: 19.10.2016

d13lider пишет:

не понял как обнуляется массив? что бы там лишнего небыло... char buf[buflen];? просто я щас делаю так:

так, как массив есть по сути блок памяти: memset(buf,0x00, sizeof(buf));

И '\0' - это не каретка, а нуль-терминатор строки. Его надо ставить, иначе есть шанс подвесится надолго при использовании строковых функций (и даже простого Serial.print);

b707
Offline
Зарегистрирован: 26.05.2017

d13lider пишет:

 а вот оператор buf[i] = '\0'; думаю не нужне, так как модуль GSM сам раздает каретку всегда

Вы ошибаетесь, нулевой терминатор '\0' и перевод строки - это совершенно разные вещи. Нулевой терминатор '\0' в конце символьного массива является обязательным для большинства Си-шных функций работы со строками.

b707
Offline
Зарегистрирован: 26.05.2017

d13lider пишет:

не понял как обнуляется массив? что бы там лишнего небыло... char buf[buflen];?

Вот для этого как раз и пригодится терминатор. Достаточно поставить '\0' в нулевую позицию массива, чтобы все системные функции считали его пустым.

Так что все просто

buf[0] = '\0';

Можете скомпилировать такой тестовый код и убедиться:

char str[] = "Bla-bla-bla!";
Serial.println(str);
str[0] = '\0';
Serial.println(str);

Должен на первой строке напечать bla-bla, а на второй - ничего.

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

т.е. на выходе из этой функции

if ( i < buflen-1)
      {
        buf[i] = ch;
        i++;
      }

поставить 

if ( i < buflen-1)
      {
        buf[i] = ch;
        i++;
      }
buf[0] = '\0';

?? просто немного непонятно что он именно делает

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

b707 пишет:

 

Вот для этого как раз и пригодится терминатор. Достаточно поставить '\0' в нулевую позицию массива, чтобы все системные функции считали его пустым.

Так что все просто

buf[0] = '\0';

Можете скомпилировать такой тестовый код и убедиться:

char str[] = "Bla-bla-bla!";
Serial.println(str);
str[0] = '\0';
Serial.println(str);

Должен на первой строке напечать bla-bla, а на второй - ничего.

это понял, спасибо большое и понял, что если закончились полезные данные которые крутились в функции while, т.е. функция прекратилась, и что бы не откуда не взялись лишние данные(ну мало ли импульс от наводки пройдет в регистр) как заканчивается функция сразу делаем все остальные данные недействительными

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

и получается надо сделать так 

while (Serial.available()) {
      ch = Serial.read();
      if ( i < buflen - 1)
      {
        buf[i] = ch;
        i++;
      }
      val += ch;
    }
buf[i] = '\0';

 

sadman41
Offline
Зарегистрирован: 19.10.2016

b707 пишет:

Вот для этого как раз и пригодится терминатор. Достаточно поставить '\0' в нулевую позицию массива, чтобы все системные функции считали его пустым.

Не путайте человека, он и сам запутается :))

Зачистить массив - это одно, а сделать пустую строку - другое (по смыслу). Потом будете объяснять, как из "пустого массива" куча разнообразных значений вылавливается.

2ТС: массив байтов и нуль-терминированная строка, которая применяется в Си, в сущности одно и то же - выделенная область последовательно идущих ячеек памяти. Встроенные строковые функции работают просто: "просматривают" ячейки памяти от нулевой и далее, не ориентируясь на указанный вами при создании таковой строки размер. Как только в текущей позиции '\0' увидели, то считают, что строка закончилась и завершают работу. А если не увидели, то будут далее просматривать всё по порядку, а это может быть очень долго. 

Однако из этого не следует, что помещение '\0' в нулевую ячейку очищает вообще всю выделенную под массив область памяти. Для реального "обнуления" нужно поместить '\0' во все ячейки, пробежав for-ом по всей длине или с помощью memset(), например. 

Какой из способов выбрать - нужно решать по месту. Например, сделали вы "пустую строку" через '\0' в нулевой ячейке, а потом в нее пихнули что-то из Serial.read(). И вот у вас уже нет строки с точки зрения внутренних функций, работающих со строками и strlen() будет показывать каждый раз безумные числа.