Всем привет. Хочу получить скорость и в зависимости от ее величины делать определенные манипуляции, например, зажечь светодиод. Вижу 2 пути решения. 1) Если использовать стандартную библиотеку Esprino, взятый по ссылкам ниже, http://wiki.amperka.ru/продукты:troyka-gps-glonass https://www.espruino.com/GPS Код (Javascript): Serial3.setup(115200, {rx: P0, tx: P1}); var gps = require("GPS").connect(Serial3, function(data) { console.log(data); }); то выводится следующие данные: Код (Javascript): { "time":"16:35:29", "lat":53.068403,"lon":-4.076282,"fix":1,"satellites":7,"altitude":1085.0 } соответственно зная широту, долготу и время в момент T1 и T0 то можно посчитать пройденное расстояние, а из него получить скорость c точностью 0,3%, что мне достаточно. код здесь https://www.movable-type.co.uk/scripts/latlong.html Проблема Как из этого добра получить широту и долготу в T0 и T1 и передать переменной? Код (Javascript): Serial3.setup(115200, {rx: P0, tx: P1}); var gps = require("GPS").connect(Serial3, function(data) { console.log(data); }); В консоль данные выводятся, а вот переменной передаваться упорно не хотят. Если сделать как-нибудь так Код (Javascript): Serial3.setup(115200, {rx: P0, tx: P1}); var gps = require("GPS").connect(Serial3, function(data) { T1=data; return T1; }) console.log(gps); ; то выводятся пустые значения. Видимо контроллер не успевает за платой или происходит, что то типа того. Может быть в массив как-то можно все складывать, или запрогать получение ответа от контроллера перед выводом, или еще что то придумать. Не знаю, как эти данные правильно вытащить из выражения выше . 2) Если общаться с Serial. Имеем: Использовал такой код Код (C++): Serial3.setup(115200, {rx: P0, tx: P1}); var bufer=''; Serial3.on('data',function(data){ bufer +=data; var lines = bufer.split('$'); bufer =lines [lines.length-1]; if (lines.length >1){ for (l=0;l<lines.length-1;l++){ print(lines[l]);}}}); Проблема Как результат,он выводит все, что передает GPS контроллер но здесь http://www.gpsinformation.org/dale/nmea.htm я сообщений с таким кодами не нашел и соответственно не понимаю какая позиция, что значит и как это все дело грамотно распарсить, чтобы вытянуть скорость. для С++есть куча библиотек и готовых решений, а тут что-то пошло не так =(
В общем идя по пути 1 с помощью зарубежных комрадов я накодил вот такую штуку, но бывают какие-то странные выбросы если спутников не видит =( типа 45 км/ ч в состоянии покоя). надо как-то побороть искажения хз как. В целом на машине протестил с показаниями яндекс навигатора визуально совнадает. Код (Javascript): //********* конектимся к GPS приемнику Serial3.setup (115200, {rx: P0, tx: P1}); var R = 6371e3; // радиус земли в метрах var Led= require('@amperka/led').connect(A1);//вводим светодиод var lastData; // все данные полученные от GPS в T0 var lastData2; //секунды в T0*** var lastLon; // широта в T0 var lastLat; // долгота в T0 var LastTime; // предыдущее время var toRad=Math.PI/180; // переводим в радианы var i=0;//ограничитель выводов инфы в консоль var gps = require ("GPS"). connect (Serial3, function (data) { if (lastData,i<50) { //ограничиваем 50-ю измерениями, чтобы проанализировать надо убрать результат // do stuff here - eg. the difference between the two readings //****** расстояние var Lon=data.lon*toRad; // lon в t1 var Lat=data.lat*toRad; //lat в t1 var diffLon=Math.abs(Lon-lastLon*toRad); //ищем дельту var diffLat= Math.abs(Lat-lastLat*toRad); //ищем дельту //************************************** блок расчета расстояния var a= Math.sin(diffLat/2) * Math.sin(diffLat/2) + Math.cos(Lat) * Math.cos(lastLat*toRad) * Math.sin(diffLon/2) * Math.sin(diffLon/2); var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); var distansP = R * c; //****** время между измерениями var tTime= data.time.split(':'); // массив чч мм tTime=tTime[2]; var diffTime=tTime-LastTime; //****** скорость var speed1= distansP/diffTime; // м/с var speed2= speed1*3.6; // км/ч //********************зажигаем диод если скорость больше 60 if(speed2>40){ Led.turnOn(); } else{Led.turnOff();} console.log(speed2,speed1); // выводим скорость в консоль //console.log ('1',Math.sin(diffLat/2),diffLat/2,'2',Math.cos(Lat), '3',Math.cos(lastLat*toRad),lastLat*toRad,'4',Math.sin(diffLon/2),'5',Math.sin(diffLon/2),'6',Math.sqrt(a),a,'7',Math.sqrt(1-a),'8',diffTime ); } // передаем предыдущие показания lastData=data; lastLon=data.lon; //в градусах lastLat=data.lat; //в градусах LastTime= data.time.split(':'); //сохраняем предыдущее значение времени в массив LastTime= LastTime[2]; // вытаскиваем изменение секунд // lastData = data.time.split(':'); //lastData2 = lastData[2]; // lastLon= data.lon; i=i+1; /ограничитель выводов инфы в консоль. надо убрать чтоб работало в авто. });
Подскажите, пожалуйста, измерения происходят раз в секунду или чаще? Есть ли возможность увеличить частоту приема сигнала до десяти раз в секунду, как для библиотек Arduino?
1) - смотри даташит на ЖПС приемник - выше, чем он отдает, не прыгнуть 2) - ЖПС уже сам может отдавать скорость - зачем изобретать велосипед? почитайте о протоколе NMEA - там много чего с вашего ЖПС идет интересного и да, не обязательно брать библиотеки - можно просто парсить что приходит на порт как пришло $ - начало строки - читать и сравнивать с шаблоном а дабы не было ошибок - под конец каждой строки есть хешсумма, сверили, если верно - собранные данные пускать в дело
Ну созданием нормальных библиотек никто так и не озаботился и походу тема с espruino потихоньку помирает и до ардуино им очень далеко. Безгеморно на этой платформе можно только задачи из наборчика йодо решать, если чуть в сторону, то получаешь сразу кучу гемора. Если идти по вар. 2. (см мой первый пост), то сообщения со спутника приходят гораздо чаще, чем раз в секунду, и очень много сообщений. Как правильно распарсить и какое сообщение со спутника парсить, чтобы вытащить скорость, я так и не разобрался. Кстати продавец контроллера мог бы и написать какие конкретно сообщения он принимает и что в них что значит. То же самое могу сказать и про гребаный гланас. За пару часов нагуглить справочник по их сообщениям не поучилось.
https://labs.mediatek.com/en/chipset/MT3333 https://labs.mediatek.com/en/download/VT9qMakW https://ru.wikipedia.org/wiki/NMEA_0183 https://ru.wikipedia.org/wiki/ГЛОНАСС https://www.sparkfun.com/datasheets/GPS/NMEA Reference Manual1.pdf http://gnss.4du.ru/wp-content/uploads/2016/02/NMEA.pdf это все в дополнение к тому что уже есть на http://wiki.amperka.ru/продукты:troyka-gps-glonass : http://naviaglonass.ru/wp-content/uploads/Apparatura-navigatsionnaya-NL3333-RE`-v1_2.pdf http://naviaglonass.ru/wp-content/uploads/Opisanie-komand-NL3333_KL3333-i-SL3333E-v1_0.pdf https://www.espruino.com/GPS http://www.gpsinformation.org/dale/nmea.htm http://www.espruino.com/modules/GPS.js так чего не хватает?
Таким образом получается, что для измерения скорости в принципе не нужны дополнительные танцы. Все данные выводятся, например, в рекомендованном минимальном наборе данных (команда $RMC). Для смены скорости сообщений, например, до десяти раз в секунду (http://wiki.amperka.ru/продукты:troyka-gps-glonass) нужно отправить из консоли соответствующую команду типа РМТК220 (с предварительно подсчитанной для нее чек-суммой). Это справедливо для Iskra JS? Кстати в коде, представленном по ссылке http://www.espruino.com/modules/GPS.js указано условие: if (tag=="GGA") Вероятно, если подставить if (tag=="RMC"), то будет выводиться минимальный набор данных, включая скорость, правда в узлах (но это не проблема). Далее, надо распарсить строку, зная где находится значение скорости. Правильно ли я понимаю суть вопроса?
да RMC - ваше всё ) жаль в нем нет высоты только но никто не мешает распарсивать и RMС и GGA а если приемник отдает то и ZDA - там дата время хранится
ну хз там большая часть сообщений RMС Такт ну давно это было. Насколько я помню и судя по моему посту rmc он не выводит. Выводит что то чего в справочниках по сообщениям gps нет.
В общем в Вики амперки все написано для Ардуино. Для искры js есть стандартный запрос, который выводит небольшой набор данных, в котором даже скорости нет. Если брать все данные, которые с контроллера приходят (см пост 1 вар. 2) то получаю сообщения, которые в справочниках не ищутся. Соответственно, вопрос можно сформулировать так: Какой код написать, чтобы получить скорость в км/ч из sme сообщений. То, что я делал, см выше. Распарить не получилось. PsPs же подробно все расписал.
подключите ЖПС к компу и посмотрите в мониторе порта что с него идет и сюда выложите сразу будет видно что есть и что брать
я брал, у меня парсер простейший именно эту группу и распарсивает вот собственно сам код, - как пример как распарсивать.... Код (C++): if(gps_valid) {digitalWrite(LED_GPS, 1);}else{digitalWrite(LED_GPS, 0);} while(true) if(gps.available()) { char ch=gps.read(); // Serial.print(ch); if(ch == '$') { cnt = 0; csv = 0; fix = 0; } else { data[cnt++] = ch; /* сбор символов /**/ if(ch == ',') { data[--cnt] = 0; /* если нашли , то ставим 0 (конец строки) /**/ cnt = 0; csv++; if(csv == 1) { res = strcmp(data,"GPRMC"); if(res == 0) fix = 1; } if(fix == 1) { // Serial.print(": ");Serial.println(data); if(csv == 2) { time=data; hour=((data[0]-48)*10+(data[1]-48)); minute=((data[2]-48)*10+(data[3]-48)); second=((data[4]-48)*10+(data[5]-48)); } else if(csv == 3) { if(data[0]==65){ gps_valid=true;}else if(data[0]==86){gps_valid=false;}} else if(csv == 4) { data[4]=data[3];data[3]=data[2];data[2]='\0'; lat = atol(data) + ((atol(data+3)/60.0)/10000.0); } else if(csv == 6) { data[5]=data[4];data[4]=data[3];data[3]='\0'; lng = atol(data) + ((atol(data+4)/60.0)/10000.0); } else if(csv == 8) { spd = atof(data); spd>0.50?spd*=1.852:spd=0; } else if(csv == 9) { crs = atoi(data); } else if(csv == 10){ date=data; day=((data[0]-48)*10+(data[1]-48)); month=((data[2]-48)*10+(data[3]-48)); year=((data[4]-48)*10+(data[5]-48)); } else if(csv == 11) {int i=0;fix = 0; long dist_tmp = 0; if(latp==0 || lngp==0 ) {latp=lat; lngp=lng; } if(latp!=lat || lngp!=lng) {dist_tmp = distance_between(lat,lng,latp,lngp); latp=lat; lngp=lng; } if(btn_b[5]){ dist=dist+dist_tmp; } if(btn_b[4]){ dist=dist-dist_tmp; } if(gps_valid){ gps_info(); /*************************************************/ if(fname==""){ fname=date+".plt"; sd_filename_chek: Serial.println(fname); if(!SD.exists(fname)){ //если файла нет такого Serial.println("SD creat File "+fname); LosGps = SD.open(fname, FILE_WRITE); if(!LosGps){ //если НЕ удалось открыть файл SD.begin(SD_CS);LosGps = SD.open(fname, FILE_WRITE); Serial.print("SD Reopen!"); //репеподключаю и переоткрываю } if(LosGps) { //если удалось открыть файл LosGps.println("OziExplorer Track Point File Version 2.0"); LosGps.println("WGS 84"); LosGps.println("Altitude is in Feet"); LosGps.println("Reserved 3"); LosGps.println("0,2,255,Treck Start "+date+" "+time+",1,0,F80"); //0,ширина,цыет,название,нормально,0,цветр ржб заполнения http://www.oziexplorer3.com/eng/help/fileformats.html LosGps.println(" "); //точек в треке LosGps.close(); } else {Serial.print("SD NO!"); } } else { fname = "_"+fname; goto sd_filename_chek; } }else{ if(dist_tmp!=0){ Serial.println("SD write GPS"); LosGps = SD.open(fname, FILE_WRITE); if(LosGps){ LosGps.print(lat,6); LosGps.print(", "); LosGps.print(lng,6); LosGps.print(", 0, ");//Код - 0, если это нормально, 1, если перерыв в дорожке. LosGps.print("-777, "); /*высота*///Высота в футах (-777, если не действительна). LosGps.print(", "); /*время делфи*/ LosGps.print(date); LosGps.print(", "); LosGps.print(time); LosGps.println(" "); LosGps.close(); } else { //не удалось открыть файл!! Serial.println("SD WARNING !!!! no open file!!!"); } } } /*************************************************/ }else{Serial.println("GPS Sat NO SIGNAL!");} break; } } } } } там в куче запись трека на Сд карту и светодиод статуса жпс есть не чистил от лишнего, не указывал объявления переменных и подключение порта - выложил чисто как пример простейшего парсинга.... код ищет начало строки $ потом ключевое слово GPRMC (можно и другие поставить) и потом просто разбирает по запятым на блоки // проверки хешсуммы строк нету ------------- //и да, не забывайте, что ЖПС приемник координаты может отдавать в РАЗНЫХ форматах!! (точнее одном из возможных форматов) есть 3 основных формата ЖПС координат - так что тут повнимательнее, если вам потом надо будет их переводить в путь или накладывать на карту!