Image by Twitter/@SchmidtOcean
The project uses an Arduino Uno as the microcontroller for all electronic components. Eight ET2045 motors control the arms, a small servo motor rotates the sensor, and an Adafruit VL53L1X Time of Flight Distance Sensor detects distances. We didn't do any firmware design, as the pre-installed firmare on the motors, Arduino, and sensor fulfilled our needs. Instead, we focused on the software that controls all these components and adds the higher level logic necessary to create the motion and behavior we were looking for.
We had a total of 11 servo motors and one sensor. For the servos, we connected all the power and ground wires to a breadboard power-rail, and the control wires were plugged into Arduino PWM pins 2-12. The sensor was plugged into the power-rail and the SCL and SDA pins. The power-rail was connected to the Arduino's GND pin, and to the ground and power of a DC power supply set to five volts and two amps. Peak power draw was just over one amp.
Attempt one
Final wiring
The physical wiring went through multiple iterations, as the wires kept coming unplugged, or were knocked loose accidentally while we were working on other parts of the box. To prevent this, we got rid of the jumper wires, and grouped the wires together to route them along the wall.
To detect if there is something in range and where it is, the project uses a time-of-flight laser distance sensor, and rotates it back and forth using a servo to scan the whole area in front of the box. We decided on this solution after experimenting with several different options, such as ultrasonic sensors which had accuracy issues, and using multiple laser sensors at different angles, which would have been expensive and would have complicated the wiring.
Attempting to use ultrasonic sensors
An early prototype
The final setup with housing
The software for this project consists of an Arduino script that runs three different functions at set intervals. One function controls the sensor, rotating the servo that the distance sensor is mounted on, and interpreting the sensor data to determine if there is a object in range, and if so where it is. The second function runs arm movement, rotating the 8 arm servos at staggered intervals to create natural looking movement and maximize range of motion. The third function controls the head. When it is dancing, it turns the head left and right, and when not dancing it lowers the head and turns to look at the person in range.
We initially ran into issues of the timers being scheduled too frequently, which caused the Arduino to not have enough time to run the full function, leading to motors stuttering and other failures. To combat this, we made the motors move a further distance at less frequent intervals, and ran the different functions at different times. With a bit of tinkering, this solved that problem completely with minimal loss of smooth movement.
Full code can be found here.
We used the Adafruit VL53L1X library to control the distance sensor, and arduino-timer to control timing.