Arduino not sensing Optocoupler Signal

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h> //Personal Library edited to correct display resolution
#include "rfwLogo" //file to show logo

#define LETTER_ARRAY 12 //Array Size

enum {PASS, FAIL_NOTCONNECTED, FAIL_WRONGCONNECTED, FAIL_SHORTENED };

int buttonPin; //Used for start button if necessary
int buttonState=0; //

char wireArray[LETTER_ARRAY] = {'A','B','C','D','E','F','G','H','J','K','L','M'};
char badWireArray[LETTER_ARRAY];

const byte pinsCableBegin[]= {28,30,32,34,36,38,40,42,44,46,48,50}; //Cable OUTPUT Pins
const byte pinsCableEnd[]  = {29,31,33,35,37,39,41,43,45,47,49,51}; //Cable INPUT Pins
const byte pinsLED[]  = {A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11}; //Red LEDs
//const byte greenLED[] = {2,3,4,5,6,7,8,9,10,11,12,13}; //Green LEDs
const byte NUMCABLES=sizeof(pinsCableBegin); //Stores quantity within array



//*************************************************************************************************
void setup()
{
 display.begin(SSD1306_SWITCHCAPVCC, 0x3D);  // initialize with the I2C addr 0x3D (for the 128x64)
 display.clearDisplay(); //Clear buffer
 
 Serial.begin(9600);
 buttonPin = A15; //Input to Start Program
 pinMode(buttonPin, INPUT_PULLUP); //Enables internal pull-up resistor
 
 if (sizeof(pinsCableBegin)!=sizeof(pinsCableEnd))
 {
 Serial.print("Pin configuration Error.");
 Serial.println("Fix declaration of pinsCableBegin[] and pinsCableEnd[] arrays!");
 while(1); // error stop with endless loop
 }
 
 Serial.println(); //For debugging purposes only
 Serial.println("################################################");
 Serial.println("#                CABLE TESTER                  #");
 Serial.println("################################################");
 Serial.println();
 //--------------------------------------------------------
 //OLED Display Sequence
 rfwOLEDXBM(); //Function from rfwLogo file
 display.display(); //load buffer to be displayed
 delay(2500);
 display.clearDisplay(); //Clear buffer
 isiOLEDXBM(); //Function from rfwLogo file
 display.display();
 delay(1500);
 display.clearDisplay();
 //--------------------------------------------------------

 //RG LEDs as outputs
 pinMode(A0, OUTPUT);
 pinMode(A1, OUTPUT);
 pinMode(A2, OUTPUT);
 pinMode(A3, OUTPUT);
 pinMode(A4, OUTPUT);
 pinMode(A5, OUTPUT);
 pinMode(A6, OUTPUT);
 pinMode(A7, OUTPUT);
 pinMode(A8, OUTPUT);
 pinMode(A9, OUTPUT);
 pinMode(A10, OUTPUT);
 pinMode(A11, OUTPUT);
 
 DoOneTest(); //Initiates Main Test
}

//*************************************************************************************************
//*************************************Main Test***************************************************
//*************************************************************************************************
void DoOneTest()
{
 byte result; //Pass or Fail per wire
 byte k=0;
 
 Serial.println();
 Serial.println("### TEST ###");
 
 testing(); //rfwLogo function to display "Analyzing"
 display.display();
 
 display.clearDisplay();
 for(int i=0;i<10;i++)
 {
 delay(100);
 }
 delay(3000);
 
 for (byte i=0;i<NUMCABLES;i++) //Test each pin 
 {
 result = PASS; // initially there is no error found, assume PASS
 allPinsInputHigh();
 //---------------------------------------------
 // first test is for continuity and OUTPUT/HIGH
 pinMode(pinsCableBegin[i], OUTPUT);
 if (digitalRead(pinsCableEnd[i])!=HIGH)
 {
     badWireArray[k] = wireArray[i];
 ++k;
     //
 digitalWrite(pinsLED[i],HIGH);
 bitSet(result,FAIL_NOTCONNECTED);
 delay(1000);
 }
 //---------------------------------------------
 // then check for continuity and OUTPUT/LOW
     digitalWrite(pinsCableBegin[i], LOW);
     if (digitalRead(pinsCableEnd[i])!=LOW)
     {
 badWireArray[k] = wireArray[i];
 ++k;
 //
 digitalWrite(pinsLED[i],HIGH);
         bitSet(result,FAIL_NOTCONNECTED);
 delay(1000);
     }
   //---------------------------------------------
     // next test: check for wrong connections to other pins
     for (byte j=0;j<NUMCABLES;j++)
     {
       if (j!=i && digitalRead(pinsCableEnd[j])==LOW)
       {
     digitalWrite(pinsLED[i],LOW);
         bitSet(result, FAIL_WRONGCONNECTED);
         delay(1000);
       }  
     }
     //---------------------------------------------
     // final test for short circuit against other pins
     for (byte j=0;j<NUMCABLES;j++)
     {
       if (j!=i && digitalRead(pinsCableBegin[j])==LOW)
       {
 badWireArray[k] = wireArray[i];
 ++k;
 //
 digitalWrite(pinsLED[i],HIGH);
 bitSet(result, FAIL_SHORTENED);
 delay(1000);
       }  
     }
    Serial.print("Line ");
    Serial.print(i+1);
    
    //Writes all outputs Pass or Fail
    if (result== PASS) digitalWrite(pinsLED[i], HIGH); //Serial.print(" PASS");
    if (bitRead(result,FAIL_NOTCONNECTED)) Serial.print(" FAIL BREAK");
    if (bitRead(result,FAIL_WRONGCONNECTED)) Serial.print(" FAIL WRONG");
    //if  (bitRead(result,FAIL_SHORTENED)) Serial.print(" SHORT");
    Serial.println();
  } 
  
 //Final display code for OLED
 if(result==PASS) //Displays when Cable is Good
 {
 
 display.setTextSize(2);
 display.setTextColor(WHITE);
 display.setCursor(3,27);
 display.clearDisplay();
 display.println("GOOD CABLE");
 display.display();
 }
 
 for(byte i=0;i<k;i++) //Displays all Bad wires.
 {
 display.setTextSize(2);
 display.setTextColor(WHITE);
 display.setCursor(10,5);
 display.clearDisplay();
 display.println("BAD WIRES");
 display.setTextSize(2);
 display.setTextColor(WHITE);
 display.setCursor(0,27);
 display.println(badWireArray);
 display.display();
 }
}

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

void allPinsInputHigh() //Set all pins to INPUT_PULLUP in a for-loop
{ 
 for (byte i=0;i<NUMCABLES;i++)
 {
 pinMode(pinsCableBegin[i],INPUT_PULLUP); //enables internal 20k pullup resistors
 pinMode(pinsCableEnd[i],INPUT_PULLUP);
   }
}

void loop() 
{
}

Ok so in the simplest sense, I would like to know if there is a way to delay/shift a signal or have my signal slightly overlap. I recently implemented a optocouplers (PC817) into my project, but I believe my problem now is that my code is running too fast for the arduino to detect the signal after passing through the isolators.

After a simple LED Blink Test with an Oscilloscope I see that the input and output signals are inverted from eachother (input is high when output is low and vice versa).

My code works perfect without the optocouplers because I'm sure that the arduino mega is able to detect the signal quick enough.

Edit it's also worth noting that I would like to stay away from any other hardware implementations.

Edit it's also worth noting that I would like to stay away from any other hardware implementations.

So post a wiring diagram of your hardware setup!

So post a wiring diagram of your hardware setup!

This is just for one IO pair. Essentially it would be reiterated for 'n' number of wires I want to test.

For debugging purposes with an oscilloscope I ran the code below to see what was going on. So I believe my issue is that after the optocoupler implementation, the signal is not being sent quick enough for the arduino to read it in time before checking the next set of IOs

void setup()
{
	pinMode(28,OUTPUT);
}
void loop() 
{
	digitalWrite(28,HIGH);
	delay(500);
	digitalWrite(28,LOW);
	delay(500);
}

That 10k resistor in the line to the LED of the first optocoupler ensures it won't light up properly if at all. Reduce that to something that provides 10-15 mA to that LED. Check data sheet for forward voltage, after that calculation of resistor value is like a regular LED.

wvmarle:
That 10k resistor in the line to the LED of the first optocoupler ensures it won't light up properly if at all. Reduce that to something that provides 10-15 mA to that LED. Check data sheet for forward voltage, after that calculation of resistor value is like a regular LED.

Shoot sorry I was looking at the wrong resistor, that one is actually 220 ohm. There is only one 10k that is next to the second optocoupler sorry about that :smiley:

I guess the speed is not relevant here (BTW, half a second is definitely very slow!) but the input resistor (10k) is to big to get enough current flowing through the LED. Try to replace that by 220Ω resistor. Remove the 1k resistor to GND after the first optocoupler but increase the 50Ω resistor to 150Ω.

I currently don't see a reason for two optocouplers here. Did you forget anything in the diagram that's relevant?

pylon:
I guess the speed is not relevant here (BTW, half a second is definitely very slow!) but the input resistor (10k) is to big to get enough current flowing through the LED. Try to replace that by 220Ω resistor. Remove the 1k resistor to GND after the first optocoupler but increase the 50Ω resistor to 150Ω.

I currently don't see a reason for two optocouplers here. Did you forget anything in the diagram that's relevant?

I have RG LEDs and TS5A3159ADBVR spdt switches in my circuit basically the outcome of if the wire passes or fails will light the LEDs red or green. Without any optocouplers the whole this works fine.

22551480_10209545281619591_1314654925_n.jpg

I'm afraid you have to start explaining again what you're even trying to accomplish here.

I see a series of two optocouplers that do nothing but pull high or low another pin on the same Arduino (some 8-36 µs later due to the delay in the optocouplers), which doesnt' seem to have much if any purpose.

The code in post 1 is too unreadable - you'll have to strip it down to the shortest possible that demonstrates the problem you actually have.

wvmarle:
I'm afraid you have to start explaining again what you're even trying to accomplish here.

I see a series of two optocouplers that do nothing but pull high or low another pin on the same Arduino (some 8-36 µs later due to the delay in the optocouplers), which doesnt' seem to have much if any purpose.

The code in post 1 is too unreadable - you'll have to strip it down to the shortest possible that demonstrates the problem you actually have.

So essentially I would like to get off the arduino board and run it straight from the ATmega2560.

The code in its simplest form is to check if the outputs = inputs (automated cable continuity test). The optocouplers are there for electrical isolation of the cable which will be connected between the optocouplers

dm41nes:
The code in its simplest form is to check if the outputs = inputs (automated cable continuity test). The optocouplers are there for electrical isolation of the cable which will be connected between the optocouplers

The way you have wired it - with the same power supply - there is no electrical isolation between the two. You'll have to get a completely independent power supply for the cable.

Other than that it should just work - as long as you add a delay of at least 40 µs between setting the output and reading the input to allow for the optocouplers to do their thing.

That said, if all you want to do is check continuity, why not power supply + resistor + LED? A microprocessor sounds like total overkill for this.

wvmarle:
The way you have wired it - with the same power supply - there is no electrical isolation between the two. You'll have to get a completely independent power supply for the cable.

Other than that it should just work - as long as you add a delay of at least 40 µs between setting the output and reading the input to allow for the optocouplers to do their thing.

That said, if all you want to do is check continuity, why not power supply + resistor + LED? A microprocessor sounds like total overkill for this.

It is over kill lol, but I have it displayed on an OLED to label open circuits or cross connections. I'm just trying to break it down see why my circuit doesn't work with the optos. Later i'll be using a battery and external cable that is x feet long with n amount of wires (preferably 100ft with 12 wires)

dm41nes:

 // first test is for continuity and OUTPUT/HIGH

pinMode(pinsCableBegin[i], OUTPUT);
if (digitalRead(pinsCableEnd[i])!=HIGH)

Did you already try adding the delay here as I suggested at least twice already? An Arduino is much faster than even one optocoupler and you have two in series.

wvmarle:
Did you already try adding the delay here as I suggested at least twice already? An Arduino is much faster than even one optocoupler and you have two in series.

I think I have before, but I'll check again. I started debugging and found some redundancy that might have me on the path to resolving my issue (or in worst case scenario is having me just sweep it under the rug) :smiley: .