makernestOrigins · all chapters

Origins · Chapter 09 · Place

Stakeout

Where it sits decides what it knows.

Sketch 09 Stakeout

Copy it, open File, New Sketch, select everything in the new window and paste over it. Check Tools, Board says Arduino Uno and Tools, Port shows your board, then press Upload.

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 soil sensor that tells you when a plant needs water

Wet soil carries power better than dry soil. Powering the probe only while it reads keeps it from corroding away.

You need

On the breadboard

TOPBOTTOM+LED22012 S12 G1234567891011121314151617

Build it

  1. Join the probe to its small board with the two-wire lead.
  2. Female-to-female from the small board: VCC to row 13 S, GND to A1 G, AO to A1 S. Leave DO empty.
  3. LED and 220 Ω as in bench 02: long leg column 13, short leg column 14, resistor 14 to 17, top half. Row 12 S to column 13, row 12 G to column 17.
  4. Upload bench sketch 09 and open the Serial Monitor.
  5. Hold the probe in air, then dip the forks in a cup of water. Write down both numbers. Set DRY_ABOVE about a third of the way down from the air number.
Download .ino
// MakerNest Origins · bench 09 · a soil sensor that tells you when a plant needs water
// The probe goes in the soil. Its board is powered from row 13, and only for a moment
// at each reading: power left on all the time slowly eats the probe away.
// Its AO pin goes to A1. The LED on row 12 comes on when the soil is dry.

const int POWER_PIN = 13;     // the sensor board's VCC wire is on row 13 S
const int SOIL_PIN = A1;      // the sensor board's AO wire is on A1 S
const int LED_PIN = 12;
const int DRY_ABOVE = 700;    // higher number = drier soil. Measure your own: see the page.
const unsigned long EVERY = 5000;

void setup() {
  pinMode(POWER_PIN, OUTPUT);
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(POWER_PIN, LOW);
  Serial.begin(9600);
}

void loop() {
  digitalWrite(POWER_PIN, HIGH);   // wake the sensor
  delay(20);
  int soil = analogRead(SOIL_PIN);
  digitalWrite(POWER_PIN, LOW);    // and put it straight back to sleep

  Serial.println(soil);
  if (soil > DRY_ABOVE) {
    digitalWrite(LED_PIN, HIGH);   // dry: water me
  } else {
    digitalWrite(LED_PIN, LOW);
  }
  delay(EVERY);
}
What you'll see

Push the forks into a plant pot, not touching the plant. Dry soil: LED on. Water it and wait a minute: LED off.

Break it on purpose

Move the VCC wire from row 13 S to row 13 V. It still works, but now the probe has power all the time, and in a few weeks the forks start to rust. Put it back.

Then try

Find the number for just right, not too wet and not too dry, and add a second line.

Safely: Only the forks go in the soil. Keep the small board and the shield dry.

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.

← The DoorkeeperThe Creature →