Как постичь непостижимое
- Войдите на сайт для отправки комментариев
Здравствуйте уважаемые гуру ардуин!
Увлекла меня тема Ардуино))) И решил я примкнуть к вашей банде.
Поморгал светодиодом, сделал радиоуправление для лодки.
Теперь хочу сделать автопилот для лодки.
Для начала решил вытащить GPS координаты в сериалпорт , взял Arduino Nano и GPS модуль NEO-M8N и пока у меня ничего не выходит.
Помогите разобраться пожалуйста как вывести в сериал монитор GPS координаты.
Сейчас пишет только вот это:
$PSV32,01,5,10121,1,911,2,Simple TinyGPS library v. 13
by Mikal Hart
соединил:
GND → GND
TX → Цифровой вывод (D10)
RX → цифровой вывод (D9)
Vcc → 5Vdc
Взял пример скетча из библиотеки TinyGPS
#include <SoftwareSerial.h>
#include <TinyGPS.h>
/* This sample code demonstrates the normal use of a TinyGPS object.
It requires the use of SoftwareSerial, and assumes that you have a
9600-baud serial GPS device hooked up on pins 9(rx) and 10(tx).
*/
TinyGPS gps;
SoftwareSerial ss(9, 10);
void setup()
{
Serial.begin(9600);
ss.begin(9600);
Serial.print("Simple TinyGPS library v. "); Serial.println(TinyGPS::library_version());
Serial.println("by Mikal Hart");
Serial.println();
}
void loop()
{
bool newData = false;
unsigned long chars;
unsigned short sentences, failed;
// For one second we parse GPS data and report some key values
for (unsigned long start = millis(); millis() - start < 1000;)
{
while (ss.available())
{
char c = ss.read();
//Serial.write(c); // uncomment this line if you want to see the GPS data flowing
if (gps.encode(c)) // Did a new valid sentence come in?
newData = true;
}
}
if (newData)
{
float flat, flon;
unsigned long age;
gps.f_get_position(&flat, &flon, &age);
Serial.print("LAT=");
Serial.print(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6);
Serial.print(" LON=");
Serial.print(flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6);
Serial.print(" SAT=");
Serial.print(gps.satellites() == TinyGPS::GPS_INVALID_SATELLITES ? 0 : gps.satellites());
Serial.print(" PREC=");
Serial.print(gps.hdop() == TinyGPS::GPS_INVALID_HDOP ? 0 : gps.hdop());
}
gps.stats(&chars, &sentences, &failed);
//Serial.print(" CHARS=");
//Serial.print(chars);
//Serial.print(" SENTENCES=");
//Serial.print(sentences);
//Serial.print(" CSUM ERR=");
//Serial.println(failed);
if (chars == 0)
Serial.println("** No characters received from GPS: check wiring **");
}
[quote=ЕвгенийП]
почитайте его, и вставляйте код по правилам.
Спасибо Евгений за совет. Я новичек в этом деле, как Вы уже поняли. В таком виде будет правильно?
Этот модуль сам по себе гонит IMEA, потому, для начала, сделайте безо всякой библиотеки - тупое копирование ss в Serial. Совсем тупое, типа такого
Когда и если Вы увидите нормальный IMEA код в мониторе, Вы будете уверены, что у Вас живой модуль, что он правильно подключён и т.п.
Только тогда переходите к библиотеке.
Попробывал Ваш код. Скорости поставил обе по 9600. все работает. Данные идут вот так:
Ну, я не знаю что там за кракозябы в начале, у меня вроде сразу нормально идёт (если склероз не изменяет, могу попробовать сейчас, если хотите). Но, если это нормально, то разбирайтесь, что у Вас с бибилотекой.
С кракозябрами все нормально. NEO8M, во всяком случае тот, с которым я имел дело, вел себя точно так же. Строковые данные вперемешку с двоичными. Периодами. Но координат в потоке нет. Видимо он в помещении его запускает.
Не знаю, восьмой у меня в доме (посерёдке причём, а не у окна) аж 12 штук наловил.
Попробовал еще раз. Теперь нормально, без кракозяблов.
Да,и еще, прочитал винете сегодня, что под эту библиотэку нужно neo-m8n как-то настраивать, что-бы в правильном формате данные отдавал. Но я не знаю как и в каком формате нужно передавать этой библиотеке данные.
Еще вычитал, что есть какая-то специальная библиотека NeoGPS-master. Но как с ней работать я опять же не знаю.
Посоветуйте что-нибудь......
Посоветуйте что-нибудь......
Совет "читать документацию к библиотекам", или "смотреть код библиотек, если там ни документации, ни примеров нет" - не катит, да?
ну как-бы Вы наверное правы, есть один ньюанс, я пока что в этом деле валенок. Не знаю куда смотреть((( и что там искать.
Вы специально себе приключений ищете? Я же Вам говорил, шаг за шагом, не лепите одну сложность на другую.
Удаляйте нахрен всё с 26 по 47 строку, а после 22-ой поставьте вывод в сериал значений lat и lon. И пока не увидиет их нормальными, забудьте про дисплеи и прочую лабуду.
Посоветуйте что-нибудь......
Советую. Вы строки на экране видите? Они же нормальные? Ну, и разбирайте их сами - назрнае Вам вообще библиотека? Я вот именно так и делаю.
Посоветуйте что-нибудь......
Советую. Вы строки на экране видите? Они же нормальные? Ну, и разбирайте их сами - назрнае Вам вообще библиотека? Я вот именно так и делаю.
Ну Евгенй, мне до восьмидесятого уровня еще далеко))))
Но проблему свою я решил))
Короче, с моей Наночкой сработала только TinyGPS++
взял скетч из примера. Работает только шуба заворачивается.))) Ну и конечно дислей прикрутил. На дисплее координаты показывает.
Евгений, а можешь объяснить мне нормально, как стоматолог гинекологу как без библиотеки координаты вытащить?
Евгений, а можешь объяснить мне нормально, как стоматолог гинекологу как без библиотеки координаты вытащить?
Помните такой аттракцион под названием "разбор предложения на члены"? Существительное там, глагол, подлежащее и т.п. Ну вот и тут так же - по сепаратору разбираете, потом делаете вывод - в текущем фрагменте текса координата или нет.
Принципиально я понимаю)) Но в програмировании не силен. Можете на примере показать?
Что вам даст пример программного кода, если вы принципиально его не понимаете?
У меня книжка есть. Я читать умею. А на конкретном примере я лучше понимаю.
Извольте пример: http://all-ht.ru/inf/prog/c/func/strtok.html
У меня книжка есть. Я читать умею. А на конкретном примере я лучше понимаю.
Задача: во входном потоке, читаемом из Serial найти стрoку вида
$GNGLL,5511.32245,N,06119.48690,E,171507.00,A,A*7C
И вытащить из неё красное число - широту и зелёное число - долготу.
Решение:
всегда, в любой задаче начинайте с полного высокоуровневого описания, вставляя низкоуровневые функции так, как если бы они у Вас уже были, не забывая чётко описывать что они должны делать. Когда верхний уровень написан, внимательно, всё проверьте и приступайте к написанию оставленных "на потом" функций. С ними поступайте также - расписывайте верхний уровень и спускайтесь ниже пока очередные функции не окажутся тривиальными.
Т.е. всегда двиайтесь по шагам. На место пока недостающих функций ставьте заглушки
Вот давайте: первый уровень
Вместо функции readLatLon, здесь написана заглушка, которая вроде как делает то, чего ожидает функция loop. Заглушка нужна для проверки, всё ли в порядке в loop.
Это надо запустить и проверить. И только если всё в порядке, переходить к следующему шагу. Если что-то не так - дожимать, отлаживать, а о следующем шаге даже не думать.
После того, как мы убедимся, что всё корректно работает (только после этого!) мы делаем вывод, что у нас всё в порядке и если мы сумеем написать правильную функцию readLatLon, то у нас всё будет замечательно.
Пока всё было понятно?
Следующий шаг - пишем функцию readLatLon:
Здесь мы написали всё, считая, что функция чтения строки из сериала (getStrFromSerial) у нас уже есть. Вместо неё пока поставили заглушку, которая всегда выдаёт правильную строку, которую "типа прочитала". опять же заглушка нужна для отладки функции readLatLon. Это надо запустить, проверить и т.п.
После того, как мы убедимся, что всё корректно работает (только после этого!) мы делаем вывод, что у нас всё в порядке и если мы сумеем написать правильную функцию getStrFromSerial, то у нас всё будет замечательно.
Следующий шаг - пишем функцию getStrFromSerial
Ну, вот теперь можете вводить ту Вашу строку в Serial и смотреть как она вполне корректно извлекает то, что нужно.
Главное, что я хотел показать. Не кидайтесь делать всё сразу - делайте по частям. Части бейте так, чтобы каждая была Вам понятна и обозрима. Вместо неготовых вещей используйте заглушки. котрые ведут себя "как настоящие". Переходите к написанию заглушек только когда всё их окружение точно работает как надо.
Тогда Вы будете всегда биться с маленьким, обозримым куском. Не пытайтесь написать всё сразу - и экран, и ввод, и вывод и ещё хрен знает что - только по кусочкам, шаг за шагом. Всё сразу Вы не отладите потому что "много всего" и что глючит - непонятно (а скорее всего ещё и "не одно что-то").
Вы уловили главную мысль?
Могу свой опыт привести. Я программирую больше лет, чем многие форумчане живут. Многие вещи. которые Вам кажутся проблемами. я делаю не думая, на автопилоте, НО я никогда не пишу функций (и стало быть не отлаживаю за раз) больших чем те. которые я могу увидеть на экране без листания. Я всегда вижу отлаживаемый кусок целиком. Вы же (я всех здешних новичков имею в виду) навалите строк триста и плачете "почему не работает". Я же столько даже не пытаюсь "навалить" - так же как и у Вас не заработает. Я делаю кусочками, которые я могу охватить взглядом и отлаживаю эти кусочки. Понимаете подход? Не валите всё в кучу. Вы в этой теме постоянно это делаете. У Вас ещё NMEA ни хрена не разбирается, а Вы уже туда на кой-то хрен экран пристроили. зачем? Чтобы одни ошибки на другие наложить?
Только, наверное, NMEA.
Наверное
ЕвгенийП, вот большое тебе, человеческое спасибо!
С мая месяца читаю разные форумы по ардуино, и почти всегда собеседниками являются мнящие себя профессионалами лузеры, которые восновном флудят и издеваются над теми, кто чуть меньше них знает. Но при этом пользы от них 0+ (в пределах случайной погрешности).
Огромный тебе респект за то, что потратил на меня свое время и интелект! Благодаря тебе, я перешел на новый уровень!))))
Со своей стороны обязуюсь усвоить, (хотя в приципе и так все предельно понятно) только запомнить нужно. Ну это практикой закрепится, я думаю.
всегда, в любой задаче начинайте с полного высокоуровневого описания, вставляя низкоуровневые функции так, как если бы они у Вас уже были, не забывая чётко описывать что они должны делать. Когда верхний уровень написан, внимательно, всё проверьте и приступайте к написанию оставленных "на потом" функций. С ними поступайте также - расписывайте верхний уровень и спускайтесь ниже пока очередные функции не окажутся тривиальными.
я никогда не пишу функций (и стало быть не отлаживаю за раз) больших чем те. которые я могу увидеть на экране без листания. Я всегда вижу отлаживаемый кусок целиком.
Рубрика "Вредные советы для новичков"?
А что не так? - вполне разумная рекомендация - оформлять код в виде коротких самодостаточных процедур и функций - в противоположность типичному коду начинающих, стремящихся всю программу запихнуть внутрь loop()
Рубрика "Вредные советы для новичков"?
А что не так? - вполне разумная рекомендация - оформлять код в виде коротких самодостаточных процедур и функций - в противоположность типичному коду начинающих, стремящихся всю программу запихнуть внутрь loop()
Рубрика "Вредные советы для новичков"?
А что не так? - вполне разумная рекомендация - оформлять код в виде коротких самодостаточных процедур и функций - в противоположность типичному коду начинающих, стремящихся всю программу запихнуть внутрь loop()
1. Начать с того, что если человек понимает, что такое функция и как оно работает, то он как бы и сам догадается. Если не понимает - то вопросы типа "а почему я не могу вот тут переменную созданную вон там" ему радости не добавят.
2. Проектирование приложения "сверху вниз" по уровням абстракции возможно только при довольно хорошем знании возможностей и ограничений инфраструктуры (языка, среды, платформы и т.п.). Иначе можно неприятно ткнуться носом в эти самые ограничения и недостаток возможностей. Сам с год назад наступил на эти грабли - архитектура, которую я придумал в ардуину не вписалась и немало уже написанного кода кода улетело тогда в корзину. Т.е. методика хорошая, но не для новичков.
3. Это вкусовщина, конечно, но формировать функции по критерию "чтобы помещалось в экран" - зло.
3. Это вкусовщина, конечно, но формировать функции по критерию "чтобы помещалось в экран" - зло.
Это классика времен Дейкстры.
Как постичь непостижимое
У Козьмы Петровича Пруткова этому посвящено целых пять пунктов списка афоризмов. Сколько тебе ещё нужно, чтобы понять?
2. Проектирование приложения "сверху вниз" по уровням абстракции возможно только при довольно хорошем знании возможностей и ограничений инфраструктуры (языка, среды, платформы и т.п.).
ИМХО, проектирование приложения всегда требует "знаний возможностей и ограничений инфраструктуры" - независмо от метода - "сверху вниз", справа-налево или еще как
Не, ну это
От новичков требуется тока уметь скачать из сети похожий скетч и запостить на форум вопль "памагити!". А знания, проектирование, это всё от лукавого.
TD27T, я прав?
для новичков loop() длиной в 4 файла - это намайна. так и надо.
для новичков loop() длиной в 4 файла - это намайна. так и надо.
ага. И еще нормально - всем, с кем не согласен - поставить в форуме -1
ага. И еще нормально - всем, с кем не согласен - поставить в форуме -1
Та тут это нинашто не влияет
2. Проектирование приложения "сверху вниз" по уровням абстракции возможно только при довольно хорошем знании возможностей и ограничений инфраструктуры (языка, среды, платформы и т.п.).
ИМХО, проектирование приложения всегда требует "знаний возможностей и ограничений инфраструктуры" - независмо от метода - "сверху вниз", справа-налево или еще как
3. Это вкусовщина, конечно, но формировать функции по критерию "чтобы помещалось в экран" - зло.
Нет, это добро.
А если возникают сомнения, берите 5К и ставьте его на попа.
https://www.nix.ru/autocatalog/lcd_iiyama/27-ZHK-monitor-IIYAMA-ProLite-XB2779QQS-S1-Silver-s-povorotom-ekrana-LCD-Wide-5120x2880-DVI-HDMI-DP_345195.html
нания требуются в любом случае, но, вот, при озвученном подходе, уровень этих знаний должен быть весьма высоким.
ну если понятие "область видимости переменных" (это то самое, что вы описали как "почему я не могу переменную здесь описанную там") - это высокий уровень знаний, то таки да, требуется высокий уровень :) И так требуется. что я бы даже есказал. что с более низким уровнем в программирование и соваться незачем.
И еще - если человек без знания инфрастуктуры написал кучу кода, которая не вписалась в ардуину и в итоге пропала даром - то это вовсе не из-за подхода "сверху вниз". Думаю, что без знаний этот человек ровно так же нагородил бы бесполезной ахинеи и при любом другом подходе.
3. Это вкусовщина, конечно, но формировать функции по критерию "чтобы помещалось в экран" - зло.
Нет, это добро.
А если возникают сомнения, берите 5К и ставьте его на попа.
Не стану разводить полемику по п.3, т.к., как я уже сказал - это вкусовщина и для программирования МК, когда текст всей программы со всеми библиотеками редко превышает пару тысяч строк проблема не так актуальна. Просто поясню моё негативное отношение к данной парадигме (к сожалению, не знаю как загнать текст под спойлер, ибо не всем он будет интересен и к ардуино отношения не имеет, но имеет к бездумному использованию и навязыванию спорных принципов построения кода).
Итак, в своём посте форумчанин сказал, что он никогда не пишет функций, текст которых не помещается в экран. Т.е. размер кода рассматривается как определяющий фактор. Нет, я понимаю, подразумевается, что вкупе с логической завершенностью, возможностью повторного использования и всё вот это вот. Но тем не менее. Одна контора, с которой мы сотрудничаем, некоторое время назад, похоже, приняла подобный подход в качестве корпоративного стандарта, ибо в их текстах начали появляться цепочки вызовов неприличной глубины и конструкции вида "делаемЧтоТо(), делаемЧтоТо_продолжаем(), делаемЧтоТо_продолжаемДалее()...". Бред, тупость, пофигизм? Ну так-то да, но мне вот с этим приходится жить. Почти привык уже, но бесит всё равно.
Лично я из ситуаций "10 функций по 1000 строк" и "160 функций по 60 строк" предпочту первую. Не стану дробить логически атомарный код в угоду размеру. Не буду выделять в функцию логику, которая не предполагает повторного использования (кроме случаев, когда того требует архитектура). Такой, вот, мой подход. На единственноправильность не претендую. Никому не навязываю.
нания требуются в любом случае, но, вот, при озвученном подходе, уровень этих знаний должен быть весьма высоким.
ну если понятие "область видимости переменных" (это то самое, что вы описали как "почему я не могу переменную здесь описанную там") - это высокий уровень знаний, то таки да, требуется высокий уровень :) И так требуется. что я бы даже есказал. что с более низким уровнем в программирование и соваться незачем.
И еще - если человек без знания инфрастуктуры написал кучу кода, которая не вписалась в ардуину и в итоге пропала даром - то это вовсе не из-за подхода "сверху вниз". Думаю, что без знаний этот человек ровно так же нагородил бы бесполезной ахинеи и при любом другом подходе.
Ну, это просто придирание к словам. Понятное дело, что всё нужно делать с умом. Ежели без ума, так ... пошли дурака Богу молиться.
И кстати, как раз категорическое "никогда" очень полезно именно для новичков, ты, просто, похоже, никогда не имел с ними дела так чтобы плотно (типа не преподавал, например). Тебя когда машину водить учили, не говорили что-нибудь типа "со временем начнёшь чувствовать когда нужно переключать передачи, а пока не чувствуешь - переключай 20-40-60". Также и здесь. Специалист понимает с чем он имеет дело и количество строк его не очень заботит, а вот как объяснить новичку. чтобы не писал длинных простыней? 10 - строк - это длинная? А 50? А 51? Где критерий "длинности"? Ему нужно дать понятный критерий, которым бы он мог пользоваться, пока не научится "чувствовать".
Лично я из ситуаций "10 функций по 1000 строк" и "160 функций по 60 строк" предпочту первую. Не стану дробить логически атомарный код в угоду размеру. Не буду выделять в функцию логику, которая не предполагает повторного использования (кроме случаев, когда того требует архитектура).
"Логически атомарный код" длиной 1000 строк? :) На языке высокого уровня, а не на асме?
Что-то ржу :)
ИМХО, вы просто не умеете выделять в коде логические блоки.
Когда пишу программу, я не забочусь специально о длине функций. Но как-то само получается, что большинство моих процедур содержат 10-20 строк. Даже не 60, как вы пишете.
Кстати то, что большинство ваших процедур не предполагают повторного использования - тоже признак того, что вы не видите в них логических частей и пишете как единое целое.
простой пример. Если вы опишете заварку чая и приготовление кофе как две огромное функции "готовим чай" и "готовим кофе" - у вас получится два куска по 1000 строк. А если расписать каждую как последовательность операций
"заливаем воду в емкость"
"зажигаем плиту"
"нагреваем воду"
"доводим до кипения"
"засыпаем кофе" или "добавляем заварку"
- то выяснится. что две трети процедур в обоих задачай - одинаковые, и итоговый код можно уместить в 1500 строк вместо 2000. А поскольку такие упрощения можно сделать на нескольких уровнях - то реально программа из процедур длиной в 50 строк будет раза в три-пять короче, чем аналогичная по функциям простыня из двух адовых кусков по 1000 строк.
Как вывод из вышеизложенного - никакой вкусовщиной тут и не пахнет. Выбора "10 функций по 1000 строк" или "160 функций по 60 строк" на самом деле нет. Написание длинных процедур (длиннее 30-50 строк примерно) - это просто низкий уровень проектирования программы.
Дорогой TD27T!
Ты ведь начинающий программист (и электронщик), о чем говорит простой поиск по твоему НИКу на форуме:
==============================================================
Слава Богу, сподобился таки я на старости лет узнать, что такое декомпозиция. Теперь понял хоть. :-)
Когда пишу программу, я не забочусь специально о длине функций. Но как-то само получается, что большинство моих процедур содержат 10-20 строк.
Та авнакодеров то везде хватает. Особенно в SQL
Дед, та ладно Вам! Ещё одно слово узнали? Помаленьку становитесь "культурной девушкой"? :))))