PLEASE HELP ME FOR THIS CODE!!!!

Go To Last Post
18 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

**reformed**

 

HI FORUMS

i'm trying drive ESP8266 module with atxmega32a4u.this module interfacing with usart(baud rate 115200,8 bit data,2 stop bit,no parity).i write following code to write a AT COMMAND to module and read response from it.the "OK" response determine with {0x0d,0x0a,0x0d,0x0a,0x4f,0x4b,0x0d,0x0a} stream  and "ERROR" response with {0x0d,0x0a,0x0d,0x0a,0x45,0x52,0x52,0x4f,0x52,0x0d,0x0a} .some of AT COMMANDs need a data that should send after it.this type of command send '>' after "OK" response in order to user send data then respond "SEND OK".some of AT COMMAND give us information.these commands first respond {0x0d,0x0a,0x2b} stream then information and respond "OK" at the end.if informations be a lot,each line start with {0x2b} and end with {0x0d,0x0a}and respond "OK" at the end.

so my code is :

#define '\CR' 0x0d
#define '\NL' 0x0a
inline void grt_information (char *buff);
inline void send_data (char *data);
int i1=0;
char ch;                                             // global index for write or read buffer
ESP_RESPONDE ESP_WRITE(char *AT_CMD,char *ESP_DATA){
	ESP_RESPONDE res;                                //variable for store response
	int i;
	for (i=0;AT_CMD[i]!='\0';i++)                      //send AT COMMAND
		usart_putchar(USART_SERIAL, AT_CMD[i]);    //send AT COMMAND with usart
	usart_putchar(USART_SERIAL, '\CR');                //each AT COMMAND end with \r\n.
	usart_putchar(USART_SERIAL, '\NL');
	i=1;
	do
	{
		ch=usart_getchar(USART_SERIAL);
		switch (i)
		{
		case 1:
			if(ch == '\CR')i++;
		break;
		case 2:
			if(ch == '\NL') i++;
			else i=1;
		break;
		case 3:
			if(ch == '\CR') i++;
			else if(ch == '+'){               //receive '+' mean,information will receive
			    get_information(ESP_DATA);	  //call this function for get information
			    i=2;          //in above function receuve '\CR' character checked,so jamp on step 2 to check '\NL' character
			}
			else i = 1;
		break;
		case 4:
			if(ch == '\NL')i++;
			else i = 1;
		break;
		case 5:
			if (ch == 'O') i++;
			else if (ch == 'E')i=9;
			else i = 1;
		break;
		case 6:
			if(ch == 'K')i++;
			else i=1;
		break;
		case 7:
			if(ch == '\CR')i++;
			else i=1;
		break;
		case 8:
			if(ch=='\NL'){
				if(ch=usart_getchar(USART_SERIAL) == '>'){  //when '>' receive after "OK" response,data should send
					send_data(ESP_DATA);                //call this function for send data stored in buffer with usart
				}
				else res= ESP_OK;                           //if '>' dont receive ,the command is ended.
			}
			else i=1;
		break;
		case 9:
			if(ch == 'R')i++;
			else i = 1;
		break;
		case 10:
			if(ch=='R')i++;
			else i=1;
		break;
		case 11:
			if(ch=='O')i++;
			else i=1;
		break;
		case 12:
			if(ch=='R')i++;
			else i=1;
		break;
		case 13:
			if(ch=='\CR')i++;
			else i=1;
		break;
		case 14:
			if(ch == '\NL')res = ESP_ERROR;
			else i = 1;
		break;
		}
	} while (ch != '\0');
return res;
}

inline void get_information (char *buff){
    ESP_DATA[i1] = '+';                   //insert '+' in the first of each line of information to separate lines
    for (i1++;(ch = usart_getchar(USART_SERIAL)) != '\CR';i1++)    //read information from usart,each information line end with \r\n
        buff[i1] = ch;                                             // store information on buffer.
}

inline void send_data (char *data){
    for(i1=0;ESP_DATA[i1]!='\0';i1++)                  //send data stored in buffer
        usart_putchar(USART_SERIAL,ESP_DATA[i1]);      //send buffer with usart
    usart_putchar(USART_SERIAL,13);                    // data end with \r\n
    usart_putchar(USART_SERIAL,10);
    i1=0;             //clear index for next task
    do				//wait for receive send ok response actually receive "OK"
    {
        ch=usart_getchar(USART_SERIAL);
        switch(i1)
        {
        case 0:
            if(ch == 'O')i1++;
        break;
        case 1:
            if(ch=='K') return ESP_SEND_OK;
            else if(ch != 'O') i1=0;
        break;
        }
    } while (ch!='\0');
}

 

 

 

actually it is a function that is called from main function.about this function :

  • param :
  1. AT_CMD : is AT COMMAND that should send.
  2. ESP_DATA : pointer to buffer that store information will receive or DATA that will transmit
  • i use ATMELL STUDIO 6.1 and ASF 3.9.1

 

and but my problem :

when call this function with a AT COMMAND which dont need data and dont respond information(other case dont check) the program looping or lopped (i cant write english exactly) in this function.

 

**reformed**

 

* Moved by moderator. *

 

Last Edited: Sun. Jul 2, 2017 - 05:40 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Do you realise you've made your code difficult for the average human to understand?

First up - some of the code can be put into functions. This helps divide up the problem into manageable pieces.

Next you've got a state machine with magic numbers. If you had some comments, that would make it easier to comprehend. Eg: what does 5 mean? Why 5 and not 0? What is state 5 looking for?

For carriage return and line feed you could do something like this:

#define CR 10

#define LF 13

 

Realistically, if you've got the memory, you would read the response into a buffer - then decode it. You try to do both at once. You wrote the code, so if you can't debug it, then you've outsmarted yourself.

Personally, I'd suggest you re-write the code and at least add comments so we can understand it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

is it ok?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

daryooosh wrote:

is it ok?

 

If Kartman said...

I'd suggest you re-write the code

do you think he is saying it is OK?

 

Ross McKenzie ValuSoft Melbourne Australia

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1
if(ch=usart_getchar(USART_SERIAL) == '>')

Parentheses missing.

 

} while (ch != '\0');

When does that happen? Does usart_getchar return zero under some circumstances (eg. a timeout)? I hope you don't expect to receive a string termination from the ESP8266.

 

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

valusoft wrote:
do you think he is saying it is OK?
OP did change the code after Kartman made his comment. So he is actually asking whether the changes are ok (whether the changes are following Kartmans advice).

 

@daryooosh: Don't do that! It destroys the logical order of the thread and confuses people. Always do a new post for a new version of the code instead.

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

daryooosh wrote:

#define '\CR' 0x0d 
#define '\NL' 0x0a

 

No - that's not what Kartman said - is it?

 

That is basic 'C' syntax stuff - so time to go back and check your 'C' textbook

 

Here are some 'C' learning & reference resources for you - including a free online textbook: http://blog.antronics.co.uk/2011...

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, I don't know anything about ASF functions, but:

int usart_getchar

  ( volatile avr32_usart_t *  usart )  

Waits until a character is received, and returns it.

Parameters

usart Base address of the USART instance.

Returns

The received character, or USART_FAILURE upon error.

So, if there is no character to be received, this function will just wait forever.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

i edit my code then said is it ok?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

first thank for all answer.heartwink

 

valusoft wrote:
do you think he is saying it is OK?
 

 

first i edit my code then asked is it ok ?

 

 

sternst wrote:
Parentheses missing.

you are right,but this dont cause program looped or loopinglaugh

 

 

sternst wrote:
I hope you don't expect to receive a string termination from the ESP8266

what dont i expect to receive a string ..... ? 

 

El Tangas wrote:
So, if there is no character to be received, this function will just wait forever.

certainly,ESP8266 after receive a command send a response(i see response with usart in loptop),i think this response terminate with NULL character like other string.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

daryooosh wrote:
i think this response terminate with NULL character like other string.

No.

 

The NUL character has to be added internally by your code.

 

The NUL character is purely an internal 'C' thing for marking the end of the string. Except in very rare cases:

 

  • The NUL is not transmitted when sending to the "outside world";
  • The NUL is not part of the data received from the "outside world".

 

Note that most (all?) of the standard 'C' library string functions do specifically document their handling of the NUL.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

daryooosh wrote:
i edit my code then said is it ok?

And you see the confusion that caused?!

 

Which is why sternst wrote:
@daryooosh: Don't do that! It destroys the logical order of the thread and confuses people. Always do a new post for a new version of the code instead.

 

http://www.avrfreaks.net/comment...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
while (uart_has_data) { 
		// Add a byte to the buffer:
	esp_data.buff[esp_data.buff_index++] = uart0_getch();
		// Check if we have enough bytes to check for a new line:
	if (esp_data.buff_index > 2) {
			// Null terminate the received data:
		esp_data.buff[esp_data.buff_index] = 0;
			// Check for a new line:
		if ((esp_data.buff[esp_data.buff_index-2] == '\r' && esp_data.buff[esp_data.buff_index-1] == '\n') {
		    // Go to next stage:
		    break;
		}
	}
}

case RX_STAGE_ID:
		// Check for IP_data:
	if (strstr_P (esp_data.buff, PSTR(IP_DATA)) != NULL) {
			// HTTP request or other data:
		esp_data.processed = false;
		// Go to next stage:
		break;
		
	} else if (strstr_P (esp_data.buff, PSTR(CLIENT_CONNECT)) != NULL) {
			// Add the connection ID to the client list:
		if (sscanf_P (esp_data.buff, PSTR("%d,CONNECT/r/n"), &iValue) == 1) {
			if (iValue < 4 && iValue >= 0) {
				esp_data.connection_list[iValue] = 1;
			}
		}
		// Go to idle stage:
		break;
	
	} else if (strstr_P (esp_data.buff, PSTR(CLIENT_CLOSED)) != NULL) {
			// Remove the connection ID from the client list:
		if (sscanf_P (esp_data.buff, PSTR("%d,CLOSED\r\n"), &iValue) == 1) {
			if (iValue < 4 && iValue >= 0) {
				esp_data.connection_list[iValue] = 0;
			}
		}
		// Go to idle stage:
		break;
	
	} else if (strstr_P (esp_data.buff, PSTR(ESP_WDT_RESET)) != NULL) {
// Check for module reset:
		wifi.wdt_reset = true;
		// Go to idle stage:
		break;
	
	} else if (strstr_P (esp_data.buff, PSTR(WIFI_CONNECTED)) != NULL) {
// Update the wifi status to connected:
		wifi.status = true;
		// Go to idle stage:
		break;
	
	} else if (strstr_P (esp_data.buff, PSTR(WIFI_DISCONNECT)) != NULL) {
// Update the wifi status to disconnected:
		wifi.status = false;
		// Go to idle stage:
		break;
	
	} else if (strstr_P (esp_data.buff, PSTR(WIFI_GOT_IP)) != NULL) {
// Update the wifi status to got IP:
		
		// Go to idle stage:
		break;
		
	} else {
			// Add the line to the AT response buffer if a response is expected.  Also check for end of AT response:
		if (!esp_data.AT_response) {
				// Check for AT success:
			if (strstr_P (esp_data.buff, PSTR(AT_OK)) != NULL) {
				esp_data.AT_response = 1;
				esp_data.AT_success = 1;
			} else if (strstr_P (esp_data.buff, PSTR(AT_ERROR)) != NULL) {	// Check for AT failure:
				esp_data.AT_response = 1;
				esp_data.AT_success = 0;
			} else {
					// We have an AT response or some other unsolicited data:
					// A line has been received so flag it for processing:
				esp_data.AT_line_received = true;
			}
				// Reset:
	    	// Go to idle stage:
			break;
		} else {
				// Unknown data reset:
		    // Go to idle stage:
			break;
		}
		break;
	}
	break;

This is a code snippet of my ESP processor.  I don't do blocking calls, so every process is run as a state machine and each is serviced in a round-robin fashion.  The receive process monitors the unsolicited data that the ESP spits out and if an AT command is expecting a response the result is updated above.  The AT commands are sent from another process, but the code snippet above should be helpful for you to determine what to do with your ESP data.  The PSTR("somestringhere") along with the somefunction_P () because all strings are stored in program memory instead of eating RAM.  I have put some pseudo code above, but the general idea is there.  I would suggest setting up your UART with a circular buffer if you haven't already.  I wait for a \r\n then send each line off for processing.  If I don't receive \r\n within a timeout I process what I have.  You also need to NULL terminate the data from the ESP if you are going to use the string functions as shown in the code above.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:
daryooosh wrote: i think this response terminate with NULL character like other string. No.   The NUL character has to be added internally by your code.   The NUL character is purely an internal 'C' thing for marking the end of the string. Except in very rare cases:   The NUL is not transmitted when sending to the "outside world"; The NUL is not part of the data received from the "outside world".   Note that most (all?) of the standard 'C' library string functions do specifically document their handling of the NUL.  

 

thanks for answerheart

so you say that program counter stay in this "do {}while". if i replace "res = ESP_OK" with "return ESP_OK" and "res=ESP_ERROR" with "return ESP_ERROR" and assume that response is OK or ERROR ,the program must exit from function and dont looped or looping.is it ok?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

IdiocyCubed wrote:
This is a code snippet of my ESP processor.

 

thanks for answerheart

it is helpful but i want solve my code.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

daryooosh wrote:

IdiocyCubed wrote:
This is a code snippet of my ESP processor.

 

thanks for answerheart

it is helpful but i want solve my code.

 

Well if I wanted to be cruel, I might ask... "Why are you asking for help here?". But basically I am not cruel... devil

Ross McKenzie ValuSoft Melbourne Australia

Last Edited: Mon. Jul 3, 2017 - 06:59 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

daryooosh wrote:
it is helpful but i want solve my code.

Have you studied it to see if it gives any "solutions" to your code?

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

daryooosh wrote:
i want solve my code.

Your code as shown in #1 still contains some basic errors; eg, see #7

 

We are also confused, because you have retrospectively edit your opening post. Again, do not do that!

 

So we are unsure what is the actual current state of your code.

 

So please post a new Reply - do not edit previous posts - with the current state of your code.

 

When posting code, always use your editor's copy & paste facility;  do not manually re-type it into the post - that just introduces transcription errors and, thus, causes confusion.