Category:

PWM and PWM on the Arduino

October 4, 2016 in Electronics

The concept of Pulse-Width Modulation (PWM) is simple: the ratio of “highs” to “lows” in a stream of high-low pulses can produce an analog effect through the digital signal!  This is useful, because this means one can control an analog value, such as the brightness of an LED or the speed of a motor, through the analog value time, without having to adjust the voltage supplied to that component.  Essentially, this makes a PWM signal both digital and analog—the signal only has two states, high and low, which makes it digital, yet at the same time, the time duration of the high pulses in the signal is an analog value, as it can have many distinct values.  In this tutorial, I’ll first cover some of the basics of the theory behind PWM, and will then introduce you to PWM implementation on the Arduino!

 

Let’s turn to the simple example of an LED.  If I wanted to dim the LED, I could simply reduce the voltage across it using a potentiometer or resistor voltage divider.  

 

[siteorigin_widget class=”SiteOrigin_Widget_Image_Widget”][/siteorigin_widget]

Alternatively, however, I could represent this lower voltage digitally by pulsing the LED on and off extremely quickly at a specified rate—the LED would appear to be dimmer because in a given time interval it is not on 100% of the time, yet it would appear to be still (not flashing) because of the rapidity of the pulsing. This is the idea of PWM. One can switch a signal rapidly so that it is on for a specific percentage of the time interval to give an “average voltage” effect. Note that there are quotes around average voltage because no actual voltage modulation occurs! PWM is extremely convenient in many situations because it is much simpler to implement than such a method of changing voltages through electronics.

 

Individuals who explore PWM signaling often encounter the term duty cycle. Duty Cycle is expressed as a percentage that indicates the proportion of a given period of time in which the PWM signal is high. This means that in a ten-second time interval, a PWM signal with a duty cycle of 20% is only on for two of those ten seconds. This does not mean, however, that the signal is high for the first two seconds and low for the remaining time. Instead, the two second time period during which the signal is high is distributed evenly over the ten seconds. This distribution depends on the modulating frequency of the PWM signal, the number of on-off cycles the signal undergoes in a second.

 

Here’s an illustration of duty cycles with a 5V digital signal.

[siteorigin_widget class=”SiteOrigin_Widget_Image_Widget”][/siteorigin_widget]

Note that the percentage of a clock cycle spent in the high state is equal to the duty cycle percentage.

 

Now we can focus on PWM implementation on the Arduino! Let’s look at the LED example from above. By wiring the LED up to an analog out or PWM pin on the Arduino and calling the analogWrite function, we can control the brightness of the LED! That’s right! So-called “Analog” pins on the Arduino actually use PWM to send signals representing “voltages” between 0V and 5V.

 

On the hardware side, the only connection between the Arduino and the LED would be to an Analog Out or Digital/PWM pin and to Ground. Digital/PWM pins on the Arduino are indicated by “~” before their pin numbers. On an Arduino Uno, the Digital/PWM pins are 3,5,6,9,10, and 11.

[siteorigin_widget class=”SiteOrigin_Widget_Image_Widget”][/siteorigin_widget]

Inside void loop(), we can then call the analogWrite method with a corresponding integer value between 0 and 255 to represent the brightness of the LED. This would mean that analogWrite(0) is a 0% duty cycle on the output signal (the LED is off), analogWrite(125) is a 50% duty cycle (the LED is half of its maximum brightness), and analogWrite(255) is a 100% duty cycle (the LED is at its maximum brightness).

 

The output signal is actually causing the LED to pulse at a very high frequency that makes individual pulses indiscernible. Therefore we do not see a flashing LED, but merely see it as dimmer or brighter when the duty cycle is modified. We can apply this concept to motor speed control as well. Here’s the setup for controlling the speed of a dc motor.

[siteorigin_widget class=”SiteOrigin_Widget_Image_Widget”][/siteorigin_widget]

The PWM signal is transmitted from the Arduino’s Digital/PWM Pin 9 to the base pin of the transistor. The transistor switches at the same rate as the PWM signal does, thereby driving the motor at the duty cycle of the PWM signal! Just like the LED, the motor is actually switching on and off at thousands of time per second, but it appears and acts as if it is in continuous motion because it is switching at such a high rate.

 

The capacitor and diode in the motor-control circuit are necessary to assist in sudden on-to-off switching of the motor. When suddenly switched off, motors can generate an enormous back-voltage that can cause damage to other electronics. In conjunction, the diode and capacitor prevent any damaging voltage spikes.

 

Finally, it is important to note that the analogWrite function should not directly be used to control servos or electronic speed controllers (ESC) through PWM. This is because the frequency at which these devices expect PWM signals is much lower than the frequency of the analogWrite-generated PWM signal. Arduino provides a great library called Servo to control Servos and ESCs. We’ll cover the Servo library in a coming tutorial!

 

Courtesy to Fritzing and Arduino for the images used in this article.

Interfacing the Arduino with Custom Circuits

August 22, 2016 in Electronics

The Arduino is a powerful development platform for hobbyists of all skill levels, as it allows any user to bring a project to life with just the Arduino board, a few key components, and some code.  The whole Arduino platform is built around the idea that it should always make projects easier to build and develop, yet inevitably, the hardest part of bringing Arduino projects to life is interfacing the Arduino with sensors and custom circuitry—how does one make the Arduino communicate and interact with these external electronics?  In this tutorial, I hope to introduce different ways to connect the Arduino to offboard sensors and electronic devices and explain the basics of communication between the Arduino and these devices.  

 

Before we dive into how the Arduino can communicate with other devices, we should first understand a microcontroller’s “input” and “output” pins and their functions.  Input pins are ports on the microcontroller that are specified to be listened to for data.  Output pins, on the other hand, are ports on the microcontroller that are specified for the microcontroller to write data to.  Input and Output pins on the Arduino come in two types: Digital and Analog, depending on the type of signal they send or receive.  

The Arduino’s Digital Pins (boxed in Red) and Analog Pins (boxed in Yellow).
The Arduino’s Digital Pins (boxed in Red) and Analog Pins (boxed in Yellow).

Digital pins have two states, “high” (a binary 1 represented by 5V at the pin) and “low” (a binary 0 represented by 0V at the pin).  This means that a digital pin can only be interpreted as being in one of these two states.  A simple example of Digital Pin manipulation is the “Blink” Arduino sketch, in which the Arduino pulses an LED at a given time interval.  The code and hardware for the “Blink” example is shown here:

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


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

The LED’s anode is connected to Digital Pin 13, and its cathode is connected to Ground (GND). (Note that a current-limiting resistor is not necessary because the Arduino’s Digital Pin 13 already has a built-in resistor.)
The LED’s anode is connected to Digital Pin 13, and its cathode is connected to Ground (GND). Note that a current-limiting resistor is not necessary because the Arduino’s Digital Pin 13 already has a built-in resistor.

The LED is connected to Digital Pin 13, and digital “high” and “low” signals are represented as 5V and 0V at Pin 13 respectively.  When the Arduino sets the pin to “high,” current flows out at 5 Volts through the LED and to ground.  When the Arduino then sets the pin to “low,” 0V (no current) flows in the circuit.  To configure a digital pin as either input or output, one must use the pinMode method in void setup() as such: pinMode(int pin, INPUT) or pinMode(int pin, OUTPUT), where int pin is the integer number of the digital pin being defined.  In the “Blink” example, Digital Pin 13 is set up as an output by the method call “pinMode (13, OUTPUT);”  To then set the value of a digital pin to HIGH or LOW, Arduino provides the digitalWrite method, which can be used as “digitalWrite(int pin, HIGH)”; or “digitalWrite(int pin, LOW)”; to drive the pin high or low respectively.


Analog pins are slightly more complicated, as they are not limited to two on/off states.  Instead, signals at Analog pins vary anywhere between 0V and 5V and are accordingly interpreted by the Arduino.  In the Arduino documentation website’s own words, the Arduino will “map input voltages between 0 and 5 volts into integer values between 0 and 1023.”  This means that through some nifty programming, the Arduino can be made to recognize the strength of an incoming signal (the interpreted integer value) and react accordingly.  An example of reading an Analog signal may be determining the amount of sunlight present in a room using a photoresistor to accordingly light up or turn off an LED lamp when the room is too dark or too bright.

 

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


void loop() {
int lightLevel = analogRead(3);
delay(100);
if (lightLevel < 20) { //20 is an arbitrary threshold to turn on LED
digitalWrite(13, HIGH);
}
else {
digitalWrite(13, LOW);
}
}

The output voltage from the photoresistor-resistor pair voltage divider is an analog input translated by the Arduino as an integer value between 0 and 1023.
The output voltage from the photoresistor-resistor pair voltage divider is an analog input translated by the Arduino as an integer value between 0 and 1023.

The intensity of light is translated by the photoresistor-resistor voltage divider as a voltage between 0V and 5V, which is then interpreted by the Arduino through an Analog input pin.  The Arduino then sends an appropriate Digital signal (HIGH if the integer value from the Analog input is less than the threshold value, or LOW otherwise) through a Digital pin configured as an output to the connected LED.

 

Before I move on to the different ways the Arduino can communicate with attached devices, I first want to cover one of the most fundamental aspects of designing circuits that interface with the Arduino: the use of current-limiting resistors.  The current-limiting resistor is not a staple in all Arduino projectsthere are many devices and circuits that do not require the use of such setupsyet it plays an important role when the Arduino is connected to small components and electronics that can be damaged by overcurrent. 

 

It is at this point that many get confused by the different electrical terms thrown around by hobbyists, primarily Current versus Voltage.  Current, expressed in units called Amperes, is the actual flow of electrons through a closed circuit.  One can think of Current as how quickly electrons flow through a closed circuit from one end of a power source to another. Voltage, quantified in units called Volts, is the potential difference created chemically or by other means in the power supply that will cause an electrical current to flow through a conductor when a circuit is closed.  To protect electronic components from damage, we have to reduce the current—the amount of electrons—flowing through through the component, so that the current does not exceed the maximum ratings of the components.  

image05

At any known voltage—let’s say 5V in this example, because the Arduino’s output pins run at 5V—we can see from Ohm’s law, Voltage = Current * Resistance, that large amounts of current can flow through the components because of little to no resistance (hindering of the flow of charge) in the circuit. We must therefore use an electronic component called a resistor to provide resistance in the circuit and reduce the current that flows through our components. To calculate the value of resistance needed (the value of the resistor) based on the known voltage and maximum current allowable, we can use Ohm’s law again, this time in the form Resistance = Voltage / Current. Always use a current-limiting resistor when connecting external components to the Arduino.

 

Here’s a hardware example of using current-limiting resistors with components connected to an Arduino:

image02

Now that we’ve covered the basic overview of the Arduino’s onboard hardware and connection points, we can now go over the actual communication between the Arduino and external electronics, sensors, and more. Since we’ve covered the basics of Digital and Analog input/output on the Arduino, we’ll now focus on interfacing the Arduino with more complicated electronics such as sensors, peripheral devices, and communication electronics. This may involve using either communication protocols such as Serial or control methods such as PWM.

 

The first communication protocol on the Arduino introduced to users is Serial Communication (“Serial” for short). It is the way the Arduino communicates with the user’s computer via USB connection, and can be a way by which the Arduino can communicate with peripheral electronics as well. Serial is a simple communication protocol to implement because its implementation only requires one Transmitting (TX) and one Receiving (RX) line (essentially just two wires) connected between the Arduino and the peripheral device. On the Arduino, Digital Pin 0 can be used as the RX pin, and Digital Pin 1 can be used as the TX pin. Wires connected to these two pins can be attached on the other end to another circuit board or even another Arduino, but it is important to remember that the RX line for one device will become the TX line for the other (the two wires will be connected to an RX pin on one and and a TX pin on the other).

Arduino connected to XBee via serial
An example of wiring the Arduino to communicate via Serial with an XBEE RF module.

We can now focus on the software implementation of Serial on the Arduino.  Arduino provides a “Serial” library to implement communication over the default Serial pins (Digital Pins 0 and 1) and a “Software Serial” library to define and use two other Digital as Serial RX/TX pins.  For a detailed overview of the Serial library visit https://www.arduino.cc/en/Reference/Serial. Some basic functions that will almost always be used in the software include the following:

  • Serial.begin, which initializes communication at a specified integer baud rate (a measurement of signal transmission speed) in the void setup method
  • Serial.print and Serial.println, which print data to the Serial Monitor in the Arduino IDE
  • Serial.write and Serial.read, which write and read byte data over the TX/RX lines respectively
  • Serial.available(), which returns the number of bytes available to read over the serial connection

Here’s some code for communicating over an XBEE module connected to the Arduino’s Digital Pins 0 and 1.  In this example, the Arduino sends 1 or 0 over Serial to the XBEE module, which will then transfer that data to another paired module and in-turn to another Arduino.

 

//sending (Arduino 1)
void setup() {
Serial.begin(9600);
}


void loop() {
Serial.write(1);
delay(1000);
Serial.write(0);
delay(1000);
}


//receiving (Arduino 2)
void setup() {
Serial.begin(9600);
}


void loop() {
if (Serial.available() > 0) {
int data = Serial.read();
if (data==1) {
digitalWrite(13, HIGH);
}
else {
digitalWrite(13, LOW);
}
}
}

 

Now that you’ve read through this tutorial on the basics of using an Arduino with other components and/or custom circuits, you can start developing your own simple Arduino projects based on the principles of Digital/Analog inputs and outputs and on Serial communication! In the next tutorial, I’ll introduce the I2C protocol, using pull-up and pull-down resistors on digital inputs where appropriate, and how to use the Arduino to control motors through Pulse-Width Modulation (PWM)!

 

Courtesy to Fritzing and Arduino for the images used in this article.

Introduction to the Atmel SAMD21 Microcontroller

July 26, 2016 in Electronics

The SAMD21 series of microcontrollers are based on the ARM Cortex®-M0+ 32-bit processor. It operates at up to 48 MHz and comes with up to 256 KiloBytes of programmable flash. At Zippy Robotics, I’ve used the SAM4S MCU to control several prototypes of our PCB milling machine, Prometheus. However, I’m evaluating the SAMD21 as a replacement for this role and I thought I’d share some information that you might find useful as you think about your own projects.

In Atmel Studio 7, you'll find that 238 example projects are available for the SAM D21 Xplained Pro board. Nice!

238 example projects are available for the SAM D21 Xplained Pro board!

The SAMD21 has several things going for it – it’s cheaper than Atmel’s other ARM cores like the SAM4S, there is a wealth of information and documentation for it (both by Atmel and third parties), and it is very well supported in Atmel Studio with example projects. There are currently 238 example projects for Atmel’s SAMD21 Xplained Pro evaluation kit. The value from the example projects cannot be overstated – combined with the Xplained Pro board, they get you up and running in no time. Additionally, if you’re a fan of Arduino, you can develop your Arduino code for the Arduino Zero board which uses the SAMD21 MCU. You can also find Arduino-compatible boards based on the SAMD21 from companies like SparkFun and Adafruit.

Program your SAM D21 Xplained Pro Evaluation Kit

This part requires that you have your own SAM D21 Xplained Pro evaluation kit so you can follow along. You’ll also need a USB cable (A to micro B); it’s not included with the evaluation kit. If you haven’t done so already, download and install Atmel Studio.

 

Open Atmel Studio and connect the Xplained Pro board to your PC via USB. The board has two USB ports; one is labeled “DEBUG USB”, which is for debugging and programming with Atmel Studio, and the other is labeled “TARGET USB” and can be used if you’re developing USB applications. In this case, we’re just programming the board, so plug the USB cable into DEBUG USB. Atmel Studio should recognize the board and may prompt you that board’s firmware is out of date. If that happens, update it before doing anything else by following the instructions Atmel Studio gives you.

 

When you’re ready, go to the menu bar and click File > New > Project. From the popup that appears, select “GCC C ASF Board Project”, give it a name if you’d like, and click OK. Next, you’ll be prompted to select the board. We need to find the SAM D21 Xplained Pro board from the list. One way to do this is to click the “Select By Device” radio button and then type “SAMD21J18” into the search box. The list will filter and you can then find and select “SAM D21 Xplained Pro – ATSAMD21J18A”. Then click OK and Atmel Studio will create the project.

new projboard selection

On the right you’ll see a panel labeled “Solution Explorer”. Navigate to “src > main.c” and double-click main.c to open it. We see the Atmel Studio has already created some skeleton code for us that we can modify. For the purpose of this tutorial, we won’t modify it – we just want to get the default sample code onto the SAM D21’s program memory. If we look at the comments and read the code, we can see that this sample code that Atmel Studio has created for us just turns on LED0 whenever we press Button 0, which is actually labeled “SW0” on the board for “switch 0”. To program the board with our simple firmware, all we have to do is click the green play button. This is the “start without debugging” option and it will program the SAM D21 and then it will immediately begin executing it’s code.

open main

Open “main.c”, found here.

initial code marked up

Once you click “start without debugging”, you will see the Output console pop up and eventually say “Build Succeeded” because the code is valid. If instead there were compilation errors, you would see those instead.

What you should see after pressing the play button.

If your project compiled successfully and you see “Ready” on the lower-left corner of the screen, you can now test your code. Push the SW0 button and you should see LED0 illuminate. Release it, and LED0 will go out. That’s it! Simple. Now you can write your own code to suit your needs. We’ll explore some more simple programming and the ASF (Atmel Software Framework) in future tutorials.