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.
// 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
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
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
// 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
// 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
// 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
// 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.