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 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:
#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.