makernestOrigins · all chapters

Origins · Chapter 11 · Diagnose

Sabotage

Somebody broke it. Find out how.

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: Five broken bench circuits to fix, one a week

Each one is a bench circuit you already know, built wrong on purpose. Build it exactly as shown, see what it does, and find the fault without looking at the answer.

Fault 1 · Week 1 · kindest

Build it like this: Build bench 01 exactly as it says, except the LED: short leg in column 5, long leg in column 6.

As built, wrong on purpose

TOPBOTTOM+LED2202209V +9V −1234567891011121314151617

It should: The LED lights when the battery is clipped on.
It does: Nothing lights. The battery is new.

Hint 1

Is power getting into the breadboard at all? How could you check without a meter?

Hint 2

Every part in this loop is happy either way round except one.

Hint 3

Look at the LED's two legs. Which one is longer, and which column is it in?

The answer. Only when you have really tried.

The LED is in backwards. An LED only lets power through from the long leg to the short one. Turn it round.

Fault 2 · Week 2

Build it like this: Build bench 06, but push button one's G wire into column 3 top, next to its S wire, instead of column 5 bottom.

As built, wrong on purpose

TOPBOTTOM12 S12 G10 S10 G1234567891011121314151617
Download .ino
// MakerNest Origins · bench 06 · a push button that counts, and a second one that undoes
// Button one on row 12 adds one. Button two on row 10 takes one away.
// No resistors: the board's own pull-up keeps each pin HIGH until a button pulls it to G.

const int ADD_PIN = 12;
const int UNDO_PIN = 10;
const unsigned long SETTLE = 30;   // milliseconds to ignore after a press. Try 0.

int count = 0;
bool addWasDown = false;
bool undoWasDown = false;
unsigned long lastChange = 0;

void setup() {
  pinMode(ADD_PIN, INPUT_PULLUP);
  pinMode(UNDO_PIN, INPUT_PULLUP);
  Serial.begin(9600);
  Serial.println("Count: 0");
}

void loop() {
  bool addDown = digitalRead(ADD_PIN) == LOW;     // pressed pulls the pin LOW
  bool undoDown = digitalRead(UNDO_PIN) == LOW;

  if (millis() - lastChange >= SETTLE) {
    if (addDown && !addWasDown) {
      count = count + 1;
      Serial.print("Count: ");
      Serial.println(count);
      lastChange = millis();
    }
    if (undoDown && !undoWasDown && count > 0) {
      count = count - 1;
      Serial.print("Count: ");
      Serial.println(count);
      lastChange = millis();
    }
    addWasDown = addDown;
    undoWasDown = undoDown;
  }
}

It should: Each press adds one.
It does: The count goes up once by itself, and after that no press of button one ever counts.

Hint 1

Watch the Serial Monitor without touching anything. Is the board seeing a press that isn't happening?

Hint 2

What joins two holes on a breadboard, even with no part in them?

Hint 3

Look at the two wires for button one. Which column is each of them in?

The answer. Only when you have really tried.

Both of button one's wires are in column 3, top half. The five holes in a column are joined underneath, so S is joined to G all the time and the board thinks the button is held down forever. G belongs on the diagonally opposite leg: column 5, bottom half.

Fault 3 · Week 3

Build it like this: Build bench 02, but leave the 10 kΩ resistor out.

As built, wrong on purpose

TOPBOTTOMLDR+LED220A0 VA0 SA0 G12 S12 G1234567891011121314151617
Download .ino
// MakerNest Origins · bench 02 · an LED that switches on below a number
// The light sensor on A0 gives a number. Below LINE, the LED on row 12 comes on.
// Open Tools, Serial Monitor (9600) to watch the number.

const int SENSOR_PIN = A0;   // light sensor and 10k resistor meet here
const int LED_PIN = 12;      // the LED's long leg is wired to row 12
const int LINE = 300;        // your number: below this, the LED comes on

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

void loop() {
  int light = analogRead(SENSOR_PIN);   // 0 is black dark, 1023 is very bright
  Serial.println(light);

  if (light < LINE) {
    digitalWrite(LED_PIN, HIGH);
  } else {
    digitalWrite(LED_PIN, LOW);
  }
  delay(500);
}

It should: The LED comes on when you cover the sensor.
It does: The number stays high and barely moves. The LED never comes on.

Hint 1

Does the number in the Serial Monitor change when you cover the sensor?

Hint 2

A0 is measuring how the power is shared between two parts. How many parts are sharing it?

Hint 3

Look at what joins column 6 to column 10.

The answer. Only when you have really tried.

The 10 kΩ is missing. Without it, the sensor has nothing to share the power with, so A0 always sees nearly all of it. Put it back from column 6 to column 10.

Fault 4 · Week 4

Build it like this: Build bench 08, but put the yellow LED's resistor from column 9 to column 10 instead of 8 to 10.

As built, wrong on purpose

TOPBOTTOM+RED220+YEL220+GRN22012 S12 G13 S13 G10 S10 G1234567891011121314151617
Download .ino
// MakerNest Origins · bench 08 · traffic lights with your own timings
// Red on row 12, yellow on row 13, green on row 10. Change the four numbers to make
// your own crossing. All times are in milliseconds: 1000 is one second.

const int RED_PIN = 12;
const int YELLOW_PIN = 13;
const int GREEN_PIN = 10;

const unsigned long RED_TIME = 5000;
const unsigned long RED_AND_YELLOW_TIME = 1500;
const unsigned long GREEN_TIME = 5000;
const unsigned long YELLOW_TIME = 2000;

void lights(bool red, bool yellow, bool green) {
  digitalWrite(RED_PIN, red ? HIGH : LOW);
  digitalWrite(YELLOW_PIN, yellow ? HIGH : LOW);
  digitalWrite(GREEN_PIN, green ? HIGH : LOW);
}

void setup() {
  pinMode(RED_PIN, OUTPUT);
  pinMode(YELLOW_PIN, OUTPUT);
  pinMode(GREEN_PIN, OUTPUT);
}

void loop() {
  lights(true, false, false);   // stop
  delay(RED_TIME);
  lights(true, true, false);    // get ready
  delay(RED_AND_YELLOW_TIME);
  lights(false, false, true);   // go
  delay(GREEN_TIME);
  lights(false, true, false);   // stop if you can
  delay(YELLOW_TIME);
}

It should: Red, red and yellow, green, yellow.
It does: Red and green work. Yellow never lights.

Hint 1

Two of three work, so the board and the sketch are probably fine. What is different about the third?

Hint 2

Follow the loop for yellow with your finger, from row 13 S, through the LED, back to G.

Hint 3

Which column is the yellow LED's short leg in, and is anything else in that column?

The answer. Only when you have really tried.

The resistor doesn't share a column with the LED's short leg, so yellow's loop is open. Move its end from column 9 to column 8.

Fault 5 · Week 5 · hardest

Build it like this: Build bench 02 exactly, every wire correct. Upload the fault 5 sketch instead of bench sketch 02.

As built, wrong on purpose

TOPBOTTOMLDR10k+LED220A0 VA0 SA0 G12 S12 G1234567891011121314151617
Download .ino
// MakerNest Origins · bench fault 5
// This is bench 02's sketch, and the circuit on the page is wired exactly like bench 02.
// Something is broken. Don't change anything until you know what.

const int SENSOR_PIN = A0;
const int LED_PIN = 10;
const int LINE = 300;

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

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

  if (light < LINE) {
    digitalWrite(LED_PIN, HIGH);
  } else {
    digitalWrite(LED_PIN, LOW);
  }
  delay(500);
}

It should: The LED comes on when you cover the sensor.
It does: The number in the Serial Monitor goes up and down perfectly. The LED never comes on.

Hint 1

The number is right, so the sensor half works. The fault is in the other half, or somewhere you can't see.

Hint 2

The circuit is exactly bench 02's. Is the sketch?

Hint 3

Read the sketch out loud, line by line. Which row does it think the LED is on?

The answer. Only when you have really tried.

The sketch says LED_PIN is 10, but the LED is wired to row 12. Nothing on the breadboard is wrong. Change it to 12, or move the wire to row 10. Sometimes the fault is in the code.

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 CreatureYour Own Machine →