Maker and IoT Ideas
Published © GPL3+

Optically Isolated 8 Digital Input Arduino Shield

Build your own Optically Isolated 8 Digital input Arduino shield, capable of accepting inputs between 3.0v and 32.0v DC

IntermediateFull instructions provided-240 minutes3,259
Optically Isolated 8 Digital Input Arduino Shield

Things used in this project

Software apps and online services

PCBWay Shared Project

Hand tools and fabrication machines

Hot Air Soldering Station

Story

Read more

Schematics

Schematics Page 1

The Schematics in PNG Format

Schematics Page 2

The Schematics in PNG Format

Bill of Materials

The Bill of Materials, in CSV format, EasyEDA export

Code

Code to Test the shield

Arduino
This is a very short sketch to test the basic functionality of the shield. It is worth noting that with the default values for the resistors, as in the schematic, the working range of the device is actually 5.5.v to 32v DC. This is due to the Optic Isolator not being able to switch at such low current levels. The 4k7 and 10k resistor divider should just be adjusted for each channel where you need 3.0 v input. It does however sort of defies the purpose of the device, as it is intended to be used in industrial environments, where the standard input voltage is usually between 12v and 24v DC

As this device is essentially just an i2c io expander with isolated inputs, it can in theory be connected to ANY microcontroller that has an i2c bus, AND that runs on 5v.
#include <Wire.h>

byte _portStatus = 0b00000000;
boolean _readI2C = false;

void MyISR() { // Interrupt service routine
  //Serial.println("Interrupt Occured on Pin2");
  if (_readI2C != true) {
    _readI2C = true;  
  }
}

void setup() {
  // put your setup code here, to run once:
  pinMode(2,INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(2),MyISR,FALLING);
  Serial.begin(115200);
  Wire.begin();
  Wire.beginTransmission(0x20);
  Wire.write(0xFF); // set all pins to 1, needed to make them inputs
  Wire.endTransmission();
}

void loop() {
  // put your main code here, to run repeatedly:
  
  byte _data;
  if (_readI2C == true) {
    _readI2C = false;
    Wire.requestFrom(0x20,1);
    if (Wire.available()) {
      _data = Wire.read();
    }
  }
  if (_portStatus != _data) {
    Serial.print("Port Data Changed : 0xb");
    Serial.print(_portStatus,BIN);
    Serial.print(" changed to : 0xb");
    Serial.println(_data,BIN);
    _portStatus = _data;
    delay(50);
  } else {
    _portStatus = _portStatus;
  }
  
}

Credits

Maker and IoT Ideas

Maker and IoT Ideas

96 projects • 24 followers
I design custom PCB solutions, usually with an IoT or Automation twist, to solve problems in my daily life. Sometimes also for other people.

Comments