makernestOrigins · all chapters

Origins · Chapter 10 · Dress

The Creature

Give it a body. Keep it working.

Sketch 09, still on your board

Nothing new to upload this chapter: sketch 09 stays on your board. If you need to upload it again, here it is.

Download .ino
// 09 Stakeout
// The Maker's Book of Origins, chapter 09. Upload it, then turn back to the book.
// makernest.com/origins/09
// MakerNest Origins is a brand of Innointel Global Private Limited.

#include <MakerNestOrigins.h>

// ---- the cold rule, with its gap (chapter 04)
bool coldNow() {
  static bool alarm = false;
  if (machine.settings.coldLine == NOT_SET) return false;      // no line chosen yet: no opinion
  int start = machine.settings.coldLine;
  int stop = (machine.settings.stopAt == NOT_SET) ? start : machine.settings.stopAt;
  float t = machine.watchedTemperature();                      // sensor A, or B if you chose B (chapter 05)
  if (!alarm && t < start) alarm = true;                       // below START: it starts
  if (alarm && t >= stop) alarm = false;                       // back up to STOP AT: it stops
  return alarm;
}

// ---- two places, one gap (chapter 05)
bool apartNow() {
  if (machine.settings.apartBy == 0) return false;             // no gap chosen yet
  float gap = machine.settings.apartBy / 2.0;                  // stored in half degrees
  return fabs(machine.temperatureA() - machine.temperatureB()) > gap;
}

// ---- what it does about it (chapters 02 and 03)
void showIt(bool cold, bool apart) {
  uint8_t w = machine.settings.whenCold;
  if (apart) {                                                 // apart: orange, and the buzzer
    machine.ring(ORANGE);
    machine.buzzerBeep(true);
    return;
  }
  if (cold && (w == WHEN_RING || w == WHEN_BOTH)) machine.ring(RED); else machine.ringNormal();
  if (w == WHEN_ALWAYS) machine.buzzer(true);                  // always on: it has stopped asking
  else { machine.buzzer(false); machine.buzzerBeep(cold && (w == WHEN_BUZZER || w == WHEN_BOTH)); }
}

bool wasCold = false;
bool tooManyFired = false;

void setup() {
  machine.begin(9, "09|STAKEOUT");
  machine.homeShows(SHOW_A | SHOW_B | SHOW_COUNT | SHOW_NOTEBOOK);
  machine.useScreen(SCR_TOO_MANY);
  machine.useScreen(SCR_LOG);
  machine.useScreen(SCR_SEQUENCE);
  machine.useScreen(SCR_RUN_NOW);
  machine.useScreen(SCR_START_WITH);
  machine.useScreen(SCR_COLD_LINE);
  machine.useScreen(SCR_STOP_AT);
  machine.useScreen(SCR_SETTLE);
  machine.useScreen(SCR_KEEP_COUNT);
  machine.useScreen(SCR_WRITE_EVERY);
  machine.useScreen(SCR_APART_BY);
  machine.useScreen(SCR_WATCHES);
  machine.useScreen(SCR_NORMAL_COLOUR);
  machine.useScreen(SCR_WHEN_COLD);
  machine.useScreen(SCR_TEST);
}

void loop() {
  machine.update();
  bool cold = coldNow();
  bool apart = apartNow();
  showIt(cold, apart);

  // TOO MANY openings in the last hour: run the sequence once. Then wait until it calms down by your gap (chapter 04).
  if (machine.settings.tooMany) {
    int start = machine.settings.coldLine == NOT_SET ? 0 : machine.settings.coldLine;
    int stop = machine.settings.stopAt == NOT_SET ? start : machine.settings.stopAt;
    int gap = max(1, stop - start);
    uint8_t n = machine.openingsInLastHour();
    if (!tooManyFired && n >= machine.settings.tooMany) { tooManyFired = true; machine.runSequence(); }
    if (tooManyFired && n + gap <= machine.settings.tooMany) tooManyFired = false;
  }
  if (machine.settings.startWith == 1 && cold && !wasCold) machine.runSequence();
  wasCold = cold;
  // The display sleeps after a minute and a half to save the battery. Turn the dial to wake it.
  // Sketch 09 stays on through chapters 10 and 11.
}

Your settings and your notebook stay saved on the board when you upload.

Wiring

Nothing new to wire in this chapter. Here is the whole shield, so you can check every wire.

The whole shield, by the end of the book

GVSROW 2SENSOR AROW 3DIALROW 4DIALROW 5DIALROW 6BUZZERROW 7SENSOR BROW 8DOOR SWITCHROW 9SWITCH BOARDROW 11LIGHT RINGA4DISPLAYA5DISPLAYPOWER 3V3DISPLAY

On the bench: A servo that waves when somebody walks past

A servo turns to the angle you send it. A passing shadow is a sudden drop in light, so the light sensor can notice somebody walking past.

You need

On the breadboard

TOPBOTTOMLDR10kA0 VA0 SA0 G1234567891011121314151617

Build it

  1. Push the servo's plug straight onto row 10: brown on G, red on V, orange on S.
  2. Build the sensor half of bench 02: light sensor in columns 3 and 6, the 10 kΩ from 6 to 10, A0 V to 3, A0 S to 6, A0 G to 10.
  3. Press a horn onto the servo.
  4. Upload bench sketch 10, unplug the USB lead and switch on the battery pack.
  5. Put it where people walk past, with the sensor facing the path.
Download .ino
// MakerNest Origins · bench 10 · a servo that waves when somebody walks past
// Nobody can walk past without blocking some light. The light sensor on A0 keeps a slow
// average of the room. A sudden drop below that average means a shadow: somebody is there.
// The servo on row 10 waves three times.

#include <Servo.h>

const int SENSOR_PIN = A0;
const int SERVO_PIN = 10;
const int DROP = 60;          // how big a sudden drop counts as a shadow
const int REST = 90;          // the arm's resting angle, in degrees

Servo arm;
float average = 0;

void wave() {
  for (int i = 0; i < 3; i++) {
    arm.write(REST - 40);
    delay(300);
    arm.write(REST + 40);
    delay(300);
  }
  arm.write(REST);
}

void setup() {
  arm.attach(SERVO_PIN);
  arm.write(REST);
  Serial.begin(9600);
  average = analogRead(SENSOR_PIN);
}

void loop() {
  int light = analogRead(SENSOR_PIN);
  Serial.print(light);
  Serial.print("   average ");
  Serial.println((int)average);

  if (light < average - DROP) {
    wave();
    delay(1500);                      // let the person walk on
    average = analogRead(SENSOR_PIN); // and start the average again
  } else {
    average = average * 0.98 + light * 0.02;   // follow the room slowly
  }
  delay(100);
}
What you'll see

Walk past it slowly. It waves three times.

Break it on purpose

Set DROP to 5. Now it waves at clouds.

Then try

Make it wave only after dark, using a number from bench 02.

Safely: Run it from the battery pack, and switch the pack off and on first so the ring goes dark. If the board restarts every time the arm moves, the servo is asking for more power than the board can give: the pack may be low, or the USB socket is too weak.

How the bench works

Bench sketches replace your chapter sketch while you use them. Your settings and your notebook stay saved on the board. When you finish, upload the chapter's sketch again and your machine is back exactly as it was.

While a bench sketch runs, the display and the ring freeze on whatever they last showed. That is normal.

If the light ring is still lit from your chapter sketch, switch everything off and on again before you start. It goes dark and stops using power the bench needs.

The breadboard has 17 numbered columns and two halves, top and bottom. The five holes in one column of one half are joined underneath. Nothing joins across the gap in the middle.

Every jumper from the shield has a female end: push it onto a shield pin. The male end goes into the breadboard. G, V and S are the same three pins you have used all book: ground, power, signal.

Never put a wire straight from V to G. That is a short circuit.

Ask Milo

Stuck, curious, or something looks wrong? Tell me what you see.

You can paste your code or an error message here too.

← StakeoutSabotage →