Hi everyone. I'm another newby. I'm trying to write a byte out of arduino decimillia to a D/A converter. Is there any way to write a byte at a time out using 8 digital pins? I'd like to use digital pins 2 thru 9 so that serial in/out isn't interfered with. How about the PORTD command?
I'd like to use digital pins 2 thru 9 so that serial in/out isn't interfered with. How about the PORTD command?
Direct port access via PORT commands can allow you to write up to 8 bits with one command, however PORTD spans only Arduino pins 0-7. Pins 8 & 9 belong to PORTB.
If you really have to write 8 bits with a single command then you would have to consider a Mega board that has more ports available. However many D/A converters have control bits such that you can set up the data input bits in a series of commands and have the converter act on them with a single control pin to latch the data bits and perform the conversion.
There are also serial and I2C D/A converters that allow you to move the data in a bit at a time and then do the conversion. It kind of depends on how fast you need the D/A to be able to operate, that is what is the output frequency bandwidth you are needing?
Thanks Lefty. Actually I'm using an AD558 from Analog Devices. It's for a school project. I'll have to see if it can accept data other than a byte at a time on the data sheet. Speed is not an issue at all. The whole purpose is to get to know the Arduino. Nobody at my school has ever tried to do D/A with it, and even the professor is surprised that there isn't a way to write a byte at a time. Is PORTB an 8 bit port? Do you know which other pins go with PORTB?
If you look at the linked schematic you can trace the Arduino pin numbers at their connector back to the processor chip where which port and pin they belong to can be seen.
If speed is not important for you, there is a way how to output 8 bits to D/A converter - use shift register with output latch . It costs 3 pins : data, clock and latch enable.
Or, if you are ready to use a different converter, select something with I2C input or serial input.
Of course, all 8 bits of one port can be written at once, but on register level.
I have checked a datasheet of the AD558 you are using - it is a paraell 8 bit input with internal latch. I do not see a problem (because speed is not an issue) to use any free 8 pins for data plus one bit for enabling the latch.
Direct port access via PORT commands can allow you to write up to 8 bits with one command, however PORTD spans only Arduino pins 0-7. Pins 8 & 9 belong to PORTB.
So for the fastest access to the 8 bits you want you can write:-
int byteOut;
// do something to set byteOut
PORTD = (byteOut <<2) | (PIND & 0x3);
PORTB = (byteOut >> 6) | (PINB & 0xFC);
What this is doing is shifting the number you want to output to match the pins you are using. Then by using PIN (read a port) you make the bits you want to change zero and leave alone the bits you don't want to change. Finally OR together (|) these two bit patterns and send them to the port.
Sending data to different ports is not a good idea if D/A converter responds immediatelly to an input data. There is a delay between write operation on different ports which leads to wrong voltage on the converter' output (voltage spikes).
Imagine :
old value = 0000 0000
new value = 1111 1111
when written on different ports :
old val : 0000 0000
step 1 : 0000 0011 - this is not what you want
step 2: 1111 1111
I have checked a datasheet of the AD558 you are using - it is a paraell 8 bit input with internal latch.
So if there is a latch, and assuming it is not being run in the transparent mode, this problem doesn't occur. By the way it is called "stuffing" which is the problem of parallel bits not arriving at the same time. That's why D/As normally use a latch.
If it is being used in the transparent mode then this solution would be much better than using individual digitalWrite() commands for each pin as the transitory case would last a much shorter time. The soloution then would be to use a shift register with output latch but that is silly as there is a latch already in the D/A.
This thread started with 8 bits, so I assumed the internal latch of D/A convertor is not used (transparent mode). I agree, it (latch) is the easiest solution for problems with transient state. Shift register with a latch is a solution when there are no enough pins.
Thank you all so much. I appreciate it. I think I'll be using the latches in the AD558. The sample code some of you have provided is especially helpful to a student like me!
@Pepe: The "incorrect" intermediate voltages are going to happen anyway, even with bytewide writes. Physics is involved This would normally be called something like "settling time" in a D-A spec sheet. Writing a bit at a time changes the settling time to be dominated by the D-A to being dominated by the software. IIRC, digitalWrite takes about 5 microseconds (you can make a 100kHz square wave), so writing 8 bits one at a time might cause your D-A output to take 50 microseconds to reach the final correct value. That's pretty awful by hardware standards (a DAC08 settles in 85ns!), but it's pretty fast by human standards, and the original poster did say "speed doesn't matter."
Making the output less spikey was one of the reasons I suggested writing the MSB first, going from 0 to 255 would look like:
Time value
0 0
5 128 (heading in the right direction)
10 192
15 224
20 240 (keeps getting closer)
25 248
30 252
35 254
40 255 (done!)