K8055 : ReadDigitalChannel

Hi,
I made a program (in C++) that uses the K8055 card. This program is used to count the number of times a light beam (signal 1) is interrupted (signal 0), by a moving object coming across the transmitter and receiver of light.

The experimental device is connected to a digital input channel of the K8055 card. My program reads the state of digital input channel, with the function (ReadDigitalChannel). Each time the channel state changes from 1 to 0, a counter is implemented.

  • My program works well when I use the “test” button located near the digital input channels of the card (without using the experimental device with the light beam).
  • When the experimental device is connected to the card, interrupts of the light beams are correctly detected when I read the state of the input channel with the program “test procedure” given with the card K8055.
  • When the device is connected to the card, not all interrupts the light beams are detected when I read the state of the input channel with my program: notably, the very short breaks fail to be detected, while the long breaks are detected.

Do you have any idea of what I need to change in my program to systematically detect interrupts of the beam, even those very short? This seems to be possible because the program “test procedure” allows it. Please note that the function “SetCounterDebounceTime” seems ineffective.

Thank you in advance
Best Regards,
Samuel Venner

If the light beam break is less than 10ms then it may not be detected. The USB communication polling interval is 10ms.
It may help to solve the problem if you can post here a snippet of your program code (or the whole code).

The “SetCounterDebounceTime” is effective only for the internal pulse counter - not for the digital inputs.

Here is the code

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

#include "K8055D.h"

int main (void)
{
        long compt,i,h,CardAddr;
        int tps,  delais, time_end;
        long c[6];
        long t0[6];
        bool a;                         // etat canal
        bool Etat_Canal_0[6];           // tableau designant l'état des canaux

        char nom_fichier[6][20];           // nom du fichier de saisi pour un canal (moulin)
        char reponse[20];

        double duration[6];             // pour obtenir le temps en ms
        clock_t start[6];
        clock_t passage[6];

	FILE *moulin[6];

        /* Préciser la durée de l'expérience */

        printf ("\n\nDuree de l'experience (en seconde)? ");
        scanf ("%d", &delais);


        /* Saisi du nom du fichier d'enregistrement des resultats */

        for (i=1;i<=5;i++)
        {
                printf ("\n\nNom du fichier d'enregistrement pour le moulin %d: ", i);
                scanf ("%s", nom_fichier[i]);
	        moulin[i]=fopen(nom_fichier[i],"a+");
                fprintf(moulin[i],"canal	passage	time");
        }


        /* ouverture du lien de communication */

        h=-1;
        CardAddr=0;                     
        h=OpenDevice(CardAddr);
                                       
        while (h==-1 && CardAddr<=3)    
        {
                printf("\nCarte pas a l'adresse %d\n\n", CardAddr);
                CardAddr+=1;
                h=OpenDevice(CardAddr);
        }


        if (h==-1)
        {
                printf("\n\nCarte non trouve");
                printf ("\nTapez sur une touche  puis entree pour quitter l'application! ");
                scanf ("%s", reponse);
        }
        else
        {
                for(i=1;i<=5;i++)
                        SetDigitalChannel(i);


                printf("\n\nCarte a l'adresse %d", CardAddr);
                for(i=1;i<=5;i++)
                        Etat_Canal_0[i]=ReadDigitalChannel(i);

                for (i=1;i<=5;i++)
                        c[i]=0;
                time_end=time(NULL);

                do
                {


                    for (i=1;i<=5;i++)
                    {

                        a=ReadDigitalChannel(i);
                        if(a!=Etat_Canal_0[i])
                        {

                                if(a==0)
                                {
                                        c[i]++;
                                        if (c[i]==1)
                                        {
                                                t0[i]=time(NULL);
                                                start[i]=clock();
                                                if(time_end<t0[i])
                                                        time_end=t0[i];
                                        }

                                        passage[i] = clock();
                                        compt=c[i]/2;                     // compteur des passages
                                        duration[i] = (double)(passage[i]-start[i]) / CLOCKS_PER_SEC;
                                        printf( "\n%d	%d	%2.3f",i, compt, duration[i]);
                                        fprintf(moulin[i],"\n%d	%d	%2.3f",i, compt, duration[i]);
                                }
                                Etat_Canal_0[i]=a;
                        }
                    }
                    tps=time(NULL);
                }
                while (tps<(time_end+delais));
        }
        
        for(i=1;i<=5;i++)
        {
                fclose(moulin[i]);
                ClearDigitalChannel(i);
        }

        CloseDevice();

}

Connect the device’s output to one of the K8055’s counter inputs (I1 or I2), then reset the counter when you wish to start counting and read the counter when you want to retrieve the number of objects counted.

I noted that you are reading all the five digital inputs in a loop.
This way it takes about 50 ms to scan all the inputs.
You may read all the digital inputs in a single instruction in 10 ms by using the ReadAllDigital() function.
Here is how to modify the code to get it running faster:
Define:

int powerof2[6] = {0, 1, 2, 4, 8, 16}; long digitalin;

Change:

do
{
    for (i=1; i<=5; i++)
    {
        a = ReadDigitalChannel(i);
        if (a != Etat_Canal_0[i])

To:

do
{
    digitalin = ReadAllDigital();
    for (i=1; i<=5; i++)
    {
        a = (digitalin & powerof2[i]);
        if (a != Etat_Canal_0[i])

For powers of 2 you can use the bitwise shift left operator <<

int i, n;

for (i=0; i<5; i++) {
    n = (1 << i);
}

n will contain 1, 2, 4, 8 and 16 respectively

Binary    | Decimal
-------------------
0000 0001 = 1
0000 0010 = 2
0000 0100 = 4
0000 1000 = 8
0001 0000 = 16

Thank you for this proposal.
Everything is OK now!

[quote=“VEL255”]I noted that you are reading all the five digital inputs in a loop.
This way it takes about 50 ms to scan all the inputs.
You may read all the digital inputs in a single instruction in 10 ms by using the ReadAllDigital() function.
Here is how to modify the code to get it running faster:
…[/quote]