GPIO over Raspberry Pi 3 model B using Node.js - node.js

I am trying to blink the led using raspberry pi 3 model B,
I have all the required modules installed on my machine i.e. npm , nodejs , pi-gpio (fixed the minor changes to detect the gpio )
Code is :
var gpio = require("pi-gpio");
gpio.open(16, "output", function(err) {
gpio.write(16, 1, function() {
gpio.close(16);
});
});
//reading the data on the pin i.e pin : 16
gpio.open(16, "output", function (err) {
gpio.read(16, function (err, value) {
console.log("Data is "+ value);
gpio.close(16);
});
});
But above code throws error while running it,
node app.js
error :
Error when trying to open pin 16
gpio-admin : could not flush data to /sys/class/gpio/export : Device or resource busy
Thanks in advance
Any links where I can see the circuit diagram and code.
Concern : I dont want to change the platform i.e. node.js
pi-gpio which i am using is : https://github.com/rakeshpai/pi-gpio

pi-gpio is just writing to the GPIO device in the background so you can skip node.js and pi-gpio and do the same manually for testing purposes.
Example:
gpio.open(16, ...
# is the same as writing in terminal:
echo 16 > /sys/class/gpio/export
and
... "output" ...
# is the same as writing in terminal:
echo "out" > /sys/class/gpio/gpio16/direction
etc.
First of all, try rebooting the Pi and see if that takes care of the issue.
If that didn't help, try manually closing/unexporting the pin as root and then re-run the script.
# unexport the pin as root in case something's holding on to it
sudo echo 16 > /sys/class/gpio/unexport
The commands below basically constitute the pi-gpio API. These lines are what you would put in a shell script to control your GPIOs. Test them without sudo first in the order I've written them and if they don't work, try with sudo. If they still don't work, I think you have a wiring/hardware problem or need to change some system settings elsewhere.
# unexport the pin
sudo echo 16 > /sys/class/gpio/unexport
# export it again
sudo echo 16 > /sys/class/gpio/export
# make it an output
sudo echo "out" > /sys/class/gpio/gpio16/direction
# write a HIGH - is the LED on now?
sudo echo 1 > /sys/class/gpio/gpio16/value
# read the value of the pin - is it 1 after writing a 1 to the pin?
cat /sys/class/gpio/gpio16/value
# write a LOW - did it turn off?
sudo echo 0 > /sys/class/gpio/gpio16/value

Let's use 'rpio' module instead of 'pi-gpio'.
https://github.com/jperkin/node-rpio
It works fine on Pi3, zero etc.

As pi-gpio has already fixed the old and new sysPath (issue# https://github.com/rakeshpai/pi-gpio )
But it is dependent on quick2wire-gpio-admin lib.
So small fix required in quick2wire-gpio-admin
git clone https://github.com/quick2wire/quick2wire-gpio-admin.git
cd quick2wire-gpio-admin
The src/gpio-admin.c has
int size = snprintf(path, PATH_MAX, "/sys/devices/virtual/gpio/gpio%u/%s", pin, filename);
replace with :
int size = snprintf(path, PATH_MAX, GPIO_CLASS_PATH "gpio%u/%s", pin, filename);
Then go to cd quick2wire-gpio-admin directory
Then sudo make uninstall and
sudo make install
Then it is running fine.
The Code for is as follows : (filename : blinking12.js)
var gpio = require("pi-gpio");
var intervalId;
var durationId;
var gpioPin = 12;
gpio.open(gpioPin, "output", function (err) {
var on =1 ;
console.log("GPIO pin "+gpioPin+" is open toggling LED every 100mS for 10s");
intervalId = setInterval( function () {
gpio.write(gpioPin, on, function () {
on = (on + 1)% 2;
});
}, 100);
});
durationId = setTimeout (function () {
clearInterval(intervalId);
clearTimeout(durationId);
console.log('10 seconds blinking completed');
gpio.write(gpioPin, 0, function () {
gpio.close(gpioPin);
//process.exit(0);
});
}, 10000);
To run the code :
node blinking12.js
Output on my machine :
GPIO pin 12 is open toggling LED every 100mS for 10s
10 seconds blinking completed

Related

NodeJS - How do I detect other copies of my program?

I have written a NodeJS command-line program with two modes:
mode foo: runs forever until the user presses Ctrl+C
mode bar: runs once
If the user is already running the program in mode foo, then running it again in mode bar will cause errors. Thus, when the user invokes mode bar, I want to search for all other existing copies of my command-line program that are running and kill them (as a mechanism to prevent the errors before they happen).
Getting a list of processes in NodeJS is easy, but that doesn't help me much. If I simply kill all other node processes, then I might be killing other programs that are not mine. So, I need to know which specific node processes are the ones running my app. Is it even possible to interrogate a process to determine that information?
Another option is to have my program write a temporary file to disk, or write a value to the Windows registry, or something along those lines. And then, before my program exists, I could clean up the temporary value. However, this feels like a precarious solution, because if my program crashes, then the flag will never be unset and will remain orphaned forever.
What is the correct solution to this problem? How can I kill my own application?
I was able to solve this problem using PowerShell:
import { execSync } from "child_process";
const CWD = process.cwd();
function validateOtherCopiesNotRunning(verbose: boolean) {
if (process.platform !== "win32") {
return;
}
// From: https://securityboulevard.com/2020/01/get-process-list-with-command-line-arguments/
const stdout = execPowershell(
"Get-WmiObject Win32_Process -Filter \"name = 'node.exe'\" | Select-Object -ExpandProperty CommandLine",
verbose,
);
const lines = stdout.split("\r\n");
const otherCopiesOfMyProgram= lines.filter(
(line) =>
line.includes("node.exe") &&
line.includes("myProgram") &&
// Exclude the current invocation that is doing a 1-time publish
!line.includes("myProgram publish"),
);
if (otherCopiesOfMyProgram.length > 0) {
throw new Error("You must close other copies of this program before publishing.");
}
}
function execPowershell(
command: string,
verbose = false,
cwd = CWD,
): string {
if (verbose) {
console.log(`Executing PowerShell command: ${command}`);
}
let stdout: string;
try {
const buffer = execSync(command, {
shell: "powershell.exe",
cwd,
});
stdout = buffer.toString().trim();
} catch (err) {
throw new Error(`Failed to run PowerShell command "${command}":`, err);
}
if (verbose) {
console.log(`Executed PowerShell command: ${command}`);
}
return stdout;
}

How to read Wiegand on Raspberry Pi 3 with Node?

I've tried numerous tutorials, and I can't get it to work.
Current situation:
- 12V Access control device that is connected like this i.e. Wiegand D0 to GPIO14 (pin 8/Tx) and D1 to GPIO15 (pin 10/Rx), with voltage dividers, shifting 5V to 3.3V.
- Raspberry Pi 3 with Raspbian Lite OS.
- Configured the GPIO serial port i.e. enabling uart and disabling the console.
I am using the onoff NPM package to read the signals, but I am not getting anything.
const Gpio = require('onoff').Gpio;
const d0 = new Gpio(8, 'in');
const d1 = new Gpio(10, 'in');
d0.watch((err, value) => {
if (err) {
throw err;
}
d0.readSync(value);
});
d1.watch((err, value) => {
if (err) {
throw err;
}
d1.readSync(value);
});
process.on('SIGINT', () => {
d0.unexport();
d1.unexport();
});
What am I doing wrong?
The NPM package you're trying to use can only detect changing logic levels on GPIO pins.
You should use Wiegand NPM instead.
And I think you have set the wrong pins on your code. Pins 8 and 10 are in fact GPIO14 and GPIO15. The library I linked uses GPIO17 and GPIO18 by default, which are located on pins 11 and 12 of the connector.
Having said that, there is no need to disable the UART to use pins 8 and 10 as digital GPIO.

NodeJS Raspberry Pi & rpio Watch button not working

I've installed the rpio node module, the first time I ran it, I changed the pin to 33. It worked, and outputted some info and changed upon changing the state of the button. However, after stopping the script, then running it again it doesn't seem to work. I've tried a reboot and thats still given me no luck.
Here is my code:
var rpio = require('rpio');
var pin = 33;
console.log('test');
rpio.open(pin, rpio.INPUT, rpio.PULL_DOWN);
function pollcb(cbpin)
{
var state = rpio.read(cbpin) ? 'pressed' : 'released';
console.log('Button event on P%d (button currently %s)', cbpin, state);
}
rpio.poll(pin, pollcb);

Raspi-io: Error: Unknown pin "null"

I'm using the johnn-five and raspi-io packages for node and I'm trying to read the events created on a PIR motion sensor, but everytime I run the application, an error is thrown.
console
pi#raspberrypi ~/poc $ sudo node app.js
1439476578608 Device(s) RaspberryPi-IO
1439476578749 Connected RaspberryPi-IO
1439476578825 Repl Initialized
>> /home/pi/poc/node_modules/raspi-io/lib/index.js:316
throw new Error("Unknown pin \"" + pin + "\"");
^
Error: Unknown pin "null"
at Raspi._defineProperty.value (/home/pi/poc/node_modules/raspi-io/lib/index.js:316:17)
at Raspi.pinMode (/home/pi/poc/node_modules/raspi-io/lib/index.js:327:47)
at Motion.Controllers.PIR.initialize.value (/home/pi/poc/node_modules/johnny-five/lib/motion.js:27:17)
at new Motion (/home/pi/poc/node_modules/johnny-five/lib/motion.js:180:10)
at Board.<anonymous> (/home/pi/poc/app.js:9:16)
at Board.emit (events.js:104:17)
at process._tickDomainCallback (node.js:381:11)
package.js
{
"name": "poc",
"version": "0.0.1",
"main": "app.js",
"private": true,
"dependencies": {
"johnny-five": "0.8.86",
"raspi-io": "3.3.4"
}
}
app.js
var raspi = require('raspi-io');
var five = require('johnny-five');
var board = new five.Board({
io: new raspi()
});
board.on('ready', function() {
var motion = new five.Motion({pin: 'PI-17'});
motion.on('calibrated', function() {
console.log('calibrated');
});
motion.on('motionstart', function() {
console.log('motionstart');
});
motion.on('motionend', function() {
console.log('motionend');
});
});
However, the following code DOES seem to work:
snipped from another poc
var raspi = require('raspi');
var gpio = require('raspi-gpio');
raspi.init(function() {
var input = new gpio.DigitalInput({
pin: 'P1-17'
});
var logInput = function() {
console.log('Input 17: ' + input.read());
setTimeout(logInput, 1000);
};
logInput();
});
The Raspberry is a Rev. 2 model B.
The Motion detector I'm using is this one.
The cables are connected as follows (physical pin, taken from this schema)
Motion Sensor -> Pi
1 GND -> 6 GND
2 VDD -> 1 +3/V3 OUT
3 OUT -> 11 GPIO17
Any help would be greatly appreciated.
After more searching I came across this image.
It provided me with more insight on the WiringPi Pin numbers, BCM GPIO naming and P1 naming.
The pin GPIO0 on Pin 0 (BCM 17) seems to be throwing the error.
I switched to using pin GPIO4 on Pin 4 (BCM 23).
It doesn't really make sense why the 0 doesn't work, but for now, the poc I'm working on can progress again.
Your issue wasn't with any of your code, or a naming issue. You unfortunately chose poorly for which pin to use. P1-17 isn't able to accept an input, as it is dedicated 3.3v out. Choose another pin, and you should be fine.
Any pin reserved for I2C or Serial can't be used for regular GPIO function within Johnny Five, along with the dedicated power and ground pins which can't be used for IO, ever. As long as you avoid these ports, you'll be fine. A good resource on Raspberry Pi pinouts is here.

Callback when starting Android emulator with shell command via node

I am opening an android emulator with node via a shell script:
var process = require('child_process');
process.exec('~/Library/Android/sdk/tools/emulator -avd Nexus_5_API_21_x86', processed);
function processed(data){
console.log('processed called', data, data.toString());
}
I need to be able to detect when the emulator has finished loading so I can initiate a screen unlock and then launch the browser to a specified url (~/Library/Android/sdk/platform-tools/adb shell input keyevent 82 and ~/Library/Android/sdk/platform-tools/adb shell am start -a android.intent.action.VIEW -d http://www.stackoverflow.com)
However, when I launch the emulator I don't appear to get anything back and the process stays engaged with the emulator. When shutting the process down (ctrl+c) the emulator is closed along with it. (This is the same behaviour as running the shell command directly in the terminal)
Is it possible to know when the emulator has opened and loaded?
How can I execute additional commands when the process continues to
run?
I solved it like a boss.
I was able to set a timer to check once a second if the bootanimation had stopped. If it has, we know the emulator is open and booted.
var process = require('child_process');
process.exec('~/Library/Android/sdk/tools/emulator -avd Nexus_5_API_21_x86');
function isEmulatorBooted(){
process.exec('~/Library/Android/sdk/platform-tools/adb shell getprop init.svc.bootanim', function(error, stdout, stderr){
if (stdout.toString().indexOf("stopped")>-1){
clearInterval(bootChecker);
emulatorIsBooted();
} else {
console.log('we are still loading');
}
});
}
function emulatorIsBooted(){
//unlock the device
process.exec('~/Library/Android/sdk/platform-tools/adb shell input keyevent 82');
//gotourl
process.exec('~/Library/Android/sdk/platform-tools/adb shell am start -a android.intent.action.VIEW -d http://192.168.10.126:9876/');
}
bootChecker = setInterval(function(){
isEmulatorBooted();
},1000);
In case anyone else is looking for this, made an alternate version of Fraser's script - which also starts the actual emulator in a background process.
#!/usr/bin/env node
const process = require('child_process');
/* Get last emulator in list of emulators */
process.exec("emulator -list-avds|sed '$!d'", (_, stdout) => {
console.log('[android emulator] Booting')
/* Start emulator */
process.exec(`nohup emulator -avd ${stdout.replace('\n', '')} >/dev/null 2>&1 &`)
/* Wait for emulator to boot */
const waitUntilBootedThen = completion => {
process.exec('adb shell getprop init.svc.bootanim', (_, stdout) => {
if (stdout.replace('\n', '') !== 'stopped') {
setTimeout(() => waitUntilBootedThen(completion), 250)
} else {
completion()
}
})
}
/* When emulator is booted up */
waitUntilBootedThen(() => {
console.log('[android emulator] Done')
})
})

Resources