Introduction: The Fruitine

The Fruitine is a project that started in the course Physical Interaction Design and Realisation at KTH university with the aim of designing and building an interactive device that achieves any positive change. In this case, making people eat more fruit in their daily basis.

The Fruitine consists of two main parts: the bowl where the fruit is going to be stored and a small standalone reminder to place it wherever the user wants.

Under the bowl, a set of 4 load sensors are measuring constantly the weight of the bowl so the system will be able to control if the user took any piece of fruit for a period of time. If the user did no take any piece of fruit for a certain period (can be configured), both the bowl and the reminder will break a pattern that they have drawn on their surfaces.

The idea of breaking a pattern came from the fact that we wanted the interaction between the user and the system to be as less intrusive as possible. This 'breaking pattern' effect is based on the fact that our brain likes order, symmetry, self-repeating patterns, perfect alignments, and intuitive placement. However, as soon as those patterns are broken, the brain is going to realise about it without paying too much attention. Subconsciously.

Magnus, Rebecka, Judith and Elena.

Step 1: Fruitine Project Components

Components:

  • RGB LEDs x 2
  • Servo motor SG90 x 2
  • Jumper wires
  • Weight sensors x 4
  • Amplifier for load cells HX711
  • Arduino MKR WiFi 1010
  • Adafruit Feather HUZZAH ESP8266
  • Rechargeable batteries (750mAh and 1500mAh) for the reminder and the bowl
  • Wooden bowl

Step 2: WiFi Connectivity Client - Server Mode

For the connection between the reminder and the bowl we implemented a WiFi connection with a "client-server model".

The reminder is going to be a server and an access point at the same time. I.e, the server will create its own network to which the client will be connected. We used for the reminder the Adafruit Feather Huzzah ESP8266 module.

The bowl is going to be a client connected to the reminder's network. We used for the client the Arduino MKR WiFi 1010.

Between them they will communicate with the HTTP protocol. The client (bowl) will send HTTP requests to the server (reminder) and depending on the kind of requests, the server will perform one action or another(*).

In our specific system, the client has the 4 load sensors always measuring the weight of the bowl. As soon as the user takes a piece of fruit, the weight is going to change and the client will send an HTTP request to the server. The server will perform different actions(*):

  • Switching on the RGB LEDs if the bowl is empty.
  • Switching off the RGB LEDs if the bowl is refilled.
  • Running the servo motor that will break the pattern if the user didn't take any fruit for a while.
  • Running the servo motor to set the pattern back to its right position if the user took a fruit.

This is the Access Point and Server code implemented in the reminder:

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>

#ifndef APSSID
#define APSSID "ESPap"
#define APPSK  "ESpap123"
#endif

/* Set these to your desired credentials. */
const char *ssid = APSSID;
const char *password = APPSK;

ESP8266WebServer server(80);

void initWifi() {
  Serial.print("Configuring access point...");
  /* You can remove the password parameter if you want the AP to be open. */
  WiFi.softAP(ssid, password); 
  IPAddress myIP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(myIP);
}

void initServer() {
  server.begin();
  Serial.println("HTTP server started");
}

void listenClient() {
  server.handleClient();
}

/* Just a little test message.  Go to 192.168.4.1 in a web browser
   connected to this access point to see it.
*/

void handleRoot() {
  server.send(200, "text/html", "You are connected");
}

This is the wifi.h code implemented in the bowl, it means the code where the client is connecting to the server and sending HTTP PUT requests. THE FULL SYSTEM CODE IS IN THE FINAL STEP.

#include <SPI.h>
#include <WiFiNINA.h>
#include "arduino_secrets.h"

///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID;        // your network SSID (name)
char pass[] = SECRET_PASS;    // your network password (use for WPA, or use as key for WEP)

int status = WL_IDLE_STATUS;
bool isConnectedToServer = false;

// Initialize the Wifi client library
WiFiClient client;

// server address:
IPAddress server(192, 168, 4, 1);
unsigned long lastConnectionTime = 0;            // last time you connected to the server, in milliseconds
const unsigned long postingInterval = 10L * 80L; // delay between updates, in milliseconds

bool isReconnecting() {
  return (millis() - lastConnectionTime > postingInterval);
}

void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

// print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

// print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

void initWifi() {
  if (!isConnectedToServer) {
    // check for the WiFi module:
    if (WiFi.status() == WL_NO_MODULE) {
      Serial.println("Communication with WiFi module failed!");
      isConnectedToServer = false;
      // don't continue
      while (true);
    }
// attempt to connect to Wifi network:
    while (status != WL_CONNECTED) {
      Serial.print("Attempting to connect to SSID: ");
      Serial.println(ssid);
      // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
      status = WiFi.begin(ssid, pass);
      // wait 10 seconds for connection:
      delay(10000);
    }
    printWifiStatus();
    isConnectedToServer = true;
  }
}

void stopConnection() {
  client.stop();
}

void connectAndSendData(String url) {
  // if there's a successful connection:
  if (client.connect(server, 80)) {
    Serial.println();
    Serial.println("connecting...");
    // send the HTTP PUT request:
    client.println(String("GET ") + url + " HTTP/1.1");
    client.println("Host: 192.168.4.1");
    client.println("User-Agent: ArduinoWiFi/1.1");
    client.println("Connection: close");
    client.println();

    // note the time that the connection was made:
    lastConnectionTime = millis();
  } else {
    // if you couldn't make a connection:
    Serial.println("connection failed");
  }
}

Step 3: Design the External Reminder (server)

The external reminder is a small device that can be placed wherever the user thinks that it will be useful to get reminded that he/she might eat fruit. It has to be easily portable. Our recommendation is to place it next to the food we might avoid such as chocolate or sugary food or next to the exit door so every time the user is going to live its apartment, is going to be reminded to take a fruit.

The external wooden design was made with a laser cutting machine and playwood of 4 mm thickness. The code is on the Github repository (next step).

The components (from Step 1) inside it are:

  • Adafruit Feather HUZZAH ESP8266
  • RGB LEDs x 2
  • Servo motor SG90 x 1
  • Rechargeable battery (750 mAh)

Step 4: Design the Bowl

    The configuration of the load sensors is the one shown in the picture. The information coming from the sensors will be send to the Arduino MKR WiFi 1010 and the Servo motor.

    The Arduino MKR WiFi 1010 is the one running the client code sending to the server the actions of lighting on the LEDs or breaking the reminder pattern.

    The servo motor placed on the bowl will break the pattern in the bowl. Therefore, we will have two patterns being broken, one in the reminder and another one in the bowl.

    Components below the bowl (from Step 1) are:

    • Arduino MKR WiFi 1010
    • Load/weight sensors x 5
    • Amplifier for load cells HX711
    • Rechargeable battery 1500 mAh
    • Servo motor SG90

    Step 5: Full Code - Arduino

    Find out the whole project code here: Github Fruitine