Wifi Module Interfacing With AVR
Wifi Module Interfacing With AVR
h>
#include "uart_noit_lib.h"
#include "config.h"
void main()
{
uart_init(UART_BAUDRATE);
for(;;)
{
c_printf_uart("AT\r\n");
}
}
//***************************************************************************
void uart_init(U32 speed)
{
UCSRB_N = 0 ; // Disable UART
Uart_set_baudrate(speed); //Setting the baud rate ,a macro in
"uart_no_int_lib.h"
UCSRA_N = (1<<UDRE_N);
UCSRC_N = (1<<USBS_N) | (1<<UCSZ1_N) | (1<<UCSZ0_N); //Setting frame
format
UCSRB_N = (1<<RXEN_N) | (1<<TXEN_N); // then, (re)enable UART. Enabling
the Transmitter&Receiver
}
//***************************************************************************
// @fn put_char_uart
//!
//! Put character on TX UART. If TxReady, the character to send on TX UART.
//!
//! @warning "uart_init()" must be performed before
//!
//! @param Character to send
//!
//! @return (none)
//!
//***************************************************************************
void put_char_uart (U8 char_2_send)
{
while ( !(UCSRA_N & (1<<UDRE_N)) ); // wait for empty transmit buffer
UDR_N = char_2_send;
}
//***************************************************************************
// @fn c_printf_uart
//!
//! Put a code-string on TX UART. The code-string is send up to null
//! character is found.
//!
//! @warning "uart_init()" must be performed before
//!
//! @param Pointer on U8 code-string
//!
//! @return (none)
//***************************************************************************
//void c_printf_uart (const U8 *c_string)
void c_printf_uart (U8 *c_string)
{
while(*c_string)
put_char_uart (*c_string++);
}
//*********************************************************************
But I encountered a problem that even though I see pulses in the scope when I sample the tx pin while sending "AT" , I can't see
nothing in the I/O view -->UDR1.
Why's that ?!
For the first step I want to receive just a single char from the OK string , like 'O' or 'K', so I'v wrote this code line :
c=get_char_uart();
//***************************************************************************
// @fn get_char_uart
//!
//! Get byte from RX UART. If UART has received a character, this character
//! is returned, if no character has been received, 0x00 is returned.
//!
//! @warning "uart_init()" must be performed before
//!
//! @param (none)
//!
//! @return Character from RX UART or 0x00 if nothing received
//!
//***************************************************************************
U8 get_char_uart (void)
{
U8 temp;
but unfortunately when I run the code step by step nothing is written into the c variable...
you'r right,my mistake, that's why I will put here all the code :
#include <avr/io.h>
#include "uart_noit_lib.h"
#include "config.h"
#include <string.h>
#include <util/delay.h>
void main()
{
int i;
U8 rxstr[50]={};
uart_init(UART_BAUDRATE);
while(1)
{
c_printf_uart("AT\r\n");
readString(rxstr);
if (strcmp(rxstr,"OK")==0)
{
for (i=0;i<5;i++) //if ESP response is OK, led blinking
5 times (for debugging)
{
DDRC=0xFF;
PORTC=0x00;
_delay_ms(1000);
PORTC=0xFF;
_delay_ms(1000);
}
}
}
}
//***************************************************************************
//! @file $RCSfile: uart_noit_lib.c,v $
//!
//! Copyright (c) 2005 Atmel.
//!
//! Please read file license.txt for copyright notice.
//!
//! @brief Low level routines for UARTs running without interrupt.
//!
//! These routines need some #define's of "board.h" file.
//!
//! @version $Revision: 2.00 $ $Name: jtellier $
//!
//! @todo
//! @bug
//***************************************************************************
//-----------------------------------------------------------------------
// Exemple of "x_printf_uart" using
// ================================
//
// #define FOSC 8000 // in KHz
// #define BAUDRATE 9600 // in K bit/s
// #define USE_UART 0 // only UART-0 will be used !
//
// U8 s_printf[80]; // 80 elements max for UART buffer
//
// uart_init(); // Setup UART at BAUDRATE (9600) Baud
//
// c_printf_uart("Counting from 0 to 9: ");
//
// for (i=0; i<10; i++) s_printf[i]=0x30+i; // Init UART buffer
// s_printf[i++]=0x0D; // "\r" - carriage return
// s_printf[i++]=0x0A; // "\n" - new line or line feed
// s_printf[i++]=0x00; // Null - End of string
// d_printf_uart(s_printf);
//
//------------------------------------------------------------------------
//_____ I N C L U D E S ___________________________________________________
#include <stdio.h>
#include "config.h"
#include "uart_noit_lib.h"
//_____ M A C R O S ________________________________________________________
//_____ D E F I N I T I O N S ______________________________________________
//_____ D E C L A R A T I O N S ____________________________________________
//***************************************************************************
// @fn uart_init
//!
//! UART initialization. Initialize the UART reffered by USE_UART definition
//! to BAUDRATE speed.
//! Initialization details: 8-bit, no parity, 2 stop-bit & no interrupt.
//!
//! @warning Set definition for BAUDRATE
//!
//! @param (none)
//!
//! @return (none)
//!
//***************************************************************************
void uart_init(U32 speed)
{
UCSRB_N = 0 ; // Disable UART
Uart_set_baudrate(speed); //Setting the baud rate ,a macro in
"uart_no_int_lib.h"
UCSRA_N = (1<<UDRE_N);
UCSRC_N = (1<<USBS_N) | (1<<UCSZ1_N) | (1<<UCSZ0_N); //Setting frame
format
UCSRB_N = (1<<RXEN_N) | (1<<TXEN_N); // then, (re)enable UART. Enabling
the Transmitter&Receiver
}
//***************************************************************************
// @fn get_char_uart
//!
//! Get byte from RX UART. If UART has received a character, this character
//! is returned, if no character has been received, 0x00 is returned.
//!
//! @warning "uart_init()" must be performed before
//!
//! @param (none)
//!
//! @return Character from RX UART or 0x00 if nothing received
//!
//***************************************************************************
U8 get_char_uart (void)
{
U8 temp;
//***************************************************************************
// @fn c_get_string_uart
//!
//! Put a code-string on RX UART.
//!
//! @warning "uart_init()" must be performed before
//!
//! @param Pointer on U8 code-string
//!
//! @return (none)
//***************************************************************************
//void readString(U8 *rxstr)
//***************************************************************************
// @fn put_char_uart
//!
//! Put character on TX UART. If TxReady, the character to send on TX UART.
//!
//! @warning "uart_init()" must be performed before
//!
//! @param Character to send
//!
//! @return (none)
//!
//***************************************************************************
void put_char_uart (U8 char_2_send)
{
while ( !(UCSRA_N & (1<<UDRE_N)) ); // wait for empty transmit buffer
UDR_N = char_2_send;
}
//***************************************************************************
// @fn c_printf_uart
//!
//! Put a code-string on TX UART. The code-string is send up to null
//! character is found.
//!
//! @warning "uart_init()" must be performed before
//!
//! @param Pointer on U8 code-string
//!
//! @return (none)
//***************************************************************************
//void c_printf_uart (const U8 *c_string)
void c_printf_uart (U8 *c_string)
{
while(*c_string)
put_char_uart (*c_string++);
}
//**************************************************************************
//! @file $RCSfile: config.h,v $
//!
//! Copyright (c) 2005 Atmel.
//!
//! Please read file license.txt for copyright notice.
//!
//! @brief Configuration file for this project.
//!
//! @version $Revision: 2.00 $ $Name: jtellier $
//!
//! @todo
//! @bug
//**************************************************************************
#ifndef _CONFIG_H_
#define _CONFIG_H_
//_____ I N C L U D E S ____________________________________________________
// Please declare _IAR_AVR_ in Compiler options if IAR Compiler is used,
// or declare _IMC_AVR_ in Compiler options if ImageCraft Compiler is
used.
# include "compiler.h"
#ifndef _AVR_IO_H_
#define _IMC_AVR_
#include "mcu.h"
#endif
//_____ M A C R O S _________________________________________________________
//_____ D E F I N I T I O N S _______________________________________________
while(1)
{
if ((*rxstr = get_char_uart()) == FALSE) // if there is
nothing waiting in the Rx pin, continue wait
continue;
if (*rxstr == '\n')
{
break;
}
rxstr++;
}
*rxstr='\0';
rxstr=head;
}
#include <avr/io.h>
#include "uart_noit_lib.h"
#include "config.h"
#include <string.h>
#include <util/delay.h>
void main()
{
int i;
U8 rxstr[30]={};
uart_init(UART_BAUDRATE);
while(1)
{
c_printf_uart("AT\r\n");
readString(rxstr);
}
//***************************************************************************
//! @file $RCSfile: uart_noit_lib.c,v $
//!
//! Copyright (c) 2005 Atmel.
//!
//! Please read file license.txt for copyright notice.
//!
//! @brief Low level routines for UARTs running without interrupt.
//!
//! These routines need some #define's of "board.h" file.
//!
//! @version $Revision: 2.00 $ $Name: jtellier $
//!
//! @todo
//! @bug
//***************************************************************************
//-----------------------------------------------------------------------
// Exemple of "x_printf_uart" using
// ================================
//
// #define FOSC 8000 // in KHz
// #define BAUDRATE 9600 // in K bit/s
// #define USE_UART 0 // only UART-0 will be used !
//
// U8 s_printf[80]; // 80 elements max for UART buffer
//
// uart_init(); // Setup UART at BAUDRATE (9600) Baud
//
// c_printf_uart("Counting from 0 to 9: ");
//
// for (i=0; i<10; i++) s_printf[i]=0x30+i; // Init UART buffer
// s_printf[i++]=0x0D; // "\r" - carriage return
// s_printf[i++]=0x0A; // "\n" - new line or line feed
// s_printf[i++]=0x00; // Null - End of string
// d_printf_uart(s_printf);
//
//------------------------------------------------------------------------
//_____ I N C L U D E S ___________________________________________________
#include <stdio.h>
#include "config.h"
#include "uart_noit_lib.h"
//_____ M A C R O S ________________________________________________________
//_____ D E F I N I T I O N S ______________________________________________
//_____ D E C L A R A T I O N S ____________________________________________
//***************************************************************************
// @fn uart_init
//!
//! UART initialization. Initialize the UART reffered by USE_UART definition
//! to BAUDRATE speed.
//! Initialization details: 8-bit, no parity, 2 stop-bit & no interrupt.
//!
//! @warning Set definition for BAUDRATE
//!
//! @param (none)
//!
//! @return (none)
//!
//***************************************************************************
void uart_init(U32 speed)
{
UCSRB_N = 0 ; // Disable UART
Uart_set_baudrate(speed); //Setting the baud rate ,a macro in
"uart_no_int_lib.h"
UCSRA_N = (1<<UDRE_N);
UCSRC_N = (1<<USBS_N) | (1<<UCSZ1_N) | (1<<UCSZ0_N); //Setting frame
format
UCSRB_N = (1<<RXEN_N) | (1<<TXEN_N); // then, (re)enable UART. Enabling
the Transmitter&Receiver
}
//***************************************************************************
// @fn get_char_uart
//!
//! Get byte from RX UART. If UART has received a character, this character
//! is returned, if no character has been received, 0x00 is returned.
//!
//! @warning "uart_init()" must be performed before
//!
//! @param (none)
//!
//! @return Character from RX UART or 0x00 if nothing received
//!
//***************************************************************************
U8 get_char_uart (void)
{
U8 temp;
//***************************************************************************
// @fn c_get_string_uart
//!
//! Put a code-string on RX UART.
//!
//! @warning "uart_init()" must be performed before
//!
//! @param Pointer on U8 code-string
//!
//! @return (none)
//***************************************************************************
//void readString(U8 *rxstr)
while(1)
{
*rxstr = get_char_uart();
if (*rxstr == FALSE) // if there is nothing waiting in the Rx
pin, continue sample
continue;
if (*rxstr == '\n')
{
rxstr++;
break;
}
rxstr++;
}
*rxstr='\0';
rxstr=head;
}
//***************************************************************************
// @fn put_char_uart
//!
//! Put character on TX UART. If TxReady, the character to send on TX UART.
//!
//! @warning "uart_init()" must be performed before
//!
//! @param Character to send
//!
//! @return (none)
//!
//***************************************************************************
void put_char_uart (U8 char_2_send)
{
while ( !(UCSRA_N & (1<<UDRE_N)) ); // wait for empty transmit buffer
UDR_N = char_2_send;
}
//***************************************************************************
// @fn c_printf_uart
//!
//! Put a code-string on TX UART. The code-string is send up to null
//! character is found.
//!
//! @warning "uart_init()" must be performed before
//!
//! @param Pointer on U8 code-string
//!
//! @return (none)
//***************************************************************************
//void c_printf_uart (const U8 *c_string)
void c_printf_uart (U8 *c_string)
{
while(*c_string)
put_char_uart (*c_string++);
}
'97' (in the rxstr string) which in ASCII equals the letter 'A'
then
Just to have a feeling how things work with my ESP (in BLUE - the AT command I send and in GREEN - the response) :
I really don't know why the response is not "\n\nOK" and just 'AT\n'
also, I'm not quite sure about the correctness of that line (in the readstring() function) :
if (*rxstr == '\n')
break;
Because the ESP module is still doing remote echo for you. It most likely defaults to that on every power-up.
If you'd go to interrupt driven reception into a ring buffer, you could then easily devise functions that
- Check if there is a complete line received and ready in the ring buffer. Lets assume that function has this signature: bool
receivedLineAvailable()
- Get a complete line out of the ring buffer. With just a little bit of effort you could even make it trim off any line ending chars (\r,
\n) before returning it. The signature woud look something like this: void getReceivedLine( char * line )
Now you can code a simple main loop going something like this
int main(void)
{
char line[32];
.
.
.
while (1)
{
// Do other stuff needed
.
.
.
// If there is a complete response line ready from the ESP module, then
deal with it
if (receivedLineAvailable()) {
getReceivedLine( line );
if (strcnmp(receivedLine, "AT", 2) {
// It's just an echo of a sent command - do nothing
}
else if (strcmp(line, "XYZ") {
// We got the exact response "XYZ", and will deal with it here
.
.
.
} else if (strncmp(line, "PQR", 3) {
// We got a response beginning with "PQR, and will deal with it
here
// Note that the complete response is still intakt in the variable
line, for further analysis
}
// ... and so on ...
}
This approach has several advantages, one being that the ring buffer will ...eeehh... buffer. I.e., even if you happen to spend time
in another piece of code for a while, the interrupt driven reception will happily receive any incoming chars and place them in the
buffer. They will stay there until you consume them at a later time. You just need to make sure that the ring buffer is big enough
and/or you dont hang in other pieces of the code for too long to make sure the buffer wont be over-run (to wear both the belt and
the braces, the interrupt driven reception should also cope with this and set a flag indicating any overrun, and your main loop
should check it before trying to get anything meaningful out of the buffer).
Another advantage is that you get your code divided into more logical modules, and "the main code" will not see any of the nitty-
gritty details of the reception. Why should it? Looking at te code in main you dont want to see those details. You want a
(slightly?) bigger picture, i.e. one step up the abstraction ladder. You just want to do things like ask "Is a response available?" and
"Get that response!".
The point is that I'm currently implementing a ring buffer (rxstr) in my code (see the changes (highlighted with a yellow color) in
the main and in the read_string()) :
#include <avr/io.h>
#include "uart_noit_lib.h"
#include "config.h"
#include <string.h>
#include <util/delay.h>
void main()
{
int i;
U8 rxstr[30]={};
uart_init(UART_BAUDRATE);
c_printf_uart("AT\r\n");
while(1)
{
readString(rxstr);
if (strcmp(rxstr,"OK")==0)
{
for (i=0;i<5;i++) //led blinking 5 times
{
DDRC=0xFF;
PORTC=0x00;
_delay_ms(1000);
PORTC=0xFF;
_delay_ms(1000);
break;
}
}
memset(rxstr,0,sizeof(rxstr));
}
}
//***************************************************************************
//! @file $RCSfile: uart_noit_lib.c,v $
//!
//! Copyright (c) 2005 Atmel.
//!
//! Please read file license.txt for copyright notice.
//!
//! @brief Low level routines for UARTs running without interrupt.
//!
//! These routines need some #define's of "board.h" file.
//!
//! @version $Revision: 2.00 $ $Name: jtellier $
//!
//! @todo
//! @bug
//***************************************************************************
//-----------------------------------------------------------------------
// Exemple of "x_printf_uart" using
// ================================
//
// #define FOSC 8000 // in KHz
// #define BAUDRATE 9600 // in K bit/s
// #define USE_UART 0 // only UART-0 will be used !
//
// U8 s_printf[80]; // 80 elements max for UART buffer
//
// uart_init(); // Setup UART at BAUDRATE (9600) Baud
//
// c_printf_uart("Counting from 0 to 9: ");
//
// for (i=0; i<10; i++) s_printf[i]=0x30+i; // Init UART buffer
// s_printf[i++]=0x0D; // "\r" - carriage return
// s_printf[i++]=0x0A; // "\n" - new line or line feed
// s_printf[i++]=0x00; // Null - End of string
// d_printf_uart(s_printf);
//
//------------------------------------------------------------------------
//_____ I N C L U D E S ___________________________________________________
#include <stdio.h>
#include "config.h"
#include "uart_noit_lib.h"
//_____ M A C R O S ________________________________________________________
//_____ D E F I N I T I O N S ______________________________________________
//_____ D E C L A R A T I O N S ____________________________________________
//***************************************************************************
// @fn uart_init
//!
//! UART initialization. Initialize the UART reffered by USE_UART definition
//! to BAUDRATE speed.
//! Initialization details: 8-bit, no parity, 2 stop-bit & no interrupt.
//!
//! @warning Set definition for BAUDRATE
//!
//! @param (none)
//!
//! @return (none)
//!
//***************************************************************************
void uart_init(U32 speed)
{
UCSRB_N = 0 ; // Disable UART
Uart_set_baudrate(speed); //Setting the baud rate ,a macro in
"uart_no_int_lib.h"
UCSRA_N = (1<<UDRE_N);
UCSRC_N = (1<<USBS_N) | (1<<UCSZ1_N) | (1<<UCSZ0_N); //Setting frame
format
UCSRB_N = (1<<RXEN_N) | (1<<TXEN_N); // then, (re)enable UART. Enabling
the Transmitter&Receiver
}
//***************************************************************************
// @fn get_char_uart
//!
//! Get byte from RX UART. If UART has received a character, this character
//! is returned, if no character has been received, 0x00 is returned.
//!
//! @warning "uart_init()" must be performed before
//!
//! @param (none)
//!
//! @return Character from RX UART or 0x00 if nothing received
//!
//***************************************************************************
U8 get_char_uart (void)
{
U8 temp;
//***************************************************************************
// @fn c_get_string_uart
//!
//! Put a code-string on RX UART.
//!
//! @warning "uart_init()" must be performed before
//!
//! @param Pointer on U8 code-string
//!
//! @return (none)
//***************************************************************************
//void readString(U8 *rxstr)
while(1)
{
*rxstr = get_char_uart();
if (*rxstr == FALSE) // if there is nothing waiting in the Rx
pin, continue sample
continue;
if (*rxstr == '\n')
{
rxstr++;
break;
}
rxstr++;
}
*rxstr='\0';
rxstr=head;
}
//***************************************************************************
// @fn put_char_uart
//!
//! Put character on TX UART. If TxReady, the character to send on TX UART.
//!
//! @warning "uart_init()" must be performed before
//!
//! @param Character to send
//!
//! @return (none)
//!
//***************************************************************************
void put_char_uart (U8 char_2_send)
{
while ( !(UCSRA_N & (1<<UDRE_N)) ); // wait for empty transmit buffer
UDR_N = char_2_send;
}
//***************************************************************************
// @fn c_printf_uart
//!
//! Put a code-string on TX UART. The code-string is send up to null
//! character is found.
//!
//! @warning "uart_init()" must be performed before
//!
//! @param Pointer on U8 code-string
//!
//! @return (none)
//***************************************************************************
//void c_printf_uart (const U8 *c_string)
void c_printf_uart (U8 *c_string)
{
while(*c_string)
put_char_uart (*c_string++);
}
You can see that I'm sampling the Rx pin char by char and inserting it into a buffer (rxstr) untill a '\n' character is reached (as
expected upon the protocol). Then I'm checking the string in the buffer and comparing it to 'OK'. If it's not equals 'OK' then I'm
cleaning the rxstr buffer and getting back to sample the Rx pin waiting for a characters to arrive in order to insert it into the rxstr
buffer but I'm getting nothing (!!!!) after the echo (if it's really an echo).
\n
\n
OK\n
I'm stuck in that Im not getting any 'OK' (and actually nothing after the echo) just that echo and I don't understand why... (even
though I continue to run after the breakpoint, still waiting for a characters to arrive).
Breakpoints and incoming data on the UART does not go well together. When your ESP module has sent the echo you receive it
and hit a breakpoint. Your AVR is now not executing any code at all, it is at a halt. Now the ESP module sends the "OK". Where
will it go? Well..., the 'O' might make it into the hardware U(DR register in the UART, but just stays there. Nothing is picking it
out. Right after that comes the 'K'. Kaboom!, and you have a collision in the UART. That is known as a data overrun.
Even with no breakpoints your current code copes badly, or not at all, with asynchronous events on the UART. You might spend
too much time in other pieces of the code to come back quickly enough to be ready to start polling for the next char before it
arrives. If you're unlucky and don't get back to the poll before the next-next character arrives you again have a data overrun.
Again: The remedy is interrupt driven reception and a ring buffer. The ring buffer will also simplify your analysis of incoming
data.
Please read up on ring buffers, an alternative term is "circular buffer". There have been MANY discussions on this before here on
AVRfreaks. You will find ready-to-run code if you don't want to write your own.
With that, you now have the ring buffer functionality nicely separated from the rest of your code. You can deal with interrupt-
driven reception, which will remedy the data overrun problem you're having. I won't talk here about how to set it up - we have an
excellent tutorial here on AVRfreaks showing you how to do that. What I will sketch is how simple it will be to get a received
character into the ring buffer:
Since the reception is interriupt driven, every received character will cause the ISR to run, the body of which will be extremely
simple:
{
ring_buffer_insert(UDR);
}
That's it! Get the char out of UDR and stuff it into the ring buffer. Done! The ISR exits and your main code resumes executing.
Simple. To the point. No intertwined and convoluted main code to try be able to run around and "do everything".
Your intellectual effort now lies in how you in your main loop look for a complete line in the ring buffer, and get it if it is there.
You should isolate this into separate functions as I suggested above.
----------
I believe that the tutorial on interrupt driven UART reception also has the basic code for a ring buffer but I'm not entirely sure. If
it has, then you're about to make some really good progress after studying it.
----------
Your problem is not unique in any way. In fact, there have been many here before you asking about communication between an
AVR and some device "talking the Hayes AT protocol". Look around and you shall find a lot!
Know what ?
Now, I'm not sure I really writing into the device , i.e not sure I really succeeded sending the msg to the avr pin and I will explain
what expreriment I did :
1. I connected the ESP to the PC and sent a command message 'AT+CWMODE=2' for configuring its mode as 2
(STA=1,AP=2,BOTH=3). The response was 'AT+CWMODE=2' then 'OK'.
2. I connected the ESP to the MCU and I sent a command "AT+CWMODE=1" through the mcu into the device (expecting to
change its mode from 2 to 1).
3. Then, in order to see if the configuration succeeded, I connected the ESP back to the PC and sent a query
message AT+CWMODE? and the response was unfortunately 2.
So, in conclusion, I have a problem with the sending and that's why (guess) I'm not receiving anything back.
What's strange in all this story is that in the scope I see pulses as if something flows in the tx pin of the mcu...
thanks!
So, in conclusion, I have a problem with the sending and that's why (guess) I'm not receiving anything back.
Don't jump to conclusions. You have previously said that you receive the "AT..." line. That is the echo thaty the ESP module
sends back to the AVR. So you are, or at least where, receiving.
I repeat what I tried to express eralier: The settings you do might very well be lost every time you power-cycle the ESP module.
That is why you still see an echo, i.e. every time the module is power cycled the ATE0 that you've sent is forgotten and the
module is back to the E1 setting that is the power-up default.
Now, go to the ESP data sheet and check out what the default is for the +CWMODE setting, and also try to figure out if it is
volatile or preserved between power-cycles. AND do this simple experiment:
3. Send AT+CWMODE=2
6. Send AT+CWMODE?
Then draw your conclusions. You might be correct above, but you base it on very weak circumstantial evidence.
I see from most all of the above that you're not taking in much of what I'm typing. Every time I try to explain (based on many
years here, and uncountable serial comms threads) what is your core problem(s) you bounce off into a different direction. That's
OK - in the end it is you who decides how to attack the problem. Nevertheless, since my advice has little (close to none at all)
impact I'll stop for now. It is not worth it for me spending the time reading, analyzing and writing responses when they are not
considered. Still, I wish you good luck!
Dear Johan,
I'm really sorry to hear that you'r thinking like that. I really appreciate your efforts to guide me, taking your advises seriously and
Its really help me. Please stay.
I'm actually trying to implement what you advised me to - using a receive interrupt and a circular/ring buffer for the receiving.
In addittion , I did the experiment you advised me to (see the attached photo) and the conclusion is that it's not a volatile after
Power-cycle
One can see that I Power-cycled the ESP by the gibberish line (which occuered when taking it out and connecting it again) and
the CWMODE stayed 3 after it as configured before.
OK, I'll do the searches for you. What is unavoidable is that it is you who must do the reading.
Note that for both those the author Dean Camera says he has updated version on his own web site.
Generic explanation of what a circular buffer is and how it works: https://en.wikipedia.org/wiki/Ci...
A lightweight ring buffer implementation, written by the same Dean Camera that wrote the two tutorials
above: http://www.fourwalledcubicle.com... . You will likely want to modify the size of the buffer, ad you will need to
complement it with the functions to "peek" into the buffer to see if there is a complete line waiting.
What would happen if one detects the EOL char in the interrupt?
SIGNAL (SIG_UART_RECV) {
// lecture du caractère reçu
char c = UDR ; // c has just been received
There were a global variable EolnDetected main can set to zero and ISR sets to 1 (say)
OK then, I followed your instructions and I coded something initially (using a ring buffer and implemented the ISR i.e interrupt
driven) that meant to read a string from the rx pin by ISR (without dealing with edge cases, for the first steps, like checking EOL)
but it seems not to work and I don't know why.
my code is :
#include <avr/io.h>
#include <avr/interrupt.h> // ISR handling.
#include "uart_noit_lib.h" // routines for UART comms.
#include "config.h"
/*
Global Variables:
Variables appearing in both ISR/Main are defined as 'volatile'.
*/
volatile int rxn=0; // buffer 'element' counter.
volatile U8 rxstr[BUFFER_SIZE]; // buffer of 'char'.
volatile uint8_t rxFlag = 0; //entire byte wasted for using a single bit
//Interrupt Service Routine (ISR) - only serviced whenever the USART hardware
module receives a byte of data in the rx pin
ISR(USART1_RX_vect)
{
while ( !(UCSRA_N & (1<<RXC_N)) ); // Do nothing cause there is no any
data on the Rx pin
if (rxn == BUFFER_SIZE) // if BUFFER_SIZE is reached, reset to start
of buffer.
rxn=0;
rxstr[rxn++] = UDR_N; // increment rxn and return new value.
rxFlag=1; // Interrupt 'flag' being reset to notify main() of receipt
of data (the byte held in the register 'UDR' is read)
}
void main()
{
int i;
uart_init(UART_BAUDRATE);
UCSRB_N |= (1<<RXCIE1); // Enable the USART Receive complete interrupt
(USART_RXC)
sei(); // Enable the Global Interrupt Enable flag so that interrupts
can be processed
c_printf_uart("AT\r\n");
while (1)
{
if (rxFlag==1)
{
for (i=0;i<rxn;i++)
put_char_uart(rxstr[i]);
rxFlag=0;
put_char_uart("'\n'");
}
}
}
So I checked the transmit (by connecting the MCU to the PC [through a ttl to usb converter) with the same baudrate as my
module has] and I get AT on the screen, i.e sending AT commands succeeded.
I also wanted to check the implementation of the ISR by also sampling the tx pin (also by connecting the MCU to the PC
[through a ttl to usb converter) with the same baudrate as my module has]) but I didn't get OK response transmitted back.
Where am I wrong :/ ?
Wait wait, I want to go step by step and understand why it's not working.
the warning is : Warning 7 'USART1_RXC_vect' appears to be a misspelled signal handler [enabled by default]
I'v looked in the data sheet of the at90can128 (page 61), the vector number is 33 and it's match my mcu header :