{"examples":[{"slug":"blink-and-count","title":"Blink + count","description":"Blink the on-board LED and print a running blink count over Serial.","english":"Blink the built-in LED, and count the blinks over the serial port.\n\nSet up the built-in LED pin as an output so we can turn it on and off.\nStart the serial connection at 9600 baud.\n\nKeep a counter for how many times we've blinked, starting at 0.\n\nThen, over and over, forever:\n  Turn the LED on.\n  Wait 500 milliseconds.\n  Turn the LED off.\n  Wait another 500 milliseconds.\n  Add 1 to the blink counter.\n  Print \"blink \" followed by the counter to the serial port.\n","app_html":"","settings":{},"by_lang":{"cpp":{"code":"void setup() {\n  pinMode(LED_BUILTIN, OUTPUT);\n  Serial.begin(9600);\n}\n\nint blinkCount = 0;\nvoid loop() {\n  digitalWrite(LED_BUILTIN, HIGH);\n  delay(500);\n  digitalWrite(LED_BUILTIN, LOW);\n  delay(500);\n  blinkCount++;\n  Serial.print(\"blink \");\n  Serial.println(blinkCount);\n}","links":[{"label":"setup_begin","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"setup_led_output","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"setup_serial_begin","code_end":3,"code_start":3,"english_end":4,"english_start":4},{"label":"setup_end","code_end":4,"code_start":4,"english_end":4,"english_start":3},{"label":"global_counter","code_end":6,"code_start":6,"english_end":6,"english_start":6},{"label":"loop_begin","code_end":7,"code_start":7,"english_end":8,"english_start":8},{"label":"loop_led_on","code_end":8,"code_start":8,"english_end":9,"english_start":9},{"label":"loop_delay_on","code_end":9,"code_start":9,"english_end":10,"english_start":10},{"label":"loop_led_off","code_end":10,"code_start":10,"english_end":11,"english_start":11},{"label":"loop_delay_off","code_end":11,"code_start":11,"english_end":12,"english_start":12},{"label":"loop_increment","code_end":12,"code_start":12,"english_end":13,"english_start":13},{"label":"loop_print_label","code_end":13,"code_start":13,"english_end":14,"english_start":14},{"label":"loop_print_count","code_end":14,"code_start":14,"english_end":14,"english_start":14},{"label":"loop_end","code_end":15,"code_start":15,"english_end":14,"english_start":8}],"structure":"{\"functions\":[{\"name\":\"setup\",\"params\":[],\"english_start\":3,\"english_end\":4,\"summary\":\"Configure the built-in LED as an output and start serial communication at 9600 baud.\",\"calls\":[{\"english_start\":3,\"english_end\":3},{\"english_start\":4,\"english_end\":4}]},{\"name\":\"loop\",\"params\":[],\"english_start\":8,\"english_end\":14,\"summary\":\"Blink the built-in LED forever, count each blink, and print the count over Serial.\",\"calls\":[{\"english_start\":9,\"english_end\":9},{\"english_start\":10,\"english_end\":10},{\"english_start\":11,\"english_end\":11},{\"english_start\":12,\"english_end\":12},{\"english_start\":13,\"english_end\":13},{\"english_start\":14,\"english_end\":14}]}]}"},"python":{"code":"# Built-in LED setup would be hardware-specific; this script simulates the blink.\n# Serial at 9600 baud would be configured here in hardware-specific code.\ncount = 0\nwhile True:\n    print(\"LED on\")\n    time.sleep(0.5)\n    print(\"LED off\")\n    time.sleep(0.5)\n    count += 1\n    print(f\"blink {count}\")\nimport time","links":[{"label":"comment","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"comment","code_end":2,"code_start":2,"english_end":4,"english_start":4},{"label":"statement","code_end":3,"code_start":3,"english_end":6,"english_start":6},{"label":"loop","code_end":4,"code_start":4,"english_end":8,"english_start":8},{"label":"loop_body","code_end":6,"code_start":5,"english_end":10,"english_start":9},{"label":"loop_body","code_end":8,"code_start":7,"english_end":12,"english_start":11},{"label":"statement","code_end":9,"code_start":9,"english_end":13,"english_start":13},{"label":"statement","code_end":10,"code_start":10,"english_end":14,"english_start":14},{"label":"import","code_end":11,"code_start":11,"english_end":1,"english_start":1}],"structure":"{\"functions\":[]}"},"ruby":{"code":"pinMode(LED_BUILTIN, OUTPUT)\nSerial.begin(9600)\nblink_count = 0\nloop do\n  digitalWrite(LED_BUILTIN, HIGH)\n  sleep(0.5)\n  digitalWrite(LED_BUILTIN, LOW)\n  sleep(0.5)\n  blink_count += 1\n  Serial.print(\"blink \")\n  Serial.println(blink_count)\nend","links":[{"label":"setup","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"setup","code_end":2,"code_start":2,"english_end":4,"english_start":4},{"label":"setup","code_end":3,"code_start":3,"english_end":6,"english_start":6},{"label":"loop","code_end":4,"code_start":4,"english_end":8,"english_start":8},{"label":"loop","code_end":5,"code_start":5,"english_end":9,"english_start":9},{"label":"loop","code_end":6,"code_start":6,"english_end":10,"english_start":10},{"label":"loop","code_end":7,"code_start":7,"english_end":11,"english_start":11},{"label":"loop","code_end":8,"code_start":8,"english_end":12,"english_start":12},{"label":"loop","code_end":9,"code_start":9,"english_end":13,"english_start":13},{"label":"loop","code_end":10,"code_start":10,"english_end":14,"english_start":14},{"label":"loop","code_end":11,"code_start":11,"english_end":14,"english_start":14},{"label":"loop","code_end":12,"code_start":12,"english_end":14,"english_start":8}],"structure":"{\"functions\":[]}"},"javascript":{"code":"let blinkCount = 0;\nconst ledPin = 'built-in LED';\nconsole.log('Serial started at 9600 baud');\nconst blink = () => {\n  console.log('LED on');\n  setTimeout(() => {\n    console.log('LED off');\n    setTimeout(() => {\n      blinkCount += 1;\n      console.log(`blink ${blinkCount}`);\n      blink();\n    }, 500);\n  }, 500);\n};\n\nblink();","links":[{"label":"initialize counter","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"set up LED pin","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"start serial","code_end":3,"code_start":3,"english_end":4,"english_start":4},{"label":"begin loop","code_end":4,"code_start":4,"english_end":8,"english_start":8},{"label":"turn LED on","code_end":5,"code_start":5,"english_end":9,"english_start":9},{"label":"wait 500 ms","code_end":6,"code_start":6,"english_end":10,"english_start":10},{"label":"turn LED off","code_end":7,"code_start":7,"english_end":11,"english_start":11},{"label":"wait another 500 ms","code_end":8,"code_start":8,"english_end":12,"english_start":12},{"label":"increment counter","code_end":9,"code_start":9,"english_end":13,"english_start":13},{"label":"print count","code_end":10,"code_start":10,"english_end":14,"english_start":14},{"label":"repeat forever","code_end":11,"code_start":11,"english_end":14,"english_start":14},{"label":"end second wait","code_end":12,"code_start":12,"english_end":14,"english_start":14},{"label":"end first wait","code_end":13,"code_start":13,"english_end":14,"english_start":14},{"label":"end loop","code_end":14,"code_start":14,"english_end":8,"english_start":8},{"label":"start blinking","code_end":16,"code_start":16,"english_end":8,"english_start":8}],"structure":"{\"functions\":[{\"name\":\"blink\",\"params\":[],\"english_start\":8,\"english_end\":14,\"summary\":\"Runs the endless blink cycle with 500 ms delays and serial count output.\",\"calls\":[{\"english_start\":14,\"english_end\":14},{\"english_start\":10,\"english_end\":10},{\"english_start\":12,\"english_end\":12}]}]}"}}},{"slug":"blink-without-delay","title":"Blink without delay","description":"Same blink, but using a timer (millis) so the loop never blocks.","english":"Blink the built-in LED roughly twice a second, but never use delay() — the loop should stay free to do other things.\n\nSet up the built-in LED pin as an output.\nRemember the last time we toggled the LED, and whether it's currently on.\n\nEvery time through the loop:\n  Look at how long it's been since we last toggled the LED.\n  If it's been at least 500 milliseconds, flip the LED (on if it was off, off if it was on) and remember this as the new toggle time.\n","app_html":"","settings":{},"by_lang":{"cpp":{"code":"bool ledState = false;\nunsigned long lastToggleTime = 0;\n\nvoid setup() {\n  pinMode(LED_BUILTIN, OUTPUT);\n}\n\nvoid loop() {\n  unsigned long elapsed = millis() - lastToggleTime;\n  if (elapsed >= 500) {\n    ledState = !ledState;\n    digitalWrite(LED_BUILTIN, ledState ? HIGH : LOW);\n    lastToggleTime = millis();\n  }\n}","links":[{"label":"state","code_end":1,"code_start":1,"english_end":4,"english_start":4},{"label":"state","code_end":2,"code_start":2,"english_end":4,"english_start":4},{"label":"function","code_end":4,"code_start":4,"english_end":3,"english_start":3},{"label":"setup","code_end":5,"code_start":5,"english_end":3,"english_start":3},{"label":"function_end","code_end":6,"code_start":6,"english_end":3,"english_start":3},{"label":"function","code_end":8,"code_start":8,"english_end":6,"english_start":6},{"label":"loop","code_end":9,"code_start":9,"english_end":7,"english_start":7},{"label":"loop","code_end":10,"code_start":10,"english_end":8,"english_start":8},{"label":"loop","code_end":11,"code_start":11,"english_end":8,"english_start":8},{"label":"loop","code_end":12,"code_start":12,"english_end":8,"english_start":8},{"label":"loop","code_end":13,"code_start":13,"english_end":8,"english_start":8},{"label":"loop","code_end":14,"code_start":14,"english_end":8,"english_start":8},{"label":"function_end","code_end":15,"code_start":15,"english_end":6,"english_start":6}],"structure":"{\"functions\":[{\"name\":\"setup\",\"params\":[],\"english_start\":3,\"english_end\":3,\"summary\":\"Set the built-in LED pin as an output.\",\"calls\":[{\"english_start\":3,\"english_end\":3}]},{\"name\":\"loop\",\"params\":[],\"english_start\":6,\"english_end\":8,\"summary\":\"Toggle the built-in LED about every 500 ms without blocking.\",\"calls\":[{\"english_start\":7,\"english_end\":7},{\"english_start\":8,\"english_end\":8}]}]}"},"ruby":{"code":"LED_PIN = :LED_BUILTIN\ndef setup\n  pin_mode(LED_PIN, :output)\nend\n@led_on = false\n@last_toggle_time = millis\ndef loop\n  now = millis\n  if now - @last_toggle_time >= 500\n    @led_on = !@led_on\n    digital_write(LED_PIN, @led_on ? :high : :low)\n    @last_toggle_time = now\n  end\nend\n\nsetup\nloop do\n  loop\n  sleep 0.001\nend","links":[{"label":"constant","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"function_start","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"statement","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"function_end","code_end":4,"code_start":4,"english_end":3,"english_start":3},{"label":"state","code_end":5,"code_start":5,"english_end":4,"english_start":4},{"label":"state","code_end":6,"code_start":6,"english_end":4,"english_start":4},{"label":"function_start","code_end":7,"code_start":7,"english_end":8,"english_start":6},{"label":"statement","code_end":8,"code_start":8,"english_end":8,"english_start":7},{"label":"conditional","code_end":9,"code_start":9,"english_end":8,"english_start":7},{"label":"statement","code_end":10,"code_start":10,"english_end":8,"english_start":8},{"label":"statement","code_end":11,"code_start":11,"english_end":8,"english_start":8},{"label":"statement","code_end":12,"code_start":12,"english_end":8,"english_start":8},{"label":"conditional_end","code_end":13,"code_start":13,"english_end":8,"english_start":7},{"label":"function_end","code_end":14,"code_start":14,"english_end":8,"english_start":6},{"label":"call","code_end":16,"code_start":16,"english_end":8,"english_start":6},{"label":"loop_start","code_end":17,"code_start":17,"english_end":8,"english_start":6},{"label":"call","code_end":18,"code_start":18,"english_end":8,"english_start":6},{"label":"yield","code_end":19,"code_start":19,"english_end":8,"english_start":6},{"label":"loop_end","code_end":20,"code_start":20,"english_end":8,"english_start":6}],"structure":"{\"functions\":[{\"name\":\"setup\",\"params\":[],\"english_start\":3,\"english_end\":3,\"summary\":\"Set the built-in LED pin as an output.\",\"calls\":[{\"english_start\":3,\"english_end\":3}]},{\"name\":\"loop\",\"params\":[],\"english_start\":6,\"english_end\":8,\"summary\":\"Check elapsed time and toggle the LED every 500 milliseconds without blocking.\",\"calls\":[{\"english_start\":7,\"english_end\":8},{\"english_start\":8,\"english_end\":8}]}]}"},"python":{"code":"LED_PIN = \"BUILTIN_LED\"\nled_is_on = False\nlast_toggle_time = time.monotonic()\nimport time\n\nif __name__ == \"__main__\":\n    while True:\n        now = time.monotonic()\n        if now - last_toggle_time >= 0.5:\n            led_is_on = not led_is_on\n            last_toggle_time = now\n            print(f\"LED {'ON' if led_is_on else 'OFF'}\")\n        time.sleep(0.01)","links":[{"label":"set_up_pin","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"remember_state","code_end":2,"code_start":2,"english_end":4,"english_start":4},{"label":"remember_toggle_time","code_end":3,"code_start":3,"english_end":4,"english_start":4},{"label":"import_time","code_end":4,"code_start":4,"english_end":1,"english_start":1},{"label":"main_loop","code_end":13,"code_start":6,"english_end":8,"english_start":6}],"structure":"{\"functions\":[]}"},"javascript":{"code":"const ledPin = LED_BUILTIN;\nlet ledOn = false;\nlet lastToggle = 0;\n\nfunction setup() {\n  pinMode(ledPin, OUTPUT);\n}\n\nfunction loop() {\n  const now = millis();\n  if (now - lastToggle >= 500) {\n    ledOn = !ledOn;\n    digitalWrite(ledPin, ledOn ? HIGH : LOW);\n    lastToggle = now;\n  }\n}","links":[{"label":"declare LED pin","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"track LED state","code_end":2,"code_start":2,"english_end":1,"english_start":1},{"label":"track last toggle time","code_end":3,"code_start":3,"english_end":4,"english_start":4},{"label":"setup function start","code_end":5,"code_start":5,"english_end":3,"english_start":3},{"label":"configure LED pin output","code_end":6,"code_start":6,"english_end":3,"english_start":3},{"label":"setup function end","code_end":7,"code_start":7,"english_end":3,"english_start":3},{"label":"loop function start","code_end":9,"code_start":9,"english_end":8,"english_start":6},{"label":"read current time","code_end":10,"code_start":10,"english_end":8,"english_start":7},{"label":"check half-second elapsed","code_end":11,"code_start":11,"english_end":8,"english_start":7},{"label":"flip LED state","code_end":12,"code_start":12,"english_end":8,"english_start":8},{"label":"write LED state","code_end":13,"code_start":13,"english_end":8,"english_start":8},{"label":"store new toggle time","code_end":14,"code_start":14,"english_end":8,"english_start":8},{"label":"end if","code_end":15,"code_start":15,"english_end":8,"english_start":8},{"label":"loop function end","code_end":16,"code_start":16,"english_end":8,"english_start":8}],"structure":"{\"functions\":[{\"name\":\"setup\",\"params\":[],\"english_start\":3,\"english_end\":3,\"summary\":\"Configure the built-in LED pin as an output.\",\"calls\":[]},{\"name\":\"loop\",\"params\":[],\"english_start\":6,\"english_end\":8,\"summary\":\"Check elapsed time and toggle the LED about twice per second without blocking.\",\"calls\":[{\"english_start\":7,\"english_end\":8}]}]}"}}},{"slug":"fade-an-led","title":"Fade an LED","description":"Smoothly fade an LED up and down with PWM (analogWrite).","english":"Smoothly fade an LED up and down, over and over.\n\nThe LED is on a PWM-capable pin.\nSet that pin as an output.\nKeep a brightness value (0 to 255) and a step amount.\n\nForever:\n  Write the current brightness to the LED pin.\n  Add the step to the brightness.\n  If the brightness has reached 0 or 255, reverse the direction of the step.\n  Wait about 20 milliseconds so the fade is visible.\n","app_html":"","settings":{},"by_lang":{"cpp":{"code":"const int ledPin = 9;\nint brightness = 0;\nint stepAmount = 5;\nvoid setup() {\n  pinMode(ledPin, OUTPUT);\n}\n\nvoid loop() {\n  analogWrite(ledPin, brightness);\n  brightness += stepAmount;\n  if (brightness <= 0 || brightness >= 255) {\n    stepAmount = -stepAmount;\n  }\n  delay(20);\n}","links":[{"label":"declaration","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"declaration","code_end":2,"code_start":2,"english_end":5,"english_start":5},{"label":"declaration","code_end":3,"code_start":3,"english_end":5,"english_start":5},{"label":"function_start","code_end":4,"code_start":4,"english_end":4,"english_start":3},{"label":"statement","code_end":5,"code_start":5,"english_end":4,"english_start":4},{"label":"function_end","code_end":6,"code_start":6,"english_end":4,"english_start":4},{"label":"function_start","code_end":8,"code_start":8,"english_end":11,"english_start":7},{"label":"statement","code_end":9,"code_start":9,"english_end":8,"english_start":8},{"label":"statement","code_end":10,"code_start":10,"english_end":9,"english_start":9},{"label":"if_start","code_end":11,"code_start":11,"english_end":10,"english_start":10},{"label":"statement","code_end":12,"code_start":12,"english_end":10,"english_start":10},{"label":"if_end","code_end":13,"code_start":13,"english_end":10,"english_start":10},{"label":"statement","code_end":14,"code_start":14,"english_end":11,"english_start":11},{"label":"function_end","code_end":15,"code_start":15,"english_end":11,"english_start":11}],"structure":"{\"functions\":[{\"name\":\"setup\",\"params\":[],\"english_start\":3,\"english_end\":4,\"summary\":\"Set the LED pin as an output.\",\"calls\":[{\"english_start\":4,\"english_end\":4}]},{\"name\":\"loop\",\"params\":[],\"english_start\":7,\"english_end\":11,\"summary\":\"Continuously fade the LED up and down with a short delay.\",\"calls\":[{\"english_start\":8,\"english_end\":8},{\"english_start\":9,\"english_end\":9},{\"english_start\":10,\"english_end\":10},{\"english_start\":11,\"english_end\":11}]}]}"},"python":{"code":"from machine import Pin, PWM\n\nled = PWM(Pin(0))\nled.freq(1000)\nbrightness = 0\nstep = 5\nif __name__ == \"__main__\":\n    while True:\n        led.duty_u16(brightness * 257)\n        brightness += step\n        if brightness <= 0 or brightness >= 255:\n            step = -step\n        import time\n        time.sleep(0.02)","links":[{"label":"setup","code_end":1,"code_start":1,"english_end":4,"english_start":3},{"label":"setup","code_end":3,"code_start":3,"english_end":4,"english_start":3},{"label":"setup","code_end":4,"code_start":4,"english_end":4,"english_start":3},{"label":"state","code_end":5,"code_start":5,"english_end":5,"english_start":5},{"label":"state","code_end":6,"code_start":6,"english_end":5,"english_start":5},{"label":"entry","code_end":7,"code_start":7,"english_end":11,"english_start":7},{"label":"loop","code_end":8,"code_start":8,"english_end":11,"english_start":7},{"label":"output","code_end":9,"code_start":9,"english_end":8,"english_start":8},{"label":"update","code_end":10,"code_start":10,"english_end":9,"english_start":9},{"label":"check","code_end":11,"code_start":11,"english_end":10,"english_start":10},{"label":"reverse","code_end":12,"code_start":12,"english_end":10,"english_start":10},{"label":"sleep_import","code_end":13,"code_start":13,"english_end":11,"english_start":11},{"label":"delay","code_end":14,"code_start":14,"english_end":11,"english_start":11}],"structure":"{\"functions\":[]}"},"ruby":{"code":"LED_PIN = 9\n\nbrightness_pin = LED_PIN\n# Set that pin as an output.\nbrightness = 0\nstep = 1\nloop do\n  puts \"PWM #{brightness_pin}: #{brightness}\"\n  brightness += step\n  if brightness <= 0 || brightness >= 255\n    step = -step\n  end\n  sleep 0.02\nend","links":[{"label":"setup","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"setup","code_end":3,"code_start":3,"english_end":4,"english_start":3},{"label":"comment","code_end":4,"code_start":4,"english_end":4,"english_start":4},{"label":"state","code_end":5,"code_start":5,"english_end":5,"english_start":5},{"label":"state","code_end":6,"code_start":6,"english_end":5,"english_start":5},{"label":"loop","code_end":7,"code_start":7,"english_end":7,"english_start":7},{"label":"write","code_end":8,"code_start":8,"english_end":8,"english_start":8},{"label":"update","code_end":9,"code_start":9,"english_end":9,"english_start":9},{"label":"condition","code_end":10,"code_start":10,"english_end":10,"english_start":10},{"label":"reverse","code_end":11,"code_start":11,"english_end":10,"english_start":10},{"label":"end","code_end":12,"code_start":12,"english_end":10,"english_start":10},{"label":"delay","code_end":13,"code_start":13,"english_end":11,"english_start":11},{"label":"end","code_end":14,"code_start":14,"english_end":11,"english_start":11}],"structure":"{\"functions\":[]}"},"javascript":{"code":"const five = require('johnny-five');\nconst board = new five.Board();\n\nboard.on('ready', () => {\n  const led = new five.Led(9);\n  let brightness = 0;\n  let step = 5;\n  const fade = () => {\n    led.brightness(brightness);\n    brightness += step;\n    if (brightness <= 0 || brightness >= 255) {\n      step = -step;\n    }\n    setTimeout(fade, 20);\n  };\n  fade();\n});","links":[{"label":"setup","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"setup","code_end":2,"code_start":2,"english_end":4,"english_start":3},{"label":"setup","code_end":4,"code_start":4,"english_end":5,"english_start":3},{"label":"setup","code_end":5,"code_start":5,"english_end":5,"english_start":3},{"label":"state","code_end":6,"code_start":6,"english_end":5,"english_start":5},{"label":"state","code_end":7,"code_start":7,"english_end":5,"english_start":5},{"label":"loop","code_end":8,"code_start":8,"english_end":11,"english_start":7},{"label":"loop","code_end":9,"code_start":9,"english_end":8,"english_start":8},{"label":"loop","code_end":10,"code_start":10,"english_end":9,"english_start":9},{"label":"loop","code_end":11,"code_start":11,"english_end":10,"english_start":10},{"label":"loop","code_end":12,"code_start":12,"english_end":10,"english_start":10},{"label":"loop","code_end":13,"code_start":13,"english_end":10,"english_start":10},{"label":"loop","code_end":14,"code_start":14,"english_end":11,"english_start":11},{"label":"loop","code_end":15,"code_start":15,"english_end":11,"english_start":7},{"label":"loop","code_end":16,"code_start":16,"english_end":11,"english_start":7},{"label":"setup","code_end":17,"code_start":17,"english_end":5,"english_start":3}],"structure":"{\"functions\":[{\"name\":\"fade\",\"params\":[],\"english_start\":7,\"english_end\":11,\"summary\":\"Continuously write the LED brightness, update it, reverse direction at the endpoints, and schedule the next update.\",\"calls\":[{\"english_start\":11,\"english_end\":11}]}]}"}}},{"slug":"button-to-led","title":"Button → LED","description":"Mirror a pushbutton (using the internal pull-up) onto the LED.","english":"Light the built-in LED while a pushbutton is held down, and turn it off when the button is released.\n\nThe button connects a pin to ground when pressed, so use the internal pull-up resistor — the pin reads HIGH when the button is up and LOW when it's pressed.\nSet the button pin as an input with pull-up, and the LED pin as an output.\n\nForever:\n  Read the button.\n  If the button is pressed, turn the LED on; otherwise turn it off.\n","app_html":"","settings":{},"by_lang":{"cpp":{"code":"const int buttonPin = 2;\nconst int ledPin = LED_BUILTIN;\nvoid setup() {\n  pinMode(buttonPin, INPUT_PULLUP);\n  pinMode(ledPin, OUTPUT);\n}\nvoid loop() {\n  int buttonState = digitalRead(buttonPin);\n  if (buttonState == LOW) {\n    digitalWrite(ledPin, HIGH);\n  } else {\n    digitalWrite(ledPin, LOW);\n  }\n}","links":[{"label":"declaration","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"declaration","code_end":2,"code_start":2,"english_end":1,"english_start":1},{"label":"function_start","code_end":3,"code_start":3,"english_end":4,"english_start":4},{"label":"statement","code_end":4,"code_start":4,"english_end":4,"english_start":4},{"label":"statement","code_end":5,"code_start":5,"english_end":4,"english_start":4},{"label":"function_end","code_end":6,"code_start":6,"english_end":4,"english_start":4},{"label":"function_start","code_end":7,"code_start":7,"english_end":6,"english_start":6},{"label":"statement","code_end":8,"code_start":8,"english_end":7,"english_start":7},{"label":"control","code_end":9,"code_start":9,"english_end":8,"english_start":8},{"label":"statement","code_end":10,"code_start":10,"english_end":8,"english_start":8},{"label":"control","code_end":11,"code_start":11,"english_end":8,"english_start":8},{"label":"statement","code_end":12,"code_start":12,"english_end":8,"english_start":8},{"label":"control","code_end":13,"code_start":13,"english_end":8,"english_start":8},{"label":"function_end","code_end":14,"code_start":14,"english_end":8,"english_start":6}],"structure":"{\"functions\":[{\"name\":\"setup\",\"params\":[],\"english_start\":4,\"english_end\":4,\"summary\":\"Configure the button as an internal pull-up input and the built-in LED as an output.\",\"calls\":[{\"english_start\":4,\"english_end\":4}]},{\"name\":\"loop\",\"params\":[],\"english_start\":6,\"english_end\":8,\"summary\":\"Continuously read the button and mirror its pressed state to the LED.\",\"calls\":[{\"english_start\":7,\"english_end\":7},{\"english_start\":8,\"english_end\":8}]}]}"},"python":{"code":"from machine import Pin\nled = Pin(\"LED\", Pin.OUT)\nbutton = Pin(0, Pin.IN, Pin.PULL_UP)\nif __name__ == \"__main__\":\"\n    while True:\n        if button.value() == 0:\n            led.value(1)\n        else:\n            led.value(0)","links":[{"label":"import","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"setup","code_end":2,"code_start":2,"english_end":4,"english_start":4},{"label":"setup","code_end":3,"code_start":3,"english_end":4,"english_start":4},{"label":"entry","code_end":4,"code_start":4,"english_end":8,"english_start":6},{"label":"loop","code_end":5,"code_start":5,"english_end":8,"english_start":6},{"label":"condition","code_end":6,"code_start":6,"english_end":7,"english_start":7},{"label":"then","code_end":7,"code_start":7,"english_end":8,"english_start":8},{"label":"else","code_end":8,"code_start":8,"english_end":8,"english_start":8},{"label":"else_body","code_end":9,"code_start":9,"english_end":8,"english_start":8}],"structure":"{\"functions\":[]}"},"ruby":{"code":"LED_PIN = 13\nBUTTON_PIN = 2\npin_mode(BUTTON_PIN, :input_pullup)\npin_mode(LED_PIN, :output)\n\nloop do\n  pressed = (digital_read(BUTTON_PIN) == :low)\n  digital_write(LED_PIN, pressed ? :high : :low)\nend","links":[{"label":"constant","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"constant","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"setup","code_end":3,"code_start":3,"english_end":4,"english_start":4},{"label":"setup","code_end":4,"code_start":4,"english_end":4,"english_start":4},{"label":"loop","code_end":6,"code_start":6,"english_end":8,"english_start":6},{"label":"read_button","code_end":7,"code_start":7,"english_end":7,"english_start":7},{"label":"set_led","code_end":8,"code_start":8,"english_end":8,"english_start":8},{"label":"loop_end","code_end":9,"code_start":9,"english_end":8,"english_start":6}],"structure":"{\"functions\":[]}"},"javascript":{"code":"const five = require('johnny-five');\nconst board = new five.Board();\nboard.on('ready', () => {\n  const button = new five.Button({ pin: 2, isPullup: true });\n  const led = new five.Led(13);\n  button.on('change', () => {\n    if (button.isDown) {\n      led.on();\n    } else {\n      led.off();\n    }\n  });\n});","links":[{"label":"setup","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"setup","code_end":2,"code_start":2,"english_end":1,"english_start":1},{"label":"setup","code_end":3,"code_start":3,"english_end":4,"english_start":4},{"label":"hardware","code_end":4,"code_start":4,"english_end":4,"english_start":4},{"label":"hardware","code_end":5,"code_start":5,"english_end":4,"english_start":4},{"label":"loop","code_end":6,"code_start":6,"english_end":8,"english_start":6},{"label":"conditional","code_end":7,"code_start":7,"english_end":8,"english_start":7},{"label":"action","code_end":8,"code_start":8,"english_end":8,"english_start":8},{"label":"conditional","code_end":9,"code_start":9,"english_end":8,"english_start":8},{"label":"action","code_end":10,"code_start":10,"english_end":8,"english_start":8},{"label":"conditional","code_end":11,"code_start":11,"english_end":8,"english_start":8},{"label":"loop","code_end":12,"code_start":12,"english_end":8,"english_start":6},{"label":"setup","code_end":13,"code_start":13,"english_end":4,"english_start":4}],"structure":"{\"functions\":[]}"}}},{"slug":"serial-hello-counter","title":"Serial: hello + counter","description":"Print \"Hello\" once, then count up once a second over Serial.","english":"Talk to the computer over the serial port.\n\nStart the serial connection at 9600 baud and print \"Hello, world!\" once.\nKeep a counter starting at zero.\n\nForever:\n  Add one to the counter.\n  Print \"tick \" followed by the counter.\n  Wait one second.\n","app_html":"","settings":{},"by_lang":{"python":{"code":"import argparse\nimport time\nimport serial\n\nparser = argparse.ArgumentParser()\nparser.add_argument(\"port\")\nargs = parser.parse_args()\nser = serial.Serial(args.port, 9600)\nprint(\"Hello, world!\")\ncounter = 0\n\nif __name__ == \"__main__\":\n    while True:\n        counter += 1\n        print(f\"tick {counter}\")\n        time.sleep(1)","links":[{"label":"import","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"import","code_end":2,"code_start":2,"english_end":1,"english_start":1},{"label":"import","code_end":3,"code_start":3,"english_end":1,"english_start":1},{"label":"setup","code_end":5,"code_start":5,"english_end":3,"english_start":3},{"label":"setup","code_end":6,"code_start":6,"english_end":3,"english_start":3},{"label":"setup","code_end":7,"code_start":7,"english_end":3,"english_start":3},{"label":"setup","code_end":8,"code_start":8,"english_end":3,"english_start":3},{"label":"output","code_end":9,"code_start":9,"english_end":3,"english_start":3},{"label":"state","code_end":10,"code_start":10,"english_end":4,"english_start":4},{"label":"entrypoint","code_end":12,"code_start":12,"english_end":9,"english_start":6},{"label":"loop","code_end":13,"code_start":13,"english_end":9,"english_start":6},{"label":"loop_body","code_end":14,"code_start":14,"english_end":7,"english_start":7},{"label":"loop_body","code_end":15,"code_start":15,"english_end":8,"english_start":8},{"label":"loop_body","code_end":16,"code_start":16,"english_end":9,"english_start":9}],"structure":"{\"functions\":[]}"},"cpp":{"code":"long counter = 0;\n\nvoid setup() {\n  Serial.begin(9600);\n  Serial.println(\"Hello, world!\");\n}\n\nvoid loop() {\n  counter++;\n  Serial.print(\"tick \");\n  Serial.println(counter);\n  delay(1000);\n}","links":[{"label":"declaration","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"function_start","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"statement","code_end":4,"code_start":4,"english_end":3,"english_start":3},{"label":"statement","code_end":5,"code_start":5,"english_end":3,"english_start":3},{"label":"function_end","code_end":6,"code_start":6,"english_end":3,"english_start":3},{"label":"function_start","code_end":8,"code_start":8,"english_end":6,"english_start":6},{"label":"statement","code_end":9,"code_start":9,"english_end":7,"english_start":7},{"label":"statement","code_end":10,"code_start":10,"english_end":8,"english_start":8},{"label":"statement","code_end":11,"code_start":11,"english_end":8,"english_start":8},{"label":"statement","code_end":12,"code_start":12,"english_end":9,"english_start":9},{"label":"function_end","code_end":13,"code_start":13,"english_end":6,"english_start":6}],"structure":"{\"functions\":[{\"name\":\"setup\",\"params\":[],\"english_start\":3,\"english_end\":3,\"summary\":\"Start the serial connection and print a greeting once.\",\"calls\":[{\"english_start\":3,\"english_end\":3}]},{\"name\":\"loop\",\"params\":[],\"english_start\":6,\"english_end\":9,\"summary\":\"Increment the counter, print the tick message, and wait one second.\",\"calls\":[{\"english_start\":8,\"english_end\":8},{\"english_start\":9,\"english_end\":9}]}]}"},"ruby":{"code":"require 'serialport'\nport_name = ARGV[0] || '/dev/ttyUSB0'\nserial = SerialPort.new(port_name, 9600, 8, 1, SerialPort::NONE)\nserial.puts 'Hello, world!'\ncounter = 0\nloop do\n  counter += 1\n  serial.puts \"tick #{counter}\"\n  sleep 1\nend","links":[{"label":"require serial port support","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"choose serial port","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"open serial connection at 9600 baud","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"print greeting once","code_end":4,"code_start":4,"english_end":3,"english_start":3},{"label":"initialize counter","code_end":5,"code_start":5,"english_end":4,"english_start":4},{"label":"forever loop start","code_end":6,"code_start":6,"english_end":6,"english_start":6},{"label":"increment counter","code_end":7,"code_start":7,"english_end":7,"english_start":7},{"label":"print tick and counter","code_end":8,"code_start":8,"english_end":8,"english_start":8},{"label":"wait one second","code_end":9,"code_start":9,"english_end":9,"english_start":9},{"label":"forever loop end","code_end":10,"code_start":10,"english_end":6,"english_start":6}],"structure":"{\"functions\":[]}"},"javascript":{"code":"const { SerialPort } = require('serialport');\nconst portPath = process.argv[2];\nconst port = new SerialPort({ path: portPath, baudRate: 9600 });\nport.write('Hello, world!\\n');\nlet counter = 0;\n\nconst wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n(async () => {\n  for (;;) {\n    counter += 1;\n    port.write(`tick ${counter}\\n`);\n    await wait(1000);\n  }\n})();","links":[{"label":"import serial support","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"get port path","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"open serial connection","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"send greeting","code_end":4,"code_start":4,"english_end":3,"english_start":3},{"label":"initialize counter","code_end":5,"code_start":5,"english_end":4,"english_start":4},{"label":"delay helper","code_end":7,"code_start":7,"english_end":9,"english_start":6},{"label":"start loop","code_end":8,"code_start":8,"english_end":9,"english_start":6},{"label":"infinite loop","code_end":9,"code_start":9,"english_end":9,"english_start":6},{"label":"increment counter","code_end":10,"code_start":10,"english_end":7,"english_start":7},{"label":"print tick","code_end":11,"code_start":11,"english_end":8,"english_start":8},{"label":"wait one second","code_end":12,"code_start":12,"english_end":9,"english_start":9},{"label":"end loop","code_end":13,"code_start":13,"english_end":9,"english_start":6},{"label":"run loop","code_end":14,"code_start":14,"english_end":9,"english_start":6}],"structure":"{\"functions\":[]}"}}},{"slug":"read-a-sensor","title":"Read a sensor","description":"Read an analog input (e.g. a potentiometer on A0) and print the value.","english":"Read an analog sensor on pin A0 and stream its value to the serial port.\n\nStart the serial connection at 9600 baud.\n\nForever:\n  Read the analog value on A0 (it will be between 0 and 1023).\n  Print that value on its own line.\n  Wait 100 milliseconds.\n","app_html":"","settings":{},"by_lang":{"python":{"code":"import sys\nimport time\ntry:\n    from machine import ADC\n    sensor = ADC(0)\nexcept ImportError:\n    ADC = None\n    sensor = None\ndef read_sensor():\n    if sensor is not None:\n        return sensor.read()\n    return 0\nif __name__ == \"__main__\":\n    while True:\n        value = read_sensor()\n        print(value)\n        time.sleep(0.1)","links":[{"label":"import","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"import","code_end":2,"code_start":2,"english_end":1,"english_start":1},{"label":"setup","code_end":3,"code_start":3,"english_end":1,"english_start":1},{"label":"setup","code_end":4,"code_start":4,"english_end":1,"english_start":1},{"label":"setup","code_end":5,"code_start":5,"english_end":1,"english_start":1},{"label":"setup","code_end":6,"code_start":6,"english_end":1,"english_start":1},{"label":"setup","code_end":7,"code_start":7,"english_end":1,"english_start":1},{"label":"setup","code_end":8,"code_start":8,"english_end":1,"english_start":1},{"label":"function","code_end":9,"code_start":9,"english_end":3,"english_start":3},{"label":"function","code_end":10,"code_start":10,"english_end":3,"english_start":3},{"label":"function","code_end":11,"code_start":11,"english_end":3,"english_start":3},{"label":"function","code_end":12,"code_start":12,"english_end":3,"english_start":3},{"label":"entry","code_end":13,"code_start":13,"english_end":8,"english_start":5},{"label":"loop","code_end":14,"code_start":14,"english_end":8,"english_start":5},{"label":"read","code_end":15,"code_start":15,"english_end":6,"english_start":6},{"label":"output","code_end":16,"code_start":16,"english_end":7,"english_start":7},{"label":"delay","code_end":17,"code_start":17,"english_end":8,"english_start":8}],"structure":"{\"functions\":[{\"name\":\"read_sensor\",\"params\":[],\"english_start\":3,\"english_end\":3,\"summary\":\"Read the analog value from A0 when supported, otherwise return a fallback value.\",\"calls\":[]}]}"},"ruby":{"code":"require 'arduino_firmata'\nboard = ArduinoFirmata.connect\nloop do\n  value = board.analog_read(0)\n  puts value\n  sleep 0.1\nend","links":[{"label":"require hardware library","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"connect to board","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"forever loop","code_end":3,"code_start":3,"english_end":5,"english_start":5},{"label":"read analog value on A0","code_end":4,"code_start":4,"english_end":6,"english_start":6},{"label":"print value","code_end":5,"code_start":5,"english_end":7,"english_start":7},{"label":"wait 100 milliseconds","code_end":6,"code_start":6,"english_end":8,"english_start":8},{"label":"end loop","code_end":7,"code_start":7,"english_end":5,"english_start":5}],"structure":"{\"functions\":[]}"},"javascript":{"code":"const { Board, Sensor } = require(\"johnny-five\");\nconst board = new Board();\n\nboard.on(\"ready\", () => {\n  const sensor = new Sensor(\"A0\");\n  this.io.serialConfig({ baud: 9600 });\n  setInterval(() => {\n    console.log(sensor.value);\n  }, 100);\n});","links":[{"label":"setup","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"setup","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"loop","code_end":4,"code_start":4,"english_end":8,"english_start":5},{"label":"loop","code_end":5,"code_start":5,"english_end":3,"english_start":3},{"label":"loop","code_end":6,"code_start":6,"english_end":3,"english_start":3},{"label":"loop","code_end":7,"code_start":7,"english_end":7,"english_start":6},{"label":"loop","code_end":8,"code_start":8,"english_end":7,"english_start":6},{"label":"loop","code_end":9,"code_start":9,"english_end":8,"english_start":8},{"label":"loop","code_end":10,"code_start":10,"english_end":8,"english_start":5}],"structure":"{\"functions\":[]}"},"cpp":{"code":"const int sensorPin = A0;\nvoid setup() {\n  Serial.begin(9600);\n}\n\nvoid loop() {\n  int sensorValue = analogRead(sensorPin);\n  Serial.println(sensorValue);\n  delay(100);\n}","links":[{"label":"declaration","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"function_start","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"statement","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"function_end","code_end":4,"code_start":4,"english_end":3,"english_start":3},{"label":"function_start","code_end":6,"code_start":6,"english_end":5,"english_start":5},{"label":"statement","code_end":7,"code_start":7,"english_end":6,"english_start":6},{"label":"statement","code_end":8,"code_start":8,"english_end":7,"english_start":7},{"label":"statement","code_end":9,"code_start":9,"english_end":8,"english_start":8},{"label":"function_end","code_end":10,"code_start":10,"english_end":5,"english_start":5}],"structure":"{\"functions\":[]}"}}},{"slug":"echo-what-you-type","title":"Echo what you type","description":"Read a line from the Serial Monitor and echo it back (and blink).","english":"Echo back anything typed into the Serial Monitor, and blink the LED each time.\n\nStart the serial connection at 9600 baud, set the built-in LED pin as an output, and print \"Type something and press Enter...\".\n\nForever:\n  If there is serial input waiting:\n    Read a whole line (up to the newline) and trim the whitespace off it.\n    Print \"you said: \" followed by that line.\n    Blink the LED briefly (on, short pause, off).\n","app_html":"","settings":{},"by_lang":{"cpp":{"code":"void setup() {\n  Serial.begin(9600);\n  pinMode(LED_BUILTIN, OUTPUT);\n  Serial.println(\"Type something and press Enter...\");\n}\n\nvoid loop() {\n  if (Serial.available() > 0) {\n    String line = Serial.readStringUntil('\\n');\n    line.trim();\n    Serial.print(\"you said: \");\n    Serial.println(line);\n    digitalWrite(LED_BUILTIN, HIGH);\n    delay(100);\n    digitalWrite(LED_BUILTIN, LOW);\n    delay(100);\n  }\n}","links":[{"label":"function_start","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"statement","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"statement","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"statement","code_end":4,"code_start":4,"english_end":3,"english_start":3},{"label":"function_end","code_end":5,"code_start":5,"english_end":3,"english_start":3},{"label":"function_start","code_end":7,"code_start":7,"english_end":5,"english_start":5},{"label":"statement","code_end":8,"code_start":8,"english_end":6,"english_start":6},{"label":"statement","code_end":9,"code_start":9,"english_end":7,"english_start":7},{"label":"statement","code_end":10,"code_start":10,"english_end":7,"english_start":7},{"label":"statement","code_end":11,"code_start":11,"english_end":8,"english_start":8},{"label":"statement","code_end":12,"code_start":12,"english_end":8,"english_start":8},{"label":"statement","code_end":13,"code_start":13,"english_end":9,"english_start":9},{"label":"statement","code_end":14,"code_start":14,"english_end":9,"english_start":9},{"label":"statement","code_end":15,"code_start":15,"english_end":9,"english_start":9},{"label":"statement","code_end":16,"code_start":16,"english_end":9,"english_start":9},{"label":"statement","code_end":17,"code_start":17,"english_end":9,"english_start":6},{"label":"function_end","code_end":18,"code_start":18,"english_end":9,"english_start":5}],"structure":"{\"functions\":[{\"name\":\"setup\",\"params\":[],\"english_start\":3,\"english_end\":3,\"summary\":\"Initialize serial at 9600 baud, configure the built-in LED as an output, and print the prompt.\",\"calls\":[]},{\"name\":\"loop\",\"params\":[],\"english_start\":5,\"english_end\":9,\"summary\":\"Wait for serial input, read and trim a line, echo it back with a prefix, and blink the LED briefly.\",\"calls\":[{\"english_start\":6,\"english_end\":9}]}]}"},"python":{"code":"import sys\n\nprint('Type something and press Enter...')\nif __name__ == '__main__':\n    while True:\n        try:\n            line = input()\n        except EOFError:\n            break\n        line = line.strip()\n        print('you said: ' + line)\n        print('LED on')\n        sys.stdout.flush()\n        print('LED off')","links":[{"label":"import","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"greeting","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"entry","code_end":4,"code_start":4,"english_end":5,"english_start":5},{"label":"loop","code_end":5,"code_start":5,"english_end":9,"english_start":5},{"label":"input-check","code_end":6,"code_start":6,"english_end":6,"english_start":6},{"label":"read-line","code_end":7,"code_start":7,"english_end":7,"english_start":6},{"label":"eof","code_end":8,"code_start":8,"english_end":6,"english_start":6},{"label":"break","code_end":9,"code_start":9,"english_end":6,"english_start":6},{"label":"trim","code_end":10,"code_start":10,"english_end":7,"english_start":7},{"label":"echo","code_end":11,"code_start":11,"english_end":8,"english_start":8},{"label":"blink-on","code_end":12,"code_start":12,"english_end":9,"english_start":9},{"label":"flush","code_end":13,"code_start":13,"english_end":9,"english_start":9},{"label":"blink-off","code_end":14,"code_start":14,"english_end":9,"english_start":9}],"structure":"{\"functions\":[]}"},"ruby":{"code":"serial = Serial.new('/dev/ttyUSB0', 9600)\nled_pin = :built_in_led\nputs 'Type something and press Enter...'\nloop do\n  if serial.available? > 0\n    line = serial.gets.chomp\n    puts \"you said: #{line}\"\n    digital_write(led_pin, :high)\n    sleep 0.1\n    digital_write(led_pin, :low)\n  end\nend","links":[{"label":"Start the serial connection at 9600 baud","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"set the built-in LED pin as an output","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"and print \"Type something and press Enter...\"","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"Forever:","code_end":4,"code_start":4,"english_end":5,"english_start":5},{"label":"If there is serial input waiting:","code_end":5,"code_start":5,"english_end":6,"english_start":6},{"label":"Read a whole line (up to the newline) and trim the whitespace off it.","code_end":6,"code_start":6,"english_end":7,"english_start":7},{"label":"Print \"you said: \" followed by that line.","code_end":7,"code_start":7,"english_end":8,"english_start":8},{"label":"Blink the LED briefly (on, short pause, off).","code_end":8,"code_start":8,"english_end":9,"english_start":9},{"label":"Blink the LED briefly (on, short pause, off).","code_end":9,"code_start":9,"english_end":9,"english_start":9},{"label":"Blink the LED briefly (on, short pause, off).","code_end":10,"code_start":10,"english_end":9,"english_start":9},{"label":"","code_end":11,"code_start":11,"english_end":9,"english_start":6},{"label":"","code_end":12,"code_start":12,"english_end":9,"english_start":5}],"structure":"{\"functions\":[]}"},"javascript":{"code":"const readline = require('readline');\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n  terminal: false,\n});\nconsole.log('Type something and press Enter...');\nconst blinkLed = () => {\n  console.log('[LED ON]');\n  setTimeout(() => {\n    console.log('[LED OFF]');\n  }, 100);\n};\n\nrl.on('line', (line) => {\n  const text = line.trim();\n  console.log(`you said: ${text}`);\n  blinkLed();\n});","links":[{"label":"setup","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"setup","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"setup","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"setup","code_end":4,"code_start":4,"english_end":3,"english_start":3},{"label":"setup","code_end":5,"code_start":5,"english_end":3,"english_start":3},{"label":"setup","code_end":6,"code_start":6,"english_end":3,"english_start":3},{"label":"prompt","code_end":7,"code_start":7,"english_end":3,"english_start":3},{"label":"function","code_end":8,"code_start":8,"english_end":9,"english_start":9},{"label":"function","code_end":9,"code_start":9,"english_end":9,"english_start":9},{"label":"function","code_end":10,"code_start":10,"english_end":9,"english_start":9},{"label":"function","code_end":11,"code_start":11,"english_end":9,"english_start":9},{"label":"function","code_end":12,"code_start":12,"english_end":9,"english_start":9},{"label":"function","code_end":13,"code_start":13,"english_end":9,"english_start":9},{"label":"event","code_end":15,"code_start":15,"english_end":9,"english_start":5},{"label":"process","code_end":16,"code_start":16,"english_end":7,"english_start":7},{"label":"output","code_end":17,"code_start":17,"english_end":8,"english_start":8},{"label":"action","code_end":18,"code_start":18,"english_end":9,"english_start":9},{"label":"event","code_end":19,"code_start":19,"english_end":9,"english_start":5}],"structure":"{\"functions\":[{\"name\":\"blinkLed\",\"params\":[],\"english_start\":9,\"english_end\":9,\"summary\":\"Simulate a brief LED blink by logging on/off messages with a short delay.\",\"calls\":[{\"english_start\":9,\"english_end\":9}]}]}"}}},{"slug":"play-a-little-melody","title":"Play a little melody","description":"Play a C-major scale on a piezo buzzer wired to pin 8.","english":"Play a short tune on a piezo buzzer connected to pin 8, then stop.\n\nMake a list of note frequencies for a C major scale: 262, 294, 330, 349, 392, 440, 494, 523 Hz.\n\nIn setup, for each note in the list:\n  Play the note on pin 8 for about 300 milliseconds.\n  Wait a touch longer than that so the notes don't run together, then stop the tone.\n\nThe loop does nothing — the tune plays once.\n","app_html":"","settings":{},"by_lang":{"cpp":{"code":"const int buzzerPin = 8;\nconst int notes[] = {262, 294, 330, 349, 392, 440, 494, 523};\nconst int noteCount = sizeof(notes) / sizeof(notes[0]);\nvoid setup() {\n  for (int i = 0; i < noteCount; i++) {\n    tone(buzzerPin, notes[i]);\n    delay(300);\n    delay(100);\n    noTone(buzzerPin);\n  }\n}\n\nvoid loop() {\n}","links":[{"label":"declaration","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"declaration","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"declaration","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"function","code_end":4,"code_start":4,"english_end":5,"english_start":5},{"label":"loop","code_end":5,"code_start":5,"english_end":7,"english_start":5},{"label":"action","code_end":6,"code_start":6,"english_end":6,"english_start":6},{"label":"action","code_end":7,"code_start":7,"english_end":6,"english_start":6},{"label":"action","code_end":8,"code_start":8,"english_end":7,"english_start":7},{"label":"action","code_end":9,"code_start":9,"english_end":7,"english_start":7},{"label":"loop_end","code_end":10,"code_start":10,"english_end":7,"english_start":5},{"label":"function_end","code_end":11,"code_start":11,"english_end":7,"english_start":5},{"label":"function","code_end":13,"code_start":13,"english_end":9,"english_start":9},{"label":"function_end","code_end":14,"code_start":14,"english_end":9,"english_start":9}],"structure":"{\"functions\":[{\"name\":\"setup\",\"params\":[],\"english_start\":5,\"english_end\":7,\"summary\":\"Plays each note in the scale once on the buzzer with short gaps, then stops the tone after each note.\",\"calls\":[{\"english_start\":6,\"english_end\":6},{\"english_start\":7,\"english_end\":7}]},{\"name\":\"loop\",\"params\":[],\"english_start\":9,\"english_end\":9,\"summary\":\"Does nothing so the tune only plays once.\",\"calls\":[]}]}"},"python":{"code":"import time\nnotes = [262, 294, 330, 349, 392, 440, 494, 523]\ndef play_tone(pin, frequency, duration_ms):\n    print(f\"Playing {frequency} Hz on pin {pin} for {duration_ms} ms\")\n    time.sleep(duration_ms / 1000.0)\n    print(f\"Stopping tone on pin {pin}\")\n\nif __name__ == \"__main__\":\n    pin = 8\n    for note in notes:\n        play_tone(pin, note, 300)\n        time.sleep(0.1)","links":[{"label":"import","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"data","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"function","code_end":3,"code_start":3,"english_end":7,"english_start":5},{"label":"function body","code_end":4,"code_start":4,"english_end":7,"english_start":5},{"label":"function body","code_end":5,"code_start":5,"english_end":7,"english_start":5},{"label":"function body","code_end":6,"code_start":6,"english_end":7,"english_start":5},{"label":"entry","code_end":8,"code_start":8,"english_end":9,"english_start":5},{"label":"main","code_end":9,"code_start":9,"english_end":9,"english_start":5},{"label":"loop","code_end":10,"code_start":10,"english_end":9,"english_start":5},{"label":"loop body","code_end":11,"code_start":11,"english_end":9,"english_start":5},{"label":"loop body","code_end":12,"code_start":12,"english_end":9,"english_start":5}],"structure":"{\"functions\":[{\"name\":\"play_tone\",\"params\":[\"pin\",\"frequency\",\"duration_ms\"],\"english_start\":5,\"english_end\":7,\"summary\":\"Simulates playing a tone on a pin for the requested duration, then stopping it.\",\"calls\":[{\"english_start\":5,\"english_end\":7}]}]}"},"ruby":{"code":"notes = [262, 294, 330, 349, 392, 440, 494, 523]\n\ndef tone(pin, frequency)\n  puts \"tone on pin \"+pin.to_s+\": \"+frequency.to_s+\" Hz\"\nend\n\ndef no_tone(pin)\n  puts \"stop tone on pin \"+pin.to_s\nend\n\ndef setup(notes)\n  notes.each do |frequency|\n    tone(8, frequency)\n    sleep 0.3\n    sleep 0.35\n    no_tone(8)\n  end\nend\n\ndef loop\nend\nsetup(notes)\nloop","links":[{"label":"create note list","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"tone helper","code_end":5,"code_start":3,"english_end":7,"english_start":5},{"label":"no_tone helper","code_end":9,"code_start":7,"english_end":7,"english_start":5},{"label":"start setup and iterate notes","code_end":12,"code_start":11,"english_end":7,"english_start":5},{"label":"play each note briefly","code_end":14,"code_start":13,"english_end":6,"english_start":6},{"label":"pause a little longer, then stop each note","code_end":18,"code_start":15,"english_end":7,"english_start":7},{"label":"empty loop","code_end":21,"code_start":20,"english_end":9,"english_start":9},{"label":"run the tune once","code_end":22,"code_start":22,"english_end":1,"english_start":1},{"label":"call empty loop","code_end":23,"code_start":23,"english_end":9,"english_start":9}],"structure":"{\"functions\":[{\"name\":\"tone\",\"params\":[\"pin\",\"frequency\"],\"english_start\":5,\"english_end\":7,\"summary\":\"Print a simulated tone action for the given pin and frequency.\",\"calls\":[]},{\"name\":\"no_tone\",\"params\":[\"pin\"],\"english_start\":5,\"english_end\":7,\"summary\":\"Print a simulated stop-tone action for the given pin.\",\"calls\":[]},{\"name\":\"setup\",\"params\":[\"notes\"],\"english_start\":5,\"english_end\":7,\"summary\":\"Play each note in the scale once on pin 8 with a short delay and then stop the tone.\",\"calls\":[{\"english_start\":6,\"english_end\":6},{\"english_start\":7,\"english_end\":7}]},{\"name\":\"loop\",\"params\":[],\"english_start\":9,\"english_end\":9,\"summary\":\"Do nothing.\",\"calls\":[]}]}"},"javascript":{"code":"const pin = 8;\nconst notes = [262, 294, 330, 349, 392, 440, 494, 523];\n\nconst playTone = (frequency, durationMs) => {\n  console.log(`tone on pin ${pin}: ${frequency} Hz for ${durationMs} ms`);\n};\n\nconst stopTone = () => {\n  console.log(`stop tone on pin ${pin}`);\n};\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\n(async () => {\n  for (const note of notes) {\n    playTone(note, 300);\n    await sleep(350);\n    stopTone();\n  }\n})();","links":[{"label":"declaration","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"declaration","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"function_start","code_end":4,"code_start":4,"english_end":6,"english_start":6},{"label":"function_body","code_end":5,"code_start":5,"english_end":6,"english_start":6},{"label":"function_end","code_end":6,"code_start":6,"english_end":7,"english_start":7},{"label":"function_start","code_end":8,"code_start":8,"english_end":7,"english_start":7},{"label":"function_body","code_end":9,"code_start":9,"english_end":7,"english_start":7},{"label":"function_end","code_end":10,"code_start":10,"english_end":7,"english_start":7},{"label":"declaration","code_end":12,"code_start":12,"english_end":7,"english_start":7},{"label":"async_start","code_end":14,"code_start":14,"english_end":9,"english_start":5},{"label":"loop_start","code_end":15,"code_start":15,"english_end":9,"english_start":5},{"label":"loop_body","code_end":16,"code_start":16,"english_end":6,"english_start":6},{"label":"loop_body","code_end":17,"code_start":17,"english_end":7,"english_start":7},{"label":"loop_body","code_end":18,"code_start":18,"english_end":7,"english_start":7},{"label":"loop_end","code_end":19,"code_start":19,"english_end":9,"english_start":9},{"label":"async_end","code_end":20,"code_start":20,"english_end":9,"english_start":9}],"structure":"{\"functions\":[{\"name\":\"playTone\",\"params\":[\"frequency\",\"durationMs\"],\"english_start\":6,\"english_end\":6,\"summary\":\"Logs that a tone would play on pin 8 for a given duration.\",\"calls\":[]},{\"name\":\"stopTone\",\"params\":[],\"english_start\":7,\"english_end\":7,\"summary\":\"Logs that the tone would stop on pin 8.\",\"calls\":[]},{\"name\":\"sleep\",\"params\":[\"ms\"],\"english_start\":7,\"english_end\":7,\"summary\":\"Returns a promise that resolves after the given delay.\",\"calls\":[]}]}"}}},{"slug":"reusable-beep-step","title":"A reusable \"beep\" step","description":"Names \"play a beep at a pitch\" once, then calls it several times — shows the ƒ function decorations & the named ribbon.","english":"Play a little sequence of beeps on a piezo buzzer wired to pin 8.\n\nHere's how to play a beep at a given pitch:\n  Play a tone on pin 8 at that pitch for 120 milliseconds.\n  Then stop the tone and wait 80 milliseconds before returning.\n\nStart the serial connection at 9600 baud.\n\nOver and over, forever:\n  Play a beep at 880 Hz.\n  Play a beep at 660 Hz.\n  Play a beep at 990 Hz.\n  Print \"beeped!\" to the serial port.\n  Wait one second before the next round.\n","app_html":"","settings":{},"by_lang":{"cpp":{"code":"void beepAtPitch(int pitch) {\n  tone(8, pitch, 120);\n  delay(120);\n  noTone(8);\n  delay(80);\n}\n\nvoid setup() {\n  Serial.begin(9600);\n}\n\nvoid loop() {\n  beepAtPitch(880);\n  beepAtPitch(660);\n  beepAtPitch(990);\n  Serial.println(\"beeped!\");\n  delay(1000);\n}","links":[{"label":"function signature","code_end":1,"code_start":1,"english_end":5,"english_start":3},{"label":"play tone","code_end":2,"code_start":2,"english_end":4,"english_start":4},{"label":"wait while tone plays","code_end":3,"code_start":3,"english_end":5,"english_start":5},{"label":"stop tone","code_end":4,"code_start":4,"english_end":5,"english_start":5},{"label":"pause before returning","code_end":5,"code_start":5,"english_end":5,"english_start":5},{"label":"end function","code_end":6,"code_start":6,"english_end":5,"english_start":3},{"label":"setup signature","code_end":8,"code_start":8,"english_end":7,"english_start":7},{"label":"start serial","code_end":9,"code_start":9,"english_end":7,"english_start":7},{"label":"end setup","code_end":10,"code_start":10,"english_end":7,"english_start":7},{"label":"loop signature","code_end":12,"code_start":12,"english_end":14,"english_start":9},{"label":"first beep","code_end":13,"code_start":13,"english_end":10,"english_start":10},{"label":"second beep","code_end":14,"code_start":14,"english_end":11,"english_start":11},{"label":"third beep","code_end":15,"code_start":15,"english_end":12,"english_start":12},{"label":"serial message","code_end":16,"code_start":16,"english_end":13,"english_start":13},{"label":"wait between rounds","code_end":17,"code_start":17,"english_end":14,"english_start":14},{"label":"end loop","code_end":18,"code_start":18,"english_end":14,"english_start":9}],"structure":"{\"functions\":[{\"name\":\"beepAtPitch\",\"params\":[\"int pitch\"],\"english_start\":3,\"english_end\":5,\"summary\":\"Plays a tone on pin 8 for 120 ms, stops it, then waits 80 ms.\",\"calls\":[{\"english_start\":4,\"english_end\":4},{\"english_start\":5,\"english_end\":5}]}]}"},"python":{"code":"import time\n\nprint(\"Serial connection started at 9600 baud\")\n\ndef beep(pitch):\n    print(f\"Tone on pin 8 at {pitch} Hz for 120 ms\")\n    time.sleep(0.12)\n    print(\"Stop tone\")\n    time.sleep(0.08)\n\nif __name__ == \"__main__\":\n    while True:\n        beep(880)\n        beep(660)\n        beep(990)\n        print(\"beeped!\")\n        time.sleep(1)","links":[{"label":"import","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"serial_start","code_end":3,"code_start":3,"english_end":7,"english_start":7},{"label":"function_def","code_end":5,"code_start":5,"english_end":5,"english_start":3},{"label":"function_body","code_end":6,"code_start":6,"english_end":5,"english_start":3},{"label":"function_body","code_end":7,"code_start":7,"english_end":5,"english_start":3},{"label":"function_body","code_end":8,"code_start":8,"english_end":5,"english_start":3},{"label":"function_body","code_end":9,"code_start":9,"english_end":5,"english_start":3},{"label":"entrypoint","code_end":11,"code_start":11,"english_end":14,"english_start":9},{"label":"loop","code_end":12,"code_start":12,"english_end":14,"english_start":9},{"label":"call","code_end":13,"code_start":13,"english_end":10,"english_start":10},{"label":"call","code_end":14,"code_start":14,"english_end":11,"english_start":11},{"label":"call","code_end":15,"code_start":15,"english_end":12,"english_start":12},{"label":"print","code_end":16,"code_start":16,"english_end":13,"english_start":13},{"label":"sleep","code_end":17,"code_start":17,"english_end":14,"english_start":14}],"structure":"{\"functions\":[{\"name\":\"beep\",\"params\":[\"pitch\"],\"english_start\":3,\"english_end\":5,\"summary\":\"Play a tone at the given pitch for 120 milliseconds, then stop and wait 80 milliseconds.\",\"calls\":[{\"english_start\":4,\"english_end\":4},{\"english_start\":5,\"english_end\":5}]}]}"},"ruby":{"code":"PIN = 8\ndef beep(pitch)\n  puts \"tone on pin #{PIN} at #{pitch} Hz for 120 ms\"\n  sleep 0.08\nend\nputs \"serial connection started at 9600 baud\"\nloop do\n  beep 880\n  beep 660\n  beep 990\n  puts \"beeped!\"\n  sleep 1\nend","links":[{"label":"setup","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"function","code_end":2,"code_start":2,"english_end":5,"english_start":3},{"label":"function","code_end":3,"code_start":3,"english_end":4,"english_start":4},{"label":"function","code_end":4,"code_start":4,"english_end":5,"english_start":5},{"label":"function","code_end":5,"code_start":5,"english_end":5,"english_start":5},{"label":"setup","code_end":6,"code_start":6,"english_end":7,"english_start":7},{"label":"loop","code_end":7,"code_start":7,"english_end":9,"english_start":9},{"label":"loop-body","code_end":8,"code_start":8,"english_end":10,"english_start":10},{"label":"loop-body","code_end":9,"code_start":9,"english_end":11,"english_start":11},{"label":"loop-body","code_end":10,"code_start":10,"english_end":12,"english_start":12},{"label":"loop-body","code_end":11,"code_start":11,"english_end":13,"english_start":13},{"label":"loop-body","code_end":12,"code_start":12,"english_end":14,"english_start":14},{"label":"loop","code_end":13,"code_start":13,"english_end":14,"english_start":9}],"structure":"{\"functions\":[{\"name\":\"beep\",\"params\":[\"pitch\"],\"english_start\":3,\"english_end\":5,\"summary\":\"Play one beep at the given pitch by announcing the tone and waiting before stopping.\",\"calls\":[]}]}"},"javascript":{"code":"const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\nconst SERIAL_BAUD = 9600;\nconst BUZZER_PIN = 8;\nconsole.log(`Serial connection started at ${SERIAL_BAUD} baud.`);\nasync function playBeep(pitch) {\n  console.log(`Tone on pin ${BUZZER_PIN} at ${pitch} Hz for 120 ms.`);\n  await sleep(120);\n  console.log(`Stop tone on pin ${BUZZER_PIN}.`);\n  await sleep(80);\n}\nasync function main() {\n  while (true) {\n    await playBeep(880);\n    await playBeep(660);\n    await playBeep(990);\n    console.log('beeped!');\n    await sleep(1000);\n  }\n}\n\nmain().catch((error) => {\n  console.error(error);\n  process.exitCode = 1;\n});","links":[{"label":"declaration","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"declaration","code_end":2,"code_start":2,"english_end":7,"english_start":7},{"label":"declaration","code_end":3,"code_start":3,"english_end":1,"english_start":1},{"label":"statement","code_end":4,"code_start":4,"english_end":7,"english_start":7},{"label":"function_start","code_end":5,"code_start":5,"english_end":5,"english_start":3},{"label":"statement","code_end":6,"code_start":6,"english_end":4,"english_start":4},{"label":"statement","code_end":7,"code_start":7,"english_end":5,"english_start":5},{"label":"statement","code_end":8,"code_start":8,"english_end":5,"english_start":5},{"label":"statement","code_end":9,"code_start":9,"english_end":5,"english_start":5},{"label":"function_end","code_end":10,"code_start":10,"english_end":5,"english_start":5},{"label":"function_start","code_end":11,"code_start":11,"english_end":14,"english_start":9},{"label":"loop_start","code_end":12,"code_start":12,"english_end":14,"english_start":9},{"label":"statement","code_end":13,"code_start":13,"english_end":10,"english_start":10},{"label":"statement","code_end":14,"code_start":14,"english_end":11,"english_start":11},{"label":"statement","code_end":15,"code_start":15,"english_end":12,"english_start":12},{"label":"statement","code_end":16,"code_start":16,"english_end":13,"english_start":13},{"label":"statement","code_end":17,"code_start":17,"english_end":14,"english_start":14},{"label":"loop_end","code_end":18,"code_start":18,"english_end":14,"english_start":9},{"label":"function_end","code_end":19,"code_start":19,"english_end":14,"english_start":9},{"label":"statement","code_end":21,"code_start":21,"english_end":9,"english_start":9},{"label":"statement","code_end":22,"code_start":22,"english_end":9,"english_start":9},{"label":"statement","code_end":23,"code_start":23,"english_end":9,"english_start":9},{"label":"statement","code_end":24,"code_start":24,"english_end":9,"english_start":9}],"structure":"{\"functions\":[{\"name\":\"playBeep\",\"params\":[\"pitch\"],\"english_start\":3,\"english_end\":5,\"summary\":\"Plays one beep at the given pitch, then stops and pauses briefly.\",\"calls\":[{\"english_start\":4,\"english_end\":4},{\"english_start\":5,\"english_end\":5},{\"english_start\":5,\"english_end\":5},{\"english_start\":5,\"english_end\":5}]},{\"name\":\"main\",\"params\":[],\"english_start\":9,\"english_end\":14,\"summary\":\"Runs the repeating three-beep sequence and prints a message after each round.\",\"calls\":[{\"english_start\":10,\"english_end\":10},{\"english_start\":11,\"english_end\":11},{\"english_start\":12,\"english_end\":12},{\"english_start\":13,\"english_end\":13},{\"english_start\":14,\"english_end\":14}]}]}"}}},{"slug":"plot-a5-voltage","title":"Plot the A5 voltage","description":"Read analog pin A5 ~20×/s and print \"A5:raw,volts:v\" so the Plot tab can graph it live (and the Data tab can log it).","english":"Read the analog input on pin A5 — that's the voltage on the wire, somewhere between 0 and 5 volts — and stream it to the serial port so the Plot tab can graph it live.\n\nStart the serial connection at 9600 baud.\n\nOver and over, about twenty times a second:\n  Read the analog value on pin A5. It comes back as a whole number from 0 (0 volts) to 1023 (5 volts).\n  Work out the voltage: divide the reading by 1023 and multiply by 5.\n  Print one line with two labelled numbers — the raw reading as \"A5\" and the voltage (to two decimal places) as \"volts\" — like \"A5:512,volts:2.50\".\n  Wait about 50 milliseconds before the next reading.\n","app_html":"","settings":{},"by_lang":{"cpp":{"code":"void setup() {\n  Serial.begin(9600);\n}\n\nvoid loop() {\n  int reading = analogRead(A5);\n  float voltage = reading * 5.0 / 1023.0;\n  Serial.print(\"A5:\");\n  Serial.print(reading);\n  Serial.print(\",volts:\");\n  Serial.println(voltage, 2);\n  delay(50);\n}","links":[{"label":"function","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"statement","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"function_end","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"function","code_end":5,"code_start":5,"english_end":5,"english_start":5},{"label":"statement","code_end":6,"code_start":6,"english_end":6,"english_start":6},{"label":"statement","code_end":7,"code_start":7,"english_end":7,"english_start":7},{"label":"statement","code_end":8,"code_start":8,"english_end":8,"english_start":8},{"label":"statement","code_end":9,"code_start":9,"english_end":8,"english_start":8},{"label":"statement","code_end":10,"code_start":10,"english_end":8,"english_start":8},{"label":"statement","code_end":11,"code_start":11,"english_end":8,"english_start":8},{"label":"statement","code_end":12,"code_start":12,"english_end":9,"english_start":9},{"label":"function_end","code_end":13,"code_start":13,"english_end":9,"english_start":5}],"structure":"{\"functions\":[{\"name\":\"setup\",\"params\":[],\"english_start\":3,\"english_end\":3,\"summary\":\"Starts the serial connection at 9600 baud.\",\"calls\":[]},{\"name\":\"loop\",\"params\":[],\"english_start\":5,\"english_end\":9,\"summary\":\"Repeatedly reads A5, converts the reading to voltage, prints both values, and waits 50 ms.\",\"calls\":[{\"english_start\":6,\"english_end\":6},{\"english_start\":7,\"english_end\":7},{\"english_start\":8,\"english_end\":8},{\"english_start\":9,\"english_end\":9}]}]}"},"ruby":{"code":"Serial.begin(9600)\n\nloop do\n  reading = analogRead(:A5)\n  voltage = reading.to_f / 1023 * 5\n  Serial.println(\"A5:#{reading},volts:#{format('%.2f', voltage)}\")\n  sleep 0.05\nend","links":[{"label":"setup","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"loop_start","code_end":3,"code_start":3,"english_end":5,"english_start":5},{"label":"read_analog","code_end":4,"code_start":4,"english_end":6,"english_start":6},{"label":"compute_voltage","code_end":5,"code_start":5,"english_end":7,"english_start":7},{"label":"print_values","code_end":6,"code_start":6,"english_end":8,"english_start":8},{"label":"delay","code_end":7,"code_start":7,"english_end":9,"english_start":9},{"label":"loop_end","code_end":8,"code_start":8,"english_end":9,"english_start":5}],"structure":"{\"functions\":[]}"},"python":{"code":"import time\ntry:\n    from machine import ADC, Pin\nexcept ImportError:\n    ADC = Pin = None\nBAUD_RATE = 9600\nDELAY_SECONDS = 0.05\nif Pin is not None:\n    sensor = ADC(Pin(\"A5\"))\nelse:\n    sensor = None\nwhile True:\n    reading = sensor.read()\n    voltage = reading / 1023 * 5\n    print(f\"A5:{reading},volts:{voltage:.2f}\")\n    time.sleep(DELAY_SECONDS)","links":[{"label":"import","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"import","code_end":5,"code_start":2,"english_end":1,"english_start":1},{"label":"constant","code_end":6,"code_start":6,"english_end":3,"english_start":3},{"label":"constant","code_end":7,"code_start":7,"english_end":5,"english_start":5},{"label":"setup","code_end":9,"code_start":8,"english_end":1,"english_start":1},{"label":"setup","code_end":11,"code_start":10,"english_end":1,"english_start":1},{"label":"loop","code_end":12,"code_start":12,"english_end":9,"english_start":5},{"label":"loop-body","code_end":13,"code_start":13,"english_end":6,"english_start":6},{"label":"loop-body","code_end":14,"code_start":14,"english_end":7,"english_start":7},{"label":"loop-body","code_end":15,"code_start":15,"english_end":8,"english_start":8},{"label":"loop-body","code_end":16,"code_start":16,"english_end":9,"english_start":9}],"structure":"{\"functions\":[]}"},"javascript":{"code":"function setup() {\n  Serial.begin(9600);\n}\n\nfunction loop() {\n  const reading = analogRead(A5);\n  const voltage = (reading / 1023) * 5;\n  Serial.println(`A5:${reading},volts:${voltage.toFixed(2)}`);\n  delay(50);\n}","links":[{"label":"function_start","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"serial_baud","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"function_end","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"function_start","code_end":5,"code_start":5,"english_end":5,"english_start":5},{"label":"read_analog","code_end":6,"code_start":6,"english_end":6,"english_start":6},{"label":"compute_voltage","code_end":7,"code_start":7,"english_end":7,"english_start":7},{"label":"print_values","code_end":8,"code_start":8,"english_end":8,"english_start":8},{"label":"wait","code_end":9,"code_start":9,"english_end":9,"english_start":9},{"label":"function_end","code_end":10,"code_start":10,"english_end":9,"english_start":5}],"structure":"{\"functions\":[{\"name\":\"setup\",\"params\":[],\"english_start\":3,\"english_end\":3,\"summary\":\"Start the serial connection at 9600 baud.\",\"calls\":[]},{\"name\":\"loop\",\"params\":[],\"english_start\":5,\"english_end\":9,\"summary\":\"Repeatedly read A5, convert to voltage, print both values, and pause about 50 ms.\",\"calls\":[]}]}"}}},{"slug":"pot-button-stream","title":"Pot + button → stream A5 and D7","description":"Send the A5 potentiometer and the D7 button ~30×/s as \"pot:NNN,d7:0|1\" — pairs with the Drum pad and Asteroids demos on the App tab.","english":"Read a potentiometer on pin A5 and a pushbutton on pin 7, and stream both to the serial port fast enough to drive a game — about thirty times a second.\n\nStart the serial connection at 9600 baud.\nSet pin 7 as an input using the internal pull-up resistor, so it reads HIGH when the button is open and LOW when it is pressed.\n\nOver and over:\n  Read the analog value on A5 — a whole number from 0 to 1023.\n  Read pin 7. Because of the pull-up it reads LOW when the button is pressed, so call that 1, and not-pressed 0.\n  Print one line with two labelled numbers: the pot reading as \"pot\" and the button state as \"d7\" — like \"pot:512,d7:0\".\n  Wait about 30 milliseconds.\n","app_html":"","settings":{},"by_lang":{"python":{"code":"import time\nfrom machine import ADC, Pin\n\npot = ADC('A5')\nbutton = Pin(7, Pin.IN, Pin.PULL_UP)\n\nif __name__ == \"__main__\":\n    while True:\n        pot_value = pot.read_u16() // 64\n        button_value = 1 if button.value() == 0 else 0\n        print(f\"pot:{pot_value},d7:{button_value}\")\n        time.sleep(0.03)","links":[{"label":"import time","code_end":1,"code_start":1,"english_end":4,"english_start":3},{"label":"import machine","code_end":2,"code_start":2,"english_end":4,"english_start":3},{"label":"setup potentiometer","code_end":4,"code_start":4,"english_end":4,"english_start":3},{"label":"setup button","code_end":5,"code_start":5,"english_end":4,"english_start":3},{"label":"entry point","code_end":7,"code_start":7,"english_end":10,"english_start":6},{"label":"loop","code_end":8,"code_start":8,"english_end":10,"english_start":6},{"label":"read pot","code_end":9,"code_start":9,"english_end":7,"english_start":7},{"label":"read button","code_end":10,"code_start":10,"english_end":8,"english_start":8},{"label":"print line","code_end":11,"code_start":11,"english_end":9,"english_start":9},{"label":"delay","code_end":12,"code_start":12,"english_end":10,"english_start":10}],"structure":"{\"functions\":[]}"},"cpp":{"code":"const int potPin = A5;\nconst int buttonPin = 7;\nvoid setup() {\n  Serial.begin(9600);\n  pinMode(buttonPin, INPUT_PULLUP);\n}\n\nvoid loop() {\n  int potValue = analogRead(potPin);\n  int buttonState = digitalRead(buttonPin) == LOW ? 1 : 0;\n  Serial.print(\"pot:\");\n  Serial.print(potValue);\n  Serial.print(\",d7:\");\n  Serial.println(buttonState);\n  delay(30);\n}","links":[{"label":"declaration","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"declaration","code_end":2,"code_start":2,"english_end":1,"english_start":1},{"label":"function_start","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"statement","code_end":4,"code_start":4,"english_end":3,"english_start":3},{"label":"statement","code_end":5,"code_start":5,"english_end":4,"english_start":4},{"label":"function_end","code_end":6,"code_start":6,"english_end":4,"english_start":4},{"label":"function_start","code_end":8,"code_start":8,"english_end":6,"english_start":6},{"label":"statement","code_end":9,"code_start":9,"english_end":7,"english_start":7},{"label":"statement","code_end":10,"code_start":10,"english_end":8,"english_start":8},{"label":"statement","code_end":11,"code_start":11,"english_end":9,"english_start":9},{"label":"statement","code_end":12,"code_start":12,"english_end":9,"english_start":9},{"label":"statement","code_end":13,"code_start":13,"english_end":9,"english_start":9},{"label":"statement","code_end":14,"code_start":14,"english_end":9,"english_start":9},{"label":"statement","code_end":15,"code_start":15,"english_end":10,"english_start":10},{"label":"function_end","code_end":16,"code_start":16,"english_end":10,"english_start":10}],"structure":"{\"functions\":[{\"name\":\"setup\",\"params\":[],\"english_start\":3,\"english_end\":4,\"summary\":\"Start serial at 9600 baud and configure pin 7 with the internal pull-up resistor.\",\"calls\":[]},{\"name\":\"loop\",\"params\":[],\"english_start\":6,\"english_end\":10,\"summary\":\"Repeatedly read the potentiometer and button, print a labeled line, then wait about 30 ms.\",\"calls\":[{\"english_start\":7,\"english_end\":7},{\"english_start\":8,\"english_end\":8}]}]}"},"javascript":{"code":"const BAUD = 9600;\nconst SAMPLE_MS = 30;\nconst POT_PIN = 'A5';\nconst BUTTON_PIN = 7;\n\nconsole.log(`Serial started at ${BAUD} baud`);\nconsole.log(`Pin ${BUTTON_PIN} set as input with internal pull-up`);\n\nsetInterval(() => {\n  const pot = 0;\n  const d7 = 0;\n  console.log(`pot:${pot},d7:${d7}`);\n}, SAMPLE_MS);","links":[{"label":"setup","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"setup","code_end":2,"code_start":2,"english_end":1,"english_start":1},{"label":"setup","code_end":3,"code_start":3,"english_end":1,"english_start":1},{"label":"setup","code_end":4,"code_start":4,"english_end":1,"english_start":1},{"label":"serial","code_end":6,"code_start":6,"english_end":4,"english_start":3},{"label":"pin-setup","code_end":7,"code_start":7,"english_end":4,"english_start":4},{"label":"loop-start","code_end":9,"code_start":9,"english_end":10,"english_start":6},{"label":"read-pot","code_end":10,"code_start":10,"english_end":8,"english_start":7},{"label":"read-button","code_end":11,"code_start":11,"english_end":8,"english_start":7},{"label":"print","code_end":12,"code_start":12,"english_end":9,"english_start":9},{"label":"loop-end","code_end":13,"code_start":13,"english_end":10,"english_start":10}],"structure":"{\"functions\":[]}"},"ruby":{"code":"serial_begin(9600)\npin_mode(7, :input_pullup)\nloop do\n  pot = analog_read(:A5)\n  d7 = digital_read(7) == :low ? 1 : 0\n  puts \"pot:\", pot, \",d7:\", d7\n  sleep 0.03\nend","links":[{"label":"start serial","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"configure button pin","code_end":2,"code_start":2,"english_end":1,"english_start":1},{"label":"repeat forever","code_end":3,"code_start":3,"english_end":10,"english_start":6},{"label":"read potentiometer","code_end":4,"code_start":4,"english_end":7,"english_start":7},{"label":"read button and convert","code_end":5,"code_start":5,"english_end":8,"english_start":8},{"label":"print values","code_end":6,"code_start":6,"english_end":9,"english_start":9},{"label":"wait 30 ms","code_end":7,"code_start":7,"english_end":10,"english_start":10},{"label":"end loop","code_end":8,"code_start":8,"english_end":10,"english_start":6}],"structure":"{\"functions\":[]}"}}},{"slug":"ctc-01-blink","title":"Crack the Code · PRP #01 — Blink (D12)","description":"Flash the ThinkerShield's D12 LED on for one second, off for one second, forever — the first Arduino sketch.","english":"Flash an LED on pin 12 — on for one second, off for one second, forever. This is the classic \"Hello, world!\" for hardware.\n\nSet pin 12 as an output.\n\nForever:\n  Turn pin 12 on (HIGH).\n  Wait one second.\n  Turn pin 12 off (LOW).\n  Wait one second.\n","app_html":"","settings":{},"by_lang":{"cpp":{"code":"void setup() {              // runs once when you press reset or power the board\n  pinMode(12, OUTPUT);      // make digital pin 12 an output\n}\n\nvoid loop() {               // runs over and over again, forever\n  digitalWrite(12, HIGH);   // turn the LED on (HIGH is the voltage level)\n  delay(1000);              // wait for one second (1000 milliseconds)\n  digitalWrite(12, LOW);    // turn the LED off (LOW)\n  delay(1000);              // wait for one second\n}\n","links":[],"structure":null},"ruby":{"code":"require 'pi_piper'\nled = PiPiper::Pin.new(pin: 12, direction: :out)\nloop do\n  led.on\n  sleep 1\n  led.off\n  sleep 1\nend","links":[{"label":"setup","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"setup","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"loop","code_end":3,"code_start":3,"english_end":5,"english_start":5},{"label":"loop","code_end":4,"code_start":4,"english_end":6,"english_start":6},{"label":"loop","code_end":5,"code_start":5,"english_end":7,"english_start":7},{"label":"loop","code_end":6,"code_start":6,"english_end":8,"english_start":8},{"label":"loop","code_end":7,"code_start":7,"english_end":9,"english_start":9},{"label":"loop","code_end":8,"code_start":8,"english_end":9,"english_start":5}],"structure":"{\"functions\":[]}"},"javascript":{"code":"const { Gpio } = require('onoff');\nconst led = new Gpio(12, 'out');\nconst wait = ms => new Promise(resolve => setTimeout(resolve, ms));\nconst blink = async () => {\n  led.writeSync(1);\n  await wait(1000);\n  led.writeSync(0);\n  await wait(1000);\n};\nsetInterval(() => {\n  blink().catch(err => console.error(err));\n}, 2000);\n\nprocess.on('SIGINT', () => {\n  led.writeSync(0);\n  led.unexport();\n  process.exit(0);\n});","links":[{"label":"setup","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"setup","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"helper","code_end":3,"code_start":3,"english_end":5,"english_start":5},{"label":"function","code_end":4,"code_start":4,"english_end":5,"english_start":5},{"label":"function_body","code_end":5,"code_start":5,"english_end":6,"english_start":6},{"label":"function_body","code_end":6,"code_start":6,"english_end":7,"english_start":7},{"label":"function_body","code_end":7,"code_start":7,"english_end":8,"english_start":8},{"label":"function_body","code_end":8,"code_start":8,"english_end":9,"english_start":9},{"label":"function_end","code_end":9,"code_start":9,"english_end":5,"english_start":5},{"label":"loop","code_end":10,"code_start":10,"english_end":9,"english_start":5},{"label":"loop","code_end":11,"code_start":11,"english_end":9,"english_start":5},{"label":"loop","code_end":12,"code_start":12,"english_end":9,"english_start":5},{"label":"cleanup","code_end":14,"code_start":14,"english_end":9,"english_start":5},{"label":"cleanup","code_end":15,"code_start":15,"english_end":9,"english_start":5},{"label":"cleanup","code_end":16,"code_start":16,"english_end":9,"english_start":5},{"label":"cleanup","code_end":17,"code_start":17,"english_end":9,"english_start":5},{"label":"cleanup","code_end":18,"code_start":18,"english_end":9,"english_start":5}],"structure":"{\"functions\":[{\"name\":\"blink\",\"params\":[],\"english_start\":5,\"english_end\":9,\"summary\":\"Turn the LED on, wait one second, turn it off, then wait one second.\",\"calls\":[{\"english_start\":7,\"english_end\":7},{\"english_start\":9,\"english_end\":9}]}]}"},"python":{"code":"import time\nimport RPi.GPIO as GPIO\n\nGPIO.setmode(GPIO.BCM)\nGPIO.setup(12, GPIO.OUT)\ntry:\n    while True:\n        GPIO.output(12, GPIO.HIGH)\n        time.sleep(1)\n        GPIO.output(12, GPIO.LOW)\n        time.sleep(1)\nfinally:\n    GPIO.cleanup()\n\nif __name__ == \"__main__\":\n    pass","links":[{"label":"import","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"import","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"setup","code_end":4,"code_start":4,"english_end":3,"english_start":3},{"label":"setup","code_end":5,"code_start":5,"english_end":3,"english_start":3},{"label":"loop","code_end":6,"code_start":6,"english_end":9,"english_start":5},{"label":"loop","code_end":7,"code_start":7,"english_end":9,"english_start":5},{"label":"output_high","code_end":8,"code_start":8,"english_end":6,"english_start":6},{"label":"sleep","code_end":9,"code_start":9,"english_end":7,"english_start":7},{"label":"output_low","code_end":10,"code_start":10,"english_end":8,"english_start":8},{"label":"sleep","code_end":11,"code_start":11,"english_end":9,"english_start":9},{"label":"cleanup","code_end":12,"code_start":12,"english_end":9,"english_start":5},{"label":"cleanup","code_end":13,"code_start":13,"english_end":9,"english_start":5},{"label":"entry","code_end":15,"code_start":15,"english_end":9,"english_start":5},{"label":"entry","code_end":16,"code_start":16,"english_end":9,"english_start":5}],"structure":"{\"functions\":[]}"}}},{"slug":"ctc-02-button","title":"Crack the Code · PRP #02 — Button → LED (D7 → D12)","description":"Use the ThinkerShield's pushbutton on D7 to switch the D12 LED on and off — digitalRead and an if/else.","english":"Light the LED on pin 12 while the pushbutton on pin 7 is pressed; turn it off when the button is released.\n\nCall pin 7 \"buttonPin\" and pin 12 \"ledPin\". Keep an integer \"buttonState\" for the current button reading, starting at 0.\n\nSet ledPin as an output and buttonPin as an input.\n\nForever:\n  Read buttonPin into buttonState.\n  If buttonState is HIGH (the button is pressed): turn ledPin on.\n  Otherwise: turn ledPin off.\n","app_html":"","settings":{},"by_lang":{"cpp":{"code":"int buttonPin = 7;        // the pushbutton is on pin D7 of the ThinkerShield\nint ledPin = 12;          // the LED is on pin D12\nint buttonState = 0;      // variable for reading the pushbutton's state\n\nvoid setup() {\n  pinMode(ledPin, OUTPUT);     // the LED pin is an output\n  pinMode(buttonPin, INPUT);   // the button pin is an input\n}\n\nvoid loop() {\n  buttonState = digitalRead(buttonPin);   // read the button\n  if (buttonState == HIGH) {              // is it pressed?\n    digitalWrite(ledPin, HIGH);           // yes -> LED on\n  } else {\n    digitalWrite(ledPin, LOW);            // no  -> LED off\n  }\n}\n","links":[],"structure":null},"python":{"code":"from machine import Pin\nbuttonPin = Pin(7, Pin.IN)\nledPin = Pin(12, Pin.OUT)\nbuttonState = 0\n\nwhile True:\n    buttonState = buttonPin.value()\n    if buttonState == 1:\n        ledPin.value(1)\n    else:\n        ledPin.value(0)","links":[{"label":"import","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"declaration","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"declaration","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"declaration","code_end":4,"code_start":4,"english_end":3,"english_start":3},{"label":"loop","code_end":6,"code_start":6,"english_end":7,"english_start":7},{"label":"assignment","code_end":7,"code_start":7,"english_end":8,"english_start":8},{"label":"if","code_end":8,"code_start":8,"english_end":9,"english_start":9},{"label":"then","code_end":9,"code_start":9,"english_end":9,"english_start":9},{"label":"else","code_end":10,"code_start":10,"english_end":10,"english_start":10},{"label":"else_body","code_end":11,"code_start":11,"english_end":10,"english_start":10}],"structure":"{\"functions\":[]}"},"ruby":{"code":"buttonPin = 7\nledPin = 12\nbuttonState = 0\npin_mode(ledPin, OUTPUT)\npin_mode(buttonPin, INPUT)\nloop do\nbuttonState = digital_read(buttonPin)\nif buttonState == HIGH\ndigital_write(ledPin, HIGH)\nelse\ndigital_write(ledPin, LOW)\nend","links":[{"label":"assignment","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"assignment","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"assignment","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"statement","code_end":4,"code_start":4,"english_end":5,"english_start":5},{"label":"statement","code_end":5,"code_start":5,"english_end":5,"english_start":5},{"label":"control","code_end":6,"code_start":6,"english_end":10,"english_start":7},{"label":"statement","code_end":7,"code_start":7,"english_end":8,"english_start":8},{"label":"control","code_end":8,"code_start":8,"english_end":9,"english_start":9},{"label":"statement","code_end":9,"code_start":9,"english_end":9,"english_start":9},{"label":"control","code_end":10,"code_start":10,"english_end":10,"english_start":10},{"label":"statement","code_end":11,"code_start":11,"english_end":10,"english_start":10},{"label":"control","code_end":12,"code_start":12,"english_end":10,"english_start":7}],"structure":"{\"functions\":[]}"},"javascript":{"code":"const { Board, Led, Button } = require('johnny-five');\nconst buttonPin = 7;\nconst ledPin = 12;\nlet buttonState = 0;\nconst board = new Board();\nboard.on('ready', () => {\n  const led = new Led(ledPin);\n  const button = new Button(buttonPin);\n  const updateLed = () => {\n    buttonState = button.isPressed ? 1 : 0;\n    if (buttonState === 1) {\n      led.on();\n    } else {\n      led.off();\n  };\n  setInterval(updateLed, 10);\n});","links":[{"label":"import hardware library","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"set button pin","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"set led pin","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"initialize button state","code_end":4,"code_start":4,"english_end":3,"english_start":3},{"label":"create board","code_end":5,"code_start":5,"english_end":5,"english_start":5},{"label":"board ready handler","code_end":6,"code_start":6,"english_end":7,"english_start":7},{"label":"configure led as output","code_end":7,"code_start":7,"english_end":5,"english_start":5},{"label":"configure button as input","code_end":8,"code_start":8,"english_end":5,"english_start":5},{"label":"start loop","code_end":9,"code_start":9,"english_end":10,"english_start":8},{"label":"read button state","code_end":10,"code_start":10,"english_end":8,"english_start":8},{"label":"pressed branch","code_end":11,"code_start":11,"english_end":9,"english_start":9},{"label":"turn led on","code_end":12,"code_start":12,"english_end":9,"english_start":9},{"label":"released branch","code_end":13,"code_start":13,"english_end":10,"english_start":10},{"label":"turn led off","code_end":14,"code_start":14,"english_end":10,"english_start":10},{"label":"end loop","code_end":15,"code_start":15,"english_end":10,"english_start":7},{"label":"repeat forever","code_end":16,"code_start":16,"english_end":10,"english_start":7},{"label":"close board ready handler","code_end":17,"code_start":17,"english_end":10,"english_start":7}],"structure":"{\"functions\":[{\"name\":\"updateLed\",\"params\":[],\"english_start\":8,\"english_end\":10,\"summary\":\"Reads the button state and turns the LED on while pressed, otherwise off.\",\"calls\":[]}]}"}}},{"slug":"ctc-03-int","title":"Crack the Code · PRP #02 — The int command","description":"Blink, rewritten to give pin 12 the name LED with the int command — clearer code, and you only change a pin in one place.","english":"Blink the LED — but give pin 12 a name first, so the rest of the code reads more clearly and you only have one place to change if the wiring moves.\n\nCall pin 12 \"LED\".\n\nSet LED as an output.\n\nForever:\n  Turn LED on.\n  Wait one second.\n  Turn LED off.\n  Wait one second.\n","app_html":"","settings":{},"by_lang":{"python":{"code":"LED = 12\nprint(\"Set LED as an output.\")\nwhile True:\n    print(\"Turn LED on.\")\n    time.sleep(1)\n    print(\"Turn LED off.\")\n    time.sleep(1)","links":[{"label":"assign name to pin 12","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"set LED as output","code_end":2,"code_start":2,"english_end":5,"english_start":5},{"label":"forever loop","code_end":3,"code_start":3,"english_end":7,"english_start":7},{"label":"turn LED on","code_end":4,"code_start":4,"english_end":8,"english_start":8},{"label":"wait one second","code_end":5,"code_start":5,"english_end":9,"english_start":9},{"label":"turn LED off","code_end":6,"code_start":6,"english_end":10,"english_start":10},{"label":"wait one second","code_end":7,"code_start":7,"english_end":11,"english_start":11}],"structure":"{\"functions\":[]}"},"ruby":{"code":"# Blink the LED, but give pin 12 a name first, so the rest of the code reads more clearly and you only have one place to change if the wiring moves.\nLED = 12\n# Set LED as an output.\nloop do\n  puts \"LED on\"\n  sleep 1\n  puts \"LED off\"\n  sleep 1\nend","links":[{"label":"comment","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"constant","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"comment","code_end":3,"code_start":3,"english_end":5,"english_start":5},{"label":"loop_start","code_end":4,"code_start":4,"english_end":7,"english_start":7},{"label":"on","code_end":5,"code_start":5,"english_end":8,"english_start":8},{"label":"wait_on","code_end":6,"code_start":6,"english_end":9,"english_start":9},{"label":"off","code_end":7,"code_start":7,"english_end":10,"english_start":10},{"label":"wait_off","code_end":8,"code_start":8,"english_end":11,"english_start":11},{"label":"loop_end","code_end":9,"code_start":9,"english_end":11,"english_start":11}],"structure":"{\"functions\":[]}"},"javascript":{"code":"const { Board, Led } = require('johnny-five');\nconst LED_PIN = 12;\nconst board = new Board();\nboard.on('ready', () => {\n  const LED = new Led(LED_PIN);\n  LED.on();\n  setInterval(() => {\n    LED.on();\n    setTimeout(() => {\n      LED.off();\n      setTimeout(() => {\n      }, 1000);\n    }, 1000);\n  }, 2000);\n});","links":[{"label":"import hardware library","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"name pin 12","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"create board","code_end":3,"code_start":3,"english_end":5,"english_start":5},{"label":"forever setup start","code_end":4,"code_start":4,"english_end":7,"english_start":7},{"label":"create led from named pin","code_end":5,"code_start":5,"english_end":3,"english_start":3},{"label":"set led as output and initial state","code_end":6,"code_start":6,"english_end":5,"english_start":5},{"label":"forever loop start","code_end":7,"code_start":7,"english_end":11,"english_start":7},{"label":"turn led on","code_end":8,"code_start":8,"english_end":11,"english_start":8},{"label":"wait one second before turning off","code_end":9,"code_start":9,"english_end":9,"english_start":9},{"label":"turn led off","code_end":10,"code_start":10,"english_end":10,"english_start":10},{"label":"wait one second before next cycle","code_end":11,"code_start":11,"english_end":11,"english_start":11},{"label":"end wait","code_end":12,"code_start":12,"english_end":11,"english_start":11},{"label":"end off delay","code_end":13,"code_start":13,"english_end":10,"english_start":10},{"label":"repeat forever","code_end":14,"code_start":14,"english_end":11,"english_start":7},{"label":"close board ready handler","code_end":15,"code_start":15,"english_end":11,"english_start":7}],"structure":"{\"functions\":[]}"},"cpp":{"code":"int LED = 12;             // call pin 12 \"LED\" for the rest of this sketch\n\nvoid setup() {\n  pinMode(LED, OUTPUT);   // make the LED pin an output\n}\n\nvoid loop() {             // runs over and over again, forever\n  digitalWrite(LED, HIGH);  // turn the LED on\n  delay(1000);              // wait for one second\n  digitalWrite(LED, LOW);   // turn the LED off\n  delay(1000);              // wait for one second\n}\n","links":[],"structure":null}}},{"slug":"ctc-05-analog-input","title":"Crack the Code · PRP #03 — Analog input (A5 → blink rate)","description":"Read the ThinkerShield's potentiometer on A5 with analogRead, use the value to set the LED's blink rate, and print it to the Serial Monitor.","english":"Read the potentiometer on analog pin A5, use its value to set the blink rate of the LED on pin 12, and print the reading to the serial port.\n\nCall A5 \"sensorPin\" and pin 12 \"ledPin\". Keep an integer \"sensorValue\" for the latest reading, starting at 0.\n\nSet ledPin as an output. Start the serial connection at 9600 baud so we can print the sensor value.\n\nForever:\n  Read the analog value on sensorPin into sensorValue (it'll be 0 to 1023).\n  Turn the LED on.\n  Wait sensorValue milliseconds.\n  Turn the LED off.\n  Wait sensorValue milliseconds again.\n  Print \"The sensor value is: \" followed by sensorValue to the serial port.\n","app_html":"","settings":{},"by_lang":{"cpp":{"code":"int sensorPin = A5;       // the potentiometer (POT A5) on the ThinkerShield\nint ledPin = 12;          // the LED on pin D12\nint sensorValue = 0;      // variable to store the value from the sensor\n\nvoid setup() {\n  pinMode(ledPin, OUTPUT);  // the LED pin is an output\n  Serial.begin(9600);       // start serial so we can print the sensor value\n}\n\nvoid loop() {\n  sensorValue = analogRead(sensorPin);  // read the knob (0 to 1023)\n  digitalWrite(ledPin, HIGH);           // LED on\n  delay(sensorValue);                   // wait — bigger value, longer wait\n  digitalWrite(ledPin, LOW);            // LED off\n  delay(sensorValue);                   // wait again\n  Serial.print(\"The sensor value is: \");\n  Serial.println(sensorValue);          // print the value to the Serial Monitor\n}\n","links":[],"structure":null},"python":{"code":"sensorPin = 'A5'\nledPin = 12\nsensorValue = 0\n\nimport random\nimport time\n\ndef serial_begin(baud):\n    pass\n\nserial_begin(9600)\n\nwhile True:\n    sensorValue = random.randint(0, 1023)\n    print(f'LED on pin {ledPin} ON')\n    time.sleep(sensorValue / 1000.0)\n    print(f'LED on pin {ledPin} OFF')\n    time.sleep(sensorValue / 1000.0)\n    print(f'The sensor value is: {sensorValue}')","links":[{"label":"assignment","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"assignment","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"assignment","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"import","code_end":5,"code_start":5,"english_end":5,"english_start":5},{"label":"import","code_end":6,"code_start":6,"english_end":5,"english_start":5},{"label":"function","code_end":8,"code_start":8,"english_end":5,"english_start":5},{"label":"function_body","code_end":9,"code_start":9,"english_end":5,"english_start":5},{"label":"call","code_end":11,"code_start":11,"english_end":5,"english_start":5},{"label":"loop","code_end":13,"code_start":13,"english_end":13,"english_start":7},{"label":"assignment","code_end":14,"code_start":14,"english_end":8,"english_start":8},{"label":"print","code_end":15,"code_start":15,"english_end":9,"english_start":9},{"label":"sleep","code_end":16,"code_start":16,"english_end":10,"english_start":10},{"label":"print","code_end":17,"code_start":17,"english_end":11,"english_start":11},{"label":"sleep","code_end":18,"code_start":18,"english_end":12,"english_start":12},{"label":"print","code_end":19,"code_start":19,"english_end":13,"english_start":13}],"structure":"{\"functions\":[{\"name\":\"serial_begin\",\"params\":[\"baud\"],\"english_start\":5,\"english_end\":5,\"summary\":\"Placeholder for starting the serial connection.\",\"calls\":[]}]}"},"ruby":{"code":"sensorPin = :A5\nledPin = 12\nsensorValue = 0\npinMode(ledPin, :output)\nserialBegin(9600)\nloop do\n  sensorValue = analogRead(sensorPin)\n  digitalWrite(ledPin, :high)\n  sleep(sensorValue / 1000.0)\n  digitalWrite(ledPin, :low)\n  sleep(sensorValue / 1000.0)\n  serialPrintln(\"The sensor value is: #{sensorValue}\")\nend","links":[{"label":"assignment","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"assignment","code_end":2,"code_start":2,"english_end":1,"english_start":1},{"label":"assignment","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"statement","code_end":4,"code_start":4,"english_end":5,"english_start":5},{"label":"statement","code_end":5,"code_start":5,"english_end":5,"english_start":5},{"label":"loop_start","code_end":6,"code_start":6,"english_end":13,"english_start":7},{"label":"statement","code_end":7,"code_start":7,"english_end":8,"english_start":8},{"label":"statement","code_end":8,"code_start":8,"english_end":9,"english_start":9},{"label":"statement","code_end":9,"code_start":9,"english_end":10,"english_start":10},{"label":"statement","code_end":10,"code_start":10,"english_end":11,"english_start":11},{"label":"statement","code_end":11,"code_start":11,"english_end":12,"english_start":12},{"label":"statement","code_end":12,"code_start":12,"english_end":13,"english_start":13},{"label":"loop_end","code_end":13,"code_start":13,"english_end":13,"english_start":7}],"structure":"{\"functions\":[]}"},"javascript":{"code":"const sensorPin = 'A5';\nconst ledPin = 12;\nlet sensorValue = 0;\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconsole.log('Serial started at 9600 baud');\nconsole.log(`Pin ${ledPin} set as output`);\n(async () => {\n  while (true) {\n    sensorValue = Math.floor(Math.random() * 1024);\n    console.log(`LED ${ledPin} ON`);\n    await sleep(sensorValue);\n    console.log(`LED ${ledPin} OFF`);\n    await sleep(sensorValue);\n    console.log(`The sensor value is: ${sensorValue}`);\n  }\n})();","links":[{"label":"declaration","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"declaration","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"declaration","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"helper","code_end":5,"code_start":5,"english_end":5,"english_start":5},{"label":"setup","code_end":7,"code_start":7,"english_end":5,"english_start":5},{"label":"setup","code_end":8,"code_start":8,"english_end":5,"english_start":5},{"label":"loop_start","code_end":9,"code_start":9,"english_end":13,"english_start":7},{"label":"loop","code_end":10,"code_start":10,"english_end":8,"english_start":8},{"label":"read_sensor","code_end":11,"code_start":11,"english_end":8,"english_start":8},{"label":"led_on","code_end":12,"code_start":12,"english_end":9,"english_start":9},{"label":"delay","code_end":13,"code_start":13,"english_end":10,"english_start":10},{"label":"led_off","code_end":14,"code_start":14,"english_end":11,"english_start":11},{"label":"delay","code_end":15,"code_start":15,"english_end":12,"english_start":12},{"label":"print","code_end":16,"code_start":16,"english_end":13,"english_start":13},{"label":"loop_end","code_end":17,"code_start":17,"english_end":13,"english_start":8},{"label":"loop_end","code_end":18,"code_start":18,"english_end":13,"english_start":7}],"structure":"{\"functions\":[]}"}}},{"slug":"ctc-07-buzzer1","title":"Crack the Code · PRP #04 — Buzzer (D3)","description":"Beep the ThinkerShield's piezo buzzer on D3 with the tone(pin, frequency, duration) command.","english":"Beep the piezo buzzer on pin 3 a few times a second, forever.\n\nCall pin 3 \"buzzerPin\".\n\nSet buzzerPin as an output.\n\nForever:\n  Play a 600 Hz tone on buzzerPin for 30 milliseconds.\n  Wait 150 milliseconds before repeating.\n","app_html":"","settings":{},"by_lang":{"cpp":{"code":"int buzzerPin = 3;        // the piezo buzzer is on pin D3 of the ThinkerShield\n\nvoid setup() {\n  pinMode(buzzerPin, OUTPUT);   // the buzzer pin is an output\n}\n\nvoid loop() {\n  tone(buzzerPin, 600, 30);     // play a 600 Hz tone for 30 ms...\n  delay(150);                   // ...then wait 150 ms before repeating\n}\n","links":[],"structure":null},"python":{"code":"buzzerPin = 3\nfrom machine import Pin, PWM\nbuzzerPin = Pin(buzzerPin, Pin.OUT)\nif __name__ == \"__main__\":\n    while True:\n        buzzer = PWM(buzzerPin)\n        buzzer.freq(600)\n        buzzer.duty_u16(32768)\n        import time\n        time.sleep_ms(30)\n        buzzer.deinit()\n        time.sleep_ms(150)","links":[{"label":"assignment","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"import","code_end":2,"code_start":2,"english_end":5,"english_start":5},{"label":"setup_pin","code_end":3,"code_start":3,"english_end":5,"english_start":5},{"label":"entry_point","code_end":4,"code_start":4,"english_end":7,"english_start":7},{"label":"loop","code_end":5,"code_start":5,"english_end":7,"english_start":7},{"label":"tone_setup","code_end":6,"code_start":6,"english_end":8,"english_start":8},{"label":"tone_freq","code_end":7,"code_start":7,"english_end":8,"english_start":8},{"label":"tone_on","code_end":8,"code_start":8,"english_end":8,"english_start":8},{"label":"import_time","code_end":9,"code_start":9,"english_end":8,"english_start":8},{"label":"tone_duration","code_end":10,"code_start":10,"english_end":8,"english_start":8},{"label":"tone_off","code_end":11,"code_start":11,"english_end":8,"english_start":8},{"label":"pause","code_end":12,"code_start":12,"english_end":9,"english_start":9}],"structure":"{\"functions\":[]}"},"ruby":{"code":"buzzerPin = 3\npinMode(buzzerPin, OUTPUT)\nloop do\n  tone(buzzerPin, 600, 30)\n  sleep 0.15\nend","links":[{"label":"declare buzzer pin","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"set pin as output","code_end":2,"code_start":2,"english_end":5,"english_start":5},{"label":"start forever loop","code_end":3,"code_start":3,"english_end":7,"english_start":7},{"label":"play tone","code_end":4,"code_start":4,"english_end":8,"english_start":8},{"label":"wait before repeating","code_end":5,"code_start":5,"english_end":9,"english_start":9},{"label":"end forever loop","code_end":6,"code_start":6,"english_end":9,"english_start":7}],"structure":"{\"functions\":[]}"},"javascript":{"code":"const buzzerPin = 3;\nconsole.log(`Setting buzzerPin (${buzzerPin}) as an output.`);\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\nconst playTone = async () => {\n  console.log(`Playing a 600 Hz tone on buzzerPin for 30 milliseconds.`);\n  await sleep(30);\n};\n\n(async () => {\n  while (true) {\n    await playTone();\n    await sleep(150);\n  }\n})();","links":[{"label":"declare buzzer pin","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"set pin as output","code_end":2,"code_start":2,"english_end":5,"english_start":5},{"label":"sleep helper","code_end":3,"code_start":3,"english_end":9,"english_start":8},{"label":"start tone function","code_end":4,"code_start":4,"english_end":8,"english_start":8},{"label":"tone on message","code_end":5,"code_start":5,"english_end":8,"english_start":8},{"label":"tone duration","code_end":6,"code_start":6,"english_end":8,"english_start":8},{"label":"end tone function","code_end":7,"code_start":7,"english_end":8,"english_start":8},{"label":"start forever loop","code_end":9,"code_start":9,"english_end":9,"english_start":7},{"label":"infinite loop","code_end":10,"code_start":10,"english_end":9,"english_start":7},{"label":"play tone each cycle","code_end":11,"code_start":11,"english_end":9,"english_start":7},{"label":"wait between tones","code_end":12,"code_start":12,"english_end":9,"english_start":7},{"label":"close infinite loop","code_end":13,"code_start":13,"english_end":9,"english_start":7},{"label":"run forever loop","code_end":14,"code_start":14,"english_end":9,"english_start":7}],"structure":"{\"functions\":[{\"name\":\"sleep\",\"params\":[\"ms\"],\"english_start\":8,\"english_end\":9,\"summary\":\"Wait for the given number of milliseconds.\",\"calls\":[{\"english_start\":8,\"english_end\":9}]},{\"name\":\"playTone\",\"params\":[],\"english_start\":8,\"english_end\":8,\"summary\":\"Log a 600 Hz buzzer tone action and hold it for 30 milliseconds.\",\"calls\":[{\"english_start\":8,\"english_end\":9}]}]}"}}},{"slug":"ctc-08-buzzer2-alarm","title":"Crack the Code · PRP #04 — Two-tone alarm","description":"Alternate a low tone and a high tone so the buzzer sounds like an alarm — a drop-in alarm sounder for the design project.","english":"Make the piezo buzzer on pin 3 sound like a two-tone alarm — alternating a low tone and a high tone, half a second each.\n\nKeep an integer lowTone equal to 400 (Hz) and an integer highTone equal to 600 (Hz). Use a constant ALARMSOUNDER to remember the buzzer is on pin 3.\n\nSet ALARMSOUNDER as an output.\n\nForever:\n  Play the low tone on ALARMSOUNDER for 500 milliseconds.\n  Wait 500 milliseconds.\n  Play the high tone on ALARMSOUNDER for 500 milliseconds.\n  Wait 500 milliseconds.\n","app_html":"","settings":{},"by_lang":{"python":{"code":"from time import sleep\n\nlowTone = 400\nhighTone = 600\nALARMSOUNDER = 3\n\ndef set_output(pin):\n    pass\n\nwhile True:\n    print(f\"tone {lowTone} Hz on pin {ALARMSOUNDER}\")\n    sleep(0.5)\n    print(f\"tone {highTone} Hz on pin {ALARMSOUNDER}\")\n    sleep(0.5)","links":[{"label":"import","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"assign","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"assign","code_end":4,"code_start":4,"english_end":3,"english_start":3},{"label":"assign","code_end":5,"code_start":5,"english_end":3,"english_start":3},{"label":"function_def","code_end":7,"code_start":7,"english_end":5,"english_start":5},{"label":"function_body","code_end":8,"code_start":8,"english_end":5,"english_start":5},{"label":"loop","code_end":10,"code_start":10,"english_end":11,"english_start":8},{"label":"statement","code_end":11,"code_start":11,"english_end":8,"english_start":8},{"label":"statement","code_end":12,"code_start":12,"english_end":8,"english_start":8},{"label":"statement","code_end":13,"code_start":13,"english_end":10,"english_start":10},{"label":"statement","code_end":14,"code_start":14,"english_end":10,"english_start":10}],"structure":"{\"functions\":[{\"name\":\"set_output\",\"params\":[\"pin\"],\"english_start\":5,\"english_end\":5,\"summary\":\"Placeholder for setting the buzzer pin as an output.\",\"calls\":[]}]}"},"ruby":{"code":"ALARMSOUNDER = 3\nlowTone = 400\nhighTone = 600\n\nputs \"Set pin #{ALARMSOUNDER} as an output\"\n\nloop do\n  puts \"Playing low tone #{lowTone} Hz on pin #{ALARMSOUNDER} for 500 ms\"\n  sleep 0.5\n  puts \"Playing high tone #{highTone} Hz on pin #{ALARMSOUNDER} for 500 ms\"\n  sleep 0.5\nend","links":[{"label":"constant","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"variable","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"variable","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"output","code_end":5,"code_start":5,"english_end":5,"english_start":5},{"label":"loop_start","code_end":7,"code_start":7,"english_end":11,"english_start":7},{"label":"action","code_end":8,"code_start":8,"english_end":8,"english_start":8},{"label":"wait","code_end":9,"code_start":9,"english_end":9,"english_start":8},{"label":"action","code_end":10,"code_start":10,"english_end":10,"english_start":10},{"label":"wait","code_end":11,"code_start":11,"english_end":11,"english_start":10},{"label":"loop_end","code_end":12,"code_start":12,"english_end":11,"english_start":11}],"structure":"{\"functions\":[]}"},"javascript":{"code":"const ALARMSOUNDER = 3;\nconst lowTone = 400;\nconst highTone = 600;\npinMode(ALARMSOUNDER, OUTPUT);\nsetInterval(() => {\n  tone(ALARMSOUNDER, lowTone, 500);\n  setTimeout(() => {\n    tone(ALARMSOUNDER, highTone, 500);\n  }, 500);\n}, 1000);","links":[{"label":"declaration","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"declaration","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"declaration","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"setup","code_end":4,"code_start":4,"english_end":5,"english_start":5},{"label":"loop_start","code_end":5,"code_start":5,"english_end":11,"english_start":7},{"label":"low_tone","code_end":6,"code_start":6,"english_end":8,"english_start":8},{"label":"delay_start","code_end":7,"code_start":7,"english_end":9,"english_start":9},{"label":"high_tone","code_end":8,"code_start":8,"english_end":10,"english_start":10},{"label":"delay_end","code_end":9,"code_start":9,"english_end":11,"english_start":11},{"label":"loop_end","code_end":10,"code_start":10,"english_end":11,"english_start":11}],"structure":"{\"functions\":[]}"},"cpp":{"code":"int lowTone = 400;\nint highTone = 600;\nconst int ALARMSOUNDER = 3;     // the buzzer is on pin D3\n\nvoid setup() {\n  pinMode(ALARMSOUNDER, OUTPUT);\n}\n\nvoid loop() {\n  tone(ALARMSOUNDER, lowTone, 500);   // low tone for half a second\n  delay(500);\n  tone(ALARMSOUNDER, highTone, 500);  // high tone for half a second\n  delay(500);\n}\n","links":[],"structure":null}}},{"slug":"ctc-09-buzzer3-sweep","title":"Crack the Code · PRP #04 extension — Tone sweep with a for loop","description":"Use a for loop to sweep the buzzer's tone smoothly up and back down — for loops are beyond the core unit, so this is an extension.","english":"Sweep the piezo buzzer's pitch smoothly up and back down, forever, using a for loop.\n\nUse a constant ALARMSOUNDER to remember the buzzer is on pin 3. Keep an integer i starting at 200.\n\nSet ALARMSOUNDER as an output.\n\nForever:\n  For i from 200 up to (but not including) 700, stepping up by 2 each time:\n    Play the tone i Hz on ALARMSOUNDER for 10 milliseconds.\n    Wait 10 milliseconds.\n  For i from 701 back down to (but not including) 200, stepping down by 2 each time:\n    Play the tone i Hz on ALARMSOUNDER for 10 milliseconds.\n    Wait 10 milliseconds.\n","app_html":"","settings":{},"by_lang":{"cpp":{"code":"int i = 200;\nconst int ALARMSOUNDER = 3;     // the buzzer is on pin D3\n\nvoid setup() {\n  pinMode(ALARMSOUNDER, OUTPUT);\n}\n\nvoid loop() {\n  for (i = 200; i < 700; i = i + 2) {   // sweep from a low tone up to a high tone\n    tone(ALARMSOUNDER, i, 10);          // play the tone, changing every 10 ms\n    delay(10);\n  }\n  for (i = 701; i > 200; i = i - 2) {   // sweep back down\n    tone(ALARMSOUNDER, i, 10);\n    delay(10);\n  }\n}\n","links":[],"structure":null},"python":{"code":"from machine import Pin, PWM\n\nALARMSOUNDER = 3\ni = 200\nbuzzer = PWM(Pin(ALARMSOUNDER))\nbuzzer.duty_u16(32768)\n\nwhile True:\n    for i in range(200, 700, 2):\n        buzzer.freq(i)\n        import time; time.sleep(0.01)\n    for i in range(701, 200, -2):\n        buzzer.freq(i)\n        import time; time.sleep(0.01)","links":[{"label":"import","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"constant","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"initialize","code_end":4,"code_start":4,"english_end":3,"english_start":3},{"label":"setup","code_end":5,"code_start":5,"english_end":5,"english_start":5},{"label":"setup","code_end":6,"code_start":6,"english_end":5,"english_start":5},{"label":"loop","code_end":8,"code_start":8,"english_end":7,"english_start":7},{"label":"up_sweep","code_end":9,"code_start":9,"english_end":10,"english_start":8},{"label":"tone","code_end":10,"code_start":10,"english_end":10,"english_start":9},{"label":"wait","code_end":11,"code_start":11,"english_end":10,"english_start":9},{"label":"down_sweep","code_end":12,"code_start":12,"english_end":13,"english_start":11},{"label":"tone","code_end":13,"code_start":13,"english_end":13,"english_start":12},{"label":"wait","code_end":14,"code_start":14,"english_end":13,"english_start":12}],"structure":"{\"functions\":[]}"},"ruby":{"code":"ALARMSOUNDER = 3\ni = 200\npin_mode(ALARMSOUNDER, :output)\nloop do\n  (200...700).step(2) do |i|\n    tone(ALARMSOUNDER, i, 10)\n    sleep(0.01)\n  end\n  (701...200).step(-2) do |i|\n    tone(ALARMSOUNDER, i, 10)\n    sleep(0.01)\n  end\nend","links":[{"label":"declare constant","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"initialize counter","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"set output mode","code_end":3,"code_start":3,"english_end":5,"english_start":5},{"label":"forever loop start","code_end":4,"code_start":4,"english_end":7,"english_start":7},{"label":"rising sweep loop","code_end":5,"code_start":5,"english_end":8,"english_start":8},{"label":"play tone","code_end":6,"code_start":6,"english_end":9,"english_start":9},{"label":"wait","code_end":7,"code_start":7,"english_end":10,"english_start":10},{"label":"end rising sweep loop","code_end":8,"code_start":8,"english_end":8,"english_start":8},{"label":"falling sweep loop","code_end":9,"code_start":9,"english_end":11,"english_start":11},{"label":"play tone","code_end":10,"code_start":10,"english_end":12,"english_start":12},{"label":"wait","code_end":11,"code_start":11,"english_end":13,"english_start":13},{"label":"end falling sweep loop","code_end":12,"code_start":12,"english_end":11,"english_start":11},{"label":"forever loop end","code_end":13,"code_start":13,"english_end":7,"english_start":7}],"structure":"{\"functions\":[]}"},"javascript":{"code":"const ALARMSOUNDER = 3;\nlet i = 200;\nconst setOutput = (pin) => {\n  console.log(`Set pin ${pin} as output`);\n};\nsetOutput(ALARMSOUNDER);\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst playTone = async (pin, frequency, duration) => {\n  console.log(`Play tone ${frequency} Hz on pin ${pin} for ${duration} ms`);\n  await sleep(duration);\n};\n\n(async () => {\n  for (i = 200; i < 700; i += 2) {\n    await playTone(ALARMSOUNDER, i, 10);\n    await sleep(10);\n  }\n  for (i = 701; i >= 200; i -= 2) {\n    await playTone(ALARMSOUNDER, i, 10);\n    await sleep(10);\n  }\n})();","links":[{"label":"declaration","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"declaration","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"function","code_end":3,"code_start":3,"english_end":5,"english_start":5},{"label":"statement","code_end":4,"code_start":4,"english_end":5,"english_start":5},{"label":"function_end","code_end":5,"code_start":5,"english_end":5,"english_start":5},{"label":"call","code_end":6,"code_start":6,"english_end":5,"english_start":5},{"label":"helper","code_end":7,"code_start":7,"english_end":13,"english_start":7},{"label":"function","code_end":9,"code_start":9,"english_end":13,"english_start":7},{"label":"statement","code_end":10,"code_start":10,"english_end":12,"english_start":9},{"label":"statement","code_end":11,"code_start":11,"english_end":13,"english_start":7},{"label":"function_end","code_end":12,"code_start":12,"english_end":13,"english_start":7},{"label":"loop","code_end":14,"code_start":14,"english_end":13,"english_start":7},{"label":"for_up","code_end":15,"code_start":15,"english_end":10,"english_start":8},{"label":"tone","code_end":16,"code_start":16,"english_end":10,"english_start":9},{"label":"wait","code_end":17,"code_start":17,"english_end":10,"english_start":9},{"label":"for_end","code_end":18,"code_start":18,"english_end":10,"english_start":8},{"label":"for_down","code_end":19,"code_start":19,"english_end":13,"english_start":11},{"label":"tone","code_end":20,"code_start":20,"english_end":13,"english_start":12},{"label":"wait","code_end":21,"code_start":21,"english_end":13,"english_start":12},{"label":"for_end","code_end":22,"code_start":22,"english_end":13,"english_start":11},{"label":"end","code_end":23,"code_start":23,"english_end":13,"english_start":7}],"structure":"{\"functions\":[{\"name\":\"setOutput\",\"params\":[\"pin\"],\"english_start\":5,\"english_end\":5,\"summary\":\"Marks the buzzer pin as output.\",\"calls\":[]},{\"name\":\"sleep\",\"params\":[\"ms\"],\"english_start\":7,\"english_end\":13,\"summary\":\"Returns a promise that resolves after a delay.\",\"calls\":[]},{\"name\":\"playTone\",\"params\":[\"pin\",\"frequency\",\"duration\"],\"english_start\":9,\"english_end\":12,\"summary\":\"Logs a tone playback and waits for its duration.\",\"calls\":[{\"english_start\":7,\"english_end\":13}]}]}"}}},{"slug":"ctc-10-alarm-basic","title":"Crack the Code · Design project — Basic box alarm","description":"Worked model for the design brief: a switch on the box arms the alarm after a short exit delay; opening the box flashes an LED and sounds the buzzer.","english":"A simple box alarm. After a short exit delay the alarm arms itself with a double-beep. When the box is opened (the switch on pin 7 reads LOW) the alarm triggers — the LED on pin 13 lights up and the buzzer alternates between two tones, forever.\n\nCall pin 7 \"sensorPin\" (the switch on the box), pin 13 \"flashPin\" (the LED that lights up when the alarm sounds), and pin 3 \"buzzerPin\". Keep an integer Status starting at 0 (0 = exit delay, 1 = armed, 2 = triggered), and an integer sensor starting at 0 for the current sensor reading.\n\nSet sensorPin as an input, and flashPin and buzzerPin as outputs.\n\nForever:\n  If Status is 0 — first time through the loop, so arm the alarm:\n    Wait 3 seconds (gives you 3 seconds to close the box).\n    Play a 725 Hz tone on buzzerPin for 40 ms.\n    Wait 200 ms.\n    Play another 725 Hz tone on buzzerPin for 40 ms — a double-beep that confirms it's armed.\n    Set Status to 1.\n\n  If Status is 1: read sensorPin into the sensor variable.\n\n  If sensor is 0 (the box has been opened): set Status to 2.\n\n  If Status is 2 — triggered, so flash the LED and sound the alarm:\n    Turn flashPin on (HIGH).\n    Play a 725 Hz tone on buzzerPin for 1000 milliseconds.\n    Wait 1000 milliseconds.\n    Play a 330 Hz tone on buzzerPin for 1000 milliseconds.\n    Wait 1000 milliseconds.\n","app_html":"","settings":{},"by_lang":{"python":{"code":"from time import sleep\nfrom gpiozero import DigitalInputDevice, LED, TonalBuzzer, Tone\n\nsensorPin = DigitalInputDevice(7, pull_up=True)\nflashPin = LED(13)\nbuzzerPin = TonalBuzzer(3)\nStatus = 0\nsensor = 0\nsensorPin.close()\nflashPin.close()\nbuzzerPin.close()\nsensorPin = DigitalInputDevice(7, pull_up=True)\nflashPin = LED(13)\nbuzzerPin = TonalBuzzer(3)\nif __name__ == \"__main__\":\n    while True:\n        if Status == 0:\n            sleep(3)\n            buzzerPin.play(Tone(725))\n            sleep(0.04)\n            buzzerPin.stop()\n            sleep(0.2)\n            buzzerPin.play(Tone(725))\n            sleep(0.04)\n            buzzerPin.stop()\n            Status = 1\n        if Status == 1:\n            sensor = 0 if sensorPin.value else 1\n            if sensor == 0:\n                Status = 2\n        if Status == 2:\n            flashPin.on()\n            buzzerPin.play(Tone(725))\n            sleep(1)\n            buzzerPin.stop()\n            sleep(1)\n            buzzerPin.play(Tone(330))\n            sleep(1)\n            buzzerPin.stop()\n            sleep(1)","links":[{"label":"import","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"import","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"setup","code_end":4,"code_start":4,"english_end":3,"english_start":3},{"label":"setup","code_end":5,"code_start":5,"english_end":3,"english_start":3},{"label":"setup","code_end":6,"code_start":6,"english_end":3,"english_start":3},{"label":"state","code_end":7,"code_start":7,"english_end":3,"english_start":3},{"label":"state","code_end":8,"code_start":8,"english_end":3,"english_start":3},{"label":"setup","code_end":9,"code_start":9,"english_end":5,"english_start":5},{"label":"setup","code_end":10,"code_start":10,"english_end":5,"english_start":5},{"label":"setup","code_end":11,"code_start":11,"english_end":5,"english_start":5},{"label":"setup","code_end":12,"code_start":12,"english_end":5,"english_start":5},{"label":"setup","code_end":13,"code_start":13,"english_end":5,"english_start":5},{"label":"setup","code_end":14,"code_start":14,"english_end":5,"english_start":5},{"label":"entry","code_end":15,"code_start":15,"english_end":24,"english_start":7},{"label":"loop","code_end":16,"code_start":16,"english_end":24,"english_start":7},{"label":"branch","code_end":17,"code_start":17,"english_end":13,"english_start":8},{"label":"delay","code_end":18,"code_start":18,"english_end":9,"english_start":9},{"label":"tone","code_end":19,"code_start":19,"english_end":10,"english_start":10},{"label":"delay","code_end":20,"code_start":20,"english_end":11,"english_start":10},{"label":"tone","code_end":21,"code_start":21,"english_end":12,"english_start":10},{"label":"delay","code_end":22,"code_start":22,"english_end":11,"english_start":11},{"label":"tone","code_end":23,"code_start":23,"english_end":12,"english_start":12},{"label":"delay","code_end":24,"code_start":24,"english_end":12,"english_start":12},{"label":"tone","code_end":25,"code_start":25,"english_end":12,"english_start":12},{"label":"state","code_end":26,"code_start":26,"english_end":13,"english_start":13},{"label":"branch","code_end":27,"code_start":27,"english_end":17,"english_start":15},{"label":"read","code_end":28,"code_start":28,"english_end":15,"english_start":15},{"label":"branch","code_end":29,"code_start":29,"english_end":17,"english_start":17},{"label":"state","code_end":30,"code_start":30,"english_end":17,"english_start":17},{"label":"branch","code_end":31,"code_start":31,"english_end":24,"english_start":19},{"label":"output","code_end":32,"code_start":32,"english_end":20,"english_start":20},{"label":"tone","code_end":33,"code_start":33,"english_end":21,"english_start":21},{"label":"delay","code_end":34,"code_start":34,"english_end":22,"english_start":21},{"label":"tone","code_end":35,"code_start":35,"english_end":22,"english_start":21},{"label":"delay","code_end":36,"code_start":36,"english_end":22,"english_start":22},{"label":"tone","code_end":37,"code_start":37,"english_end":23,"english_start":23},{"label":"delay","code_end":38,"code_start":38,"english_end":24,"english_start":23},{"label":"tone","code_end":39,"code_start":39,"english_end":24,"english_start":23},{"label":"delay","code_end":40,"code_start":40,"english_end":24,"english_start":24}],"structure":"{\"functions\":[]}"},"cpp":{"code":"int sensorPin = 7;    // the sensor (a switch on the box) connects to pin 7\nint flashPin = 13;    // an LED that lights up when the alarm sounds\nint buzzerPin = 3;    // the buzzer connects to pin 3\nint Status = 0;       // 0 = exit delay, 1 = armed, 2 = triggered\nint sensor = 0;       // the current sensor reading\n\nvoid setup() {\n  pinMode(sensorPin, INPUT);\n  pinMode(flashPin, OUTPUT);\n  pinMode(buzzerPin, OUTPUT);\n}\n\nvoid loop() {\n  if (Status == 0) {            // first time through the loop — arm the alarm\n    delay(3000);                // gives you 3 seconds to close the box\n    tone(buzzerPin, 725, 40);   // a short beep...\n    delay(200);\n    tone(buzzerPin, 725, 40);   // ...and another, so it double-beeps when armed\n    Status = 1;                 // armed — don't run this block again\n  }\n  if (Status == 1) {\n    sensor = digitalRead(sensorPin);   // read the switch\n  }\n  if (sensor == 0) {            // the box has been opened\n    Status = 2;\n  }\n  if (Status == 2) {            // triggered — flash the LED and sound the alarm\n    digitalWrite(flashPin, HIGH);\n    tone(buzzerPin, 725, 1000);\n    delay(1000);\n    tone(buzzerPin, 330, 1000);\n    delay(1000);\n  }\n}\n","links":[],"structure":null},"ruby":{"code":"def pinMode(pin, mode)\nend\ndef digitalRead(pin)\n  1\nend\ndef digitalWrite(pin, value)\nend\ndef tone(pin, frequency, duration_ms)\nend\nsensorPin = 7\nflashPin = 13\nbuzzerPin = 3\nstatus = 0\nsensor = 0\npinMode(sensorPin, :input)\npinMode(flashPin, :output)\npinMode(buzzerPin, :output)\nloop do\n  if status == 0\n    sleep 3\n    tone(buzzerPin, 725, 40)\n    sleep 0.2\n    tone(buzzerPin, 725, 40)\n    status = 1\n  end\n  if status == 1\n    sensor = digitalRead(sensorPin)\n  end\n  if sensor == 0\n    status = 2\n  end\n  if status == 2\n    digitalWrite(flashPin, :high)\n    tone(buzzerPin, 725, 1000)\n    sleep 1\n    tone(buzzerPin, 330, 1000)\n    sleep 1\n  end\nend","links":[{"label":"hardware stub","code_end":2,"code_start":1,"english_end":1,"english_start":1},{"label":"hardware stub","code_end":5,"code_start":3,"english_end":1,"english_start":1},{"label":"hardware stub","code_end":7,"code_start":6,"english_end":1,"english_start":1},{"label":"hardware stub","code_end":9,"code_start":8,"english_end":1,"english_start":1},{"label":"pin name","code_end":10,"code_start":10,"english_end":3,"english_start":3},{"label":"pin name","code_end":11,"code_start":11,"english_end":3,"english_start":3},{"label":"pin name","code_end":12,"code_start":12,"english_end":3,"english_start":3},{"label":"state","code_end":13,"code_start":13,"english_end":3,"english_start":3},{"label":"state","code_end":14,"code_start":14,"english_end":3,"english_start":3},{"label":"setup input","code_end":15,"code_start":15,"english_end":5,"english_start":5},{"label":"setup output","code_end":16,"code_start":16,"english_end":5,"english_start":5},{"label":"setup output","code_end":17,"code_start":17,"english_end":5,"english_start":5},{"label":"main loop","code_end":18,"code_start":18,"english_end":7,"english_start":7},{"label":"arm on first pass","code_end":19,"code_start":19,"english_end":8,"english_start":8},{"label":"exit delay","code_end":20,"code_start":20,"english_end":9,"english_start":9},{"label":"first beep","code_end":21,"code_start":21,"english_end":10,"english_start":10},{"label":"beep gap","code_end":22,"code_start":22,"english_end":11,"english_start":11},{"label":"second beep","code_end":23,"code_start":23,"english_end":12,"english_start":12},{"label":"armed","code_end":24,"code_start":24,"english_end":13,"english_start":13},{"label":"end arm check","code_end":25,"code_start":25,"english_end":13,"english_start":13},{"label":"read sensor while armed","code_end":26,"code_start":26,"english_end":15,"english_start":15},{"label":"read sensor","code_end":27,"code_start":27,"english_end":15,"english_start":15},{"label":"end sensor read","code_end":28,"code_start":28,"english_end":15,"english_start":15},{"label":"opened box check","code_end":29,"code_start":29,"english_end":17,"english_start":17},{"label":"triggered","code_end":30,"code_start":30,"english_end":17,"english_start":17},{"label":"end opened check","code_end":31,"code_start":31,"english_end":17,"english_start":17},{"label":"triggered alarm","code_end":32,"code_start":32,"english_end":19,"english_start":19},{"label":"LED on","code_end":33,"code_start":33,"english_end":20,"english_start":20},{"label":"alarm tone one","code_end":34,"code_start":34,"english_end":21,"english_start":21},{"label":"alarm wait one","code_end":35,"code_start":35,"english_end":22,"english_start":22},{"label":"alarm tone two","code_end":36,"code_start":36,"english_end":23,"english_start":23},{"label":"alarm wait two","code_end":37,"code_start":37,"english_end":24,"english_start":24},{"label":"end triggered alarm","code_end":38,"code_start":38,"english_end":24,"english_start":24},{"label":"end loop","code_end":39,"code_start":39,"english_end":24,"english_start":24}],"structure":"{\"functions\":[{\"name\":\"pinMode\",\"params\":[\"pin\",\"mode\"],\"english_start\":1,\"english_end\":1,\"summary\":\"No-op hardware stub for setting a pin mode.\",\"calls\":[]},{\"name\":\"digitalRead\",\"params\":[\"pin\"],\"english_start\":1,\"english_end\":1,\"summary\":\"No-op hardware stub that returns a non-triggered reading.\",\"calls\":[]},{\"name\":\"digitalWrite\",\"params\":[\"pin\",\"value\"],\"english_start\":1,\"english_end\":1,\"summary\":\"No-op hardware stub for writing a pin state.\",\"calls\":[]},{\"name\":\"tone\",\"params\":[\"pin\",\"frequency\",\"duration_ms\"],\"english_start\":1,\"english_end\":1,\"summary\":\"No-op hardware stub for playing a tone.\",\"calls\":[]}]}"},"javascript":{"code":"const sensorPin = 7;\nconst flashPin = 13;\nconst buzzerPin = 3;\nlet Status = 0;\nlet sensor = 0;\nfunction setup() {\n  pinMode(sensorPin, INPUT);\n  pinMode(flashPin, OUTPUT);\n  pinMode(buzzerPin, OUTPUT);\n}\nfunction loop() {\n  if (Status === 0) {\n    delay(3000);\n    tone(buzzerPin, 725, 40);\n    delay(200);\n    tone(buzzerPin, 725, 40);\n    Status = 1;\n  }\n  if (Status === 1) {\n    sensor = digitalRead(sensorPin);\n    if (sensor === LOW) {\n      Status = 2;\n    }\n  }\n  if (Status === 2) {\n    digitalWrite(flashPin, HIGH);\n    tone(buzzerPin, 725, 1000);\n    delay(1000);\n    tone(buzzerPin, 330, 1000);\n    delay(1000);\n  }\n}","links":[{"label":"declaration","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"declaration","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"declaration","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"declaration","code_end":4,"code_start":4,"english_end":3,"english_start":3},{"label":"declaration","code_end":5,"code_start":5,"english_end":3,"english_start":3},{"label":"function","code_end":6,"code_start":6,"english_end":5,"english_start":5},{"label":"statement","code_end":7,"code_start":7,"english_end":5,"english_start":5},{"label":"statement","code_end":8,"code_start":8,"english_end":5,"english_start":5},{"label":"statement","code_end":9,"code_start":9,"english_end":5,"english_start":5},{"label":"end","code_end":10,"code_start":10,"english_end":5,"english_start":5},{"label":"function","code_end":11,"code_start":11,"english_end":7,"english_start":7},{"label":"if","code_end":12,"code_start":12,"english_end":13,"english_start":8},{"label":"statement","code_end":13,"code_start":13,"english_end":9,"english_start":9},{"label":"statement","code_end":14,"code_start":14,"english_end":12,"english_start":10},{"label":"statement","code_end":15,"code_start":15,"english_end":12,"english_start":11},{"label":"statement","code_end":16,"code_start":16,"english_end":12,"english_start":12},{"label":"statement","code_end":17,"code_start":17,"english_end":13,"english_start":13},{"label":"end","code_end":18,"code_start":18,"english_end":13,"english_start":13},{"label":"if","code_end":19,"code_start":19,"english_end":17,"english_start":15},{"label":"statement","code_end":20,"code_start":20,"english_end":15,"english_start":15},{"label":"if","code_end":21,"code_start":21,"english_end":17,"english_start":17},{"label":"statement","code_end":22,"code_start":22,"english_end":17,"english_start":17},{"label":"end","code_end":23,"code_start":23,"english_end":17,"english_start":17},{"label":"end","code_end":24,"code_start":24,"english_end":17,"english_start":15},{"label":"if","code_end":25,"code_start":25,"english_end":24,"english_start":19},{"label":"statement","code_end":26,"code_start":26,"english_end":20,"english_start":20},{"label":"statement","code_end":27,"code_start":27,"english_end":21,"english_start":21},{"label":"statement","code_end":28,"code_start":28,"english_end":22,"english_start":22},{"label":"statement","code_end":29,"code_start":29,"english_end":23,"english_start":23},{"label":"statement","code_end":30,"code_start":30,"english_end":24,"english_start":24},{"label":"end","code_end":31,"code_start":31,"english_end":24,"english_start":19},{"label":"end","code_end":32,"code_start":32,"english_end":24,"english_start":7}],"structure":"{\"functions\":[]}"}}},{"slug":"vce-u1-03-read-ldr","title":"VCE Systems Engineering · PRP #03 — Read an LDR (A0)","description":"Read an LDR voltage divider on A0 once a second and print the raw 0-1023 value to the Serial Monitor at 9600 baud.","english":"Read a light-dependent resistor on pin A0 once a second and print the raw number to the Serial Monitor — wire the LDR and a fixed resistor as a voltage divider, with the junction going to A0.\n\nCall pin A0 \"LDR_PIN\".\n\nStart the serial connection at 9600 baud.\n\nForever:\n  Read the analogue value on LDR_PIN into an integer called \"reading\" (it comes back from 0 to 1023, and that is only a raw voltage reading, not a light level in any real unit yet).\n  Print reading to the serial port, followed by a new line.\n  Wait one second before taking the next sample.\n","app_html":"","settings":{},"by_lang":{"ruby":{"code":"# Wire the LDR and fixed resistor as a voltage divider, with the junction connected to A0.\nLDR_PIN = \"A0\"\nSTDOUT.sync = true # Serial connection at 9600 baud\nloop do\n  reading = rand(0..1023)\n  puts reading\n  sleep 1\nend","links":[{"label":"voltage divider wiring","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"name the sensor pin","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"start serial output","code_end":3,"code_start":3,"english_end":5,"english_start":5},{"label":"repeat forever","code_end":4,"code_start":4,"english_end":7,"english_start":7},{"label":"read the analogue value","code_end":5,"code_start":5,"english_end":8,"english_start":8},{"label":"print the reading","code_end":6,"code_start":6,"english_end":9,"english_start":9},{"label":"wait one second","code_end":7,"code_start":7,"english_end":10,"english_start":10},{"label":"end repeating loop","code_end":8,"code_start":8,"english_end":7,"english_start":7}],"structure":"{\"functions\":[]}"},"cpp":{"code":"// PRP 3 — light sensing with an LDR.\n// Wire the LDR and a fixed resistor as a divider, junction to A0.\n\nconst int LDR_PIN = A0;\n\nvoid setup() {\n  Serial.begin(9600);\n}\n\nvoid loop() {\n  int reading = analogRead(LDR_PIN);   // 0-1023, NOT a light level yet\n  Serial.println(reading);\n  delay(1000);\n}\n","links":[],"structure":null},"python":{"code":"SERIAL_BAUD = 9600\nLDR_PIN = \"A0\"\nprint(f\"Serial connection started at {SERIAL_BAUD} baud\")\nwhile True:\n    reading = int(input())\n    print(reading)\n    __import__(\"time\").sleep(1)","links":[{"label":"serial baud rate","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"LDR pin name","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"start serial connection","code_end":3,"code_start":3,"english_end":5,"english_start":5},{"label":"forever loop","code_end":4,"code_start":4,"english_end":7,"english_start":7},{"label":"read analogue value","code_end":5,"code_start":5,"english_end":8,"english_start":8},{"label":"print reading","code_end":6,"code_start":6,"english_end":9,"english_start":9},{"label":"wait one second","code_end":7,"code_start":7,"english_end":10,"english_start":10}],"structure":"{\"functions\":[]}"},"javascript":{"code":"// LDR voltage divider junction connected to A0; raw readings are printed once per second.\n\nconst LDR_PIN = \"A0\";\nconst serial = { begin: () => {}, println: value => console.log(value) };\nserial.begin(9600);\nsetInterval(() => {\n  const reading = Math.floor(Math.random() * 1024);\n  serial.println(reading);\n}, 1000);","links":[{"label":"LDR wiring and sampling","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"name the LDR pin","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"start serial interface","code_end":4,"code_start":4,"english_end":5,"english_start":5},{"label":"set baud rate","code_end":5,"code_start":5,"english_end":5,"english_start":5},{"label":"start forever loop","code_end":6,"code_start":6,"english_end":7,"english_start":7},{"label":"read analogue value","code_end":7,"code_start":7,"english_end":8,"english_start":8},{"label":"print reading","code_end":8,"code_start":8,"english_end":9,"english_start":9},{"label":"wait one second","code_end":9,"code_start":9,"english_end":10,"english_start":10}],"structure":"{\"functions\":[]}"}}},{"slug":"vce-u1-04-read-dht22","title":"VCE Systems Engineering · PRP #04 — Temperature and humidity (DHT22)","description":"Read a DHT22 on pin 2, print both values over Serial every two seconds, and report a failed reading instead of a stale one.","english":"Read the temperature and humidity from a DHT22 sensor on pin 2 and print both to the Serial Monitor every two seconds — two seconds is the fastest a DHT22 can be sampled, so that wait is a limit of the sensor, not a choice.\n\nCall pin 2 \"DHT_PIN\". Set up a DHT22 sensor called \"dht\" connected to DHT_PIN.\n\nStart the serial connection at 9600 baud. Start the sensor.\n\nForever:\n  Read the humidity from the sensor into a decimal number \"humidity\".\n  Read the temperature in degrees Celsius from the sensor into a decimal number \"tempC\".\n  If either humidity or tempC is not a number (the sensor did not answer): print the line \"read failed\".\n  Otherwise: print tempC, then print a single space, then print humidity and end the line.\n  Wait two seconds.\n","app_html":"","settings":{},"by_lang":{"ruby":{"code":"DHT_PIN = 2\ndht = DHT22.new(DHT_PIN)\n$stdout.sync = true\ndht.start\nloop do\n  humidity = dht.read_humidity\n  temp_c = dht.read_temperature_celsius\n  if humidity.nil? || temp_c.nil?\n    puts \"read failed\"\n  else\n    print temp_c, \" \", humidity, \"\\n\"\n  end\n  sleep 2\nend","links":[{"label":"Define the sensor pin","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"Create the DHT22 sensor","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"Prepare serial-style output","code_end":3,"code_start":3,"english_end":4,"english_start":4},{"label":"Start the sensor","code_end":4,"code_start":4,"english_end":5,"english_start":5},{"label":"Repeat forever","code_end":5,"code_start":5,"english_end":7,"english_start":7},{"label":"Read humidity","code_end":6,"code_start":6,"english_end":8,"english_start":8},{"label":"Read Celsius temperature","code_end":7,"code_start":7,"english_end":9,"english_start":9},{"label":"Check whether the reading failed","code_end":8,"code_start":8,"english_end":10,"english_start":10},{"label":"Print the failure message","code_end":9,"code_start":9,"english_end":10,"english_start":10},{"label":"Handle a successful reading","code_end":10,"code_start":10,"english_end":11,"english_start":11},{"label":"Print temperature and humidity","code_end":11,"code_start":11,"english_end":11,"english_start":11},{"label":"Finish the reading check","code_end":12,"code_start":12,"english_end":11,"english_start":10},{"label":"Wait two seconds","code_end":13,"code_start":13,"english_end":12,"english_start":12},{"label":"Finish the forever loop","code_end":14,"code_start":14,"english_end":7,"english_start":7}],"structure":"{\"functions\":[]}"},"cpp":{"code":"// PRP 4 — temperature and humidity, plotted over time.\n// Requires the DHT sensor library.\n//\n// The DHT22 needs at least 2 seconds between reads. Sampling faster\n// returns stale values or nan — it is the most common cause of both.\n\n#include <DHT.h>\n\nconst int DHT_PIN = 2;\nDHT dht(DHT_PIN, DHT22);\n\nvoid setup() {\n  Serial.begin(9600);\n  dht.begin();\n}\n\nvoid loop() {\n  float humidity = dht.readHumidity();\n  float tempC = dht.readTemperature();\n\n  if (isnan(humidity) || isnan(tempC)) {\n    Serial.println(\"read failed\");   // check wiring, and check you waited 2s\n  } else {\n    Serial.print(tempC);\n    Serial.print(\" \");\n    Serial.println(humidity);       // two values, space separated, for the plotter\n  }\n\n  delay(2000);                       // minimum sampling interval for this sensor\n}\n","links":[],"structure":null},"python":{"code":"import adafruit_dht\nimport board\nimport time\nDHT_PIN = board.D2\ndht = adafruit_dht.DHT22(DHT_PIN)\ndef main():\n    print(\"Serial connection started at 9600 baud\")\n    dht.measure()\n    while True:\n        try:\n            humidity = dht.humidity\n            tempC = dht.temperature\n        except (RuntimeError, TypeError):\n            humidity = None\n            tempC = None\n        if humidity is None or tempC is None:\n            print(\"read failed\")\n        else:\n            print(tempC, humidity)\n        time.sleep(2)\n\nif __name__ == \"__main__\":\n    main()","links":[{"label":"Import the DHT sensor library","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"Import board pin definitions","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"Import timing support","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"Assign pin 2 to DHT_PIN","code_end":4,"code_start":4,"english_end":3,"english_start":3},{"label":"Create the DHT22 sensor","code_end":5,"code_start":5,"english_end":3,"english_start":3},{"label":"Define the program entry point","code_end":6,"code_start":6,"english_end":5,"english_start":5},{"label":"Start the serial connection at 9600 baud","code_end":7,"code_start":7,"english_end":5,"english_start":5},{"label":"Start the sensor","code_end":8,"code_start":8,"english_end":5,"english_start":5},{"label":"Repeat forever","code_end":9,"code_start":9,"english_end":7,"english_start":7},{"label":"Attempt to read the sensor","code_end":10,"code_start":10,"english_end":8,"english_start":8},{"label":"Read the humidity","code_end":11,"code_start":11,"english_end":8,"english_start":8},{"label":"Read the temperature in Celsius","code_end":12,"code_start":12,"english_end":9,"english_start":9},{"label":"Handle a failed sensor response","code_end":13,"code_start":13,"english_end":10,"english_start":10},{"label":"Mark humidity as unavailable","code_end":14,"code_start":14,"english_end":10,"english_start":10},{"label":"Mark temperature as unavailable","code_end":15,"code_start":15,"english_end":10,"english_start":10},{"label":"Check whether either reading failed","code_end":16,"code_start":16,"english_end":10,"english_start":10},{"label":"Print the failure message","code_end":17,"code_start":17,"english_end":10,"english_start":10},{"label":"Handle valid readings","code_end":18,"code_start":18,"english_end":11,"english_start":11},{"label":"Print temperature and humidity separated by a space","code_end":19,"code_start":19,"english_end":11,"english_start":11},{"label":"Wait two seconds before the next reading","code_end":20,"code_start":20,"english_end":12,"english_start":12},{"label":"Run the program when executed directly","code_end":22,"code_start":22,"english_end":12,"english_start":7},{"label":"Start the main program","code_end":23,"code_start":23,"english_end":12,"english_start":7}],"structure":"{\"functions\":[{\"name\":\"main\",\"params\":[],\"english_start\":5,\"english_end\":12,\"summary\":\"Initializes the DHT22 sensor, repeatedly reads its values, reports failures or readings, and waits two seconds between samples.\",\"calls\":[]}]}"},"javascript":{"code":"const DHT_PIN = 2;\nconst dht = {\n  begin() {},\n  readHumidity() { return Number.parseFloat(process.env.DHT_HUMIDITY); },\n  readTemperatureC() { return Number.parseFloat(process.env.DHT_TEMPERATURE_C); }\n};\nconst BAUD_RATE = 9600;\nconsole.log(`Serial connection started at ${BAUD_RATE} baud`);\ndht.begin();\n\nfunction readAndPrint() {\n  const humidity = dht.readHumidity();\n  const tempC = dht.readTemperatureC();\n  if (Number.isNaN(humidity) || Number.isNaN(tempC)) {\n    console.log(\"read failed\");\n    return;\n  }\n  console.log(`${tempC} ${humidity}`);\n}\nsetInterval(readAndPrint, 2000);","links":[{"label":"Define the sensor pin","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"Create the DHT22 sensor","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"Initialize the sensor","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"Read humidity","code_end":4,"code_start":4,"english_end":3,"english_start":3},{"label":"Read Celsius temperature","code_end":5,"code_start":5,"english_end":3,"english_start":3},{"label":"Finish sensor setup","code_end":6,"code_start":6,"english_end":3,"english_start":3},{"label":"Set the serial baud rate","code_end":7,"code_start":7,"english_end":4,"english_start":4},{"label":"Start the serial connection","code_end":8,"code_start":8,"english_end":4,"english_start":4},{"label":"Start the sensor","code_end":9,"code_start":9,"english_end":4,"english_start":4},{"label":"Repeat the sensor-reading work","code_end":11,"code_start":11,"english_end":7,"english_start":7},{"label":"Read humidity","code_end":12,"code_start":12,"english_end":8,"english_start":8},{"label":"Read Celsius temperature","code_end":13,"code_start":13,"english_end":9,"english_start":9},{"label":"Check whether either reading failed","code_end":14,"code_start":14,"english_end":10,"english_start":10},{"label":"Report a failed reading","code_end":15,"code_start":15,"english_end":10,"english_start":10},{"label":"Stop processing the failed reading","code_end":16,"code_start":16,"english_end":10,"english_start":10},{"label":"Finish the failure check","code_end":17,"code_start":17,"english_end":11,"english_start":11},{"label":"Print temperature and humidity","code_end":18,"code_start":18,"english_end":11,"english_start":11},{"label":"Finish one sensor-reading cycle","code_end":19,"code_start":19,"english_end":12,"english_start":12},{"label":"Run the cycle every two seconds","code_end":20,"code_start":20,"english_end":12,"english_start":12}],"structure":"{\"functions\":[{\"name\":\"readAndPrint\",\"params\":[],\"english_start\":7,\"english_end\":12,\"summary\":\"Reads both DHT22 values, reports failures, and prints valid readings.\",\"calls\":[{\"english_start\":8,\"english_end\":8},{\"english_start\":9,\"english_end\":9}]}]}"}}},{"slug":"vce-u1-05-threshold","title":"VCE Systems Engineering · PRP #05 — Threshold control","description":"Read a sensor on A0, print it to the serial monitor, and switch pin 13 on whenever the reading falls below a threshold of 500.","english":"Watch a sensor on A0 and switch an output on pin 13 whenever the reading drops below a threshold — the threshold is a design decision you make from your own recorded data.\n\nCall pin A0 \"SENSOR_PIN\" and pin 13 \"OUTPUT_PIN\". Call the whole number 500 \"THRESHOLD\" — a starting value, to be replaced with your own.\n\nSet OUTPUT_PIN as an output. Start serial communication at 9600 baud.\n\nForever:\n  Read the analogue value on SENSOR_PIN into a whole number called \"reading\" (somewhere from 0 to 1023).\n  Print reading to the serial monitor on its own line, so you can watch the values and choose your threshold.\n  If reading is less than THRESHOLD: turn OUTPUT_PIN on (HIGH).\n  Otherwise: turn OUTPUT_PIN off (LOW).\n  Wait one hundred milliseconds (a tenth of a second) before the next reading.\n","app_html":"","settings":{},"by_lang":{"ruby":{"code":"SENSOR_PIN = :A0\nOUTPUT_PIN = 13\nTHRESHOLD = 500\ndef pin_mode(pin, mode)\n  puts \"Pin #{pin} set to #{mode}\"\nend\ndef serial_begin(baud_rate)\n  puts \"Serial started at #{baud_rate} baud\"\nend\ndef analog_read(_pin)\n  rand(1024)\nend\npin_mode(OUTPUT_PIN, :output)\nserial_begin(9600)\n\nloop do\n  reading = analog_read(SENSOR_PIN)\n  puts reading\n  output_state = reading < THRESHOLD ? :high : :low\n  puts \"Pin #{OUTPUT_PIN}: #{output_state}\"\n  sleep 0.1\nend","links":[{"label":"Define sensor pin","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"Define output pin","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"Define threshold","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"Define pin mode operation","code_end":4,"code_start":4,"english_end":4,"english_start":4},{"label":"Simulate pin setup","code_end":5,"code_start":5,"english_end":4,"english_start":4},{"label":"Finish pin mode operation","code_end":6,"code_start":6,"english_end":4,"english_start":4},{"label":"Define serial startup","code_end":7,"code_start":7,"english_end":4,"english_start":4},{"label":"Start simulated serial communication","code_end":8,"code_start":8,"english_end":4,"english_start":4},{"label":"Finish serial startup","code_end":9,"code_start":9,"english_end":4,"english_start":4},{"label":"Define analogue reading","code_end":10,"code_start":10,"english_end":8,"english_start":8},{"label":"Generate a simulated sensor reading","code_end":11,"code_start":11,"english_end":8,"english_start":8},{"label":"Finish analogue reading","code_end":12,"code_start":12,"english_end":8,"english_start":8},{"label":"Set output pin as output","code_end":13,"code_start":13,"english_end":4,"english_start":4},{"label":"Start serial communication","code_end":14,"code_start":14,"english_end":4,"english_start":4},{"label":"Repeat forever","code_end":16,"code_start":16,"english_end":7,"english_start":7},{"label":"Read sensor value","code_end":17,"code_start":17,"english_end":8,"english_start":8},{"label":"Print sensor value","code_end":18,"code_start":18,"english_end":9,"english_start":9},{"label":"Switch output based on threshold","code_end":19,"code_start":19,"english_end":11,"english_start":10},{"label":"Apply output state","code_end":20,"code_start":20,"english_end":11,"english_start":10},{"label":"Wait one hundred milliseconds","code_end":21,"code_start":21,"english_end":12,"english_start":12},{"label":"Finish forever loop","code_end":22,"code_start":22,"english_end":7,"english_start":7}],"structure":"{\"functions\":[{\"name\":\"pin_mode\",\"params\":[\"pin\",\"mode\"],\"english_start\":4,\"english_end\":4,\"summary\":\"Simulates configuring a pin mode.\",\"calls\":[]},{\"name\":\"serial_begin\",\"params\":[\"baud_rate\"],\"english_start\":4,\"english_end\":4,\"summary\":\"Simulates starting serial communication.\",\"calls\":[]},{\"name\":\"analog_read\",\"params\":[\"_pin\"],\"english_start\":8,\"english_end\":8,\"summary\":\"Returns a simulated analogue sensor value from 0 through 1023.\",\"calls\":[]}]}"},"python":{"code":"const int SENSOR_PIN = A0;\nconst int OUTPUT_PIN = 13;\nconst int THRESHOLD = 500;\n\nvoid setup() {\n  pinMode(OUTPUT_PIN, OUTPUT);\n  Serial.begin(9600);\n}\n\nvoid loop() {\n  int reading = analogRead(SENSOR_PIN);\n  Serial.println(reading);\n  if (reading < THRESHOLD) {\n    digitalWrite(OUTPUT_PIN, HIGH);\n  }\n  else {\n    digitalWrite(OUTPUT_PIN, LOW);\n  }\n  delay(100);\n}","links":[{"label":"sensor pin","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"output pin","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"threshold","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"setup","code_end":5,"code_start":5,"english_end":5,"english_start":5},{"label":"configure output","code_end":6,"code_start":6,"english_end":5,"english_start":5},{"label":"start serial communication","code_end":7,"code_start":7,"english_end":5,"english_start":5},{"label":"end setup","code_end":8,"code_start":8,"english_end":5,"english_start":5},{"label":"forever loop","code_end":10,"code_start":10,"english_end":7,"english_start":7},{"label":"read sensor","code_end":11,"code_start":11,"english_end":8,"english_start":8},{"label":"print reading","code_end":12,"code_start":12,"english_end":9,"english_start":9},{"label":"check threshold","code_end":13,"code_start":13,"english_end":10,"english_start":10},{"label":"turn output on","code_end":14,"code_start":14,"english_end":10,"english_start":10},{"label":"end threshold check","code_end":15,"code_start":15,"english_end":10,"english_start":10},{"label":"otherwise","code_end":16,"code_start":16,"english_end":11,"english_start":11},{"label":"turn output off","code_end":17,"code_start":17,"english_end":11,"english_start":11},{"label":"end otherwise","code_end":18,"code_start":18,"english_end":11,"english_start":11},{"label":"wait before next reading","code_end":19,"code_start":19,"english_end":12,"english_start":12},{"label":"end forever loop","code_end":20,"code_start":20,"english_end":7,"english_start":7}],"structure":"{\"functions\":[{\"name\":\"setup\",\"params\":[],\"english_start\":5,\"english_end\":5,\"summary\":\"Configures the output pin and starts serial communication.\",\"calls\":[]},{\"name\":\"loop\",\"params\":[],\"english_start\":7,\"english_end\":12,\"summary\":\"Repeatedly reads the sensor, reports the value, switches the output based on the threshold, and waits.\",\"calls\":[]}]}"},"cpp":{"code":"// PRP 5 — a single threshold decision.\n//\n// THRESHOLD is a design decision. Replace this value with one you\n// chose from your own recorded readings, and be able to defend it.\n//\n// Expect this sketch to chatter when the reading sits near the\n// threshold. That fault is the point of the activity — PRP 6 fixes it.\n\nconst int SENSOR_PIN = A0;\nconst int OUTPUT_PIN = 13;\nconst int THRESHOLD  = 500;   // <-- your number, from your data\n\nvoid setup() {\n  pinMode(OUTPUT_PIN, OUTPUT);\n  Serial.begin(9600);\n}\n\nvoid loop() {\n  int reading = analogRead(SENSOR_PIN);\n  Serial.println(reading);\n\n  if (reading < THRESHOLD) {\n    digitalWrite(OUTPUT_PIN, HIGH);\n  } else {\n    digitalWrite(OUTPUT_PIN, LOW);\n  }\n\n  delay(100);\n}\n","links":[],"structure":null},"javascript":{"code":"const SENSOR_PIN = \"A0\";\nconst OUTPUT_PIN = 13;\nconst THRESHOLD = 500;\nlet outputState = false;\nconst analogRead = () => Math.floor(Math.random() * 1024);\nconst digitalWrite = (pin, state) => {\n  outputState = state;\n};\nconst setup = () => {\n  console.log(`Pin ${OUTPUT_PIN} configured as OUTPUT`);\n  console.log(\"Serial communication started at 9600 baud\");\n};\nconst loop = () => {\n  const reading = analogRead(SENSOR_PIN);\n  console.log(reading);\n  if (reading < THRESHOLD) {\n    digitalWrite(OUTPUT_PIN, true);\n  } else {\n    digitalWrite(OUTPUT_PIN, false);\n  }\n};\n\nsetup();\nsetInterval(loop, 100);","links":[{"label":"Define the sensor pin","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"Define the output pin","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"Define the starting threshold","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"Track the simulated output state","code_end":4,"code_start":4,"english_end":5,"english_start":5},{"label":"Simulate an analogue sensor reading","code_end":5,"code_start":5,"english_end":8,"english_start":8},{"label":"Define output switching","code_end":6,"code_start":6,"english_end":11,"english_start":10},{"label":"Set the simulated output state","code_end":7,"code_start":7,"english_end":10,"english_start":10},{"label":"Finish output switching","code_end":8,"code_start":8,"english_end":11,"english_start":10},{"label":"Initialize the program","code_end":9,"code_start":9,"english_end":5,"english_start":5},{"label":"Configure the output pin","code_end":10,"code_start":10,"english_end":5,"english_start":5},{"label":"Start serial communication","code_end":11,"code_start":11,"english_end":5,"english_start":5},{"label":"Finish initialization","code_end":12,"code_start":12,"english_end":5,"english_start":5},{"label":"Begin the repeating sensor loop","code_end":13,"code_start":13,"english_end":7,"english_start":7},{"label":"Read the analogue sensor value","code_end":14,"code_start":14,"english_end":8,"english_start":8},{"label":"Print the reading","code_end":15,"code_start":15,"english_end":9,"english_start":9},{"label":"Check whether the reading is below the threshold","code_end":16,"code_start":16,"english_end":10,"english_start":10},{"label":"Turn the output on","code_end":17,"code_start":17,"english_end":10,"english_start":10},{"label":"Handle readings at or above the threshold","code_end":18,"code_start":18,"english_end":11,"english_start":10},{"label":"Turn the output off","code_end":19,"code_start":19,"english_end":11,"english_start":11},{"label":"Finish the threshold decision","code_end":20,"code_start":20,"english_end":11,"english_start":10},{"label":"Finish the repeating loop","code_end":21,"code_start":21,"english_end":12,"english_start":7},{"label":"Run initialization","code_end":23,"code_start":23,"english_end":5,"english_start":5},{"label":"Repeat the loop every one hundred milliseconds","code_end":24,"code_start":24,"english_end":12,"english_start":12}],"structure":"{\"functions\":[{\"name\":\"setup\",\"params\":[],\"english_start\":5,\"english_end\":5,\"summary\":\"Configures the simulated output and starts serial communication.\",\"calls\":[]},{\"name\":\"loop\",\"params\":[],\"english_start\":7,\"english_end\":12,\"summary\":\"Reads the simulated sensor, prints the reading, switches the output, and repeats every 100 milliseconds.\",\"calls\":[{\"english_start\":8,\"english_end\":8},{\"english_start\":10,\"english_end\":11}]}]}"}}},{"slug":"vce-u1-06-hysteresis","title":"VCE Systems Engineering · PRP #06 — Hysteresis","description":"Switch pin 13 from an A0 reading using two thresholds — on below 480, off above 520 — so sensor noise cannot make it chatter.","english":"Switch an output on and off from an analogue sensor using two thresholds instead of one, so the sensor's own noise cannot make the output chatter.\n\nCall analogue pin A0 \"SENSOR_PIN\" and pin 13 \"OUTPUT_PIN\". Keep two fixed whole numbers: \"TURN_ON_BELOW\" equal to 480, and \"TURN_OFF_ABOVE\" equal to 520 — the gap between them is wider than the sensor's noise, and between the two thresholds nothing changes at all.\n\nKeep a true/false value \"outputOn\" for whether the output is currently on, starting as false.\n\nSet OUTPUT_PIN as an output. Start the serial connection at 9600 baud so we can print the readings.\n\nForever:\n  Read the analogue value on SENSOR_PIN into a whole number \"reading\" (it will be 0 to 1023).\n  If outputOn is false and reading is less than TURN_ON_BELOW (480): set outputOn to true.\n  Otherwise, if outputOn is true and reading is greater than TURN_OFF_ABOVE (520): set outputOn to false.\n  Otherwise, leave outputOn exactly as it is.\n  Turn OUTPUT_PIN on (HIGH) if outputOn is true, otherwise turn it off (LOW).\n  Print reading to the serial port on its own line.\n  Wait 100 milliseconds before reading again.\n","app_html":"","settings":{},"by_lang":{"cpp":{"code":"// PRP 6 — hysteresis.\n//\n// One threshold chatters because the sensor's own noise crosses it\n// repeatedly. Two thresholds with a gap wider than that noise fixes it.\n//\n// Make the gap wider than the noise you measured in PRP 4, and no wider.\n\nconst int SENSOR_PIN = A0;\nconst int OUTPUT_PIN = 13;\nconst int TURN_ON_BELOW  = 480;   // <-- your numbers\nconst int TURN_OFF_ABOVE = 520;\n\nbool outputOn = false;\n\nvoid setup() {\n  pinMode(OUTPUT_PIN, OUTPUT);\n  Serial.begin(9600);\n}\n\nvoid loop() {\n  int reading = analogRead(SENSOR_PIN);\n\n  if (!outputOn && reading < TURN_ON_BELOW) {\n    outputOn = true;\n  } else if (outputOn && reading > TURN_OFF_ABOVE) {\n    outputOn = false;\n  }\n  // Between the two thresholds nothing changes. That is the whole trick.\n\n  digitalWrite(OUTPUT_PIN, outputOn ? HIGH : LOW);\n  Serial.println(reading);\n  delay(100);\n}\n","links":[],"structure":null},"python":{"code":"from machine import ADC, Pin\nSENSOR_PIN = ADC(0)\nOUTPUT_PIN = Pin(13, Pin.OUT)\nTURN_ON_BELOW = 480\nTURN_OFF_ABOVE = 520\noutputOn = False\nOUTPUT_PIN.value(0)\nprint(\"Serial connection started at 9600 baud\")\nwhile True:\n    reading = SENSOR_PIN.read_u16() * 1023 // 65535\n    if not outputOn and reading < TURN_ON_BELOW:\n        outputOn = True\n    elif outputOn and reading > TURN_OFF_ABOVE:\n        outputOn = False\n    OUTPUT_PIN.value(1 if outputOn else 0)\n    print(reading)\n    time.sleep_ms(100)","links":[{"label":"Import hardware interfaces","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"Configure analogue sensor pin","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"Configure output pin","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"Set turn-on threshold","code_end":4,"code_start":4,"english_end":3,"english_start":3},{"label":"Set turn-off threshold","code_end":5,"code_start":5,"english_end":3,"english_start":3},{"label":"Initialize output state","code_end":6,"code_start":6,"english_end":4,"english_start":4},{"label":"Start with output off","code_end":7,"code_start":7,"english_end":6,"english_start":6},{"label":"Start serial output","code_end":8,"code_start":8,"english_end":6,"english_start":6},{"label":"Repeat forever","code_end":9,"code_start":9,"english_end":16,"english_start":9},{"label":"Read analogue sensor value","code_end":10,"code_start":10,"english_end":10,"english_start":10},{"label":"Check turn-on condition","code_end":11,"code_start":11,"english_end":11,"english_start":11},{"label":"Turn output state on","code_end":12,"code_start":12,"english_end":11,"english_start":11},{"label":"Check turn-off condition","code_end":13,"code_start":13,"english_end":12,"english_start":12},{"label":"Turn output state off","code_end":14,"code_start":14,"english_end":12,"english_start":12},{"label":"Apply output state","code_end":15,"code_start":15,"english_end":14,"english_start":14},{"label":"Print sensor reading","code_end":16,"code_start":16,"english_end":15,"english_start":15},{"label":"Wait before next reading","code_end":17,"code_start":17,"english_end":16,"english_start":16}],"structure":"{\"functions\":[]}"},"ruby":{"code":"SENSOR_PIN = 0\nOUTPUT_PIN = 13\nTURN_ON_BELOW = 480\nTURN_OFF_ABOVE = 520\noutput_on = false\nHIGH = 1\nLOW = 0\nserial_baud = 9600\nwhile (line = STDIN.gets)\n  reading = line.to_i\n  if !output_on && reading < TURN_ON_BELOW\n    output_on = true\n  elsif output_on && reading > TURN_OFF_ABOVE\n    output_on = false\n  end\n  output_pin_state = output_on ? HIGH : LOW\n  puts reading\n  sleep 0.1\nend","links":[{"label":"Define the sensor pin","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"Define the output pin","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"Define the turn-on threshold","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"Define the turn-off threshold","code_end":4,"code_start":4,"english_end":3,"english_start":3},{"label":"Initialize the output state","code_end":5,"code_start":5,"english_end":5,"english_start":5},{"label":"Define the high output state","code_end":6,"code_start":6,"english_end":6,"english_start":6},{"label":"Define the low output state","code_end":7,"code_start":7,"english_end":6,"english_start":6},{"label":"Start the serial connection","code_end":8,"code_start":8,"english_end":6,"english_start":6},{"label":"Repeat while sensor readings are available","code_end":9,"code_start":9,"english_end":9,"english_start":9},{"label":"Read the analogue value","code_end":10,"code_start":10,"english_end":10,"english_start":10},{"label":"Check whether to turn the output on","code_end":11,"code_start":11,"english_end":11,"english_start":11},{"label":"Turn the output on","code_end":12,"code_start":12,"english_end":11,"english_start":11},{"label":"Check whether to turn the output off","code_end":13,"code_start":13,"english_end":12,"english_start":12},{"label":"Turn the output off","code_end":14,"code_start":14,"english_end":12,"english_start":12},{"label":"Leave the output unchanged otherwise","code_end":15,"code_start":15,"english_end":13,"english_start":13},{"label":"Set the output pin state","code_end":16,"code_start":16,"english_end":14,"english_start":14},{"label":"Print the reading","code_end":17,"code_start":17,"english_end":15,"english_start":15},{"label":"Wait before reading again","code_end":18,"code_start":18,"english_end":16,"english_start":16},{"label":"End the repeated reading loop","code_end":19,"code_start":19,"english_end":9,"english_start":9}],"structure":"{\"functions\":[]}"},"javascript":{"code":"const SENSOR_PIN = \"A0\";\nconst OUTPUT_PIN = 13;\nconst TURN_ON_BELOW = 480;\nconst TURN_OFF_ABOVE = 520;\nlet outputOn = false;\n\nfunction pinMode(pin, mode) {\n  console.log(`Pin ${pin} configured as ${mode}.`);\n}\n\nfunction beginSerial(baudRate) {\n  console.log(`Serial started at ${baudRate} baud.`);\n}\n\nfunction analogRead(pin) {\n  return Math.floor(Math.random() * 1024);\n}\n\nfunction digitalWrite(pin, value) {\n  console.log(`Pin ${pin}: ${value}`);\n}\n\npinMode(OUTPUT_PIN, \"OUTPUT\");\nbeginSerial(9600);\n\nsetInterval(() => {\n  const reading = analogRead(SENSOR_PIN);\n  if (!outputOn && reading < TURN_ON_BELOW) {\n    outputOn = true;\n  } else if (outputOn && reading > TURN_OFF_ABOVE) {\n    outputOn = false;\n  }\n  digitalWrite(OUTPUT_PIN, outputOn ? \"HIGH\" : \"LOW\");\n  console.log(reading);\n}, 100);","links":[{"label":"sensor pin","code_end":1,"code_start":1,"english_end":2,"english_start":2},{"label":"output pin","code_end":2,"code_start":2,"english_end":2,"english_start":2},{"label":"turn-on threshold","code_end":3,"code_start":3,"english_end":2,"english_start":2},{"label":"turn-off threshold","code_end":4,"code_start":4,"english_end":2,"english_start":2},{"label":"output state","code_end":5,"code_start":5,"english_end":3,"english_start":3},{"label":"configure pin","code_end":7,"code_start":7,"english_end":4,"english_start":4},{"label":"configure pin","code_end":8,"code_start":8,"english_end":4,"english_start":4},{"label":"configure pin","code_end":9,"code_start":9,"english_end":4,"english_start":4},{"label":"start serial connection","code_end":11,"code_start":11,"english_end":4,"english_start":4},{"label":"start serial connection","code_end":12,"code_start":12,"english_end":4,"english_start":4},{"label":"start serial connection","code_end":13,"code_start":13,"english_end":4,"english_start":4},{"label":"read analogue sensor","code_end":15,"code_start":15,"english_end":4,"english_start":4},{"label":"read analogue sensor","code_end":16,"code_start":16,"english_end":4,"english_start":4},{"label":"read analogue sensor","code_end":17,"code_start":17,"english_end":4,"english_start":4},{"label":"set digital output","code_end":19,"code_start":19,"english_end":4,"english_start":4},{"label":"set digital output","code_end":20,"code_start":20,"english_end":4,"english_start":4},{"label":"set digital output","code_end":21,"code_start":21,"english_end":4,"english_start":4},{"label":"configure output","code_end":23,"code_start":23,"english_end":7,"english_start":7},{"label":"start serial","code_end":24,"code_start":24,"english_end":7,"english_start":7},{"label":"repeat forever","code_end":26,"code_start":26,"english_end":10,"english_start":10},{"label":"read sensor","code_end":27,"code_start":27,"english_end":10,"english_start":10},{"label":"turn output on below threshold","code_end":28,"code_start":28,"english_end":11,"english_start":11},{"label":"turn output on","code_end":29,"code_start":29,"english_end":11,"english_start":11},{"label":"turn output off above threshold","code_end":30,"code_start":30,"english_end":12,"english_start":12},{"label":"turn output off","code_end":31,"code_start":31,"english_end":12,"english_start":12},{"label":"preserve output state otherwise","code_end":32,"code_start":32,"english_end":13,"english_start":13},{"label":"write output state","code_end":33,"code_start":33,"english_end":14,"english_start":14},{"label":"print reading","code_end":34,"code_start":34,"english_end":15,"english_start":15},{"label":"wait before next reading","code_end":35,"code_start":35,"english_end":16,"english_start":16}],"structure":"{\"functions\":[{\"name\":\"pinMode\",\"params\":[\"pin\",\"mode\"],\"english_start\":7,\"english_end\":7,\"summary\":\"Configures a simulated output pin.\",\"calls\":[{\"english_start\":7,\"english_end\":7}]},{\"name\":\"beginSerial\",\"params\":[\"baudRate\"],\"english_start\":7,\"english_end\":7,\"summary\":\"Starts a simulated serial connection.\",\"calls\":[{\"english_start\":7,\"english_end\":7}]},{\"name\":\"analogRead\",\"params\":[\"pin\"],\"english_start\":10,\"english_end\":10,\"summary\":\"Returns a simulated analogue reading from 0 through 1023.\",\"calls\":[{\"english_start\":10,\"english_end\":10}]},{\"name\":\"digitalWrite\",\"params\":[\"pin\",\"value\"],\"english_start\":14,\"english_end\":14,\"summary\":\"Sets a simulated digital output value.\",\"calls\":[{\"english_start\":14,\"english_end\":14}]},{\"name\":\"loop\",\"params\":[],\"english_start\":9,\"english_end\":16,\"summary\":\"Reads the sensor, applies hysteresis, updates the output, and prints the reading repeatedly.\",\"calls\":[{\"english_start\":10,\"english_end\":16}]}]}"}}},{"slug":"vce-u1-07-watering","title":"VCE Systems Engineering · PRP #07 — Automatic watering","description":"Read soil moisture on A0 and drive a pump on pin 9 with dry/wet thresholds, a 15 second run limit and a 60 second rest between waterings.","english":"Water a plant by itself — read a soil moisture sensor on A0 and run a pump on pin 9 only while the soil is dry, with a maximum run time, a compulsory rest, and separate start and stop thresholds so the pump cannot chatter on and off.\n\nCall A0 \"MOISTURE_PIN\" (the soil moisture sensor) and pin 9 \"PUMP_PIN\". Pin 9 goes to the input of a motor driver module, never straight to the pump — a board pin supplies tens of milliamps and the pump wants hundreds.\n\nUse constants: DRY_BELOW is 400 (a reading under this counts as dry soil), WET_ABOVE is 600 (a reading over this counts as wet enough), MAX_RUN_MS is 15000 milliseconds (fifteen seconds — the longest one watering is ever allowed to run, so a sensor that has fallen out of the soil cannot empty the reservoir onto the bench), and REST_MS is 60000 milliseconds (sixty seconds — the pump must sit idle at least this long before it may start again, so the water can soak in). The two millisecond constants are long counts that never go negative, because 60000 will not fit in a plain integer. Those four numbers are your design decisions — tune them to your plant, pot and pump.\n\nKeep a true/false flag \"pumping\" for whether the pump is running, starting at false. Keep two millisecond timestamps, \"pumpStartedAt\" and \"pumpStoppedAt\" — long counts that never go negative, like the constants — both starting at 0, so the rest period is already counting from the moment the board powers up.\n\nSet PUMP_PIN as an output and immediately turn it off (LOW), so the pump cannot kick on while the board is starting. Start the serial connection at 9600 baud.\n\nForever:\n  Read the analogue level on MOISTURE_PIN (0 to 1023) into an integer \"moisture\".\n  Read the number of milliseconds since the board started into \"now\", a long count that never goes negative.\n\n  If pumping (the pump is currently running):\n    Work out \"wetEnough\": true when moisture is greater than WET_ABOVE (600).\n    Work out \"runTooLong\": true when now minus pumpStartedAt is MAX_RUN_MS (15000 milliseconds) or more.\n    If wetEnough or runTooLong:\n      Turn PUMP_PIN off (LOW).\n      Set pumping to false.\n      Set pumpStoppedAt to now.\n      If it was runTooLong that stopped it, print \"STOPPED ON RUN LIMIT - check the sensor\" on its own line — fifteen seconds of pumping that never read wet is a fault, not a thirsty plant.\n\n  Otherwise (the pump is off):\n    Work out \"dry\": true when moisture is less than DRY_BELOW (400).\n    Work out \"rested\": true when now minus pumpStoppedAt is REST_MS (60000 milliseconds) or more.\n    If dry and rested:\n      Turn PUMP_PIN on (HIGH).\n      Set pumping to true.\n      Set pumpStartedAt to now.\n\n  Print moisture on its own line, every time round the loop, whether the pump is running or not.\n  Wait 500 milliseconds (half a second).\n","app_html":"","settings":{},"by_lang":{"python":{"code":"import time\nMOISTURE_PIN = \"A0\"\nPUMP_PIN = 9\nDRY_BELOW = 400\nWET_ABOVE = 600\nMAX_RUN_MS = 15000\nREST_MS = 60000\npumping = False\npumpStartedAt = 0\npumpStoppedAt = 0\ndef set_pump(on):\n    print(f\"PUMP {'HIGH' if on else 'LOW'}\")\ndef read_moisture():\n    try:\n        return int(input(f\"{MOISTURE_PIN} moisture (0-1023): \"))\n    except (EOFError, ValueError):\n        return 1023\n\ndef main():\n    set_pump(False)\n    print(\"Serial started at 9600 baud\")\n    pumping = False\n    pumpStartedAt = 0\n    pumpStoppedAt = 0\n    while True:\n        moisture = read_moisture()\n        now = time.monotonic_ns() // 1_000_000\n        if pumping:\n            wetEnough = moisture > WET_ABOVE\n            runTooLong = now - pumpStartedAt >= MAX_RUN_MS\n            if wetEnough or runTooLong:\n                set_pump(False)\n                pumping = False\n                pumpStoppedAt = now\n                if runTooLong:\n                    print(\"STOPPED ON RUN LIMIT - check the sensor\")\n        else:\n            dry = moisture < DRY_BELOW\n            rested = now - pumpStoppedAt >= REST_MS\n            if dry and rested:\n                set_pump(True)\n                pumping = True\n                pumpStartedAt = now\n        print(moisture)\n        time.sleep(0.5)\n\nif __name__ == \"__main__\":\n    main()","links":[{"label":"standard library import","code_end":1,"code_start":1,"english_end":1,"english_start":1},{"label":"moisture pin","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"pump pin","code_end":3,"code_start":3,"english_end":3,"english_start":3},{"label":"dry threshold","code_end":4,"code_start":4,"english_end":5,"english_start":5},{"label":"wet threshold","code_end":5,"code_start":5,"english_end":5,"english_start":5},{"label":"maximum pump runtime","code_end":6,"code_start":6,"english_end":5,"english_start":5},{"label":"pump rest period","code_end":7,"code_start":7,"english_end":5,"english_start":5},{"label":"pump state","code_end":8,"code_start":8,"english_end":7,"english_start":7},{"label":"pump start timestamp","code_end":9,"code_start":9,"english_end":7,"english_start":7},{"label":"pump stop timestamp","code_end":10,"code_start":10,"english_end":7,"english_start":7},{"label":"pump output helper","code_end":11,"code_start":11,"english_end":9,"english_start":9},{"label":"set pump output","code_end":12,"code_start":12,"english_end":9,"english_start":9},{"label":"moisture input helper","code_end":13,"code_start":13,"english_end":12,"english_start":12},{"label":"read simulated sensor","code_end":14,"code_start":14,"english_end":12,"english_start":12},{"label":"read analogue moisture","code_end":15,"code_start":15,"english_end":12,"english_start":12},{"label":"handle missing sensor input","code_end":16,"code_start":16,"english_end":12,"english_start":12},{"label":"default sensor reading","code_end":17,"code_start":17,"english_end":12,"english_start":12},{"label":"watering controller","code_end":19,"code_start":19,"english_end":1,"english_start":1},{"label":"initially turn pump off","code_end":20,"code_start":20,"english_end":9,"english_start":9},{"label":"start serial connection","code_end":21,"code_start":21,"english_end":9,"english_start":9},{"label":"initialize pump state","code_end":22,"code_start":22,"english_end":7,"english_start":7},{"label":"initialize start timestamp","code_end":23,"code_start":23,"english_end":7,"english_start":7},{"label":"initialize stop timestamp","code_end":24,"code_start":24,"english_end":7,"english_start":7},{"label":"forever loop","code_end":25,"code_start":25,"english_end":11,"english_start":11},{"label":"read soil moisture","code_end":26,"code_start":26,"english_end":12,"english_start":12},{"label":"read elapsed milliseconds","code_end":27,"code_start":27,"english_end":13,"english_start":13},{"label":"pump-running branch","code_end":28,"code_start":28,"english_end":15,"english_start":15},{"label":"check wet threshold","code_end":29,"code_start":29,"english_end":16,"english_start":16},{"label":"check maximum runtime","code_end":30,"code_start":30,"english_end":17,"english_start":17},{"label":"stop condition","code_end":31,"code_start":31,"english_end":18,"english_start":18},{"label":"turn pump off","code_end":32,"code_start":32,"english_end":19,"english_start":19},{"label":"clear pump state","code_end":33,"code_start":33,"english_end":20,"english_start":20},{"label":"record stop time","code_end":34,"code_start":34,"english_end":21,"english_start":21},{"label":"run-limit fault condition","code_end":35,"code_start":35,"english_end":22,"english_start":22},{"label":"report run-limit fault","code_end":36,"code_start":36,"english_end":22,"english_start":22},{"label":"pump-off branch","code_end":37,"code_start":37,"english_end":23,"english_start":23},{"label":"check dry threshold","code_end":38,"code_start":38,"english_end":25,"english_start":25},{"label":"check rest period","code_end":39,"code_start":39,"english_end":26,"english_start":26},{"label":"start condition","code_end":40,"code_start":40,"english_end":27,"english_start":27},{"label":"turn pump on","code_end":41,"code_start":41,"english_end":28,"english_start":28},{"label":"set pump state","code_end":42,"code_start":42,"english_end":29,"english_start":29},{"label":"record start time","code_end":43,"code_start":43,"english_end":30,"english_start":30},{"label":"report moisture","code_end":44,"code_start":44,"english_end":32,"english_start":32},{"label":"wait half a second","code_end":45,"code_start":45,"english_end":33,"english_start":33},{"label":"program entry point","code_end":47,"code_start":47,"english_end":1,"english_start":1},{"label":"run controller","code_end":48,"code_start":48,"english_end":1,"english_start":1}],"structure":"{\"functions\":[{\"name\":\"set_pump\",\"params\":[\"on\"],\"english_start\":9,\"english_end\":9,\"summary\":\"Simulates setting the motor-driver input HIGH or LOW.\",\"calls\":[]},{\"name\":\"read_moisture\",\"params\":[],\"english_start\":12,\"english_end\":12,\"summary\":\"Reads a simulated A0 moisture value from standard input.\",\"calls\":[]},{\"name\":\"main\",\"params\":[],\"english_start\":1,\"english_end\":33,\"summary\":\"Runs the hysteresis-based watering controller indefinitely.\",\"calls\":[{\"english_start\":9,\"english_end\":9},{\"english_start\":12,\"english_end\":12}]}]}"},"javascript":{"code":"const MOISTURE_PIN = \"A0\";\nconst PUMP_PIN = 9;\nconst DRY_BELOW = 400;\nconst WET_ABOVE = 600;\nconst MAX_RUN_MS = 15000;\nconst REST_MS = 60000;\nlet pumping = false;\nlet pumpStartedAt = 0;\nlet pumpStoppedAt = 0;\npinMode(PUMP_PIN, \"OUTPUT\");\ndigitalWrite(PUMP_PIN, LOW);\nSerial.begin(9600);\nasync function loop() {\n  const moisture = analogRead(MOISTURE_PIN);\n  const now = millis();\n  if (pumping) {\n    const wetEnough = moisture > WET_ABOVE;\n    const runTooLong = now - pumpStartedAt >= MAX_RUN_MS;\n    if (wetEnough || runTooLong) {\n      digitalWrite(PUMP_PIN, LOW);\n      pumping = false;\n      pumpStoppedAt = now;\n      if (runTooLong) {\n        Serial.println(\"STOPPED ON RUN LIMIT - check the sensor\");\n      }\n    }\n  } else {\n    const dry = moisture < DRY_BELOW;\n    const rested = now - pumpStoppedAt >= REST_MS;\n    if (dry && rested) {\n      digitalWrite(PUMP_PIN, HIGH);\n      pumping = true;\n      pumpStartedAt = now;\n    }\n  }\n  Serial.println(moisture);\n  await delay(500);\n}\n\nconst LOW = 0;\nconst HIGH = 1;\nconst startedAt = Date.now();\nconst Serial = { begin: () => {}, println: value => console.log(value) };\nconst pinMode = () => {};\nconst digitalWrite = (pin, state) => {};\nconst analogRead = () => 1023;\nconst millis = () => Date.now() - startedAt;\nconst delay = milliseconds => new Promise(resolve => setTimeout(resolve, milliseconds));\nloop();","links":[{"label":"name the soil moisture sensor","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"name the pump control pin","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"define the dry threshold","code_end":3,"code_start":3,"english_end":5,"english_start":5},{"label":"define the wet threshold","code_end":4,"code_start":4,"english_end":5,"english_start":5},{"label":"define the maximum run time","code_end":5,"code_start":5,"english_end":5,"english_start":5},{"label":"define the compulsory rest time","code_end":6,"code_start":6,"english_end":5,"english_start":5},{"label":"initialize the pump state","code_end":7,"code_start":7,"english_end":7,"english_start":7},{"label":"initialize the pump start timestamp","code_end":8,"code_start":8,"english_end":7,"english_start":7},{"label":"initialize the pump stop timestamp","code_end":9,"code_start":9,"english_end":7,"english_start":7},{"label":"configure the pump pin as an output","code_end":10,"code_start":10,"english_end":9,"english_start":9},{"label":"turn the pump off during startup","code_end":11,"code_start":11,"english_end":9,"english_start":9},{"label":"start serial communication","code_end":12,"code_start":12,"english_end":9,"english_start":9},{"label":"repeat the control loop","code_end":13,"code_start":13,"english_end":11,"english_start":11},{"label":"read the soil moisture","code_end":14,"code_start":14,"english_end":12,"english_start":12},{"label":"read elapsed time","code_end":15,"code_start":15,"english_end":13,"english_start":13},{"label":"handle a running pump","code_end":16,"code_start":16,"english_end":15,"english_start":15},{"label":"check whether the soil is wet enough","code_end":17,"code_start":17,"english_end":16,"english_start":16},{"label":"check the maximum run time","code_end":18,"code_start":18,"english_end":17,"english_start":17},{"label":"stop when wet or over the run limit","code_end":19,"code_start":19,"english_end":18,"english_start":18},{"label":"turn the pump off","code_end":20,"code_start":20,"english_end":19,"english_start":19},{"label":"record that the pump stopped","code_end":21,"code_start":21,"english_end":20,"english_start":20},{"label":"record the stop time","code_end":22,"code_start":22,"english_end":21,"english_start":21},{"label":"check whether the run limit caused the stop","code_end":23,"code_start":23,"english_end":22,"english_start":22},{"label":"report a run-limit fault","code_end":24,"code_start":24,"english_end":22,"english_start":22},{"label":"finish the run-limit check","code_end":25,"code_start":25,"english_end":22,"english_start":22},{"label":"finish the stop condition","code_end":26,"code_start":26,"english_end":18,"english_start":18},{"label":"handle a stopped pump","code_end":27,"code_start":27,"english_end":23,"english_start":23},{"label":"check whether the soil is dry","code_end":28,"code_start":28,"english_end":25,"english_start":25},{"label":"check whether the pump has rested","code_end":29,"code_start":29,"english_end":26,"english_start":26},{"label":"start only when dry and rested","code_end":30,"code_start":30,"english_end":27,"english_start":27},{"label":"turn the pump on","code_end":31,"code_start":31,"english_end":28,"english_start":28},{"label":"record that the pump started","code_end":32,"code_start":32,"english_end":29,"english_start":29},{"label":"record the start time","code_end":33,"code_start":33,"english_end":30,"english_start":30},{"label":"finish the start condition","code_end":34,"code_start":34,"english_end":27,"english_start":27},{"label":"finish the pump-state branch","code_end":35,"code_start":35,"english_end":23,"english_start":23},{"label":"print the moisture reading","code_end":36,"code_start":36,"english_end":32,"english_start":32},{"label":"wait half a second","code_end":37,"code_start":37,"english_end":33,"english_start":33},{"label":"finish the control loop","code_end":38,"code_start":38,"english_end":11,"english_start":11},{"label":"define the low output state","code_end":40,"code_start":40,"english_end":1,"english_start":1},{"label":"define the high output state","code_end":41,"code_start":41,"english_end":1,"english_start":1},{"label":"record program start time","code_end":42,"code_start":42,"english_end":1,"english_start":1},{"label":"provide serial output","code_end":43,"code_start":43,"english_end":1,"english_start":1},{"label":"provide pin configuration","code_end":44,"code_start":44,"english_end":1,"english_start":1},{"label":"provide digital output","code_end":45,"code_start":45,"english_end":1,"english_start":1},{"label":"provide an analog sensor adapter","code_end":46,"code_start":46,"english_end":1,"english_start":1},{"label":"provide elapsed milliseconds","code_end":47,"code_start":47,"english_end":1,"english_start":1},{"label":"provide a non-blocking delay","code_end":48,"code_start":48,"english_end":1,"english_start":1},{"label":"start the controller","code_end":49,"code_start":49,"english_end":1,"english_start":1}],"structure":"{\"functions\":[{\"name\":\"loop\",\"params\":[],\"english_start\":11,\"english_end\":33,\"summary\":\"Reads moisture, controls the pump with hysteresis, enforces run and rest limits, reports readings, and repeats forever.\",\"calls\":[]}]}"},"cpp":{"code":"// PRP 7 — automatic watering.\n//\n// Pump is driven through a motor driver module, NOT directly from a pin.\n// A board pin supplies tens of milliamps; the pump wants hundreds.\n//\n// MAX_RUN_MS is the safety limit. If the sensor falls out of the soil or\n// fails open, an unlimited pump empties the reservoir onto the bench.\n// A control system that cannot fail safely is not finished.\n\nconst int MOISTURE_PIN = A0;\nconst int PUMP_PIN     = 9;      // to the driver module input\n\nconst int DRY_BELOW  = 400;      // <-- your calibrated numbers\nconst int WET_ABOVE  = 600;\nconst unsigned long MAX_RUN_MS  = 15000UL;   // never pump longer than this\nconst unsigned long REST_MS     = 60000UL;   // let water soak in before re-reading\n\nbool pumping = false;\nunsigned long pumpStartedAt = 0;\nunsigned long pumpStoppedAt = 0;\n\nvoid setup() {\n  pinMode(PUMP_PIN, OUTPUT);\n  digitalWrite(PUMP_PIN, LOW);\n  Serial.begin(9600);\n}\n\nvoid loop() {\n  int moisture = analogRead(MOISTURE_PIN);\n  unsigned long now = millis();\n\n  if (pumping) {\n    bool wetEnough = moisture > WET_ABOVE;\n    bool runTooLong = (now - pumpStartedAt) >= MAX_RUN_MS;\n\n    if (wetEnough || runTooLong) {\n      digitalWrite(PUMP_PIN, LOW);\n      pumping = false;\n      pumpStoppedAt = now;\n      if (runTooLong) {\n        Serial.println(\"STOPPED ON RUN LIMIT - check the sensor\");\n      }\n    }\n  } else {\n    bool dry = moisture < DRY_BELOW;\n    bool rested = (now - pumpStoppedAt) >= REST_MS;\n\n    if (dry && rested) {\n      digitalWrite(PUMP_PIN, HIGH);\n      pumping = true;\n      pumpStartedAt = now;\n    }\n  }\n\n  Serial.println(moisture);\n  delay(500);\n}\n","links":[],"structure":null},"ruby":{"code":"MOISTURE_PIN = \"A0\"\nPUMP_PIN = 9\nDRY_BELOW = 400\nWET_ABOVE = 600\nMAX_RUN_MS = 15_000\nREST_MS = 60_000\npumping = false\npump_started_at = 0\npump_stopped_at = 0\nputs \"PUMP_PIN configured as OUTPUT\"\nputs \"PUMP_PIN: LOW\"\nputs \"Serial started at 9600 baud\"\nloop do\nmoisture = STDIN.gets.to_i\nnow = (Process.clock_gettime(Process::CLOCK_MONOTONIC) * 1000).to_i\nif pumping\nwet_enough = moisture > WET_ABOVE\nrun_too_long = now - pump_started_at >= MAX_RUN_MS\nif wet_enough || run_too_long\nputs \"PUMP_PIN: LOW\"\npumping = false\npump_stopped_at = now\nputs \"STOPPED ON RUN LIMIT - check the sensor\" if run_too_long\nend\nend\nelse\ndry = moisture < DRY_BELOW\nrested = now - pump_stopped_at >= REST_MS\nif dry && rested\nputs \"PUMP_PIN: HIGH\"\npumping = true\npump_started_at = now\nend\nend\nputs moisture\nsleep 0.5\nend","links":[{"label":"Define moisture sensor pin","code_end":1,"code_start":1,"english_end":3,"english_start":3},{"label":"Define pump control pin","code_end":2,"code_start":2,"english_end":3,"english_start":3},{"label":"Define dry threshold","code_end":3,"code_start":3,"english_end":5,"english_start":5},{"label":"Define wet threshold","code_end":4,"code_start":4,"english_end":5,"english_start":5},{"label":"Define maximum pump runtime","code_end":5,"code_start":5,"english_end":5,"english_start":5},{"label":"Define compulsory rest period","code_end":6,"code_start":6,"english_end":5,"english_start":5},{"label":"Initialize pump state","code_end":7,"code_start":7,"english_end":7,"english_start":7},{"label":"Initialize pump start timestamp","code_end":8,"code_start":8,"english_end":7,"english_start":7},{"label":"Initialize pump stop timestamp","code_end":9,"code_start":9,"english_end":7,"english_start":7},{"label":"Configure pump output","code_end":10,"code_start":10,"english_end":9,"english_start":9},{"label":"Turn pump off at startup","code_end":11,"code_start":11,"english_end":9,"english_start":9},{"label":"Start serial connection","code_end":12,"code_start":12,"english_end":9,"english_start":9},{"label":"Begin forever loop","code_end":13,"code_start":13,"english_end":11,"english_start":11},{"label":"Read soil moisture","code_end":14,"code_start":14,"english_end":12,"english_start":12},{"label":"Read elapsed milliseconds","code_end":15,"code_start":15,"english_end":13,"english_start":13},{"label":"Handle running pump","code_end":16,"code_start":16,"english_end":15,"english_start":15},{"label":"Check wet threshold","code_end":17,"code_start":17,"english_end":16,"english_start":16},{"label":"Check maximum runtime","code_end":18,"code_start":18,"english_end":17,"english_start":17},{"label":"Check whether pumping must stop","code_end":19,"code_start":19,"english_end":18,"english_start":18},{"label":"Turn pump off","code_end":20,"code_start":20,"english_end":19,"english_start":19},{"label":"Record pump stopped","code_end":21,"code_start":21,"english_end":20,"english_start":20},{"label":"Record stop time","code_end":22,"code_start":22,"english_end":21,"english_start":21},{"label":"Report runtime fault","code_end":23,"code_start":23,"english_end":22,"english_start":22},{"label":"End stop condition","code_end":24,"code_start":24,"english_end":22,"english_start":22},{"label":"End running-pump branch","code_end":25,"code_start":25,"english_end":23,"english_start":23},{"label":"Handle stopped pump","code_end":26,"code_start":26,"english_end":23,"english_start":23},{"label":"Check dry threshold","code_end":27,"code_start":27,"english_end":25,"english_start":25},{"label":"Check compulsory rest","code_end":28,"code_start":28,"english_end":26,"english_start":26},{"label":"Check whether watering may start","code_end":29,"code_start":29,"english_end":27,"english_start":27},{"label":"Turn pump on","code_end":30,"code_start":30,"english_end":28,"english_start":28},{"label":"Record pump running","code_end":31,"code_start":31,"english_end":29,"english_start":29},{"label":"Record start time","code_end":32,"code_start":32,"english_end":30,"english_start":30},{"label":"End start condition","code_end":33,"code_start":33,"english_end":31,"english_start":31},{"label":"End pump-state branch","code_end":34,"code_start":34,"english_end":31,"english_start":31},{"label":"Print moisture reading","code_end":35,"code_start":35,"english_end":32,"english_start":32},{"label":"Wait half a second","code_end":36,"code_start":36,"english_end":33,"english_start":33},{"label":"Repeat forever","code_end":37,"code_start":37,"english_end":33,"english_start":33}],"structure":"{\"functions\":[]}"}}}]}