Mad Eye Moody v2 with Wifi

My Mad-Eye Moody eye has worked pretty well for the past year and has gone to several costume parties where it always catches people by surprise. That’s a fun moment, hearing people around you go “OMG it moved”, but I never felt like the eye itself was interactive enough. It just moved at random, no real intention behind it.  So for its last appearance I decided to rebuild it and make it more aware of it’s environment.

I’ve been playing with the ESP8266 and really like all of the capabilities of that cheap little chip, so I decided to press it into service for my Eye.  I thought it might be fun, since the chip has wifi built in,  to make the eyes movements react to the amount of wireless in the room.

Using an adafruit Huzzah as my base,  I copy and pasted bits of code together to look for the number of available APs.  I use the number of APs to control how fast the eye moves from one random position to the next and how long the eye waits in any one position. After a cycle of wifi driven movement, I perform a slow sweep back and forth and then wait a random (wifi driven) period of time before starting it over again.  Here’s a video and  the code. I’m waiting on a nice iris to replace the hand painted mess.

#include <Servo.h>
#include "ESP8266WiFi.h"
Servo myservo;
int sweep;

void setup() {
  Serial.begin(115200);
  myservo.attach(2);
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  delay(100);
}

void loop() {

  Serial.println("starting scan for APs");
  int n = WiFi.scanNetworks();    //scan for wireless APs and return as n
  Serial.println("scan done");
  if (n == 0) {                   //where are you that no APs are around???
    Serial.println("no networks found");
    sweep = 1;
  }
  else
  {
    Serial.print(n);               //num of APs found
    Serial.println(" networks found");
    for (int i = 0; i < n; i++) //print SSIDs
    {
      Serial.println(WiFi.SSID(i));
    }
    Serial.println();
    sweep = n;
  }
  int pos = random(60, 110);  //create a random start point between 60 and 110 degrees
  myservo.write(pos); //set the servo to a random start point
  Serial.print("servo starting point is ");
  Serial.println(pos);
  delay(5000 / sweep); //5 second default delay divided by number of APs


  for (pos; pos <= 110; pos += (sweep / 5)) // servo can only go between 60 and 110 degress or I get poked in the eye
  {
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for (pos; pos >= 60; pos -= (sweep / 5)) // and now we go the other way
  {
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }


  pos = random(60, 110);
  myservo.write(pos);
  delay(100 * sweep);
  for (pos; pos <= 110; pos += 1) // goes from 0 degrees to 180 degrees
  { 
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(20);                       // waits 15ms for the servo to reach the position
  }
  for (pos; pos >= 60; pos -= 1) // goes from 180 degrees to 0 degrees
  {
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(20);                       // waits 15ms for the servo to reach the position
  }
  myservo.write(80);
  delay(random(5000 / sweep));
}