go_away

Author Topic: C version of digitalRead(pin)?  (Read 5151 times)

0 Members and 1 Guest are viewing this topic.

Offline Ro-Bot-XTopic starter

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 1,431
  • Helpful? 25
  • Store: RoBotXDesigns.ca
C version of digitalRead(pin)?
« on: December 30, 2009, 06:41:39 PM »
Hi guys, I'm trying to do something that needs to read fast an input pin and then write that to an output pin, but it seems that it is not going fast enough in Arduino, can someone help me write it using directly registers or what ever works as fast as possible?

Here is the code in Arduino:
Code: [Select]
void loop(){
      boolean a = digitalRead(0);
      digitalWrite(2, a);   
      boolean b = digitalRead(3);
      digitalWrite(1, b);

Check out the uBotino robot controller!

Offline madsci1016

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 1,450
  • Helpful? 43
Re: C version of digitalRead(pin)?
« Reply #1 on: December 30, 2009, 06:50:39 PM »
I had to do something similar when i built my Arduino powered smart motor controller.

This helped me write the code for direct access of i/o register:

http://arduino.cc/en/Reference/PortManipulation

Hope this helps.

Edit:

here's a sample of my code. This reads the state of pin 7:

Code: [Select]
if (PIND & 0b10000000)
The if statement is true if pin 7 is high.
« Last Edit: December 30, 2009, 06:53:56 PM by madsci1016 »

Offline Razor Concepts

  • Supreme Robot
  • *****
  • Posts: 1,856
  • Helpful? 53
Re: C version of digitalRead(pin)?
« Reply #2 on: December 30, 2009, 07:04:24 PM »
I use bit_is_clear and bit_is_set.

clear returns true if the pin is grounded, set returns true if the pin is high.

Code: [Select]
if(bit_is_cleaar(PIND,0))   //if pin D0 is grounded...
{
//pin D0 is grounded!
}

Offline madsci1016

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 1,450
  • Helpful? 43
Re: C version of digitalRead(pin)?
« Reply #3 on: December 30, 2009, 07:09:24 PM »
I use bit_is_clear and bit_is_set.

clear returns true if the pin is grounded, set returns true if the pin is high.

Code: [Select]
if(bit_is_cleaar(PIND,0))   //if pin D0 is grounded...
{
//pin D0 is grounded!
}

If cycles really counted, would bit_is_clear still be a waste of extra cycles to process that function? (or do i not understand what that is?)

My method is the lowest level direct port access( ie least number of cycles required), at least from what i understand.

Offline Ro-Bot-XTopic starter

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 1,431
  • Helpful? 25
  • Store: RoBotXDesigns.ca
Re: C version of digitalRead(pin)?
« Reply #4 on: December 30, 2009, 07:17:14 PM »
OK, so if I write:

Code: [Select]
      if (PIND&0){
        PORTD&2;
      else{
        PORTD||2;
      }

will write 1 on port D2 if pin D0 is 1 and will write 0 on port D2 if pin D0 is 0?
Check out the uBotino robot controller!

Offline madsci1016

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 1,450
  • Helpful? 43
Re: C version of digitalRead(pin)?
« Reply #5 on: December 30, 2009, 07:26:25 PM »
When setting ports, do it like this:

PORTD |= b00000010

this leaves ever other pins where they are and sets the second pin high.

You are confused about the D2 thing. Stick to using binary numbers when doing this, because each binary digit is one pin in the port.

I am still trying to find the right bitwise operator to clear only one bit (pin) in the port and leave the rest, i will get back to you when i find it.

Offline Ro-Bot-XTopic starter

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 1,431
  • Helpful? 25
  • Store: RoBotXDesigns.ca
Re: C version of digitalRead(pin)?
« Reply #6 on: December 30, 2009, 07:35:07 PM »
Is this better?

Code: [Select]
      if (PIND&0){
        PORTD|=B00000100;
      else{
        PORTD|=B00000000;
      }

Thanks for your help!
Check out the uBotino robot controller!

Offline GearMotion

  • Supreme Robot
  • *****
  • Posts: 489
  • Helpful? 24
  • Two decades+ of Embedded Design
Re: C version of digitalRead(pin)?
« Reply #7 on: December 30, 2009, 07:40:59 PM »
I am still trying to find the right bitwise operator to clear only one bit (pin) in the port and leave the rest, i will get back to you when i find it.

Another way is to define these macros:

Code: [Select]

#define BIT_SET(REG, bit)                    ( REG |= (1UL << (bit) ) )

#define BIT_CLR(REG, bit)                    ( REG &= ~(1UL << (bit) ) )

#define BIT_TST(REG, bit, val)              ( ( (REG & (1UL << (bit) ) ) == ( (val) << (bit) ) ) )


And then write your code like this:

Code: [Select]


    if ( BIT_TST( PIND, 0, 1 ) )
        {
        BIT_SET( PORTD, 2);
        }
    else
        {
        BIT_CLR( PORTD, 2);
        }
    

« Last Edit: December 30, 2009, 07:50:53 PM by GearMotion »

Offline rgcustodio

  • Robot Overlord
  • ****
  • Posts: 217
  • Helpful? 0
  • Use "Search" and ye might find answers!
Re: C version of digitalRead(pin)?
« Reply #8 on: December 30, 2009, 07:47:18 PM »
bit_is_clear IMHO is part of AVR libc ... http://www.nongnu.org/avr-libc/user-manual/group__avr__sfr.html


FWIW, the actual number of cycles used up will only be evident in the assembly code generated. Most optimizing C compilers (including gcc) will generate almost the same code for bit_is_clear() macro and the method being used by madsci1016.

Here are the other bitwise operations for everyone's reference.
http://en.wikipedia.org/wiki/Bit_manipulation
The best thing one can do when it's raining is to let it rain. - H. W. Longfellow

understanding is the path to enlightenment

Offline Ro-Bot-XTopic starter

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 1,431
  • Helpful? 25
  • Store: RoBotXDesigns.ca
Re: C version of digitalRead(pin)?
« Reply #9 on: December 30, 2009, 08:00:49 PM »

Another way is to define these macros:

Code: [Select]

#define BIT_SET(REG, bit)                    ( REG |= (1UL << (bit) ) )

#define BIT_CLR(REG, bit)                    ( REG &= ~(1UL << (bit) ) )

#define BIT_TST(REG, bit, val)              ( ( (REG & (1UL << (bit) ) ) == ( (val) << (bit) ) ) )


And then write your code like this:

Code: [Select]


    if ( BIT_TST( PIND, 0, 1 ) )
        {
        BIT_SET( PORTD, 2);
        }
    else
        {
        BIT_CLR( PORTD, 2);
        }
    



IT WORKS! Thank you very much! You made my day!

I mean not only that replaces perfectly the Arduino syntax, but it actually makes the serial bridge between the PC to the VRbot card that is plugged into Arduino, so I don't have to remove it and connect it to a Basic FTDI adapter to set up the new commands. Kudos to GearMotion and madsci1016!
« Last Edit: December 30, 2009, 08:24:14 PM by Ro-Bot-X »
Check out the uBotino robot controller!

Offline GearMotion

  • Supreme Robot
  • *****
  • Posts: 489
  • Helpful? 24
  • Two decades+ of Embedded Design
Re: C version of digitalRead(pin)?
« Reply #10 on: December 30, 2009, 08:33:15 PM »
I'm glad that worked for you. I might have nabbed those exact macros from here or somewhere. I use similar ones in my code.

I keep a notebook in my PIM and so such things are only a cut/paste away.

Offline Razor Concepts

  • Supreme Robot
  • *****
  • Posts: 1,856
  • Helpful? 53
Re: C version of digitalRead(pin)?
« Reply #11 on: December 30, 2009, 08:34:12 PM »
Gearmotion, could you post what little macros you had? Just recently I had to manipulate some ports and it took me quite a bit to dig through my old code and relearn what I used  :P

Offline GearMotion

  • Supreme Robot
  • *****
  • Posts: 489
  • Helpful? 24
  • Two decades+ of Embedded Design
Re: C version of digitalRead(pin)?
« Reply #12 on: December 30, 2009, 08:44:36 PM »
Gearmotion, could you post what little macros you had? Just recently I had to manipulate some ports and it took me quite a bit to dig through my old code and relearn what I used  :P

Well, those above for bit test and setting. Some macros for determining if a character is hex, numeric, etc. Lots of that done instead of linking in a library. Those?

 


Get Your Ad Here