Automatic Blinds Adjuster:
Description:
The device I decided to make is an automatic blinds adjuster for people who may have a hard time maneuvering to a window to adjust their blinds. The user can either use a theoretical slider on a wall somewhere that would change the slide position on the webpage or they could use the webpage to adjust the blinds height.
I had some trouble integrating both ways into one script so I have split the Arduino to p5.js and p5.js to Arduino parts for the purpose of this post.


Arduino to p5.js:
The user can adjust the slider on the webpage with a theoretical slider represented by a potentiometer.
Video Demo:
p5.js Code:
var serial; // variable to hold an instance of the serialport library
// for macos and *nix, you'll do something like this:
//var portName = '/dev/cu.usbserial-DN01DW79'; // fill in your serial port name here
// for windows, just the COM port you're using
var portName = '/dev/tty.usbmodem14101';
var inData = 0; // variable to hold the input data from Arduino
var minWidth = 600; //set min width and height for canvas
var width, height; // actual width and height for the sketch
// set the canvas to match the window size
if (window.innerWidth > minWidth){
width = window.innerWidth;
if (window.innerHeight > minHeight) {
height = window.innerHeight;
sliderStartX = width/2 - slideLength/2;
createCanvas(width, height);
//set up communication port
serial = new p5.SerialPort(); // make a new instance of the serialport library
serial.on('list', printList); // set a callback function for the serialport list event
serial.on('connected', serverConnected); // callback for connecting to the server
serial.on('open', portOpen); // callback for the port opening
serial.on('data', serialEvent); // callback for when new data arrives
serial.on('error', serialError); // callback for errors
serial.on('close', portClose); // callback for the port closing
serial.list(); // list the serial ports
serial.open(portName); // open a serial port
// set background to black
textAlign(CENTER, BOTTOM);
text("Curtain Height", sliderStartX + slideLength/2, sliderY - outlineWeight);
//-----Draw Slider-----//
// Following functions print the serial communication status to the console for debugging purposes
function printList(portList) {
// portList is an array of serial port names
for (var i = 0; i < portList.length; i++) {
// Display the list the console:
print(i + " " + portList[i]);
function serverConnected() {
print('connected to server.');
print('the serial port opened.')
// on the arduino we are using Serial.write to send an inteer
// so we have to use Number() to convert it to a number.
// otherwise it would be a string
inData = serial.readLine();
// if you do this, the inData value will be a string, not a number
//inData = serial.read();
function serialError(err) {
print('Something went wrong with the serial port. ' + err);
print('The serial port closed.');
function updateSlider() {
serial.write(parseInt(map(sliderX, sliderStartX, sliderStartX+slideLength-sliderWidth, 0, 1023)));
text("Value: " + parseInt(map(sliderX, sliderStartX, sliderStartX+slideLength-sliderWidth, 0, 1023)), sliderStartX + slideLength/2, 70);
//This section is commented out for the p5.js to arduino configuration
// if (!sliderClicked && inData != sliderX){
// sliderX = map(inData, 0, 180, sliderStartX, sliderStartX+slideLength);
rect(sliderStartX - outlineWeight/2, sliderY - outlineWeight/2, slideLength + outlineWeight, sliderHeight + outlineWeight,30);
rect(sliderStartX, sliderY, slideLength, sliderHeight,30);
rect(sliderX, sliderY, sliderWidth, sliderHeight,30);
function mousePressed() {
sliderClicked = isInRectangle(mouseX, mouseY, sliderY, (sliderY + sliderHeight), sliderX, (sliderX + sliderWidth));
if (inBounds(mouseX, sliderStartX, sliderStartX + slideLength - sliderWidth)){
function mouseDragged() {
if (inBounds(mouseX, sliderStartX, sliderStartX + slideLength - sliderWidth)){
function inBounds(value, lowerBound, upperBound) {
if ((value > lowerBound) && (value < upperBound)) {
function isInRectangle(x, y, topBound, bottomBound, leftBound, rightBound) {
let xInRect = inBounds(x, leftBound, rightBound);
let yInRect = inBounds(y, topBound, bottomBound);
if (xInRect && yInRect) {
var serial; // variable to hold an instance of the serialport library
// for macos and *nix, you'll do something like this:
//var portName = '/dev/cu.usbserial-DN01DW79'; // fill in your serial port name here
// for windows, just the COM port you're using
var portName = '/dev/tty.usbmodem14101';
var inData = 0; // variable to hold the input data from Arduino
var minWidth = 600; //set min width and height for canvas
var minHeight = 400;
var width, height; // actual width and height for the sketch
var sliderWidth = 30;
var sliderHeight = 200;
var slideLength = 400;
var outlineWeight = 10;
var sliderStartX;
var sliderX;
var sliderY = 200;
var sliderClicked = 0;
function setup() {
// set the canvas to match the window size
if (window.innerWidth > minWidth){
width = window.innerWidth;
} else {
width = minWidth;
}
if (window.innerHeight > minHeight) {
height = window.innerHeight;
} else {
height = minHeight;
}
sliderStartX = width/2 - slideLength/2;
sliderX = sliderStartX;
//set up canvas
createCanvas(width, height);
noStroke();
//set up communication port
serial = new p5.SerialPort(); // make a new instance of the serialport library
serial.on('list', printList); // set a callback function for the serialport list event
serial.on('connected', serverConnected); // callback for connecting to the server
serial.on('open', portOpen); // callback for the port opening
serial.on('data', serialEvent); // callback for when new data arrives
serial.on('error', serialError); // callback for errors
serial.on('close', portClose); // callback for the port closing
serial.list(); // list the serial ports
serial.open(portName); // open a serial port
}
function draw() {
// set background to black
background(0);
fill(255);
textSize(24);
textAlign(CENTER, BOTTOM);
text("Curtain Height", sliderStartX + slideLength/2, sliderY - outlineWeight);
//-----Draw Slider-----//
updateSlider();
}
// Following functions print the serial communication status to the console for debugging purposes
function printList(portList) {
// portList is an array of serial port names
for (var i = 0; i < portList.length; i++) {
// Display the list the console:
print(i + " " + portList[i]);
}
}
function serverConnected() {
print('connected to server.');
}
function portOpen() {
print('the serial port opened.')
}
function serialEvent() {
// on the arduino we are using Serial.write to send an inteer
// so we have to use Number() to convert it to a number.
// otherwise it would be a string
inData = serial.readLine();
// if you do this, the inData value will be a string, not a number
//
//inData = serial.read();
//
// in arduino terms it's
// int inData = 1;
// vs
// String inData = "1';
}
function serialError(err) {
print('Something went wrong with the serial port. ' + err);
}
function portClose() {
print('The serial port closed.');
}
function updateSlider() {
serial.write(parseInt(map(sliderX, sliderStartX, sliderStartX+slideLength-sliderWidth, 0, 1023)));
text("Value: " + parseInt(map(sliderX, sliderStartX, sliderStartX+slideLength-sliderWidth, 0, 1023)), sliderStartX + slideLength/2, 70);
//This section is commented out for the p5.js to arduino configuration
// if (!sliderClicked && inData != sliderX){
// sliderX = map(inData, 0, 180, sliderStartX, sliderStartX+slideLength);
// }
//Background
fill(100);
rect(sliderStartX - outlineWeight/2, sliderY - outlineWeight/2, slideLength + outlineWeight, sliderHeight + outlineWeight,30);
fill(255);
rect(sliderStartX, sliderY, slideLength, sliderHeight,30);
//Slider
fill(100, 10, 10);
rect(sliderX, sliderY, sliderWidth, sliderHeight,30);
}
function mousePressed() {
sliderClicked = isInRectangle(mouseX, mouseY, sliderY, (sliderY + sliderHeight), sliderX, (sliderX + sliderWidth));
if (sliderClicked) {
if (inBounds(mouseX, sliderStartX, sliderStartX + slideLength - sliderWidth)){
sliderX = mouseX;
}
}
}
function mouseDragged() {
if (sliderClicked) {
if (inBounds(mouseX, sliderStartX, sliderStartX + slideLength - sliderWidth)){
sliderX = mouseX;
}
}
}
function inBounds(value, lowerBound, upperBound) {
if ((value > lowerBound) && (value < upperBound)) {
return 1;
} else {
return 0;
}
}
function isInRectangle(x, y, topBound, bottomBound, leftBound, rightBound) {
let xInRect = inBounds(x, leftBound, rightBound);
let yInRect = inBounds(y, topBound, bottomBound);
if (xInRect && yInRect) {
return 1;
} else {
return 0;
}
}
var serial; // variable to hold an instance of the serialport library
// for macos and *nix, you'll do something like this:
//var portName = '/dev/cu.usbserial-DN01DW79'; // fill in your serial port name here
// for windows, just the COM port you're using
var portName = '/dev/tty.usbmodem14101';
var inData = 0; // variable to hold the input data from Arduino
var minWidth = 600; //set min width and height for canvas
var minHeight = 400;
var width, height; // actual width and height for the sketch
var sliderWidth = 30;
var sliderHeight = 200;
var slideLength = 400;
var outlineWeight = 10;
var sliderStartX;
var sliderX;
var sliderY = 200;
var sliderClicked = 0;
function setup() {
// set the canvas to match the window size
if (window.innerWidth > minWidth){
width = window.innerWidth;
} else {
width = minWidth;
}
if (window.innerHeight > minHeight) {
height = window.innerHeight;
} else {
height = minHeight;
}
sliderStartX = width/2 - slideLength/2;
sliderX = sliderStartX;
//set up canvas
createCanvas(width, height);
noStroke();
//set up communication port
serial = new p5.SerialPort(); // make a new instance of the serialport library
serial.on('list', printList); // set a callback function for the serialport list event
serial.on('connected', serverConnected); // callback for connecting to the server
serial.on('open', portOpen); // callback for the port opening
serial.on('data', serialEvent); // callback for when new data arrives
serial.on('error', serialError); // callback for errors
serial.on('close', portClose); // callback for the port closing
serial.list(); // list the serial ports
serial.open(portName); // open a serial port
}
function draw() {
// set background to black
background(0);
fill(255);
textSize(24);
textAlign(CENTER, BOTTOM);
text("Curtain Height", sliderStartX + slideLength/2, sliderY - outlineWeight);
//-----Draw Slider-----//
updateSlider();
}
// Following functions print the serial communication status to the console for debugging purposes
function printList(portList) {
// portList is an array of serial port names
for (var i = 0; i < portList.length; i++) {
// Display the list the console:
print(i + " " + portList[i]);
}
}
function serverConnected() {
print('connected to server.');
}
function portOpen() {
print('the serial port opened.')
}
function serialEvent() {
// on the arduino we are using Serial.write to send an inteer
// so we have to use Number() to convert it to a number.
// otherwise it would be a string
inData = serial.readLine();
// if you do this, the inData value will be a string, not a number
//
//inData = serial.read();
//
// in arduino terms it's
// int inData = 1;
// vs
// String inData = "1';
}
function serialError(err) {
print('Something went wrong with the serial port. ' + err);
}
function portClose() {
print('The serial port closed.');
}
function updateSlider() {
serial.write(parseInt(map(sliderX, sliderStartX, sliderStartX+slideLength-sliderWidth, 0, 1023)));
text("Value: " + parseInt(map(sliderX, sliderStartX, sliderStartX+slideLength-sliderWidth, 0, 1023)), sliderStartX + slideLength/2, 70);
//This section is commented out for the p5.js to arduino configuration
// if (!sliderClicked && inData != sliderX){
// sliderX = map(inData, 0, 180, sliderStartX, sliderStartX+slideLength);
// }
//Background
fill(100);
rect(sliderStartX - outlineWeight/2, sliderY - outlineWeight/2, slideLength + outlineWeight, sliderHeight + outlineWeight,30);
fill(255);
rect(sliderStartX, sliderY, slideLength, sliderHeight,30);
//Slider
fill(100, 10, 10);
rect(sliderX, sliderY, sliderWidth, sliderHeight,30);
}
function mousePressed() {
sliderClicked = isInRectangle(mouseX, mouseY, sliderY, (sliderY + sliderHeight), sliderX, (sliderX + sliderWidth));
if (sliderClicked) {
if (inBounds(mouseX, sliderStartX, sliderStartX + slideLength - sliderWidth)){
sliderX = mouseX;
}
}
}
function mouseDragged() {
if (sliderClicked) {
if (inBounds(mouseX, sliderStartX, sliderStartX + slideLength - sliderWidth)){
sliderX = mouseX;
}
}
}
function inBounds(value, lowerBound, upperBound) {
if ((value > lowerBound) && (value < upperBound)) {
return 1;
} else {
return 0;
}
}
function isInRectangle(x, y, topBound, bottomBound, leftBound, rightBound) {
let xInRect = inBounds(x, leftBound, rightBound);
let yInRect = inBounds(y, topBound, bottomBound);
if (xInRect && yInRect) {
return 1;
} else {
return 0;
}
}
Arduino Code:
const int SERVO_PIN = 10;
pinMode(LED_PIN, OUTPUT);
curtainHeight.attach(SERVO_PIN);
// this sends the sensorValue as a raw int
if (Serial.available() > 0) {
incomingData = Serial.parseInt();
newHeight = map(incomingData, 0, 1023, 0, 180);
curtainHeight.write(newHeight);
newHeight = map(analogRead(POT_PIN), 0, 1023, 0, 180);
if (abs(prevHeight - newHeight) > 2) {
curtainHeight.write(newHeight);
Serial.println(newHeight);
#include <Servo.h>
const int POT_PIN = A0;
const int SERVO_PIN = 10;
int incomingData = 0;
int potVal;
int newHeight;
int prevHeight = 0;
Servo curtainHeight;
void setup() {
Serial.begin(9600);
pinMode(LED_PIN, OUTPUT);
pinMode(POT_PIN, INPUT);
curtainHeight.attach(SERVO_PIN);
}
void loop() {
// this sends the sensorValue as a raw int
//LED state changes
if (Serial.available() > 0) {
incomingData = Serial.parseInt();
newHeight = map(incomingData, 0, 1023, 0, 180);
curtainHeight.write(newHeight);
} else {
newHeight = map(analogRead(POT_PIN), 0, 1023, 0, 180);
if (abs(prevHeight - newHeight) > 2) {
curtainHeight.write(newHeight);
Serial.println(newHeight);
prevHeight = newHeight;
}
}
}
#include <Servo.h>
const int POT_PIN = A0;
const int SERVO_PIN = 10;
int incomingData = 0;
int potVal;
int newHeight;
int prevHeight = 0;
Servo curtainHeight;
void setup() {
Serial.begin(9600);
pinMode(LED_PIN, OUTPUT);
pinMode(POT_PIN, INPUT);
curtainHeight.attach(SERVO_PIN);
}
void loop() {
// this sends the sensorValue as a raw int
//LED state changes
if (Serial.available() > 0) {
incomingData = Serial.parseInt();
newHeight = map(incomingData, 0, 1023, 0, 180);
curtainHeight.write(newHeight);
} else {
newHeight = map(analogRead(POT_PIN), 0, 1023, 0, 180);
if (abs(prevHeight - newHeight) > 2) {
curtainHeight.write(newHeight);
Serial.println(newHeight);
prevHeight = newHeight;
}
}
}
p5.js to Arduino:
The user can also use the slider on the interface to adjust the blind height from a potential website. I was not able to get this part to work as I was having a little trouble figuring out how to read data from p5.js in Arduino. The code and setup are the same as for the Arduino to p5.js case.