Week 15

This is my 15th week at Fabacademy, this week I learnt about interface and application programming. This is the summary of the week assignment:

  • Group Assignment: Review and compare different software tools used for interacting with the physical world, focusing on serial communication and visualization. Each member explored various tools for hardware interaction.

  • Individual Assignment: Develop a thermometer simulation with a visual interface using Processing, where a servo motor’s angle is adjusted according to temperature data.

Group Assignment

For this assignment, we explored different tools related to programming and interaction between the digital and physical world. I worked with Scratch, Firefly, and MATLAB.

  • Scratch: A beginner-friendly visual programming language. I explored its platform and created a basic game. It helped me understand key programming concepts like loops and events without writing code.
  • Firefly: A plugin for Grasshopper that lets you connect devices (like Arduino) to digital models. I tested it by linking a temperature sensor to a servo motor and streaming real-time data into Grasshopper.
  • MATLAB: I used MATLAB to analyze accelerometer data and plot vibration patterns, especially useful for signal processing and data visualization.

This group task helped me explore various tools for different use cases such as education, prototyping, and technical computing.

Details can be seen on the group page: Group link

Individual Assignment

Servo

As I wanted to include in my final project a servo that moves according to ambient temperature, I decided to focus on creating an interface application about it in the software Processing. The temperature was visualized with a thermometer bar, and the servo angle was adjusted dynamically based on the incoming temperature data. The servo’s angle changes to simulate how a real-world temperature sensor might drive a mechanical needle. The brief explanation of the code and interface developed is as follows:

This Processing code visualizes a temperature value read from a serial port (e.g., from a sensor connected to an Arduino). It displays:

A dial that rotates like a gauge needle (servo style).

A vertical thermometer with a dynamic color (from blue to red) depending on the value.

A large text showing the temperature in degrees Celsius.

The needle angle and thermometer level adjust based on the received temperature, mapping the value between 20 °C and 30 °C.

The graphical user interface (GUI) in Processing is designed to represent a thermometer and display the temperature in a visually appealing way.

  • Thermometer Base:

A vertical rectangle is drawn to simulate the body of the thermometer. The base of the thermometer is centered on the screen.

The thermometer has a white fill and black border for a clean, simple design.

Here you can see the differnt parts of my design:

  • Mercury Simulation:

Inside the thermometer base, a smaller rectangle is drawn to simulate the mercury level. The height of this rectangle dynamically changes based on the temperature.

The map() function is used to map the temperature range to the height of the mercury, creating a visual representation of the temperature rising and falling.

  • Temperature Display:

The temperature value is displayed at the top of the screen in large text, along with the unit (°C).

The text changes color to indicate whether the temperature is increasing or decreasing.

Simulating the Needle (Servo Simulation)

A triangular shape is used to simulate the movement of a needle that would represent a physical thermometer’s mercury level. This needle rotates around the center of the screen as the temperature changes.

Needle Positioning and Rotation: The needle is positioned at the center of the screen, and its angle of rotation is determined by the temperature value.

The temperature value is mapped to an angle using the map() function, which adjusts the needle’s position based on the temperature data.

Here you can see an image of the parts of the resulting design:

And here the composition of both:

Here you can see the code I used in Processing:


import processing.serial.*;

Serial myPort;  // Serial variable declaration
String val = "25.0";  // Temperature value
float previousVal = 25.0;
float angle = 0;
float scale = 0.6;

PImage servoBase;

void setup() {
  size(400, 400);
  String portName = "COM2";  // Adjust the port name according to your setup
  myPort = new Serial(this, portName, 9600);  // Initialize the serial port
  delay(100);

  servoBase = loadImage("servo_base.png");
  imageMode(CORNER);  // Default coordinates
  ellipseMode(RADIUS);
  textAlign(CENTER);
}

void draw() {
  background(135, 206, 250);  // Light blue background

  if (myPort.available() > 0) {
    String input = myPort.readStringUntil('\n');
    if (input != null) {
      val = input.trim();
      println("Temp: " + val);
    }
  }

  // Convert the temperature value
  float temp;
  try {
    temp = float(val);
  } catch (Exception e) {
    temp = previousVal;
  }

  // Calculate angle based on temperature
  angle = map(temp, 20, 30, radians(-90), radians(90));  // Adjust temperature range
  
  float cx = width / 2;
  float cy = height / 2;

  // Draw the servo base image if needed
  image(servoBase, cx - 120, cy - 100, servoBase.width * scale, servoBase.height * scale);

  // Draw center circle (pivot)
  fill(255);
  stroke(0);
  ellipse(cx, cy, 15, 15);  // Enlarged circle

  // Draw triangle (needle) rotating around center
  pushMatrix();
  translate(cx, cy);  // Move origin to center
  rotate(angle);      // Rotate based on temperature

  fill(255);  // White needle color
  noStroke();

  // Larger triangle for the needle
  float base = 20;
  float height = 100;
  triangle(0, -height, -base, 0, base, 0);
  popMatrix();

  // Show temperature as text
  fill(0);
  textSize(32);
  text(nf(temp, 1, 2) + " ºC", width / 2, 50);

  // Draw thermometer
  drawThermometer(temp);

  previousVal = temp;
  delay(100);
}

// Function to draw the thermometer
void drawThermometer(float temp) {
  // Thermometer position
  float tx = 50;
  float ty = 120;
  float tw = 40;
  float th = 200;

  // Draw thermometer outline
  fill(255);
  stroke(0);
  rect(tx, ty, tw, th);

  // Dynamic thermometer color
  colorMode(HSB, 360, 100, 100);
  float H_color = map(temp, 20, 30, 220, 0);  // From blue to red
  fill(H_color, 80, 80);
  noStroke();

  // Draw mercury level based on temperature
  float h = map(temp, 20, 30, 0, th);  // Adjust height according to temperature
  rect(tx, ty + th - h, tw, h);  // Thermometer column
}

In the following video you can see the result of the implemented interface:

Download section and replication

Here you can get the developed code for implementation in processing along with the images of the GUI: interface_and_application_programming.