-
1Build Temperature Cable
- Measure the size of the bin
- Go out and estimate the size of the bin so that you know how far apart to spread the cables. The 5000-bushel bins my dad is monitoring have a sensor spacing of 7ft and that gives one at the bottom, one around the middle, and one a single ring deep at the top.
- Mark the location of the sensors
- String out some 4 conductor fire alarm wire (or the wire of your choosing), and mark the place where the sensors will be attached. Currently, I just roughly do this myself but eventually, I am going to place markers on the shop floor so that I can measure it more accurately.
- Attach the bottom sensor.
- The wires on the DS18B20 sensor are either red, blue, and yellow or red, black, and yellow. In both cases the red is power and the data wire is yellow. That leaves either the blue or the black cable being the ground/negative end. At this point, one has to strip away some sheathing with wire strippers to attach the sensor to the cable. On the cable I have been using there is a red wire, a green wire, a black wire and a blue wire. I have been attaching the red wire to the power, the black wire to the ground, and the blue wire to the data wire. All of these wires must be soldered on and after taped so that they do not touch. I also apply heat shrink where the connections are, and although I do not 'shrink' it until after I would string three sections on now since they can be difficult to get on later. On GitHub, there is a document that contains photos and may explain this better.
- Attach middle and top sensor
- For these two wire strippers can not be used since they are in the middle of the wire. I use a utility knife to strip away some of the sheathing and then side cutters to cut the sheathing that has been stripped away. I have been told that a propane torch could be used to burn away the sheathing but I have found that after scraping away burnt sheathing my way is just as fast.
- Roll out the rest of the length of wire.
- In the case of the 5000-bushel bins currently being monitored the total length is about 60ft.
- Test the cable and collect addresses.
- Currently, I use the following code example in DallasTemperature, https://github.com/milesburton/Arduino-Temperature-Control-Library/blob/master/examples/Multiple/Multiple.ino, but I intend to edit it more to my specific purposes and to make better instructions here.
- Shrink the Heat shrink and complete the cable
- Go through all steps in step one, except for 8, 3 more times to get a total of four cables.
The cable schematic include in the files may help for this one, but it is nothing special
- Measure the size of the bin
-
2Assemble the PCB
This is the order in which I would assemble the PCB.
- Resistors
- MKR headers
- Cable connectors
- Onboard DHT22
The KiCad files can be found here: https://github.com/PhysicsUofRAUI/binTempSensor/tree/master/ecad.
I will be selling the bare PCBs as well as assembled PCBs on Tindie and possibly other places.
Also, I intend to improve these instructions greatly.
-
3Program the Arduino
// OneWire - Version: Latest #include <OneWire.h> #include <DallasTemperature.h> // On board Sensor #include <DHT.h> #include <DHT_U.h> #include <Adafruit_Sensor.h> #define DHTPIN A5 #define DHTTYPE DHT22 DHT_Unified dht(DHTPIN, DHTTYPE); /* Sketch generated by the Arduino IoT Cloud Thing "DS018s_temp_test" https://create.arduino.cc/cloud/things/952e3ad9-ef0f-46b0-aa63-a71ab33f7a11 Arduino IoT Cloud Variables description The following variables are automatically generated and updated when changes are made to the Thing float top; float middle; float bottom; Variables which are marked as READ/WRITE in the Cloud Thing will also have functions which are called when their values are changed from the Dashboard. These functions are generated with the Thing and added at the end of this sketch. */ #include "thingProperties.h" #define BIN_ONE_ONE_WIRE_BUS 13 #define BIN_TWO_ONE_WIRE_BUS 14 #define BIN_THREE_ONE_WIRE_BUS 5 #define BIN_FOUR_ONE_WIRE_BUS 2 #define TEMPERATURE_PRECISION 9 // Bin One OneWire binOneOneWire(BIN_ONE_ONE_WIRE_BUS); DallasTemperature binOneSensors(&binOneOneWire); DeviceAddress one_top_address = { }; DeviceAddress one_middle_address = { }; DeviceAddress one_bottom_address = { }; // Bin Two OneWire binTwoOneWire(BIN_TWO_ONE_WIRE_BUS); DallasTemperature binTwoSensors(&binTwoOneWire); DeviceAddress two_top_address = { }; DeviceAddress two_middle_address = { }; DeviceAddress two_bottom_address = { }; // Bin Three OneWire binThreeOneWire(BIN_THREE_ONE_WIRE_BUS); DallasTemperature binThreeSensors(&binThreeOneWire); DeviceAddress three_top_address = { }; DeviceAddress three_middle_address = { }; DeviceAddress three_bottom_address = { }; // Bin Four OneWire binFourOneWire(BIN_FOUR_ONE_WIRE_BUS); DallasTemperature binFourSensors(&binFourOneWire); DeviceAddress four_top_address = {}; DeviceAddress four_middle_address = {}; DeviceAddress four_bottom_address = {}; unsigned long last_time; void setup() { // Initialize serial and wait for port to open: Serial.begin(9600); // This delay gives the chance to wait for a Serial Monitor without blocking if none is found delay(1500); // get the onboard sensor ready dht.begin(); sensor_t sensor; /* Getting Bin One's Sensors Ready */ binOneSensors.begin(); if (!binOneSensors.getAddress(one_top_address, 0)) { Serial.println("Unable to find address for Device 0"); } delay(500); if (!binOneSensors.getAddress(one_middle_address, 1)) { Serial.println("Unable to find address for Device 1"); } delay(500); if (!binOneSensors.getAddress(one_bottom_address, 2)) { Serial.println("Unable to find address for Device 2"); } binOneSensors.setResolution(one_top_address, TEMPERATURE_PRECISION); delay(500); binOneSensors.setResolution(one_middle_address, TEMPERATURE_PRECISION); delay(500); binOneSensors.setResolution(one_bottom_address, TEMPERATURE_PRECISION); /* Getting Bin Two's Sensors Ready */ binTwoSensors.begin(); if (!binTwoSensors.getAddress(two_top_address, 0)) { Serial.println("Unable to find address for Device 0"); } delay(500); if (!binTwoSensors.getAddress(two_middle_address, 1)) { Serial.println("Unable to find address for Device 1"); } delay(500); if (!binTwoSensors.getAddress(two_bottom_address, 2)) { Serial.println("Unable to find address for Device 2"); } binTwoSensors.setResolution(two_top_address, TEMPERATURE_PRECISION); delay(500); binTwoSensors.setResolution(two_middle_address, TEMPERATURE_PRECISION); delay(500); binTwoSensors.setResolution(two_bottom_address, TEMPERATURE_PRECISION); /* Getting Bin Three's Sensors Ready */ binThreeSensors.begin(); if (!binThreeSensors.getAddress(three_top_address, 0)) { Serial.println("Unable to find address for Device 0"); } delay(500); if (!binThreeSensors.getAddress(three_middle_address, 1)) { Serial.println("Unable to find address for Device 1"); } delay(500); if (!binThreeSensors.getAddress(three_bottom_address, 2)) { Serial.println("Unable to find address for Device 2"); } binThreeSensors.setResolution(three_top_address, TEMPERATURE_PRECISION); delay(500); binThreeSensors.setResolution(three_middle_address, TEMPERATURE_PRECISION); delay(500); binThreeSensors.setResolution(three_bottom_address, TEMPERATURE_PRECISION); /* Getting Bin Four's Sensors Ready */ binFourSensors.begin(); if (!binFourSensors.getAddress(four_top_address, 0)) { Serial.println("Unable to find address for Device 0"); } delay(500); if (!binFourSensors.getAddress(four_middle_address, 1)) { Serial.println("Unable to find address for Device 1"); } delay(500); if (!binFourSensors.getAddress(four_bottom_address, 2)) { Serial.println("Unable to find address for Device 2"); } binFourSensors.setResolution(four_top_address, TEMPERATURE_PRECISION); delay(500); binFourSensors.setResolution(four_middle_address, TEMPERATURE_PRECISION); delay(500); binFourSensors.setResolution(four_bottom_address, TEMPERATURE_PRECISION); // Defined in thingProperties.h initProperties(); // Connect to Arduino IoT Cloud ArduinoCloud.begin(ArduinoIoTPreferredConnection); /* The following function allows you to obtain more information related to the state of network and IoT Cloud connection and errors the higher number the more granular information you’ll get. The default is 0 (only errors). Maximum is 4 */ setDebugMessageLevel(4); ArduinoCloud.printDebugInfo(); last_time = millis(); } void loop() { ArduinoCloud.update(); // Your code here if (millis() - last_time > 600000) { // Get temperature from the pcb sensors_event_t event; dht.temperature().getEvent(&event); if (isnan(event.temperature)) { pcb_temp = -100.0; } else { pcb_temp = event.temperature; } /* Get Bin One Temperatures */ binOneSensors.requestTemperatures(); one_top = binOneSensors.getTempC(one_top_address); if (one_top == DEVICE_DISCONNECTED_C) { one_top = -100; Serial.println("Error"); } one_middle = binOneSensors.getTempC(one_middle_address); if (one_middle == DEVICE_DISCONNECTED_C) { Serial.println("Error"); one_middle = -100; } one_bottom = binOneSensors.getTempC(one_bottom_address); if (one_bottom == DEVICE_DISCONNECTED_C) { Serial.println("Error"); one_bottom = -100; } /* Get Bin Two Temperatures */ binTwoSensors.requestTemperatures(); two_top = binTwoSensors.getTempC(two_top_address); if (two_top == DEVICE_DISCONNECTED_C) { two_top = -100; Serial.println("Error"); } two_middle = binTwoSensors.getTempC(two_middle_address); if (two_middle == DEVICE_DISCONNECTED_C) { Serial.println("Error"); two_middle = -100; } two_bottom = binTwoSensors.getTempC(two_bottom_address); if (two_bottom == DEVICE_DISCONNECTED_C) { Serial.println("Error"); two_bottom = -100; } /* Get Bin Three Temperatures */ binThreeSensors.requestTemperatures(); three_top = binThreeSensors.getTempC(three_top_address); if (three_top == DEVICE_DISCONNECTED_C) { three_top = -100; Serial.println("Error"); } three_middle = binThreeSensors.getTempC(three_middle_address); if (three_middle == DEVICE_DISCONNECTED_C) { Serial.println("Error"); three_middle = -100; } three_bottom = binThreeSensors.getTempC(three_bottom_address); if (three_bottom == DEVICE_DISCONNECTED_C) { Serial.println("Error"); three_bottom = -100; } /* Get Bin Four Temperatures */ binFourSensors.requestTemperatures(); four_top = binFourSensors.getTempC(four_top_address); if (four_top == DEVICE_DISCONNECTED_C) { four_top = -100; Serial.println("Error"); } four_middle = binFourSensors.getTempC(four_middle_address); if (four_middle == DEVICE_DISCONNECTED_C) { Serial.println("Error"); four_middle = -100; } four_bottom = binFourSensors.getTempC(four_bottom_address); if (four_bottom == DEVICE_DISCONNECTED_C) { Serial.println("Error"); four_bottom = -100; } last_time = millis(); } }
The above code is the .ino part of the code, and the only edits that need to be made is the addition of your particular sensor addresses. Not adding the addresses will also work, but will probably have more unpredictable results.
Next is the thingProperties.h file where everything is configured. This file is automatically generated by Arduino if you are programming it through the browser.
// Code generated by Arduino IoT Cloud, DO NOT EDIT. #include <ArduinoIoTCloud.h> #include <Arduino_ConnectionHandler.h> const char THING_ID[] = ""; const char SSID[] = ""; // Network SSID (name) const char PASS[] = ""; // Network password (use for WPA, or use as key for WEP) float one_top; float one_bottom; float one_middle; float pcb_temp; float two_middle; float two_top; float two_bottom; float three_top; float three_middle; float four_bottom; float three_bottom; float four_top; float four_middle; void initProperties(){ ArduinoCloud.setThingId(THING_ID); ArduinoCloud.addProperty(one_top, READ, 900 * SECONDS, NULL); ArduinoCloud.addProperty(one_bottom, READ, 900 * SECONDS, NULL); ArduinoCloud.addProperty(one_middle, READ, 900 * SECONDS, NULL); ArduinoCloud.addProperty(pcb_temp, READ, 900 * SECONDS, NULL); ArduinoCloud.addProperty(two_middle, READ, 900 * SECONDS, NULL); ArduinoCloud.addProperty(two_top, READ, 900 * SECONDS, NULL); ArduinoCloud.addProperty(two_bottom, READ, 900 * SECONDS, NULL); ArduinoCloud.addProperty(three_top, READ, 900 * SECONDS, NULL); ArduinoCloud.addProperty(three_middle, READ, 900 * SECONDS, NULL); ArduinoCloud.addProperty(four_bottom, READ, 900 * SECONDS, NULL); ArduinoCloud.addProperty(three_bottom, READ, 900 * SECONDS, NULL); ArduinoCloud.addProperty(four_top, READ, 900 * SECONDS, NULL); ArduinoCloud.addProperty(four_middle, READ, 900 * SECONDS, NULL); } WiFiConnectionHandler ArduinoIoTPreferredConnection(SSID, PASS);
This one is using the MKR WiFi, but any MKR device will work and Arduino Cloud will change the correct code if you are using a different device. The next step will show you how to configure the device/thing and that will take care of thingProperties.h so don't worry too much about it.
-
4Configure your thing
First I would read this getting started document for the Arduino cloud: https://docs.arduino.cc/cloud/iot-cloud/tutorials/iot-cloud-getting-started.
Now as long as you have an Arduino account and the Arduino Create Agent installed you should be able to use the browser to complete the rest of the steps.
- Create a new thing
- Name it whatever you would like to call your monitoring device and continue.
- Create all 13 float variables
- I named the sensor on the pcb 'pcb_temp'.
- For the other float variables, I named them 'one_middle', 'one_top', and so on in that format.
- All of them are currently programmed to read every 15 minutes but that could be changed to whatever you like.
- The last thing to do is to fill out the secret tab with your specific network credentials. If using GSM you should check what your network provider requires.
I hope this part is clear enough, but I have a feeling I'll have to add more detail later.
- Create a new thing
-
5Get the Enclosure ready
I would now fasten the PCB board to the enclosure and also drill out a hole in three of the rubber stoppers so that the USB power cable and the monitoring cables can be inserted.
-
6Place cables in the bin
At the moment we are just using the wire with no protection, but later if it frays at the top of the bin we may add some sort of protection up there.
As for placement, we have tried to place the bottom one as close to the bottom as possible without hitting anything, and the top one deep enough so that it should be enveloped by lots of grain when the bin is full.
-
7Plug it in and start monitoring.
The last step is to attach the bin cable wire to the male end of the connectors and plug them in the correct spots. The Arduino can then be plugged in and everything should start reporting.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.