← archive

Laser Servo

Cover image

For a simple prototype that incorporates a web server and physical device, I decided to make a wifi controlled laser pointer. I'm using a NodeMCU micro controller and the ESP8266 WiFi Library. My goal is to control a laser pointer on two axis by web browser via http requests.

Circuit diagram:

Circuit diagram

Beautiful soldering:
Sloppy solder job

Physical

To make the joint, I used two servos. I hot glued a servo to the horn of another servo. It's pretty rudimentary but works for its purpose. I also picked up a simple laser diode that is easy to work with.

Programming

I continued to use the esp8266 library for my server. It requires very little code to get up and running. I figured I would need a minumum of 6 buttons to control the Wifi: 1. Power on laser 2. Power off laser 3. Rotate left 4. Rotate right 5. Rotate up 6. Rotate down

I creates routes for each button which calls functions that control the laser.

Conclusion

The quick prototype pretty much works as expected although it is pretty basic. The way my server handles the buttons by sending a lot HTTP requests, I imagine that it would pretty quickly overload if it was public.

Servo laser

Questions moving forward

  1. What is the difference between a client and server? Could I have ran the server on my computer and send commands to my nodemcu as the client?
  2. My original plan was to make a moveable camera. That way you could view the stream on the browser and control the camera. But problems arose when streaming the webcam to browser. I saw raspberry pi IP camera libraries, but would I be able to run a web server while running a media streaming server on the same device, or would it make more sense to have the raspi ip camera and nodemcu arm as different.
  3. If wanted to use a joystick control the camera would I need to use something like web sockets or web rtc for a connection to handle the data instead of a lot HTTP requests.

code:

// Include ESP8266 WiFi Libraries
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>

// include servo header
#include <Servo.h>

// servo pins
int lrPin = 4;
int udPin = 2;

int lrPos=90;
int udPos=90;

#define D3 0

// create servos
Servo servoLR;
Servo servoUD;

// Wifi Credentials const char* ssid = "<wifi name>";
const char* password = "<password>";

//  laser
const int laser = D3;

// Instantiate  server on port 80
ESP8266WebServer server(80);

// String for HTML
String page = "";

// turn led on
void ledOn(){
    server.send(200, "text/html", page);
    digitalWrite(laser, HIGH); // turns on LED
    delay(1000);
}

// turn led off
void ledOff(){
    server.send(200, "text/html", page);
    digitalWrite(laser, LOW); // turns off LED
    delay(1000);
}

void moveRight(){
    server.send(200, "text/html", page);
    lrPos-=2;
    servoLR.write(lrPos);
    delay(100);
}

void moveLeft(){
    server.send(200, "text/html", page);
    lrPos+=2;
    servoLR.write(lrPos);
    delay(100);
}

void moveDown(){
    server.send(200, "text/html", page);
    udPos-=2;
    servoUD.write(udPos);
    delay(100);
}

void moveUp(){
    server.send(200, "text/html", page);
    udPos+=2;
    servoUD.write(udPos);
    delay(100);
}

void setup(){

    // attach servos
    servoLR.attach(lrPin);
    servoUD.attach(udPin);

    // HTML of page with inline style
    page = "<h1>ESP Web Server</h1><a href='/on'><button>Laser On</button></a><a href='/off'><button>Laser off</button></a><a href='/left'><button>Left</button></a><a href='/up'><button>Up</button></a><a href='/down'><button>Down</button></a><a href='/right'><button>Right</button></a>  ";
    
    // Open serial monitor
    Serial.begin(115200);
    
    // declare pinmode for onboard led
    pinMode(laser, OUTPUT);

    // begin WiFi connection
    WiFi.begin(ssid, password);
    
    Serial.println("");
    
    // is connecting screen
    while(WiFi.status() != WL_CONNECTED){
        delay(500);
        Serial.print("#");
    }
    
    // Success and print IP address
    Serial.println("");
    Serial.print("Connected to: ");
    Serial.print(ssid);
    Serial.println("");
    Serial.print("IP address: ");
    Serial.print("http://");
    Serial.print(WiFi.localIP());
    Serial.println("/");
    
    // Serial.println(WiFi.localIP());
    
    // Create routes
    server.on("/", [](){
        server.send(200, "text/html", page);
    });
    
    server.on("/on", ledOn);
    server.on("/off",ledOff);

    server.on("/left",moveLeft);
    server.on("/right",moveRight);
    server.on("/up",moveUp);
    server.on("/down",moveDown);

    // begin server and success message
    server.begin();
    Serial.println("Web server started!");


}

void loop(){
    server.handleClient(); // handles callback functions
}
// Wifi Credentials
const char* ssid = "<wifi name>";
const char* password = "<password>";

//  laser
const int laser = D3;

// Instantiate  server on port 80
ESP8266WebServer server(80);

// String for HTML
String page = "";

// turn led on
void ledOn(){
    server.send(200, "text/html", page);
    digitalWrite(laser, HIGH); // turns on LED
    delay(1000);
}

// turn led off
void ledOff(){
    server.send(200, "text/html", page);
    digitalWrite(laser, LOW); // turns off LED
    delay(1000);
}

void moveRight(){
    server.send(200, "text/html", page);
    lrPos-=2;
    servoLR.write(lrPos);
    delay(100);
}

void moveLeft(){
    server.send(200, "text/html", page);
    lrPos+=2;
    servoLR.write(lrPos);
    delay(100);
}

void moveDown(){
    server.send(200, "text/html", page);
    udPos-=2;
    servoUD.write(udPos);
    delay(100);
}

void moveUp(){
    server.send(200, "text/html", page);
    udPos+=2;
    servoUD.write(udPos);
    delay(100);
}

void setup(){

    // attach servos
    servoLR.attach(lrPin);
    servoUD.attach(udPin);

    // HTML of page with inline style
    page = "<h1>ESP Web Server</h1><a href='/on'><button>Laser On</button></a><a href='/off'><button>Laser off</button></a><a href='/left'><button>Left</button></a><a href='/up'><button>Up</button></a><a href='/down'><button>Down</button></a><a href='/right'><button>Right</button></a>  ";
    
    // Open serial monitor
    Serial.begin(115200);
    
    // declare pinmode for onboard led
    pinMode(laser, OUTPUT);

    // begin WiFi connection
    WiFi.begin(ssid, password);
    
    Serial.println("");
    
    // is connecting screen
    while(WiFi.status() != WL_CONNECTED){
        delay(500);
        Serial.print("#");
    }
    
    // Success and print IP address
    Serial.println("");
    Serial.print("Connected to: ");
    Serial.print(ssid);
    Serial.println("");
    Serial.print("IP address: ");
    Serial.print("http://");
    Serial.print(WiFi.localIP());
    Serial.println("/");
    
    // Serial.println(WiFi.localIP());
    
    // Create routes
    server.on("/", [](){
        server.send(200, "text/html", page);
    });
    
    server.on("/on", ledOn);
    server.on("/off",ledOff);

    server.on("/left",moveLeft);
    server.on("/right",moveRight);
    server.on("/up",moveUp);
    server.on("/down",moveDown);

    // begin server and success message
    server.begin();
    Serial.println("Web server started!");


}

void loop(){
    server.handleClient(); // handles callback functions
}