Skip to content

Instantly share code, notes, and snippets.

@KiashanP
Created November 30, 2017 13:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KiashanP/5661fa895284e37df65c3236f4dd0166 to your computer and use it in GitHub Desktop.
Save KiashanP/5661fa895284e37df65c3236f4dd0166 to your computer and use it in GitHub Desktop.
Low cost Arduino DAQ - Temperature Measurment and PWM Control of a PC Fan and Heater.

This flow makes use of Johnny-five to interface with an Arduino Uno, in order to measure temperatures through a PC heatsink. This can be performed at different power inputs to the heater and different fan speeds.This flow can however be edited to be used for other purposes. Both the fan and heater were controlled using MOSFET transistors.

The temperatures are graphed and can be viewed in a dashboard interface. The heater and fan input PWM signal can be adjusted from this interface as well. The temperature readings are also saved to a text file.

This flow was adapted from a flow created by Bradley Bock: https://flows.nodered.org/flow/4bceef5251eaa1f17a8f1fbeb5b6c34d

[{"id":"81d287fb.ec7c48","type":"tab","label":"Flow 2","disabled":false,"info":""},{"id":"b2eef7ed.8e0f58","type":"file","z":"81d287fb.ec7c48","name":"Save to Text File","filename":"","appendNewline":true,"createDir":false,"overwriteFile":"false","x":1437,"y":413,"wires":[]},{"id":"cca111f6.70937","type":"inject","z":"81d287fb.ec7c48","name":"Timestamp (5sec)","topic":"timestamp","payload":"","payloadType":"date","repeat":"2","crontab":"","once":false,"x":260,"y":405,"wires":[["bd647f8d.72ed4","fc1319d9.c9df18","605d51e7.eade1"]]},{"id":"266473c4.9d493c","type":"template","z":"81d287fb.ec7c48","name":"Convert to CSV","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{payload.timestamp}} , {{payload.sensor1}} , {{payload.sensor2}};","x":1202,"y":414,"wires":[["b2eef7ed.8e0f58"]]},{"id":"605d51e7.eade1","type":"function","z":"81d287fb.ec7c48","name":"timeConvert","func":"//create date object from timestamp injected in\nvar dt = new Date(msg.payload); \n\n\n//Create timestamp with only the time, no date, information\nmsg.payload = {\n timestamp: dt.getHours() + ':' + \ndt.getMinutes() + ':' + dt.getSeconds()\n}\n\n//Get the month information out\nvar month = dt.getMonth() + 1; \n\n//Create Filename that data will be saved to\nmsg.filename = dt.getFullYear() + '_' + month \n+ '_' + dt.getDate() + \n'_tempLog.txt';\n\n//Convert log name to string - required for saveFile node\nmsg.filename = msg.filename.toString();\n\nreturn msg;","outputs":1,"noerr":0,"x":650,"y":487,"wires":[["1b4a31c6.17e71e"]]},{"id":"1b4a31c6.17e71e","type":"function","z":"81d287fb.ec7c48","name":"Join Data Streams","func":"/*\nThis file is based on the flow supplied at \nhttp://flows.nodered.org/flow/8ba7f90f3ea8d92b1e01\nby mharizanov\n\nAll sensors that you have added will need to\nto be added to the code below\n\n*/\ncontext.data = context.data || new Object();\n\n//Add all\n//Wait for information and store it when it comes\nswitch (msg.topic) {\n case \"sensor1\":\n context.data.sensor1 = msg.payload;\n msg = null;\n break;\n case \"sensor2\":\n context.data.sensor2 = msg.payload;\n msg = null;\n break;\n case \"timestamp\":\n context.data.timestamp = msg.payload.timestamp;\n context.filename = msg.filename;\n msg = null;\n break;\n \n default:\n msg = null;\n \tbreak;\n}\n\n//When all the data bins are filled, send out the information in one clump\nif(context.data.sensor1 != null && context.data.sensor2 != null && context.data.timestamp != null) {\n msg = new Object();\n msg.payload = context.data;\n msg.filename = context.filename;\n context.data=null;\n\treturn msg;\n\t\n} else return null; //msg;\n\n\n\n\n\n\n\n","outputs":1,"noerr":0,"x":966,"y":413,"wires":[["266473c4.9d493c"]]},{"id":"bd647f8d.72ed4","type":"function","z":"81d287fb.ec7c48","name":"Temperature Thermistor Sensor1","func":"sensorName = \"sensor1\";\nvar sensor = global.get(sensorName);\n\nvar T;\nvar R;\nvar analogueOut = 0; //analogue out\n\n//these values are far from the standard and were fitted using an excel sheet\nvar A = 0.001314268;\nvar B = 0.000174416;\nvar C = 0.000000555;\n\n\nvar rPass = 9.64; //resitance of passive resitor in kOhm\n//var rThermistor = 8.97; //resistance of thermistor at room temperature in kOhm\n\n//Take readings\nanalogueOut = sensor.scaleTo(0, 1023); //read sensor info, scale to value between 0 and 1023\n//calculate resistance of thermistor\nR = rPass / ((1023 / analogueOut)-1); \n//calculate correspnding temperature in degC of thermistor based on resistance value using Steinhart-Hart equation\n//B parameter version of steinhart equation\n\nR = R*1000;\n\nvar K = (Math.log(R))*(Math.log(R))*(Math.log(R));\n\nT = ( 1/(A + B*(Math.log(R)) + C*(K) ))-273.15;\n\n\n//Round Number to 2 decimals\nT = Math.round(T * 100) / 100; \n\n//Send the information out\n//node.send({topic: sensorName , payload: R , id: '2'});\nnode.send({topic: sensorName , payload: T , id: '2'}); //send inforamtion out of node, attach topic to payload for identification later\n\n \n\n","outputs":1,"noerr":0,"x":617,"y":299,"wires":[["1b4a31c6.17e71e","3666fa3b.d5b366","f5b16053.5c645"]]},{"id":"5d69d5c4.2e007c","type":"johnny5","z":"81d287fb.ec7c48","name":"Initialise Sensors","func":" //Create all the sensor instances you wish\n //The j5 node is only run once, thus there is no\n //chance of multiple instances being created.\n var sensorA4 = new five.Sensor({\n pin: \"A4\",\n }); //read in values from sensor\n var sensorA5 = new five.Sensor({\n pin: \"A5\",\n }); //read in values from sensor\n \n//make sensors available across all function nodes\nglobal.set(\"sensor1\" , sensorA4); // this is now available to other nodes\nglobal.set(\"sensor2\" , sensorA5); // this is now available to other nodes","board":"35e41946.c28956","noerr":0,"x":263,"y":333,"wires":[["bd647f8d.72ed4","fc1319d9.c9df18"]]},{"id":"fc1319d9.c9df18","type":"function","z":"81d287fb.ec7c48","name":"Temperature Thermistor Sensor2","func":"//Access the sensors you wish to use\nsensorName = \"sensor2\";\nvar sensor = global.get(sensorName);\n\nvar T;\nvar R;\nvar analogueOut = 0; //analogue out\n\n//these values are far from the standard and were fitted using an excel sheet\nvar A = 0.001314268;\nvar B = 0.000174416;\nvar C = 0.000000555;\n\n\nvar rPass = 9.64; //resitance of passive resitor in kOhm\n//var rThermistor = 8.97; //resistance of thermistor at room temperature in kOhm\n\n//Take readings\nanalogueOut = sensor.scaleTo(0, 1023); //read sensor info, scale to value between 0 and 1023\n//calculate resistance of thermistor\nR = rPass / ((1023 / analogueOut)-1); \n//calculate correspnding temperature in degC of thermistor based on resistance value using Steinhart-Hart equation\n//B parameter version of steinhart equation\n\nR = R*1000;\n\nvar K = (Math.log(R))*(Math.log(R))*(Math.log(R));\n\nT = ( 1/(A + B*(Math.log(R)) + C*(K) ))-273.15;\n\n\n//Round Number to 2 decimals\nT = Math.round(T * 100) / 100; \n\n//Send the information out\n//node.send({topic: sensorName , payload: R , id: '2'});\nnode.send({topic: sensorName , payload: T , id: '2'}); //send inforamtion out of node, attach topic to payload for identification later\n\n \n","outputs":1,"noerr":0,"x":618,"y":377,"wires":[["1b4a31c6.17e71e","86a202d0.3e8d9","32f68344.78185c"]]},{"id":"11efd556.0eb9fb","type":"gpio out","z":"81d287fb.ec7c48","name":"Pin 3 PWM","state":"PWM","pin":"3","i2cDelay":"0","i2cAddress":"","i2cRegister":"","outputs":0,"board":"35e41946.c28956","x":504,"y":715,"wires":[]},{"id":"f34c01d8.534dd","type":"gpio out","z":"81d287fb.ec7c48","name":"Pin 5 PWM","state":"PWM","pin":"5","i2cDelay":"0","i2cAddress":"","i2cRegister":"","outputs":0,"board":"35e41946.c28956","x":1047,"y":702,"wires":[]},{"id":"e7d9e27e.7b4d4","type":"ui_slider","z":"81d287fb.ec7c48","name":"Fan","label":"Fan","group":"ad6a3467.8f98f8","order":1,"width":"0","height":"0","passthru":true,"topic":"Fan","min":"0","max":"255","step":"1","x":237,"y":656,"wires":[["11efd556.0eb9fb","685ca7c7.1fda88"]]},{"id":"600f2f15.541fd","type":"ui_slider","z":"81d287fb.ec7c48","name":"Heater","label":"Heater","group":"ad6a3467.8f98f8","order":3,"width":0,"height":0,"passthru":true,"topic":"Heater","min":0,"max":"255","step":"1","x":810,"y":640,"wires":[["f34c01d8.534dd","b97bf303.684b4"]]},{"id":"3666fa3b.d5b366","type":"ui_chart","z":"81d287fb.ec7c48","name":"Temperature 1","group":"eaa8f458.53c5a8","order":0,"width":"6","height":"6","label":"Temperature 1","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"0","ymax":"70","removeOlder":"2","removeOlderPoints":"","removeOlderUnit":"60","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"x":1200,"y":175,"wires":[[],[]]},{"id":"86a202d0.3e8d9","type":"ui_chart","z":"81d287fb.ec7c48","name":"Temperature 2","group":"eaa8f458.53c5a8","order":0,"width":"6","height":"6","label":"Temperature 2","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"0","ymax":"70","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"60","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#9e1d1d","#ff9896","#9467bd","#c5b0d5"],"x":1200,"y":289,"wires":[[],[]]},{"id":"685ca7c7.1fda88","type":"ui_gauge","z":"81d287fb.ec7c48","name":"","group":"ad6a3467.8f98f8","order":2,"width":0,"height":0,"gtype":"gage","title":"Fan Speed","label":"PWM","format":"{{value}}","min":0,"max":"255","colors":["#00b500","#e6e600","#ca3838"],"seg1":"","seg2":"","x":503,"y":597,"wires":[]},{"id":"f5b16053.5c645","type":"ui_gauge","z":"81d287fb.ec7c48","name":"","group":"54d3ca88.2b66e4","order":0,"width":0,"height":0,"gtype":"donut","title":"Temp 1","label":"Degrees C","format":"{{value}}","min":0,"max":"100","colors":["#00b500","#e6e600","#9f2b2b"],"seg1":"","seg2":"","x":1180,"y":131,"wires":[]},{"id":"32f68344.78185c","type":"ui_gauge","z":"81d287fb.ec7c48","name":"","group":"54d3ca88.2b66e4","order":0,"width":0,"height":0,"gtype":"donut","title":"Temp 2","label":"Degrees C","format":"{{value}}","min":0,"max":"100","colors":["#00b500","#e6e600","#972828"],"seg1":"","seg2":"","x":1179,"y":233,"wires":[]},{"id":"b97bf303.684b4","type":"ui_gauge","z":"81d287fb.ec7c48","name":"","group":"ad6a3467.8f98f8","order":4,"width":0,"height":0,"gtype":"gage","title":"Heater","label":"PWM","format":"{{value}}","min":0,"max":"255","colors":["#00b500","#e6e600","#ca3838"],"seg1":"","seg2":"","x":1060,"y":592,"wires":[]},{"id":"35e41946.c28956","type":"nodebot","z":"81d287fb.ec7c48","name":"COM3_port","username":"","password":"","boardType":"firmata","serialportName":"COM3","connectionType":"local","mqttServer":"","socketServer":"","pubTopic":"","subTopic":"","tcpHost":"","tcpPort":"","sparkId":"","sparkToken":"","beanId":"","impId":"","meshbluServer":"https://meshblu.octoblu.com","uuid":"","token":"","sendUuid":""},{"id":"ad6a3467.8f98f8","type":"ui_group","z":"","name":"Input","tab":"723e0c03.ca8984","disp":true,"width":"6"},{"id":"eaa8f458.53c5a8","type":"ui_group","z":"","name":"Results","tab":"723e0c03.ca8984","disp":true,"width":"6"},{"id":"54d3ca88.2b66e4","type":"ui_group","z":"","name":"Gauges","tab":"723e0c03.ca8984","disp":true,"width":"6"},{"id":"723e0c03.ca8984","type":"ui_tab","z":"","name":"Home","icon":"dashboard"}]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment