Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
JohanEkdahl
PostPosted: Jan 07, 2010 - 09:18 PM
10k+ Postman


Joined: Mar 27, 2002
Posts: 18543
Location: Lund, Sweden

Ha! My suspicions about bad grounding was well grounded! Very Happy

Happy that it worked out for you!
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
oitguy
PostPosted: Feb 28, 2010 - 05:01 AM
Newbie


Joined: Nov 05, 2009
Posts: 15


Thanks Dean, this is another clean tutorial. This has possibly been mentioned by others: The interrupt vector table (Attiny2313) gives a source of "USART0, RX" which would be thought to be converted to "USART0_RX_vect" for use in ISR(), however it must be specified as "USART_RX_vect" as stated here:

http://www.nongnu.org/avr-libc/user-man ... rupts.html
 
 View user's profile Send private message  
Reply with quote Back to top
Jericho_D_Niera
PostPosted: Mar 01, 2010 - 10:38 AM
Newbie


Joined: Mar 01, 2010
Posts: 2


hello guys! i'm jericho. i'm trying to learn avr micros, i'm studying it for about 3 weeks now and this site help me a lot!

now i'm having a hard time doing my code. i'm using atmega8 to be interfaced with a GPS module. i already made a code displaying GPS data sent to the MCU then the MCU sending the gps data to hyperterminal..

but now, i'm trying to display this in hyperterminal

Code:


time: (current GPS time)



unfortunately, i can't do it. it seems like my code is not working.. here it is..

Code:


//   atmega8    //


#include <avr/io.h>
#include <inttypes.h>
#include <util/delay.h>
#include <avr/interrupt.h>


#define USART_BAUDRATE 4800
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)


volatile uint8_t data, parsing_state, state;
volatile int8_t ReceivedByte[5], time[13], latitude[12];
volatile int8_t longitude[13], speed[6], date[9] ;


void init_uart()
{
   // enable Tx/Rx circuitry
   UCSRB |= (1<<RXEN) | (1<<TXEN);

   // 4800bps, 8-bit data, no parity, 1 stop bit
   UCSRC |= (1<<URSEL) | (1<<UCSZ0) | (1<<UCSZ1);

   UBRRL = BAUD_PRESCALE;
   UBRRH = (BAUD_PRESCALE>>8);
}


void gprmc_only()
{
   int8_t GPRMC[] = "$PSTMNMEACONFIG,0,4800,64,1\r\n";

   while (GPRMC[data] != 0x00)
   {
      while ((UCSRA & (1<<UDRE)) == 0) {};
      UDR = GPRMC[data++];
   }
}


void time_menu()
{   
   data = 0;

   int8_t real_time[] = "time: ";
   
   while (real_time[data] != 0x00)
   {
      while ((UCSRA & (1<<UDRE)) == 0) {};
      UDR = real_time[data++];
   }
   
   data = 0;
   
   while (time[data] != ',')
   {
      while ((UCSRA & (1<<UDRE)) == 0) {};
      UDR = time[data++];
   }

   state = 0;   
}               

int main (void)
{
   init_uart();

   state = 0;
   parsing_state = 0;
   data = 0;
   
   UCSRB |= (1<<RXCIE);   // enable Rx complete interrupt

   _delay_ms(1000);
   _delay_ms(1000);
   _delay_ms(1000);

   gprmc_only();

   sei();   // enable all interrupt

   while (1)
   {
      if (state == 1)
      {
         UCSRB |= (0<<RXCIE); // disable Rx interrupt
         
         time_menu();
   
         UCSRB |= (1<<RXCIE); // enable Tx interrupt
      }

   }
}


ISR (USART_RXC_vect)
{
   switch (parsing_state)
   {
      case 0:

         data = 0;

         ReceivedByte[data] = UDR;
         
         if (ReceivedByte[data] == '$')
            parsing_state++;
         
         else
         {
            parsing_state = 0;
            state = 0;
         }

         break;


      case 1:
   
         ReceivedByte[data] = UDR;
         
         if (ReceivedByte[data] == ',')
            parsing_state++;
         
         else
         {
            parsing_state = 1;
            state = 0;
         }
            
         break;   


      case 2:

         data = 0;

         time[data] = UDR;

         if (time[data] == ',')
            parsing_state++;
         
         else
         {
            data++;
            parsing_state = 2;
            state = 0;
         }

         break;


      case 3:
         
         data = 0;

         ReceivedByte[data] = UDR;
         
         if (ReceivedByte[data] == ',')
            parsing_state++;

         else
         {
            parsing_state = 3;
            state =0;
         }

         break;

      case 4:
         

         data = 0;

         latitude[data] = UDR;

         if (latitude[data] == ',')
            parsing_state++;

         else
         {
            parsing_state = 4;
            data++;
            state = 0;
         }
            
         break;

      case 5:


         data = 0;

         ReceivedByte[data] = UDR;

         if (ReceivedByte[data] == ',')
            parsing_state++;

         else
         {
            parsing_state = 5;
            state = 0;
         }

         break;


      case 6:
         
         data = 0;

         longitude[data] = UDR;

         if (latitude[data] == ',')
            parsing_state++;

         else
         {
            parsing_state = 6;
            data++;
            state = 0;
         }

         break;


      case 7:
   
         data = 0;
         
         ReceivedByte[data] = UDR;
         
         if (ReceivedByte[data] == ',')
            parsing_state++;
         
         else
         {
            parsing_state = 7;
            state = 0;
         }
            
         break;

                  
      case 8:
         
         data = 0 ;

         speed[data] = UDR;

         if (speed[data] == ',')
            parsing_state++;

         else
         {
            parsing_state = 8;
            data++;
            state = 0;
         }

         break;


      case 9:
         
         data = 0;

         ReceivedByte[data] = UDR;

         if (ReceivedByte[data] == ',')
            parsing_state++;

         else
         {
            parsing_state = 9;
            state = 0;
         }

         break;

                        
      case 10:
         
         data = 0;

         date[data] = UDR;

         if (date[data] == ',')
            parsing_state++;

         else
         {
            parsing_state = 10;
            data++;
            state = 0;
         }
         
         break;


      case 11:

         data = 0;
         
         ReceivedByte[data] = UDR;

         if (ReceivedByte[data] == 0x00)
         {
            parsing_state = 0;
            state = 1;
         }
            
         else
         {
            parsing_state = 11;
            state = 0;
         }
         break;
      
   }

}



i hope you can tell me what's wrong with my code.. thanks!
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Mar 01, 2010 - 11:00 AM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62270
Location: (using avr-gcc in) Finchingfield, Essex, England

Forget the interrupts and the GPS parsing to start with. Are the basics working? If you simply:
Code:
int main(void) {
  init_uart();
  while(1) {
     while ((UCSRA & (1<<UDRE)) == 0) {};
     UDR = 'A';
  }
}

do you see a stream of 'A's at 4,800 baud on your PC terminal?

If you then modify that to just have a single character RXC interrupt handler that main() echoes back does that then work?

Continue adding the program complexity back in and retesting until you find any flaw in the logic but don't expect all of such a complex program to all work right from the start.

Make a lot of use of the PC terminal for debugging. Remember that if the AVR only RX's from the GPS then as long as you stick to 4800 you can split TX/RX so TX goes to the PC terminal as a debug output and RX is the connection from the GPS

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
Jericho_D_Niera
PostPosted: Mar 01, 2010 - 03:04 PM
Newbie


Joined: Mar 01, 2010
Posts: 2


hi clawson! thanks for the reply!

i already did what you've said before doing this. and it worked fine. i also finished writing a code that will display the GPS data sent to the MCU then the MCU sending the data to hyperterminal. but after inserting the parsing routine, it seems stopped working..

Sad
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Mar 01, 2010 - 03:06 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62270
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

but after inserting the parsing routine, it seems stopped working..

In which case you have identified the bit that requires the work - now break that into small implementation steps and try to find the point where it stops behaving as expected.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
rnable
PostPosted: Mar 23, 2010 - 10:55 AM
Newbie


Joined: Mar 04, 2010
Posts: 5


Hello all,
How i can extract only #GPRMC sentence from all nmea sentences ? Jericho wrote code isn't universal function for taking only gprmc. Im thinking to use data from "$" to "*" but how ?
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Mar 23, 2010 - 11:10 AM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62270
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:
How i can extract only #GPRMC sentence

http://www.maartenlamers.com/nmea/

(it's C++ for Arduino but you should be able to convert if you need it in C)

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
rnable
PostPosted: Mar 23, 2010 - 05:19 PM
Newbie


Joined: Mar 04, 2010
Posts: 5


How i should convert it ? i never worked with Arduino :\
Any other suggestions in c language ?
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Mar 23, 2010 - 05:57 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62270
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

Any other suggestions in c language ?

I found that after 2 minutes with Google. If I'd spent the whole 5 minutes I'm sure I could have found C code - it's not like you are the first person who wants to parse NMEA. Try "parse NEMA GPRMC C source" or similar.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
rnable
PostPosted: Mar 23, 2010 - 07:26 PM
Newbie


Joined: Mar 04, 2010
Posts: 5


Need some TUTorials about avr interfacing with gps, like TUT using usart.. Confused
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Mar 24, 2010 - 09:59 AM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62270
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

Need some TUTorials about avr interfacing with gps, like TUT using usart..

Surely it's the same thing. They almost all use a 4800 baud UART link so this thread applies.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
rnable
PostPosted: Mar 24, 2010 - 07:12 PM
Newbie


Joined: Mar 04, 2010
Posts: 5


rnable wrote:
Need some TUTorials about avr interfacing with gps, like TUT using usart.. Confused



whoops, I meant parsing gps data with avr.. Rolling Eyes
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: Mar 24, 2010 - 07:51 PM
10k+ Postman


Joined: Mar 27, 2002
Posts: 18543
Location: Lund, Sweden

Quote:

I meant parsing gps data with avr..

That would be "Parsing GPS data in C", yes? C is a standardized language so, as long as you have the NMEA, you should be able to use any C code with only small changes.

Keeping the reception and the parsing divided is recommended: Getting the string is one thing. Parsing it is another. You could even develop and test the parsing code in on a PC with eg MS Visual Studio (a free Express version is available) so that you don't have to go through the relative awkwardness of debugging in AVR Studio, simulated or with on-chip debugging).

I'm fairly sure that we've had NMEA string parsing up here before. And it is almost sure that you can find C code on the web that is close to what you need.

Quote:

Need some TUTorials about avr interfacing with gps, like TUT using usart..

What you need, as I hinted about, is to try to think about the complete problem you're facing as consisting of several smaller, more manageable, problems.

The communication, getting the NMEA string is plain UART communication, and for that there is a tutorial (as you yourself has noted). Gete that working receiving the complete NMEA string.

Then create a new little project that sets up a constant NMEA string and start working on parsing that. (Steal code from the net. Or just get inspired by it.) The advantage of this approach is that you dont have the complete hardware setup running, and more importantly that you know what the string you're parsing looks like so you have a better chance of detecting bugs and debugging. When it works for that string you test it with a few variants. When you're gaining confidence in the parser, you hook the two things together.

Any successful programmer uses the principle of "divide and conquer" to solve problems. Un-experienced programmers not applying this principle most likely gets overwhelmed by the problem, or gets lost in a maze of problems and symptoms leading to an uncontrollable situation.

Going from one place to another with success is a matter of taking many small steps, rather than one giant leap. Patience is a necessary virtue of a programmer.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
divide_overflow
PostPosted: May 21, 2010 - 03:03 AM
Newbie


Joined: May 21, 2010
Posts: 3


As a certified newbie to AVR and and a current 8051 user(don't laugh), most of the tutorials and example code in proliferation it seems is written using GCC which is not obvious to the casual observer except for the #include <avr/io.h>. GCC is such a mountain of macros and header files that for someone (especially new)trying to decipher it into a working version using something other than GCC is a herculean and time consuming effort. Nowhere can I find anything that fully makes this known up front to someone using a commercial compiler. Mayabe I should have known...Turns out when it comes to gcc I have more money than time.

But again for beginners at AVR, it would be very helpful to put a disclaimer with the gcc stuff.

Sorry but this vent (not against anyone in particular it's just a beef with the way gcc seems "universal") has been building a while.

So feel free to torch back.
 
 View user's profile Send private message  
Reply with quote Back to top
ArnoldB
PostPosted: May 21, 2010 - 06:30 AM
Raving lunatic


Joined: Nov 29, 2007
Posts: 3219


divide_overflow wrote:
GCC is such a mountain of macros and header files that for someone (especially new)trying to decipher it into a working version using something other than GCC is a herculean and time consuming effort.
And why is that our problem?

Typical kids. They get code for free, but than insist the get also spoon feed. If they don't get spoon feed they spread FUD like
Quote:
GCC is such a mountain of macros and header files
. Whine, whine, whine. How disgusting.

Remember, YOU decided to use that "something other". No one forced you. YOU decided to not read the GCC and avr-libc manuals. And I am sure you worked very hard to avoid reading any serious text book about C programming ("For Dummies" guides and "in 21 days" junk don't count). And may I guess, YOU decided to use oh so simple looking stuff like MikroE C or Arduino, and now you are surprised that the rest of the world doesn't feed you with code.

If you are a professional programmer, please, consider a career change. You are obviously not even capable of operating a compiler. Like a carpenter isn't able to handle a saw.
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: May 21, 2010 - 10:09 AM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62270
Location: (using avr-gcc in) Finchingfield, Essex, England

didvide_overflow,

I fear you may have missed the point of this Tutorial forum. Any user of any compiler is quite at liberty to submit an article about how some function is performed using their compiler. I guess if there is an error here it is that tutorial authors are encouraged to either include "[GCC]" (or whatever "[IAR]", "[CV]", ...) in the name of the thread though many just use a title such as "using GCC's PROGMEM attribute". So perhaps this tutorial should have mentioned GCC in the thread title. OTOH the techniques it presents are generally portable to any compiler with the only part that is GCC specific being the ISR syntax but presumably the users of other compilers will know the corresponding ISR syntax to use?

The propensity of GCC articles here simply reflects its wide spread usage amongst both hobbyists and professionals.

Personally I'm having a hard time understanding how GCC is "worse" in the sense of header macro usage. The standard headers of most compilers are actually very close.

Moderator.

PS feel free to write and submit your own tutorials - they are always welcome.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
Ragooman
PostPosted: Jul 29, 2010 - 06:39 PM
Newbie


Joined: Apr 11, 2009
Posts: 16
Location: Pittsburgh,PA

Hello,
thanks for a great tutorial here.
I'm trying to upgrade the serial code in my robot. I'm using a ATMega128. I currently use a software polling code to send & receive thru the usart.
I added a little command line routine in our code to allow me to type in commands using TeraTerm terminal to access the Robot hardware and display telemetry data on the screen. At the moment, the robot is on a tether(serial cable), eventually we will upgrade to using a RF transceiver.
But now as the project gets larger I need to move to this type of Interrupt servicing USART method so as to keep the robot running and not sit waiting at the command line with software polling .

So since I'm dealing with strings on the command line, I use some of the standard library to get things done. Such as fgets and strcmp, as shown here below, but it's all software pollling. This works fine as it is, but when working with robots, you need to have the robot run independantly, and not wait for your commands using software polling.

I had initially used the sample code you have in this tutorial and stored each character of the command line into a buffer array. But then I didn't know how to continue using the 'strcmp' library to compare strings with what I have in the buffer array. I had to resort to comparing one character at a time, which becomes self-defeating--and the code becomes larger-- when working with a command line interface.

So I thought maybe there's someway of using Timer1 in combination with this, to simply check the usart few times a sec--without polling, but I'm not sure.
I hope you can suggest something.
Code:

//-----------------------------------------------
char cmd[80]; // buffer to construct parsable string terminating with CR

int main(void)
{     
.
.
.
     fgets( cmd, 80, stdin ); '//get command line string
     strip_newline( cmd, 80 ); //remove null terminator
.
.
.
     if ( strcmp ( cmd, "quit" ) == 0 )  //time to quit
      {
        //do something
      }
}
//-----------------------------------------------
// remove the null terminator from input string
void strip_newline( char *str, int size )
{
    int i;
    for (  i = 0; i < size; ++i )
    {
        if ( str[i] == '\n' )
        {
            str[i] = '\0';
            return;   /* we're done, exit function */
        }
    }
    /* if exit here, must not have been any newline! */
}
//-----------------------------------------------
 
 View user's profile Send private message  
Reply with quote Back to top
genetica
PostPosted: Aug 17, 2010 - 04:40 PM
Rookie


Joined: Jul 20, 2010
Posts: 36
Location: South Africa

Good day

I have a problem with interrupt driven USART.
firstly here is my code that does not work:

Code:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <string.h>

#define Buffer_Size 32
#define USART_BAUDRATE 9600
#define BAUD_PRESCALE 103

// Define the buffer structure
typedef struct buffer_
{
   char    data[Buffer_Size];
   uint8_t size;
} buffer;

// Set permanent buffer
   buffer   buf;   
   char    Command[Buffer_Size];
   
// Global variables
   uint8_t tel;

int main (void)
{
// Initialize Buffer
   buf.size = 0;

// Set RS485 enable pin as output
   DDRD |= (1<<DDD6);
   PORTD &= (0<<PORTD6);

// SETUP of USART 0
   // Turn on the TX RX
      UCSR0B |= (1 << RXEN0) | (1 << TXEN0);   

   // Use 8-bit char - Asynchronous, no parity, 1 Stop-bit
   UCSR0C |= (1 << UCSZ00) | (1 << UCSZ01);
        //Baud rate
   // Load lower 8-bits
   UBRR0L = BAUD_PRESCALE;
   // Load upper 8-bits
   UBRR0H = (BAUD_PRESCALE >> 8);
   
   tel = 0;

     // Enable the handling of USART interrupt vector
   UCSR0B |= (1 << RXCIE0)|(1 << TXCIE0);

      // Enable the Global Interrupts
      sei();

   for(;;)
   {
      if (tel == 1)
      {
                 //Set end of string     
         buf.data[buf.size] = 0;
                 //Copy string for command line
         strcpy(Command,&buf.data[1]);
                 // Reset buffer
         buf.size = 0;

         tel = 0;
                 //Output Enter
         PORTD |= (1<<PORTD6);
         UDR0 = '\r';
      }
   }
}

ISR(USART0_RX_vect)
{
   // Code to be executed when the USART receives a byte here
   char ReceivedByte;

   // Fetch the recieved byte
   ReceivedByte = UDR0;
   
   buf.size += 1;
   buf.data[buf.size] = ReceivedByte;

   if (ReceivedByte == '\r')
   {
      tel = 1;
   }
   else
   {
       //Clear previous data
                buf.data[buf.size+1] = 0;

            //Reflect received character
      PORTD |= (1<<PORTD6);
      UDR0 = buf.data[buf.size];
   }
}
   
ISR(USART0_TX_vect)
{
   PORTD &= (0<<PORTD6); // Enable RS485 receive
}


The code above works when you replace:
Code:
tel = 1;

(which is in the ISR) with the code within the if statement:
Code:
if (tel == 1)
      {
                 //Set end of string     
         buf.data[buf.size] = 0;
                 //Copy string for command line
         strcpy(Command,&buf.data[1]);
                 // Reset buffer
         buf.size = 0;

         tel = 0;
                 //Output Enter
         PORTD |= (1<<PORTD6);
         UDR0 = '\r';
      }


Why is that? What am I doing wrong when using the first code presented? Is it the way that USART interrupts work?
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Aug 17, 2010 - 04:46 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62270
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

Why is that?

FAQ#1

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits