Skip to content

First program: draw on the screen and light an LED

  1. Place a text label on the screen with ui.Label and print to the Console drawer with lcd.print, and have it run without errors
  2. Blink an LED with gpio.led(n).on() / off() and time.sleep_ms() for a given number of times
  3. Predict a result before running it, and explain why the program should end with led.off()
  • From the previous lesson, which command makes a label appear on screen as soon as it is created?
  • In the emulator, which button opens the simulated hardware panel that has the LEDs?

Before reading the code, predict first. Open examples/02_blink.py and read only the top three lines that set ROUNDS, ON_MS and OFF_MS, then write on paper “how many times will the light blink, and how long does each blink last?”

Then run it in the BENTO Emulator (press HW to open the simulated hardware panel first, then press ▶ Run), or on a real board with Program to Device, and compare it with what you predicted.

1. One line of text can go to three places

Section titled “1. One line of text can go to three places”
Command Where the text goes Who sees it
ui.Label("...") On the screen, at the given x, y position Someone looking at the screen
lcd.print("...") The Console drawer on the screen (opened with the green button in the bottom-right corner) Someone who opens the drawer
print("...") The console on the computer side Someone sitting at the computer

These are three different places. Many beginners run their program and say “I don’t see anything”, when the text is actually waiting in a different place. Run examples/01_hello_screen.py and find the text in all three places.

Turn on, wait, turn off, wait. The waiting time is what sets the rhythm. A microcontroller runs very fast, so without time.sleep_ms() the light would turn on and off too quickly for the eye to catch.

led.on() and led.off() set the value directly: read one line and you know exactly what the light will do. That is why we choose these two commands first.

3. A good program says which state it ends in

Section titled “3. A good program says which state it ends in”

If a program ends while the light is on, the light stays on forever with nobody intending it. In real work, such as a warning light in a factory, this can mislead people. Every example file in this course therefore starts with led.off() (start from a known state) and ends with led.off() (end at a known state).

examples/02_blink.py is a shortened version of examples/s03/02_led_blink.py from the AIoT in Action course.

  • Move 1: pick a light Ask for the list of LEDs from gpio.board_info() and pick the one whose name starts with RGB_; use the first one if there is none
  • Move 2: start from a known state led.off()
  • Move 3: place a label and a number A status label, plus ui.Seg7 showing a number like a digital clock
  • Move 4: loop the blink In a for loop: turn on, update the label, wait, turn off, count the round, wait
  • Move 5: end at a known state led.off() again

The file examples/01_hello_screen.py is a shortened version of examples/s01/01_first_line.py and uses the same Move 3.

Screens from the BENTO Emulator for this lesson’s examples (click a file name to open the code)

Open practice/blink_count.py. It has 2 blanks to fill in (lines starting with # fill in:)

  • Blank 1: turn the light on
  • Blank 2: add one to the counter, then write the new number to the screen

If you would like to practise without typing, first try arranging the code lines in quiz question 3 into the right order (a Parsons problem), then come back and fill in the real file.

Try it yourself for at least 15 minutes first, then open solution/blink_count.py and compare. The comments in the solution explain “why” you count while the light is off, and why you need str() before passing a value to Seg7.

Answer the questions in quiz.yaml. A score of 80% or more passes.

Modify Set ON_MS = 50 and OFF_MS = 950 in examples/02_blink.py. Predict what the light will look like first, then run it for real.

Make Write a new program that blinks a short–long code, for example three short blinks, three long blinks, three short blinks, then take a screenshot (or a short clip if you are using a real board) and keep it as evidence in your portfolio.

A blinking light is the “Hello, World” of the embedded world. If you would like to see how a single LED can be dimmed, look at the example examples/s03/03_led_brightness.py in the AIoT in Action course.

Did your prediction differ from what actually happened when you ran it? If it did, why? Does predicting before running change the way you read code?

Review questions

Answer on your own first, then open the answer.

  1. Where does lcd.print("hello") put its text? (Objective 1)

    1. คอนโซลฝั่งคอมพิวเตอร์
    2. ลิ้นชัก Console บนจอบอร์ด
    3. ป้ายตรงตำแหน่ง x, y บนจอ
    4. ไม่ปรากฏที่ใดเลย
    Show answer

    Answer: B. ลิ้นชัก Console บนจอบอร์ด

    lcd.print เขียนลงลิ้นชัก Console ต้องเปิดลิ้นชักด้วยปุ่มสีเขียวมุมขวาล่างถึงจะเห็น ส่วน print() ไปที่คอมพิวเตอร์ และ ui.Label ไปที่จอตรง ๆ

  2. In ui.Label("hello", x=24, y=8, color=0xE8EAED, value=28), what does value=28 set? (Objective 1)

    1. ตำแหน่งแนวตั้ง
    2. สีของตัวอักษร
    3. ขนาดตัวอักษร
    4. จำนวนครั้งที่แสดง
    Show answer

    Answer: C. ขนาดตัวอักษร

    สำหรับป้าย value คือขนาดตัวอักษร ตำแหน่งคือ x กับ y และสีคือ color

  3. Order the lines inside the blink loop (one blink). (Objective 2)

    1. led.off()
    2. time.sleep_ms(ON_MS)
    3. led.on()
    4. time.sleep_ms(OFF_MS)
    Show answer

    Correct order: C. led.on() → B. time.sleep_ms(ON_MS) → A. led.off() → D. time.sleep_ms(OFF_MS)

    สั่งติด รอ สั่งดับ รอ ถ้าไม่มีช่วงรอ ไฟจะติดดับเร็วเกินกว่าตาจะเห็น

  4. With ROUNDS = 6, ON_MS = 250 and OFF_MS = 250, roughly how long does the blinking take (ignoring drawing time)? (Objective 3)

    1. 0.5 วินาที
    2. 1.5 วินาที
    3. 3 วินาที
    4. 6 วินาที
    Show answer

    Answer: C. 3 วินาที

    หนึ่งรอบคือ 250 + 250 = 500 ms หกรอบจึงราว 3000 ms เวลาจริงจะนานกว่านี้เล็กน้อยเพราะการวาดจอก็ใช้เวลา

  5. Why does the example call led.off() again after the loop? (Objective 3)

    1. เพราะ MicroPython บังคับให้ทุกโปรแกรมจบด้วย off()
    2. เพื่อให้แน่ใจว่าโปรแกรมจบที่สถานะที่รู้แน่ ไม่ปล่อยไฟค้างติดโดยไม่ตั้งใจ
    3. เพื่อให้ไฟกะพริบเพิ่มอีกหนึ่งครั้ง
    4. เพื่อประหยัดหน่วยความจำ
    Show answer

    Answer: B. เพื่อให้แน่ใจว่าโปรแกรมจบที่สถานะที่รู้แน่ ไม่ปล่อยไฟค้างติดโดยไม่ตั้งใจ

    โปรแกรมที่จบแล้วควรบอกได้แน่ว่าไฟอยู่สถานะไหน ในงานจริงไฟที่ค้างติดผิดจังหวะทำให้คนเข้าใจผิดได้

Cite this lesson

If you teach from this lesson or reuse it in slides or documents, credit it with the text below. If you changed it, add (adapted) after the title.

"First program: draw on the screen and light an LED" from TESA Open Knowledge by the Thai Embedded Systems Association (TESA), https://github.com/tesaiot/tesa-qualification-program, licensed under CC BY-NC 4.0

Thai attribution: "โปรแกรมแรก: เขียนบนจอและเปิดไฟ" จาก TESA Open Knowledge โดยสมาคมสมองกลฝังตัวไทย (Thai Embedded Systems Association: TESA) https://github.com/tesaiot/tesa-qualification-program สัญญาอนุญาต CC BY-NC 4.0

Lesson link: https://tesaiot.github.io/tesa-qualification-program/en/courses/explorer/m01-meet-embedded/l03-first-program/

This lesson adapts the source below; keep its credit too.
https://github.com/Advance-Innovation-Centre-AIC/embedded-systems-for-aiot-developer/blob/a80bbe88a34bcb9bb8d991f42f9252b77cdab079/examples/s03/02_led_blink.py · ตัวอย่างโค้ดทุกไฟล์ในหลักสูตรนี้ย่อและดัดแปลงจากตัวอย่างของ AIoT in Action (MIT) ใช้ API ของ BENTO MicroPython ตามที่ตัวอย่างต้นฉบับใช้ ไม่มีการเพิ่มคำสั่งใหม่

Full guide: how to cite TESA

TESA Open Knowledge · © 2026 สมาคมสมองกลฝังตัวไทย (TESA) · CC BY-NC 4.0

Content is licensed CC BY-NC 4.0. Reuse it non-commercially and credit the Thai Embedded Systems Association (TESA) every time. · How to cite TESA