Проблема с интеграцией GPS в Arduino ESP8266

Я столкнулся с проблемой при использовании двух последовательных устройств связи с Arduino uno. Я пытаюсь использовать GPS-модуль ESP8266, Neo 6M с Arduino UNO, но одновременно работает только одно устройство. Есть ли какое-нибудь решение, чтобы сделать эту работу? Когда я комментирую processGPS() и раскомментирую API, связанный с TCP, и наоборот, любое из устройств работает. Любая идея, как мы можем заставить работать оба?

Мой код:

// Это демонстрационный пример использования общедоступного http-сервера для тестирования запросов GET и POST.

#include <Arduino.h>
#include <LiteESP8266Client.h>
#include "TinyGPS++.h"
#include "SoftwareSerial.h"

#define PACKET_MTU 500    // Стандартный MTU сети составляет 500 байт.

LiteESP8266 radio;

const char ssid[] PROGMEM = "xyz";    // измените его на SSID вашего Wi-Fi
const char password[] PROGMEM = "xyz";    // измените его на ваш пароль от Wi-Fi
const char host[] PROGMEM = "192.168.0.156";
const int port = 8080;

const char http_get_request[] PROGMEM = "GET /getLedStatus HTTP/1.1\r\n";
const char http_useragent[] PROGMEM = "User-Agent: Arduino-stm32/0.1\r\n";
const char http_content_type_json[] PROGMEM = "Content-Type: application/json\r\n";
const char http_host[] PROGMEM = "Host: 192.168.0.156\r\n";
const char http_close_connection[] PROGMEM = "Connection: close\r\n\r\n";
const char http_content_length_header[] PROGMEM = "Content-Length: ";
const char success[] PROGMEM = "success";
const char failed[] PROGMEM = "failed";
const char CRLF[] PROGMEM = "\r\n";
const char error_data_null[] PROGMEM = "Error: data came back null.";
const int ledPin=11;
// Выберите два вывода Arduino, которые будут использоваться для последовательного интерфейса программного обеспечения.
int RXPin = 5;
int TXPin = 4;

int GPSBaud = 9600;

// Создаем объект TinyGPS++
TinyGPSPlus gps;

// Создаем программный последовательный порт с именем "gpsSerial"
SoftwareSerial gpsSerial(RXPin, TXPin);

void setupStationMode() {
  Serial.print(F("Setup station mode... "));
  if (radio.set_station_mode()) {
    Serial.println(F("success"));
  } else {
    Serial.println(F("failed"));
  }
}

void joinAP() {
  Serial.print(F("Join AP "));
  Serial.print(F("... "));
  if (radio.connect_to_ap(ssid, password)) {
    Serial.println(F("Success"));
  } else {
    Serial.println(F("Failed"));
  }
}

boolean establishTcpConnect() {
  Serial.print(F("Establish TCP Connection... "));
  if (radio.connect_progmem(host, port)) {
    Serial.println(F("Success"));
    return true;
  } else {
    Serial.println(F("Failed"));
    return false;
  }
}

void readHttpPacketAndProcessLEDStatus() {
  char *data;
  while ((data = radio.get_response_packet(PACKET_MTU, 5000))) {
    if (data) {
      Serial.println(F("Response Received..."));
      Serial.println(data);
      if(strstr(data, "ON") != NULL) {
        digitalWrite(ledPin, HIGH);
      }else{
        digitalWrite(ledPin, LOW);
      }
      free(data);//Обязательно
    } else {
      Serial.println(error_data_null);
    }
  }
}

void httpGetLedStatus() {
  Serial.println(F("Sending GET request... "));
  radio.send_progmem(http_get_request);
  radio.send_progmem(http_useragent);
  radio.send_progmem(http_host);
  radio.send_progmem(http_close_connection);
}
void setupGPS(){
  // Запустите программный последовательный порт со скоростью передачи GPS по умолчанию
  gpsSerial.begin(GPSBaud);
  Serial.println("GPS Start");//Просто показываем на монитор, что скетч запустился
}
void setup() {
  delay(2000);
  pinMode(ledPin, OUTPUT);
  radio.begin(9600,2,3);
  Serial.begin(9600);
  while (!Serial) {};
  //setupStationMode();
  //присоединиться к точке доступа();
  setupGPS();
}
void displayInfo()
{
  if (gps.location.isValid())
  {
    Serial.print("Latitude: ");
    Serial.println(gps.location.lat(), 6);
    Serial.print("Longitude: ");
    Serial.println(gps.location.lng(), 6);
    Serial.print("Altitude: ");
    Serial.println(gps.altitude.meters());
    Serial.println("Speed MPH:");
    Serial.println(gps.speed.mph());
  }
  else
  {
    Serial.println("Location: Not Available");
  }
  
  Serial.print("Date: ");
  if (gps.date.isValid())
  {
    Serial.print(gps.date.month());
    Serial.print("/");
    Serial.print(gps.date.day());
    Serial.print("/");
    Serial.println(gps.date.year());
  }
  else
  {
    Serial.println("Not Available");
  }

  Serial.print("Time: ");
  if (gps.time.isValid())
  {
    if (gps.time.hour() < 10) Serial.print(F("0"));
    Serial.print(gps.time.hour());
    Serial.print(":");
    if (gps.time.minute() < 10) Serial.print(F("0"));
    Serial.print(gps.time.minute());
    Serial.print(":");
    if (gps.time.second() < 10) Serial.print(F("0"));
    Serial.print(gps.time.second());
    Serial.print(".");
    if (gps.time.centisecond() < 10) Serial.print(F("0"));
    Serial.println(gps.time.centisecond());
  }
  else
  {
    Serial.println("Not Available");
  }

  Serial.println();
  Serial.println();
  delay(1000);
}
void processGps(){
   // Этот скетч отображает информацию каждый раз, когда новое предложение правильно закодировано.
  if (gpsSerial.available() > 0)
    if (gps.encode(gpsSerial.read()))
      displayInfo();
}
void loop() {
  /*if(establishTcpConnect()){
    httpGetLedStatus();
    readHttpPacketAndProcessLEDStatus();
  }*/
  processGps();
  }

, 👍0

Обсуждение

И ESP8266, и GPS используют SoftwareSerial. При использовании SoftwareSerial только один порт может получать данные одновременно. См. [здесь] (https://www.arduino.cc/en/Reference/softwareSerial). Для Arduino Uno нет простого решения. Вам понадобится другое оборудование, которое имеет более одного аппаратного последовательного порта (например, Mega2560, если вы хотите использовать AVR)., @StarCat

Исправление к моему собственному комментарию: ESP8266 на самом деле не использует SoftwareSerial, но сторона Arduino, взаимодействующая с ESP8266, использует., @StarCat

Согласен с @StarCat. Зачем вообще возиться с Arduino UNO? Если ваш ESP8266 имеет достаточно открытых контактов, он может запустить сам код и напрямую общаться с модулем GPS с гораздо меньшими проблемами., @romkey

@romkey, правда, отсюда и мой комментарий о приверженности AVR. Запуск непосредственно на ESP8266 был бы гораздо предпочтительнее. Я конечно не знаю, что еще нужно подключить дополнительно от GPS (дисплеи, прочая периферия?)., @StarCat


1 ответ


Лучший ответ:

1

Как упоминалось StarCat и romkey, SoftwareSerial разрешает только одно соединение за раз.

На мой взгляд, есть два возможных решения этой проблемы, но для каждого из них требуется новое оборудование.

Решение 1. Замените Arduino Uno на STM32 Blue Pill

STM32 Blue Pill имеет более одного аппаратного последовательного интерфейса, поэтому вам даже не нужен SoftwareSerial, фактически LiteESP8266Client.h автоматически определит, используется ли STM32 или AVR. на основе Arduino используется для принятия решения об использовании HardwareSerial или SoftwareSerial, см. здесь.

Плюсы:

  • Минимальное изменение кода. Вы сможете использовать то, что написали до сих пор, и продолжать использовать ESP-01 в качестве WiFi-экрана;

Минусы:

  • Немного дополнительных работ по настройке STM32duino Core для Arduino. Требуется либо программатор SWDI, либо программатор USB-serial.

Прочитайте это для начала работы с STM32 и того, что нужно знать.

Решение 2. Замените Arduino Uno и ESP-01 на плату разработчика ESP8266

Вместо того, чтобы использовать ESP-01 в качестве экрана WiFi, возьмите плату для разработки на основе ESP12 в качестве Arduino, чтобы заменить Arduino Uno и ESP-01. В этом случае вы запускаете скетч Arduino прямо на плате и заменяете прошивку AT загрузчиком Arduino.

Плюсы:

  • Интеграция Arduino Uno с беспроводной функциональностью ESP в одно устройство.

Минусы:

  • Необходимо полностью переписать ваше приложение.

Гитхаб ESP8266 Arduino должен содержать достаточно информации для начала работы.

,

почему СТМ32? Arduino имеет платы ARM, @Juraj

Почему не ESP32?, @StarCat

@Juraj Лично я никогда не использовал платы SAMD, поэтому не могу это комментировать., @hcheung