MIT App Inventor

ICT 360: Introduction to IoT

Mr. Seng Theara

DC Motor

How to make the DC Motor rotate

Power Supply

DC Motor

How to make the DC Motor rotate

Power Supply

How to make the DC Motor rotate

Voltage 12V

Voltage 6V

How to make the DC Motor rotate

Forward Direction

Backward Direction

  • Red wire from power Supply to red wire of the dc motor
  • Black wire from power supply to black wire of the dc motor
  • Red wire from power Supply to black wire of the dc motor
  • Black wire from power supply to red wire of the dc motor

Why we can't use ESP32 to control DC Motor Directly?

ESP32

  • Output Voltage is only 3.3V
  • Max Current from the pin ~12mA

Why we can't use ESP32 to control DC Motor Directly

DC Motor

ESP32

  • Output Voltage is only 3.3V
  • Max Current from the pin ~12mA
  • DC Motor usually need 6V, 9V, 12V (more)
  • Needs hundreds of mA to several A

Why we can't use ESP32 to control DC Motor Directly

DC Motor

ESP32

  • Output Voltage is only 3.3V
  • Max Current from the pin ~12mA
  • DC Motor usually need 6V, 9V, 12V (more)
  • Needs hundreds of mA to several A

Result

  • ESP32 may reset, overheat, or get permanently damaged
  • Motor won’t spin or spin slowly

Why we can't use ESP32 to control DC Motor Directly

DC Motor

ESP32

  • Output Voltage is only 3.3V
  • Max Current from the pin ~12mA
  • DC Motor usually need 6V, 9V, 12V (more)
  • Needs hundreds of mA to several A

Result

ESP32 may reset, overheat, or get permanently damaged

Motor won’t spin or spin slowly

Correct Way to Control a DC Motor with ESP32

ESP32

  • Output Voltage is only 3.3V
  • Max Current from the pin ~12mA

Motor Driver

Correct Way to Control a DC Motor with ESP32

ESP32

  • Output Voltage is only 3.3V
  • Max Current from the pin ~12mA

Motor Driver

TB6612

Correct Way to Control a DC Motor with ESP32

ESP32

  • Output Voltage is only 3.3V
  • Max Current from the pin ~12mA

Motor Driver

TB6612

L298N

Correct Way to Control a DC Motor with ESP32

ESP32

  • Output Voltage is only 3.3V
  • Max Current from the pin ~12mA

Motor Driver

TB6612

L298N

L293D

Correct Way to Control a DC Motor with ESP32

ESP32

  • Output Voltage is only 3.3V
  • Max Current from the pin ~12mA

Motor Driver

TB6612

L298N

L293D

BTS7960

Correct Way to Control a DC Motor with ESP32

ESP32

  • Output Voltage is only 3.3V
  • Max Current from the pin ~12mA

Motor Driver

TB6612

L298N

L293D

BTS7960

These drivers:

  • Supply high current

  • Protect ESP32

  • Allow speed & direction control

Correct Way to Control a DC Motor with ESP32

ESP32

  • Output Voltage is only 3.3V
  • Max Current from the pin ~12mA

Motor Driver

TB6612

L298N

L293D

BTS7960

These drivers:

  • Supply high current

  • Protect ESP32

  • Allow speed & direction control

Speed and Direction Control of Dc Motor

Driver Motor which is used in this class

L298N

ESP32 with Driver Motor

Speed and Direction Control of Dc Motor

         Driver       State
IN1       HIGH
IN2       LOW
ENA 10 bit (0-1023)
IN3       HIGH
IN4       LOW
ENB 10 bit (0-1023)
    Motor
    
    

Forward

= \frac{12V \times \text{pwmA}}{1023}
= \frac{12V \times \text{pwmB}}{1023}

Forward

       State
      LOW
      HIGH
10 bit (0-1023)
      LOW
      HIGH
10 bit (0-1023)
    Motor
    
    

Backward

= \frac{12V \times \text{pwmA}}{1023}
= \frac{12V \times \text{pwmB}}{1023}

Backward

Coding one DC Motor

from machine import Pin, PWM
import time

# Motor direction pins
IN1 = Pin(27, Pin.OUT)
IN2 = Pin(26, Pin.OUT)

# PWM pin for speed control
ENA = PWM(Pin(14))
ENA.freq(1000)

def motor_forward(speed):
    IN1.value(1)
    IN2.value(0)
    ENA.duty(speed)


while True:

    print("Forward slow")
    motor_forward(300)
    time.sleep(3)

MIT App Inventor Web Server

MIT App Inventor Web Server

MIT App Inventor is a block-based programming platform to create apps.

Features:

  • Drag and drop UI

  • Block programming (no complex syntax)

  • Works with Bluetooth / WiFi / IoT devices

MIT App Inventor Interface

There are 3 mains part in the MIT App inventor

Designer

Used to build the app interface

Examples:

  • Buttons

  • Labels

  • Images

Blocks

Used to create the logic

Components

Devices used by the app

Examples:

  • Bluetooth

  • WiFi

  • Sensors

Designer Interface

We create 3 button in here to move backward, stop, and Forward

A slider here is used to adjust the speed

This horizontal Arrangement is just for spacing

Backward Appearance

Designer Interface

We create 3 button in here to move backward, stop, and Forward

A slider here is used to adjust the speed

This horizontal Arrangement is just for spacing

Stop Appearance

Designer Interface

We create 3 button in here to move backward, stop, and Forward

A slider here is used to adjust the speed

This horizontal Arrangement is just for spacing

Forward Appearance

Designer Interface

We create 3 button in here to move backward, stop, and Forward

A slider here is used to adjust the speed

This horizontal Arrangement is just for spacing

Slider Appearance

Component

In here, we use the wifi component. You can actually use the bluetooth, but it supports only the android 

Block

You need to adjust this with your own IP from the esp32 

ESP32 Code 

import network
import socket

ssid = "ssid"
password = "password"

# Connect to WiFi
wifi = network.WLAN(network.STA_IF)
wifi.active(True)
wifi.connect(ssid, password)

print("Connecting", end="")
while not wifi.isconnected():
    pass

print("\nConnected!")
print("ESP32 IP:", wifi.ifconfig()[0])



def forward():
    print("Command: FORWARD")

def backward():
    print("Command: BACKWARD")

def stop():
    print("Command: STOP")

def set_speed(value):
    print("Speed value received:", value)


# ==== Web Server ====
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
server = socket.socket()
server.bind(addr)
server.listen(5)

print("Server running on", addr)


while True:
    client, addr = server.accept()
    print("Client connected from", addr)

    request = client.recv(1024).decode()
    print("Request:", request)

    # ==== Parse Request ====
    if "GET /forward" in request:
        forward()
        response = "Forward received"

    elif "GET /backward" in request:
        backward()
        response = "Backward received"

    elif "GET /stop" in request:
        stop()
        response = "Stop received"

    elif "GET /speed" in request:
        # Extract value parameter
        try:
            value = request.split("value=")[1].split(" ")[0]
            set_speed(value)
        except:
            value = "None"
            print("No speed value")
        response = "Speed received"

    else:
        response = "Invalid command"

    
    client.send("HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n")
    client.send(response)
    client.close()

Mobile Phone

Download the MIT App Inventor from your mobile phone and scan QR using MIT App Inventor AI Companion as shown below

TCS34725 Color Sensor

TCS34725 Color Sensor

The TCS34725 is a digital color sensor that we can use with a processor to measure the RGB values off the color off an object or light

Color detection is based on light reflection:

  • A light source shines on an object
  • The object reflects certain wavelengths (colors)
  • The sensor measures the reflected light

Example

  • A red object reflects more red light
  • A blue object reflects more blue light

TCS34725 Connection

TCS34725 Library

import time

class TCS34725:

    COMMAND_BIT = 0x80
    ENABLE = 0x00
    ENABLE_AEN = 0x02
    ENABLE_PON = 0x01
    ATIME = 0x01
    CONTROL = 0x0F
    ID = 0x12
    CDATA = 0x14

    def __init__(self, i2c, address=0x29):
        self.i2c = i2c
        self.address = address

        self.write(self.ENABLE, self.ENABLE_PON)
        time.sleep_ms(10)
        self.write(self.ENABLE, self.ENABLE_PON | self.ENABLE_AEN)

    def write(self, reg, value):
        self.i2c.writeto_mem(self.address, reg | self.COMMAND_BIT, bytes([value]))

    def read(self, reg, nbytes):
        return self.i2c.readfrom_mem(self.address, reg | self.COMMAND_BIT, nbytes)

    def read16(self, reg):
        data = self.read(reg,2)
        return data[1]<<8 | data[0]

    def read_raw(self):
        c = self.read16(self.CDATA)
        r = self.read16(self.CDATA+2)
        g = self.read16(self.CDATA+4)
        b = self.read16(self.CDATA+6)
        return (r,g,b,c)

Create a tcs34527.py and save this in the micropython device

TCS34725 Coding

from machine import Pin, I2C
import time
import tcs34725

i2c = I2C(0, scl=Pin(22), sda=Pin(21))
sensor = tcs34725.TCS34725(i2c)

print("Place object in front of sensor")

while True:

    r,g,b,c = sensor.read_raw()

    print("R:",r," G:",g," B:",b)

    time.sleep(1)

In this code, we read the raw value of the RGB and the result is shown below

when it doesn't detect the RGB Color, the value is below 200, but this also related to the brightness as well

RGB Color Detection

Red Color Detection

Green Color Detection

Blue Color Detection

The red color work better than green and blue because of the reflection strength, sensor sensitivity and lighting

WS2812 NeoPixel 

WS2812 NeoPixel 

WS2812 is a smart RGB LED:

  • Combines LED + controller chip in one package
  • Can display millions of colors
  • Each LED can be controlled individually
  • Uses only ONE data wire

WS2812 NeoPixel 

Inside each WS2812, There is

  • Red LED
  • Green LED
  • Blue LED
  • Control IC (chip)

Each LED has its own address

How WS2812 Work 

  • Microcontroller sends a data signal
  • First LED reads its data
  • Passes remaining data to next LED
  • Each LED displays its own color

one wire

WS2812 Connection 

Color Representation 

Each color uses values: (0–255, 0–255, 0–255)

ColorValue
Red(255, 0, 0)
Green(0, 255, 0)
Blue(0, 0, 255)
White(255, 255, 255)
Off(0, 0, 0)

WS2812 Coding

from machine import Pin
import neopixel
import time

led = neopixel.NeoPixel(Pin(23), 16)

while True:

    led[0] = (255,0,0)  # RED
    led.write()
    time.sleep(1)

    led[1] = (0,255,0)  # GREEN
    led.write()
    time.sleep(1)

    led[2] = (0,0,255)  # BLUE
    led.write()
    time.sleep(1)

We declare the pin23 using with the WS2812 with the number of 16 led

Set the first led to red using the address 0

Set the second led to green using the address 1

Set the third led to Blue using the address 2

WS2812 Coding

from machine import Pin
import neopixel
import time

led = neopixel.NeoPixel(Pin(23), 16)

while True:
    for i in range(16):
        led[i] = (255,0,0)
        led.write()
        time.sleep(0.2)
        led[i] = (0,0,0)

Using for loop to moves like a “chasing light”

WS2812 Coding

from machine import Pin
import neopixel
import time

led = neopixel.NeoPixel(Pin(23), 16)

def wheel(pos):
    if pos < 85:
        return (pos * 3, 255 - pos * 3, 0)
    elif pos < 170:
        pos -= 85
        return (255 - pos * 3, 0, pos * 3)
    else:
        pos -= 170
        return (0, pos * 3, 255 - pos * 3)

while True:
    for j in range(255):
        for i in range(16):
            led[i] = wheel((i + j) & 255)
        led.write()

Rainbow Effect