15. Interface and application programming¶
1. Arduino Serial Communication – Basic Control¶
To begin with, I used the Arduino IDE to perform basic serial communication. I connected three LEDs to a board I designed during the Input/Output week. Using simple serial commands sent from the Serial Monitor, I could:
- Turn ON/OFF individual LEDs by typing commands like
LED1_ON
,LED2_OFF
, etc. - Control all three simultaneously with multi-command inputs.
// Define LED pins
const int led1 = 26;
const int led2 = 27;
const int led3 = 28;
void setup() {
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
Serial.begin(9600);
Serial.println("Send commands like: LED1 ON");
}
void loop() {
if (Serial.available()) {
String command = Serial.readStringUntil('\n');
command.trim();
if (command == "LED1 ON") digitalWrite(led1, HIGH);
else if (command == "LED1 OFF") digitalWrite(led1, LOW);
else if (command == "LED2 ON") digitalWrite(led2, HIGH);
else if (command == "LED2 OFF") digitalWrite(led2, LOW);
else if (command == "LED3 ON") digitalWrite(led3, HIGH);
else if (command == "LED3 OFF") digitalWrite(led3, LOW);
else Serial.println("Invalid command");
}
}
This was a straightforward and effective way to test basic communication between a PC and microcontroller using Serial.print() and Serial.read()
functions.
2. Processing IDE – Graphical User Interface¶
I used Processing IDE to create a simple GUI for serial control:
- Six buttons control ON/OFF states for three LEDs.
- Clicking a button sends a command to the Arduino.
Arduino Code:
const int led1 = 26;
const int led2 = 27;
const int led3 = 28;
void setup() {
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
Serial.begin(9600);
}
void loop() {
if (Serial.available()) {
String command = Serial.readStringUntil('\n');
command.trim();
if (command == "LED1 ON") digitalWrite(led1, HIGH);
else if (command == "LED1 OFF") digitalWrite(led1, LOW);
else if (command == "LED2 ON") digitalWrite(led2, HIGH);
else if (command == "LED2 OFF") digitalWrite(led2, LOW);
else if (command == "LED3 ON") digitalWrite(led3, HIGH);
else if (command == "LED3 OFF") digitalWrite(led3, LOW);
}
}
Processing Code:
import processing.serial.*;
Serial myPort;
Button[] buttons = new Button[6];
String[] labels = {
"LED1 ON", "LED1 OFF",
"LED2 ON", "LED2 OFF",
"LED3 ON", "LED3 OFF"
};
void setup() {
size(400, 300);
println(Serial.list());
myPort = new Serial(this, Serial.list()[2], 9600);
for (int i = 0; i < 6; i++) {
buttons[i] = new Button(50 + (i % 2) * 150, 50 + (i / 2) * 70, 120, 50, labels[i]);
}
}
void draw() {
background(240);
for (Button b : buttons) {
b.display();
}
}
void mousePressed() {
for (Button b : buttons) {
if (b.isClicked(mouseX, mouseY)) {
myPort.write(b.label + "\n");
println("Sent: " + b.label);
}
}
}
class Button {
float x, y, w, h;
String label;
Button(float x, float y, float w, float h, String label) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.label = label;
}
void display() {
fill(200);
rect(x, y, w, h);
fill(0);
textAlign(CENTER, CENTER);
text(label, x + w/2, y + h/2);
}
boolean isClicked(float mx, float my) {
return mx > x && mx < x + w && my > y && my < y + h;
}
}
Input Device Interface¶
I added a Hall effect sensor interface with a real-time bar visualization in Processing.
Arduino Code:
const int sensorPin = A0;
void setup() {
Serial.begin(9600);
}
void loop() {
int sensorValue = analogRead(sensorPin);
Serial.println(sensorValue);
delay(10);
}
Processing Code:
import processing.serial.*;
Serial myPort;
int sensorValue = 0;
void setup() {
size(500, 200);
println(Serial.list());
myPort = new Serial(this, Serial.list()[2], 9600);
myPort.bufferUntil('\n');
}
void draw() {
background(255);
fill(0);
textAlign(CENTER);
text("Hall Sensor Slider", width / 2, 30);
float mappedWidth = map(sensorValue, 0, 1023, 0, width - 60);
fill(220);
rect(30, 100, width - 60, 30, 10);
fill(0, 150, 255);
rect(30, 100, mappedWidth, 30, 10);
fill(0);
textAlign(LEFT);
text("Value: " + sensorValue, 30, 90);
}
void serialEvent(Serial p) {
String input = p.readStringUntil('\n');
if (input != null) {
input = trim(input);
if (input.length() > 0) {
sensorValue = int(input);
}
}
}
3. Robot Operating System (ROS) – Advanced Real-Time Interaction¶
a. IMU Visualization in ROS¶
I followed this tutorial: automaticaddison.com – BNO055
- Used Arduino with BNO055 to publish quaternion orientation data to ROS.
- Visualized in RViz for real-time movement tracking.
Arduino Code:
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <ros.h>
#include <sensor_msgs/Imu.h>
Adafruit_BNO055 bno = Adafruit_BNO055(55);
ros::NodeHandle nh;
sensor_msgs::Imu imu_msg;
ros::Publisher imu_pub("imu/data", &imu_msg);
void setup() {
nh.initNode();
nh.advertise(imu_pub);
if (!bno.begin()) {
while (1);
}
delay(1000);
}
void loop() {
imu::Quaternion quat = bno.getQuat();
imu_msg.orientation.w = quat.w();
imu_msg.orientation.x = quat.x();
imu_msg.orientation.y = quat.y();
imu_msg.orientation.z = quat.z();
imu_msg.header.stamp = nh.now();
imu_msg.header.frame_id = "imu_link";
imu_pub.publish(&imu_msg);
nh.spinOnce();
delay(10);
}
b. Robot Arm Control (Hardware-in-the-Loop)¶
Tutorials used:
- How to Control a Robot Arm with ROS
- DIY Arduino Robot Arm
- Synchronized real robot arm and virtual arm model using ROS.
- Used joint state publishers and real-time inputs to simulate and control motion.
This was a great example of hardware-software integration using ROS and real-time feedback systems.
4. MIT App Inventor¶
MIT App Inventor is a free, web-based visual programming tool developed by the Massachusetts Institute of Technology (MIT). It enables users to build Android (and limited iOS) apps without writing traditional code.
Key Features¶
- Block-based coding: Uses drag-and-drop blocks for logic, ideal for beginners.
- Designer & Blocks Editor:
- Designer: Create the app’s user interface.
- Blocks Editor: Define behavior using logic blocks.
- Real-time testing with the MIT AI2 Companion app.
- Built-in components: Buttons, sensors, media, databases, connectivity (Bluetooth, Web), and more.
Educational Use¶
- Widely used in schools to teach programming, logic, and mobile app development.
- Supports STEM learning and global innovation challenges.
Pros¶
- Easy to use and beginner-friendly.
- Great for rapid prototyping.
- No installation needed (runs in the browser).
Limitations¶
- Limited support for iOS.
- Not ideal for complex or high-performance apps.
MIT App Inventor empowers anyone to create mobile apps, especially useful in education, innovation, and social impact projects.
How to Use MIT App Inventor¶
- Go to the Website
- Visit https://appinventor.mit.edu
- Sign In
- Click “Create Apps”
- Sign in with a Google account
- Start a New Project
- Click “Start new project”
- Enter a name (e.g.,
Test
)
- Design the Interface
- Drag components (buttons, labels, etc.) from the Palette to the Viewer
- Customize them in the Properties panel
Here, we add a button and a text box.
- Add Functionality
- Switch to the Blocks Editor
- Drag and connect logic blocks to define app behavior (e.g., what happens when a button is clicked)
When the button is pressed, it will turn green and display the text “Button Pressed.”
- Test the App
- Download the MIT AI2 Companion App on your phone
- Scan the QR code shown in the browser to live test your app
- Save or Export
- Save your project online automatically
- Use “Export” to download the
.aia
file - Build an
.apk
file to install the app on Android devices