The Oreo Cookie Thrower codebase

Fred Damstra dd5d9e0c46 Added select picture saving. 6 年之前
calibrate 0aedd4beab Initial fisheye correction. Should probably recalibrate, but should also determine the resolution we want. 7 年之前
tmp f35d9c8260 Initial commit. 7 年之前
.gitignore 0aedd4beab Initial fisheye correction. Should probably recalibrate, but should also determine the resolution we want. 7 年之前
README.md e159dd92a5 Minor changes from implementation. 7 年之前
facetracker.py dd5d9e0c46 Added select picture saving. 6 年之前
frontalface_fromweb.xml 45cf428de1 Cleaned up code. 6 年之前
haarcascade_frontalface_alt.xml 45cf428de1 Cleaned up code. 6 年之前
haarcascade_frontalface_default.xml f35d9c8260 Initial commit. 7 年之前
haarcascade_profileface.xml f35d9c8260 Initial commit. 7 年之前
i2c_console.py 9f13707c15 Working! 6 年之前

README.md

OCT - The Oreo Cookie Thrower

A face tracking, cookie throwing robot. Uses an arduino and a raspberry together. Almost 100% 3D printed.

Disclaimer: I do not know what I'm doing. What you see below is stuff that worked through some research (probably not enough) along with some trial and error. I'm sure there are a lot of improvements that could be made and probably some straight out mistakes.

Hardware

  • 3D Printed OCT Parts
  • Plenty of M3 nuts and bolts of varying lengths
  • An appropriately sized spring
  • Small stepper motors with drivers. I used cheap 12V 28byj-48 motors with ULN2003 drivers
  • 1k resistors
  • Capacitors
  • Diodes
  • 12V DC adapter
  • Something to drop voltage down to 5V DC for the pi
  • magetic switch
  • endstops (maybe?)
  • A momentary push button
  • A power button

Tools

  • Hex Drivers
  • Screwdrivers
  • Drill

Circuit Elements

Summary: | Device 1 | Pin | Device 2 | Pin | Purpose | |--------------|-----------------|--------------|--------------|--------------| | Uno | A0 | Motor 1 | 1 (1kohm) | Firing Motor | Uno | A1 | Motor 1 | 2 (1kohm) | Firing Motor | Uno | A2 | Motor 1 | 3 (1kohm) | Firing Motor | Uno | A3 | Motor 1 | 4 (1kohm) | Firing Motor | Uno | 5 | Reed Switch | 1 | Load Detect | | Uno | 6 | Motor 2 | 1 (1kohm) | Vertical Motor | Uno | 7 | Motor 2 | 2 (1kohm) | Vertical Motor | Uno | 8 | Motor 2 | 3 (1kohm) | Vertical Motor | Uno | 9 | Motor 2 | 4 (1kohm) | Vertical Motor | Uno | 10 | Motor 3 | 1 (1kohm) | Horizontal Motor | Uno | 11 | Motor 3 | 2 (1kohm) | Horizontal Motor | Uno | 12 | Motor 3 | 3 (1kohm) | Horizontal Motor | Uno | 13 | Motor 3 | 4 (1kohm) | Horizontal Motor | Pi | SDA (Pin 3) | Uno | A4 | i2c | | Pi | SCL (Pin 5) | Uno | A5 | i2c | | Pi | GPIO26 (Pin 37) | Momentary B1 | 1 | Mode Select | | Pi | GPIO20 (Pin 38) | Momentary B2 | 1 | Fire |

TODO: Output of some sort to determine current mode. LEDs? LCD Display? Speaker?

i2c connection

The Raspberry Pi is connected to the raspberry pi via i2c. According to Oscar Liang, this works just fine despite the differing logic levels, provided the Pi is the master.

There is no need for any additional hardware nor resistors.

i2c Uno Configuration

Pi Pin 3 (SDA) <-> Arduino Uno Pin A4 (SDA) Pi Pin 5 (SCL) <-> Arduino Uno Pin A5 (SCL)

i2c MEGA Configuration

Pi Pin 3 (SDA) <-> Arduino MEGA Pin 20 Pi Pin 5 (SCL) <-> Arduino MEGA Pin 21

Motor Connections

For my design, I used the ULN2003 drivers. I believe these are supposed to be test boards, but they work well enough. I put a good sized capacitor (70uF?) across the positive/negative leads in case of sudden current draw, and also placed a diode running from the negative lead to the positive lead as an extra suppression diode. The ULN2003 has built in suppression diodes, but after losing my serial interface on my arduino, I decided it best to add some extra protection. For that matter, I also added diodes before the Vin of the Arduino.

To protect the output pins from backcurrent, install a 1kohm resister inline with each of the 12 pins below.

Arduino Uno Motor Connections

Order of "Motor 1" through Motor 3" depends on your wiring. It doesn't matter provided it matches the code. For that matter, the actual pins don't matter, either. Use whatever's easiest to wire.

Arduino Uno Pin A0, A1, A2, A3 -> 1kohm resistor -> Motor 1 Arduino Uno Pin 6, 7, 8, 9 -> 1kohm resistor -> Motor 2 Arduino Uno Pin 10, 11, 12, 13 -> 1kohm resitor -> Motor 3

Switches

Magnetic (Reed) Switch

A reed switch is used to determine when the arm has reached the reload position. Place the magnet on the launch arm, and the reed switch on the base. This uses the arduinos internal pullup resistor for logic.

Reed switch wire 1 -> GND Reed switch wire 2 -> Arduino Uno Pin 5

Endstops

It would probably be wise to use endstops to prevent the vertical motor from traveling too far. I haven't done that, but don't see any reason why it couldn't be done.

Mode Select Button

A mode select button should be wired to the raspberry pi gpio 26 (Pin 37, opposite the SDA pin). Uses the raspberry pi's built-in pullup resistor, so the second pin should be attached go ground.

Mode Select Pin 1 -> GND Mode Select Pin 2 -> Pi GPIO 26 (Pin 37)

Fire Button

A fire button should be wired to the raspberry pi gpio 20 (Pin 38. Uses the raspberry pi's built-in pullup resistor, so the second pin should be attached go ground.

Fire Select Pin 1 -> GND Fire Select Pin 2 -> Pi GPIO 20 (Pin 38)

Code Elements

Fisheye Camera

If using a fisheye camera, be sure to calibrate your lens using the fisheye correction instructions here and enter them in the code. https://medium.com/@kennethjiang/calibrate-fisheye-lens-using-opencv-333b05afa0b0

i2c Communication

Messages from Pi to Arduino

| Character | Function | |+---------+|---------------------------------| | w | Aim higher | s | Aim lower | a | Aim left | d | Aim right | r | Increase load arm (see note 1) | f | reverse load arm (no effect) | space | Stop all | L | Move until load switch activates | F | Fire and reload (see note 2)

note 1: Arduino will stop automatically when the load sensor comes on.

note 2: For "Fire", if the load switch is not activated, it will perform a load action first, and then move forward until the switch deactivates, and then load again. The end result is that it is reloaded.