About Port Manipulation

Hi helpful people,

I am making a 16-bit decimal to binary converter with 8 leds using port manipulation. User enters the
decimal then program converts it to binary then writes the leds. But I have a problem with port manipulation. I keep binary number as a type of String so I can't write number to pins. Code like this;

void setup() {
DDRC = B11111111;

void loop() {
// put your main code here, to run repeatedly:
long input = Serial.parseInt();

if (input>=2){
y = input/2;
while (y>0){
r = input % 2;
out = String(r) + out;
y = input/2;
input = y ;
out = String(input);
int digits = out.length();

for(int i=0; i<(16-digits); i++){
out = "0" + out;
String firstEight = "B" + out.substring(0,8);
String lastEight = "B" + out.substring(8,16);

Then I write end of this code;

PORTC = firstEight;

and I get this error message : cannot convert 'String' to 'volatile uint8_t {aka volatile unsigned char}' in assignment
Sorry if this is actually common knowledge, but I couldn't find it.
Thanks for your help


Hello and welcome,

Why use String? You want numbers so use numbers.

long input = Serial.parseInt();

PORTC = input & 0xFF; // first 8 bits
PORTX = (input >> 8) & 0xFF; // next 8 bits

Most here would recommend you not use String as there are problems with using it.

I make it a habit of not looking at sketches that are not commented.

Thanks for your answers quix and LarryD.
Actually this is my homework so i have to convert decimal to binary using my own code. That is why i used the String. It keeps the bits of binary number.

Modifying your original post makes no sense at at all.

Here is a similar function that converts Decimal to Seven-Segment. To do discrete LEDs, just replace the PortB values. e.g.:

case 2: PORTB = 0b00000010; break; // Segments for "2"

  // ****FUNCTION******* SevenSeg ********************************
//  Code to drive 7-segment display, process one digit at a time
void SevenSeg(int TDisplay)
  { switch (TDisplay)
  {//                          gfedcba.   segments to light
  case 0:   PORTB = 0b01111110;  break; // Segments for "0"
  case 1:   PORTB = 0b00001100;  break; // Segments for "1"
  case 2:   PORTB = 0b10110110;  break; // Segments for "2"
  case 3:   PORTB = 0b10011110;  break; // Segments for "3"
  case 4:   PORTB = 0b11001100;  break; // Segments for "4"
  case 5:   PORTB = 0b11011010;  break; // Segments for "5"
  case 6:   PORTB = 0b11111010;  break; // Segments for "6"
  case 7:   PORTB = 0b00001110;  break; // Segments for "7"
  case 8:   PORTB = 0b11111110;  break; // Segments for "8"
  case 9:   PORTB = 0b11011110;  break; // Segments for "9"
}// End FUNCTION SevenSeg ---------------------------

Quick different example, as this is your homework.

You don't want to use port manipulation, as that automatically
does the conversion. (Output decimal to port, you see binary.)

I doubt, if I understand the assignment correctly, that the
educator would accept you using such a method, unless it's
only breaking the 2 byte integer into it's low and high byte,
in which case I see no purpose to the assignment. I mean you
have way more code than that would require, right?

So, as an example only, say you set the following variables.
(I'm NOT giving full real code, as that would be cheating.)

Integer PortBase // Set this to the lowest Bit pin number.
(The above assumes bit 0 is the lowest pin and 7 the highest.)
(If the pin numbers are reversed, remember to take that into
account. Use Highest Pin # and Subtract ( 7 - I ) as below.)

Do your input whatever way into a Long Integer "Input".

Use the "Old Way" from Boolean algebra. Here Goes.
(Note: I am a "C" noob. This is a translate from assembly
code to "C" so it may not be optimal, but demonstrates OK.)

for (int I=7; I>=0; I--) { // Setup the bit loop
if ((Input - (2 Pwr I)) >= 0) { // Decode to Binary

// (By Pwr - I Mean exponent - 2 to the power of I)
// (Remember, example, not finished code)
// (Suggest left shift rather than "call" pwr function.)
// (Right shift from max to calc on the fly, etc.)
// Now do these bits individually

digitalWrite (I + Portbase, HIGH); // Binary 1
Input -= (2 Pwr I); // Decrease Input
(Save bit to array here, If Req'd)

// The decrement removes the bit from the value
// so you can just continue on to the next one.
else {
DigitalWrite (I + Portbase, LOW); // Binary 0
(Save bit to array here, If Req'd)
} // This is the end of the "For" loop - All Done

Finally, for 16 bit conversion, start I at 15, break decode
as desired. If port numbers are reverse order, use the
Portbase - ( 7 - I ) or ( 15 - I ) as needed to get the
correct pin number on the port. I really can't write
more without actually doing most of the assignment.

Of course, the loop may be broken into 2 half processes, so
you could display the first half, wait for any serial input,
then display the second half, but that part is up to you.

This was a common method in old days but I have no idea
if this helps as displaying 16 bits with 8 leds has already
got me slightly confused. As MY instructors would have said,
"It's cheating to let the compiler do the work." With this
method, you make no "calls" and store the bits directly in
the port, bit by bit, so no save is really req'd. If it IS
required, you can store the bits in a boolean array, etc.
Also, You have done all the work, not the compiler and it
clearly does a decimal to binary conversion, even though, in
reality, the parseint function already did one. (You didn't
think the CPU ever stored in decimal, did you?) If the real
object is to convert the string input to a decimal value, and
then convert to binary, follow standard build methods, count
the chars, add (Char Value - 48) * 10 Pwr (Char Position)
where Char position is Max - 0, loop through all, you already
know all this part and I'm just rambling now.

I hope this is of use to you. Thanks for reading.

The only purpose of the assignment is converting decimal to binary(with your own code) and writing the leds. I have already did converting part, I had a problem with writing part but I changed something on my code and I solve the problem. Actually your answer helped me Arthur_Clark. Thanks for your answer.