Society of Robots - Robot Forum
Software => Software => Topic started by: Ro-Bot-X 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:
void loop(){
boolean a = digitalRead(0);
digitalWrite(2, a);
boolean b = digitalRead(3);
digitalWrite(1, b);
}
-
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 (http://arduino.cc/en/Reference/PortManipulation)
Hope this helps.
Edit:
here's a sample of my code. This reads the state of pin 7:
if (PIND & 0b10000000)
The if statement is true if pin 7 is high.
-
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.
if(bit_is_cleaar(PIND,0)) //if pin D0 is grounded...
{
//pin D0 is grounded!
}
-
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.
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.
-
OK, so if I write:
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?
-
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.
-
Is this better?
if (PIND&0){
PORTD|=B00000100;
else{
PORTD|=B00000000;
}
Thanks for your help!
-
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:
#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:
if ( BIT_TST( PIND, 0, 1 ) )
{
BIT_SET( PORTD, 2);
}
else
{
BIT_CLR( PORTD, 2);
}
-
bit_is_clear IMHO is part of AVR libc ... http://www.nongnu.org/avr-libc/user-manual/group__avr__sfr.html (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 (http://en.wikipedia.org/wiki/Bit_manipulation)
-
Another way is to define these macros:
#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:
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!
-
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.
-
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
-
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?