Can you turn on pull up resistors using port manipulation?

I've looked around and haven't seen a way to use port manipulation that includes setting the internal pull up resistors.

Some background: I've a 4 bit grey code foot pedal switch from a Pfaff industrial sewing machine. The sewing machine is no toy at 1/2 hp, 240v, using pneumatic operators for things like the presser foot its a beast. I've already saved some big bucks by doing my own sailboat canvas and sail projects. Unfortunately the logic board went poof with replacement/repair of the custom EFKA control system beyond what i'm willing to pay. As an industrial electrician with say "intermediate" level Arduino experience i've made a working replacement system (quick pat on the back).

Seems like i've used a lot of code just for the foot pedal. i use the following ( just the relevant stuff ):

#define A 14 //from pedal A0
#define B 15 //from pedal A1
#define C 16 //from pedal A2
#define D 17 //from pedal A3

void setup()
{
//Setup inputs
pinMode(A, INPUT_PULLUP);
pinMode(B, INPUT_PULLUP);
pinMode(C, INPUT_PULLUP);
pinMode(D, INPUT_PULLUP);
}

void get_pedal(){
Adat= digitalRead (A);//these are like individual bits from 4 bit gray encoder
Bdat= digitalRead (B);
Cdat= digitalRead (C);
Ddat= digitalRead (D);
Pdat = (Adat)+(Bdat2)+(Cdat4)+(Ddat* 8 ) ; //create a unique value for each pedal position (gray code)
}
and it works OK

My thought was to use the DDRC ( appropriately masked of course) to set all four inputs at the same time and read all four using "PINC". The physical set up of the switch however is switched low (see attachment) requiring my inputs to have a pull up resistor. Just can't see how you set them on with port manipulation, if it can be done at all. Its not really a problem, i could just add external pull ups or keep things the way they are. It might be interesting to others to find out if this can be done.

Screen shot 2014-12-16 at 5.20.25 PM.png

Why would you bother even assuming that it is possible ?

Turning on the internal pullup resistors happens once in setup(). Do you really need to do it faster than using pinMode() ?

If you really must do it then presumably you could use port manipulation to do the equivalent of

pinMode(pin, INPUT);           // set pin to input
digitalWrite(pin, HIGH);       // turn on pullup resistors

Write the DDRn to set your pins to input and then PORTn to set them high. INPUT_PULLUP.

Of course you can! What else do you think pinMode etc do?

Mark

Pins 14 through 17 are all on port C so this should do it (untested)...

void setup( void )
{
  // Configure the pins for input
  DDRC = DDRC &
      ~ (
        (1 << DDC0) |  // pinMode( 14, INPUT ); // Set to input
        (1 << DDC1) |  // pinMode( 15, INPUT ); // Set to input
        (1 << DDC2) |  // pinMode( 16, INPUT ); // Set to input
        (1 << DDC3)    // pinMode( 17, INPUT ); // Set to input
      );

  // Enable the pullups
  PORTC = PORTC |
      (
        (1 << PORTC0) |  // digitalWrite( 14, HIGH ); // Enable the pullup
        (1 << PORTC1) |  // digitalWrite( 15, HIGH ); // Enable the pullup
        (1 << PORTC2) |  // digitalWrite( 16, HIGH ); // Enable the pullup
        (1 << PORTC3)    // digitalWrite( 17, HIGH ); // Enable the pullup
      );

  // Read all four inputs
  uint8_t Pdat = PINC & ( (1 << PINC0) | (1 << PINC1) | (1 << PINC2) | (1 << PINC3) );
}

void loop( void )
{
}

You can have all those precompiled as globals if you don't want to spend cycles at runtime.

just as untested

byte ddrcMask =       ~ 
(
        (1 << DDC0) |  // pinMode( 14, INPUT ); // Set to input
        (1 << DDC1) |  // pinMode( 15, INPUT ); // Set to input
        (1 << DDC2) |  // pinMode( 16, INPUT ); // Set to input
        (1 << DDC3)    // pinMode( 17, INPUT ); // Set to input
);


byte portcMask =
(
        (1 << PORTC0) |  // digitalWrite( 14, HIGH ); // Enable the pullup
        (1 << PORTC1) |  // digitalWrite( 15, HIGH ); // Enable the pullup
        (1 << PORTC2) |  // digitalWrite( 16, HIGH ); // Enable the pullup
        (1 << PORTC3)    // digitalWrite( 17, HIGH ); // Enable the pullup
);

byte pincMask = ( (1 << PINC0) | (1 << PINC1) | (1 << PINC2) | (1 << PINC3) );


void setup( void )
{
  // Configure the pins for input
  DDRC = DDRC & ddrcMask;

  // Enable the pullups
  PORTC = PORTC | portcMask;

  // Read all four inputs
  uint8_t Pdat = PINC & pincMask;
}

void loop( void )
{
}

The UNO has 3 ports with 6 pins open. A stand-alone 328P @ 8 MHz has 1 port with 8 pins open.

If you go to a Mega2560 or 1284P chip you have a few 8-bit ports to choose from.

GoForSmoke:
You can have all those precompiled as globals if you don't want to spend cycles at runtime.

Just as Luke benefitted from trusting The Force so shall you benefit from trusting The Compiler. (All compile-time constants are folded.)

Thank you all. Makes perfect sense.

To answer UKHeliBob: I should have asked "How do you turn on pull up resistors using port manipulation?". My apologies. Speed is not my issue. It was just a chance to learn more about port manipulation by applying it to my project. I normally find answers to such questions by searching this forum. When nothing seemed to come up, I felt others may gain from your answers. Thank you again.

Regards

If you go to the Atmel site and get the full doc on the chip family you're using, you can see where and how it all comes together piece by piece (I can't deal with it all at once, still working on the 328P for 3 or 4 years now) as you have time and need. There is a lot for something so inexpensive but it's all on a simpler level than the libraries and code make it seem.

There's a port manipulation trick that lets you toggle a pin LOW/HIGH without checking. Write a 1 to that pin in the PINxn register (that you normally read pin state from) and it will flip the state in one operation, without if-else, and/or coding, just PINx = bitmask and bang, the pin states flip.

Thanks GoForSmoke.
Your solution works perfect. I'm with you regarding the bang for the buck in modern devices. I worked with 6502 processors in the 80's using only machine code. Not a time i want to go back to. The Arduino IDE is so much fun its inspired several fun projects for me. Truth is though without the contributions of people like yourself things would be a lot more challenging. Thanks for the tip on the AVR docs. I'll look them up and see what I can see.

Regards

Just to finish off. Using port manipulation the code that i started with can be reduced to :

const byte Mask = 15;
uint8_t Pdat;
void setup( )
{
// Configure the pins for input
DDRC = DDRC & Mask;

// Enable the pullups
PORTC = PORTC | Mask;

void loop( )
{
// Read all four inputs
Pdat = PINC & Mask;
}

The draw back is that this is only applicable to this application using this processor. Not the way we want modern portable code to be. It was just fun to see how concise it could be made. Reminds me of the days when we only had 1K byte of memory to work with.

Regards

Reminds me of the days when we only had 1K byte of memory to work with.

1K ? Luxury !
The first computer that I built had 256 bytes of RAM and was programmed in machine code.
Science of Cambridge MK14

1 Like

UKHeliBob are you from the old intel 8080 days?

Intel 8080 ? Luxury !
No, I never used one.

macgregor_sailor:
Thank you all. Makes perfect sense.

To answer UKHeliBob: I should have asked "How do you turn on pull up resistors using port manipulation?". My apologies. Speed is not my issue. It was just a chance to learn more about port manipulation by applying it to my project. I normally find answers to such questions by searching this forum. When nothing seemed to come up, I felt others may gain from your answers. Thank you again.

Regards

Remember you can look at the source code for pinMode...