Socket
Socket
Sign inDemoInstall

node-red-contrib-anolog-to-digital-converter-raspberry-pi

Package Overview
Dependencies
25
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.2.13 to 0.4.16

doc/examplenode2.png

188

ads1x15.js

@@ -17,2 +17,3 @@

RED.nodes.createNode(this, config);
var globalContext = this.context().global;
var node = this;

@@ -28,2 +29,3 @@

//Function to Clear user notices, used for timmer

@@ -36,93 +38,145 @@ var status_clear = function()

//clear status icon on deploy
node.status({});
//used for a sleap timmer in main async function
function sleep(ms)
{
return new Promise(resolve => setTimeout(resolve, ms));
}
this.on("input", function(msg)
this.on("input", async function(msg, send, done)
{
// If this is pre-1.0, 'send' will be undefined, so fallback to node.send
send = send || function() { node.send.apply(node,arguments) }
//clear status icon every new trigger input
node.status({});
// Init Raspi
Raspi.init(() =>
//Check to see if a job is already waiting in que / drop msg and next job and warn user about trigger rate
var is_que_full = globalContext.get("node_red_contrib_anolog_to_digital_converter_raspberry_pi_"+this.chip+this.i2c_address+this.channel);
if (is_que_full === true)
{
return node.error('Dropped Request to fetch value from ADC, Chip:'+this.chip+' '+this.i2c_address+' '+this.channel+' , Please increse the ammount of time/rate of trigger when requesting this voltage');
}
else
{
//set the is_que_full to true untill the work is done
globalContext.set("node_red_contrib_anolog_to_digital_converter_raspberry_pi_"+this.chip+this.i2c_address+this.channel, true);
// Init Raspi-I2c
const i2c = new I2C();
//sleep 100ms to drop any extra requests made on this chip,i2c_address, and channel
await sleep(100);
// Init the ADC
const adc = new ADS1x15(
//check to see if ads is busy with another job from another node/tree and wait for job to finish before sending this nodes work
var adc_busy = globalContext.get("adc_is_busy_node_red_contrib_anolog_to_digital_converter_raspberry_pi");
if (adc_busy === true)
{
i2c, // i2c interface
chip: ADS1x15.chips.IC_ADS1115, // chip model
address: ADS1x15.address[this.i2c_address], // i2c address on the bus
node.warn('Upstream Treeing of node anolog_to_digital_converter_raspberry_pi detected. Please do not trigger more than one of these nodes at a time as Asynchronous message passing is not recomended; though supported it adds a delay to the output of these nodes. See documentation for this node on treeing');
while(adc_busy === true)
{
//Math.floor(Math.random() * (max - min + 1) + min);
var random_number_between_100_200 = Math.floor(Math.random() * (200 - 100 + 1) + 100);
await sleep(random_number_between_100_200);
adc_busy = globalContext.get("adc_is_busy_node_red_contrib_anolog_to_digital_converter_raspberry_pi");
}
}
// Defaults for future readings
pga: ADS1x15.pga[this.progGainAmp], // power-gain-amplifier range
sps: ADS1x15.spsADS1115[this.samplesPerSecond] // data rate (samples per second)
});
//now that we have our spot in line set to true so no one else can cut in
globalContext.set("adc_is_busy_node_red_contrib_anolog_to_digital_converter_raspberry_pi", true);
if ( this.channel.includes('CHANNEL') )
//sleep 100ms to drop any extra requests made to the ads
await sleep(50);
// Init Raspi
Raspi.init(() =>
{
// Get a single-ended reading from channel-X and display the results
adc.readChannel(ADS1x15.channel[this.channel], (err, value, volts) =>
// Init Raspi-I2c
const i2c = new I2C();
// Init the ADC
const adc = new ADS1x15(
{
if (err)
i2c, // i2c interface
chip: ADS1x15.chips.IC_ADS1115, // chip model
address: ADS1x15.address[this.i2c_address], // i2c address on the bus
// Defaults for future readings
pga: ADS1x15.pga[this.progGainAmp], // power-gain-amplifier range
sps: ADS1x15.spsADS1115[this.samplesPerSecond] // data rate (samples per second)
});
if ( this.channel.includes('CHANNEL') )
{
// Get a single-ended reading from channel-X and display the results
adc.readChannel(ADS1x15.channel[this.channel], (err, value, volts) =>
{
return node.error('Failed to fetch value from ADC', err);
}
else
{
//send to volts to payload
RED.util.setMessageProperty(msg,node.property,volts);
//send the payload
node.send(msg);
//send status msg
node.status(
if (err)
{
fill: 'blue',
shape: 'dot',
text: volts + 'v'
});
// clear/end status msg after 3 seconds
var timmerClear = setTimeout(status_clear, 5000);
}
});
}
return node.error('Failed to fetch value from ADC', err);
}
else
{
else if ( this.channel.includes('DIFF') )
{
// Get a differential reading from channel-X and display the results
adc.readDifferential(ADS1x15.differential[this.channel], (err, value, volts) =>
//send status msg
node.status(
{
fill: 'blue',
shape: 'dot',
text: volts + 'v'
});
// clear/end status msg after 3 seconds
var timmerClear = setTimeout(status_clear, 5000);
//send to volts to payload
RED.util.setMessageProperty(msg,node.property,volts);
send(msg);
}
});
}
else if ( this.channel.includes('DIFF') )
{
if (err)
// Get a differential reading from channel-X and display the results
adc.readDifferential(ADS1x15.differential[this.channel], (err, value, volts) =>
{
return node.error('Failed to fetch value from ADC', err);
}
else
{
//send to volts to payload
RED.util.setMessageProperty(msg,node.property,volts);
//send the payload
node.send(msg);
//send status msg
node.status(
if (err)
{
fill: 'blue',
shape: 'dot',
text: volts + 'v'
});
// clear/end status msg after 3 seconds
var timmerClear = setTimeout(status_clear, 5000);
}
});
}
return node.error('Failed to fetch value from ADC', err);
}
else
{
});
//send status msg
node.status(
{
fill: 'blue',
shape: 'dot',
text: volts + 'v'
});
// clear/end status msg after 3 seconds
var timmerClear = setTimeout(status_clear, 5000);
//send to volts to payload
RED.util.setMessageProperty(msg,node.property,volts);
send(msg);
}
});
}
});
await sleep(10);
//set adc_busy and is_que_full to false now that we are done with them
globalContext.set("adc_is_busy_node_red_contrib_anolog_to_digital_converter_raspberry_pi", false);
globalContext.set("node_red_contrib_anolog_to_digital_converter_raspberry_pi_"+this.chip+this.i2c_address+this.channel, false);
done();
}
});
}
RED.nodes.registerType("ads1x15-raspi", ads1x15MainFunction);
};
{
"name": "node-red-contrib-anolog-to-digital-converter-raspberry-pi",
"version": "0.2.13",
"version": "0.4.16",
"description": "A node-red node providing access to a ADS1x15 I2C analog to digital converter using a raspberry pi",

@@ -5,0 +5,0 @@ "dependencies": {

@@ -20,3 +20,6 @@ node-red-contrib-anolog-to-digital-converter-raspberry-pi

* [Example Flows](#example-flows)
* [Example](#example)
* [Simple_Example](#simple_example)
* [advance_example](#advance_example)
* [treeing](#treeing)
* [Dropped_Request](#Dropped_Request)
* [Bugs / Feature request](#bugs--feature-request)

@@ -78,6 +81,6 @@ * [License](#license)

Simple examples showing how to use the voltage_undivider.
Examples showing how to use the voltage_undivider.
### Example
### simple_example

@@ -90,2 +93,33 @@ ![examplenode.png](./doc/examplenode.png)

<br>
### advance_example
![examplenode2.png](./doc/examplenode2.png)
```
[{"id":"9fa062dc.6e1b6","type":"inject","z":"a074224d.a6b91","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":240,"wires":[["2bfc185d.72ddd8"]]},{"id":"2bfc185d.72ddd8","type":"ads1x15-raspi","z":"a074224d.a6b91","property":"x48_A0-GND","name":"x48_A0-GND","chip":"IC_ADS1115","i2c_address":"ADDRESS_0x48","channel":"CHANNEL_0","samplesPerSecond":"SPS_250","progGainAmp":"PGA_4_096V","x":350,"y":140,"wires":[["e219cd74.4ea59"]]},{"id":"edb67462.6fbb88","type":"debug","z":"a074224d.a6b91","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":550,"y":220,"wires":[]},{"id":"e219cd74.4ea59","type":"ads1x15-raspi","z":"a074224d.a6b91","property":"x48_A1-GND","name":"x48_A1-GND","chip":"IC_ADS1115","i2c_address":"ADDRESS_0x48","channel":"CHANNEL_1","samplesPerSecond":"SPS_250","progGainAmp":"PGA_4_096V","x":350,"y":200,"wires":[["bc5b5300.34dc1"]]},{"id":"bc5b5300.34dc1","type":"ads1x15-raspi","z":"a074224d.a6b91","property":"x48_A2-GND","name":"x48_A2-GND","chip":"IC_ADS1115","i2c_address":"ADDRESS_0x48","channel":"CHANNEL_2","samplesPerSecond":"SPS_250","progGainAmp":"PGA_4_096V","x":350,"y":260,"wires":[["6a55c7a6.54e078"]]},{"id":"6a55c7a6.54e078","type":"ads1x15-raspi","z":"a074224d.a6b91","property":"x48_A3-GND","name":"x48_A3-GND","chip":"IC_ADS1115","i2c_address":"ADDRESS_0x48","channel":"CHANNEL_3","samplesPerSecond":"SPS_250","progGainAmp":"PGA_4_096V","x":350,"y":320,"wires":[["edb67462.6fbb88"]]}]
```
<br>
### treeing
![treeing.png](./doc/treeing.png)
<br>
<br>
This is supported but highly discouraged. A warning message will display when this method is used.
<br>
The ADS1X15 cannot process more than one task at a time. To support this a delay is added to each trigger and while loop is used to check when a slot is available. This adds overhead that is not needed if the user just daisy-chain the nodes and sets the msg.payload to a more appropriate name.
<br>
Please import and use the advance example above if you need direction.
<br>
### Dropped_Request
If you try to get more than one voltage reading in 100ms, from the same address, and channel, the node will drop the msg triggering the event.<br> To stop this error just lower the amount of trigger events your sending to the node.
## Bugs / Feature request

@@ -110,2 +144,4 @@ Please [report](https://github.com/meeki007/node-red-contrib-ads1x15-raspi/issues) bugs and feel free to [ask](https://github.com/node-red-contrib-ads1x15-raspi/issues) for new features directly on GitHub.

Thanks to [Kevin Fitzgerald AKA kfitzgerald](https://github.com/kfitzgerald/raspi-kit-ads1x15#readme) for his work on raspi-kit-ads1x15. It made making this node for node-red possible.
<br>
Thank you to Andre van Amerongen; took the time to let me know about multiple trigger / treeing issue.

@@ -116,2 +152,25 @@ ## release notes ##

version 0.2.13
<br>
First Public release
<br>
<br>
version 0.3.13
<br>
Updated node to support the input event callback function, and add Backwards compatibility
<br>
more info found here: [https://nodered.org/blog/2019/09/20/node-done](https://nodered.org/blog/2019/09/20/node-done)
<br>
<br>
version 0.4.15
<br>
Bug fix: no error msg when treeing node / triggering multiple nodes at the same time
<br>
New feature: added Asynchronous Function to handle treeing<br>
Also added duplicate trigger drop on same msg triggering the same chip, address, and channel in less than 100ms
<br>
<br>
version 0.4.16
<br>
Updated Documentation
<br>

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc