i'm working on a laser timer using arduino and i saw that using direct port manipulation can have a really better time precision. My only concern is about serial communication, because i am using some pins for a software serial, and i don't know how to set them in the ports register. The pins are the 4 and 5, and the number 3 is the trigger output, unluckily this pinset cannot change. How should i set them in the DDRD? I'm using an Arduino Nano board
1 Answer
You can modify a single or multiple bits in a register by using a Read-Modify-Write approach. Essentially something like this:
byte temp = DDRD;
temp = (temp & ~(bitmask)) | bits_to_set;
DDRD = temp;
In the above code, bitmask
is some value with the bit or bits you want to modify set - e.g. if you want to change bits 4 and 5, it would be (_BV(4) | _BV(5))
or just (0b00110000)
. bits_to_set
is a value with all bits that you want to be one set - e.g. if you want bit 5 to be a 1, it would be (_BV(5))
or (0b00100000)
.
What the code does is to first get the current value of the register you want to manipulate. Then it will clear only the bits which you want to modify to 0 by using bitwise AND on the temp value. Next it will set only the bits you want to change to be set by using a bitwise OR. Finally it writes it back to the register.
If you are using interrupts which, you may wish to do this atomically (so that the register is not changed by an interrupt occurring before the new value is written back). You can do this by wrapping the above code in:
byte oldSREG = SREG;
cli();
...
SREG = oldSREG;
Which will clear the global interrupt flag to pause any interrupts, and then will restore the value of it afterwards.
If you just want to change a single bit in a register you can optimise this code down to one of the following examples:
DDRD |= _BV(4); //Set bit 4
DDRD &= ~_BV(5); //Clear bit 5
Again you may want to do this atomically as it may compile to a Read-Modify-Write access.
SoftwareSerial
object different from the defaultSerial
, take a look to the "Arduino - Software Serial Example". A possible setting could beSoftwareSerial mySerial(4, 5); // RX=4, TX=5
.