Проблема с кодом w/ Uno+GPS+GPRS?

У меня есть Arduino Uno, SIM900 GPRS и Adafruit Breakout GPS.

Можно ли оптимизировать этот код?

#include <SoftwareSerial.h>
#include <TinyGPS++.h>
#include <Ubidots_Arduino_GPRS.h>
//Serial Relay - Arduino will patch a 
//serial link between the computer and the GPRS Shield
//at 19200 bps 8-N-1
//Computer is connected to Hardware UART
//GPRS Shield is connected to the Software UART 
#define APN "myapn" 
#define USER ""  // If your apn doesnt have username just put ""
#define PASS ""  // If your apn doesnt have password just put ""
#define TOKEN "ubidotsToken"  // Replace it with your Ubidots token
#define ID "Your_id_here" // Replace it with your Ubidots' variable ID
// You can send 1 to 10 variable at the same time
#define ID1 "idHere" // Replace it with your variable ID
//#define ID2 "" // Replace it with your variable ID
//#define ID3 "Your_id_here" // Replace it with your variable ID

TinyGPSPlus gps; // The TinyGPS++ object for interfacing with the GPS
//Declare indexes, and strings
char latitude[12];
char longitude[12];
float value_1 = 1;
char var[18] = "Lat: ";
char var2[18] = "Long: ";
Ubidots client(TOKEN);  
SoftwareSerial ss(2,3);
void setup() {

// the Serial port of Arduino baud rate.
  Serial.begin(9600);               

  client.powerUpOrDown();
  client.setApn(APN,USER,PASS);
//.endC is for _client.end() in Ubidots_GPRS.cpp
  client.endC();
  ss.begin(9600);
}

void loop() {

  //handling GPS data parsing
  while (ss.available() > 0) {
    gps.encode(ss.read());}
  //Once a valid location comes up it updates Lat/Long variables
   if (gps.location.isUpdated())
{
    strcpy(var, "Lat: ");
    strcpy(var2,"Long: ");

    dtostrf(gps.location.lat(),10,6,latitude);
    strcat(var, latitude);

    dtostrf(gps.location.lng(),10,6,longitude);
    strcat(var2, longitude);
  //Added ss.flush();
    ss.flush();
    ss.end();
    Serial.flush()
  //Added client.beginC() for _client.begin(9600) is Ubidots_GPRS.cpp
    client.beginC();
    client.add(ID1, value_1, var, var2);
    client.sendAll();
    client.endC();
    ss.begin(9600);
  }
 Serial.println(var);
 Serial.println(var2);
}

Из этой ссылкия переместил println из inside .isUpdated() за пределы оператора if. Я смог получить данные GPS, отправленные из устройства на мой счет Ubidots во время поездки по городу. После этого я смог ввести данные в Google Maps, и маршрут был точным. Нужен ли мне flush()?

, 👍1

Обсуждение

Простой тест: закомментируйте весь код, связанный с отправкой данных по GPRS, и снова запустите скетч. Выводятся ли значения GPS на монитор без ошибок?, @SoreDakeNoKoto

Я прокомментировал .add() и .sendAll(), и значения GPS обновляются без ошибки., @roe-el

Я снова отредактировал свой пост., @roe-el

Из того, что вы говорите, все работает. Я собирался добавить несколько слов "listen ()" в ваш код, но этот подход тоже хорош. Если все, что вы хотите сделать, это оптимизировать код, вы можете навсегда сохранить настройки APN на sim900. Просто добавьте client.println("AT&W") в конец setApn() и используйте ReadData (), чтобы убедиться, что получено OK. Запустите скетч, а затем вы можете закомментировать вызов setApn () в setup (). Также предоставьте ссылку на вашу обновленную библиотеку с ее новыми функциями., @SoreDakeNoKoto

Да, это действительно работает. Вот эта [ссылка](https://github.com/roe-el/ubidots-arduino-gprs) в мой раздвоенный репозиторий с изменениями, которые я сделал до сих пор. Код в примерах/SaveValuesGPS, @roe-el

Оптимизация - это общее слово с множеством различных значений. Пожалуйста, дайте понять, что вы хотите: меньший код? Более быстрый код? Код fatser для компиляции? Код легко понять или поддерживать?..., @jfpoilpret


1 ответ


0

Похоже, вы используете один и тот же аппаратный последовательный порт как для вашего компьютера, так и для GPS-модуля. Это приведет к тому, что GPS-модуль будет получать все, что вы отправляете на компьютер, с помощью Serial.print (), и это может быть причиной вашей проблемы, так как это может запутать модуль и либо заставить его отправлять бесконечный поток тарабарщины, и/или сделать isValid() всегда ложным. Вместо этого вы должны создать экземпляр SoftwareSerial, прикрепленный к любым 2 цифровым контактам (возможно, 2 и 3), таким образом:

SoftwareSerial ss(2, 3);

и в настройке():

ss.begin(9600);  // используйте скорость передачи данных вашего модуля

Затем в верхней части цикла ()вместо этого используйте следующее:

while (ss.available() > 0)
    gps.encode(ss.read());

Избавьтесь от рекурсивного вызова функции loop() внутри функции loop (), так как это приведет к быстрому переполнению вашего стека.

Если вы хотите, чтобы данные отправлялись только тогда, когда значения местоположения обновляются на основе недавно полученных данных (но не обязательно изменяются, так как вы все еще можете находиться в том же месте), вместо этого вам следует использовать if (gps.location.isUpdated ()).

Ваш вызов dtostrf() также неверен. Вторым аргументом должна быть длина создаваемой строки (включая десятичную точку), а третьим аргументом должно быть количество цифр после десятичной точки. Что - то вроде этого должно быть в порядке вещей:

dtostrf(gps.location.lat(), 10, 6, latitude); 

Вы также можете поместить это в конец цикла (), чтобы проверить, действительно ли данные поступают из модуля и обрабатываются библиотекой:

if (millis() > 5000 && gps.charsProcessed() < 10)
  Serial.println(F("WARNING: No GPS data.  Check wiring."));
  while (1){ // infinite loop
    if (ss.available())
      Serial.print(ss.read());
  }
}    

Этот сайт может предоставить дополнительную информацию.

,

Спасибо вам за ваш вклад. Я внес изменения, которые вы предложили. Я получаю ошибки от последовательного монитора, но, возможно, я ошибся в одном из изменений. пустая настройка() { // последовательный порт скорости передачи данных Arduino. Серийный.начало(9600); сс.начало(9600); клиент.powerUpOrDown(); клиент.setApn(APN,ПОЛЬЗОВАТЕЛЬ,PASS); }, @roe-el

Какие именно ошибки? вы подключили RX gps-модуля к контакту 3 arduino, а его TX-к контакту 2?, @SoreDakeNoKoto

ДА. Если я запущу его с Serial.begin() первым в setup (), он будет работать, а с ss.begin() последним он будет анализировать данные. Но внутри .isUpdated() при попытке запуска будет отображаться ошибка .добавить()., @roe-el

Какую именно ошибку вы получаете? Откуда вы знаете, что он анализирует данные? меняются ли данные gps (при изменении вашего местоположения) и отображаются ли они с помощью Serial.print ()?, @SoreDakeNoKoto

Он исправит ошибку и покажет координаты на последовательном мониторе. Я знаю, что есть ошибка, потому что .add() отображает строку ошибки "Ошибка с AT+CSQ" на последовательном мониторе. Кажется, что он работает только в зависимости от того, где расположены Serial.begin() и ss.begin() в setup(). пустая настройка() { // последовательный порт скорости передачи данных Arduino. Серийный номер.начало(9600); клиент.powerUpOrDown(); клиент.setApn(APN,ПОЛЬЗОВАТЕЛЬ,PASS); ss.начало(9600); }, @roe-el

@roe-el Ах, это потому, что используется несколько экземпляров программного обеспечения. К каким контактам подключен SIM900?, @SoreDakeNoKoto

Из Ubidot_GPRS.h, \n - класса Ubidots{ Частное SoftwareSerial _client = SoftwareSerial(7, 8); bool httpInit(); символ* _токен; bool httpTerm(); символ* Данные чтения(время ожидания uint16_t); пустот flushInput(); максимальные значения uint8_t; uint8_t текущее значение; Значение * val; ` Значит 7,8?, @roe-el

@roe-el Отредактируйте свой код, чтобы я мог видеть изменения, которые вы внесли до сих пор. Я отредактирую часть кода библиотеки., @SoreDakeNoKoto

Я отредактировал код, приведенный выше., @roe-el