Не работает разбор строки из Serial от GPRS-модуля
- Войдите на сайт для отправки комментариев
Ср, 05/10/2016 - 07:34
Пытаюсь научить 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
Подскажите, что здесь не так, как быть?
Как нет, когда есть? Или Вы имеете ввиду, что APN должен быть в кавычках? Много раз проверено, именно так всё как раз и работает.
Из-за кавычек даже String atcusd="at+cusd=1,*99#,15"; пришлось прописать. Внутри функции никак эту строку было не уместить.
1. предлагаю добавить в начало
#define gsm Serial1
и заменить везде Serial1 на gsm
- так станет проще читать текст программы
- облегчит возможный переезд на другие пины, ардуину или SoftwareSerial
2. считаю использование String лишним в МК. Лучше без него по моему скромному мнению.
3. Отсутствует ожидание и проверка ответа модуля на каждую команду. Позже постараюсь достать пример из своего sim900-проекта
Собственно. Я нашёл код, где как раз всё так и было, как Вы описываете. Но, к сожалению, и он не хотел работать.
Я тут случайно наткнулся на тему, где обсуждали похожую проблему. Терялись данные при общении по UART.
Повторюсь: Если набирать все те же команды руками, то всё работает. Если же прописать команды в Ардуину, то начинает происходить что-то странное. Программа вообще останавливается.
Мне кажется, в модем должно посылаться 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\"");
Да при чём тут это! Модуль нормально с этим кодом заходит на FTP, но, если попросить Ардуину получить ответ, то начинается странное.
Вот тут человек с той же проблемой: http://arduino.ru/forum/programmirovanie/problema-s-softwareserial-i-gsm-modulem-a6#comment-224333
Кажется, разобрался с проблемой. Видимо, переполняется буфер.
Написал функцию чтения из порта модема:
void modemread(){ while (gsm.available()>0) { char c = gsm.read(); Serial.write(c); } }Пихнул её почти после каждого оператора, данные перестали теряться.
Внимание, вопрос: Как теперь избавиться от этой порнографии и сделать так, чтобы буфер не переполнялся, когда нам не надо его читать?
Решил переделать весь код и вместо delay считывать подтверждение от модема. Вроде как убиваем двух зайцев.
Но тут вот меня ждал вот такой облом при компиляции:
#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: }Помогите, пожалуйста! Что это за бред выходит? Как с ним справиться?
Это жесть. Помогите очистить буфер и это
void loop() { // put your main code here, to run repeatedly: }ПС: ТС хороший анекдот рассказал. +5 ему.
Спасибо. А теперь для тек, кто в танке, можно повторить?
я у себя увеличел буфер в softwareserial билиотеке, может конечно это не совсем правильно
я у себя увеличел буфер в softwareserial билиотеке, может конечно это не совсем правильно
А что это даст? Рано или поздно он всё равно переполнится.
разви когда считываеш из буфера данные не удаляются? и они должны только поместиться в буфер сериала (из за этого и увеличел)