Как можно красивее офрмить эти if'ы
- Войдите на сайт для отправки комментариев
Пт, 12/04/2019 - 20:49
как можно красивее(взрослее) сделать эту логику ?
c while красивее но не хочу т.к. может зависнуть ожидая какогото ответа
обработчик ошибок еще не дописал
bool isModemRegistered(){ if (isModemAlive()){ Serial1.print("ATH\r"); if (Serial1.find("OK")){ Serial1.print("AT+CPAS\r"); if (Serial1.find("0")){ Serial1.print("AT+CREG?\r"); if (Serial1.find("0,1")) return true: return false; } else return false; } else return false; } else return false; } bool isModemBootup(){ if (!isModemAlive()){ if (!(PINC & (1 << 6))) delay(5000); //delay if shutdown routine is initiated //(PINC & (1 << 6)) >> 6 PORTC &= ~(1 << 6); //boot pin low delay(300); //time by datasheet PORTC |= (1 << 6); //boot pin high delay(5000); //delay if it actually is a reset if (Serial1.find("+PBREADY")) return true: return false; } else return true; } bool isModemAlive(){ Serial1.print("AT\r"); if (Serial1.find("OK")) return true: return false; } void modemOn(){ if (isModemBootup()){ if (isModemRegistered()) error no error yes; } else error yes; }
т.к. на самом деле мы не знаем физического состояния внешнего устройства то попытался максимально (на сколько хватило мне соображалки) сделать защиту от дурака/случайного выключения/зависания. т.к. нет while и код после обработки ошибки, побежит по второму/третьему кругу и даже несмотряна то что мы пытаемся только включить внешнее устройство, фактически мы можем его и ресетнуть и если с подключением /питанием все ок, то в конце концов должно заработать.
Красивее оформить - инвертировать условие и сразу сделать return false. А вот как умнее сделать - надобно мозг наморщить.
В строчке 8 - дичь написана, там нет тернарного оператора, компилироваться не должно. В строчке 21 - також. Или это - просто псевдокод?
По поводу красивости: всё субъективно. Красиво - это когда код форматирован по одному из стандартов. Как правильно замечено выше - инверсия условия сильно сократит кол-во ненужных else.
Функции типа
можно переписать короче:
В целом же, исходя из опыта: блокирующая работа с GSM-модемом в реальном более-менее серьёзном проекте - неприемлема, от слова "совсем": ответ на некоторые команды по даташиту может занимать до 80 секунд. Что в это время делать остальному функционалу прошивки - курить бамбук? Единственное верное пмсм решение - это неблокирующий конечный автомат с состояниями, вещь не самая тривиальная к реализации, в своё время убил на отладку этого дела больше месяца.
А что, прежде, чем задавать вопрос о красоте, просто добиться успешной компиляции ... не судьба?
Нет, не зря я Вас в соседней теме медалью наградил! Вы достойны! :)))
DIYMan так вроде у меня не блокирующая я поэтому и убрал while(!serial.find()); ?
а почему
return
(!)Serial1.find(
"OK"
);
когда вроде надоreturn
Serial1.find(
"OK"
);
?"инвертировать условие и сразу сделать return false"
вы это имели ввиду?
DIYMan так вроде у меня не блокирующая я поэтому и убрал while(!serial.find()); ?
а почему
return
(!)Serial1.find(
"OK"
);
когда вроде надоreturn
Serial1.find(
"OK"
);
?"инвертировать условие и сразу сделать return false"
вы это имели ввиду?
У вас - именно блокирующая, потому что Serial.find не сразу возвращает управление, а по таймауту. К тому же - такой подход не обеспечит правильного реагирования на многие команды: как я писал выше - ответ на некоторые команды может занимать много секунд.
Почему !Serial.find - описка, если имелась в виду функция isModemAlive. В целом же, повторюсь ещё раз: ваш подход - не очень, на простом примере: вы послали команду AT, а в этот момент в порт упала SMS, до прихода ответа OK. С вашим кодом - СМС будет пропущена.
Инвертирование условия - это:
1. Ваш пример:
2. Инвертирование условия:
Второй вариант - короче и читабельней.
По поводу синтаксиса и пр.: очень советую почитать учебник по С++ - многие вопросы отпадут сами собой.
Евгений теперь компилируется
Инвертирование условия - это:
1. Ваш пример:
2. Инвертирование условия:
Второй вариант - короче и читабельней.
return condition;
не?
если инвертировать:
return !condition;
Инвертирование условия - это:
1. Ваш пример:
2. Инвертирование условия:
Второй вариант - короче и читабельней.
return condition;
не?
если инвертировать:
return !condition;
Зависит от задачи и условий. В моём случае можно добавить дополнительные операторы:
В случае простого возврата return !condition - так не выйдет. К тому же - ТС нужен условный возврат, а не безусловный - это видно из логики кода. Поэтому именно if.
DIYMan да я заметил что ответ иногда вообще не приходит, ну или ему надо было много больше время. я послал другую команду и ответ пришел сразу на вторую а на первую получилось так и не пришел. да find он таймаут меня это как раз избавляет от while.
про потеряю смс вы правы я даже не подумал об этом. но в данном конкретном проекте это не критично. будут пошаговые операции так сказать. вначале включили. потом настроили модем. птом приняли команду. отправили команду и тд. и когда мы отправляем команду - программе будет - уже пофиг что ктото ждет чтоб мы получили её. опоздал - твои проблеммы :) да это ни рил тайм. не смогу как вы :) но зато (кмк) будет весьма надежно, безотказно. во всяком случае точно интерактивнее и отказоустойчевее чем у многих готовых китайских аналогов.
с инвертированием кажется понял, уже завтра попробую. спасибо
В целом же, исходя из опыта: блокирующая работа с GSM-модемом в реальном более-менее серьёзном проекте - неприемлема, от слова "совсем": ответ на некоторые команды по даташиту может занимать до 80 секунд. Что в это время делать остальному функционалу прошивки - курить бамбук? Единственное верное пмсм решение - это неблокирующий конечный автомат с состояниями, вещь не самая тривиальная к реализации, в своё время убил на отладку этого дела больше месяца.
Вы абсолютно правы. Попытался сделать пасечные весы. Что-бы по звонку от меня и подачи определенных DTMF сигналов "озвучивался" привес за сутки либо за неделю (файлы озвучки в SIM800). Ну и плюс энергосберегающий режим и периодическая проверка регистрации в сети (сеть теряется часто в предполагаемом месте установки устройства), нет сети - отключи радиомоодуль, минут через несколько снова проверь... Это штоба батарейку поберечь. Ну и плюс экранчик с кнопочкой, на месте привес проверить. Ну и RTC с микросхемой памяти, - эти привесы хранить и долгими зимними вечерами анализировать.
Код блокирующий : АТ команда - ждем овет - что-то делаем. Вроде и работает все, но криво как-то. То на звонок не отвечает, то ДТМФ не распознает, то еще какая хрень...
НО! Представив сложность написания конЧЕного автомата (с кучей незапрашиваемых уведомлений, вариантами ответов от SIM) - решил НИАСИЛЮ ;)) Жил же я раньше без умных весов, может и дальше проживу...
kolyn, при таком раскладе нужно было идти в обратную сторону - не по запросу отдавать данные, а пушить куда-нить. Сейчас, как я понимаю, модно на MQTT-сервер выкидывать данные, потом со смартфона клиентом смотреть. А если 3310 в качестве клиентского устройства, то ежедневный смс-репорт - сколько прибавилось за сутки, сколько с начала недели. Заодно будет уверенность, что система не висит.
не по запросу отдавать данные, а пушить куда-нить.
В месте, где хотел пользовать устройство мобильного интернета нет. От слова совсем. Даже EDGE нет! Это первое. Второе - вохдящие бесплатны. Т.е я пополнил карту раз в год и звоню на устройство, не заморачиваясь с проверкой счета, пополнением и т.д. - считаю жирным плюсом при эксплуатации.
Насколько я понял - хотели звонить с бесплатными входящими и пр. пирогами, но не смогли обуздать систему. Так что - или смс или ничего. Выбор Ваш, конечно - мотаться на пасеку чтобы смотреть на экранчик или иногда пополнять баланс.
Выбор Ваш, конечно - мотаться на пасеку чтобы смотреть на экранчик
Летом живу там практически все время - это основное занятие для денг. Ардуина - хобби, тренировка для мозгов, черствеют с годами, знаете ли. Проект пытался замутить не для себя, хотел выложить в свободный доступ. "Умные пчеловодные весы" как коммерчесский проект есть и в Украине и в России, и за далеким бугром, но цена!!! Любителю не по карману, профессионалу по сути не нужны - он и так все видит...
То,что сгородил я, в принципе работает, но... Глюки, такое предлагать для повторения - дурной тон. Может следующей зимой... или никогда...
qwone, писал ранее про логику:
Что-бы по звонку от меня и подачи определенных DTMF сигналов "озвучивался" привес за сутки либо за неделю (файлы озвучки в SIM800).
Квон опять неправильного мёда хлебнул...
А теперь представим ситуацию. Вы находитесь хер-знаете-где. Хотите узнать прирост. Отправляете СМС . И улий озвучивает прирост +5 кг. Замечательно. Но вы из местности хер-знаете-где услышите озвучку находящую на улике,а значит далеко от вас. Вот и выходит, что нужно отправить прирост уже к вам на мобилу, который это и озвучит .
Одно из двух - либо я тупо пояснил, либо до Вас тупо не дошло ;)
Я звоню весам. Они снимают трубу, и говорят мне (человечьим голосом на чистом русском языке): "Хотите узнать привес за сутки - нажмите 1, привес за неделю - нажмите два, хотите послушать свежий анекдот - нажмите 666". Я на своем телефоне нажимаю кнопку 1, весам передается ДТМФ-сигнал и они говорят человечьим языком: "Привес за сутки составил 16 кг. 850 гр." Я переключаюсь с телефона на калькулятор, умножаю на количество семей, на цену меда в долларах и довольный потираю руки.
Позже выясняется, что это был глюк и в реале вместо привеса была убыль...
Значить, Пух приходил, покопаца
В целом же, повторюсь ещё раз: ваш подход - не очень, на простом примере: вы послали команду AT, а в этот момент в порт упала SMS, до прихода ответа OK. С вашим кодом - СМС будет пропущена.
вчера во время эксперементов с модем добавил прерывание для отладки и заметил следующее:
- если прерывания нет, то все что уходит в сериал от модема успешно получается ардуиной. без пропусков.
- если я добавляю короткое и быстрое прерывание, просто зажечь 13 лед, когда чтото пришло в сериал. причем зажигаем через запись в порт а не через digitalWrite(); который в 20 раза медленее, то первые 5 символов пропадают из эфира. как можно словить все символы ?
весь код показывайте.
И вообще непонятно, зачем прерывание для отладки если все что валится из модема вы все равно выводите в монитор.
Уже многократно обсуждалось здесь, максимально отказываться от вских выводов информации во время приема данных, т.е. или делаете большой буфер, в него все кидаете а потом обрабатываете или обрабатывать online но тогда код должен быть максимально коротким
код в другом месте, пишу по памяти. может чтот азбыл. но смысл такой.
ну и как сказал уж без прерывания все ок а так первые 5 символов пропадают
ну вопрос то остался: зачем моргать светодиодом со скоростью 115200 при приеме данных?
не, он моргает один раз. согласно низкому уровню на ноге 10 модема.
в кратце. на ноге 10 модема. появляется низкий уровень когда приходит смс. в этоже время одновременно когда приходит смс модем отправляет текст RING в сериал. т.е. одновременно ринг в сериал и ноль на 10 ноге. по этому нулю я зажигаю лед. но не вижу надписб RING в сериал. если закоментить прерывание то RING я вижу.