Не работает разбор строки из Serial от GPRS-модуля

Sh0a1m0a0n1
Offline
Зарегистрирован: 16.09.2016

Пытаюсь научить Arduino Mega 2560 принимать команды из интернета через Neoway M590E.

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

Делаю так:

if (Serial1.available())
Serial.write(Serial1.read());
if (Serial.available())
 Serial1.write(Serial.read());

Вроде, всё работает. С помощью AT-команд отправляю и получаю данные по FTP.

Пишем в Ардуину код для "общения" с сервером, например так:

boolean strtrd=false;
String inputString = "";         // a string to hold incoming data
boolean stringComplete = false;  // whether the string is complete
String atcusd="at+cusd=1,*99#,15";
int ledPin = 13;
void gprssend(){
  delay(2000);
  Serial1.println("AT+FTPLOGIN=IP,Login,Password");
  delay(3000);
   Serial1.println("AT+FTPPUT=test2.txt,1,1,5");
   delay(3000);
   Serial1.println("12345");
   
   delay(3000);
   Serial1.println("AT+FTPLOGOUT");
}
void gprsget(){
  delay(2000);
  Serial1.println("AT+FTPLOGIN=IP,Login,Password");
  delay(3000);
  Serial1.println("AT+FTPGET=test.txt,1,1");
  strtrd=true;
  delay(7000);
Serial1.println("AT+FTPLOGOUT");
strtrd=false;
}
void setup() {
  delay(2000);
  inputString.reserve(200);
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, HIGH);
  Serial.begin(9600);  //Скорость порта для связи Arduino с компьютером
 Serial1.begin(9600);
delay(2000);
 Serial1.println("AT&D2");
 delay(2000);
 Serial1.println("AT+CGDCONT=1,IP,internet.tele2.ru");
 delay(5000);
 Serial1.println("AT+CLIP=1");
 delay(5000);
 Serial1.println(atcusd);
 delay(2000);
 Serial1.println("at+xisp=0");
 delay(2000);
 Serial1.println("at+xiic=1");
 delay(2000);
 Serial1.println("at+xiic?");
 delay(2000);
//gprssend();
gprsget();
gprssend();
}

void serialEvent1(){

while (Serial1.available()) {
    // get the new byte:
    char inChar = (char)Serial1.read();
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
}
void loop() {

  if (stringComplete) {
    Serial.println(inputString);
    // clear the string:
    inputString = "";
    stringComplete = false;
  }

}

И либо вообще не получаем ответа, либо долго ждём и как-то так:

AT&D2
 
OK
AT+CGDCONT=1,IP,internet.tele2.ru
 
ERROR
AT+CLIP=
AT+FTPLOGOUT
 
 
OK
 
 
Подскажите, что здесь не так, как быть?

 

Sh0a1m0a0n1
Offline
Зарегистрирован: 16.09.2016

Как нет, когда есть? Или Вы имеете ввиду, что APN должен быть в кавычках? Много раз проверено, именно так всё как раз и работает.

Из-за кавычек даже String atcusd="at+cusd=1,*99#,15"; пришлось прописать. Внутри функции никак эту строку было не уместить.

toc
Offline
Зарегистрирован: 09.02.2013

1. предлагаю добавить в начало
#define gsm Serial1
и заменить везде Serial1 на gsm
- так станет проще читать текст программы
- облегчит возможный переезд на другие пины, ардуину или SoftwareSerial

2. считаю использование String лишним в МК. Лучше без него по моему скромному мнению.

3. Отсутствует ожидание и проверка ответа модуля на каждую команду. Позже постараюсь достать пример из своего sim900-проекта

Sh0a1m0a0n1
Offline
Зарегистрирован: 16.09.2016

Собственно. Я нашёл код, где как раз всё так и было, как Вы описываете. Но, к сожалению, и он не хотел работать.

Я тут случайно наткнулся на тему, где обсуждали похожую проблему. Терялись данные при общении по UART. 

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

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

Araris пишет:

Мне кажется, в модем должно посылаться AT+CGDCONT=1,"IP","internet.tele2.ru"

Попробуйте

Serial1.println("AT+CGDCONT=1,\"IP\",\"" + "internet.tele2.ru" + "\"");

или, иначе,

Serial1.println("AT+CGDCONT=1,\"IP\",\"internet.tele2.ru\"");  

Sh0a1m0a0n1
Offline
Зарегистрирован: 16.09.2016

Да при чём тут это! Модуль нормально с этим кодом заходит на FTP, но, если попросить Ардуину получить ответ, то начинается странное.

Вот тут человек с той же проблемой: http://arduino.ru/forum/programmirovanie/problema-s-softwareserial-i-gsm-modulem-a6#comment-224333

Sh0a1m0a0n1
Offline
Зарегистрирован: 16.09.2016

Кажется, разобрался с проблемой. Видимо, переполняется буфер.

Написал функцию чтения из порта модема:

void modemread(){
    while (gsm.available()>0)
{
  char c = gsm.read();
  Serial.write(c);
}
}

Пихнул её почти после каждого оператора, данные перестали теряться. 

Внимание, вопрос: Как теперь избавиться от этой порнографии и сделать так, чтобы буфер не переполнялся, когда нам не надо его читать?

 

Sh0a1m0a0n1
Offline
Зарегистрирован: 16.09.2016

Решил переделать весь код и вместо delay считывать подтверждение от модема. Вроде как убиваем двух зайцев.

Но тут вот меня ждал вот такой облом при компиляции:

exit status 1
a function-definition is not allowed here before '{' token
#define gsm Serial1
#include <DmxSimple.h>
int channel;
int value;
String atcusd = "at+cusd=1,\"*99#\",15";

void modemread() {
  do
  {
    delay(100);
  } while (gsm.find("OK") == false);
}
void gprsconnect() {

  gsm.println("ATE0");
  modemread();
  gsm.println("AT&D2");
  modemread();
  gsm.println("AT+CGDCONT=1,\"IP\",\"internet.tele2.ru\"");
  modemread();
  gsm.println("AT+CLIP=1");
  modemread();
  gsm.println(atcusd);
  modemread();
  gsm.println("at+xisp=0");
  modemread();
  gsm.println("at+xiic=1");
  modemread();
  do
  {
    gsm.println("at+xiic?");
    delay(100);
  } while (gsm.find("0.0.0.0") == true);
  gsm.println("at+xiic?");
  delay(100);
  Serial.println(gsm.readString());
}
void gprsget() {
  gsm.println("at+xiic?");
  delay(100);
  
  while(gsm.find("0.0.0.0")) {
    gprsconnect();
  }
  gsm.println("AT+FTPLOGOUT");
  modemread();
  gsm.println("AT+FTPLOGIN=Логин");
  do
  {
    delay(500);
  } while (gsm.find("User logged in.") == false);
  gsm.println("AT+FTPGET=test.txt,1,1");
  do {

  } while (gsm.find("+FTPGET:7"));

  while (gsm.available() > 0);
  {
    channel = gsm.parseInt();
    value = gsm.parseInt();
    DmxSimple.write(channel, value);
    Serial.write('\n\n');
    Serial.println("DMX:" + String(channel) + "," + String(value));
  }
  
  void setup() {
    delay(1000);
    Serial.begin(9600);
    gsm.begin(9600);
    do {            // проверяем готовность модема
      gsm.println("AT+CPAS");
      Serial.print(".");
      delay(100);
    } while (!gsm.find("0"));

    do {
      gsm.println("AT+CREG?");
      Serial.print(":");
      delay(100);
    } while (!gsm.find("+CREG: 0,1"));
    gprsconnect();
  }


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

  }

Помогите, пожалуйста! Что это за бред выходит? Как с ним справиться?

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Это жесть. Помогите очистить буфер и это

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

ПС: ТС хороший анекдот рассказал. +5 ему.

Sh0a1m0a0n1
Offline
Зарегистрирован: 16.09.2016

Спасибо. А теперь для тек, кто в танке, можно повторить?

Baks
Baks аватар
Offline
Зарегистрирован: 11.01.2016

я у себя увеличел буфер в softwareserial билиотеке, может конечно это не совсем правильно

Sh0a1m0a0n1
Offline
Зарегистрирован: 16.09.2016

Baks пишет:

я у себя увеличел буфер в softwareserial билиотеке, может конечно это не совсем правильно

А что это даст? Рано или поздно он всё равно переполнится.

Baks
Baks аватар
Offline
Зарегистрирован: 11.01.2016

разви когда считываеш из буфера данные не удаляются? и они должны только поместиться в буфер сериала (из за этого и увеличел)