Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 8 of 8

Thread: High Speed Timer - DigitalRead problems

  1. #1
    Junior Member
    Join Date
    Dec 2014
    Posts
    9

    High Speed Timer - DigitalRead problems

    I have two related problems with my optically isolated inputs and the associated digital reads on the TEENSY 3.1.

    The primary problem is that the DigitalRead is not consistent in reading the status of the optically isolated input (pins 14 through to 21). As it goes through the FOR loop monitoring status, sometimes the status is read and sometimes not. For example pins 16 and 17 are pretty consistent, but 14 and especially 15 are not. Note that this was tested with the TEENSY plugged into a VMWare Windows 8.1 computer running on Mac Yosemite via a USB cable.

    The secondary problem is that when the TEENSY is plugged directly into a USB power supply, all of the inputs status are not read. They remain high even through there is an optically isolated input (and the LED comes on). Note as well that I have tried both INPUT and INPUT_PULLUP with no impact.

    Thanks, Rudy



    // set this to the hardware serial port you wish to use
    #define LCD Serial1

    // Teensy 2.0 has the LED on pin 11
    // Teensy++ 2.0 has the LED on pin 6
    // Teensy 3.x has the LED on pin 13
    const int LEDPOWER = 13;

    // Definte Input Pins
    const int INPUTRESET = 3;
    const int INPUTSTART = 4;
    const int INPUT0 = 14;
    const int INPUT1 = 15;
    const int INPUT2 = 16;
    const int INPUT3 = 17;
    const int INPUT4 = 18;
    const int INPUT5 = 19;
    const int INPUT6 = 20;
    const int INPUT7 = 21;
    const int VERSIONMAJOR = 1;
    const int VERSIONMINOR = 1;

    // Clear the LCD Display
    void clearLCD(){
    LCD.write(254);
    LCD.write(88);
    }

    // Set Cursor Position on LCD Display
    void setCursorLCD(){
    LCD.write(254);
    LCD.write(121);
    LCD.write(0);
    LCD.write(40);
    }

    void setup() {
    // Set up inputs and outputs
    pinMode(LEDPOWER, OUTPUT);
    pinMode(INPUTSTART, INPUT_PULLUP);
    pinMode(INPUTRESET, INPUT_PULLUP);
    pinMode(INPUT0, INPUT);
    pinMode(INPUT1, INPUT);
    pinMode(INPUT2, INPUT);
    pinMode(INPUT3, INPUT);
    pinMode(INPUT4, INPUT);
    pinMode(INPUT5, INPUT);
    pinMode(INPUT6, INPUT);
    pinMode(INPUT7, INPUT);
    }

    void loop() {
    int inputInitial[8];
    int inputFinal[8];
    unsigned long inputTime[8];
    unsigned long timeTemp;
    unsigned long timeInitial;
    int i = 0;
    int j;
    delay(100);

    // Turn on LED on CPU
    digitalWrite(LEDPOWER, HIGH);

    // Display Startup Message
    LCD.begin(19200);
    delay(100);
    clearLCD();

    LCD.print("R Engineering Inc.\n");
    LCD.print("High Speed 8 Channel Timer\n");
    LCD.print("Version ");
    LCD.print(VERSIONMAJOR, DEC );
    LCD.print(".");
    LCD.println(VERSIONMINOR, DEC );

    while(digitalRead(INPUTSTART) == HIGH) delay(50);
    LCD.print("Waiting to arm for testing...");

    while(digitalRead(INPUTSTART) == LOW) {
    setCursorLCD();
    switch(i) {
    case 0:
    LCD.print("- ");
    break;
    case 1:
    LCD.print("\\ ");
    break;
    case 2:
    LCD.print("| ");
    break;
    case 3:
    LCD.print("/ ");
    break;
    default:
    LCD.print(" ");
    break;
    }
    // Read input status
    inputInitial[0] = digitalReadFast(INPUT0);
    inputInitial[1] = digitalReadFast(INPUT1);
    inputInitial[2] = digitalReadFast(INPUT2);
    inputInitial[3] = digitalReadFast(INPUT3);
    inputInitial[4] = digitalReadFast(INPUT4);
    inputInitial[5] = digitalReadFast(INPUT5);
    inputInitial[6] = digitalReadFast(INPUT6);
    inputInitial[7] = digitalReadFast(INPUT7);
    i+=1;
    if(i>3) i = 0;
    // for(j=0;j<8;j++) LCD.print(!inputInitial[j]);
    // Delay for serial to catch up
    delay(100);
    }

    // Display current value and set counters / flags to zero
    setCursorLCD();
    LCD.print("INIT ");
    for(i=0;i<8;i++) {
    LCD.print(!inputInitial[i]);
    inputTime[i] = 0;
    }
    while(digitalRead(INPUTSTART) == HIGH) delay(50);
    // Display current time
    LCD.print("\nTIME ");
    timeInitial = micros();
    LCD.print(timeInitial);
    LCD.print("uSec\nTiming Circuit Active...\n");

    // Make timing measurements
    while(digitalRead(INPUTSTART) == LOW) {
    if(!inputTime[0] && digitalRead(INPUT0) == LOW) inputTime[0] = micros();
    if(!inputTime[1] && digitalRead(INPUT1) == LOW) inputTime[1] = micros();
    if(!inputTime[2] && digitalRead(INPUT2) == LOW) inputTime[2] = micros();
    if(!inputTime[3] && digitalRead(INPUT3) == LOW) inputTime[3] = micros();
    if(!inputTime[4] && digitalRead(INPUT4) == LOW) inputTime[4] = micros();
    if(!inputTime[5] && digitalRead(INPUT5) == LOW) inputTime[5] = micros();
    if(!inputTime[6] && digitalRead(INPUT6) == LOW) inputTime[6] = micros();
    if(!inputTime[7] && digitalRead(INPUT7) == LOW) inputTime[7] = micros();
    }
    inputFinal[0] = digitalReadFast(INPUT0);
    inputFinal[1] = digitalReadFast(INPUT1);
    inputFinal[2] = digitalReadFast(INPUT2);
    inputFinal[3] = digitalReadFast(INPUT3);
    inputFinal[4] = digitalReadFast(INPUT4);
    inputFinal[5] = digitalReadFast(INPUT5);
    inputFinal[6] = digitalReadFast(INPUT6);
    inputFinal[7] = digitalReadFast(INPUT7);

    // Display data
    for(i=0;i<8;i++) {
    LCD.print("\n");
    LCD.print(i);
    LCD.print(": ");
    LCD.print(!inputInitial[i]);
    LCD.print(" > ");
    LCD.print(!inputFinal[i]);
    LCD.print(" ");
    if(inputTime[i]) {
    timeTemp = inputTime[i] - timeInitial;
    LCD.printf("%10d",timeTemp);
    LCD.print(" uSec");
    if(inputTime[0]) {
    timeTemp = inputTime[i] - inputTime[0];
    LCD.printf("%10d",timeTemp);
    LCD.print(" uSec");
    }
    }
    }

    while(digitalRead(INPUTSTART) == HIGH) delay(50);
    while(digitalRead(INPUTSTART) == LOW) delay(50);
    }
    Click image for larger version. 

Name:	OpticalTeensy.jpg 
Views:	247 
Size:	102.1 KB 
ID:	3043

  2. #2
    Senior Member
    Join Date
    Sep 2013
    Location
    Sonoma County, CA
    Posts
    141
    What sort of voltages are on the optocoupler inputs, and what is the value of the resistors in series with the LEDs?

    You have a lot of resistance on the optocoupler inputs, so you may not be driving enough current to pull the optocoupler outputs low enough for the Teensy to recognize them as low. The optocoupler output current may be high enough to light the LEDs without pulling the voltage low enough to switch the Teensy inputs.

  3. #3
    Junior Member
    Join Date
    Dec 2014
    Posts
    9
    Whollender, that is a good point. The current limiting resistors in front of the optocoupler are 3W 10k. I wanted to make sure I could take in 125VDC (12.3mA and 1.5W), but was doing my testing at 12VDC (1.0mA and 0.01W). The OptoCoupler is a Vishay K847PH. The LEDs have a 1k resistor.

    I have a 24VDC power supply and will try that, which should give 2.2mA (0.05W) on the optical side.

    Any advice on whether I need to use INPUT or INPUT_PULLUP for the optocoupler inputs. As you mention above, given the at there is built in resistance, the INPUT should be appropriate for the pinmode setup.

    Thanks,
    Rudy
    Last edited by rjb; 12-03-2014 at 07:37 PM.

  4. #4
    Senior Member
    Join Date
    Sep 2013
    Location
    Sonoma County, CA
    Posts
    141
    Rudy,

    I don't think that you need to use the INPUT_PULLUP mode because you already have a "pullup" in the diode and resistor.

    If the possible input voltage has a pretty wide range, I'd size the current limiting resistor on the optical side to give around 40mA (the datasheet has an absolute max of 60mA) at the max allowable input voltage. At that range, if your input voltage is even 1/10th of the max, then you'll still have a pretty reasonable forward current (4mA).

    If you don't want to use such high forward currents at max voltage, you'll need to increase the pullup resistor values to make sure that the collector current on the optocoupler output can pull the voltage all the way down to ground.

  5. #5
    Junior Member
    Join Date
    Dec 2014
    Posts
    9
    Whollender... You were right in that I did not need the INPUT_PULLUP mode. The circuit works flawlessly and measures micro-second times perfectly. Thanks. Rudy

  6. #6
    Senior Member
    Join Date
    Sep 2013
    Location
    Sonoma County, CA
    Posts
    141
    Glad you got everything working.

    Did you just have to adjust the resistors on the optocoupler input to get everything to work?

  7. #7
    Junior Member
    Join Date
    Dec 2014
    Posts
    9
    Whollender... I simply just used a 24VDC power supply instead of a ~12VDC power supply. After this, I tested it again with 125VDC and it worked properly. Therefore, as you suggested, at 12VDC, I was dropping the input voltage a little too much and therefore there was not enough current to the optocoupler input to properly drive the optocoupler outputs low enough to trigger the inputs on the Teensy from HIGH to LOW. Thanks again... Rudy

    PS.
    I will try to post the final design / code on my web site and will provide a link when I do that.

  8. #8
    Senior Member
    Join Date
    Sep 2013
    Location
    Sonoma County, CA
    Posts
    141
    Cool. Glad it was so simple.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •