UNPKG

node-red-contrib-ads1x15_i2c

Version:

A node-red node providing access to a ADS1x15 I2C analog to digital converter

219 lines (203 loc) 12.1 kB
//Licensed under the Apache License, Version 2.0 // 2021 David L Burrows //Contact me @ https://github.com/meeki007 //or meeki007@gmail.com module.exports = function(RED) { const ads1x15 = require('ads1x15'); function ads1x15MainFunction(config) { RED.nodes.createNode(this, config); var node = this; // config this.property = config.property||"payload"; this.i2c_device_number = parseInt(config.i2c_device_number, 10); this.chip = config.chip; this.i2c_address = config.i2c_address; this.inputsForChannel = config.inputsForChannel; this.singleEndedChannel0 = config.singleEndedChannel0; this.singleEndedChannel1 = config.singleEndedChannel1; this.singleEndedChannel2 = config.singleEndedChannel2; this.singleEndedChannel3 = config.singleEndedChannel3; this.differentialChannel0_1 = config.differentialChannel0_1; this.differentialChannel0_3 = config.differentialChannel0_3; this.differentialChannel1_3 = config.differentialChannel1_3; this.differentialChannel2_3 = config.differentialChannel2_3; this.samplesPerSecond1 = config.samplesPerSecond1; //tied to ads1115 this.samplesPerSecond0 = config.samplesPerSecond0; //tied to ads1015 this.progGainAmp = config.progGainAmp; var dply_rdy = true; //FORMAT //convert hexadec i2c chip and address to a number const number_of_chip = Number(this.chip); var format_number_of_chip; var format_samplesPerSeconds; if (number_of_chip === 1) { format_number_of_chip = 'ads1115'; format_samplesPerSeconds = Number(this.samplesPerSecond1); } else { format_number_of_chip = 'ads1015'; format_samplesPerSeconds = Number(this.samplesPerSecond0); } const number_of_i2c_address = Number(this.i2c_address); const format_number_of_i2c_address = this.i2c_address; const format_i2c_device_number = '/dev/i2c-' + this.i2c_device_number.toString(); const format_inputsForChannel = this.inputsForChannel; const format_progGainAmp = Number(this.progGainAmp); //populate channels_array_of_objects var channels_array_of_objects = []; if (format_inputsForChannel === 'singleEnded') { if (this.singleEndedChannel0 === true || this.singleEndedChannel1 === true || this.singleEndedChannel2 === true || this.singleEndedChannel3 === true) { if (this.singleEndedChannel0 === true) { channels_array_of_objects.push({channel: 0, programmable_gain_amplifier: format_progGainAmp, samples_per_second: format_samplesPerSeconds}); } if (this.singleEndedChannel1 === true) { channels_array_of_objects.push({channel: 1, programmable_gain_amplifier: format_progGainAmp, samples_per_second: format_samplesPerSeconds}); } if (this.singleEndedChannel2 === true) { channels_array_of_objects.push({channel: 2, programmable_gain_amplifier: format_progGainAmp, samples_per_second: format_samplesPerSeconds}); } if (this.singleEndedChannel3 === true) { channels_array_of_objects.push({channel: 3, programmable_gain_amplifier: format_progGainAmp, samples_per_second: format_samplesPerSeconds}); } } else { this.warn("No Single Ended Channels Selected: Please Select a Channel"); dply_rdy = "No Single Ended Channels Selected: Please Select a Channel"; } } if (format_inputsForChannel === 'differential') { if (this.differentialChannel0_1 === true || this.differentialChannel0_3 === true || this.differentialChannel1_3 === true || this.differentialChannel2_3 === true) { if (this.differentialChannel0_1 === true) { channels_array_of_objects.push({channelPositive: 0, channelNegative: 1, programmable_gain_amplifier: format_progGainAmp, samples_per_second: format_samplesPerSeconds}); } if (this.differentialChannel0_3 === true) { channels_array_of_objects.push({channelPositive: 0, channelNegative: 3, programmable_gain_amplifier: format_progGainAmp, samples_per_second: format_samplesPerSeconds}); } if (this.differentialChannel1_3 === true) { channels_array_of_objects.push({channelPositive: 1, channelNegative: 3, programmable_gain_amplifier: format_progGainAmp, samples_per_second: format_samplesPerSeconds}); } if (this.differentialChannel2_3 === true) { channels_array_of_objects.push({channelPositive: 2, channelNegative: 3, programmable_gain_amplifier: format_progGainAmp, samples_per_second: format_samplesPerSeconds}); } } else { this.warn("No Differential Channels Selected: Please Select a Channel"); dply_rdy = "No Differential Channels Selected: Please Select a Channel"; } } //clear status icon if one is hanging about wehn you deploy the node node.status({}); //Function to Clear user notices, used for timmer var status_clear = function() { //clear status icon node.status({}); }; //used for a sleap timmer in main async function function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } //setup the ads const adc = new ads1x15(number_of_chip, number_of_i2c_address); try { const adc = new ads1x15(number_of_chip, number_of_i2c_address); } catch (error) { this.warn("Load const adc: " + error); this.status({ fill: 'red', shape: 'dot', text: "detected error" }); } //is Bus ready - load device address number var bus_ready; //error check of bus_ready Promise.resolve (adc.openBus(this.i2c_device_number)) .then( bus_ready = true ) .catch(error => { bus_ready = ("adc.openBus: " + error), this.warn(bus_ready), this.status({ fill: 'red', shape: 'dot', text: "detected error" }); }); //DO STUFF WHEN TRIGGERED this.on("input", async function(msg, send, done) { // For maximum backwards compatibility, check that send exists. // If this node is installed in Node-RED 0.x, it will need to // fallback to using `node.send` send = send || function() { node.send.apply(node,arguments); }; //user error function function notify_user_errors(err) { if (done) { // Node-RED 1.0 compatible done(err); } else { // Node-RED 0.x compatible node.error(err, msg); } } //clear status icon every new trigger input node.status({}); if (dply_rdy !== true) { notify_user_errors(dply_rdy); this.status({ fill: 'red', shape: 'dot', text: "detected error" }); if (done) { done(); } } else { // create object to store voltage values var voltage_output_object = {}; voltage_output_object[format_i2c_device_number] = {}; voltage_output_object[format_i2c_device_number][format_number_of_chip] = {}; voltage_output_object[format_i2c_device_number][format_number_of_chip][format_number_of_i2c_address] = {}; voltage_output_object[format_i2c_device_number][format_number_of_chip][format_number_of_i2c_address][format_inputsForChannel] = {}; if (format_inputsForChannel === 'singleEnded') { for await (let request of channels_array_of_objects) { try { voltage_output_object[format_i2c_device_number][format_number_of_chip][format_number_of_i2c_address][format_inputsForChannel]['channel_'+request.channel] = {}; const measure = await adc.readSingleEnded({ channel: request.channel, pga: request.programmable_gain_amplifier, sps: request.samples_per_second }); voltage_output_object[format_i2c_device_number][format_number_of_chip][format_number_of_i2c_address][format_inputsForChannel]['channel_'+request.channel]['Volts'] = measure / 1e3; voltage_output_object[format_i2c_device_number][format_number_of_chip][format_number_of_i2c_address][format_inputsForChannel]['channel_'+request.channel]['miliVolts'] = measure; voltage_output_object[format_i2c_device_number][format_number_of_chip][format_number_of_i2c_address][format_inputsForChannel]['channel_'+request.channel]['samples_sec'] = request.samples_per_second; voltage_output_object[format_i2c_device_number][format_number_of_chip][format_number_of_i2c_address][format_inputsForChannel]['channel_'+request.channel]['gain'] = request.programmable_gain_amplifier; } catch (error) { notify_user_errors(error); } } } if (format_inputsForChannel === 'differential') { for await (let request of channels_array_of_objects) { try { voltage_output_object[format_i2c_device_number][format_number_of_chip][format_number_of_i2c_address][format_inputsForChannel]['channel_'+request.channelPositive+'_'+request.channelNegative] = {}; const measure = await adc.readSingleEnded({ channelPositive: request.channelPositive, channelNegative: request.channelNegative, pga: request.programmable_gain_amplifier, sps: request.samples_per_second }); voltage_output_object[format_i2c_device_number][format_number_of_chip][format_number_of_i2c_address][format_inputsForChannel]['channel_'+request.channelPositive+'_'+request.channelNegative]['Volts'] = measure / 1e3; voltage_output_object[format_i2c_device_number][format_number_of_chip][format_number_of_i2c_address][format_inputsForChannel]['channel_'+request.channelPositive+'_'+request.channelNegative]['miliVolts'] = measure; voltage_output_object[format_i2c_device_number][format_number_of_chip][format_number_of_i2c_address][format_inputsForChannel]['channel_'+request.channelPositive+'_'+request.channelNegative]['samples_sec'] = request.samples_per_second; voltage_output_object[format_i2c_device_number][format_number_of_chip][format_number_of_i2c_address][format_inputsForChannel]['channel_'+request.channelPositive+'_'+request.channelNegative]['gain'] = request.programmable_gain_amplifier; } catch (error) { notify_user_errors(error); } } } //send voltage_output_object to payload RED.util.setMessageProperty(msg,node.property,voltage_output_object); send(msg); if (done) { done(); } } }); } RED.nodes.registerType("ads1x15_i2c", ads1x15MainFunction); };