Skip to content

loopstick/ESP32_Tutorial_Art385

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Hands-on ESP32 Tutorial

This tutorial created by Sudhu Tewari 2020

  • from materials originally created by: Michael Shiloh and Judy Castro for Teach Me To Make

Tutorial overview

The tutorial will focus on getting you up and running with Arduino quickly, so that you will understand the basic procedures for working with your ESP32 (specifically Adafruit's Huzzah32) and the Arduino IDE and can explore further on your own.

We will cover how to install Arduino on your laptop; how to understand, modify, and write Arduino programs; how to connect input devices and sensors to your ESP32 and read them from a program; and how to connect actuators (LEDs, motors, speakers) and control them from a program. Other topics will be covered as interest dictates and time permits.

Additional Resources

What is Arduino anyway?

What is ESP32?

Start Here

First steps: Verifying correct installation

  1. Connect ESP32 via USB cable

    • Windows? Might see “New Hardware Discovered” and later might see “New Hardware Ready for Use”.
    • Mac OS X? Might see “New Network Interface Found”. Click “Network Preferences…”,  click “Apply”, and when it finishes, click “Close”. It doesn’t matter if the configuration fails.
    • Linux? Nothing to do here
  2. Open Arduino software (IDE)

  3. Select Tools -> Board

    • You have a Adafruit ESP32 Feather.
  4. Select Tools -> Serial Port

    • Windows? Chose the largest COM number
    • Mac OS X? Chose /dev/cu.SLAB_USDtoUART
    • Linux? There is only one choice
  5. Open File->Examples->Basics->Blink

    • Click “Upload”
    • Look for errors in the bottom window of the program
    • Look for an amber LED blinking rapidly and a red LED blinking slowly on the other side of the USB connector

Is this thing really on?

Copy the code below into a new Arduino sketch or download and open this example sketch: HelloWorld.ino

/*
  Hello World
  A "Hello, World!" program generally is a computer program that
	outputs or displays the message "Hello, World!".
	Such a program is very simple in most programming languages,
	and is often used to illustrate the basic syntax of a programming language.
	It is often the first program written by people learning to code
*/

void setup() {
//initialize serial communications at 9600 baud rate
Serial.begin(9600);
}

void loop(){
//send 'Hello, world!' over the serial port
Serial.println("Hello, world!");
//wait 100 milliseconds so we don't drive ourselves crazy
delay(1000);
}

The Serial commands allow Arduino to send a message to your laptop. In order to see this message you need to open the Serial Monitor by clicking on the magnifying glass near the top right corner.

a little code anatomy:

  • the setup() function is called when a sketch starts.

    • Use it to initialize variables, pin modes, start using libraries, etc.
    • The setup() function will only run once, after each powerup or reset of the Arduino board.
  • the loop() function does precisely what its name suggests, and loops consecutively through your list of instructions to control the Arduino.

    • Arduino only executes one instruction at a time

More on specific functions and variables soon! Let's make something happen in the real world first.

How to use Arduino to turn something ON and OFF

How does the program (sketch) do this? (all described in the Blink tutorial)

/*
  Blink

  Turns an LED on for one second, then off for one second, repeatedly.

  Most Arduinos have an on-board LED you can control. 
  On the UNO it is attached to digital pin 13

  This example code is modified from.
  https://www.arduino.cc/en/Tutorial/BuiltInExamples/Blink
*/

int led = 13;  // define a variable to hold the pin number of the internal LED

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(led, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

some more code anatomy - info about an Arduino Sketch

Exercise:
  • combine HelloWorld and Blink to make a program that shows it's working with physical and digital output.

Connecting to your Microcontroller - Pinouts

In order to connect inputs or outputs to your microcontroller you need to know where the GPIO (general-purpose input/output) pins are!

feather_pinouttop

feather_pinoutbot

adafruithuzzah32pin

adafruithuzzah32pin

Using a solderless Breadboard to connect your microcontroller to other things (LEDs, motors, speakers, sensors, etc.)

The Solderless Breadboard

Breadboard

Breadboard underside

Use the breadboard to add an external LED.

Here’s a picture showing how to connect the LED and resistor on the breadboard:

LED_Breadboard2

Here is another view of this circuit:

ESP32_LED_01

Use the Blink sketch: File -> Examples -> Basics -> Blink

Does the LED on the breadboard blink? (think about why)

Exercise:

Move LED to a different pin (e.g. pin 12). See if you can figure out how to do this on your own

Now the LED won’t blink until you change the program, since the program is only turning pin 13 on and off. Change the program to control pin 8.

Exercise:

If you changed the program to control only pin 8, then the built-in LED on pin 13 is no longer blinking. Can you change the program to make them both blink?

Are we limited to LEDs? No; we could replace the LED (and its resistor) with any other suitable device, with some considerations. We’ll learn more about this later.

How to read a switch from a GPIO: digitalRead()

  • Switches

  • digitalRead()

    ESP32_BTN_LED

    /*
    DigitalReadSerial
    Reads a digital input on pin A0, prints the result to the Serial Monitor
    This example code is in the public domain.
    http://www.arduino.cc/en/Tutorial/DigitalReadSerial
    */
    
      // A0 has the pushbutton attached to it. Give it a name:
      int pushButton = A0;
    
      // the setup routine runs once when you press reset:
      void setup() {
       // initialize serial communication at 9600 bits per second:
    	Serial.begin(9600);
       // make the pushbutton's pin an input:
    	pinMode(pushButton, INPUT);
      }
    
      // the loop routine runs over and over again forever:
      void loop() {
       // read the input pin:
    	int buttonState = digitalRead(pushButton);
       // print out the state of the button:
       Serial.println(buttonState);
       delay(1);        // delay in between reads for stability
      }
Exercises:
  • Write an IF statement to turn the LED on when the button is pushed.
  • Write an IF statement to toggle the LED when the button is pushed a certain number of times.

How to use a sensor: analogRead()

So far we’ve only used Arduino as an output device, to control something in the physical world (the LED). The other way of interfacing to the physical world is as an input device, using a sensor to get information about the physical world. We’ll start with a photoresistor, also called a light dependent resistor or LDR. It’s a resistor whose resistance depends on the light: the more light, the lower the resistance. (The resistor we used above with the LED is a fixed resistor.) The LDR indicates the amount of light by changing its resistance, but Arduino can not measure resistance. But, Arduino can measure voltage! Fortunately, we can easily convert a varying resistance to a varying voltage using a fixed resistor to create a voltage divider. This time the fixed resistor needs a larger resistance, so select a 10k ohm resistor and build the circuit below. You don’t need to remove the LED circuit as there should be room on your breadboard for both, and we’ll use the LED again later.

CircuitExample

Open and upload this sketch: File->Examples->Basics->AnalogReadSerial

How do you know if anything is working? Arduino might be reading the sensor, but is it telling you anything?

Arduino is connected to your computer, so they can communicate - just like we did earlier with Hello World, but now your Ardunio is sending sensor DATA!

  • this line: cpp Serial.println(sensorValue); allows Arduino to send a message to your laptop. In order to see this message you need to open the Serial Monitor by clicking on the magnifying glass near the top right corner. Read the Arduino AnalogRead tutorial to find out more. Also see File->Examples->Communication for more examples of other types of Serial communication).

Now that we've got sensor data coming in (as a range of values) what can we do with the data?

  • ESP32 can measure varying voltage levels between 0 V and 3.3 V.
    • The voltage measured is assigned to a value between 0 and 4095
      • 0V corresponds to 0, and 3.3V corresponds to 4095.
      • Any voltage between 0 V and 3.3 V will be given the corresponding value.
    • We could do some math to calculate the voltage we're measuring: File->Examples->Basics->AnalogReadVoltage
      • we'll need to do some different math to re-configure the stock Arduino example for ESP32
        • Arduino inputs range from 0-1024

That's nice, but what if we want to use the sensor data to control some kind of physical reaction (light, heat, motion) to the data?

Exercise:

Use an IF statement to turn your LED on and off according to the data coming from the LDR.

What other kinds of sensors are there?

IMPORTANT NOTE:

  • When looking for sensors to use
    • be aware that ESP32 is a 3.3V system.
    • Many microcontrollers and sensors are made to run on 5v
      • 5V WILL KILL YOUR ESP32!
    • It is possible to convert 5V sensor outputs to 3.3v
    • It is even easier to use 3.3V compatible sensors

More on Sensors in the near future

Let's shift our focus, now, for a moment, to outputting a range of voltages. Then we'll put the input and output together to get real world input to control real world output.

Sensor ranges, calibration, and mapping

analogWrite(): Controlling speed or brightness

  • If digitalWrite() can turn an LED on and off, and analogRead() can read a range of values, what would you guess analogWrite() might do?

    • You guessed it!
  • analogWrite outputs PWM

    • PWM = pulse width modulation
    • this allows us, effectively, to output any voltage between minimum
      • minimum = 0 volts = 0 in code
      • maximum = 3.3 volts (ESP32) = 255 (@8bit resolution)
  • Arduino: analogWrite() only works on certain pins.

  • ESP32 can output PWM on ANY pin.

Analog Output - PWM - Major Difference between Arduino and ESP32

  • ESP32 uses different functions to call PWM output

    • ledcAttachPin(GPIO, channel)
    • ledcWrite(channel, dutycycle)
  • 16 PWM channels (0-15)

    • variable PWM frequency (5000 is plenty for LEDs)
    • variable duty cycle
      • 8 bits = 0-255
      • this is how you control the intensity of the output
/*
 * PWM example code
 */

// the number of the LED pin
const int ledPin = 12;  // 12 corresponds to GPIO16

// setting PWM properties
// variable PWM frequency (5000 is plenty for LEDs)
const int freq = 5000;
// 16 PWM channels available (0-15)
const int ledChannel = 0;
// 8 bits = 0-255
const int resolution = 8;

void setup(){
  // configure LED PWM functionalitites
  ledcSetup(ledChannel, freq, resolution);

  // attach the channel to the GPIO to be controlled
  ledcAttachPin(ledPin, ledChannel);
}

void loop(){
  // increase the LED brightness
  for(int dutyCycle = 0; dutyCycle <= 255; dutyCycle++){   
    // changing the LED brightness with PWM
    ledcWrite(ledChannel, dutyCycle);
    delay(15);
  }

  // decrease the LED brightness
  for(int dutyCycle = 255; dutyCycle >= 0; dutyCycle--){
    // changing the LED brightness with PWM
    ledcWrite(ledChannel, dutyCycle);   
    delay(15);
  }
}
Exercises:

ESP32_AnalogWrite

Exercises:

RGB LEDs

RGB LEDs are really handy for non-text, non-serial debug and they make really pretty colors!

ESP32_LED_RGB

  • Generally we use a slightly larger resistor (150 ohm) for the RED component and the same slightly smaller resistor values (100 ohm) for the GREEN and BLUE components.

  • for our circuit let's use:

    • 470 ohm for RED
      • color bands-> yellow, purple, black, black, brown
    • 430 ohm for GREEN and BLUE
      • color bands-> yellow, orange, black, black, brown
    • We're using common CATHODE RGB LEDs
  • RGB LED Test Code

  • RGB LED code example using analogWrite()

Some other online information about RGB LEDs

INTRODUCING - the ART 385 hardware platform !!!

ESP32_Art385_Platform

  • Here's a layout that will allow you to use all of the components you have to write code and prototype functionality.

    • RGB LED
      • Red on pin 12
      • Green on pin 27
      • Blue on pin 33
      • common cathode to GND (ground) - the common pin is the longest of all 4 legs
    • LDR (Light Dependent Resistor)
      • LDR on pin A0
        • pin 1 to 3v
        • pin 2 to A0 & 10Kohm pulldown to GND (ground)
    • Potentiometer (blue thing with knob)
      • potentiometer on pin A1
        • pin 1 to 3v
        • pin 2 to A1 (pin 2 is the middle pin)
        • pin 3 to GND (pin 1 and pin 3 are the outer pins (doesn't matter which is which))
    • Button (switch)
      • insert in parallel with LDR
        • or
      • use in place of LDR
  • Art 385 Platform Test - Color Flashing code

  • Art 385 Platform Test - Color Fading code

  • Art 385 Platform Test - Citrus Strawberry

Multi-Tasking - DITCH the DELAY!

  • Using delay() to control timing is probably one of the very first things you learned when experimenting with the Arduino. Timing with delay() is simple and straightforward, but it does cause problems down the road when you want to add additional functionality. The problem is that delay() is a "busy wait" that monopolizes the processor.

  • During a delay() call, you can’t respond to inputs, you can't process any data and you can’t change any outputs. Delay() ties up 100% of the processor. So, if any part of your code uses a delay(), everything else is dead in the water for the duration.

What else can PWM do?

  • PWM also works well to control the speed of a motor.
    • However now we need to consider whether our motor is compatible with our GPIO output "levels".

Interlude: Ohm's Law!

GPIO outputs: Voltage and current

  • When used as outputs, two things must be considered: the voltage and the current. Our ESP32 can deliver 3.3v, and at most 12 or 28mA (250mA maximum for all channels - according to Adafruit).
  • The voltage is determined by the source, but the current is determined by whatever we’re trying to control. In the case of LEDs, they only need 20 mA or less. The motor we have might take more than 40 mA. In the worst case, when it’s stalled, it might want a 200 mA.
  • The important thing to realize is that the microcontroller does not have the ability to limit this current. It will try to deliver whatever is asked of it, even if it overheats and damages itself.
  • If we want to control a device that might take more than 40 mA, we have to use an intermediary.

Controlling large loads with a transistor

The transistor is like a bicycle gear: you control it with a small amount of current, and it in turn can control a lot more current. The transistor also allows us to use a higher voltage than the 3.3V the ESP32 can deliver.

Use a transistor to control a higher current for a motor.

  • There are hundreds of transisors that will work for this application.
    • here are a few that I commonly use:
    • TIP120 - Darlington sold by Adafruit
    • IRF520
    • IRF8721 - MOSFET sold by Adafruit
  • never assume the pinout of a transistor or IC.
    • ALWAYS look up the pinout before applying power.
      • or else 爆炸

CircuitExample

You can test this with any of the code above for driving an LED, replacing the LED with the motor and transistor circuit.

It's important to note that we are now using a separate power source for the motor. There are good reasons for doing so...

References:

More to explore

  • Arduino Language Reference

  • Interfacing with Hardware

  • Interfacing with Hardware

  • Joining inputs and outputs: switch controls speed, switch choses between two brightness levels, thermistor or other sensor changes behavior, etc.

  • Multiple output devices: play melody while controlling motor speed, etc.

  • Boolean logic, tests, and conditionals

  • Making sounds 

Interfacing with Processing

Resources!!!

About

ESP32 tutorial for Art 385

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published