if (Serial.available()) br = Serial.read();
if (br) {/ запись байта в буфер
resp_buf[pos_buf] = br; // записали
++pos_buf; // увеличили счетчик
if (pos_buf >= max_size_response_buf) pos_buf = 0; // если дошло до максимума - обнуляем
}
где то я косячу...
void loop() {
while (1) {
wdt_reset();
if (Serial.available())MODEM.write(Serial.read());
if (MODEM.available() > 0) {
if (MODEM.available())temp = MODEM.read();
buffers[pos_buf] = temp;
pos_buf++;
if (pos_buf >= MAX_SIZE_RESP_BUF) pos_buf = 0;
Serial.print("Polucheno: ");
Serial.print(pos_buf);
Serial.print(" Byte");
Serial.println("");
Serial.println(buffers);
for (byte i = 0; i < pos_buf ; i++)buffers[i] = NULL;
pos_buf = 0;
}//if (MODEM.available() > 0) {
}//while (1) {
}//loop
void loop() {
while (1) {
wdt_reset();
if (Serial.available())MODEM.write(Serial.read());
if (MODEM.available() > 0) {//Если модем что-то отправил в порт
delay(50);
byte a = MODEM.available();//Получаем количество байт, которые модем отправил в порт
//в цикле заношу все полученные байты в массив
for (byte i = 0; i < a; i++)
{
byte temp = MODEM.read();
buffers[pos_buf] = temp;
pos_buf++;
}
for (byte i = 0; i < pos_buf ; i++) {
if (buffers[i] == '\r')buffers[i] = 'r';
if (buffers[i] == '\n')buffers[i] = 'n';
}
Serial.print("Polucheno: ");
Serial.print(pos_buf);
Serial.print(" Byte");
Serial.println("");
//Serial.println(buffers);
for (byte i = 0; i < pos_buf ; i++) {
Serial.println(buffers[i]);
}
for (byte i = 0; i < pos_buf ; i++)buffers[i] = NULL;
pos_buf = 0;
}//if (MODEM.available() > 0) {
}//while (1) {
}//loop
1 проход loop = 1 прочитанный байт от модема
Если байт не равен нулю - работаем
Выводим его в монитор (write) и заносим в буфер
Если упёрлись в размер буфера - очищаем буфер
Если пришло \n и в буфере больше одного байта - смотрим предыдущий , если он \r - закончилась строка - ищем в ней нужные подстроки
Очищаем буфер, работаем дальше.
Ну а DTMF куда уж проще, нашли ring значит прилетел звонок, смотрим телефонный номер, если разрешенный - возводим флаг управления.
Далее в строках высматривает нажатые кнопки, параллельно высматривает команду прекращения звонка.
Не, все не так,много лишнего,от while не избавились, зачем менять \n на n, логика вообще не как я написал, зачем лишняя функция чтения если все в одно условие можно запихнуть. Смотрите пример в теме Снова mqtt там все готовое уже есть, правда обработка побайтная, но к вашему буферу прикрутить можно.
вот пример только круговой буфер
if (modemAvailable()) { // если что то пришло из модема
br = modemRead(); // читаем пришедший байт
if (br) { // если он больше нуля
if (posModemBuf >= maxSizeRespBuf) posModemBuf = 0; respBufModem[posModemBuf] = br; ++posModemBuf; // добавляем пришедший байт в круговой буфер
#ifdef SHOW_LOG
if ((br == '\r') || (br == '\n') || ((br >= ' ') && (br < 0x7F))) { // если символ печатный или конец строки
logWrite(br); // выводим его в лог
} else { // если не печатный
logHexPrint(br); logWrite(' '); // выводим его шестнадцатиричное представление в лог
}
#endif
//-------------здесь пишем что то свое обрабатываем содержимое буфера --- добавляем условие что конец строки, те пришло \r\n
//-------------если обработка прошла успешно чистим буфер
memset(respBufModem,0,maxSizeRespBuf);
//-------------закончили работу с данными от модема
}
}
Не нашел проверку на переполнение буфера после ++pos, соответственно и очистка в 57 строке может вылезти за границы памяти
В остальном движение правильное
Да-да, я немного не поняла, когда я заполняла буфер в цикле while, как только буфер наполнялся до максимума, я выходила из while, обрабатывала буфер и очищала его
А сейчас, просто если буфер переполнен прекратить наполнение? а если не придёт конец строки то буфер будет заполнен и очистка не произойдёт?
if (MODEM.available()) {//если что-то пришло с модема
byte temp = MODEM.read();//читаю 1 байт
if (temp) {//если считанный байт больше 0
if (pos_buf<MAX_SIZE_RESP_BUF){
???
}
buffes[pos_buf] = temp;//добавляю считанный байт в буфер
Ну не, обрабатывать строку / буфер когда придет конец строки. Сразу после обработки данных всегда в любом случае буфер чистить, т к данные в нём уже не нужны. А за размером буфера следить банально потому что при превышении МК зависнет. Т е по факту это две параллельные задачи, обработка сама по себе, контроль размера сам по себе. При превышении тупо pos в ноль и чистим буфер. Да, мы потеряем данные, но пока так научитесь, на след шаге будете круговой буфер использовать.
Да, но кроме этой строчки ещё и проверку на переполнение перетащить вниз, иначе может произойти ситуация что конец строки попадет на последние ячейки буфера, но 5е обработается.
Впрочем оставьте как есть, должно работать ок при не сильном потоке данных
если буфер переполняется, то данные теряются, так как буфер очищаю, а с другой стороны, у меня нет таких больших ответов от модема, размером больше 50 байт (MAX_SIZE_RESP_BUF)
Правильно, только жизнь сложнее чем теория и вместе с ответами могут прилетать например длинные рекламные СМС и вы легко потеряете важную информацию, но пока об этом не думайте, с опытом все перепишите или возьмите готовое пару страниц назад в этой ветке.
У меня почему-то не отключаются мыло-оповещения про этот топик, а я аккуратный, читаю все входящие мылы. Поставьте же уже задачу, я напишу может, по-быстрому, что требуется, и закроем тему ?
Ну и вообще красивый вариант решения любой проблемы - создавать отдельную тему и там уже обсуждать проблему сообразно названию темы. А какое отношение имеет, например "pos_buf++ с 10 строчки на 29", к SIM800L ?
nhs, Вы правы.
Я прошу администрацию форума, если это возможно, перенести все сообщения, начиная с #179 в отдельную тему "Чтение порта в char" раздела "Песочница. Раздел для новичков"
nhs, анекдот есть в тему ".....всех удовлетворяет а его нет...."
Может быть читать быстрее необходимо или все уведомления тупо в почте настроить через правила ? И проблема исчезнет....
основная проблема в выводе всяких сообщений в процессе работы с модемом Polecheno и прочее.
возьмите как аксиому: ни при каких обстоятельствах при чтении данных из модема не задерживать поток.
максимально что можно это с помощью serial.write вывести приходящий байт.
если уж очень хочеться то только при отрицательном условии modem.available().
в любом случае, когда железку доделаете и она будет работать удалите (или define отключите) все диагностические сообщения software serial как страшный сон, включая саму include и инициализацию библиотеки.
Масса путей, самый правильный наверное писать классы под команды, и каждому классу прописывать требуемые ответы. Поскольку я с ООП не дружу, у меня под каждую команду выбирается свой case и ожидается нужный ответ. Выбирайте не по принципу нравится\нет а работает\нет, потом с опытом будете красоту наводить.
Да,. Только добавить таймеры, условия чтоб если на х миллисекунд нет правильного ответа значит проблема, искать строки заново или модем перезагружать. В примерах все есть :)
Помогите! Купил SIM800L, подключил к usb-uart к компу, работал в terminal 1,9. К модулю припаял стандартную антенну. Модуль настроил, несмотря на периодические отвалы питания (на делителе от 5 В) модуль в 80-90% выдает адекватные ответы. Однако модуль не регистрируется в сети, хоть и видит эти сети (МТС, Билайн, Мегафон), проверял AT+CCID, результат положительный, что говорит о том, что симка коннектится. Перепрошил модуль на 3 версии вверх с дров производителя. AT+CREG? выдает 0,2; мне непонятно какова причина "2". AT+CSQ выдает иногда 0,0, иногда 28,0, подключал на аппаратной антенне, на дополнительной, на обоих сразу. Менял симку с ТЕЛЕ2 на МТС, в AT+CREG? появилось еще и 0,4, что не добавило понимания. Подскажите, что делать? Вангуя, что будет ответ про смену/запайку питания: проверял его кучу раз, запитывал как от делителя, так и от БП, т.к. интересует только отправка СМС потребление будет небольшое, поэтому делитель.
Потребление 50-70 мА, откуда 2А? Если я все правильно понимаю, сила тока скачет при интернет подключении. Команда проверки питания выдает 3,82 В, если вам интересно
1. Пиков в 2 ампера я не заметил на всем промежутки работы модуля (10 минут)
2. Стандартный ток в модуле - 20 мА
3. При регистрации в сети ток - 100мА, никакими 2А там и не пахнет.
3. Как я и говорил проблема не в питании, сейчас обеспечил абсолютно стабильные 4В 2А, результат нулевой. Прошу если и высказываться, то конструктивно, имхо даже с студенту 1-2 курса понятно что при нагрузках в виде регистрации в сети и отправки 3-4 сообщений по юарту в секунду модуль не сможет физически жрать 2А.
где то я косячу...
Вопрос чуть в сторону. Какой тариф, какого оператора сейчас выгоден и работает с 800l в МО?
Может я что-то не так понимаю в работе порта...
К примеру, на АТ модем отвечает
1 проход loop = 1 прочитанный байт от модема
Если байт не равен нулю - работаем
Выводим его в монитор (write) и заносим в буфер
Если упёрлись в размер буфера - очищаем буфер
Если пришло \n и в буфере больше одного байта - смотрим предыдущий , если он \r - закончилась строка - ищем в ней нужные подстроки
Очищаем буфер, работаем дальше.
Ну а DTMF куда уж проще, нашли ring значит прилетел звонок, смотрим телефонный номер, если разрешенный - возводим флаг управления.
Далее в строках высматривает нажатые кнопки, параллельно высматривает команду прекращения звонка.
Как-то так?)
Почему в монитор порта постоянно отправляется символ n
Не, все не так,много лишнего,от while не избавились, зачем менять \n на n, логика вообще не как я написал, зачем лишняя функция чтения если все в одно условие можно запихнуть. Смотрите пример в теме Снова mqtt там все готовое уже есть, правда обработка побайтная, но к вашему буферу прикрутить можно.
вот пример только круговой буфер
Спасибо. Учту.
На счёт примеров, как будет время, ткните, пожалуйста, хочу знать.
функция, возвращающая указатель на строку
Я всё думала от какого while я не избавилась...
Об этом я прочитала в статье про тюнинг ардуино ....
http://codius.ru/articles/Тюнинг_Arduino_или_ускоряем_работу_платы
Это я для себя делала, смотрела что приходит от модема посимвольно.
С кодом разбираюсь)
Не нашел проверку на переполнение буфера после ++pos, соответственно и очистка в 57 строке может вылезти за границы памяти
В остальном движение правильное
Да-да, я немного не поняла, когда я заполняла буфер в цикле while, как только буфер наполнялся до максимума, я выходила из while, обрабатывала буфер и очищала его
А сейчас, просто если буфер переполнен прекратить наполнение? а если не придёт конец строки то буфер будет заполнен и очистка не произойдёт?
}
Так?
Ну не, обрабатывать строку / буфер когда придет конец строки. Сразу после обработки данных всегда в любом случае буфер чистить, т к данные в нём уже не нужны. А за размером буфера следить банально потому что при превышении МК зависнет. Т е по факту это две параллельные задачи, обработка сама по себе, контроль размера сам по себе. При превышении тупо pos в ноль и чистим буфер. Да, мы потеряем данные, но пока так научитесь, на след шаге будете круговой буфер использовать.
Irinka, а вы а школе/вузе информатику учили ?)
Рекомендую нарисовать все на бумаге ромбиками и квадратиками - сильно поможет в понимании.
Информатика в школе была, и в колледже была (мне 27 лет, Иринкой звать:) ) рисовали в паинте, печатали в ворде, работали в экселе, всё)
Итак:
Если модем отправил какие-то данные
Считываем 1 байт
Если байт не равен 0, записываем его в буфер
Если размер буфера становится больше MAX_SIZE_RESP_BUF то очищаю буфер и начинаю заполнения с 0 позиции
Но тогда я теряю данные? Правильно?
Дальше, если буфер не переполнен
Если приходит перенос строки, работаю с накопившемся буфером, и очищаю буфер.
При превышении нет смысла дальше обрабатывать , соответственно все что ниже 13 строки засунуть в else и в фигурные скобки соответственно
Но я б проверку на переполнение сразу после ++ сделал и поставил бы после обработки это увеличение
Вы имеете ввиду pos_buf++ с 10 строчки на 29?
Да, но кроме этой строчки ещё и проверку на переполнение перетащить вниз, иначе может произойти ситуация что конец строки попадет на последние ячейки буфера, но 5е обработается.
Впрочем оставьте как есть, должно работать ок при не сильном потоке данных
если буфер переполняется, то данные теряются, так как буфер очищаю, а с другой стороны, у меня нет таких больших ответов от модема, размером больше 50 байт (MAX_SIZE_RESP_BUF)
Правильно понимаю?
Правильно, только жизнь сложнее чем теория и вместе с ответами могут прилетать например длинные рекламные СМС и вы легко потеряете важную информацию, но пока об этом не думайте, с опытом все перепишите или возьмите готовое пару страниц назад в этой ветке.
По коду выше
Строка 26
memset(buffers, 0, pos_buf); или лучше чистить весь буфер
memset(buffers, 0, MAX_SIZE_RESP_BUF);Я лучше с опытом) а Ваш код часто просматриваю, изучаю, спасибо что помогаете.
С использованием char всё работает намного быстрее. )
У меня почему-то не отключаются мыло-оповещения про этот топик, а я аккуратный, читаю все входящие мылы. Поставьте же уже задачу, я напишу может, по-быстрому, что требуется, и закроем тему ?
Ну и вообще красивый вариант решения любой проблемы - создавать отдельную тему и там уже обсуждать проблему сообразно названию темы. А какое отношение имеет, например "pos_buf++ с 10 строчки на 29", к SIM800L ?
del
nhs, анекдот есть в тему ".....всех удовлетворяет а его нет...."
Может быть читать быстрее необходимо или все уведомления тупо в почте настроить через правила ? И проблема исчезнет....
andykat, у Вас нет задержки после 2 строки, и всё работает?
у меня вообще нигде delay нет и вам советую
и все работает
Update: вру, есть delay, но в не критичных секциях, типа ожидание модема при перезагрузке.
Irinka , в вашем коде
http://arduino.ru/forum/apparatnye-voprosy/vse-o-sim800l-i-vse-chto-s-ni...
основная проблема в выводе всяких сообщений в процессе работы с модемом Polecheno и прочее.
возьмите как аксиому: ни при каких обстоятельствах при чтении данных из модема не задерживать поток.
максимально что можно это с помощью serial.write вывести приходящий байт.
если уж очень хочеться то только при отрицательном условии modem.available().
в любом случае, когда железку доделаете и она будет работать удалите (или define отключите) все диагностические сообщения software serial как страшный сон, включая саму include и инициализацию библиотеки.
Я отладку делаю вот так:
Буду удалять и этот код.
В ответ на команду AT+CCALR? я получаю три строки:
Не нравится мне мой код, как сделать правильнее?
Масса путей, самый правильный наверное писать классы под команды, и каждому классу прописывать требуемые ответы. Поскольку я с ООП не дружу, у меня под каждую команду выбирается свой case и ожидается нужный ответ. Выбирайте не по принципу нравится\нет а работает\нет, потом с опытом будете красоту наводить.
С case так?
Да,. Только добавить таймеры, условия чтоб если на х миллисекунд нет правильного ответа значит проблема, искать строки заново или модем перезагружать. В примерах все есть :)
Хотя нет, неверно
Только если таймером ответа сбросить BAT_SET в 0
Ещё вопросик, я создала функцию для чтения из модема
А в loop просто её вызываю.
Не влияет на быстродействие?
На быстродействие все влияет, пробуйте, будут проблемы - будете оптимизировать.
Помогите! Купил SIM800L, подключил к usb-uart к компу, работал в terminal 1,9. К модулю припаял стандартную антенну. Модуль настроил, несмотря на периодические отвалы питания (на делителе от 5 В) модуль в 80-90% выдает адекватные ответы. Однако модуль не регистрируется в сети, хоть и видит эти сети (МТС, Билайн, Мегафон), проверял AT+CCID, результат положительный, что говорит о том, что симка коннектится. Перепрошил модуль на 3 версии вверх с дров производителя. AT+CREG? выдает 0,2; мне непонятно какова причина "2". AT+CSQ выдает иногда 0,0, иногда 28,0, подключал на аппаратной антенне, на дополнительной, на обоих сразу. Менял симку с ТЕЛЕ2 на МТС, в AT+CREG? появилось еще и 0,4, что не добавило понимания. Подскажите, что делать? Вангуя, что будет ответ про смену/запайку питания: проверял его кучу раз, запитывал как от делителя, так и от БП, т.к. интересует только отправка СМС потребление будет небольшое, поэтому делитель.
2 ампера с делителя ?
Потребление 50-70 мА, откуда 2А? Если я все правильно понимаю, сила тока скачет при интернет подключении. Команда проверки питания выдает 3,82 В, если вам интересно
По даташиту пиковый ток 2А.
Да, при регистрации именно самые пики питания.
Итак, господа:
1. Пиков в 2 ампера я не заметил на всем промежутки работы модуля (10 минут)
2. Стандартный ток в модуле - 20 мА
3. При регистрации в сети ток - 100мА, никакими 2А там и не пахнет.
3. Как я и говорил проблема не в питании, сейчас обеспечил абсолютно стабильные 4В 2А, результат нулевой. Прошу если и высказываться, то конструктивно, имхо даже с студенту 1-2 курса понятно что при нагрузках в виде регистрации в сети и отправки 3-4 сообщений по юарту в секунду модуль не сможет физически жрать 2А.
Чем проводились измерения?
Chenod
Table 41: Absolute maximum ratings (page 58)
БП ELEMENT 1502DD
Фотку подключения к БП киньте, а то вдруг дюпонты