Ports (Newbie Question)


as a newbie with GrovePI I miss a little documentation about the port usage.

Looking at your python code there is no difference between setting a digital port (p.E. D2) to output and setting an analog port (p.E. A2) to output.

Does this mean that I can only use Port A1 OR Port D1 at the same time (maybe they share pins?),
or does this mean that when I switch an anlogue port to output, the digital port with same number is also set to output?

Is this also valid for I2c ports, or are they handled different?

On your site you mention a PDF file of the schematics, but I found only the design files on github, but no PDF …

best regards

Hey Stephan,
If you use analog read/write on analog ports 0-3, you would only be able to read/write the Analog ports. You cannot use analog read/write on digital ports.

If you do digital read/write on digital ports, you are setting them on the digital ports and not the analog ports. Analog port A0 corresponds to digital pin 14, A1 to 15 and so on. So to use the analog ports as digital, the numbering starts from 14 onward.

I2C is handled a bit differently, you can connect any I2C sensor to any I2C port. All the I2C ports are connected together but each sensor has a different address which is set at teh factory. So if you have multiple I2C sensors, you can connect them to different ports and communicate with them with their own I2C addresses.

Looks like we forgot to upload the PDF of the schematics. We’ll upload them asap.


sorry, it is still not clear to me with the ports …

from your python script for digital Port 3

button = 3

you set pinmode to input for Port 3 and do a digital read afterwards

here is a analog script

loudness_sensor = 0

you set pinmode to input for Port 0, and do a analog read afterwards

you use the same routine with the same pin number range,
but one time you adress digital port the second time the analog port …

Thanks for pointing that out. The pinMode setting is actually a big that looks like it creeped into the codebase. The pinMode() sets the pin state for only the digital pin, so it’s not doing much there. Sorry for the confusion. We’ll get this corrected ASAP.


It took me a while to get my head around this one.
I’ll try to explain it as best I can.

The GrovePi runs an ATmega328 which contains an onboard 6 channel analog-to-digital (A/D) converter.
The AD converter has 10-bit resolution, returning values 0-1023.
Analog pins are usually used for reading analog sensors but can also be used for general purpose i/o, same as digital pins 0-13.
If you need more digital sockets, you can repurpose an analog socket.

The pinMode() method is used to set the pin to INPUT or OUTPUT.

analogRead(2) and digitalRead(2) will read from different GrovePi sockets.

grovepi.analogRead(2) will read from the socket labelled A2.
grovepi.digitalRead(2) will read from the socket labelled D2.

On an Arduino Uno (same ATmega328 chip) the digital pins are marked as D0-D13 and analog pins A0-A5.
The analog pins are actually aliases for digital channels.

A0 = D14
A1 = D15
A2 = D16
A3 = D17
A4 = D18
A5 = D19

In an Arduino sketch, analogRead(A0) is the same as analogRead(14).
You can call grovepi.analogRead(0) or grovepi.analogRead(14) and you will get the same result.

GrovePi sockets A0,A1,A2 use the AD converter and support analogRead() values 0-1023.

GrovePi sockets D2-D8 are digital and support 1-bit input/output, values 0-1, using digitalRead() and digitalWrite().

GrovePi sockets D3,D5,D6 also support Pulse Width Modulation (PWM) which means you can write 8-bit values 0-255 with analogWrite().

Sadly you can’t use analogRead() with D3,D5,D6, only with A0,A1,A2 (aka D14,D15,D16).

grovepi.analogRead() uses the above aliases so if you are trying to read a value from an analog sensor connected to D3 analogRead(3) will actually read from the 2nd pin on the A2 socket.
If you analogRead(pin) where pin is 0-5, it automagically adds 14 to the pin number to read the correct digital channel, where the AD converter exists.
So analogRead(2) will only read from socket A2, never socket D2.
And digitalRead(2) will only read from socket D2, never socket A2.

Why does the GrovePi not have any A3, A4 or A5 sockets?
Because I2C.
Channel A4 is used for SDA (serial data line) and channel A5 for SCL (serial clock line).

Ok, so why was an A3 socket not added to the board?
Socket A2’s 2nd pin is A3 and an A3 Socket’s second pin would be A4.
You can analogRead() A3 if you have a 4 wire analog sensor, such as some of the analog accelerometers.
A4 is common with the I2C pins and would probably confuse people.
Cost may have also been a factor.

Why is there no D0 and D1 sockets on the GrovePi?
Serial bro.
On the ATmega328, D0 is for RX (receive) and D1 is for TX (transmit)


grovepi.analogRead(0) - socket A0, read 0-1023
grovepi.analogRead(1) - socket A1, read 0-1023
grovepi.analogRead(2) - socket A2, read 0-1023
grovepi.analogRead(14) - socket A0, read 0-1023
grovepi.analogRead(15) - socket A1, read 0-1023
grovepi.analogRead(16) - socket A2, read 0-1023
grovepi.analogWrite(3,val) - socket D3, write PWM 0-255
grovepi.analogWrite(5,val) - socket D5, write PWM 0-255
grovepi.analogWrite(6,val) - socket D6, write PWM 0-255
grovepi.digitalRead(2) - socket D2, read 0-1
grovepi.digitalRead(3) - socket D3, read 0-1
grovepi.digitalRead(4) - socket D4, read 0-1
grovepi.digitalRead(5) - socket D5, read 0-1
grovepi.digitalRead(6) - socket D6, read 0-1
grovepi.digitalRead(7) - socket D7, read 0-1
grovepi.digitalRead(8) - socket D8, read 0-1
grovepi.digitalRead(14) - socket A0, read 0-1
grovepi.digitalRead(15) - socket A1, read 0-1
grovepi.digitalRead(16) - socket A2, read 0-1
grovepi.digitalWrite(2,val) - socket D2, write 0-1
grovepi.digitalWrite(3,val) - socket D3, write 0-1
grovepi.digitalWrite(4,val) - socket D4, write 0-1
grovepi.digitalWrite(5,val) - socket D5, write 0-1
grovepi.digitalWrite(6,val) - socket D6, write 0-1
grovepi.digitalWrite(7,val) - socket D7, write 0-1
grovepi.digitalWrite(8,val) - socket D8, write 0-1
grovepi.digitalWrite(14,val) - socket A0, write 0-1
grovepi.digitalWrite(15,val) - socket A1, write 0-1
grovepi.digitalWrite(16,val) - socket A2, write 0-1

Further reading:

Whoa mike,
Thanks again for one of your stellar posts. I was lazying around, not feeling to write a long post. So, thanks a lot.
You are awesome,

thank you for this great post !
it gives a lot of background information for somebody with no arduino background.