Using data received via USART

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

I am experimenting with USART capabilities of my ATMega8, and am trying to write code that that will let my send commands to the ATMega8 via a serial connection with my PC. The commands will cause a servo wired to the circuit to rotate a given direction depending on the command received via the serial connection. For example, I want the code to work as follows:

    if user enters "1" in terminal -> servo rotates to full counter-clockwise if user enters "2" in terminal -> servo rotates to center
    if user enters "3" in terminal -> servo rotates full clockwise
The servo command code looks like this:

if((ServoCommand == 1) || (ServoCommand == 2) || (ServoCommand == 3))
{	
					
						
	switch(ServoCommand) 
	{						
		case 1:
	
			OCR1A = 0x258; //rotate to -90 degress (left)
			break;
							
		case 2:
			
			OCR1A = 0x5DC; //rotate to 0 degress (center)
			break;

		case 3:
			
			OCR1A = 0x960; //rotate to 90 degress (right)
			break;	
							
	} //end swtich
						
} //end if

Say, the user enters and sends "1" via hyper-terminal, as I understand things (I think) the UDR register will receive the following 8 bits -> 00110001. So, I need to write code that will convert or interpret those 8 bits as a a value of 1 and store that value in my variable "ServoCommand."

Pseudo-code akin to the following:

ReadByte = UDR
if ReadByte = 0b00110001 -> ServoCommand = 1
if ReadByte = 0b00110010 -> ServoCommand = 2
if ReadByte = 0b00110011 -> ServoCommand = 3
else printf("invalid command sent")

I am understanding this correctly?

Russ

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

First up, why do you test for values 1,2 and 3 then do a switch? You really only need to do the switch as logically it tests for the three conditions!

If you want to interpret ASCII numbers, yes, your pseudocode will work. You can more simply use the ascii values in the switch statement:

case '1':

case '2':

the '' causes the compiler to use the ascii values. Also there is the default case for a catch all.

default: //catch all
printf("invalid command");

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

You need not convert what you get from terminal.
Just write

   switch(ServoCommand)
   {                  
      case '1':
   
         OCR1A = 0x258; //rotate to -90 degress (left)
         break;
                     
      case '2':
         
         OCR1A = 0x5DC; //rotate to 0 degress (center)
         break;

Edit:
Damn, Kartman has beat me one minute.

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

Thank you very much for your help, Kartman and Visovian. I appreciate it!

Kartman wrote:
First up, why do you test for values 1,2 and 3 then do a switch? You really only need to do the switch as logically it tests for the three conditions!

In my full code, I am testing for a valid ServoCommand with an "else" (following the "if" block that I quoted above):

else
{
printf("Invalid command, please try again./n");
} //end else

I had included that test in the pseudo-code just to show that I was thinking about that possibility. But your point about the "default" case seems cleaner - - thanks!

Kartman wrote:
If you want to interpret ASCII numbers, yes, your pseudocode will work. You can more simply use the ascii values in the switch statement:

case '1':

case '2':

the '' causes the compiler to use the ascii values. Also there is the default case for a catch all.

default: //catch all
printf("invalid command");

I want to use the value of ServoCommand in other sections of my code. I suppose that I could use "#defines" to define the ascii values? As follows:

#define '1'	FCCW
#define	'2'	Center
#define	'3'	FCW

Using these definitions, I think, makes the code easier to follow as it better describes what is going on.

Thanks, again!

Russ

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

Actually the #defines would be:

#define FCCW '1'
#define CENTER '2'
#define FCW '3'

The defacto standard is that macros and #defines are in uppercase. In order to make it a bit more useable ( FCCW might apply to various things)

#define CMD_FCCW '1'
#define CMD_CENTER '2'

and so on

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

Thank you.

Russ