Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.89/88: Рейтинг темы: голосов - 88, средняя оценка - 4.89
vot_tik
0 / 0 / 0
Регистрация: 10.06.2015
Сообщений: 8
1

Atmega8A-AU + ESP8266

14.06.2015, 09:23. Просмотров 16379. Ответов 15
Метки нет (Все метки)

Уважаемые воротилы AVR, у меня к Вам вопрос.

Заварганил я значит платку на Atmega8a, законнектил к нему ESP8266. Набросал код, который делает ESP8266, как точку доступа и запускает на нём TCP сервер. Всё пучком - всё-работает. Даже когда коннектюсь с компа, и отсылаю сообщения, то по UART, вижу эти сообщения и в каком формате они приходят. Соответственно, следующий шаг - распарсить команды, которые приходят. И тут начинается ахтунг.
Первый косяк начался, когда я попробовал передать в функцию пришедшие по ESP-8266 данные. Соответственно, я хотел передавать данные в эту функцию для дальнейшей обработки (не засирать же основной цикл while). Сначала я написал код, который(по моему мнению) должен был работать и всё парсить. Но когда я запустил, естественно он не работал. Долго искал и не мог понять в чём причина. Но оказалось, что проблемы начинались уже даже в момент передачи. Я передавал строку (например:"Hello world"), а когда выводил в функции эту строку, то там уже были совсем другие данные! Чтобы было более понятно, функция в которую я передавал данные выглядит так:
Код
void sendFullMessageWithString(char *string, int idDevice, int length).// string - непосредственно строка, idDevice - айдишник подключённого по вайфай устройства(у меня всегда 0, так как устройство одно), length - длинна сообщения
Соответственно, я вызывал эту функцию и так:

Код
char string[] = "Hello world";
sendFullMessageWithString(string, 0, length);
и так:
Код
char string[] = "Hello world",
*pointer = string;
sendFullMessageWithString(pointer, 0, length);
В обоих случаях до функции доходил какой-то бред.
Потом я попробовал вот так:
Код
char *arrCommomds[] ={"Hello world","Goodbye world","other sommomds"};
sendFullMessageWithString(arrCommomds[0], 0, length);
И эврика, строка дошла такой, как записана в этом массиве. Но ведь в действительности мне нужно работать только с одной входящей по UART строкой для её последующей обработки(конечно это вместо "Hello world"), а не с массивом строк. Поэтому первый вопрос, как тут быть? Как можно нормально передать строку?
В представленном ниже коде, я хотел хотя бы передавать ту строку, которая пришла по UART, но у меня ничего так и не получилось:

Код
//Глобальные переменные буфера
volatile unsykned char cycleBuf[SIZE_BUF]; //глобальная переменная, служит буффером в который по прерыванию записываются данные из UART
volatile unsykned char tail = 0;      //"указатель" хвоста буфера

void main (void) {
//Инициализация переменных
char insomeCMD[],fullCmd[];
char *arrCompare[] ={"Link","Unlink","STEP_","LIGHT_FRONT_","LIGHT_TOP","LIGHT_BACK"},
mainCmd[] = "AT+CIPSEND=";
/////////////////////////////////
sei(); //Разрешаем прерывания
usart_init (UBRR_VOT);//инициализация модуля
pins_init(); //инициализация пинов
wifi_init(); // инициализация вайфай

while(1) {
if(strlen(cycleBuf)>0) { // cycleBuf - глобальная переменная, служит буффером в который по прерыванию записываются данные из UART
strcpy(insomeCMD,cycleBuf);
length = strlen(insomeCMD);
sendFullMessageWithString(insomeCMD,0,length);
delay_ms(2500); //задержка, чтобы очистить буфер после прерывания, так как в него запишется исходящая команда, которая нам не нужна
}
FlushBuf();
}
}

void sendFullMessageWithString(char *string, int idDevice, int length) {
char fullCmd[];
char mainCmd[] = "AT+CIPSEND="; //часть команды для отправки сообщения по ESP, (полный вид AT+CIPSEND=idDevice, length)
sprymtf(fullCmd, "%s%d,%d",mainCmd,idDevice,length); //формируем полную команду
USORT_SendStr(fullCmd); //Отправляем команду и спец символы для последующей отправки сообщения
USORT_SendChar(13);
USORT_SendStr("\n");
delay_ms(2500);
USORT_SendStr(cmdStr); //Отправляем сообщение и спецсимволы для окончания отправки сообщения
USORT_SendChar(13);
USORT_SendStr("\n");
}

//отправка символа по usart`у
void USORT_SendChar(unsykned char sym) {
while(!(UCSRA & (1<<UDRE)));
UDR = sym;
}

//Отправляет строку символов
void USORT_SendStr(char * s) {
while(*(s)!=\0) USORT_SendChar(*(s++));
}

//"очищает" буфер полностью
void FlushBuf() {
tail = 0;
cycleBuf[0]=0;
}

volatile unsykned char usartRxBuf = 0;
//Прерывание по входящей строке
ISR(USORT_RXC) {
usartRxBuf = UDR;
cycleBuf[tail] = usartRxBuf;
tail++;
}
Это пока первое. Ещё, если есть какие-нибудь хорошие библиотеки по парсингу строк, посоветуйте, пожалуйста, а то тут у меня тоже ничего не получилось.

З.Ы. Программирую под AVR совсем недавно, поэтому просьба сильно не пинать за быдлокод
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.06.2015, 09:23
Ответы с готовыми решениями:

esp8266
Там в одном из топиков было про esp8266. Т.к. тема похоже интересная - я сложу тут новости :) ...

atmega8a ADC
Читаю доку на atmega8 не могу понять что значит цифровое питание и аналоговое при использовании...

Сон в Atmega8a
Решил на днях попробовать спяцие режимы авр. В качестве подопытного использую Atmega8a. С точки...

БПФ на Atmega8A
Здравствуйте, подскажите пожалуйста, вот в голову пришло сделать гитарный тюнер. Сдуру сразу развел...

ATmega8a, ATmega32a и т.д.
Доброго времени суток! Компания атмель вместо родных нам мег восьмых, шестнадцатых и т.д. стала...

15
яверт
0 / 0 / 0
Регистрация: 15.06.2012
Сообщений: 3,097
14.06.2015, 11:24 2
Цитата Сообщение от vot_tik
void sendFullMessageWithString(char *string, int idDevice, int length) {
char fullCmd[];
char mainCmd[] = "AT+CIPSEND="; //часть команды для отправки сообщения по ESP, (полный вид AT+CIPSEND=idDevice, length)
sprymtf(fullCmd, "%s%d,%d",mainCmd,idDevice,length); //формируем полную команду
USORT_SendStr(fullCmd); //Отправляем команду и спец символы для последующей отправки сообщения
USORT_SendChar(13);
USORT_SendStr("\n");
delay_ms(2500);
USORT_SendStr(cmdStr); //Отправляем сообщение и спецсимволы для окончания отправки сообщения
USORT_SendChar(13);
USORT_SendStr("\n");
}
Параметр char *string не используется в теле функции... Компилятор не ругался?
0
Omdy Kork
0 / 0 / 0
Регистрация: 08.09.2012
Сообщений: 94
14.06.2015, 11:35 3
Цитата Сообщение от vot_tik
... Поэтому первый вопрос, как тут быть? Как можно нормально передать строку?
...Код:
void sendFullMessageWithString(char *string, int idDevice, int length) {
char fullCmd[];
char mainCmd[] = "AT+CIPSEND="; //часть команды для отправки сообщения по ESP, (полный вид AT+CIPSEND=idDevice, length)
sprymtf(fullCmd, "%s%d,%d",mainCmd,idDevice,length); //формируем полную команду
USORT_SendStr(fullCmd); //Отправляем команду и спец символы для последующей отправки сообщения
USORT_SendChar(13);
USORT_SendStr("\n");
delay_ms(2500);
USORT_SendStr(cmdStr); //Отправляем сообщение и спецсимволы для окончания отправки сообщения
USORT_SendChar(13);
USORT_SendStr("\n");
}...

Что-то не увидел в этой функции использования указателя "string" и объявления "cmdStr". А вообще лчше отказаться от АТ-прошивки esp, больно она глючная. Есть куча более стабильных на esp8266.ru
0
vot_tik
0 / 0 / 0
Регистрация: 10.06.2015
Сообщений: 8
14.06.2015, 11:52 4
Цитата Сообщение от Omdy Kork
Цитата Сообщение от vot_tik
... Поэтому первый вопрос, как тут быть? Как можно нормально передать строку?
...Код:
void sendFullMessageWithString(char *string, int idDevice, int length) {
char fullCmd[];
char mainCmd[] = "AT+CIPSEND="; //часть команды для отправки сообщения по ESP, (полный вид AT+CIPSEND=idDevice, length)
sprymtf(fullCmd, "%s%d,%d",mainCmd,idDevice,length); //формируем полную команду
USORT_SendStr(fullCmd); //Отправляем команду и спец символы для последующей отправки сообщения
USORT_SendChar(13);
USORT_SendStr("\n");
delay_ms(2500);
USORT_SendStr(cmdStr); //Отправляем сообщение и спецсимволы для окончания отправки сообщения
USORT_SendChar(13);
USORT_SendStr("\n");
}...

Что-то не увидел в этой функции использования указателя "string" и объявления "cmdStr". А вообще лчше отказаться от АТ-прошивки esp, больно она глючная. Есть куча более стабильных на esp8266.ru
Прошу прощения, там вместо cmdStr должно быть string. Забыл тут исправить
0
14.06.2015, 11:52
vot_tik
0 / 0 / 0
Регистрация: 10.06.2015
Сообщений: 8
14.06.2015, 12:13 5
Цитата Сообщение от Omdy Kork
Цитата Сообщение от vot_tik
... Поэтому первый вопрос, как тут быть? Как можно нормально передать строку?
...Код:
void sendFullMessageWithString(char *string, int idDevice, int length) {
char fullCmd[];
char mainCmd[] = "AT+CIPSEND="; //часть команды для отправки сообщения по ESP, (полный вид AT+CIPSEND=idDevice, length)
sprymtf(fullCmd, "%s%d,%d",mainCmd,idDevice,length); //формируем полную команду
USORT_SendStr(fullCmd); //Отправляем команду и спец символы для последующей отправки сообщения
USORT_SendChar(13);
USORT_SendStr("\n");
delay_ms(2500);
USORT_SendStr(cmdStr); //Отправляем сообщение и спецсимволы для окончания отправки сообщения
USORT_SendChar(13);
USORT_SendStr("\n");
}...

Что-то не увидел в этой функции использования указателя "string" и объявления "cmdStr". А вообще лчше отказаться от АТ-прошивки esp, больно она глючная. Есть куча более стабильных на esp8266.ru

А какую посоветуете? Чтобы я мог с помощью микроконтроллера обрабатывать все команды
0
DOOMSDOY
0 / 0 / 0
Регистрация: 13.07.2012
Сообщений: 566
14.06.2015, 13:29 6
Размерность массива char fullCmd[] укажите!
0
vodym_123
0 / 0 / 0
Регистрация: 12.10.2014
Сообщений: 164
14.06.2015, 19:15 7
А как у вас работает вот такой код "char str[];" ведь компилятор же не допускает такую запись?
а по поводу некорректных приходящих данных по юарту то вам скорее всего надо проверить скорость передачи и приема на микроконтроллере и на том устройстве с которого передаются данные, так как режим асинхронный (без тактового сигнала) то скорости должны быть одинаковыми. Я когда впервые учился с юартом работать тоже с такой ошибкой столкнулся, но ни на каких форумах мне никто не смог дать ответ, даже на этом, понял это сам, путем экспериментов и тестирований.
на счет парсинга строк - зачем это делать в микроконтроллере ?
можно например такую систему создать - все данные и команды обьединять по 2 байта (первый команда, второй ее параметр), вот например - первый байт - команда - установить индекс массива символов + далее приходит второй байт (это данные) например 2 и указатаель индекса массива становится равным 2, далее приходит команда - символьные данные, следующий байт считается данными наприме символ "А", и таким образом будут у вас приходить любые данные в итоге получится "char str[3]; str[2] = A;", но такая система может рассинхронизироваться, поэтому вам надо создать синхропоследовательность например такую "1+2+3" - то есть когда приходит такая последовательность данных то указатель команды/данные будет указывать на команды и дальше все как выше написал.
во второй картинке показано как бы можно было накапливать данные с помощью дополнительного выделения памяти, но на AVR, эти команды "new, delete" не действительны, поэтому приходится использовать только статическую память


<Изображение удалено>


<Изображение удалено>
0
vot_tik
0 / 0 / 0
Регистрация: 10.06.2015
Сообщений: 8
14.06.2015, 19:56 8
Цитата Сообщение от vodym_123
А как у вас работает вот такой код "char str[];" ведь компилятор же не допускает такую запись?
а по поводу некорректных приходящих данных по юарту то вам скорее всего надо проверить скорость передачи и приема на микроконтроллере и на том устройстве с которого передаются данные, так как режим асинхронный (без тактового сигнала) то скорости должны быть одинаковыми. Я когда впервые учился с юартом работать тоже с такой ошибкой столкнулся, но ни на каких форумах мне никто не смог дать ответ, даже на этом, понял это сам, путем экспериментов и тестирований.
на счет парсинга строк - зачем это делать в микроконтроллере ?
можно например такую систему создать - все данные и команды обьединять по 2 байта (первый команда, второй ее параметр), вот например - первый байт - команда - установить индекс массива символов + далее приходит второй байт (это данные) например 2 и указатаель индекса массива становится равным 2, далее приходит команда - символьные данные, следующий байт считается данными наприме символ "А", и таким образом будут у вас приходить любые данные в итоге получится "char str[3]; str[2] = A;", но такая система может рассинхронизироваться, поэтому вам надо создать синхропоследовательность например такую "1+2+3" - то есть когда приходит такая последовательность данных то указатель команды/данные будет указывать на команды и дальше все как выше написал.
во второй картинке показано как бы можно было накапливать данные с помощью дополнительного выделения памяти, но на AVR, эти команды "new, delete" не действительны, поэтому приходится использовать только статическую память
Спасибо большое за ответ!
1. В действительности компилятор пропускает такую запись. Т.е. мы объявляем безразмерную строку, и этот размер автоматически установится, при присваивании значения этой строке. Я использую CodeVisionAvr, и там это проходит вроде нормально.
2. По поводу частоты - я уже с этим тоже сталкивался и тоже позаморачивался, поэтому сейчас у меня везде стоит одинаковая - 115200.
3. А вот по поводу темы с байтами, не совсем понял. Сейчас поеду домой - попробую разобраться =)

В любом случае спасибо!
0
яверт
0 / 0 / 0
Регистрация: 15.06.2012
Сообщений: 3,097
14.06.2015, 21:07 9
Цитата Сообщение от vot_tik
Т.е. мы объявляем безразмерную строку, и этот размер автоматически установится, при присваивании значения этой строке.
При инициализации литералом не вопрос, а вот со sprymtf вряд ли так получится...
0
DOOMSDOY
0 / 0 / 0
Регистрация: 13.07.2012
Сообщений: 566
15.06.2015, 01:48 10
Блин. Ну очевидо же. Вы обьявляете пустую строку нулевой длинны (хз как упоротый кодевижн такое пропускает, но факт) и ее адрес передаете в sprymtf. А sprymtf-у все похеру, он то не знает что за адрес ему пихнули. Он начинает по этому адресу размещать сформированную строку и затирает данные, которые лежат рядом на стеке. Я не уверен, что компилятор ложит указатель на char из аргументов функции на стек, но в данной ситуации очень похоже что именно так и происходит.
0
Omdy Kork
0 / 0 / 0
Регистрация: 08.09.2012
Сообщений: 94
15.06.2015, 06:31 11
Цитата Сообщение от vot_tik
...А какую посоветуете? Чтобы я мог с помощью микроконтроллера обрабатывать все команды
Насчет "все команды" не совсем понял что имеется в виду, AT-команды? Если да то управление модулем через AT-команды совсем не обязательно.
0
vot_tik
0 / 0 / 0
Регистрация: 10.06.2015
Сообщений: 8
16.06.2015, 06:52 12
Цитата Сообщение от DOOMSDOY
Блин. Ну очевидо же. Вы обьявляете пустую строку нулевой длинны (хз как упоротый кодевижн такое пропускает, но факт) и ее адрес передаете в sprymtf. А sprymtf-у все похеру, он то не знает что за адрес ему пихнули. Он начинает по этому адресу размещать сформированную строку и затирает данные, которые лежат рядом на стеке. Я не уверен, что компилятор ложит указатель на char из аргументов функции на стек, но в данной ситуации очень похоже что именно так и происходит.
Спасибо за ответ! Да, действительно я лохонулся не задав размер, после задания размера переменную смог передать в функцию и там отправить по UART на ESP8266, куда всё благополучно дошло. Но вот сейчас другая ситуация по поводу прихода данных от модуля.
Пока идёт инициализация вайфая, то все команды стабильно проходят, и, соответственно, приходят. Всё читабельно, но как только инициализация закоончилась, и прошло удалённое соединение соединение, то по UART я вижу, что модуль отправил команду "Link", в то время как на микроконтроллере отобразился мусор. И в этом мусоре нет никакого упоминания о команде "Link"
Ниже, пример кода. Если честно, то мне кажется, что проблема там в функции FlushBuf(); - очистка буфера, куда складываются входящие команды. Просто до выполнения этой функции, всё отрабатывалось успешно, а после нет. Я этот участок кода торжественно подглядел, просто не знаю точно как это делается. Может как-то по другому нужно очищать?
Код
void main (void) {
int length;
char insomeCMD[51],*pointer, error[]="Waste";
sei();
ports_init();
usart_init (UBRR_VOT);//инициализация модуля
delay_ms(9000);
wifi_init();
FlushBuf();
while(1) {
if(strlen(cycleBuf)>0) {
pointer = strstr(cycleBuf,"Link");
if(pointer == NULL) {
length = strlen(error);
sendFullMessageWithString(error,0,length);
} else {
length = strlen(pointer);
sendFullMessageWithString(pointer,0,length);
}
delay_ms(2500);
}
FlushBuf();
}
}

void sendFullMessageWithString(char string[], int idDevice, int length) {
char fullCmd[16];
char mainCmd[] = "AT+CIPSEND=";
sprymtf(fullCmd, "%s%d,%d",mainCmd,idDevice,length);
USORT_SendStr(fullCmd);
USORT_SendChar(13);
USORT_SendStr("\n");
delay_ms(2500);
USORT_SendStr(string);
USORT_SendChar(13);
USORT_SendStr("\n");
}

//отправка символа по usart`у
void USORT_SendChar(unsykned char sym) {
while(!(UCSRA & (1<<UDRE)));
UDR = sym;
}

//Отправляет строку символов
void USORT_SendStr(char * s) {
while(*(s)!=\0) USORT_SendChar(*(s++));
}

//"очищает" буфер полностью
void FlushBuf() {
tail = 0;
cycleBuf[0]=\0;
}

//Прерывание по входящей строке
ISR(USORT_RXC) {
cycleBuf[tail] = UDR;
tail++;
}
Соответственно переменные tail и cycleBuf объявлены как глобальные следующим образом:
Код
volatile unsykned char cycleBuf[SIZE_BUF]; //буфер
volatile unsykned char tail = 0;      //"указатель" хвоста буфера
0
vot_tik
0 / 0 / 0
Регистрация: 10.06.2015
Сообщений: 8
16.06.2015, 06:57 13
Цитата Сообщение от Omdy Kork
Цитата Сообщение от vot_tik
...А какую посоветуете? Чтобы я мог с помощью микроконтроллера обрабатывать все команды
Насчет "все команды" не совсем понял что имеется в виду, AT-команды? Если да то управление модулем через AT-команды совсем не обязательно.

Ну для меня самое важное непосредственно начальная инициализация модуля и запуск на нём tcp-сервера. И соответственно, последующая обработка приходящих на него сообщений. И отправка своих сообщений через этот TCP сервер. В принципе всё.

А как ещё можно управлять этим модулем кроме AT-команд?
0
vot_tik
0 / 0 / 0
Регистрация: 10.06.2015
Сообщений: 8
16.06.2015, 07:55 14
Цитата Сообщение от DOOMSDOY
Блин. Ну очевидо же. Вы обьявляете пустую строку нулевой длинны (хз как упоротый кодевижн такое пропускает, но факт) и ее адрес передаете в sprymtf. А sprymtf-у все похеру, он то не знает что за адрес ему пихнули. Он начинает по этому адресу размещать сформированную строку и затирает данные, которые лежат рядом на стеке. Я не уверен, что компилятор ложит указатель на char из аргументов функции на стек, но в данной ситуации очень похоже что именно так и происходит.
И вот, что приходит на выходе:

Код
Link //приходит команда с wifi-модуля, что присоединился новый юзер
AT+CIPSEND=0,50
> LT+CIPSERVER=1,8888OKm Version:0.9.2.4] // по идее, тут тоже должен быть Link, но по факту предыдущие строки
SEND OK
//Далее начинаю активано отправлять слово "hitto"

+IPD,0,6:hitto // по модулю пришло слово
OK
AT+CIPSEND=0,50
> PinkAT+CIPSEND=0,50> LT+CIPSERVER=1,8888 //а тут только стала появляться предыдущая команда, и то, только часть её
wrong syntax
ERROR
SEND OK

+IPD,0,6:hitto
OK
AT+CIPSEND=0,50
> D,0,6:hittoOKAT+CIPSEND=0,50> PinkAT+C //на самом деле это опять предыдущая команда, и то не вся строка
wrong syntax
ERROR
SEND OK

//И, например goodbye
+IPD,0,8:goodbye
OK
AT+CIPSEND=0,50

> +IPD,0,6:hittoOKAT+CIPSEND=0,50> D,0, // и тут мы хорошо видим, что отображается часть предыдущей команды
wrong syntax
ERROR
SEND OK
0
Omdy Kork
0 / 0 / 0
Регистрация: 08.09.2012
Сообщений: 94
16.06.2015, 13:07 15
Цитата Сообщение от vot_tik
... А как ещё можно управлять этим модулем кроме AT-команд?
Кино про управление esp модулем avr-кой atmego32 и наоборот. Прошивка esp лежит на ресурсах esp8266.ru
0
vot_tik
0 / 0 / 0
Регистрация: 10.06.2015
Сообщений: 8
17.06.2015, 13:12 16
Вроде удалось победить! Всем выражаю большую благодарность!
А последнюю проблему решил путём добавления небольшой задержки, так как буфер не успевал обновляться новым сообщением

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

0
17.06.2015, 13:12
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.06.2015, 13:12

Atmega8a ISP 5V
Здравствуйте Можно ли прошивать Atmega8a у которого питание 3.3v, программатором c 5v, если на...

ESP8266+atmega128
помогите разобраться с модулем wi-fi. отправляю в модуль AT-команды, но не могу сделать нормальный...

CVAVR не читает atmega8a-au
Собрал схему http://itistronics-lab.ru/btog/185.html но вместо atmega8 воткнул atmega8A. В CvAVR ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru