Skip to content

Reading Switch Positions with Arduino and Sending the Data out over Ethernet

These are the details of the switch box I constructed for my DCS World project and the Arduino code used. The switches themselves are simple push buttons and SPDT type toggle switches. The box itself is a small storage container from Home Depot.

As you can see, I followed a simple color code within the box to keep things orderly (wires were ordered by wire color and then further separated by shrink-tube color). I used a CAT6 cable with re-terminated ends to carry the multiplexer address signals to the box/ICs as well as carry the input signals from the switches back to the Arduino. The 8 lines within the CAT6 cable allow for 2 lines of +/- power, 3 address lines (common addressing is used with all multiplexers), and 3 remaining lines for reading the output pins of 3 multiplexers. This allows for quick reading of up to 24 switch states with no significant delay. Fancier data bus architectures could allow for time-synchronized sharing of the lines, but I don’t have time to implement that (see what I did there?).

Here is the simple Arduino code I wrote to check the multiplexer+switches functionality:


  int ad0pin = 11;
  int ad1pin = 12;
  int ad2pin = 13;
  int inPin1 = 2;
  int inPin2 = 3;
  int j = 7;

  int switches[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  int swMem[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
 
  int LHs0[] = {LOW, HIGH, LOW, HIGH, LOW, HIGH, LOW,  HIGH};
  int LHs1[] = {LOW, LOW, HIGH, HIGH, LOW, LOW,  HIGH, HIGH};
  int LHs2[] = {LOW, LOW,  LOW,  LOW, HIGH,HIGH, HIGH, HIGH};

void setup() {
  // put your setup code here, to run once:
  pinMode(ad0pin, OUTPUT);
  pinMode(ad1pin, OUTPUT);
  pinMode(ad2pin, OUTPUT);
  pinMode(inPin1, INPUT_PULLUP);
  pinMode(inPin2, INPUT_PULLUP);

  Serial.begin(9600);
  while (!Serial){
    ; // wait for the serial port to connect
  }

  Serial.println("4051 Multiplexer Sketch vB.8");
}

void loop() {
  // put your main code here, to run repeatedly:
  for (byte i=0; i < 8; ++i)
  {
    digitalWrite(ad0pin, LHs0[i]);
    digitalWrite(ad1pin, LHs1[i]);
    digitalWrite(ad2pin, LHs2[i]);
    delay(20);
    switches[i] = digitalRead(inPin1);
    switches[i+8] = digitalRead(inPin2);
    delay(20);
  }

  for(int i = 0; i < 16; i++)
  {
    if(swMem[i] != switches[i]) {
    String SwStat = "switch ";
    SwStat = SwStat + (i+1) + " = " + switches[i];
    Serial.println(SwStat);
    }
    swMem[i] = switches[i];  
  
  }
  //delay(50);

}

Here is the more involved code for sending the multiplexer data out over Ethernet. There is reference to something I call ‘XmitPin’ because I wanted to create feedback from the DCS simulator back to an LED via the same routing; it is not used on the current version of the switch box.

#include <Ethernet.h>
#include <SPI.h>
#include <EthernetUdp.h>

// ad#pin refers to address pins used to set the 8 channel multiplexers
// inPin refers to the read pins from the individual multiplexers
  int ad0pin = 11;
  int ad1pin = 12;
  int ad2pin = 13;
  int inPin1 = 2;
  int inPin2 = 3;
  int XmitPin = 6;

// This sets the current state of the variables for the pins
  int switches[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
  int swMem[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};

// These arrays dictate the order to set each of the address pins of the multiplexers
  int LHs0[] = {LOW, HIGH, LOW, HIGH, LOW, HIGH, LOW, HIGH};
  int LHs1[] = {LOW, LOW, HIGH, HIGH, LOW, LOW, HIGH, HIGH};
  int LHs2[] = {LOW, LOW,LOW,LOW,HIGH,HIGH,HIGH,HIGH};

  char SwStat [5];
  unsigned long time;
  unsigned long oldtime;

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress MyIPAddress(192,168,1,167); // The Arduino
unsigned int localPort = 8090;

IPAddress ServerIP(192,168,1,121); // The computer
unsigned int ServerPort(9000);
EthernetUDP Udp;

char packetBuffer[UDP_TX_PACKET_MAX_SIZE];
char *ptr = NULL;
char *parm = NULL;
char *val = NULL;
int counter = 0;

void setup()
{
    pinMode(ad0pin, OUTPUT);
    pinMode(ad1pin, OUTPUT);
    pinMode(ad2pin, OUTPUT);
    pinMode(XmitPin, OUTPUT);
    pinMode(inPin1, INPUT_PULLUP);
    pinMode(inPin2, INPUT_PULLUP);
    
  Serial.begin(9600);
  while (!Serial){
    ; // wait for the serial port to connect
    time = millis();
    oldtime = millis();
  }
  
  Ethernet.begin(mac, localPort);

  Serial.println("Sketch v3.0");
  Serial.print("Local IP: ");
  Serial.println(Ethernet.localIP());

  Serial.println("Opening port...");

  Udp.begin(localPort);

  Udp.beginPacket(ServerIP,ServerPort);
    Udp.write("Arduino Online");
    Udp.endPacket(); 
}

void loop()
{

  int packetSize = Udp.parsePacket();
  if(packetSize)
  {
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Udp.read(packetBuffer,packetSize); // UDP_TX_PACKET_MAX_SIZE);

    Serial.println("Contents:");
    Serial.println(packetBuffer);

    byte index = 0;
    parm = strtok(packetBuffer,":");
    val = strtok(NULL,":");
    
    Serial.print("Contents: ");
    Serial.println(parm);
    Serial.println(val);    

    if(strcmp(parm,"Xmit")==0)
    Serial.println("Received Xmit");
    {
      if(strcmp(val,"true")==0)
      {
        digitalWrite(XmitPin, 1);
        Serial.println("Radar Xmit");
      }
      else if (strcmp(val,"false")==0)
      {
        digitalWrite(XmitPin, 0);
      }       
      
    }
    
  }
  delay(5);
  
  for (byte i=0; i < 8; ++i)
  {
    digitalWrite(ad0pin, LHs0[i]);
    digitalWrite(ad1pin, LHs1[i]);
    digitalWrite(ad2pin, LHs2[i]);
    delay(5);
    switches[i] = digitalRead(inPin1);
    switches[i+8] = digitalRead(inPin2);
  delay(5);
  }

  String SwStat = String("Sw999,0/");
  char SwStatNew[11];
 
  Udp.beginPacket(ServerIP,ServerPort);
  
  for(int i = 0; i < 8; i++)
    {
      if(swMem[i] != switches[i]) {
        sprintf(SwStatNew,"Sw%03d,%1d/",i+1,switches[i]);
        SwStat = String(SwStatNew);
        Udp.print(SwStat);
        Udp.endPacket();
        swMem[i] = switches[i]; 
      }
    }
     
      //time = millis();
      //float rate = 1000/(time-oldtime);
      //Serial.print("update rate = ");
      //Serial.println(rate);
      //oldtime = time;
       
    for(int i=0;i<UDP_TX_PACKET_MAX_SIZE;i++) packetBuffer[i] = 0;
}