EnotionZ / gpio

Talk to your Single Board Computer's gpio pins
MIT License
394 stars 57 forks source link

Pin direction change #23

Open 0xceb1d opened 10 years ago

0xceb1d commented 10 years ago

Apologies if I have miss understood your documentation, however, when implementing your library for my project I am having trouble with switching the direction of a pin from out to in after sending a signal to it (working with a proximity sensor).

This is my code:

// Distance change listener

var gpioProximity = gpio.export(18, {
    direction: 'in',
    ready: function() {
        logger.info('GPIO pin 18 set up as proximity sensor');
        distanceReady = true;
        distanceCheck();
        gpioProximity.on("change", function(val){
            logger.info('GPIO pin 18 seen change');
            if (pingSent == true){
                if (val == 1) {
                    endTime = Date.now();
                    logger.info('End ' + endTime);
                    logger.info('Ping received');
                }
            }
        })
   }
});  

// Distance check

function distanceCheck(){

    distanceChecking = setInterval(function(){
        gpioProximity.setDirection("out");
        setTimeout(gpioProximity.set(1),100);
        setTimeout(gpioProximity.reset(),100);
        startTime = Date.now();
        logger.info('Start ' + startTime);
        pingSent = true;
        gpioProximity.setDirection("in");
        setTimeout(pingSent = false, 500);
        // MATH
        // UPDATE DISTANCE
    }, 2000);
}

This is the console log:

info: GPIO pin 18 set up as proximity sensor
info: Start 1386161269665
EPERM write /sys/class/gpio/gpio18/value
info: Start 1386161271662
EPERM write /sys/class/gpio/gpio18/value
info: Start 1386161273660
EPERM write /sys/class/gpio/gpio18/value
info: Start 1386161275661
EPERM write /sys/class/gpio/gpio18/value
info: Start 1386161277660
EPERM write /sys/class/gpio/gpio18/value
info: Start 1386161279660
EPERM write /sys/class/gpio/gpio18/value
info: Start 1386161281660
EPERM write /sys/class/gpio/gpio18/value

For reference, this is the python script I am basing this on:

import time
import RPi.GPIO as GPIO

    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(12, GPIO.OUT)

    GPIO.output(12, 0)
    time.sleep(0.000002)

    GPIO.output(12, 1)
    time.sleep(0.000005)

    GPIO.output(12, 0)
    GPIO.setup(12, GPIO.IN)

    while GPIO.input(12)==0:
            starttime=time.time()

    while GPIO.input(12)==1: 
            endtime=time.time()

    duration=endtime-starttime
    distance=duration*34000/2
    print str(x + 1) + ": " + str(distance)
EnotionZ commented 10 years ago

Two problems

1) JavaScript suck balls for real-time operations. Looking at the code, I'm assuming you're using a sonar sensor? You send a ping through a header, change it to listening mode, wait for the time it takes to hit a wall and come back, take that time, divide by 2, multiplied by speed of sound? This requires a timer precision in the microseconds which you won't get in JavaScript. On top of that, this library sets directions and pins using node's file writes, so it's not exactly fast either. If you're dealing with real time stuff like putting distance sensors on a robot, I can't possibly recommend JavaScript (unless you make arduinos do the heaving lifting and send the results through node-serialport or something).

2) Even if the above wasn't an issue, JavaScript is async, so placing 2 setDirection and 2 value sets in the same function block will be problematic. You will have to utilize callbacks (or whatever promise/async library you use) to ensure that the async process is complete before performing the next call. I wrote this library before being educated on callbacks hell, promises, and api standards for async calls. Admittedly it was not possible for me to convert your code to something elegant and concise, so I'd rather not share a spaghetti code solution. I'll fix up the API and docs when I get a chance, this issue of when and how to fire certain methods have come up more than once.

0xceb1d commented 10 years ago

Thank you for the response, I currently have the JS app talking to a python socket, however I ideally wanted to integrate the socket into the app. It looks like using JS to do so isn't really possible now.

Have you had any experience with edge.js? specifically the python integration? http://tjanczuk.github.io/edge/#/4