#smileMecca Project

  • Team:
  • Antonio Grillo //
  • Salvatore Di Benedetto //
  • Carlo Colella

Physical Representation of Sentiment Text Analysis

smileMecca aka Harvey, in tribute to Harvey Ross Ball who, in 1963, was the first artist that design a smiley face. This project is based on a physical representation of the sentiment state analysis of a query keyword. The system capture the keyword trought any device with a terminal connect to the same network of the host device; in my case I use a raspberryPi.

I use Sentiment140 API, a machine learning algorithm, to analyze the query keyword and receive a typical response as the polarity value:

  • 0: negative
  • 2: neutral
  • 4: positive


Hardware

Main body of Harvey is lasercutted 4mm plywood, with eyes and mouth in EVA (an elastomeric polymer that produces materials which are "rubber-like" in softness and flexibility). The custom parts for the movements are 3D printed.


  • Materials:
  • ABS - 120gr;
  • EVA (10mm thickness) - 300 x 100 mm;
  • Plywood (4mm thickness) - 600 x 400 mm
  • Electronic components:
  • A4988 stepper driver;
  • NEMA17 stepper motor;
  • 100uF 25V Capacitor;
  • Raspberry Pi;
  • 12V powersupply for NEMA17;
  • some wires

You can Download all the files for 3D printing and Laser Cutting.


After having produced and mounted all the parts you can follow this connections:

  • connect the NEMA17 to the A4988 driver (@ pin 1B 1A 2A 2B)
  • connect the GPIO19 to DIR pin on A4988
  • connect the GPIO26 to STEP pin on A4988
  • connect the Vmot on the A4988 to the 12V positive cable from the powersupply
  • connect the GND from the power to the A4988
  • connect the 100uF capacitor between + and gnd of the 12V powersupply
  • connect the Vin and GND from raspberry GPIO to the A4988

Software

For this project I and Salvatore have write some bit of code in Python for use Sentiment140 API and make a simple GET request to the server. When the code receive the response "200" from Sentiment140 the software parse the JSON data for give us the "polarity" relative to the keyword. At this point a part of SW convert the polarity in the right steps for the movement.

Code:

# coding=utf-8

import sys
import RPi.GPIO as gpio
import time
import requests
import json

# Opzioni controllo motore
stepUp = 2000 # Posizione in step per espressione triste
stepDwn = -2000 # Posizione in step per espressione sorridente
setpNeuter = 0 # Posizione in step per espressione neutra
WaitTime = 0.001


# API Sentiment140
url = "http://www.sentiment140.com/api/bulkClassifyJson"

# ====================== Funzioni di controllo motore ======================= #

gpio.setmode(gpio.BCM)
gpio.setwarnings(False)

gpio.setup(19, gpio.OUT)
gpio.setup(26, gpio.OUT)


def move(targhetStep):

	# StepCounter mi serve globale in maniera che gli aggiornamenti siano 
	# visibili esternamente.
	global StepCounter

	# Muovo il cursore verso l'alto
	if StepCounter < targhetStep:
		gpio.output(19, True)

		while StepCounter < targhetStep:
			#turning the gpio on and off tells the easy driver to take one step
			gpio.output(26, True)
			gpio.output(26, False)

			StepCounter += 1

			#Wait before taking the next step...this controls rotation speed
			time.sleep(WaitTime)

	# Muovo il cursore verso il basso
	elif StepCounter > targhetStep:
		gpio.output(19, False)

		while StepCounter > targhetStep:
			#turning the gpio on and off tells the easy driver to take one step
			gpio.output(26, True)
			gpio.output(26, False)

			StepCounter -= 1

			#Wait before taking the next step...this controls rotation speed
			time.sleep(WaitTime)

#	gpio.cleanup()	


# ====================== Funzioni richiesta/Impiego sentiment ================ #

def negative():
	print "Negative"
	move(stepUp)

def positive():
	print "Positive"
	move(stepDwn)

def neutral():
	print "Neutral"
	move(setpNeuter)

polarityOpt = {	0 : negative,
				2 : neutral,
				4 : positive,
}

# ====================== Ciclo principale ======================= #
if __name__ == '__main__':

	StepCounter = 0
	print "Posizine del cursore: ", StepCounter

	while True:
		keyword = raw_input("Inserisci la keyword:")

		data = "{'data': [{'text': '"+keyword+"'}]}"

		r = requests.post(url, data)

		print(r.status_code)

		reqResult = r.json()

		polarity = reqResult["data"][0]["polarity"]

		polarityOpt[polarity]()

		print "Posizine del cursore: ", StepCounter

Remember to calibrate the mouth in Neutral position with "calibra.py", before you launch the main SW.

After download the software and calibrate the mouth in the middle, you can launch "smileMecca.py".

$ cd smileMecca/SW/
$ sudo python smileMecca.py

Posizine del cursore:  0
Inserisci la keyword:i love fablabnapoli
200
Positive
Posizine del cursore:  -2000
Inserisci la keyword:i hate fablab napoli
200
Negative
Posizine del cursore:  2000
Inserisci la keyword:fablab
200
Neutral
Posizine del cursore:  0
Inserisci la keyword:

Enjoy with Harvey!!

And this is the screenshot of the terminal that you saw on the video, while I was doing some test with Harvey.