Git Product home page Git Product logo

Comments (15)

fivdi avatar fivdi commented on August 24, 2024

Yeah, I saw the chip-gpio package and spoke with the author. We discussed an issue related to reading the value of an input pin using onoff. The discussion is at jeremyscalpello/chip-gpio#1 but it stopped before figuring out what the problem is.

Perhaps we can figure out what the problem is together as I don't have a CHIP board. The PIN labels on the CHIP board are different to the Linux GPIO numbers. For example, XIO-P0 corresponds to gpio408, so 408 is the number to use with onoff. The table below shows the PIN labels and the corresponding gpio numbers to use with onoff.

PIN label gpio gpio number used by onoff
XIO-P0 gpio408 408
XIO-P1 gpio409 409
XIO-P2 gpio410 410
XIO-P3 gpio411 411
XIO-P4 gpio412 412
XIO-P5 gpio413 413
XIO-P6 gpio414 414
XIO-P7 gpio415 415

Can you try some outputs and inputs and let me know if there are issues? If there are, we can try to resolve them together.

from onoff.

roccomuso avatar roccomuso commented on August 24, 2024

@fivdi Yeah of course we can try to debug everything together, but I'm still wait to get mine. I should have a couple of them on june. :')

from onoff.

fivdi avatar fivdi commented on August 24, 2024

Ok, let me know how things go and we can take it from there :)

from onoff.

roccomuso avatar roccomuso commented on August 24, 2024

I got them ;) Let me know how could we debug everything.

from onoff.

fivdi avatar fivdi commented on August 24, 2024

@roccomuso Excellent, thanks for the feedback.

Let's start by checking to see what parts of onoff work on the CHIP.

Below is a test program that can be run on the CHIP. It assumes that XIO-P6 (gpio414) is connected to XIO-P7 (gpio415). To be on the safe side, XIO-P6 should be connected to XIO-P7 via a 1K current limiting resistor.

The test program configures XIO-P6 (gpio414) as an input and XIO-P7 (gpio415) as an output. It then sets the output to 0/1 using the onoff writeSync/write methods and reads the input (which is connected to the output) to see if has the same value. The test program also test interrupts.

"use strict";

var Gpio = require('onoff').Gpio,
  input = new Gpio(414, 'in', 'both'),
  output = new Gpio(415, 'out');

// Set output to 0 synchronously and check if input is also set to 0
output.writeSync(0);
if (input.readSync() === 0) {
  console.log('success: writeSync set output to 0');
} else {
  console.log('error: writeSync did not set output to 0');
}

// Set output to 1 synchronously and check if input is also set to 1
output.writeSync(1);
if (input.readSync() === 1) {
  console.log('success: writeSync set output to 1');
} else {
  console.log('error: writeSync did not set output to 1');
}

// Set output to 0 asynchronously ...
output.write(0, function (err) {
  if (err) {
    throw err;
  }

  // ... and check if input is also set to 0
  input.read(function (err, value) {
    if (err) {
      throw err;
    }

    if (value === 0) {
      console.log('success: write set output to 0');
    } else {
      console.log('error: write did not set output to 0');
    }

    // Set output to 1 asynchronously ...
    output.write(1, function (err) {
      if (err) {
        throw err;
      }

      // ... and check if input is also set to 1
      input.read(function (err, value) {
        if (err) {
           throw err;
        }

        if (value === 1) {
          console.log('success: write set output to 1');
        } else {
          console.log('error: write did not set output to 1');
        }
      });
    });
  });
});

function interrupt(err, value) {
  if (err) {
    throw err;
  }

  if (value === 1) {
    console.log('success: rising edge interrupt detected');
  } else if (value === 0) {
    console.log('success: falling edge interrupt detected');
  } else {
    console.log('error: unknown interrupt type detected');
  }
}

setTimeout(function () {
  // Set output (and input) to 0
  output.writeSync(0);

  // Start interrupt detection
  input.watch(interrupt);

  // Trigger a rising edge interrupt by setting output (and input) to 1
  output.write(1);

  setTimeout(function () {
    // Trigger a falling edge interrupt by setting output (and input) to 0
    output.write(0);

    setTimeout(function () {
      input.unexport();
      output.unexport();
    }, 1000);
  }, 1000);
}, 1000);

Please give the test program a try and post your findings. If everything functions as expected, the following should be displayed on the console:

success: writeSync set output to 0
success: writeSync set output to 1
success: write set output to 0
success: write set output to 1
success: rising edge interrupt detected
success: falling edge interrupt detected

from onoff.

shy21grams avatar shy21grams commented on August 24, 2024

@fivdi - I connected GPIO6 and GPIO7 using a 1k resistor and ran the test code above on a CHIP. It returned:
success: writeSync set output to 0
success: writeSync set output to 1
success: write set output to 0
success: write set output to 1

Edge detection works using CHIP_IO with GPIO2 and CSID0 connected using a 1k resistor.

So I updated your test code to reflect GPIO02 and CSIDO info. That test code was successful detecting the rising and falling edge with the with GPIO2 and CSID0 connected using a 1k resistor.
input = new Gpio(410, 'in', 'both'),
output = new Gpio(132, 'out');

I'm not sure why edge detection didn't work with GPIO6 and GPIO7 connected. Please let me know if I can help with other information. Thanks!

from onoff.

fivdi avatar fivdi commented on August 24, 2024

So the onoff read, readSync, write, and writeSync methods appear to function as expected.

For some reason edge detection doesn't appear to function on XIO-P6 (gpio414). Edge detection does however appear to function on XIO-P2 (gpio410), when connected to CSID0 (gpio132).

Does edge detection function on XIO-P2 (gpio410) when XIO-P2 is wired to XIO-P7 (gpio415) via a 1K resistor? i.e., what's the output of the following test program?

"use strict";

var Gpio = require('onoff').Gpio,
  input = new Gpio(410, 'in', 'both'),
  output = new Gpio(415, 'out');

// Set output to 0 synchronously and check if input is also set to 0
output.writeSync(0);
if (input.readSync() === 0) {
  console.log('success: writeSync set output to 0');
} else {
  console.log('error: writeSync did not set output to 0');
}

// Set output to 1 synchronously and check if input is also set to 1
output.writeSync(1);
if (input.readSync() === 1) {
  console.log('success: writeSync set output to 1');
} else {
  console.log('error: writeSync did not set output to 1');
}

// Set output to 0 asynchronously ...
output.write(0, function (err) {
  if (err) {
    throw err;
  }

  // ... and check if input is also set to 0
  input.read(function (err, value) {
    if (err) {
      throw err;
    }

    if (value === 0) {
      console.log('success: write set output to 0');
    } else {
      console.log('error: write did not set output to 0');
    }

    // Set output to 1 asynchronously ...
    output.write(1, function (err) {
      if (err) {
        throw err;
      }

      // ... and check if input is also set to 1
      input.read(function (err, value) {
        if (err) {
           throw err;
        }

        if (value === 1) {
          console.log('success: write set output to 1');
        } else {
          console.log('error: write did not set output to 1');
        }
      });
    });
  });
});

function interrupt(err, value) {
  if (err) {
    throw err;
  }

  if (value === 1) {
    console.log('success: rising edge interrupt detected');
  } else if (value === 0) {
    console.log('success: falling edge interrupt detected');
  } else {
    console.log('error: unknown interrupt type detected');
  }
}

setTimeout(function () {
  // Set output (and input) to 0
  output.writeSync(0);

  // Start interrupt detection
  input.watch(interrupt);

  // Trigger a rising edge interrupt by setting output (and input) to 1
  output.write(1);

  setTimeout(function () {
    // Trigger a falling edge interrupt by setting output (and input) to 0
    output.write(0);

    setTimeout(function () {
      input.unexport();
      output.unexport();
    }, 1000);
  }, 1000);
}, 1000);

from onoff.

shy21grams avatar shy21grams commented on August 24, 2024

success: writeSync set output to 0
success: writeSync set output to 1
success: write set output to 0
success: write set output to 1

That is the output after P2 and P7 were connected.

from onoff.

fivdi avatar fivdi commented on August 24, 2024

@shy21grams: I'm not sure what's going on here.

If I understand you correctly, if XIO-P2 (gpio410) is connected to CSID0 (gpio132):

input = new Gpio(410, 'in', 'both'),
output = new Gpio(132, 'out');

Then the output of the test program is:

success: writeSync set output to 0
success: writeSync set output to 1
success: write set output to 0
success: write set output to 1
success: rising edge interrupt detected
success: falling edge interrupt detected

But if XIO-P2 (gpio410) is connected to XIO-P7 (gpio415):

input = new Gpio(410, 'in', 'both'),
output = new Gpio(415, 'out');

Then the output of the test program is:

success: writeSync set output to 0
success: writeSync set output to 1
success: write set output to 0
success: write set output to 1

Is this correct?

from onoff.

nkolban avatar nkolban commented on August 24, 2024

I think we need to also be cognizant of what version of the Kernel is being used. There are two distributed by CHIP. One is at 4.3 and the other is at 4.4. They have distinct base addresses for GPIO usage.

from onoff.

nkolban avatar nkolban commented on August 24, 2024

I have a couple of CHIPs and feel pretty handy in JavaScript and C. Is there anything I can offer up to assist in adding support for CHIP?

from onoff.

fivdi avatar fivdi commented on August 24, 2024

To the best of my knowledge, interrupt detection should work on AP-EINT1, AP-EINT3, and XIO-P0 through XIO-P7. From the reports above, onoff appears to be able to detect interrupts in some cases and not in others. I don't understand why this is the case.

The first thing to do is to find out which GPIOs onoff can detect interrupts on. If it can detect interrupts, then all is ok. If it can't, the question is why.

The gpio numbers to use with onoff depends on the Linux kernel version.

PIN label gpio number used by onoff
AP-EINT1 193
AP-EINT3 35
XIO-P0 408 (4.3) 1016 (4.4)
XIO-P1 409 (4.3) 1017 (4.4)
XIO-P2 410 (4.3) 1018 (4.4)
XIO-P3 411 (4.3) 1019 (4.4)
XIO-P4 412 (4.3) 1020 (4.4)
XIO-P5 413 (4.3) 1021 (4.4)
XIO-P6 414 (4.3) 1022 (4.4)
XIO-P7 415 (4.3) 1023 (4.4)

from onoff.

rkagerer avatar rkagerer commented on August 24, 2024

Ran the Jul 9 code (slightly modified to change 414 --> 1022 and 415 --> 1023) on my CHIP running 4.4 with a 1K resistor connecting P6 to P7, and got identical output to @shy21grams; no rising/falling edges detected:

chip@Chip1:~/nodehello$ sudo node onofftest1.js
success: writeSync set output to 0
success: writeSync set output to 1
success: write set output to 0
success: write set output to 1

Did the same as him and changed input pin to P2 (1018) and output to CSID0 (132) and got the edges:

success: writeSync set output to 0
success: writeSync set output to 1
success: write set output to 0
success: write set output to 1
success: rising edge interrupt detected
success: falling edge interrupt detected

Then tried the Jul 19 code (also modified to work with 4.4) with P2 (1018) inputting from P7 (1023), again with the same results as shy21grams:

chip@Chip1:~/nodehello$ sudo node onofftest1.js
success: writeSync set output to 0
success: writeSync set output to 1
success: write set output to 0
success: write set output to 1

So I can confirm the answer to the Jul 20 question is "Yes, that's correct".

I also inspected the binary value by hand, per the Jan 10 instructions here:

sudo sh -c 'echo 1018 > /sys/class/gpio/export'
sudo sh -c 'echo both > /sys/class/gpio/gpio1018/edge' # was 'none' by default
od -cx /sys/class/gpio/gpio1018/value

Yeilds 0x30 when XIO-P2 is grounded, and 0x31 when it's tied to 3.3V (same results as jeremyscalpello).

To answer the unanswered Jan 11 questions in the other thread:

chip@Chip1:~/nodehello$ cat testONE.js
var ONE = new Buffer('1');
console.log(ONE[0].toString(16));

chip@Chip1:~/nodehello$ node testONE.js
31

And the second small example using input.watch seems to behave correctly (outputting 0 or 1 depending on whether P2 is grounded).

Side note: A more kernel-agnostic way to find the correct pin numbers is described here, with some further discussion here, and a sample python algorithm. Seeing as Howie at NextThingCo says they're anticipated to change yet again in upcoming kernel 4.7, it might be a good idea to prepare.

Also note, according to the docs:

CHIP’s most easily available IO pins are the “XIO” pins on header U14. This is the “GPIO eXpander” that uses an I2C bus to create eight (8) convenient pins for GPIO. These use address 0x38 on the TWI bus 2. Other pins are available for GPIO if more than eight are needed.

I'm not sure how the CSID pins are connected vs XIO, but is it possible the I2C expander on the latter is the reason edge interrupts aren't occurring? Perhaps the schematics will help.

I'm limited on time for any follow-up troubleshooting, but sent @fivdi an email offering to buy / lend him a $9 CHIP to facilitate his efforts. Would also love to see an improved debounce mechanism implemented.

Hope this helps!

from onoff.

fivdi avatar fivdi commented on August 24, 2024

@rkagerer Thanks for all the feedback and yes, it helps. I've ordered a few CHIP computers that should ship in October. Hopefully I can figure things out when they arrive.

from onoff.

fivdi avatar fivdi commented on August 24, 2024

I finally got a CHIP computer and was able to do some testing. It turns out that onoff actually works well on the CHIP. Input, output and interrupt detection all function as expected.

So why doesn't the test program listed above detect interrupts in all cases?

The hardware setup for the test program is two GPIOs connected to each other via a 1K current limiting resistor. One GPIO is configured as an input, the other as an output. If the state of the output is changed an interrupt is expected on the input. However, depending on the GPIOs chosen, interrupt detection may not work.

If the two GPIOs chosen are any of XIO-P0 through XIO-P7, interrupt detection doesn't work. However, if the input GPIO is any of XIO-P0 through XIO-P7 and the output is anything other than XIO-P0 through XIO-P7, for example, any of CSID0 through CSID7, interrupt detection does work.

The reason for interrupt detection not functioning correctly is related how the PFC8574 I/O expander works. XIO-P0 through XIO-P7 are pins from the PCF8574 I/O expander broken out to the CHIPs GPIO header. When the test program changes the state of the GPIO output, it writes information to the PCF8574 I/O expander using the I2C bus. The value written to the GPIO output also changes the state of the GPIO input as both GPIOs are connected together. However, a side effect of this write operation on the I2C bus to the PCF8574 I/O expander is that it clears the interrupt. The interrupt ends up getting lost.

Section 8.1 of the PFC8574 I/O expander datasheet explains how interrupts can be lost.

Interrupt detection is possible on any of XIO-P0 through XIO-P7, AP-EINT1 and AP-EINT3. Initial tests show that interrupt detection on AP-EINT1 and AP-EINT3 is approximately three times faster than on XIO-P0 through XIO-P7.

Have fun with onoff on your CHIP computer :)

from onoff.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.