Функция String(int) останавливает Arduino

Ну, я пытаюсь сделать приложение с Arduino leonardo и GSM Shield. Есть условия if, else if, else .. и т.д.

  if (smsMetni.indexOf("DURUM") != -1) {
    Serial.println("SMS income");
    String temp= String(analogRead(LM35_pin) * 0.48828125);
    String temp2 = "Hava " + temp + " derece.";
    char tempSMS2[] = "";
    temp2.toCharArray(tempSMS2, 30);
    Serial.println(tempSMS2);
    Kapadokya.smsGonder(gonderilecekTelNumarasi, tempSMS2);
  }

После последней строки "Kapadokya.smsGonder(gonderilecekTelNumarasi, tempSMS2);" остановка программы, я смотрю последовательный монитор, нет никаких уведомлений или ошибок. просто останавливаюсь.

Если я изменю эти строки и удалю String(analogRead(LM35_pin) * 0.48828125) :

    String temp= String(analogRead(LM35_pin) * 0.48828125);
    String temp2 = "Hava " + temp + " derece.";

и просто пишите вот так, это работает очень хорошо.

String temp2 = "Hava  derece.";

может быть, вы думаете, что есть проблема с LM35, даже если я изменю его String(analogRead(LM35_pin) * 0.48828125); на String(30);, это снова не работает. после последней строки продолжение не продолжается.

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

, 👍1

Обсуждение

Не видя всего кода программы, я подозреваю, что у вас не хватает памяти, потому что вы широко используете класс String. Старайтесь НЕ объединять строки в новый строковый объект, так как вам нужно вдвое больше места, а затем копируйте его содержимое только в СЛИШКОМ МАЛЕНЬКИЙ массив tempSMS2, размер которого равен 1 (конечный нулевой символ). Просто последовательно печатайте строковые литералы, когда они у вас есть. Также используйте L-Macro, чтобы хранить строковые литералы в памяти программы, а не в ОЗУ. Serial.print также отлично способен печатать числа. Нет необходимости сначала преобразовывать их в String., @Kwasmich


1 ответ


Лучший ответ:

2

Вы должны избегать String на Arduino. Это вызовет случайные сбои. Однако это не ваша проблема. Ваша проблема заключается в попытке скопировать данные в слишком маленький массив.

char tempSMS2[] = "";

Это создает массив из одного байта, который содержит только \0. Затем вы пытаетесь втиснуть в него свои данные String, и они, конечно же, переполняют все остальные ваши переменные и данные.

Лучшее решение – работать непосредственно с массивами символов. Однако это немного сложнее:

Сначала преобразуйте число с плавающей запятой в строку:

char tempFloat[8];
dtostrf(analogRead(LM35_pin) * 0.48828125, -7, 3, tempFloat);

Затем создайте свою строку:

char tempSMS2[30];
strcpy_P(tempSMS2, PSTR("Hava "));
strcat(tempSMS2, tempFloat);
strcat_P(tempSMS2, PSTR(" derece."));
,

Ух ты. это выглядит потрясающе. но если добавить Serial.println(tempSMS2); в последней строке печатается только "derece". ты можешь починить это., @mehmet

К сожалению, последний strcpy_P должен был быть strcat_P., @Majenko

(PGM_P)F("foo") можно записать проще PSTR("foo"). На самом деле макрос F() использует PSTR()., @Edgar Bonet

@EdgarBonet Да, я никогда не могу вспомнить, какой из этих макросов. TBH Я никогда не использую их, но я никогда не использую AVR, если это специально не требуется клиенту., @Majenko