Commit e76b6f5e authored by Chris Prince's avatar Chris Prince

Initial commit of cat laser.

parents
A simple service to move an ESP-12
\ No newline at end of file
/*******************************************************************
Servo Controlled LASER Cat Toy by Ryan Soderlund
Uses two SG90 servos, 2~5v 5mW LASER, and ESP-12E Dev Board
TODO:
X Make servos quiet
* HW: add 1/4-20 thread to base
/ way to adjust the spread of laser postions? (like no more than 5 degrees from prior?)
* enter distance from target and that determines the amount of movement
* move from html/post requests to interface and socket
* make randomness2 keep running until "stop" is received
* add features to GUI (show position, laser status)
* add watchdog timer to reset system periodically
* add timer so it never runs more than 10 minutes after last command.
* HW: add Power LED
* HW: Add manual (random) start button and reset button.
* add local AP for setting up system (entering WIFI info) and IP configuration.
References:
Wifi Chip: https://www.amazon.com/gp/product/B010O1G1ES/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&th=1
wifi code from:
https://www.engineersgarage.com/esp8266/servo-motor-with-nodemcu-web-control/
https://tttapa.github.io/ESP8266/Chap07%20-%20Wi-Fi%20Connections.html
https://learn.sparkfun.com/tutorials/esp8266-thing-hookup-guide/example-sketch-ap-web-server
*******************************************************************/
#include <Servo.h>
#include <ESP8266WiFi.h>
Servo servoX; //initiate servo object horizontal
Servo servoY; //initiate servo object vertical
const char* ssid = "gofast";
const char* password = "getexcitednow!";
WiFiServer server(80); // i think this establishes instance "server" on port 80
//////// PINOUTS
const int LASER = D6; //Laser On/Off
const int redLED = 4; //Activity LED (manual or auto mode activated)
const int modeSwitch = 2; //Momentary Button to activate Auto Mode
const int sX = D7; //horizontal servo control (X-X degrees)
const int sY = D8; //vertical servo control (X-X degrees)
//Servo BLACK WIRE = GND
//Servo RED WIRE = 5v
//////// DEFINE GLOBAL VARIABLES
//#define centerPos 90 //sets servo center position
//#define zeroPos 0
//sets vertical servo zero position
int posCnt = 0; // variable to store the position counter
int Xpos = 150; // variable to store the X servo position
int Ypos = 75; // variable to store the Y servo position
int Xmin = 90; // default vertical min X servo position
int Xmax = 170; // default vertical max X servo position
int Ymin = 55; // default vertical min Y servo position
int Ymax = 90; // default vertical min Y servo position
int rate = 100; //time to wait between servo angle changes in ms, affects speed of servo motion.
int randomState = 0;
void setup();
void loop();
void moveLaser(int x, int y) {
servoX.attach(sX); //attaches servo to pin
servoY.attach(sY); //attaches servo to pin
servoX.write(x); // tell servo to go to position in variable 'Xpos'
servoY.write(y); // tell servo to go to position in variable 'Ypos'
delay(500); // waits for the servo to reach the position
servoX.detach(); //detaches from all servos to quiet them
servoY.detach();
}
void moveRequest(String req) {
int x;
int y;
const paramQIdx = req.indexOf('?');
const paramAtIdx = req.indexOf('&');
const String valA = req.substring(paramQIdx + 1, paramAtIdx);
const String valB = req.substring(paramAtIdx+1);
if (valA.startsWith('x=')) {
string tmpX = valA.substring(2);
string tmpY = valB.substring(2);
x = tmpX.toInt();
y = tmpY.toInt();
} else {
string tmpY = valA.substring(2);
string tmpX = valB.substring(2);
x = tmpX.toInt();
y = tmpY.toInt();
}
moveLaser(x, y);
}
///////////////// RANDOMNESS 2 - MOVE ERRATICALLY /////////////////////
void randomness2() { //attempt to limit movements by tying to prior position, while also keeping w/in mix/max bounds
int Xgoal = random(Xmin,Xmax); //initialize X/Ygoal, which is where the laser will move *towards*
int Ygoal = random(Ymin,Ymax);
Serial.print("Xgoal=");Serial.print(Xgoal); Serial.print(", Ygoal="); Serial.println(Ygoal);
int DXmax = 10;
int DYmax = 5;
if ((Xgoal - Xpos) >DXmax){
Xgoal = Xpos + DXmax;
Serial.println("Xgoal - Xpos >5");
}
if ((Xgoal - Xpos) <-DXmax){
Xgoal = Xpos - DXmax;
Serial.println("Xgoal - Xpos <-5");
}
if ((Ygoal - Ypos) >DYmax){
Ygoal = Ypos + DYmax;
Serial.println("Ygoal - Ypos >5");
}
if ((Ygoal - Ypos) <-DYmax){
Ygoal = Ypos - DYmax;
Serial.println("Ygoal - Ypos <-5");
}
int Xdelta = Xgoal - Xpos; //determine the distance to move
int Ydelta = Ygoal - Ypos;
Serial.print("x=");Serial.print(Xgoal); Serial.print(", y="); Serial.print(Ygoal);
Serial.print(", Xdelta="); Serial.print(Xdelta); Serial.print(", Ydelta="); Serial.println(Ydelta);
moveLaser(Xpos+Xdelta/DXmax, Ypos+Ydelta/DYmax);
}
/**
* setup():
*
*/
void setup() {
// initialize inputs and outputs:
pinMode(LASER, OUTPUT);
pinMode(redLED, OUTPUT);
pinMode(sX, OUTPUT);
pinMode(sY, OUTPUT);
pinMode(modeSwitch, INPUT);
Serial.begin(115200);
delay(10);
// Connect to WiFi network
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
// Start the server
server.begin();
Serial.println("Server started");
// Print the IP address on serial monitor
Serial.print("Use this URL to connect: ");
Serial.print("http://"); Serial.print(WiFi.localIP()); Serial.println("/");
}
/**
* loop():
*
*/
void loop() {
// Check if a client has connected
WiFiClient client = server.available();
if (!client) {
return;
}
// Wait until the client sends some data
Serial.println("new client");
while(!client.available()){
delay(1);
}
// Read the first line of the request
String request = client.readStringUntil('\r');
Serial.print("Request Received: ");
Serial.println(request);
// client.flush();
//////////// GENERATE HTML CODE WITH BUTTONS AND LISTEN FOR RESPONSE //////////////
delay(1);
Serial.println("Client disconnected");
Serial.println("");
// Match the request: (THIS CODE MUST BE BELOW THE "return the response" SECTION OR IT WON'T COMPILE...)
if (request.indexOf("/random") != -1) {
randomState = 1; //debugging
Serial.println("SET Random Flag");
} else if (request.indexOf("/move") != -1 ) { // move?x=X&y=Y
digitalWrite(LASER, HIGH); // turn the LASER on.
moveRequest(request);
} else if (request.indexOf("/start") != -1) {
digitalWrite(LASER, HIGH); // turn the LASER on.
} else if (request.indexOf("/stop") != -1 ) {
randomState = 0;
digitalWrite(LASER, LOW); // turn off the laser
Serial.println("Stop Laser and Turn off Random Flag"); //debugging
} else {
// If we don't have a request what should we do? Nothing maybe?
Serial.println(".");
}
if (randomState == 1) {
randomness2(); // initiate cat distraction // HOW DO I KEEP IT DOING THING WHILE ALSO WAITING FOR new request?
delay(random(50,4000)); //delay between movements. 20,2000 was a too short.
}
// add if..else here to countdown before turning off laser?
Serial.print("random State=");
Serial.println(randomState); //debugging
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment