3

I try to build a function generator (preferably a sine) with an R-2R ladder and a Arduino Leonardo by Borderless Electronics.

For performance reasons one should use portd instead of digitalWrite. However the signal is not at all what I want (just noise). So upon further investigation I found that the digital pins were never on HIGH. Pin 6 worked flawlessly. Furthermore I have tested the two failing pins with simple test programms and they behaved exactly as I would have expected.

Here is the code I use

 int sine[255];

 void setup() 
 { 
     pinMode(0, OUTPUT); 
     pinMode(1, OUTPUT); 
     pinMode(2, OUTPUT); 
     pinMode(3, OUTPUT); 
     pinMode(4, OUTPUT); 
     pinMode(5, OUTPUT); 
     pinMode(6, OUTPUT);
     pinMode(7, OUTPUT); 

     float x; 
     float y; 
     for(int i=0;i<255;i++)
     {
          x=(float)i;
          y=sin((x/255)*2*PI);
          sine[i]=int(y*128)+128;
     }
} 

void loop() 
{ 
     for (int i=0;i<255;i++) 
     { 
          PORTD=sine[i]; 
          delayMicroseconds(10); 
     }
}

I tested this with two Arduinos of the exactly same type.

Question: Why are pins 5 and 7 never on HIGH?

Edit: I have simplified everything down to one statement in the loop: portd = x;

I vary x manually

expected findings:

x -> #pin that is on high

0 -> None

1 -> 0

2 -> 1

4 -> 2

8 -> 3

...

128 -> 7

actual findings

x -> #pin that is on high

0 -> None

1 -> 3

2 -> 2

4 -> 0

8 -> 1

16 -> 4

32 -> None

64 -> None

128-> 6

I test this by simply connecting an oscilloscope to the output pins. The behaviour is extremely strange since the pins seem to be in random order, some even missing to portd. Furthermore portd = B11111111, according to the manual, is equivalent to portd = 255; and should set all pins on HIGH. But in my case it sets every pin to HIGH, except pins 5 and 7 are on LOW.

2
  • How are you testing the signal? Can you give examples of the actual and expected output from all pins? Commented May 14, 2014 at 8:26
  • Hi Peter. Thanks for your comment, i edited the question and hope it is more clear now. Commented May 14, 2014 at 8:48

2 Answers 2

4

This is because on ATmega 32u4, which is used in Arduino Leonardo, pins 5 and 7 are not mapped to port D but to port C and E respectively, as you can see in the ATmega 32u4 - Arduino Pin Mapping.

enter image description here

So you will have to:

  • either find another port where all 8 bits are available as digital outputs (note that I'm not sure one such port exists)
  • or split each sine[i] in 2 parts because you will have to work with 2 ports at the same time.
0
2

As @jfpoilpret points out, Arduino pins are not always mapped to port bits in a straightforward manner, and it’s crucial to understand the mapping for your particular model.

In fact, the Arduino Leonardo is designed in a way that none of the ports has all 8 bits usable as I/O pins. As far as the microcontroller is concerned, ports B and D each have all 8 bits available, but the Arduino Leonardo/Micro design uses one bit on each port for a LED.

I would also recommend that if you’re using a PORTx register directly, instead of going through the Arduino API, that you also use the DDRx register to set pin directions, instead of trying to use pinMode.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.