Archive | Arduino RSS feed for this section

Servo Motors with Two-Axis Joystick Control

This project makes use of two servos (Tiankongrc MG995), servo mounting brackets a 2-axis thumb joystick, an active buzzer, and an Arduino Uno R3. To operate the two servos together it is necessary to mount them perpendicular to each other. Where one servo moves along 180 degrees horizontally (x-axis) and the other moves 180 degrees vertically (y-axis). While the joystick VRx, VRy, and SW terminals are read by the Arduino through its GPIO pins, their coordinates are interpreted and sent to each servo for positioning. Either by a single manual motion event or as movement continuously read at the servos to rotate from one position to the next.

Two servos, 2-axis thumb joystick, active buzzer, and an Arduino Uno R3.

The active buzzer sounds when the joystick is depressed. It acts as a toggle to represent a select function that corresponds to typical X,Y positioning at a specific point along its movement.

Rotational Movement Control with the Thumb Joystick.

Project Schematic:

Through pulse width modulation pin connections on the Arduino, simultaneously movement control is achieved at both servos. Along with voltage and ground connections shared with the joystick, separate analog connections are terminated for analogRead instructions at the Arduino controller.

Dual X & Y servos with a 2-axis thumb joystick makes use of both PWM and analog input pins.

Project Review:

This video demonstrates the servo motor’s range of motion and precise positioning as the joystick is controlled with its push-button switch.


Code Example:

#include <Servo.h>
Servo Xservo;
Servo Yservo;

int Xpin=A0;
int Ypin=A1;
int Spin=2;
int XSpin=9;
int YSpin=10;
int buzzPin=7;
int WVx;
int WVy;
int Xval;
int Yval;
int Sval;
int dt=200;

void setup()
{
Serial.begin(9600);
pinMode(Xpin,INPUT);
pinMode(Ypin,INPUT);
pinMode(Spin,INPUT);
pinMode(XSpin,OUTPUT);
pinMode(YSpin,OUTPUT);
pinMode(buzzPin,OUTPUT);

Xservo.attach(XSpin);
Yservo.attach(YSpin);

digitalWrite(Spin,HIGH);
}

void loop() {
Xval=analogRead(Xpin);
WVx=(180./1023.)Xval; Yval=analogRead(Ypin); WVy=(180./1023.)Yval;
Sval=digitalRead(Spin);

Xservo.write(WVx);
Yservo.write(WVy);

if (Sval==0)
{
digitalWrite(buzzPin, HIGH);
}
else
{
digitalWrite(buzzPin, LOW);
}

delay(dt);
Serial.print(“X Value = “);
Serial.print(Xval);
Serial.print(” Y Value = “);
Serial.print(Yval);
Serial.print(” Switch State is “);
Serial.println(Sval);
}


Stepper Motor with Direction Control & Reversal

This project involved a 5VDC stepper motor and its corresponding ULN2003 driver assembly. Stepper motors are unique from servos or DC motors because they are very precise, have a full range of motion, and they can produce a lot of torque. This specific motor permits 2048 steps according to its specifications, so each step represents a high level of rotational movement granularity in a small package. –The purpose of the system is to evaluate a simple stepper motor along with its driver assembly to understand their behavior, limitations, and performance characteristics.

The normally closed micro-switch provides a toggle for the stepper motor shaft to move in either a forward or reverse direction. Directionality is set by a code condition determined by the toggle switch transition states whereas the switch is depressed to activate a change of direction opposite the prior rotational motion. Programmatically, the rotational speed is set to about 10 RPM in this project, but speeds are assigned slower as desired.

ULN2003 Assembly with Motor and Arduino connections.

Stepper motors are found among many applications today. They allow for precision movement and control of hardware throughout various industries, households, or personal devices. They open lids, doors, and windows. They drive gears to rotate lamps, sensors, cameras, and so forth. The use-cases of stepper motors are very wide-spread.

The ULN2003 IC chip located on this assembly is really an array of Darlington pairs that drive up to 500mA at 50VDC. As a current boost is produced from the second Darlington transistor staged after the first of its pair, sufficient current capacity is presented to the terminals of the assembly that hosts the ULN2003. This assembly provides for input and output connections between the stepper motor and an Arduino unit along with LEDs and voltage supply terminals.

Each LED on the ULN2003 indicates the step activity of all four stators. Notice that each stator is in a fixed position with coil wrapping. As each coil is charged on and off, the motor shaft rotates a single step.

The internal workings of the stepper motor convert electrical energy (5VDC in this case) to mechanical movement. In an incremental fashion, all four coils in a fixed position advance the internal rotation in clockwise or counter-clockwise steps (depending upon motor capability). The shaft assembly that extends outside of the motor enclosure provides for a mechanical attachment to get practical use of the stepper motor.

The 28BYJ-48 stepper motor and its ULN2003 driver assembly are separately powered from the Arduino UNO R3 host. Stepper motors draw extra high current to require more power than what an Arduino can support. So this motor runs from a separate wall adapter that delivers 5VDC at 3.5A (~18W).

It is because of this higher motor current requirement that the Darlington pair boost is provided through the ULN2003 assembly. So it is necessary to recognize that motors must be matched with a corresponding driver board that includes a suitable current capacity along with the appropriate types of input and output terminations matched to the motor. Normally, stepper motors have four wires for driver connectivity.

Project Schematic:

The ULN2003 driver hosts a ULN2003 IC chip that terminates to a 28BYJ-48 stepper motor since it is matched to the motor’s operating requirements.

Project Review:

This video demonstrates the stepper motor’s direction of rotation as the pushbutton switch is toggled.


Arduino IDE:

Code Setup:

#include <Stepper.h>
int stepsPerRevolution=2048; //get this step count from the spec sheet
int motSpeed=10; //10 RPM
int dt=500;

int buttonPin=2;
int motDir=1; //variable to keep track direction of motor shaft
int buttonValNew; //present state of the button switch
int buttonValOld=1; //prior state of the button switch initiated as 1 (not pressed)

Stepper myStepper(stepsPerRevolution, 8,10,9,11);
//the numbers are the pin sequence for a specific driver and specific motor connected in a specific way

void setup() {
Serial.begin(9600);
myStepper.setSpeed(motSpeed);
pinMode(buttonPin,INPUT);
digitalWrite(buttonPin,HIGH); //puts a pullup high state onto the button pin
}

void loop() {
buttonValNew=digitalRead(buttonPin);
if (buttonValOld==1 && buttonValNew==0){
motDir=motDir(-1); } //button transition (1,0) sets condition for motor direction change buttonValOld=buttonValNew; myStepper.step(motDir1);

}


Tilt Switch with LED Indicator and Fan Interrupt

This project was about making a tilt sense system that involves a motor or fan. The system is also programmed and set up with a tip sense light. It simulates a tip-over or roll-over situation and when the system reaches a 90-degree angle from level. At 90 degrees, the sensor drive signal shuts everything down through the Nano. It also has industrial applications as there are different tilt switches at different angles.

Tilt detection system that senses motion up to a 90 degree angle before motor or fan cut-off. The green LED indicator represents a normal state. While the red LED illumination represents an abnormal state when the system tilts 90 degrees or more.

Normal state of operation with function fan or motor.

Abnormal state of operation with fan interrupted.

Project Schematic:

The system requires separate power supplies to support a higher current draw motor or fan unless the entire system provides for sufficient power or current draw. Motors and fans normally draw much more current that the controller or sensor devices hosted within its system.

A tilt switch is really just a type of motion sensor that activates after a certain angle from a reference point is reached. Among various approaches toward level detection and sensor motion, this project uses a canister tilt switch that uses a small internal ball that interrupts a closed switch path as it is rolled from one position to another at the component’s specified angle.

At the specified angle, the tilt switch path is open and no further connection between its leads is permitted. For example, in a level state, a tilt device’s upright position settles an internal miniature metal ball for a closed switch path (or “on” function). Conversely, when the position tips beyond its specified angle, the internal metal ball moves to another position where the connection path between the two switch leads become interrupted (or “off” function).

Tilt switch canister with two leads and internal unseen miniature ball.

Project Operation:

The demonstration of this system zooms in on the states of LED illumination and fan movement as its position changes from level (0-degrees) to upright (90-degrees).


Code Setup:

int speedPin=5;
int dir1=4;
int dir2=3;
int mSpeed=255;
int tiltPin=2;
int tiltVal;

int redPin=7;
int greenPin=6;

void setup() {
Serial.begin(9600);
pinMode(speedPin,OUTPUT);
pinMode(dir1,OUTPUT);
pinMode(dir2,OUTPUT);
pinMode(tiltPin,INPUT);
digitalWrite(tiltPin,HIGH); //to assign as pullup pin

pinMode(redPin,OUTPUT);
pinMode(greenPin,OUTPUT);
}

void loop() {
digitalWrite(dir1,LOW);
digitalWrite(dir2,HIGH);
tiltVal=digitalRead(tiltPin);
Serial.println(tiltVal);
if (tiltVal==0){
digitalWrite(greenPin,HIGH);
digitalWrite(redPin,LOW);
analogWrite(speedPin,mSpeed);
}
if (tiltVal==1){
digitalWrite(greenPin,LOW);
digitalWrite(redPin,HIGH);
analogWrite(speedPin,0);
}
}


Light Sensor Control of Servo with Photoresistor

This project makes use of a photoresistor as a light sensor to control the movement of a servo motor’s shaft. The change of position in the servo motor’s output shaft moves from 0 degrees to 180 degrees maximum depending upon the light intensity present at the photoresistor. The highest level of light places the output shaft arm to 0 degrees while the absence of light at the sensor moves the output shaft arm to about 180 degrees. The actual range of motion is limited to the quality of the servo, but 180 degrees is generally the limit.

All components in the system are powered by the Arduino Uno (R3) through the USB connection from a local supply or computer.

The purpose of the project is to demonstrate the simple use of a servo for the automatic positioning of a physical object as a function of light intensity. The light sensor is read at an analog GPIO pin to get continuously variable values to read into memory via an analogRead operation. The motor response to continuous analog read activity (with a small 250ms delay between each) is calculated to a PWM output level written to a port where the output shaft moves at a corresponding angle.

The micro servo mounts nicely onto the Arduino Uno in a secure way through the two standoffs on the controller. The various terminal connections in this photo correspond to the schematic diagram posted below.

The resistor is 5K-ohms with the analogRead connection between it and the photoresistor for active continuous input to the Arduino.

Project Operation:


Project Schematic:

Arduino IDE:

Servo Output Angle Calculations:

Code Setup:

#include <Servo.h>
int lightVal;
int lightPin=A4;
int dt=250;
int angle;
int servoPin=9;
int servoPos=165;
Servo myServo; //create object with a name

void setup() {
Serial.begin(9600);
myServo.attach(servoPin);
pinMode(lightPin,INPUT);
pinMode(servoPin,OUTPUT);
}

void loop() {
lightVal=analogRead(lightPin);
Serial.println(angle);
delay(dt);
angle=(-16./63.)*lightVal+(16.*780.)/63.;
myServo.write(angle);
}


Color and Light Control via Infrared Sensor

This project runs with an IR sensor that reads a remote control’s Hexadecimal data bursts as its buttons are selected. Each button represents a function that becomes executed programmatically within the Nano to affect the color and light intensity at the LED. As hex values are decoded into the Arduino Nano via the IR sensor, a conditional statement evaluates the decoded value held in memory. For each button selected, the conditional statement evaluates the hex value unique to each.

Functional Demonstration Video:

The video demonstrates a visual walkthrough of power on, off, color selection, and increase or decrease of each color brightness. Control is demonstrated through the remote control through the wireless communication made through infrared modulation of binary data decoded or translated into useful hex values for programming and operation.


Project Schematic:

The schematic diagram of the circuit is simple. The connections are defined as illustrated as power, ground, and pin-to-pin terminations are made. The RGB LED supported with three 330-ohm current limiting resistors, but this value can be adjusted higher as desired.

It is necessary to select PWM pins to connect the RGB LED as needed. Since values of 0 to 255 are applied to each red, green, and blue LED pin, varying levels of intensity are adjustable in programmatic increments or decrements. This is only possible through the use of PWM GPIO pins as indicated by the ~ mark on an Arduino unit or pin-out diagram. It is important to note that the <IRremote.h> library file ( version 2.2.3) is not compatible with the use of pins 3 and 11 for PWM operation.

The infrared sensor accepts HEX encoded pulse emissions from the remote control to instruct the Arduino Nano to combine red, green, and blue values to a single LED device. Each Nano pin produces pulse width modulation power to set mixed colors with up and down brightness for each color selected. The color palette possibilities with this project are very high.
The simplicity of the circuit is made possible through the use of the Nano controller, its processor, and GPIO interfaces.

Arduino IDE:

The IR sensor reads a remote control’s Hexadecimal data stream as its buttons are selected. Each button represents a function that becomes executed programmatically. As hex values are decoded into the Arduino Nano via the IR sensor, a conditional statement evaluates the decoded value held in memory. For each button selected, the conditional statement evaluates the hex value unique to each.

Code Setup:

#include <IRremote.h>
int IRpin=9;
IRrecv IR(IRpin);
decode_results cmd;
String myCom;

int rPin=6;
int gPin=10;
int bPin=5;

int rBright=255;
int gBright=255;
int bBright=255;

float dFact=1;

void setup()
{
Serial.begin(9600);
IR.enableIRIn();

pinMode(rPin,OUTPUT);
pinMode(gPin,OUTPUT);
pinMode(bPin,OUTPUT);
}

void loop() {
while (IR.decode(&cmd)==0){
}
delay(1000);
IR.resume();

if (cmd.value==0xFF6897){
myCom=”zero”;
Serial.println(myCom);
}
if (cmd.value==0xFF30CF){
myCom=”one”;
Serial.println(myCom);
}
if (cmd.value==0xFF18E7){
myCom=”two”;
Serial.println(myCom);
}
if (cmd.value==0xFF7A85){
myCom=”three”;
Serial.println(myCom);
}
if (cmd.value==0xFF10EF){
myCom=”four”;
Serial.println(myCom);
}
if (cmd.value==0xFF38C7){
myCom=”five”;
Serial.println(myCom);
}
if (cmd.value==0xFF5AA5){
myCom=”six”;
Serial.println(myCom);
}
if (cmd.value==0xFF42BD){
myCom=”seven”;
Serial.println(myCom);
}
if (cmd.value==0xFF4AB5){
myCom=”eight”;
Serial.println(myCom);
}
if (cmd.value==0xFF52AD){
myCom=”nine”;
Serial.println(myCom);
}
if (cmd.value==0xFFA25D){
myCom=”pwr”;
Serial.println(myCom);
}
if (cmd.value==0xFF629D){
myCom=”v+”;
Serial.println(myCom);
}
if (cmd.value==0xFFE21D){
myCom=”fun”;
Serial.println(myCom);
}
if (cmd.value==0xFF22DD){
myCom=”rew”;
Serial.println(myCom);
}
if (cmd.value==0xFF02FD){
myCom=”play”;
Serial.println(myCom);
}
if (cmd.value==0xFFC23D){
myCom=”ff”;
Serial.println(myCom);
}
if (cmd.value==0xFFE01F){
myCom=”dn”;
Serial.println(myCom);
}
if (cmd.value==0xFFA857){
myCom=”v-“;
Serial.println(myCom);
}
if (cmd.value==0xFF906F){
myCom=”up”;
Serial.println(myCom);
}
if (cmd.value==0xFF9867){
myCom=”eq”;
Serial.println(myCom);
}
if (cmd.value==0xFFB04F
){
myCom=”st”;
Serial.println(myCom);
}
if(myCom==”pwr”){
rBright=255;
gBright=255;
bBright=255;
dFact=1;
}

if(myCom==”fun”){
rBright=0;
gBright=0;
bBright=0;
dFact=0;
}
//white
if(myCom==”zero”){
rBright=255;
gBright=255;
bBright=255;
}
//red
if(myCom==”one”){
rBright=255;
gBright=0;
bBright=0;
}
//green
if(myCom==”two”){
rBright=0;
gBright=255;
bBright=0;
}
//blue
if(myCom==”three”){
rBright=0;
gBright=0;
bBright=255;
}
//cyan
if(myCom==”four”){
rBright=0;
gBright=255;
bBright=255;
}
//magenta
if(myCom==”five”){
rBright=255;
gBright=0;
bBright=150;
}
//yellow
if(myCom==”six”){
rBright=255;
gBright=255;
bBright=0;
}
if (myCom==”dn”){
dFact=dFact0.75; } if (myCom==”up”){ dFact=dFact1.3;
if (dFact>1){
dFact=1;
}
}
analogWrite(rPin,rBrightdFact); analogWrite(gPin,gBrightdFact);
analogWrite(bPin,bBright*dFact);
}


DC Motor Control via Infrared Sensor & Remote

This project accomplishes a few objectives. First, the use of a KY-022 Infrared sensor is incorporated for general familiarity. Second, the IR remote control emits HEX codes for each button pressed, so it is necessary to capture those HEX codes to map them to specific button IDs and functions later developed. Third, to integrate the motor control driver (L293D) with the Arduino Nano to control motor activity such as speed and direction.

The project is supplied by two separate power supplies. The Arduino Nano and IR sensor is powered by the USB connection while the motor driver is powered by the regulated +5VDC supply. The DC motor operates in both forward and reverse motion depending upon a positive or negative voltage presented by the driver. The higher the positive or negative voltage, the higher the speed. The lower the voltage presented from the driver, the lower the speed. The propeller mounted to the DC motor shaft is simply for ease of visibility.

The L293D motor driver interfaces with the Arduino Nano at a few pins. Specifically, forward and backward motor shaft direction (pin 2 & 7) and speed (pin 1). Code control of these GPIO pins is set up through digitalWrite operation for high/low binary direction assignment while the speed of the motor is set by an analogWrite instruction (from 0 to 255). The IR remote control provides for power on / off, forward or reverse direction, increase speed, and decrease speed. The capacitors bypassed at the motor connections are to filter noise that may appear from unwanted radiation conducted back into the system. These capacitors help to snub back EMF otherwise present throughout the circuit.



The Arduino Nano is programmed through the same USB port that powers it. The USB power and data connection to a local computer is not illustrated in this schematic as it is assumed. After programming the USB is detachable provided the Nano is powered by an alternate source such as a power bank, battery, or wall adapter. The connections throughout this system are illustrated for pin-to-pin connectivity between the motor driver, the Arduino Nano, the IR Sensor, and the DC motor.

Arduino Setup:

See the full code in text format below for copy and paste use.
Serial Monitor: During set up, it was necessary to set up a temporary remote control read operation through the IR sensor to get all of the HEX addresses emitted for each keypress. All button names were pressed to get their corresponding HEX values whereby the mapping is complete to assign button unique functions through conditional statements within the program.
Serial Monitor: To track actual IR sensor readings that correspond to motor activity, the Serial Monitor reports back what remote control button press activity occurs. In this example view, the down button is pressed repeatedly to slow motor speed, and the up button is pressed repeatedly to increase motor speed. The power on (pwr) and power off (func) events record the on/off activity of the motor through the IR remote control and its corresponding sensor.

Code Setup:


#include <IRremote.h>

int IRpin=9;
IRrecv IR(IRpin);
decode_results cmd;
String myCom;

int speedPin=5;
int dir1=4;
int dir2=3;
int mSpeed=205;

void setup() {
Serial.begin(9600);
IR.enableIRIn();

pinMode(speedPin,OUTPUT);
pinMode(dir1,OUTPUT);
pinMode(dir2,OUTPUT);
digitalWrite(dir1,HIGH);
digitalWrite(dir2,LOW);
}

void loop() {
while (IR.decode(&cmd)==0){
}

//Serial.println (cmd.value,HEX);
delay(1000);
IR.resume();

if (cmd.value==0xFF6897) {
myCom=”zero”;
Serial.println(myCom);
}
if (cmd.value==0xFF30CF) {
myCom=”one”;
Serial.println(myCom);
}
if (cmd.value==0xFF18E7) {
myCom=”two”;
Serial.println(myCom);
}
if (cmd.value==0xFF7A85) {
myCom=”three”;
Serial.println(myCom);
}
if (cmd.value==0xFF10EF) {
myCom=”four”;
Serial.println(myCom);
}
if (cmd.value==0xFF38C7) {
myCom=”five”;
Serial.println(myCom);
}
if (cmd.value==0xFF5AA5) {
myCom=”six”;
Serial.println(myCom);
}
if (cmd.value==0xFF42BD) {
myCom=”seven”;
Serial.println(myCom);
}
if (cmd.value==0xFF4AB5) {
myCom=”eight”;
Serial.println(myCom);
}
if (cmd.value==0xFF52AD) {
myCom=”nine”;
Serial.println(myCom);
}
if (cmd.value==0xFFA25D) {
myCom=”pwr”;
Serial.println(myCom);
}
if (cmd.value==0xFF629D) {
myCom=”v+”;
Serial.println(myCom);
}
if (cmd.value==0xFFA857) {
myCom=”v-“;
Serial.println(myCom);
}
if (cmd.value==0xFFE21D) {
myCom=”func”;
Serial.println(myCom);
}
if (cmd.value==0xFF22DD) {
myCom=”rwd”;
Serial.println(myCom);
}
if (cmd.value==0xFF02FD) {
myCom=”play”;
Serial.println(myCom);
}
if (cmd.value==0xFFC23D) {
myCom=”ff”;
Serial.println(myCom);
}
if (cmd.value==0xFFE01F) {
myCom=”down”;
Serial.println(myCom);
}
if (cmd.value==0xFF906F) {
myCom=”up”;
Serial.println(myCom);
}
if (cmd.value==0xFF9867) {
myCom=”eq”;
Serial.println(myCom);
}
if (cmd.value==0xFFB04F) {
myCom=”st”;
Serial.println(myCom);
}
if (myCom==”pwr”){
digitalWrite(dir1,LOW);
digitalWrite(dir2,HIGH);
analogWrite(speedPin,205);
}
if (myCom==”func”){
digitalWrite(dir1,LOW);
digitalWrite(dir2,LOW);
analogWrite(speedPin,0);
}
if (myCom==”ff”){
digitalWrite(dir1,LOW);
digitalWrite(dir2,HIGH);
analogWrite(speedPin,mSpeed);
}
if (myCom==”rwd”){
digitalWrite(dir1,HIGH);
digitalWrite(dir2,LOW);
analogWrite(speedPin,mSpeed);
}
if (myCom==”up”){
mSpeed=mSpeed+5;
if (mSpeed>255){
mSpeed=255;
}
analogWrite(speedPin,mSpeed);
}
if (myCom==”down”){
mSpeed=mSpeed-5;
if (mSpeed<0){
mSpeed=0;
}
analogWrite(speedPin,mSpeed);
}
delay(500);
}


Proximity Detection with Distance Sensor HC-SR04

This project involves the use of an HC-SR04 proximity sensor commonly used among robotic devices for purposes of collision avoidance. In this project, the sensor is applied to an Arduino Nano system measure distance from an object and report back the results to a serial monitor on a computer, and an LCD display. This unit is powered via a battery or USB power back for portability.

Distance measurements between object and proximity sensor.

Each measurement is taken once the sensor appears before an object, or if a target object is placed in front of the sensor. Once the target is placed, a user is prompted to press the circuit switch to activate the measurement activity that occurs. The measurement reported to a computer and LCD display is an average of 100 readings between the sensor and the placed object. The Nano programmatically operates a high-speed loop by which each reading event (0 to 100) is cumulatively stored into a memory bucket. Once all reading measurements are taken, the average measurement is obtained by calculating the total by dividing the number of measurements completed into the total bucket value. This function is repeated for each switch/button-press event to activate a measurement.

The integration of all system components is easily made by to combing key elements onto a single perf/vector board, or PCB.

Functional Demonstration Video:


Project Schematic:

The HC-SR04 proximity sensor symbol is available for download from SnapEDA.

Arduino Setup:

Sketch IDE with code entries. The LCD object library and variable declarations are made to set up the conditions necessary to operate the system. As the proximity sensor is set up for each pin (trigger and echo), they function in bidirectional manner. The trigger function is an output from the Nano that sends out an ultrasonic ping to a target object through the transducers on the sensor. As that ping signal reflects back, the transducer picks up the difference in time to translate that into distance. Since the speed of sound is a known constant, and the travel time of the ping signal is measured, the distance measurement is derived. The derived results are sent back to the Nano from the sensor’s echo pin.

Serial Monitor results with object distance change three-times with two measurements in each position. Each measure corresponds the to LCD display reading.

Code Example:

#include <LiquidCrystal.h>
int rs=7;
int en=8;
int d4=9;
int d5=10;
int d6=11;
int d7=12;
int buttonPin=A0;
int buttonVal;
int numMeas=100;
float avMeas; // make float not int to avoid rounding error
int j;
float bucket=0; // make float not int to avoid rounding error

LiquidCrystal lcd(rs,en,d4,d5,d6,d7);

int trigPin=3;
int echoPin=2;
int pingTravelTime;
float pingTravelDistance;
float distanceToTarget;
int dt=5000; //int dt(5000);

void setup() {
Serial.begin(9600);
lcd.begin(16,2);
pinMode(trigPin,OUTPUT);
pinMode(echoPin,INPUT);
pinMode(buttonPin,INPUT);
digitalWrite(buttonPin,HIGH); //initializes analog A0 pin for digital use through an internal pull up resistor.
}

void loop() {
lcd.setCursor(0,0);
lcd.print(“Place the Target”);
lcd.setCursor(0,1);
lcd.print(“Press to Measure”);
buttonVal=digitalRead(buttonPin);
while (buttonVal==1){
buttonVal=digitalRead(buttonPin);
}
lcd.setCursor(0,0);
lcd.clear();
lcd.print(“Measuring…”);
for (j=1;j<=numMeas;j=j+1){
digitalWrite(trigPin,LOW);
delayMicroseconds(10);
digitalWrite(trigPin,HIGH);
delayMicroseconds(10);
digitalWrite(trigPin,LOW);
pingTravelTime=pulseIn(echoPin,HIGH);
delay(25);
pingTravelDistance=(pingTravelTime*765.*5280.*12)/(3600.*1000000);
distanceToTarget=pingTravelDistance/2;
bucket=bucket+distanceToTarget;
}
avMeas=bucket/numMeas;

Serial.print(“Target Distance: “);
Serial.print(distanceToTarget);
Serial.println(” inches”);
lcd.clear();
lcd.setCursor(0,0);
lcd.print(“Target Distance:”);
lcd.setCursor(0,1);
lcd.print(distanceToTarget);
lcd.print(” Inches”);
delay(dt);
}


Portable Temperature & Humidity Monitor System

The purpose of this build is to become more familiar with how to develop a free-standing Arduino system using the Arduino Nano. The Nano is a smaller equivalent to the Arduino Uno, but with fewer interface options. It obviously occupies less space since it is a smaller footprint while having reduced overall dimensions. The project makes use of a DHT temperature and humidity sensor that interfaces with the Nano and it includes a 16×2 LCD display to indicate measurement results.

As temperature and humidity variations appear within the immediate environment, there are readings at the sensor read into the Arduino Nano. The system is configured and programmed to accept those readings and report them to the liquid crystal display. The ambient conditions surrounding the sensor are processed within the Nano to translate sensor data into usable information at the display.
The system is powered by a 9V battery stepped down to a regulated 5VDC supply. The power module supports the Nano, DHT sensor, and LCD display. The power supply module’s detachability renders the Nano accessible for ease programming and alternative power through the Nano’s USB receptacle. This setup removes any permanent tethering with extended life through a power supply module’s USB-A receptacle if a power bank is used instead. The 10K-ohm potentiometer is a brightness control for the LCD display.

The system schematic makes no use of passive components except for the single variable resistor (10K-ohm potentiometer). The direct connections between the Nano and display provide for desired simplicity during build and diagnostics. The DHT11 sensor pin-out provides for clarity about necessary connections at the Nano.

1602A LCD Display Pinout

PinSymbolFunction
1VSSGround
2VDD+5VDC
3V0Contrast
4RSRegister
5R/WRead/Write
6EEnable
7D0Data
8D1Data
9D2Data
10D3Data
11D4Data
12D5Data
13D6Data
14D7Data
15AAnode (+5VDC)
16KCathode (Ground)

Arduino Setup:

To program, edit, or update the firmware within the Arduino Nano, it is necessary to attach a USB connection from computer. The serial connection is made to update settings, configure the Arduino IDE (Sketch)
The conventional structured programming setup applies to this project as with any other. The top of the program specifies libraries to support physical objects or devices in the project such as the DHT sensor and the LCD display in this case. Above the void set up procedure block, relevant variables are declared by data type (integer, float, etc). The void setup initiates devices, Arduino functions, or GPIO pins. The loop functions are the procedure itself that iterates to execute the main process by which the program operates.
To set up and program the Nano, it is necessary to select it under the Board option from the Tool menu. The Port option within the Tools menu may require selection or setup as COM1 – COM5 (or some COM#) to establish a connection to a computer for programming and to run the Serial Monitor under this same Tools menu selection.
To install relevant external device libraries (such as a temperature sensor, or display), it might be necessary to add the device to the Arduino Sketch folder on its host computer (usually C:\Users\[name]\Documents\Arduino\libraries).
An example to install or update a device library from the Manage Libraries selection of the Tools Menu option, provides a dialog box to search by library name or description. In this example, “DHT” is keyed in to find the temp & humidity sensor for installation.
Once the Arduino Sketch IDE is set up and configured with the correct board, serial COM connection, and relevant libraries, the code becomes operable and the serial monitor confirms proper use and setup (if/as applicable).

Code Setup:

#include <DHT.h>
#include <LiquidCrystal.h>
int rs=7;
int en=8;
int d4=9;
int d5=10;
int d6=11;
int d7=12;
LiquidCrystal lcd(rs,en,d4,d5,d6,d7);

int sensePin=2;
DHT HT(sensePin,Type);
float humidity;
float tempC;
float tempF;
int setTime=500;
int dt=1000;

void setup() {
Serial.begin(9600);
HT.begin();
delay(setTime);
lcd.begin(16,2);
}

void loop() {
humidity=HT.readHumidity();
tempC=HT.readTemperature();
tempF=HT.readTemperature(true);

lcd.setCursor(0,0);
lcd.print(“Temp F= “);
lcd.print(tempF);
lcd.setCursor(0,1);
lcd.print(“Humidity= “);
lcd.print(humidity);
lcd.print(“%”);
delay(500);
lcd.clear();

Serial.print(“Humidity: “);
Serial.print(humidity);
Serial.print(” Temperature: “);
Serial.print(tempC);
Serial.print(“C “);
Serial.print(tempF);
Serial.println(“F “);
}


Liquid Crystal Display Setup, Control & Calculator

A common Arduino system typically includes a display of some type. This project was to set up a 16×2 LCD display to an Arduino unit and run it with simple messages that render it available for inputs or computational processing. It produces an informational output of its own, or to correspond to another event controlled by a wider system.

While the LCD display takes up several digital GPIO pins, there are several more remaining to build additional system functions. As either inputs or outputs, the display can read sensor data and trigger a relay, an alarm, or other device as specified. The potentiometer in the project as illustrated in the schematic below controls the LCD character block brightness.
Aside from any additional inputs, controls, or outputs, the LCD can display processes that run within the Arduino unit. Even as depicted here such as a counter or a calculator.

The physical connections between the Arduino and LCD display are through direct jumper connections between GPIO pins to data, control, power, and ground. The potentiometer is simply for character illumination intensity.

The digital GPIO pins that interface to the LCD connect to its data pins. R/W is strapped low to ground.

Arduino 16×2 LCD System Schematic

1602A LCD Display Pinout

PinSymbolFunction
1VSSGround
2VDD+5VDC
3V0Contrast
4RSRegister
5R/WRead/Write
6EEnable
7D0Data
8D1Data
9D2Data
10D3Data
11D4Data
12D5Data
13D6Data
14D7Data
15AAnode (+5VDC)
16KCathode (Ground)

Program & Functional Operation:



Code Setup:

#include <LiquidCrystal.h>
int rs=7;
int en=8;
int d4=9;
int d5=10;
int d6=11;
int d7=12;
LiquidCrystal lcd(rs,en,d4,d5,d6,d7);

void setup() {
lcd.begin(16,2);
}

void loop() {
lcd.setCursor(0,0);
lcd.print(“Counter:”);
lcd.setCursor(0,1);
lcd.print(“Hello James”);
for (int j=1;j<=10;j=j+1){
lcd.setCursor(9,0);
lcd.print(j);
delay(500);
}
lcd.clear();
}

Arduino Setup:

Calculator Setup:

#include <LiquidCrystal.h>
int rs=7;
int en=8;
int d4=9;
int d5=10;
int d6=11;
int d7=12;

float firstNum;
float secNum;
float answer;

String op;

LiquidCrystal lcd(rs,en,d4,d5,d6,d7);

void setup() {
lcd.begin(16,2);
Serial.begin(9600);
}

void loop() {

lcd.setCursor(0,0);
lcd.print(“Input 1st Number”);
while (Serial.available()==0){
}
firstNum=Serial.parseFloat();
lcd.clear();
lcd.setCursor(0,0);
lcd.print(“Input 2nd Number”);
while (Serial.available()==0){
}
secNum=Serial.parseFloat();

lcd.clear();
lcd.setCursor(0,0);
lcd.print(“Operator(+,-,*,/)”);
while (Serial.available()==0){
}
op=Serial.readString();

if (op==”+”){
answer=firstNum+secNum;
}
if (op==”-“){
answer=firstNum-secNum;
}
if (op==””){
answer=firstNumsecNum;
}
if (op==”/”){
answer=firstNum/secNum;
}
lcd.clear();
lcd.setCursor(0,0);
lcd.print(firstNum);
lcd.print(op);
lcd.print(secNum);
lcd.print(” = “);
lcd.print(answer);
lcd.setCursor(0,1);
lcd.print(“Thank You”);
delay(10000);
lcd.clear();
}



Pushbutton Switch Dimmer Control & Alarm

This project controls an increasing and decreasing voltage level in increments to represent a dimmer present at an LED. An in-circuit buzzer serves as an alarm to indicate either a maximum or minimum level is attained. Two separate pushbutton switches are up / down controls at programmable increments.

Both switches are set up in a common physical configuration only attached to separate GPIO ports. The difference between their operation rests within the code. Brightness increments are defined within the code as is the decrements. Each increment and decrement interval is code-defined as both switches are attached as inputs to separate GPIO ports. The LED is simply an indicator of a GPIO output to show what the increments and decrements are doing (increasing and decreasing voltage levels).
The buzzer that operates as an alarm triggers when the pushbutton switch is pressed too much or too long. As increments increase to a cap (255) or decrease to a floor (0), the alarm will sound to indicate there is no further increase or decrease available. The dimming or brightness levels off and goes no further.

One pull up resistor for each pushbutton switch is necessary to correctly assert each GPIO input to control circuit and code activity. Four total GPIO pins used, each one for its dedicated function. There is no attempt to make dual use of a GPIO port.

Project schematic to illustrate connections and devices interfaced to the Arduino SBC.

Program & Functional Operation:



Code Setup:

int buttonPin1=12;
int buttonPin2=11;
int buzzPin=2;
int LEDPin=3;
int buttonVal1;
int buttonVal2;
int LEDbright=0;
int dt=500;

void setup() {
pinMode(buttonPin1,INPUT);
pinMode(buttonPin2,INPUT);
pinMode(LEDPin,OUTPUT);
pinMode(buzzPin, OUTPUT);
Serial.begin(9600);
}

void loop() {
buttonVal1=digitalRead(buttonPin1);
buttonVal2=digitalRead(buttonPin2);
Serial.print(“Button 1 = “);
Serial.print(buttonVal1);
Serial.print(“, “);
Serial.print(“Button 2 = “);
Serial.println(buttonVal2);
delay(dt);

if (buttonVal1==0){
LEDbright=LEDbright+25;
}
if (buttonVal2==0){
LEDbright=LEDbright-25;
}
Serial.println(LEDbright);
if (LEDbright>255){
LEDbright=255;
digitalWrite(buzzPin,HIGH);
delay(dt);
digitalWrite(buzzPin,LOW);
Serial.println(“Buzz High”);
}
if (LEDbright<0){
LEDbright=0;
digitalWrite(buzzPin,HIGH);
delay(dt);
digitalWrite(buzzPin,LOW);
Serial.println(“Buzz Low”);
}

analogWrite(LEDPin, LEDbright);

}

Arduino Set Up:

Partial view of the code to operate the project. The full code is in the text field above.

Serial display of printed values to indicate states of switch buttons and increment or decrement values of 25. The smaller the increment or decrement, the more pushbutton switch presses are needed to reach either upper or lower limit. Increment and decrement was set arbitrarily in the code to initialize a reasonable value of 25 to reduce the time and clicks it takes to get to the maximum and minimum (0 – 255).

Toggle Switch PullUp with digitalRead

This project involves a toggle switch that an Arduino UNO recognizes through code as necessary to activate an LED over a GPIO pin. Assembly of the circuit requires a 330 resistor, 10K resistor, normally open pushbutton switch, and a red LED plus some jumpers. For added clarity about the assembly refer to the photos below. The schematic illustration merely offers a symbolic representation of the setup. The prior project involved the use of pushbutton switch that temporarily enabled an output (LED) from a GPIO pin.

This project changes the state of the GPIO (LED) each time the pushbutton is pressed. The pushbutton switch in this way operates as a toggle as a steady-state on/off through conditional instruction statements written into the code.

Simple set up of a small circuit to interface with the Arduino UNO R3 SBC. Includes 330 ohm, 10K ohm current limiting resistors, a RED LED, and a small pushbutton normally open switch. Circuit jumpers interface to the Arduino’s GPIO ports.

Top down view of circuit connections.

To register active high and active low states at a GPIO port, it is necessary to apply pull up or pull-down resistors to a circuit’s normally open or normally closed pushbutton switch. It is not an acceptable practice to place a GPIO pin directly to a +5V source, or Ground in order to operate a directly connected switch. The purpose of a pulldown or pullup resistor placed onto a switch is to correctly register an active high or low state at an assigned GPIO measurement pin. To illustrate the connections see the diagrams below:

Pull Up Resistor Example
Pull Down Resistor Example

Simply put, there just must be a circuit path to either a voltage reference or ground reference using a resistor connected to a switch for proper operation. The active voltage present at pin-12, while the button switch is not pressed, is 5VDC. When the pushbutton switch is pressed this voltage level drops to 0VDC. As a 0VDC state is read into pin 12 by the digitalRead operation (i.e. pin 12 becomes grounded), pin 8 presents 5VDC to R2 for the Red LED to illuminate. While the pushbutton switch is pressed and held closed, the serial monitor presents a digital “0” state. This is due to the placement of the digitalRead command within the continuous program loop.

To run the project it is necessary to assemble the circuit onto a breadboard using the components identified above. When the hardware is set up, it is then necessary to write and run the code to get functional use of the project.



Code Setup:

int LEDState=0;
int LEDPin=8;
int buttonPin=12;
int buttonNew;
int buttonOld=1;
int dt=100;

void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(LEDPin, OUTPUT);
pinMode(buttonPin, INPUT);
}

void loop() {
buttonNew=digitalRead(buttonPin);
if(buttonOld==0 && buttonNew==1){
if(LEDState==0){
digitalWrite(LEDPin,HIGH);
LEDState=1;
}
else{
digitalWrite(LEDPin,LOW);
LEDState=0;
}
}
buttonOld=buttonNew;
delay(dt);
}

With all suitable integer variables declared, operational instructions become written to perform their intended purpose. Standard pin mode set up declarations are made, and thereafter, the main loop program begins.

The digitalRead operation is executed as the buttonPin command is asserted. The physical state change that occurs from the button switch is detected at the Arduino port (pin 12) and that change is digitally read into memory and stored to the buttonNew variable. Once a switch state is read into memory via the GPIO port, the next set of instructions act upon those states held into memory.

The if-else statement parameters check for the high or low (5VDC or 0VDC) level presented to GPIO pin 12. As the buttonOld and buttonNew variables are checked for true status against assigned states “0” to buttonOld and “1” to buttonNew, the next if-statement is executed. The LEDState is checked for a logic 0 state and if it is true, the digitalWrite command places a HIGH state (logic 1, 5VDC) to the LEDPin (pin 8) GPIO port. The LEDState is then given a logic 1 into its memory space to initialize it for repeat evaluation during the continuous loop in function. Once the true state instructions are executed within both ‘if’ commands, the program falls through the function to bypass the ‘else’ code segment and continues through to the rest to the program until completion where the loop again begins.

The second half of the conditional function, ‘else’ supports the logic evaluation that previously occurred between the buttonNew and buttonOld ‘recognized’ states. If the combination of both variable assessments proves false, the else statement becomes effective within the loop to set the LEDPin to Low. This is the equivalent of a logic evaluation that checks for voltage transitions low to high and turn the LED off. Each time this transition occurs, the program loop writes the active high to turn the LED on or off. The next low-to-high button switch transition evaluation occurs within the ‘else’ segment of the conditional loop to again set the GPIO pin to low (pin-8 LED off) if that else condition should become true.

As the program loop continuously runs, the GPIO pin accepts state changes to operate as a toggle on and off, then on and off again.


Arduino IDE:

Code set up in the Arduino IDE (Sketch).

Pushbutton Switch PullUp with digitalRead

This project involves a push-button switch that an Arduino UNO recognizes through code as necessary to activate an LED over a GPIO pin. Assembly of the circuit requires a 330 resistor, 10K resistor, normally open pushbutton switch, and a red LED plus some jumpers. For added clarity about the assembly refer to the photos below. The schematic illustration merely offers a symbolic representation of the setup.

Simple set up of a small circuit to interface with the Arduino UNO R3 SBC. Includes 330 ohm, 10K ohm current limiting resistors, a RED LED, and a small pushbutton normally open switch. Circuit jumpers interface to the Arduino’s GPIO ports.
Top down view of circuit connections.

To register active high and active low states at a GPIO port, it is necessary to apply pull up or pull-down resistors to a circuit’s normally open or normally closed pushbutton switch. It is not an acceptable practice to place a GPIO pin directly to a +5V source, or Ground in order to operate a directly connected switch. The purpose of a pulldown or pullup resistor placed onto a switch is to correctly register an active high or low state at an assigned GPIO measurement pin. To illustrate the connections see the diagrams below:

Pull Up Resistor Example
Pull Down Resistor Example

Simply put, there just must be a circuit path to either a voltage reference or ground reference using a resistor connected to a switch for proper operation. The active voltage present at pin-12, while the button switch is not pressed, is 5VDC. When the pushbutton switch is pressed this voltage level drops to 0VDC. As a 0VDC state is read into pin 12 by the digitalRead operation (i.e. pin 12 becomes grounded), pin 8 presents 5VDC to R2 for the Red LED to illuminate. These states correspond to the Sketch serial monitor “0” or “1” messages presented. While leaving the pushbutton switch unpressed, the serial monitor presents a digital “1” state. While the pushbutton switch is pressed and held closed, the serial monitor presents a digital “0” state. This is due to the placement of the digitalRead command within the continuous program loop.

To run the project it is necessary to assemble the circuit onto a breadboard using the components identified above. When the hardware is set up, it is then necessary to write and run the code to get functional use of the project.


Program & Functional Operation:


Code Setup:

int LEDPin=8;
int buttonPin=12;
int buttonRead;
int dt=250;

void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(LEDPin, OUTPUT);
pinMode(buttonPin, INPUT);
}

void loop() {
// put your main code here, to run repeatedly:
buttonRead=digitalRead(buttonPin);
Serial.println(buttonRead);
delay(dt);
if(buttonRead==1){
digitalWrite(LEDPin, LOW);
}
if(buttonRead==0){
digitalWrite(LEDPin, HIGH);
}
}

Arduino IDE:

Code set up in the Arduino IDE (Sketch).

Continuously scrolled active states as values are read into memory via digitalRead from the pushbutton switch. State change from “1” to “0” to indicate LED on/off status.