Using pins as input then output (with dip switches attached)?

I'm trying to use a cheaper smaller ATtiny24 rather than eg ATmega48 (approx $1.00 vs $2.50 for >10)

I need 4 digital in (to set the mode), and 8ADC + 4 digital out while running. The ATtiny has 8ADC + 4Dig.

So, can I do something (with diodes and other stuff maybe ??) so that when I press the reset button the sketch first reads the input mode from 4 dip switches attached to 4 digital pins. And then the main loop uses those pins as outputs (and the output state isn't affected by the dip switch positions) ?

thanks.

We need much more information.

Outputs to what ?

The output will be simulating a switch input by taking the level to ground. Will be used as input to eg an old arcade pcb or eg a keyboard encoder such as an i-pac.

https://www.arcadeworlduk.com/categories/Arcade-Parts/Printed-Circuit-Boards/Keyboard-Encoders/

The above schematic is what I use to have a pin be both an input and output.

You need to set pinMode as needed.

1 Like

Typical code:


/*
  Demonstration how to use a pin as a output for a LED 
  and as an input for a switch.

  Note:
  The LED 'must' be connected to +5V through a 470 ohm (or larger) resistor.
  The switch is connected to GND through a 220 ohm resistor.
  
  Version YY/MM/DD
  1.00    16/12/11   Running code
  
*/

//**********************************************************************
//G l o b a l   v a r i a b l e s
//**********************************************************************

const byte heartLED  = 13; //Heart beat LED, toggles on and off showing if there is blocking code
const byte Pin12LED  = 12; //Push ON push OFF, controlled by a switch on pin 6
const byte SwitchLED =  6; //Switch and LED connected this pin, switch pushed = LOW
                           //LED is toggled showing the dual action of this pin

//SRAM variables
byte state = 1;
byte lastSwitchState = 1;

unsigned long Pin13Millis;
unsigned long Pin6Millis;
unsigned long SwitchMillis;


//                         s e t u p ( )
//**********************************************************************
void setup()
{
  //**************************************
  digitalWrite(heartLED, HIGH);  //LOW = ON
  pinMode(heartLED, OUTPUT);

  digitalWrite(Pin12LED, HIGH);  //LOW = ON
  pinMode(Pin12LED, OUTPUT);

  digitalWrite(SwitchLED, HIGH); //LOW = ON
  pinMode(SwitchLED, OUTPUT);    //normal state of this pin

} //  >>>>>>>>>>>>>>>>>> E N D  O F  s e t u p ( ) <<<<<<<<<<<<<<<<<<<<<


//                             l o o p ( )
//**********************************************************************
void loop()
{
  //***************************
  //HeartBeat LED
  if (millis() - Pin13Millis >= 100UL)
  {
    Pin13Millis = millis();
    //Toggle heartLED
    digitalWrite(heartLED, !digitalRead(heartLED));
  }

  //***************************
  if (millis() - Pin6Millis >= 500ul)
  {
    Pin6Millis = millis();
    //Toggle the LED on the SwitchLED pin
    digitalWrite(SwitchLED, !state);
    state = !state;
  }


  //***************************

  //None blocking code goes here

  //***************************
  //time to check the Switch(s)?
  if (millis() - SwitchMillis >= 50ul)
  {
    SwitchMillis = millis();
    handleSwitchPresses();
  }

} //  >>>>>>>>>>>>>>>>>>> E N D  O F  l o o p ( ) <<<<<<<<<<<<<<<<<<<<<<


//======================================================================
//                         F U N C T I O N S
//======================================================================

//                h a n d l e S w i t c h P r e s s e s( )
//**********************************************************************

void handleSwitchPresses()
{
  //**** R e a d i n g   t h e  s w i t c h   s h a r e d   w i t h   L E D ****
  //Reading the switch takes ~14us
  //save the condition of the output pin
  byte PinState = digitalRead(SwitchLED);
  //read the switch connected to this pin
  pinMode(SwitchLED, INPUT_PULLUP);
  byte switchPosition = digitalRead(SwitchLED);

  //return the pin to OUTPUT
  pinMode(SwitchLED, OUTPUT);
  //restore the pin state
  digitalWrite(SwitchLED, PinState);
  //**** R e a d i n g  t h e  s w i t c h   s h a r e d   w i t h   L E D ****

  //has the SwitchLED changed state?
  if (switchPosition != lastSwitchState)
  {
    lastSwitchState = switchPosition;

    if (switchPosition == LOW) //do LOW stuff
    {
      //toggle Pin12LED
      digitalWrite(Pin12LED, !digitalRead(Pin12LED));
    }

    else                       //do HIGH stuff
    {
    }

  } //END of SwitchLED changed state


  //Other Switches

} //      E n d   o f   h a n d l e S w i t c h P r e s s e s ( )

//**********************************************************************


//======================================================================
//                        E N D  O F  C O D E
//======================================================================

I've been looking at that circuit for a while. Is it telling me the following:

When the pins are set to OUTPUT LOW, the voltages are all LOW (.13V to .56V) regardless of the mechanical switch position.

And then I guess, when set to OUTPUT HIGH they would all be approx 5V.

And when set to INPUT, they read HIGH or LOW depending on the switch position.

If that's right, then my next questions are: Is the diode needed or just for show? What's a good value for my R1 to R4 ?

I suppose I can breadboard this with 2 arduinos to test it out (or could I even use the same one?)

thanks

LED diodes are just indicators.


The schematic is an actual project that works.


This shows a PCB with the switches and LEDs as in the schematic.


For a simple LED/switch project, what has been shown works fine.


Scope timing of a switch read then back to pin toggling.

2016-12-05_11-58-42

The LEDs represent the devices you need to control. Note that they can only be loads connected to the supply or a high impedance as they must not pull down against INPUT_PULLUP.

Similarly the protective resistors in series with the DIP switches must be substantially less (at very minimum, half the value) than the LED resistors because the DIP switches must be able to pull the load sufficiently LOW to be correctly read. OTOH, their minimum value of 240 Ohms is chosen so that the pin when set to output HIGH is not overloaded.

Thus the value of 240 Ohms (I would say 330) for the switch resistors and 1k2 for the LED resistors.

Like this ?

You must remember there is a short interval when the pin is an input and a much longer period when the pin is an output.
This should be taken into consideration in your project.

To repeat, here is a read when the pin is at output LOW and the switch was open/HIGH during the read time, hence the short positive pulse.
2016-12-05_11-58-42

If the pin was at output HIGH and the switch was closed, you would see an inverted image of what’s seen above.

Since you read your switches at reset, setup( ), time, things should be fine if you follow the offered code and wiring.

Well, I said

Now another Arduino - or similar, or a CMOS logic gate - is (or should be) a high impedance. You do not need a pull-up as to read the DIP switch, INPUT_PULLUP will generally pull up quite well and when the pin becomes an OUTPUT, its state will be strictly controlled as HIGH or LOW.

If however there was a long cable between the two, you may want a stronger pull-up than INPUT_PULLUP provides in order to account for leakage and interference pickup in the wiring.

I think you are saying I don't need the 1k2 ? Which I can see now as it's a pull-up and we've already got that internally.

You have it within you try do a dry run to see if things work.
:wink:

I could, but there are many other strands needing my attention at the same time. eg I don't know if I can get custom PCBs with ATTINYx4 on them. JLCPCB says no stock even though their parts supplier has them. More stuff I don't understand!