Добрый день.
Искал решение проблемы в топиках, но так и не добрался до сути.
Использую Arduino Nano в связке с A7 GPRS/GSM/GPS модулем.
Для связи, использую Software Serial на 4 и 5 пине. BaudRate = 9600/
Библиотеки: TinyGsmClient, NMEAGPS, BlynkSimpleTinyGSM, SoftwareSerial.
Если запускать скетч, который не использует Blynk, а просто соединяется с модулем A7 и выдаёт в монитор порта, данные с GPS, то всё красиво. Данные есть, их можно разобрать.
Но, хотел использовать Blynk для оболочки, чтобы удобно передавать координаты GPS с модуля A7 на приложение Blynk, например в виджет Map, или просто широту и долготу в виртуальные переменные.
И тут возникла проблема, если в цикле loop работает Blynk,run(), то как я понимаю, все данные из Software Serial он обрабатывает сам.
Следовательно, я в скетче, не могу уже отловить отдельно, что поступили данные, и проверить их на формат NMEA, и уже потом разобрать их.
Если запускать Blynk.run() по таймеру (что конечно противоречит документации), то первое время работы скетча, я данные получаю, и они отправляются в виджет.
Но, через какое-то время, я теряю соединение с Blynk.
Подскажите, какое может быть решение данного вопроса? Возможно, надо каким-то образом, отслеживать поток обмена Blynk в arduino? и из него уже брать нужные данные, если они в формате NMEA?
Код скетча
[code]
#include <NMEAGPS.h>
#define TINY_GSM_MODEM_A7
#include <TinyGsmClient.h>
int j = 0;
#define BLYNK_PRINT Serial // Comment this out to disable prints and save space
#define BLYNK_DEBUG
#define BLYNK_TIMEOUT_MS 6000UL
#define BLYNK_HEARTBEAT 60
//#define BLYNK_DEBUG_ALL Serial
#include <BlynkSimpleTinyGSM.h>
SimpleTimer timer;
// Your GPRS credentials
// Leave empty, if missing user or pass
const char apn[] = "";
const char user[] = "";
const char pass[] = "";
// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
const char auth[] = "Здесь код устройства Blynk";
//#include <SoftwareSerial.h>
//SoftwareSerial GSM_m(4, 5); // RX, TX
WidgetTerminal terminal(V1);
//======================================================================
// Program: NMEA.ino
//
// Description: This program uses the fix-oriented methods available() and
// read() to handle complete fix structures.
//
// When the last character of the LAST_SENTENCE_IN_INTERVAL (see NMEAGPS_cfg.h)
// is decoded, a completed fix structure becomes available and is returned
// from read(). The new fix is saved the 'fix' structure, and can be used
// anywhere, at any time.
//
// If no messages are enabled in NMEAGPS_cfg.h, or
// no 'gps_fix' members are enabled in GPSfix_cfg.h, no information will be
// parsed, copied or printed.
//
// Prerequisites:
// 1) Your GPS device has been correctly powered.
// Be careful when connecting 3.3V devices.
// 2) Your GPS device is correctly connected to an Arduino serial port.
// See GPSport.h for the default connections.
// 3) You know the default baud rate of your GPS device.
// If 9600 does not work, use NMEAdiagnostic.ino to
// scan for the correct baud rate.
// 4) LAST_SENTENCE_IN_INTERVAL is defined to be the sentence that is
// sent *last* in each update interval (usually once per second).
// The default is NMEAGPS::NMEA_RMC (see NMEAGPS_cfg.h). Other
// programs may need to use the sentence identified by NMEAorder.ino.
// 5) NMEAGPS_RECOGNIZE_ALL is defined in NMEAGPS_cfg.h
//
// 'Serial' is for debug output to the Serial Monitor window.
//
// License:
// Copyright (C) 2014-2017, SlashDevin
//
// This file is part of NeoGPS
//
// NeoGPS is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// NeoGPS is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with NeoGPS. If not, see <http://www.gnu.org/licenses/>.
//
//======================================================================
//-------------------------------------------------------------------------
// The GPSport.h include file tries to choose a default serial port
// for the GPS device. If you know which serial port you want to use,
// edit the GPSport.h file.
#include <GPSport.h>
//------------------------------------------------------------
// For the NeoGPS example programs, "Streamers" is common set
// of printing and formatting routines for GPS data, in a
// Comma-Separated Values text format (aka CSV). The CSV
// data will be printed to the "debug output device".
// If you don't need these formatters, simply delete this section.
#include <Streamers.h>
//------------------------------------------------------------
// This object parses received characters
// into the gps.fix() data structure
static NMEAGPS gps;
//------------------------------------------------------------
// Define a set of GPS fix information. It will
// hold on to the various pieces as they are received from
// an RMC sentence. It can be used anywhere in your sketch.
static gps_fix fix;
//----------------------------------------------------------------
// This function gets called about once per second, during the GPS
// quiet time. It's the best place to do anything that might take
// a while: print a bunch of things, write to SD, send an SMS, etc.
//
// By doing the "hard" work during the quiet time, the CPU can get back to
// reading the GPS chars as they come in, so that no chars are lost.
static void doSomeWork()
{
// Print all the things!
trace_all( DEBUG_PORT, gps, fix );
trace_all( terminal, gps, fix );
} // doSomeWork
//#define DUMP_AT_COMMANDS
#define TINY_GSM_DEBUG DEBUG_PORT
#ifdef DUMP_AT_COMMANDS
#include <StreamDebugger.h>
StreamDebugger debugger(gpsPort, DEBUG_PORT);
TinyGsm modem(debugger);
#else
TinyGsm modem(gpsPort);
#endif
void RepeatTask() {
DEBUG_PORT.println("1 second timer for run");
Blynk.run();
}
//------------------------------------
// This is the main GPS parsing loop.
static void GPSloop()
{
while (gps.available( gpsPort )) {
DEBUG_PORT.println("GPS Availible!");
fix = gps.read();
doSomeWork();
}
} // GPSloop
//--------------------------
void setup()
{
DEBUG_PORT.begin(9600);
while (!DEBUG_PORT)
;
DEBUG_PORT.print( F("NMEA.INO: started\n") );
DEBUG_PORT.print( F(" fix object size = ") );
DEBUG_PORT.println( sizeof(gps.fix()) );
DEBUG_PORT.print( F(" gps object size = ") );
DEBUG_PORT.println( sizeof(gps) );
DEBUG_PORT.println( F("Looking for GPS device on " GPS_PORT_NAME) );
#ifndef NMEAGPS_RECOGNIZE_ALL
#error You must define NMEAGPS_RECOGNIZE_ALL in NMEAGPS_cfg.h!
#endif
#ifdef NMEAGPS_INTERRUPT_PROCESSING
#error You must *NOT* define NMEAGPS_INTERRUPT_PROCESSING in NMEAGPS_cfg.h!
#endif
#if !defined( NMEAGPS_PARSE_GGA ) & !defined( NMEAGPS_PARSE_GLL ) & \
!defined( NMEAGPS_PARSE_GSA ) & !defined( NMEAGPS_PARSE_GSV ) & \
!defined( NMEAGPS_PARSE_RMC ) & !defined( NMEAGPS_PARSE_VTG ) & \
!defined( NMEAGPS_PARSE_ZDA ) & !defined( NMEAGPS_PARSE_GST )
DEBUG_PORT.println( F("\nWARNING: No NMEA sentences are enabled: no fix data will be displayed.") );
#else
if (gps.merging == NMEAGPS::NO_MERGING) {
DEBUG_PORT.print ( F("\nWARNING: displaying data from ") );
DEBUG_PORT.print ( gps.string_for( LAST_SENTENCE_IN_INTERVAL ) );
DEBUG_PORT.print ( F(" sentences ONLY, and only if ") );
DEBUG_PORT.print ( gps.string_for( LAST_SENTENCE_IN_INTERVAL ) );
DEBUG_PORT.println( F(" is enabled.\n"
" Other sentences may be parsed, but their data will not be displayed.") );
}
#endif
DEBUG_PORT.print ( F("\nGPS quiet time is assumed to begin after a ") );
DEBUG_PORT.print ( gps.string_for( LAST_SENTENCE_IN_INTERVAL ) );
DEBUG_PORT.println( F(" sentence is received.\n"
" You should confirm this with NMEAorder.ino\n") );
trace_header( DEBUG_PORT );
DEBUG_PORT.flush();
gpsPort.begin( 9600 );
Blynk.begin(auth, modem, apn, user, pass);
DEBUG_PORT.println("Activation GPS ...");
gpsPort.println("AT+GPS=1"); // Включаем GPS
delay(3000);
gpsPort.println("AT+GPSRD=1"); // Включаем GPS данные
delay(1000);
timer.setInterval(1000, RepeatTask);
//terminal.clear();
DEBUG_PORT.println("Started!");
}
//--------------------------
void loop()
{
if (j==0) {
DEBUG_PORT.println("Run!");
j=1;}
GPSloop();
timer.run();
//Blynk.run();
}
[/code]
Вот что получаю в мониторе порта:
18:19:52.806 -> NMEA.INO: started
18:19:52.806 -> fix object size = 31
18:19:52.840 -> gps object size = 84
18:19:52.873 -> Looking for GPS device on SoftwareSerial( RX pin 4, TX pin 5 )
18:19:52.942 ->
18:19:52.942 -> GPS quiet time is assumed to begin after a RMC sentence is received.
18:19:53.010 -> You should confirm this with NMEAorder.ino
18:19:53.043 ->
18:19:53.043 -> Status,UTC Date/Time,Lat,Lon,Hdg,Spd,Alt,Sats,Rx ok,Rx err,Rx chars,
18:19:53.111 -> [328]
18:19:53.146 -> ___ __ __
18:19:53.146 -> / _ )/ /_ _____ / /__
18:19:53.180 -> / _ / / // / _ \/ '_/
18:19:53.213 -> /____/_/\_, /_//_/_/\_\
18:19:53.247 -> /___/ v0.6.1 on Arduino Nano
18:19:53.281 ->
18:19:53.281 -> [420] Modem init...
18:19:57.727 -> [4907] Connecting to network...
18:19:59.286 -> [6463] Network: MegaFon
18:19:59.286 -> [6463] Connecting to ...
18:20:05.049 -> [12239] Connected to GPRS
18:20:05.252 -> [12419] Connecting to blynk-cloud.com:80
18:20:08.816 -> [15976] <[1D|00|01|00] "Здесь код устройства Blynk"
18:20:09.937 -> [17101] >[00|00|01|00|C8]
18:20:09.937 -> [17102] Ready (ping: 108ms).
18:20:09.971 -> [17103] Free RAM: 552
18:20:10.006 -> [17187] <[11|00|02|00]bver[00]0.6.1[00]h-beat[00]60[00]buff-in[00]256[00]dev[00]Arduino Nano[00]cpu[00]ATmega328P[00]con[00]A7[00]build[00]Aug 16 2019 18:16:14[00]
18:20:10.923 -> Activation GPS ...
18:20:14.931 -> Started!
18:20:14.931 -> Run!
18:20:15.201 -> GPS Availible!
18:20:15.201 -> 0,,,,,,,0,2,0,129,
18:20:15.957 -> 1 second timer for run
18:20:16.161 -> GPS Availible!
18:20:16.161 -> 0,,,,,,,0,5,0,223,
18:20:16.941 -> 1 second timer for run
18:20:17.179 -> GPS Availible!
18:20:17.179 -> 0,,,,,,,0,8,0,316,
18:20:17.962 -> 1 second timer for run
18:20:18.266 -> GPS Availible!
18:20:18.266 -> 0,,,,,,,0,13,0,458,
18:20:18.334 -> [25508] <[14|00|03|00]Evw[00]1[00]0,,,,,,,0,2,0,129,[0A]0,,,,,,,0,5,0,223,[0A]0,,,,,,,0,8,0,316,[0A]0,,,,,,
18:20:20.233 -> 1 second timer for run
18:20:20.946 -> 1 second timer for run
18:20:21.184 -> GPS Availible!
18:20:21.184 -> 0,,,,,,,0,15,0,525,
18:20:21.968 -> 1 second timer for run
18:20:22.172 -> GPS Availible!
18:20:22.172 -> 0,,,,,,,0,18,0,617,
18:20:22.952 -> 1 second timer for run
18:20:23.289 -> GPS Availible!
18:20:23.289 -> 0,,,,,,,0,23,0,760,
18:20:23.323 -> [30504] <[14|00|04|00]Evw[00]1[00],0,13,0,458,[0A]0,,,,,,,0,15,0,525,[0A]0,,,,,,,0,18,0,617,[0A]0,,,,,,,0,2
18:20:24.990 -> 1 second timer for run
18:20:25.193 -> GPS Availible!
18:20:25.193 -> 0,,,,,,,0,25,0,826,
18:20:25.971 -> 1 second timer for run
18:20:26.175 -> GPS Availible!
18:20:26.175 -> 0,,,,,,,0,28,0,920,
18:20:26.962 -> 1 second timer for run
18:20:27.163 -> GPS Availible!
18:20:27.163 -> 0,,,,,,,0,31,0,1013,
18:20:27.230 -> [34400] <[14|00|05|00]Evw[00]1[00]3,0,760,[0A]0,,,,,,,0,25,0,826,[0A]0,,,,,,,0,28,0,920,[0A]0,,,,,,,0,31,0,
18:20:28.859 -> 1 second timer for run
18:20:28.961 -> 1 second timer for run
18:20:29.166 -> GPS Availible!
18:20:29.166 -> 0,,,,,,,0,33,0,1079,
18:20:29.995 -> 1 second timer for run
18:20:30.181 -> GPS Availible!
18:20:30.181 -> 0,,,,,,,0,36,0,1173,
18:20:30.960 -> 1 second timer for run
18:20:31.164 -> GPS Availible!
18:20:31.164 -> 0,,,,,,,0,39,0,1266,
18:20:31.231 -> [38398] <[14|00|06|00]Evw[00]1[00]1013,[0A]0,,,,,,,0,33,0,1079,[0A]0,,,,,,,0,36,0,1173,[0A]0,,,,,,,0,39,0,1
18:20:32.965 -> 1 second timer for run
18:20:32.965 -> 1 second timer for run
18:20:33.270 -> GPS Availible!
18:20:33.270 -> 0,,,,,,,0,43,0,1381,
18:20:33.980 -> 1 second timer for run
18:20:34.184 -> GPS Availible!
18:20:34.184 -> 0,,,,,,,0,46,0,1475,
18:20:34.963 -> 1 second timer for run
18:20:35.167 -> GPS Availible!
18:20:35.167 -> 0,,,,,,,0,49,0,1567,
18:20:35.235 -> [42393] <[14|00|07|00]Evw[00]1[00]266,[0A]0,,,,,,,0,43,0,1381,[0A]0,,,,,,,0,46,0,1475,[0A]0,,,,,,,0,49,0,15
18:20:36.862 -> 1 second timer for run
18:20:36.965 -> 1 second timer for run
18:20:37.168 -> GPS Availible!
18:20:37.168 -> 0,,,,,,,0,51,0,1633,
18:20:37.981 -> 1 second timer for run
18:20:38.287 -> GPS Availible!
18:20:38.287 -> 0,,,,,,,0,56,0,1775,
18:20:38.965 -> 1 second timer for run
18:20:39.169 -> GPS Availible!
18:20:39.169 -> 0,,,,,,,0,59,0,1869,
18:20:39.238 -> [46392] <[14|00|08|00]Evw[00]1[00]67,[0A]0,,,,,,,0,51,0,1633,[0A]0,,,,,,,0,56,0,1775,[0A]0,,,,,,,0,59,0,186
18:20:40.898 -> 1 second timer for run
18:20:40.966 -> 1 second timer for run
18:20:41.169 -> GPS Availible!
18:20:41.169 -> 0,,,,,,,0,61,0,1935,
18:20:41.984 -> 1 second timer for run
18:20:42.187 -> GPS Availible!
18:20:42.187 -> 0,,,,,,,0,64,0,2028,
18:20:42.972 -> 1 second timer for run
18:20:43.276 -> GPS Availible!
18:20:43.276 -> 0,,,,,,,0,69,0,2170,
18:20:43.345 -> [50491] <[14|00|09|00]Evw[00]1[00]9,[0A]0,,,,,,,0,61,0,1935,[0A]0,,,,,,,0,64,0,2028,[0A]0,,,,,,,0,69,0,2170
18:20:45.007 -> 1 second timer for run
18:20:45.176 -> GPS Availible!
18:20:45.176 -> 0,,,,,,,0,71,0,2237,
18:20:45.990 -> 1 second timer for run
18:20:46.193 -> GPS Availible!
18:20:46.193 -> 0,,,,,,,0,74,0,2329,
18:20:46.973 -> 1 second timer for run
18:20:47.177 -> GPS Availible!
18:20:47.177 -> 0,,,,,,,0,77,0,2423,
18:20:47.244 -> [54385] <[14|00|0A|00]Evw[00]1[00],[0A]0,,,,,,,0,71,0,2237,[0A]0,,,,,,,0,74,0,2329,[0A]0,,,,,,,0,77,0,2423,
18:20:48.906 -> 1 second timer for run
18:20:48.974 -> 1 second timer for run
18:20:49.178 -> GPS Availible!
18:20:49.178 -> 0,,,,,,,0,79,0,2489,
18:20:49.990 -> 1 second timer for run
18:20:50.193 -> GPS Availible!
18:20:50.193 -> 0,,,,,,,0,82,0,2583,
18:20:50.973 -> 1 second timer for run
18:20:51.177 -> GPS Availible!
18:20:51.177 -> 0,,,,,,,0,85,0,2675,
18:20:51.245 -> [58383] <[14|00|0B|00]Evw[00]1[00|0A]0,,,,,,,0,79,0,2489,[0A]0,,,,,,,0,82,0,2583,[0A]0,,,,,,,0,85,0,2675,[0A]
18:20:52.839 -> 1 second timer for run
18:20:52.976 -> 1 second timer for run
18:20:53.280 -> GPS Availible!
18:20:53.280 -> 0,,,,,,,0,89,0,2791,
18:20:53.998 -> 1 second timer for run
18:20:54.161 -> GPS Availible!
18:20:54.161 -> 0,,,,,,,0,92,0,2883,
18:20:54.973 -> 1 second timer for run
18:20:55.176 -> GPS Availible!
18:20:55.176 -> 0,,,,,,,0,95,0,2976,
18:20:55.990 -> 1 second timer for run
18:20:56.192 -> GPS Availible!
18:20:56.192 -> 0,,,,,,,0,98,0,3070,
18:20:56.226 -> [63378] <[14|00|0C|00]Evw[00]1[00]0,,,,,,,0,89,0,2791,[0A]0,,,,,,,0,92,0,2883,[0A]0,,,,,,,0,95,0,2976,[0A]0
18:20:57.819 -> 1 second timer for run
18:20:57.990 -> 1 second timer for run
18:20:58.262 -> GPS Availible!
18:20:58.262 -> 0,,,,,,,0,102,0,3185,
18:20:58.975 -> 1 second timer for run
18:20:59.179 -> GPS Availible!
18:20:59.179 -> 0,,,,,,,0,105,0,3278,
18:20:59.247 -> [66379] <[14|00|0D|00]Evw[00]1[00],,,,,,,0,98,0,3070,[0A]0,,,,,,,0,102,0,3185,[0A]0,,,,,,,0,105,0,3278,[0A]
18:21:01.009 -> 1 second timer for run
18:21:01.179 -> GPS Availible!
18:21:01.179 -> 0,,,,,,,0,107,0,3344,
18:21:01.993 -> 1 second timer for run
18:21:02.164 -> GPS Availible!
18:21:02.164 -> 0,,,,,,,0,110,0,3437,
18:21:02.977 -> 1 second timer for run
18:21:03.281 -> GPS Availible!
18:21:03.281 -> 0,,,,,,,0,115,0,3579,
18:21:03.349 -> [70477] <[14|00|0E|00]Evw[00]1[00]0,,,,,,,0,107,0,3344,[0A]0,,,,,,,0,110,0,3437,[0A]0,,,,,,,0,115,0,3579
18:21:04.977 -> 1 second timer for run
18:21:05.011 -> 1 second timer for run
18:21:05.181 -> GPS Availible!
18:21:05.181 -> 0,,,,,,,0,117,0,3645,
18:21:05.998 -> 1 second timer for run
18:21:06.167 -> GPS Availible!
18:21:06.167 -> 0,,,,,,,0,120,0,3738,
18:21:06.979 -> 1 second timer for run
18:21:07.183 -> GPS Availible!
18:21:07.183 -> 0,,,,,,,0,123,0,3832,
18:21:07.251 -> [74374] <[14|00|0F|00]Evw[00]1[00],[0A]0,,,,,,,0,117,0,3645,[0A]0,,,,,,,0,120,0,3738,[0A]0,,,,,,,0,123,0,38
18:21:08.914 -> 1 second timer for run
18:21:08.982 -> 1 second timer for run
18:21:09.186 -> GPS Availible!
18:21:09.186 -> 0,,,,,,,0,125,0,3898,
18:21:10.003 -> 1 second timer for run
18:21:10.037 -> [77175] <[06|00|10|00|00]
18:21:12.073 -> 1 second timer for run
18:21:12.176 -> GPS Availible!
18:21:12.176 -> 0,,,,,,,0,128,0,3991,
18:21:12.990 -> 1 second timer for run
18:21:13.295 -> GPS Availible!
18:21:13.295 -> 0,,,,,,,0,133,0,4157,
18:21:13.329 -> [80470] <[14|00|11|00]Evw[00]1[00]32,[0A]0,,,,,,,0,125,0,3898,[0A]0,,,,,,,0,128,0,3991,[0A]0,,,,,,,0,133,0,
18:21:15.263 -> 1 second timer for run
18:21:16.010 -> 1 second timer for run
18:21:16.180 -> GPS Availible!
18:21:16.180 -> 0,,,,,,,0,135,0,4223,
18:21:16.993 -> 1 second timer for run
18:21:17.027 -> [84175] <[06|00|12|00|00]
18:21:18.621 -> 1 second timer for run
18:21:18.996 -> 1 second timer for run
18:21:19.164 -> GPS Availible!
18:21:19.164 -> 0,,,,,,,0,138,0,4341,
18:21:20.011 -> 1 second timer for run
18:21:20.181 -> GPS Availible!
18:21:20.181 -> 0,,,,,,,0,141,0,4433,
18:21:20.247 -> [87363] <[14|00|13|00]Evw[00]1[00]4157,[0A]0,,,,,,,0,135,0,4223,[0A]0,,,,,,,0,138,0,4341,[0A]0,,,,,,,0,141,
18:21:21.876 -> 1 second timer for run
18:21:22.012 -> 1 second timer for run
18:21:22.183 -> GPS Availible!
18:21:22.183 -> 0,,,,,,,0,143,0,4499,
18:21:22.997 -> 1 second timer for run
18:21:23.268 -> GPS Availible!
18:21:23.268 -> 0,,,,,,,0,148,0,4641,
18:21:24.015 -> 1 second timer for run
18:21:24.049 -> [91176] <[06|00|14|00|00]
18:21:25.543 -> 1 second timer for run
18:21:26.017 -> 1 second timer for run
18:21:26.187 -> GPS Availible!
18:21:26.187 -> 0,,,,,,,0,151,0,4758,
18:21:26.220 -> [93359] <[14|00|15|00]Evw[00]1[00]0,4433,[0A]0,,,,,,,0,143,0,4499,[0A]0,,,,,,,0,148,0,4641,[0A]0,,,,,,,0,15
18:21:27.795 -> 1 second timer for run
18:21:27.998 -> 1 second timer for run
18:21:28.031 -> [95165] Heartbeat timeout: 95155, 17102, 91156
18:21:28.269 -> GPS Availible!
18:21:28.269 -> 0,,,,,,,0,155,0,4873,
18:21:29.014 -> 1 second timer for run
18:21:29.184 -> GPS Availible!
18:21:29.184 -> 0,,,,,,,0,158,0,4966,
18:21:29.997 -> 1 second timer for run
18:21:30.064 -> [97221] Connecting to blynk-cloud.com:80
18:22:45.317 -> 1 second timer for run
18:22:45.419 -> [172463] Connecting to blynk-cloud.com:80
18:22:46.811 -> [173879] <[1D|00|01|00] "Здесь код устройства Blynk"
Подскажите, как мне реализовать такое взаимодействие?