IoT Cookbook > Arduino Yun > Building Weighing Pads

Building Weighing Pads using the Yun

--- under construction ---

The Arduino Yun Weighing Pad component publishes data from a weighing pad component (see instructions for making these). It can publish both raw data and events when certain configurable thresholds are passed.

The sensor

The weighing pad sensor uses a type of plastic foil which changes resistance in reaction to pressure. It is a simple DIY project, consists of low-cost components, and can be made reasonably robust very easily.

Trying it out

Hardware

Using an Arduino XXX shield, here are step-by-step instructions:

--- add instructions for connecting the sensors --- --- ask Tobias ---

Software

The code for this can be found in the crossbarexamples GitHub repository under iotcookbook. You need to clone this (or download it as a ZIP file).

Open a shell in the component directory (crossbarexamples/iotcookbook/device/yun/weighingpad).

Start up Crossbar.io:

crossbar start

This also serves a frontend where you can view the weighing pad data logged at http://localhost:8080.

Configuration

In weighingpad_yun.js, add the URL of the machine on which Crossbar.io runs:

var connection = new autobahn.Connection({
    // replace with the url of your crossbar instance
    url: "ws://<URL OF YOUR CROSSBAR INSTANCE>/ws",
    realm: "iot_cookbook"
});

You need to set up the Yun for using AutobahnJS, including setting up Firmata on the MCU part of the Yun, and have at least one weighing pad connected.

The general configuration for the component is:

The configuration is in the config variable, and as a default raw data is published every 200 milliseconds.

The component has two main modes for sending sensor data:

With raw data, the component just sends the current sensor readings. If you have the component set to publish data only on value changes, then you additionally need to configure how big the value change has to be (on a per-sensor basis) to trigger the sending.

With changes in user-defined units, only a single unit value is transmitted which is determined by the component across all sensor readings. You provide training data, i.e. sets of sensor readings (like raw mode delivers) together with a value which these correspond to. The component then determines which which set the current readings are closest to and sends this change.

For creating the sets of sensor readings, you can use the wpadlab.

Once you've got things configured, transfer weighingpad_yun.js to the Yun, e.g. by doing

scp weighingpad_yun.js root@<IP of your Yun>:~/

in the component directory.

Then run the file on the Yun.

node weighingpad_yun.js

which should log something like

Arduino Yun Weighing Pads starting ...
Arduino connected (over /dev/ttyATH0, board version 2.3)
Connecting to router ...
/usr/bin/nodejs: '/usr/lib/node_modules/autobahn/node_modules/ws/node_modules/bufferutil/build/Release/bufferutil.node' is not an ELF file
/usr/bin/nodejs: '/usr/lib/node_modules/autobahn/node_modules/ws/node_modules/utf-8-validate/build/Release/validation.node' is not an ELF file
Router connected. Session ID: 1311074825864401
setting mode for pin 1
setting mode for pin 2
publishing:  { '1': 992, '2': 1001 }
...

In the above example, two weighing pads are connected (pins 1 & 2).

The API

The components publishes the current weighing pad data as an event io.crossbar.examples.yun.weighingpad.on_sample. The payload is an object, e.g.

{
   id: "yun1",
   samples: {
      1: 345,
      2: 999
   }
}

and the frequency of publication depends on the configuration.

To allow retrieval of the configuration, the component subscribes to io.crossbar.examples.yun.weighingpad.who_is_out_there and responds with a publication to io.crossbar.examples.yun.weighingpad.i_am_here which contains its configuration as the payload, e.g.

{
   id: "yun1",
   pins: [1, 2],
   frequency: 200,
   publishOnDifference: false
}

To change the configuration, the component registers a procedure, e.g. io.crossbar.examples.yun.weighingpad.yun1.configure which can be called with any subset of confguration values, e.g.

{
   id: "parkingSpace_01"
}

to change the ID contained in the values event to, and to which the yun responds to "parkingSpace_01". (This results in a de-registration and re-registration of the configuration procedure, which would now be reachable under io.crossbar.examples.yun.weighingpad.parkingSpace_01.configure.), or

{
   frequency: 10,
   publishOnDifference: true,
   difference: 100
}

which would switch the sending of events from a constant stream (at the sampling frequency) to events only sent when there are value changes which exceed the difference threshold (set here to 100), as well as setting a new sampling frequency.

--------------- Advanced version - work in progress ----------------

You can additionally configure

An example configuration is:

var config = {
   instance: "yun1",
   pads: [
      {
         pin: 1,
         type: continuous,
         frequency: 1000
      },
      {
         pin: 2,
         type: continuous,
         frequency: 50
      },
      {
         pin: 3,
         type: threshold,
         frequency: 1
         thresholds: {
            emtpy:  {
               min: 0,
               max: 5,
               duration: 1000
            },
            permanent: {
               min: 23,
               max: 100,
               duration: 1000
            },
            impulse: {
               min: 60,
               max: 100,
               duration: 0
            }
         }
      }
   ]
];

In the above configuration, the yun sending the data is identified by the instance name. Three weighing pads are connected.

The first weighing pad connected to pin 1 sends its current value every second (1000 ms), which is useful if you only need to check for more permanent pressure changes, e.g. whether a car is parked or not.

With the second pad, connected to pin 2 the sampling frequency is 50 ms, allowing more fine-grained detection of pressure changes.

For the third pad, connected to pin 3, events are produced if: the pressure is a value between 0 and 5% of the configured range and this persists for at least 1 second ("empty"), if the pressure is between 23% and 100% and this persists for at least 1 s ("permanent"), and if the pressure is above 60% for even a single sample ("impulse"). The sampling frequency for events is set to 1 ms.

--- do we need to configure a range per pad? test this! ---

If all you set is the pin, then the component defaults to continuous transmission with a sampling frequency of 100ms.

If you have a pad connected but do not wish to receive data or events for it, then set the type to none.

The configuration can be changed via WAMP calls during operation (see below).

Transfer weighingpad_yun.js on the Yun, e.g. by doing

scp weighinpad_yun.js root@<IP of your Yun>:~/

Then run weighingpad_yun.js

node weighingpad.js

This should log something like

Arduino Yun Weighingpad starting ...
Arduino connected (over /dev/ttyATH0, board version 2.3)
Connecting to router ...
Router connected. Session ID: 1595783623
...

Once this is running, open the browser console for the frontend page. You'll see data and evnets logged as they are received, e.g. for a single weighing pad at the default continuos transmission.

received weighingpad sample data: yun1, pin 1, value 2
received weighingpad sample data: yun1, pin 1, value 1
received weighingpad sample data: yun1, pin 1, value 2
...

The API

The component publishes two types of events: continuous sampling events and threshold events:

Sample events have the structure:

{
   instance: "yun1"
   pin: 1,
   value: 34
}

Threshold events have the structure:

{
   instance: "yun1"
   pin: 4,
   name: "impulse"
}

It also registers two procedures:

The call takes a dictionary of the same format as the config. As an example, assume the following dictionary were sent to an instance currently configured as "yun1" with the configuration listed earlier in this documentation:

var config = {
   instance: "my_yun_3",
   pads: [
      {
         pin: 1,
         type: none
      },
      {
         pin: 3,
         type: threshold,
         frequency: 1
         thresholds: {
            emtpy:  none,
            permanent: {
               duration: 500
            },
            transient: {
               min: 50,
               max: 100,
               duration: 50
            }
         }
      },
      {
         pin: 5,
         type: continuous,
         frequency: 1
      }
   ]
};

This accomplished the following changes:

Top

Assembly

Each Weighing Pad station consists of an Arduino Yun with 6 pluggable weighing pads, and each weighing pad has 2 pressure sensors and 1 RGB LED.

Conductive Plastic

We are using Linqstat Electrically Conductive Film for our pressure sensors.

We have settled on using a product from the LINQSTAT Mid-Level (<= 50,000 ohms/sq) Electrically Conductive Film (LINQSTAT MVCF S-Series).

The two products we considered are:

The vendor has the following to say: Which Linqstat product is right for pressure sensors?

In particular:

The thinner sheets are less sensitive to pressure changes than the thicker ones (because essentially by reducing the thickness, you increase the conductivity). The minimum thickness suitable for pressure sensors is 4mil, but the 6-mil and 8-mil thicknesses are more common for pressure sensors.

More information:

Copper Foil

It's critical that the copper foil used has an electrically conductive adhesive.

BOM

Total BOM: 180 Euro.

Connectivity

The 6 weighing pads are connected to the base station over 6 cables using Mini-DIN. Each cable has 6+1 poles: