# Making Adabot: Part 2

## Overview

Time to make your robot scoot around, blink, and smile.

https://vine.co/v/M7tvVrE6iua

We'll put the skin on in part three.

![](https://cdn-learn.adafruit.com/assets/assets/000/014/360/medium800/3d_printing_IMG_1145.jpg?1392501915)

[For best results, follow the AdaBot part 1 tutorial first!](http://learn.adafruit.com/making-adabot-part-1 "Link: http://learn.adafruit.com/making-adabot-part-1")   
# Making Adabot: Part 2

## Tools / Materials

Let's take inventory of the tools you'll need for this guide.

- hot-glue gun and glue sticks
- wire cutters
- screw driver
- soldering iron and solder

  
And materials...  

- Arduino UNO R3
- PWM / Servo Shield
- 2x stacking shield headers
- 1x micro servo
- 2x continuous rotation servo
- #10 o-rings
- 2x LED matrix w/I2C backpack
- 1x NeoPixel Stick
- RF receiver (momentary)
- RF 4-button transmitter
- 5v 2A power supply (for testing on your desktop)
- 2X 9v batteries (when you're ready to go wireless)
- 2X 9v battery clips
- Female DC power adapter
- Hook-up wire

![](https://cdn-learn.adafruit.com/assets/assets/000/011/751/medium800/3d_printing_IMG_9475.jpg?1382236713)

With regard to the servos, this design was crafted around the dimensions of the popular and inexpensive Hextronik HXT900.   
  
We've modified a set of these for continuous rotation using this guide...  
  
[Modifying Servos for Continuous Rotation](http://learn.adafruit.com/modifying-servos-for-continuous-rotation)  
  
Let's put the pieces together!

# Making Adabot: Part 2

## Neck Servo

Lets start with the neck servo, a small 9g one to be exact. Put a little hot-glue on the underside of the tab and push it into place.

![](https://cdn-learn.adafruit.com/assets/assets/000/011/752/medium800/3d_printing_IMG_9487.jpg?1382237307)

Orientation is important... notice how the servo aligns with the holes.

![](https://cdn-learn.adafruit.com/assets/assets/000/011/725/medium800/3d_printing_IMG_9483.jpg?1382234598)

Make the servo extra secure by adding more hot-glue over the top of the tabs.

![](https://cdn-learn.adafruit.com/assets/assets/000/011/726/medium800/3d_printing_IMG_9489.jpg?1382234628)

If you need a little more detail, you can download a complete photostream of each step.

[Neck Servo Photostream](http://learn.adafruit.com/system/assets/assets/000/011/727/original/Neck_Servo_Photostream.zip?1382234659)
# Making Adabot: Part 2

## Mouth

Grab a NeoPixel stick and consult the [Adafruit NeoPixel Überguide](http://learn.adafruit.com/adafruit-neopixel-uberguide) for hook-up details o' plenty.

![](https://cdn-learn.adafruit.com/assets/assets/000/011/728/medium800/3d_printing_IMG_9528.jpg?1382234802)

Insert the stick into the mouth hole...

![](https://cdn-learn.adafruit.com/assets/assets/000/011/729/medium800/3d_printing_IMG_9529.jpg?1382234825)

This isn't a snap-fit, so you're going to have to secure it with something.

![](https://cdn-learn.adafruit.com/assets/assets/000/011/730/medium800/3d_printing_IMG_9531.jpg?1382234846)

I used a bit ot painters tape on the back and then added a bit of hot-glue on the front to hold it in place.   
  
Connect the Neo Pixel stick as follows:

- VCC --\> 3v  
- GND --\> GND  
- SIG --\> D7 (digital pin)  

[Mouth Photostream](http://learn.adafruit.com/system/assets/assets/000/011/731/original/Mouth_Photostream.zip?1382234866)
# Making Adabot: Part 2

## Eyes

Either solder the LED matrix into place on the backpack, or add some machine pin headers so that you can swap out the matrix as you like.   
  
It's a good idea to pre-assemble all the electronics loosely before gluing everything into place.

![](https://cdn-learn.adafruit.com/assets/assets/000/011/738/medium800/3d_printing_IMG_9522.jpg?1382235182)

Now is a good time to [adjust the address settings](http://learn.adafruit.com/adafruit-16-channel-pwm-slash-servo-shield/faq "Link: http://learn.adafruit.com/adafruit-16-channel-pwm-slash-servo-shield/faq") on each matrix. I found the 0x73 works a treat!

![](https://cdn-learn.adafruit.com/assets/assets/000/014/356/medium800/3d_printing_IMG_9214.jpg?1392486402)

Grab your hook-up wire and create a harness that chains the eyes together and then connects to the Arduino...

![](https://cdn-learn.adafruit.com/assets/assets/000/011/740/medium800/3d_printing_IMG_9525.jpg?1382235218)

Or you can solder the wires directly to the backpack.

![](https://cdn-learn.adafruit.com/assets/assets/000/011/741/medium800/3d_printing_IMG_9526.jpg?1382235232)

Insert each matrix into the eye hole...

![](https://cdn-learn.adafruit.com/assets/assets/000/011/732/medium800/3d_printing_IMG_9532.jpg?1382234920)

And secure with just a touch of hot-glue on the corners.

![](https://cdn-learn.adafruit.com/assets/assets/000/011/733/medium800/3d_printing_IMG_9535.jpg?1382234941)

Double check the wiring.

![](https://cdn-learn.adafruit.com/assets/assets/000/011/734/medium800/3d_printing_IMG_9536.jpg?1382234972)

And pull the ends through the holes in the base of the head.   
  
When you're ready, connect the pins of the eye harness into the Arduino as follows:

- VCC --\> VIN  
- GND --\> GND  
- SDA --\> A4  
- SCL --\> A5  

If you plug VCC into the Arduino 5v line... power to the radio will sag below it's minimum requirement. Alternatively, you could plug VCC directly into your battery source as long as it won't exceed 9 volts.  
[Eyes Photostream](http://learn.adafruit.com/system/assets/assets/000/011/737/original/Eyes_Photostream.zip?1382235132)
# Making Adabot: Part 2

## Footie Wheels

You'll need your continuous rotation servos and some more #10 o-rings (two per hub) to complete this step.

![](https://cdn-learn.adafruit.com/assets/assets/000/011/742/medium800/3d_printing_IMG_9509.jpg?1382235387)

Trim the servo horn down a bit so that it will fit inside the hub.

![](https://cdn-learn.adafruit.com/assets/assets/000/011/743/medium800/3d_printing_IMG_9511.jpg?1382235435)

Make sure it's oriented correctly, and then hot-glue in place.

![](https://cdn-learn.adafruit.com/assets/assets/000/011/744/medium800/3d_printing_IMG_9514.jpg?1382235460)

Screw the hub to the continuous rotation servo and hot-glue the servo into the footie.

![](https://cdn-learn.adafruit.com/assets/assets/000/011/745/medium800/3d_printing_IMG_9516.jpg?1382235492)

Rise. Wash. Repeat for the other foot.

![](https://cdn-learn.adafruit.com/assets/assets/000/011/746/medium800/3d_printing_IMG_9517.jpg?1382235510)

Ready to roll!

[Footie Servo Photostream](http://learn.adafruit.com/system/assets/assets/000/011/747/original/Footie_Servo_Photostream.zip?1382235548)
# Making Adabot: Part 2

## Servo Controller

Take the wires that you passed through the base of the head...

![](https://cdn-learn.adafruit.com/assets/assets/000/011/748/medium800/3d_printing_IMG_9537.jpg?1382235583)

And pass them through the holes in the body. We still have to add the skin... so wait before screwing-in the servo horn.

![](https://cdn-learn.adafruit.com/assets/assets/000/011/749/medium800/3d_printing_IMG_9521.jpg?1382235610)

Pass the wires from the servos in the feet through the body as well.

![](https://cdn-learn.adafruit.com/assets/assets/000/011/750/medium800/3d_printing_IMG_9518.jpg?1382235631)

Swap out the header pins for stacking headers to give you twice as much awesome.

![](https://cdn-learn.adafruit.com/assets/assets/000/014/357/medium800/3d_printing_IMG_9217.jpg?1392487013)

[Adjust the address](http://learn.adafruit.com/adafruit-16-channel-pwm-slash-servo-shield/faq "Link: http://learn.adafruit.com/adafruit-16-channel-pwm-slash-servo-shield/faq") on your [Servo Shield](http://www.adafruit.com/products/1411 "Link: http://www.adafruit.com/products/1411") ... remember that you will need to make adjustments in Adafruit\_PWMServoDriver.h (Adafruit PWM Library).   
  
I've used 0x43 here.  
![](https://cdn-learn.adafruit.com/assets/assets/000/014/355/medium800/3d_printing_IMG_9213.jpg?1392486350)

Grab your [Arduino UNO](http://www.adafruit.com/products/50 "Link: http://www.adafruit.com/products/50") and plug the shield into it.   
  
Connect your servos to the shield PWM inputs as follows:

- Left servo --\> PWM 0  
- Right servo-\> PWM 1  
- Neck servo-\> PWM 2  

# Making Adabot: Part 2

## RF Remote

Hidden treasures abound in the Adafruit store... and this is one. A little radio module with four pins that can be controlled from a battery powered key fob.

![](https://cdn-learn.adafruit.com/assets/assets/000/014/358/medium800/3d_printing_IMG_1118.jpg?1392501744)

We will use those four pins to control the direction of each servo: forward, backward, left, and right.  
  
Connect the pins of the radio module to the Arduino as follows.

- GND -\> GND  
- +5V --\> 5v  
- D0 ----\> A0  
- D1 ----\> A1  
- D2 ----\> A2  
- D3 ----\> A3  

  
  
![](https://cdn-learn.adafruit.com/assets/assets/000/014/359/medium800/3d_printing_IMG_1116.jpg?1392501860)

If your robot keeps resetting or the radio doesn't seem to be working... voltage could be sagging below 5 volts - the radio module doesn't operate reliably below that threshold.

# Making Adabot: Part 2

## Source Code

Here is the code that makes your robot go. You'll need to have a few libraries installed in the Arduino IDE.

- [PWM Servo Driver Library](https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library)
- [LED Backpack Library](https://github.com/adafruit/Adafruit-LED-Backpack-Library)
- [GFX Library](https://github.com/adafruit/Adafruit-GFX-Library) (used in the LED Backpack Library)
- [BusIO Library](https://github.com/adafruit/Adafruit_BusIO)
- [Neo Pixel Library](https://github.com/adafruit/Adafruit_NeoPixel)

When you're ready to go wireless, cut and tin the leads of one of the 9V battery clips and insert the wires into the PWM shield PC terminal.  
  
The other battery clip is for the Arduino... via the barrel connector.

```auto
#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
#include <Adafruit_NeoPixel.h>
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"

Adafruit_NeoPixel mouth = Adafruit_NeoPixel(8, 7, NEO_GRB + NEO_KHZ800);
Adafruit_PWMServoDriver servos = Adafruit_PWMServoDriver();
Adafruit_8x8matrix eyes = Adafruit_8x8matrix();

// Eye bitmaps are stored in program memory.
static uint8_t PROGMEM
blinkImg[][8] = {
  { 
    B00111100,
    B01111110,
    B11111111,
    B11111111,
    B11111111,
    B11111111,
    B01111110,
    B00111100 }
  ,
  { 
    B00000000,
    B01111110,
    B11111111,
    B11111111,
    B11111111,
    B11111111,
    B01111110,
    B00111100 }
  ,
  { 
    B00000000,
    B00000000,
    B00111100,
    B11111111,
    B11111111,
    B11111111,
    B00111100,
    B00000000 }
  ,
  { 
    B00000000,
    B00000000,
    B00000000,
    B00111100,
    B11111111,
    B01111110,
    B00011000,
    B00000000 }
  ,
  { 
    B00000000,
    B00000000,
    B00000000,
    B00000000,
    B10000001,
    B01111110,
    B00000000,
    B00000000 } 
};

// Analog threshold used to determine when FOB buttons are pressed.
const byte BUTTON_THRESHOLD = 50;

uint8_t
blinkIndex[] = { 1, 2, 3, 4, 3, 2, 1 }, // Blink bitmap sequence.
blinkCountdown = 100,  // Countdown to next blink (in frames).
gazeCountdown  =  75,  // Countdown to next eye movement.
gazeFrames     =  50;

int8_t
eyeX = 3, eyeY = 3,     // Current eye position.
newX = 3, newY = 3,     // Next eye position.
dX   = 0, dY   = 0;  

unsigned long tme = 0;  // Last time we processed a mouth animation.
unsigned long slc = 50; // Milliseconds between mouth animations.
unsigned long ms = 0;   // Used to track a millis() time-slice.

int stt = 0;            // Revolving start position for the neck servo.
int pos = 0;            // Current 'moving' position of the neck servo.
int dst = 0;            // Random destination for the neck servo.
int dur = 0;            // Number of frames used by the easing function.
int fme = 0;            // Animation frame counter.

void setup() {
  // Make sure to adjust the address jumpers on the shield, and 
  // in Adafruit_PWMServoDriver.h on line ~48 -- I've used 0x43.
  eyes.begin(0x73);
  // Brightness is set _very_ low to conserve power.
  eyes.setBrightness(1);

  // We're using a Neo Pixel Stick for the mouth.
  mouth.begin();
  mouth.show();

  // We have two servos in the feet and one in the neck.
  servos.begin();
  servos.setPWMFreq(60);
}

void loop() {

  // Every few milliseconds we will animate the mouth.
  ms = millis();
  if ( tme + slc < ms ) {
    tme = ms;

    // 10% chance that the mouth will animate.
    if ( random( 1, 10 ) == 1 ) {
      // LEDs are set to ~1% brightness.
      animateMouth(mouth.Color(0, 0, 5), 15);
    } 
    else {
      // LEDs are set to ~10% brightness.
      animateMouth(mouth.Color(0, 0, 25), 15);
    }

    // Every few milliseconds we will update the neck position.
    if ( pos != dst && fme < dur )
    {
      // Update position until we arrive at dst.
      pos = (int)easeInOut( fme, stt, ( dst - stt ), dur );
      fme += 1;
      servos.setPWM(2, 0, pos);
    } 
    else {
      // Advance to the new destination.
      stt = pos;
      // Adjust this range if necessary.
      dst = random(150, 350);
      fme = 0;
      dur = 50;
    }
  }

  // Mirror animation of each 8x8 eye matrix.
  eyes.clear();
  eyes.drawBitmap(0, 0,
  // Blinking? Yes, look-up bitmap #. No, show bitmap 0.
  blinkImg[ (blinkCountdown < sizeof(blinkIndex)) ? blinkIndex[blinkCountdown] : 0 ], 8, 8, LED_ON);
  // Decrement blink counter.  At end, set random time for next blink.
  if(--blinkCountdown == 0) blinkCountdown = random(5, 180);

  // Add a pupil (2x2 black square) atop the blinky eyeball bitmap.
  // Periodically, the pupil moves to a new position...
  if(--gazeCountdown <= gazeFrames) {
    // Eyes are in motion - draw pupil at interim position.
    eyes.fillRect(
    newX - (dX * gazeCountdown / gazeFrames),
    newY - (dY * gazeCountdown / gazeFrames),
    2, 2, LED_OFF);
    if(gazeCountdown == 0) {    // Last frame?
      eyeX = newX; 
      eyeY = newY; // Yes.  What's new is old, then...
      do { // Pick random positions until one is within the eye circle.
        newX = random(7); 
        newY = random(7);
        dX   = newX - 3;  
        dY   = newY - 3;
      } 
      while((dX * dX + dY * dY) >= 10);        // Thank you Pythagoras.
      dX            = newX - eyeX;             // Horizontal distance to move.
      dY            = newY - eyeY;             // Vertical distance to move.
      gazeFrames    = random(3, 15);           // Duration of eye movement.
      gazeCountdown = random(gazeFrames, 120); // Count to end of next movement.
    }
  } 
  else {
    // Not in motion yet -- draw pupil at current static position.
    eyes.fillRect(eyeX, eyeY, 2, 2, LED_OFF);
  }
  eyes.writeDisplay();

  // Now, lets check to see if any of the buttons on the FOB are pressed.
  byte a = analogRead(3); // forward right
  byte b = analogRead(2); // forward left
  byte c = analogRead(1); // reverse right
  byte d = analogRead(0); // reverse left

  if ( ( b > BUTTON_THRESHOLD && d > BUTTON_THRESHOLD ) || ( b < BUTTON_THRESHOLD && d < BUTTON_THRESHOLD ) ) {
    // Turn servo 0 off if FOB buttons B + D are both pressed or released.
    servos.setPWM(0, 0, 0);
  } 
  else {
    if ( b > BUTTON_THRESHOLD ) {
      // FOB button B is pressed... forward left.
      servos.setPWM(0, 0, 400);
    }
    if ( d > BUTTON_THRESHOLD ) {
      // FOB button D is pressed... reverse left.
      servos.setPWM(0, 0, 350);
    }
  }

  if ( ( a > BUTTON_THRESHOLD && c > BUTTON_THRESHOLD ) || ( a < BUTTON_THRESHOLD && c < BUTTON_THRESHOLD ) ) {
    // Turn servo 1 off if FOB buttons A + C are both pressed or released.
    servos.setPWM(1, 0, 0);
  } 
  else {
    if ( a > BUTTON_THRESHOLD ) {
      // FOB button A is pressed... forward left.
      servos.setPWM(1, 0, 350);
    }
    if ( c > BUTTON_THRESHOLD ) {
      // FOB button C is pressed... reverse left.
      servos.setPWM(1, 0, 400);
    }
  }
}

void animateMouth(uint32_t c, uint8_t wait) {
  // Quick loop that does a symmetric animation on a single Neo Pixel Strip.
  for(uint16_t i=( mouth.numPixels() / 2 ); i<mouth.numPixels(); i++) {
    // Pixels 3, 2, 1, and 0.
    mouth.setPixelColor(mouth.numPixels() - i - 1, c);
    // Pixels 4, 5, 6, and 7.
    mouth.setPixelColor(i, c);
    mouth.show();
    delay(wait);
  }
}

float easeInOut( float t, float b, float c, float d )
{
  // Function used to smooth servo movements.
  if ((t/=d/2) < 1) 
    return c/2*t*t*t + b;

  return c/2*((t-=2)*t*t + 2) + b;
}
```


## Featured Products

### Adafruit METRO 328 Fully Assembled - Arduino IDE compatible

[Adafruit METRO 328 Fully Assembled - Arduino IDE compatible](https://www.adafruit.com/product/50)
We sure love the ATmega328 here at Adafruit, and we use them&nbsp;_a lot_&nbsp;for our own projects. The processor has plenty of GPIO, Analog inputs, hardware UART SPI and I2C, timers and PWM galore - just enough for most simple projects. When we need to go small, we use a <a...></a...>

Out of Stock
[Buy Now](https://www.adafruit.com/product/50)
[Related Guides to the Product](https://learn.adafruit.com/products/50/guides)
### Adafruit 16-Channel 12-bit PWM/Servo Shield - I2C interface

[Adafruit 16-Channel 12-bit PWM/Servo Shield - I2C interface](https://www.adafruit.com/product/1411)
You want to make a cool Arduino robot, maybe a hexapod walker, or maybe just a piece of art with a lot of moving parts. Or maybe you want to drive a lot of LEDs with precise PWM output. Then you realize that the Arduino has only a few PWM outputs, and maybe those outputs are conflicting with...

Out of Stock
[Buy Now](https://www.adafruit.com/product/1411)
[Related Guides to the Product](https://learn.adafruit.com/products/1411/guides)
### Shield stacking headers for Arduino (R3 Compatible)

[Shield stacking headers for Arduino (R3 Compatible)](https://www.adafruit.com/product/85)
_“How could something so simple be so useful?”&nbsp;_

We heard once that&nbsp;in the 4th millennium B.C.&nbsp;some guy asked the person who invented the wheel that question.&nbsp; The person who invented the wheel’s answer, we were told, was...

In Stock
[Buy Now](https://www.adafruit.com/product/85)
[Related Guides to the Product](https://learn.adafruit.com/products/85/guides)
### Micro servo

[Micro servo](https://www.adafruit.com/product/169)
Tiny little servo can rotate approximately 180 degrees (90 in each direction) and works just like the standard kinds you're used to but _smaller_. You can use any servo code, hardware, or library to control these servos. Good for beginners who want to make stuff move without...

In Stock
[Buy Now](https://www.adafruit.com/product/169)
[Related Guides to the Product](https://learn.adafruit.com/products/169/guides)
### Adafruit Small 1.2" 8x8 LED Matrix w/I2C Backpack - Blue

[Adafruit Small 1.2" 8x8 LED Matrix w/I2C Backpack - Blue](https://www.adafruit.com/product/1052)
What's better than a single LED? Lots of LEDs! A fun way to make a small display is to use an [8x8 matrix](https://www.adafruit.com/category/37_88) or a [4-digit 7-segment display](https://www.adafruit.com/category/37_103). Matrices like these are...

Out of Stock
[Buy Now](https://www.adafruit.com/product/1052)
[Related Guides to the Product](https://learn.adafruit.com/products/1052/guides)
### NeoPixel Stick - 8 x 5050 RGB LED with Integrated Drivers

[NeoPixel Stick - 8 x 5050 RGB LED with Integrated Drivers](https://www.adafruit.com/product/1426)
Make your own little LED strip arrangement with this stick of NeoPixel LEDs. We crammed 8 of the tiny 5050 (5mm x 5mm) smart RGB LEDs onto a PCB with mounting holes and a chainable design. Use only one microcontroller pin to control as many as you can chain together! Each LED is addressable as...

In Stock
[Buy Now](https://www.adafruit.com/product/1426)
[Related Guides to the Product](https://learn.adafruit.com/products/1426/guides)
### Simple RF M4 Receiver - 315MHz Momentary Type

[Simple RF M4 Receiver - 315MHz Momentary Type](https://www.adafruit.com/product/1096)
These Simple RF receivers are the easiest way possible to add wireless control, painlessly! There's no programming, configuring or addressing - simply power the receiver with ~5 VDC and press the buttons on our matching RF keyfob remote. When the A button is pressed, it activates the first...

In Stock
[Buy Now](https://www.adafruit.com/product/1096)
[Related Guides to the Product](https://learn.adafruit.com/products/1096/guides)
### Keyfob 4-Button RF Remote Control - 315MHz

[Keyfob 4-Button RF Remote Control - 315MHz](https://www.adafruit.com/product/1095)
This 4-button keyfob remote goes with [our three basic 315MHz RF receiver modules](http://adafruit.com/category/112). It will work with all of them, sending out one of four commands that match up with the four outputs. Its small and light weight and will work up to 25 feet away...

Out of Stock
[Buy Now](https://www.adafruit.com/product/1095)
[Related Guides to the Product](https://learn.adafruit.com/products/1095/guides)

## Related Guides

- [Adafruit LED Backpacks](https://learn.adafruit.com/adafruit-led-backpack.md)
- [Ladyada's Learn Arduino - Lesson #0](https://learn.adafruit.com/ladyadas-learn-arduino-lesson-number-0.md)
- [2.2" TFT Display](https://learn.adafruit.com/2-2-tft-display.md)
- [36mm LED Pixels](https://learn.adafruit.com/36mm-led-pixels.md)
- [Adafruit Proto Screw Shield](https://learn.adafruit.com/adafruit-proto-screw-shield.md)
- [How to Choose a Microcontroller](https://learn.adafruit.com/how-to-choose-a-microcontroller.md)
- [LED Backpack Displays on Raspberry Pi and BeagleBone Black](https://learn.adafruit.com/led-backpack-displays-on-raspberry-pi-and-beaglebone-black.md)
- [Let’s Put LEDs in Things!](https://learn.adafruit.com/lets-put-leds-in-things.md)
- [2.8" TFT Touchscreen](https://learn.adafruit.com/2-8-tft-touchscreen.md)
- [DS1307 Real Time Clock Breakout Board Kit](https://learn.adafruit.com/ds1307-real-time-clock-breakout-board-kit.md)
- [WiFi Candy Bowl Monitor](https://learn.adafruit.com/wifi-candy-bowl.md)
- [Character LCDs](https://learn.adafruit.com/character-lcds.md)
- [Experimenting with NeverWet + Electronics](https://learn.adafruit.com/neverwet-electronics.md)
- [Low Power Coin Cell Voltage Logger](https://learn.adafruit.com/low-power-coin-cell-voltage-logger.md)
- [Track Your Treats: Halloween Candy GPS Tracker](https://learn.adafruit.com/track-your-treats-halloween-candy-gps-tracker.md)
- [Star Fragment IoT Lamp](https://learn.adafruit.com/star-fragment-iot-lamp.md)
