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"}]
KiashanP

Flow Info

created 1 week, 5 days ago

Node Types

Core
  • file (x1)
  • function (x4)
  • inject (x1)
  • template (x1)
Other
  • gpio out (x2)
  • johnny5 (x1)
  • nodebot (x1)
  • tab (x1)
  • ui_chart (x2)
  • ui_gauge (x4)
  • ui_group (x3)
  • ui_slider (x2)
  • ui_tab (x1)

Tags

  • ArduinoUNO
  • DAQ
  • Temperature
  • Thermistors
  • Johnny-five
  • Heatsink
  • PWM
  • Fan
  • Heater
Copy this flow JSON to your clipboard and then import into Node-RED using the Import From > Clipboard (Ctrl-I) menu option