The Really Smart Box platform turns a Really Useful Box (tm) into an intelligent, internet connected storage box for stock monitoring. Based on the Sigfox Arduino MKR FOX 1200 it senses the weight of things stored in the box, along with temperature and humidity and uses the low power Sigfox radio to relay this information.
Use Case - 3D Printer Filament Storage:If you own a 3D printer you will most likely care about how your filament is stored, this is true not only of printer filament but many other things need to be stored within acceptable temperature and humidity ranges (for example painters caulk may become unusable if exposed to below freezing temperatures).
As one of the people responsible for maintaining the 3D printers in my local maker space, I need to ensure we have sufficient stock of filament and that it is kept dry.
With the Really Smart Box I am able to monitor the weight of the filament and so know if we were getting low, along with the monitoring the humidity level in the box to tell if the silica gel needs replacing.
A cleaning contractor may wish to keep a stock of air freshener, hand soap or other consumables at a clients site, the client would likely not allow the contractor WiFi access or to power a device like this when not present, however the contractors company needs to know when to send in new stock, adding overhead to the cleaners time and extra paperwork that nobody likes.
The Really Smart Box platform simply drops into a storage box, because it uses Sigfox it does not need to connect to the clients network and is low power so runs from a set of batteries. As the contents of the box would change very infrequently the Arduino can be held in a low power state for most of the time helping to extend the battery lifetime.
The platform can be told the weight of the item type stored in the box (i.e. the air fresheners) and hence calculate how many are in the box. This can then be sent to the cleaning contractors company to alert them when they need more stoke to be delivered to the clients site.
The platform is of simple construction, the main body is made from two pieces of laser cut acrylic (I used 3mm, thicker would be better for heavy items like printer filament) with a pair of load cells between them.
I manually counter sunk the screw holes for the load cell to give a nicer finish, I have as yet to find a laser cutter that does countersinking!
The acrylic can be cut to any size to match the box you like, however watch of positioning of the load cells and the length of wire on these as it's fairly short. The upper acrylic sheet is slightly smaller than the lower to ensure it doesn't snag on the box sides.
The lower sheet has a cutout to allow the electronics to be mounted to the acrylic without spacers and have the soldered device legs poking through. I used a M3 tap on the corner sections of the cutout to directly bolt the PCB to it. 3D printed feet were also fitted at the corners to sure that any screws from the load cell that were not flush with the acrylic did not affect the balance.
The weight is sensed using two 5Kg load cells. A set of 4 is normally used in bathroom scales and this might have be better, however I couldn't find a nice way to fix them to the acrylic as well as provide the spacing required for the electronics.
The load cells need some padding top and bottom to allow for a little flexing and the actual strain gauge sensors (the white bit in the picture) of the load cell are fatter than the mounting block. This is achieved under the load cell with the two "Really Smart Box" 3D Printed end plates which have a small block to raise the load cell up, on the top of the load cell are some laser cut acrylic padding blocks.
The load cells are connected to a HX711 load cell amplifier. This has two channels (A and B) that can be selected which is perfect for this use.
Each load cell is constructed of strain gauges in a Wheatstone bridge configuration, this creates an unbalanced pair of potential dividers, when the load cell is placed under load, the resistance of the strain gauges change and hence a difference between the two potential dividers is created, this is amplified and measured by the HX711 which performs the analog to digital conversion for us.
I've used two 5kg load cells for this project, you can get different ratings (e.g. 1kg and 10kg) which work exactly the same but with different sensitivity.
When placing the load cells ensure that the arrow on the end of the cell is pointing down (in the direction of the load). The cells have M5 tapped holes at one end (generally the fixed end) and M4 the other (the side you place the load on.
The red/black wires are power, this feeds top and bottom of the potential dividers and is shared between the two load cells. Green and white are the sense wires from the middle of the potential dividers, these are connected to Channel A and B on the HX711.
The HX711 supports 3 gain factors, however these are also used for channel selection. Gains of 128 and 64 are available on the A channel, where as selecting a gain of 32 selects the B channel. this means our second channel will not be as sensitive as the main channel, this is fine for this application.
The HX711 can be connected to any digital pins on the Arduino, I've used D0 (Data) and D1 (Clock), then the amplifier just needs to be connected to the Arduino's 3v3 supply.
You can read more about load cells and the HX711 at SparkFuns excellent load cell tutorial.
Finally a BME280 is connected to the I2C bus and used to sense the temperature and humidity inside the box, this can also be used to sense pressure however this is probably of little interest and we only have 12 bytes of sigfox data to play with so it's not reported.
The electronics is mounted on a ThingySticks Arduino Prototype board, I added a battery holder (hot melt glued to the lower acrylic sheet) and connected the aerial which is of a nice flat design so worked perfectly for the platform.
Before we can use the platform the load cells need calibrating. Each load cell is unique, it is made by attaching strain gauge to a block of metal and holes drilled in it to provide sufficient flexing that can be sensed without it snapping, because of this we need to calibrate each load cell for its response to weight.
Once calibrated we apply the y=mx+c equation to the measured ADC value (x) to get the actual weight (y). So we need to find c (the offset) and m (the slope) for our load cell.
I removed the main platform top and attached a small acrylic square to each load cell in turn, and monitored the measured values (theirs a routing in the firmware to do this which can be started by sending a "c" to the serial port.
Initially the reading for an empty platform was measured, this gives the offset (c) value, then placing a load of known weight on the cell, the difference in readings gives us the slope.
Slope = (measured - offset) / weight (g).
I used both a small air freshener can (ca. 230g) and a spool of printer filament (ca. 1.5kg) to check the values, both gave about the same slope which was reassuring.
Naturally the offset measured with the small acrylic pad is different to that experienced with the full top sheet, likewise their is also a small slope difference when using both load cells so a secondary calibration is needed. For now a one point zero offset (tare) is used, this is set in the firmware but can also be set using the USB serial connection or through a Sigfox downlink message once deployed.
Sigfox Connection:With the Really Smart Box wire up I initially used the USB serial port to monitor the output to help debug and tune the system. This way you can see the individual load cells, changes and noise. However this isn't going to work for a deployed box as it needs to be totally wireless.
With Sigfox we can send 12 bytes of data upto 140 times a day to our online service, this is more than enough for the Really Smart Box. The below data structure is used in the Arduino describes how we use the 12 bytes.
typedef struct __attribute__ ((packed)) sigfox_message {
uint8_t status; // status flags
int8_t humidity; // humidity::int:8 - some sensors (HTU21D) read -ve humidity)
int8_t temperature; // temperature::int:8 (no decimal places).
int16_t zeroWeight; // zeroWeight::int:16:little-endian
int16_t weight; // weight::int:16:little-endian
int16_t itemCount; // itemCount::int:16:little-endian (100x actual item count to allow for 2.01 (as weight won't match exactly)
int8_t driftCorrection; // Drift Correction for changes in zero weight applied to the scales.
int8_t filler; // Nothing to see here, move along....
int8_t lastStatus; // Last sigfox status
} SigfoxMessage;
The first byte (status) is split into bit flags to indicated issues:
// status::uint:8 -> Split to 8 bits
// B7 - First run
// B6 - HX711 fault
// B5 - BME280 fault
// B4 - Temperature alarm
// B3 - Humidity alarm
// B2 - Weight alarm
// B1 - Low stock
// B0 - spare
This structure compacts down to 12 bytes, however we need to unpack it at the Sigfox end to push onto Tinamous. We use a Custom Payload Configuration for that and it's best to work this out as the data structure is defined. Ours is:
firstRun::bool:7 hx711Fault::bool:6 bmeFault::bool:5 temperatureAlarm::bool:4 humidityAlarm::bool:3 weightAlarm::bool:2 lowStock::bool:1 b0::bool:0 status::int:8 humidity::int:8 temperature::int:8 zeroWeight::int:16:little-endian weight::int:16:little-endian itemCount::int:16:little-endian
The custom payload splits our 12 bytes down as it is parsed.
Note that we need to specify the little-endian nature of anything larger than 1 byte as Sigfox defaults to big-endian and the Arduino uses little-endian (i.e. the least significant byte is first in multi-byte words).
Also note that splitting out the boolean flags in the first byte doesn't progress the byte marker as it does with all other reads so the status byte which holds all the flags is also read to skip over the first byte.
Included in the flags are temperature, humidity and weight range alarm flags, we could use an online service (i.e. Tinamous) to monitor for out of range temperature,humidity and weight, however these may be short lived (a few hours) and our box may be sending infrequently (once or twice a day) the resulting possible damaging environmental condition could easily be missed, so they are flagged on the device and sent (and reset after a successful send).
The item count is actually set to 100 times the actual item count. I wanted to allow for values such as 2.2 items (due to weight error or other items in the box) without forcing a rounding, likewise 2.95 might be rounded down to 2 if we are not careful and it would be more suggestive of 3 items in the box and a small error. I also didn't want to use a float which would require more space so I've used a 16 bit word and applied a factor to allow easy conversion (it's also signed to allow for a zero error, which might result in a stock level of -1 or -2 etc.).
Very little needs to be done to enable Sigfox communication. Within the Arduino the Sigfox library is added and appropriate functions called to push the data out as per the Arduino examples for the Sigfox library, however we need to register our device with Sigfox.
Sending an "s" to the serial port of the Really Smart Box prints the Sigfox ID and PAC code, these are used to activate the device at the Sigfox backend. We then head over to the Sigfox backend activation service and follow the wizard, first selecting our device, then country/provider and then some details.
And finally our device is activated and listed:
Sigfox assigns devices to Device Type grouping which is sensible as you may normally have many (hundreds, thousands, etc.) of the same device type which you wish to act on as a group. With the Device Type defined we can configure a custom callback to push the data we've received to our online service. I'm using Tinamous for this (hint: see my profile name - I might be biased in my selection).
Using the Really Smart Box:Once wired up, bolted together, firmware flashed and batteries fitted the platform is simply dropped into a Really Useful Box (tm) and ready to go.
Power should be applied as late as possible as once the device is powered up it will send the first Sigfox message after 2 minutes and request downlink data with it. This data can include a "Zero" command to zero the platforms weight. Failing this either a USB serial connection is needed or waiting for the next downlink request - these are made every 12 hours.
Once up and running the platform will publish Sigfox messages every 15 minutes to send the weight, item count, temperature, humidity and alarm states. Temperature, humidity and weight are measured every minute to ensure these are not out of range with alarms being flagged for the next transmission if they have been raised.
Monitoring With Tinamous:Tinamous supports Sigfox custom callbacks by adding a "Sigfox Bot" to our account, for instructions on how to do that please see my "Get Your Sigfox On" Hackster.io tutorial.
When add a Sigfox Bot to your Tinamous account, if you include the API settings, the Sigfox Bot will lookup your devices and add them to your Tinamous account, however you don't need to do this as the device will be automatically added when data is published.
When you've added the Bot we are be presented with a Callback configuration screen to help set-up the Sigfox Callbacks.
You can then create a custom callback at Sigfox, note that the Really Smart Box uses DATA -> BIDIR callback which handles the normal UPLINK callback and the BIDIR (up and downlink) callbacks.
This is where the custom payload from before comes in handy, paste this from the source code into custom payload and update the fields section to reflect this.
Lat and Lng are specified in this callback which gives an approximate location, however Sigfox on the Arduino supports improved location setting, but this needs a second callback. If you use the Geo location facility don't specify the Lat/Lng in this message as the Really Smart Box will appear to be moving between locations.
Once this is configured it also needs to be enabled for Downlink, this is disabled by default even though the BIDIR was set.
Note the screenshot below the Downlink option is "checked", this has to be done manually, and may not be available if the Device Type has not been set to "CALLBACK" for downlink data (Device Type -> Edit -> Downlink Data).
With a Downlink callback we also want to specify a SERVICE -> ACKNOWLEDGE callback to know our device has received the downlink data. By clicking on the Sigfox Bot in Tinamous other callback configurations are shown, follow the instructions for the ACKNOWLEDGE and GEOLOC callbacks.
Note that you need to copy the authorization header from the first uplink/bidir callback as this is a password that is one-way encrypted in Tinamous an no longer available for display.
With our callbacks in place the data published by our device should now be being sent to Tinamous. We could also add email callbacks at Sigfox which may help confirm the data is coming through (but can also get very noisy very quickly).
Configuring the Tinamous Device:Once the Sigfox device has been seen at Tinamous (either through the api lookup or a callback), it will be shown on the Devices page, from here we can edit the properties. Fields are automatically added as they come from the Sigfox callback so it's best to wait until the device is publishing data.
I set the "Not Reporting After" time to 1 hour (It currently publishing every 15 minutes) so I can tell if the device has is broken and optionally get notified about this.
I didn't want to see all the fields sent by the device on the chart/details page (their's a lot if you include all the flags), so Tinamous is configured only to show weight and item count. Human friendly labels and units were also applied here.
The Item Count field is 100x the actual item count, so a calibration is applied to that field to reduce it 100 fold.
Some downlink data is set that will cause the Really Smart Box to zero and apply temperature and humidity range limits when it next requests a downlink message (2 minutes after power on, then once every 12 hours).
Now the device fields are configured we can monitor them through the device details page (Note I'd not zero'd the platform at this time, hence it thinks 1/2 a unit is present - I also replaced the acrylic top with a 5mm version which is heavier but will handle printer filament better).
We can also see the Sigfox callback interactions from the Sigfox section. Notice here that the downlink data is being sent and acked however the Arduino is reporting an error. More on that at the end.
On the Location tab we can also see where our Really Smart Box is, which might be useful if you forget which customer it's at, or if it's in a van.
And naturally we want a nice dashboard view of our Really Smart Box, the one below shows the box contents weight, the estimated units in it, and a count of devices that are not reporting so we can tell if one is broken.
Next I set-up Tinamous to send an email and sms when the item count is low. I did this by specify a working range of 3 - 300 for the item count field. If the value is outside of this range a measurement out of range even is raised.
Adding a Notification to Tinamous we can be notified when that happens.
We could specify just the field we're interested in, but leaving this empty gives us notifications for any field that is out of range.
Likewise for devices, leave it blank for all devices (i.e. the only one we've got at present!)
Set the Repeat Notifications to trigger once only, until it is reset (every day), otherwise notifications every 15 minutes gets annoying very quickly!
Then select how to be notified, I set it for email and sms then create the notification:
I can now deploy the Really Smart Box and (hopefully) forget about it. When the stock level gets low I'll be notified and I can check on the dashboard to see how it is doing. Using Sigfox I don't have to worry about powering the device other than an occasional battery change and no WiFi set-up on site is required making deployment extremely simple.
I'm planning to deploy this unit into one of our filament storage boxes in Cambridge Makespace to monitor filament stock levels.
Needless to say this isn't a production quality finished project, a few issue still need to be resolved:
Sigfox Downlink:
Sigfox allows for 4 messages a day to be send in response to a uplink message. The Really Smart Box uses these to allow for re-zeroing of the scales, setting upper and lower temperature and humidity ranges and the item weight. However whilst trying to get this to work, even though the downlink message appears to be getting sent and is being acked (as shown in the Sigfox backend) the Arduino is reporting a status error of 62, which doesn't map to any error flag conditions listed for the ATA8520 chip, digging into the drivers the command uses a request for downlink that is also not listed in the data sheet, so some more investigation needs to be done.
Debug Only:
Running the Sigfox communications with debug disabled causes the low power setting of the Arduino to be activated with kills the USB serial port.
Low Power Mode:
As described for the Sigfox debug setting, using the Arduino's Low Power library causes the USB serial to drop off so this is not enabled at this time.
Drift:
No compensation for drift has been added, no doubt the load cells will drift when held under constant load.
Noise / Non Vertical Measurements:
It's possible the Really Smart Box may be in the back of a van (e.g. mobile cleaner, carpenter, plumber etc). It would be good to add an accelerometer to the platform and skip measurement cycles when the box is not steady, likewise if the box is not vertical the weight will not go through the load cells as expected.
Comments