Introduction: Internet of Things - EasyPainting

EasyPainting is an IoT product where a projection is fired from a beamer to the back of a painting canvas. This product helps users to paint specific designs.

EasyPainting is controlled by the means of multiple servomotors built into the beamer its lens. The beamer also has an on and off button on the side.

In this manual I will teach you how to code your own EasyPainting:

Supplies

  1. NodeMCU
  2. Servomotors
  3. Button
  4. Interactive beamer

Step 1: Downloading of Arduino

The first step in coding your own EasyPainting product is to download the application on which it will be made. This will be Arduino.

Download link Arduino

Click here on the correct computer program that you have, a Windows, Mac or Linux.

Step 2: Collect Your Supplies

After Arduino is successfully downloaded, it is time to attach your IoT equipment to your NodeMCU.

For the servomotor it is important to put the wire PWM in D5, VCC in 3V and GND in G. It is also important to tell you that we use three servomotors in this project. This will later be explained in the manual, so make sure you have a NodeMCU that has three inputs from each said above.

For the button it does not matter which wire goes into which.

Finally, the purple wire in the picture is for your own beamer.

Step 3: Downloading of Webinator

When all the sensors are in the right place, it is time to download a machine learning software called Webinator. This software allows you to create your own voice commands. Furthermore in the manual we will use these voice commands to control our servomotors.

Download link Webinator

Step 4: Downloading One More File

The last step in the downloading process is the downloading of a specific file. This file ensures that we can create voice commands ourselves in Webinator.

Download link file

After clicking the link you have to scroll down on the page until you find 'Audio'. Then click under 'Various audio features' and again choose your correct computer version.

If that is successful then you must be given this black screen with green text as seen above. If so, proceed to the next step.

Step 5: Changing the Menu

After this you can open Webinator. If correct, when opening you will receive this screen. If you look back at the green text on the previous image, you will read 13 inputs to port 6448. We must also state that in this menu so that it will import the data that we are going to make. Therefore change 'Wekinator listening for inputs and control on port' to 6448 and '# inputs' to 13.

After this you also have to set how many voice commands you want to make. First change 'Type' to All dynamic time warping (default settings). If all goes well, the input field with gesture types will pop up. Enter here how many voice commands you wish to make. EasyPainting itself uses 6.

If all is set correctly, click on next.

Step 6: The Making of Voice Commands

If you followed every step, then you will now see a screen like the one above. Here you can create your own voice commands. To do this, click on the + sign behind the output and simply say your voice command. After that, you can listen to it and hear if you think it is right for you. You can re-enter it in the left options. If all is well then also perform this on the other outputs. *Don't forget, always make an output command where you can stop all the movement.

The outputs of EasyPainting are:

  1. output_1 = left
  2. output_2 = right
  3. output_3 = up
  4. output_4 = down
  5. output_5 = rotate
  6. output_6 = stop

Step 7: Get the Code From Webinator

The processing code of Webinator will be transferred to Arduino with this code:

import vsync.*; // Importing the library that will help sending and receiving the values from the Arduino<br>import processing.serial.*;  // Importing the serial library

// Below libraries will connect and send, receive the values from Wekinator
import oscP5.*;
import netP5.*;

// Creating the instances
OscP5 oscP5;
NetAddress dest;
Valuesender sender;

// This variable will be synchronised with the Arduino and it should be same on the 
Arduino side.
public int output;
void setup() 
{
  // Starting the serial communication, the baudrate and the com port should be same as on the Arduino side.
  Serial serial = new Serial(this, "COM10", 115200);
  sender = new ValueSender(this, serial);
  
  // Synchronizing the variable as on the Arduino side.
  sender.observe("output");
  
  // Starting the communication with wekinator. listen on port 12000, return messages on port 6448
  oscP5 = new OscP5(this, 12000); 
  dest = new NetAddress("127.0.0.1", 6448);
} 

With the help of

Step 8: Letting the Servomotors React

If the previous step was transferred successful, start making responses as given below.

In this code we will tell the servomotors how they have to react to a specific output. We use multiple servomotors, because they can only can go one way. One servomotor can simply go left and right. So how do we make it go up and down? We create an up and down effect by turning a different servomotor 90 degrees, so the motor now goes up and down.

Don't forget to give each servomotor its own name and pin, as seen in the example below.

#include  //including the library that will help us in receiving and sending the values from processing<br>#include  
Servo myservo;  // right and left
Servo myservo2; // up en down
Servo myservo3; // rotate
int output;  
int angle = 90;
int pos = 0;

void setup() {

   // starting the serial communication
   Serial.begin (115200);
   myservo.attach(D5);
   myservo2.attach(D6);
   myservo3.attach(D7);

   // Synchronising the variable with the processing
   receiver.observe(output);
}
void loop() {

  // Receiving the output from processing
  receiver.sync(); 

The most important part in the code is what you see below. Here we tell the servomotor what to do if a specific voice command was used. For example saying left: the servomotor will go left when an user says your output 1, it will go until the user says your stop output.

  // saying left
  if (output == 1) {
    myservo.write(angle);
    angle--;
    delay(100);         
    }

  // saying right
  else if (output == 2) {
    myservo.write(angle);
    angle++;
    delay(100);
    }

  // saying up
  else if (output == 3) {
    myservo2.write(angle);
    angle--;
    delay(100);
    }
  // saying down
  else if (output == 4) {
    myservo2.write(angle);
    angle++;
    delay(100);
    }

  // saying rotate (clockwise) 
  else if (output == 5) {
    myservo3.write(angle);
    angle--;
    delay(100);
    }

  // saying stop
  else if (output == 6) {
  break;
  }
} 

Made with a little help of

Step 9: Adding the on and Off Button

Give the servomotors reacting a small test, if it succeeds, we can add this next step of code. On the last part of this code we will give the beamer an on and off button. In the code below we use a ledPin, but when building yourself, it must be replaced with your own specific beamer.

const int buttonPin = D2;<br>// for now a led, but you need to connect it to your specific beamer
const int ledPin = D1;  

// reading pushbutton status;
int buttonState = 0;

void setup() {

  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT);

} 

Below is coded what needs to be done when the button is pressed. You can use this to switch a product on or off.

void loop() {
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed. If it is, the buttonState is HIGH;
  if (buttonState == HIGH) {
    // turn LED on;
    digitalWrite(ledPin, HIGH);
  } else {
    // turn LED off;
    digitalWrite(ledPin, LOW);
  }
}

Step 10: Lastly, Putting All the Codes Together

If all the given code does not contain any error messages, you can merge them together and enjoy your own EasyPainting product. (To get it completely working, don't forget to connect it with the application.)

However, for convenience we also have an .ino version ready for you.