Author Topic: UART and scanf. Please help.  (Read 11377 times)

0 Members and 1 Guest are viewing this topic.

Offline AntiLogickTopic starter

  • Jr. Member
  • **
  • Posts: 10
  • Helpful? 0
UART and scanf. Please help.
« on: January 23, 2012, 09:55:59 AM »
Hello. I want that my atmega168 could scan for string and then repeat it. I know how to do it for only character. but i want that i could scan whole string. I have tried a lot things, i cant find anything about it on internet. Please help.  :-\
here is a bit of code:
int main ( void ){
   uart_init();
   
   
   int16_t z;
   
   while(1){
   printf("Enter your string: \r\n");
   scanf("%s",&z);
   printf("You mean %s?\r\n",z);
   }
      
}

Offline joe61

  • Supreme Robot
  • *****
  • Posts: 417
  • Helpful? 16
Re: UART and scanf. Please help.
« Reply #1 on: January 23, 2012, 05:14:41 PM »
There isn't any operating system on the atmega, so there's very little notion of files. It's possible to setup stdio to use a uart or some such, but I've never tried it. See http://www.nongnu.org/avr-libc/user-manual/group__avr__stdio.html" for information about that if you're using gcc or the windows equivalent.

I normally read the string from a uart, then use sscanf () rather than scanf (). Either way, your format string is a little off, you're telling scanf to look for a string rather than a decimal number. Try this instead

Code: [Select]
scanf("%d",&z);
Joe
« Last Edit: January 23, 2012, 05:16:48 PM by joe61 »

Offline AntiLogickTopic starter

  • Jr. Member
  • **
  • Posts: 10
  • Helpful? 0
Re: UART and scanf. Please help.
« Reply #2 on: January 24, 2012, 06:56:01 AM »
It works with numbers :)
But is it possible to do this with words?
thanks.

Offline joe61

  • Supreme Robot
  • *****
  • Posts: 417
  • Helpful? 16
Re: UART and scanf. Please help.
« Reply #3 on: January 24, 2012, 07:40:23 AM »
It works with numbers :)
But is it possible to do this with words?
thanks.

When you use %s in a scanf/printf string, you're telling the function that the next thing on the stack is a pointer to a null terminated array of characters. What it's actually getting is a pointer to an integer. scanf() will start at that address and store incoming characters. When you print it back out again you're just printing the same string that was stored at that address. Sooner or later you're going to overwrite a function, another variable, or something else you don't want to.

So I don't understand what you mean. Could you give me an example of an input string of the type you expect, and what you want to do with it?

Joe
« Last Edit: January 24, 2012, 07:45:53 AM by joe61 »

Offline newInRobotics

  • Supreme Robot
  • *****
  • Posts: 1,015
  • Helpful? 48
  • N.I.R.
Re: UART and scanf. Please help.
« Reply #4 on: January 24, 2012, 07:53:11 AM »
Hi there,

You defined z as 16-bit integer and try to put string into it: scanf("%s",&z);.

I've never done this before, but I know that strings in AVR GCC are char[] (array of chars). So, writing this should do the trick:

Code: [Select]
int main ( void )
{
      unsigned char z[256] ;
   
      while(1)
      {
            printf("Enter your string: \r\n");
            scanf("%s",&z);
            printf("You mean %s?\r\n",z);
      }
}
"Computer games don't affect kids; I mean if Pac-Man affected us as kids, we'd all be running around in darkened rooms, munching magic pills and listening to repetitive electronic music." - Kristian W

Offline joe61

  • Supreme Robot
  • *****
  • Posts: 417
  • Helpful? 16
Re: UART and scanf. Please help.
« Reply #5 on: January 24, 2012, 08:02:52 AM »
Code: [Select]
int main ( void )
{
      unsigned char z[256] ;
   
      while(1)
      {
            printf("Enter your string: \r\n");
            scanf("%s",&z);
            printf("You mean %s?\r\n",z);
      }
}

The format string isn't correct here either. z is now defined as an array of chars but the type of &z is an array of pointers to unsigned char (a pointer to a pointer).

The name of an array decays to a pointer when used as a function argument, so all that's needed is z, ie

Code: [Select]
scanf("%s",z);

Joe

Offline AntiLogickTopic starter

  • Jr. Member
  • **
  • Posts: 10
  • Helpful? 0
Re: UART and scanf. Please help.
« Reply #6 on: January 24, 2012, 08:51:53 AM »
I actually want to scan for string(word) then atmega168 check if this string is for example "hello" then do a command(run timer, printout something, calculate something or etc.) I just want to know ho i could send words to mcu that it would do a job.

Hi there,

You defined z as 16-bit integer and try to put string into it: scanf("%s",&z);.

I've never done this before, but I know that strings in AVR GCC are char[] (array of chars). So, writing this should do the trick:

Code: [Select]
int main ( void )
{
      unsigned char z[256] ;
   
      while(1)
      {
            printf("Enter your string: \r\n");
            scanf("%s",&z);
            printf("You mean %s?\r\n",z);
      }
}
it did  that what i wanted Thanks. Now i just dont know how to test string. for example:
if(string =="hello"){printf("strings match!\r\n");} <- it doesnt work
how i could test strings? thanks for any answer :)

P.S. My c programming skills are lame.

Offline joe61

  • Supreme Robot
  • *****
  • Posts: 417
  • Helpful? 16
Re: UART and scanf. Please help.
« Reply #7 on: January 24, 2012, 09:14:27 AM »
Use strcmp() or (preferably) strncmp() to compare strings.

I suggest you to fix the scanf format string. If it's working now, it's only working by accident.

Code: [Select]
if (strcmp ("hello", string) == 0)
{
    // found "hello"
}
else
{
    // not "hello
}

Offline AntiLogickTopic starter

  • Jr. Member
  • **
  • Posts: 10
  • Helpful? 0
Re: UART and scanf. Please help.
« Reply #8 on: January 24, 2012, 09:49:55 AM »
THANK YOU! its really working. I'm glad i found help here. :)
and now i changed that line scanf("%s",&z); to scanf("%s",z); so i fixed it?

Offline joe61

  • Supreme Robot
  • *****
  • Posts: 417
  • Helpful? 16
Re: UART and scanf. Please help.
« Reply #9 on: January 24, 2012, 10:02:11 AM »
Glad you got it working. You might want to take a look at a tutorial on the library functions for future reference. The link I posted earlier has specifics for the avr-libc version, but any ISO C reference should be fine.

Pointers in C are a common source of problems for programmers just learning the language. They take some getting used to, and being obsessive about them is a good thing :-)

Joe

Offline AntiLogickTopic starter

  • Jr. Member
  • **
  • Posts: 10
  • Helpful? 0
Re: UART and scanf. Please help.
« Reply #10 on: January 24, 2012, 10:13:45 AM »
This website will be useful for me, thanks .Is there any websites where i can learn all the C language for avr. Im really sometimes very confusing about my program, sometimes i just dont know what to write even if i know what i must to do in program.
And by the way I like this forum, you helped me to solve my problem really fast :)

Offline joe61

  • Supreme Robot
  • *****
  • Posts: 417
  • Helpful? 16
Re: UART and scanf. Please help.
« Reply #11 on: January 24, 2012, 10:28:38 AM »
There are some good tutorials on the avrfreaks forum

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewforum&f=11

You can also find a number of tutorials by Googling "c tutorial". And the C FAQ is a good thing to bookmark: http://www.faqs.org/faqs/C-faq/faq/

The AVR C forum at avrfreaks is a good place for avr C related questions:

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewforum&f=2

Joe

Offline AntiLogickTopic starter

  • Jr. Member
  • **
  • Posts: 10
  • Helpful? 0
Re: UART and scanf. Please help.
« Reply #12 on: January 27, 2012, 11:28:38 AM »
Hello again. I decided to don't create other topic, because its about scanf again. :-\
So here is the problem.
int main (void){
uart_init();
timer1_init();
float x = 1.5;
OCR1A = ICR * x/20;
while(1){
            printf("Type number:\r\n");
            scanf("%.1lf", &x);
            OCR1A=ICR1*x/20;
}
}

so i want that i can type number and that way control my servo. When i run it it keeps spamming "Type number:"
it worked me when I made my variable into uint_8. and  scanf("%d",&x); but i want more accuracy.
Pls help if you know how to solve it.
« Last Edit: January 27, 2012, 11:44:52 AM by AntiLogick »

Offline joe61

  • Supreme Robot
  • *****
  • Posts: 417
  • Helpful? 16
Re: UART and scanf. Please help.
« Reply #13 on: January 27, 2012, 12:49:21 PM »
Registers can only hold integer values, so it does you no good to generate floating point values. It also makes your program bigger and slower.

If you're using a 16 bit timer, then the resolution  you have is 16 bits. You simply can't change that.

Of course, you can use a uint16_t instead of a uint8_t.

Joe

Offline AntiLogickTopic starter

  • Jr. Member
  • **
  • Posts: 10
  • Helpful? 0
Re: UART and scanf. Please help.
« Reply #14 on: January 27, 2012, 01:10:24 PM »
I see. I find other way how to control servo by uart.

Offline joe61

  • Supreme Robot
  • *****
  • Posts: 417
  • Helpful? 16
Re: UART and scanf. Please help.
« Reply #15 on: January 27, 2012, 01:23:54 PM »
Just curious, but what are you trying to do that needs more than 16 bit resolution? Servos only have a 1ms range to work with.

Joe

Offline chuckdaball

  • Jr. Member
  • **
  • Posts: 10
  • Helpful? 0
Re: UART and scanf. Please help.
« Reply #16 on: January 27, 2012, 01:36:31 PM »
If you still want to use a floating point number for precision, you can typecast the result, converting it to an int then saving it to the register.  The typecast will round down the floating point to a whole number.

Try the following:
float temp = ICR1 * x / 20.0;
OCR1A = (uint16_t)temp;

Offline joe61

  • Supreme Robot
  • *****
  • Posts: 417
  • Helpful? 16
Re: UART and scanf. Please help.
« Reply #17 on: January 27, 2012, 01:47:59 PM »
Try the following:
float temp = ICR1 * x / 20.0;
OCR1A = (uint16_t)temp;

Which will still leave him with a 16 bit integer. All that will have been accomplished is to bloat and slow down the code with floating point operations, the precision of which are thrown away.

Still curious why more precision is needed. There might be another way to do what he's trying to do that would be better. Maybe use a stepper motor vs servo, etc.

Offline AntiLogickTopic starter

  • Jr. Member
  • **
  • Posts: 10
  • Helpful? 0
Re: UART and scanf. Please help.
« Reply #18 on: January 27, 2012, 02:24:04 PM »
I'v found a method to drive a servo trough uart. Thanks for help.
Now im just learning things, how to do this how to do that and etc  ;D :)

Offline joe61

  • Supreme Robot
  • *****
  • Posts: 417
  • Helpful? 16
Re: UART and scanf. Please help.
« Reply #19 on: January 27, 2012, 02:31:53 PM »
What did you decide on?

Offline AntiLogickTopic starter

  • Jr. Member
  • **
  • Posts: 10
  • Helpful? 0
Re: UART and scanf. Please help.
« Reply #20 on: January 27, 2012, 02:58:20 PM »
my ICR1 = 19999
so i calculated a bit with my calculator what i should do to get one or other duty cycle. I left uint16_t x;
and i tell that OCR1A will be x;
then 19999 * 1.5/20 =~ 1500, 19999*1/20=~1000, and 19999*2/20=~2000.
while(1){
printf("Type number between 1500 and 2000\r\n");
scanf("%d",&x);
OCR1A = x;
printf("OCRA1=%d",x\r\n);
}
thats what i did  ;D took me a while to figure it out. Good feeling when it works how i expected :)

 


Get Your Ad Here