Помогите отправить команду в Serial, непонятный предел.

Hibernator
Offline
Зарегистрирован: 18.10.2015

Добрый день.

Нужна помощь знающих людей.

Arduino Nano + Sim800L. 

Все работает хорошо, кроме того, что не могу передать команду на выполнение модему - обрезается длина строки.

Объявлена переменная char URL[100] = "?api_key=QDGLLN3P678PLY3D&field1=11\"";

Передаю команду модему GSMport.print("AT+HTTPPARA=\"URL\",\"https://api.thingspeak.com/update");

Далее, побайтно, передаю остаток строки из переменной

  for (int i=0; i < sizeof(URL); i++) {
    GSMport.print(URL[i]);
 
В итоге, получаю результат: AT+HTTPPARA="URL","https://api.thingspeak.com/update?api_key=QD
 
Т.о. из требуемой длинны в 36 символов передалось всего 11. В сумме 64 символа.
Как с этим бороться?
 
Спасибо!
andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Размер "64 символа" наводит на мысль о переполнении буфера.

Можно либо увеличить длину буфера, либо использовать небуферизованную передачу.

Araris
Offline
Зарегистрирован: 09.11.2012

64 символа ? А почитайте про размер буфера последовательного порта, например, https://www.google.com.ua/?gws_rd=ssl#q=arduino+serial+%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%80+%D0%B1%D1%83%D1%84%D0%B5%D1%80%D0%B0

Hibernator
Offline
Зарегистрирован: 18.10.2015

andriano пишет:

Размер "64 символа" наводит на мысль о переполнении буфера.

Можно либо увеличить длину буфера, либо использовать небуферизованную передачу.

Спасибо за ответ. Длину буфера попытался увеличить переназначив #define buffer с 64 на 128. Не помогло.

А как организовать небуферизированную передачу?

Araris
Offline
Зарегистрирован: 09.11.2012

Hibernator пишет:

Длину буфера попытался увеличить переназначив #define buffer с 64 на 128. Не помогло.

Это не то, и не там. Найдите в в каталоге Arduino IDE файл HardwareSerial.h, посмотрите там 

#define SERIAL_TX_BUFFER_SIZE
#define SERIAL_RX_BUFFER_SIZE
Hibernator
Offline
Зарегистрирован: 18.10.2015

Araris пишет:

Hibernator пишет:

Длину буфера попытался увеличить переназначив #define buffer с 64 на 128. Не помогло.

Это не то, и не там. Найдите в в каталоге Arduino IDE файл HardwareSerial.h, посмотрите там 

#define SERIAL_TX_BUFFER_SIZE
#define SERIAL_RX_BUFFER_SIZE

Понял. Нашел и подправил вот так:

#if !defined(SERIAL_TX_BUFFER_SIZE)
#if (RAMEND < 1000)
#define SERIAL_TX_BUFFER_SIZE 128
#else
#define SERIAL_TX_BUFFER_SIZE 256
#endif
#endif
#if !defined(SERIAL_RX_BUFFER_SIZE)
#if (RAMEND < 1000)
#define SERIAL_RX_BUFFER_SIZE 128
#else
#define SERIAL_RX_BUFFER_SIZE 256
#endif
#endif
 
Перезагружал. Не помогло.
Есть еще варианты как это зло победить?
andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Hibernator пишет:

Не помогло.
Есть еще варианты как это зло победить?

Чтобы победить, нужно понять, что именно происходит.

Для начала просто распечатать SERIAL_TX_BUFFER_SIZE и SERIAL_RX_BUFFER_SIZE.

Hibernator
Offline
Зарегистрирован: 18.10.2015

andriano пишет:

Hibernator пишет:

Не помогло.
Есть еще варианты как это зло победить?

Чтобы победить, нужно понять, что именно происходит.

Для начала просто распечатать SERIAL_TX_BUFFER_SIZE и SERIAL_RX_BUFFER_SIZE.

Да, все верно. Я это сделал в предыдущем посте.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

И что получили?

Hibernator
Offline
Зарегистрирован: 18.10.2015

andriano пишет:

И что получили?

К сожалению, все тоже самое :(

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Нет в софт-сериале  НА ПЕРЕДАЧУ никакого буфера, вообще никакого.

В чем-то другом дело. Покажите больше кода.

То есть 64 - это конечно искуственно вылезающее ограничение, но это размер буфера ПРИЕМА. Какая связь?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Hibernator пишет:

andriano пишет:

И что получили?

К сожалению, все тоже самое :(

Еще раз: какое число выдает в консоль?

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Андриано!

Это GSM модуль и Нанка. Подключение возможно исключительно через софт-сериал.

Какое значение имеют размеры буферов хард-сериала? Мы куда-то в дебри полезли, не имеющие отношения к задаче.

Hibernator
Offline
Зарегистрирован: 18.10.2015

Поменял Nano на Uno.

Та же ерунда, уже и не знаю что с этим делать. Не хочет отдавать в модуль строку - хоть убейся!

Значения буфера изменены, вот так:

#if !defined(SERIAL_TX_BUFFER_SIZE)
#if ((RAMEND - RAMSTART) < 1023)
#define SERIAL_TX_BUFFER_SIZE 256
#else
#define SERIAL_TX_BUFFER_SIZE 256
#endif
#endif
#if !defined(SERIAL_RX_BUFFER_SIZE)
#if ((RAMEND - RAMSTART) < 1023)
#define SERIAL_RX_BUFFER_SIZE 256
#else
#define SERIAL_RX_BUFFER_SIZE 256
#endif
#endif

Вот код. Помогите люди добрые!

#include <SoftwareSerial.h>
SoftwareSerial GSMport(4, 3); // RX, TX
String cmd = "QDGLLN3P678PLN3D&field1=";

void setup() {
  // put your setup code here, to run once:

//  pinMode(SensorPin, INPUT);
//  digitalWrite(SensorPin, HIGH);  //вкл. подтягивающий резистор 20ом

  Serial.begin(9600);  //скорость порта
  GSMport.begin(9600);
  delay(3000); //дадим время на инициализацию GSM модулю
  Serial.println("GPRS test started...");
  gprs_init();

  GSMport.println("AT");
  delay(100);
  resp();

  GSMport.println("AT+CGATT?");
  delay(200);
  resp();


  GSMport.println("AT+CIPSHUT");
  delay(2000);
  resp();


  GSMport.println("AT+CIPSTATUS");
  delay(100);
  resp();


  GSMport.println("AT+CIPMUX=0");
  delay(100);
  resp();


  GSMport.println("AT+CSTT=\"internet.mts.ru\",\"mts\",\"mts\"");
  delay(100);
  resp();


  GSMport.println("AT+CIICR");
  delay(1000);
  resp();


  GSMport.println("AT+CIFSR");
  delay(2000);
  resp();


  GSMport.println("AT+CIPSTATUS");
  delay(500);
  resp();


  GSMport.println("AT+CIPSTART=\"TCP\",\"thingspeak.com\",\"80\"");
  delay(2000);
  resp();

  cmd += "77";
  GSMport.print("AT+CIPSEND=");
  GSMport.println(cmd.length()+42);
  delay(1000);
  resp();

  GSMport.print("https://api.thingspeak.com/update?api_key=");

//  for (int i=0; i < sizeof(cmd); i++) {
//   GSMport.print(cmd[i]);
//  }

  delay(0);
  GSMport.print(cmd);
  delay(1000);
  GSMport.println(0x1A, HEX);
  delay(1000);
  resp();
  
/*  
  if (GSMport.find(">")) {
    GSMport.print(cmd);
    GSMport.println(0x1A, HEX);
    resp();
    Serial.println("Command string transmited...");
    delay(500);
  } else Serial.println("Command string not trasmited...Not found >...");
  if (GSMport.find("OK")) Serial.println("RECEIVED: OK");
  else Serial.println("RECEIVED: Error");
  delay(1000);
*/
  GSMport.println("AT+CIPCLOSE");
  delay(500);
  resp();

  GSMport.println("AT+CIPSHUT");
  delay(500);
  resp();

}

void loop() {
  // put your main code here, to run repeatedly:

}

void gprs_init() {
  
}

void resp() {
  while (GSMport.available()) {
    if (GSMport.available() > 0) {
      Serial.write(GSMport.read());
    }
  }
}

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Hibernator пишет:

Поменял Nano на Uno.

Та же ерунда, уже и не знаю что с этим делать. Не хочет отдавать в модуль строку - хоть убейся!

Значения буфера изменены, вот так:

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

Если же Вы считаете, что эти константы для Вас важны, то следует убадиться, какие знеачения они принимают на самом деле. А проще всего это сделать примерно так:

voud setup() {
  Serial.print("SERIAL_TX_BUFFER_SIZE: ");
  Serial.print(SERIAL_TX_BUFFER_SIZE);
  Serial.print(", ");
  Serial.print("SERIAL_RX_BUFFER_SIZE: ");
  Serial.println(SERIAL_RX_BUFFER_SIZE);
}
okta
Offline
Зарегистрирован: 10.01.2015

У софтового сериала свой буфер. Править его размер надо в SoftwareSerial.h

Сейчас могу не правильно вспомнить (среды под рукой нет), вроде #define _SS_MAX_TX_BUFF и #define _SS_MAX_RX_BUFF

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

okta пишет:

У софтового сериала свой буфер. Править его размер надо в SoftwareSerial.h

Сейчас могу не правильно вспомнить (среды под рукой нет), вроде #define _SS_MAX_TX_BUFF и #define _SS_MAX_RX_BUFF

а у меня есть под рукой. у софт сериала буфер - только не прием.

/*
SoftwareSerial.h (formerly NewSoftSerial.h) - 
Multi-instance software serial library for Arduino/Wiring
-- Interrupt-driven receive and other improvements by ladyada
   (http://ladyada.net)
-- Tuning, circular buffer, derivation from class Print/Stream,
   multi-instance support, porting to 8MHz processors,
   various optimizations, PROGMEM delay tables, inverse logic and 
   direct port writing by Mikal Hart (http://www.arduiniana.org)
-- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com)
-- 20MHz processor support by Garrett Mace (http://www.macetech.com)
-- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/)

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library 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
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

The latest version of this library can always be found at
http://arduiniana.org.
*/

#ifndef SoftwareSerial_h
#define SoftwareSerial_h

#include <inttypes.h>
#include <Stream.h>

/******************************************************************************
* Definitions
******************************************************************************/

#define _SS_MAX_RX_BUFF 64 // RX buffer size
#ifndef GCC_VERSION
#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#endif

class SoftwareSerial : public Stream
{
private:
  // per object data
  uint8_t _receivePin;
  uint8_t _receiveBitMask;
  volatile uint8_t *_receivePortRegister;
  uint8_t _transmitBitMask;
  volatile uint8_t *_transmitPortRegister;
  volatile uint8_t *_pcint_maskreg;
  uint8_t _pcint_maskvalue;

  // Expressed as 4-cycle delays (must never be 0!)
  uint16_t _rx_delay_centering;
  uint16_t _rx_delay_intrabit;
  uint16_t _rx_delay_stopbit;
  uint16_t _tx_delay;

  uint16_t _buffer_overflow:1;
  uint16_t _inverse_logic:1;

  // static data
  static char _receive_buffer[_SS_MAX_RX_BUFF]; 
  static volatile uint8_t _receive_buffer_tail;
  static volatile uint8_t _receive_buffer_head;
  static SoftwareSerial *active_object;

  // private methods
  inline void recv() __attribute__((__always_inline__));
  uint8_t rx_pin_read();
  void setTX(uint8_t transmitPin);
  void setRX(uint8_t receivePin);
  inline void setRxIntMsk(bool enable) __attribute__((__always_inline__));

  // Return num - sub, or 1 if the result would be < 1
  static uint16_t subtract_cap(uint16_t num, uint16_t sub);

  // private static method for timing
  static inline void tunedDelay(uint16_t delay);

public:
  // public methods
  SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic = false);
  ~SoftwareSerial();
  void begin(long speed);
  bool listen();
  void end();
  bool isListening() { return this == active_object; }
  bool stopListening();
  bool overflow() { bool ret = _buffer_overflow; if (ret) _buffer_overflow = false; return ret; }
  int peek();

  virtual size_t write(uint8_t byte);
  virtual int read();
  virtual int available();
  virtual void flush();
  operator bool() { return true; }
  
  using Print::write;

  // public only for easy access by interrupt handlers
  static inline void handle_interrupt() __attribute__((__always_inline__));
};

// Arduino 0012 workaround
#undef int
#undef char
#undef long
#undef byte
#undef float
#undef abs
#undef round

#endif

 

okta
Offline
Зарегистрирован: 10.01.2015

Этот ньюанс не помнил)) Посмотрел реализацию write - вывод действительно идет без буфера.

Hibernator
Offline
Зарегистрирован: 18.10.2015

Может это как-то задержки отрицательно сказываются или их время не оптимально? Я тупо не могу понять как это победить... Ведь народ использует эти модули! Я уже грешу на то, что модуль неисправен...

DenBak
Offline
Зарегистрирован: 30.01.2017

Попробуйте в функции resp(), после 118 строки добавить небольшую задержку, delay(10), например. Возможно, не успевает выдать всю информацию.

И как Вы определяете, что передалась не вся строка? Если по ответу модуля, то в этом случае нужно увеличивать буфер в SoftwareSerial.h, параметр _SS_MAX_RX_BUFF

Еще, в режиме gprs модуль крайне требователен к питанию. Мне помогла припайка проводов питания напрямую, через макетку работало нестабильно, хотя все остальные функции - без проблем были.

Ice1361
Offline
Зарегистрирован: 14.12.2017

Решил проблему или нет?

достучался до сайта thing speak.com?

Я на sim800l отправил данные на этот сайт только через набор команд at-sapbr

Для работы по http протоколу, и модуль твой исправен:))