Skip to content

MayushKumar/envisage-microcontrollers

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 

Repository files navigation

Envisage 12.0 - Microcontrollers Module

What even is a microcontroller?

A microcontroller is basically a small computer, whose main job is to control electronics. Just like your normal computers, it has a CPU, some RAM and some flash memory to store your program. It also has programmable IO (Input/Ouput) pins. These pins are what helps them ‘control’ your electronics. There are tons of microcontrollers available in the market. The most popular one being the Arduino UNO. Now just to clarify, Arduino UNO is not actually the microcontroller, rather, it is just a ‘development board’ built around the ATmega328P microcontroller. Development boards make it easy for us to work with microcontrollers, as they have additional circuits designed to help run and program them.

imgs/arduino-uno.jpg

Setup

Arduino IDE

The Arduino IDE is the most common program that you will be using while working with an Arduino (and many other microcontrollers). You can download it from here.

Tinkercad

We will be using Tinkercad throughout this module for easy simulations. Go here and make an account if you don’t have one already.

Blink Blink!

Let’s start with the ‘Hello World’ of microcontrollers, ie, blinking an LED. Go to this example. Click on ‘Tinker this’ and then ‘Start Simulation’. Click on ‘Code’ to see the magic behind all of it. As you can see, the code is made up of two ‘functions’, namely void setup() and void loop(). The important part:

  • void setup() : Runs once at the start.
  • void loop() : Obviously, keeps running in a loop.

Now, a very important reference image:

imgs/arduino_uno3_pinout.png I would suggest you to always keep this handy while working with your Arduino UNO. Each pin on your microcontroller serves a purpose, and majority of them, can be used in a variety of ways. As you can see in the image, D8 is our pin number 8, which has been marked as a Digital Pin, which means you can turn it HIGH or LOW. Now, as Arduino UNO runs on 5V:

  • HIGH / ON means 5V
  • LOW / OFF means Ground

Before you start using a pin, you need set the mode of the pin to tell the microcontroller how you intend on using it.

void setup()
{
  pinMode(8, OUTPUT);
}

This, at the start, sets the mode of pin 8 to OUTPUT, ie, you can turn it on or off.

void loop()
{
  digitalWrite(8, HIGH);
  delay(1000);
  digitalWrite(8, LOW);
  delay(1000);
}

This first turns the pin 8 HIGH and then waits for 1000 miliseconds, ie, 1 second. Then it turns the pin LOW and again waits 1 second. After that, the cycle continues indefinitely, and we get a blinking LED! (Notice that we have a current limiting resistor in series with our LED so that it does not burn up).

Controlling the brightness (PWM)

Let’s try to vary the brightness of the LED. Arduino UNO doesn’t have a Digtal-to-Analog Converter (DAC), so we cannot get a true analog output. Look up the difference between digital and analog if you do not know. Arduino UNO can produce a PWM signal, which in most cases can be used as an alternative to true analog output. Pins that support PWM output are marked with a tilde (~) before their number. Looking at the pinout diagram, we see that pin 6 is one of such pins. Look at this simulation.

#define LED_PIN 6

byte brightness = 0;

The first line basically means - “replace every occurence of LED_PIN with the number 6.” Next, we define a variable of the type byte, and initialize it to zero. Go here to see all the datatypes available to you. As you can see from the documentation, a byte stores values from 0 to 255.

void setup()
{
  pinMode(LED_PIN, OUTPUT);
}

This is the same as before.

void loop()
{
  analogWrite(LED_PIN, brightness);
  delay(10);
  brightness++;
}

Now, for the analogWrite function, a value of 0 corresponds to a PWM signal with 0% duty cycle (ie completely off) and it linearly goes up to 255, which corresponds to a PWM signal with 100% duty cycle (ie fully on). The last line simply means ‘add 1 to the brightness variable’.

As a result, the brightness of the LED increases with time. Note that brightness suddenly drops to zero. This is due to something called the ‘Integer Overflow’. Basically, when the value of brightness is 255, and we try to add 1 to it, the result comes out to be 256, but as a byte can only store values upto 255, it loops around to 0. Therefore, the value of brightness becomes 0, and hence the LED also turns off momentarily. Then the cycle continues.

Taking Input

Let’s say you want to toggle the LED using a push button. When you press the push button once, the LED turns on, and when you push it again, it turns off. Take a look at this simulation. Try to push the button a few times.

#define LED_PIN 4
#define BUTTON_PIN 2

void setup()
{
  pinMode(LED_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT);
}

General setup. Note that the pinMode of BUTTON_PIN has been set to INPUT.

bool led_state = false;
bool prev_button_state = false;

We create two variables of type bool (check the official reference provided earlier if you don’t know what that means).

void loop()
{
  bool button_state = !digitalRead(BUTTON_PIN);
  if(prev_button_state == false && button_state == true)
  {
    led_state = !led_state;
    digitalWrite(LED_PIN, led_state);
  }
  prev_button_state = button_state;
}

OK, we have a lot going on here. So first we use the digitalRead function to read the state of the button. The function returns true (or 1) if the BUTTON_PIN is connected to 5V, and false (or 0) if it is connected to ground. Note that when we press the button, the pin gets connected to ground, whereas by default it is connected to 5V (using the pull-up resistor). As this would give us false when we press the button, we have added an exclamation mark in front of the function call, which simply inverts the output. Therefore, now when we press the button, button_state will be set to true.

prev_button_state corresponds to the state of the button during the previous iteration of the loop. button_state corresponds to the current state. We set prev_button_state equal to button_state at the end of the loop.

Now, if the previous state of the button was false (unpressed), but now is true (pressed), we have detected a button press. Then, we toggle the led_state variable (set to its opposite using the exclamation mark). Then we write the led_state to LED_PIN. As you can see, you can use true / false instead of HIGH / LOW. HIGH is basically the number 1 and LOW is the number 0. You can use any non-zero number for the HIGH state, as anything non-zero is true, whereas zero is false.

Note that we can remove the pull-up resistor as Arduino also comes with a builtin one. To use the builtin pull-up resistor, set the pinMode of BUTTON_PIN to INPUT_PULLUP. Go here to learn about floating-pins and pull-up/pull-down resistors.

Analog Input

What we saw previously was an example of digital input. It can have only two states - on or off. Now we’ll look at analog input. Let’s control the speed of blinking of an LED using a dial. We use a potentiometer as the dial. Here is the simulation. The code, now should be self-explanatory.

Talking to your Arduino

Let’s send and receive messages from our Arduino. There are a number of communication protocols popular in the world of microcontrollers, such as UART, I2C, SPI, etc. Arduino uses UART (generally called serial communication) to talk to your system. Go to this simulation. Go to the code section and click on the ‘Serial Monitor’ below. Now, enter values from 0 to 255 to change the brightness of the LED. You will also see those values printed back to you.

#define LED_PIN 9

void setup()
{
  pinMode(LED_PIN, OUTPUT);
  Serial.begin(9600);
  Serial.setTimeout(10);
}

Serial.begin function begins the serial communication at a certain baud-rate (9600 in this case). You can learn about baud-rate online, but in general, it’s good enough to know that the baud-rate of your Arduino and that of you serial monitor should match (you have to choose a baud-rate in the Arduino IDE). Our serial monitor sends data to the Arduino sequentially. Therefore, we need to set a timeout for the Arduino to know that it can safely end the interpretation of the bytes. It is necessary only for the functions that parse the incoming bytes to a value (such as parseFloat and parseInt).

byte brightness = 0;

void loop()
{
  if(Serial.available() > 0)
  {
     brightness = Serial.parseInt();
     Serial.println(brightness);
     analogWrite(LED_PIN, brightness);
  }
}

if Serial.available is greater than 0, it means that we have received some input. Then we parse the input stream (which is in form of bytes) into an integer, and store it in our brightness value. Using Serial.println, we print the value back to the user. Then, we simply set the brightness of the LED.

I highly suggest you to go through the official documentation of the serial communication here to learn about all the different functions available to you. Also, you can look up a tutorial about this.

Additional References

Everything till now has just given you an idea of what using a microcontroller looks like. Here are some links that will help you move forward in your journey of microcontrollers.

Other Microcontrollers

Arduino UNO, although being very popular, is not the perfect fit for every project. There are tons of other microcontrollers that you should consider. Most important in our case would be the esp32. It has a faster processor, and builtin wifi and bluetooth support, being cheap at the same time. Be sure to take a look at it, as it is probably the microcontroller you would be using in your projects. Other microcontrollers are the Arduino Mega, Arduino Nano, etc.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published