Ade Lab Manual PDF
Ade Lab Manual PDF
Laboratory Manual
Gokaraju Rangaraju
Institute Of Engineering and Technology
(Approved by A.I.C.T.E and Affiliated to JNTU)
Bachupally, Kukatpally
HYDERABAD 500090.
1
Analog Electronics Lab Record
Name:
Reg no.:
Course: B.Tech. __ Year __ Semester
Branch:
2
Contents
Proportional Amplifier .................................................................................................................... 04
ANNEXURE:
LM 741-IC78
555 TIMER..79
3
EXPERIMENT-1
PROPORTIONAL AMPLIFIER
AIM: To demonstrate Proportional Amplifier Circuit using Op-Amp.
1K Resistor (1)
Multimeter
Breadboard/PCB
CIRCUIT DIAGRAM:
PROCEDURE:
1. Simulate the circuit using Multisim.
4
3. Adjust the input to 100mv and output should be 1V.
5. Change the feedback resistor to 5K and draw the graph between input and output.
MODEL
GRAPH:
5
GRAPH SHEET:
RESULT:
6
EXPERIMENT-2
INTEGRATING AMPLIFIER
AIM: To demonstrate Integrator Amplifier Circuit using Op-Amp
1K Resistor (1)
Multimeter
Breadboard/PCB
THEORY:
Integrator:
It is a low pass RC filter circuit. It can work as an integrator when time constant is very
large. This requires very large values of R and c. by Millers theorem the effective input
capacitance becomes C!(1-Av)where Av is the gain of the op-amp. The gain Av is infinite for an
ideal op-amp.so, the effective time constant of the op-amp becomes large which results in perfect
integration.
7
CIRCUIT DIAGRAM:
R1 10k
C1 100nF
XSC1
V2
15 V 0 Ext T rig
+
1 _
A B
4 U1A + _ + _
03
1 7 0
R2 3 2
5
V3100k 11 LM324AD
2
-20 V 20 V V1
15 V
0 0.5msec 1msec 0
PROCEDURE:
1. Connect the circuit as shown in the circuit diagram.
2. Suitable Rf and C1 are chosen such that the output of the circuit is the integral of the input
voltage.
3. A square wave input voltage (V) is applied at the input terminal.
4. Observe the output voltage waveform on the CRO and note down the corresponding values.
5. The time constant RfC1 is changed by changing the values of R f or C1 and the corresponding
output waveforms are noted.
MODEL GRAPH:
8
Tabular Column & Theoritical Calculations:
9
GRAPHSHEET:
RESULT:
10
EXPERIMENT-3
DIFFERENTIATING AMPLIFIER
AIM: To demonstrate Differentiate Amplifier Circuit using Op-Amp.
0.1uF Capacitor
Multimeter
Breadboard/PCB
CIRCUIT DIAGRAM:
THEORY:
It consists of an high pass RC filter .it acts as a differentiator for low values of time constant.
Here the output is the derivative of the input signal by
Thus output is not only the derivative of the input but also out of phase by 180 w.r.t the input.
11
PROCEDURE:
1. Connect the circuit as shown in the circuit diagram.
2. Suitable Rf and C1 are chosen such that the output of the circuit is the integral of the input
voltage.
3. A square wave input voltage (V) is applied at the input terminal.
4. Observe the output voltage waveform on the CRO and note down the corresponding values.
5. The time constant RfC1 is changed by changing the values of R f or C1 and the corresponding
output waveforms are noted.
MODEL GRAPHS:
12
Tabular Column & Theoritical Calculations:
13
GRAPHSHEET:
RESULT:
14
EXPERIMENT-4
SUMMING AMPLIFIER
0.1uF Capacitor
Multimeter
Breadboard/PCB
THEORY:
Summing amplifier is a circuit whose output is the sum of several input signals.
For example: An inverting summing amplifier three input voltages , and , three input
resistors , and and a feedback resistor has as follows.
= -( + + )
CIRCUIT DIAGRAM:
15
PROCEDURE:
1. Connect the relevant circuit for the inverting configuration as shown in the circuit
diagram.
2. Measure the output voltage Vo using a CRO.
3. Observe the waveforms at V1, V2, and Vo.
4. Note the phase of the output voltage Vo with respect to the input voltage.
5. Set the signal generator to give 1 VPP sine wave at 100Hz.
6. Repeat the steps 3, 4, and 5.
7. The waveforms are to be noted.
16
GRAPH SHEET:
RESULT:
17
EXPERIMENT-5
SQUAREWAVE GENERATOR
AIM: To construct and demonstrate square wave generator using op-amp.
APPARATUS:
Op-amp LM741 IC 1No.
Capacitors 0.1F 1No.
Resistors 10k (2Nos.), 1k (1No.)
CRO and Bread Board.
THEORY:
A simple op-amp square wave generator (Astable multivibrator), also called free running
oscillator, is shown in the diagram. The principle of the circuit is to force an op-amp to operate in
the saturation region. A fraction () of the output is feedback to the positive input terminal. Thus,
the reference voltage is and may take values as + or . The output is also
feedback to the negative input terminal. When just exceeds then switching takes place
resulting in a square wave output. In this multivibrator, both the states are quasi stable.
Consider an instant of time when the output is at + . The capacitor now starts charging
towards + through resistor R. the voltage Vref is held at + by - combination. This
condition continues as the charge on C rises, until it has just exceeded + , the reference
voltage. When the capacitor voltage becomes just greater than this , the output is driven to
. It charges more and more negatively until its voltage just exceeds . At capacitor
voltage equals to the output switches back to + the cycle repeats itself.
CIRCUIT DIAGRAM:
0
R3
0 10k XSC1
V2 8
15 V Ext T rig
+
4 R2 _
1k A B
4 U1A + _ + _
3
1 10 0
2
C1 R1
9 11 LM324AD
0 6
100nF 22k
V1
15 V
0
18
PROCEDURE:
MODEL GRAPHS:
a. For R = 10k,
19
GRAPHSHEET:
RESULT:
20
EXPERIMENT-6
TRIANGULARWAVE GENERATOR
AIM: To construct and demonstrate Triangular wave generator using LM741 IC.
APPARATUS REQUIRED:
Op-Amp LM741 1No.
Resistors 10k (2Nos.), 22k, 47k -- 1No. each.
Capacitor 0.1F 1No.
CRO and Bread Board.
THEORY:
Monostable Multivibrator has one stable state and the other is quasi stable state. The
circuit is useful for generating single output pulse of adjustable time duration in response to a
triggering signal. The width of the output pulse depends only on external components connected
to the op amp. A diode clamps the capacitor voltage to 0.7V when the output is at + .A
negative going pulse signal of magnitude passing through the differentiator and diode
produces a negative going triggering in pulse and is applied to the (+)Input terminal.
To analyse the circuit, let us assume the stable state, the output is at + . The diode
conducts and the voltage across the capacitor C gets clamped to +0.7 volts. The voltage as
the (+) input terminal through the potentiometric divider is + . Now if a negative
trigger of magnitude V1 is applied at the (+) input terminal so that the effective signal at this
terminal is< 0.7V i.e. [ +(- )) < 0.7V ), the output of the op-amp will switch from + to
. The diode will now get reverse biased and the capacitor starts charging exponentially to
through resistance R.
The voltage at the (+) input terminal is now . When the capacitor voltage
becomes just slightly more negative than . The output of the op-amp switches back to
+ . The capacitor now starts charging to + through R until =0.7V, as capacitor C gets
clamped to the voltage.
21
CIRCUIT DIAGRAM:
PROCEDURE:
OBSERVATIONS:
S.No R2(k) fth Square Triangular ON Time OFF fp
Amplitude Amplitude Time
1.
2.
22
MODEL GRAPH:
RESULT:
23
EXPERIMENT-7
PRECISION HALFWAVE RECTIFIER
AIM: To construct and demonstrate a Precision half-wave rectifier.
APPARATUS:
Op-Amp LM741 IC 1No.
Diodes 1N4007 2Nos.
Resistors 10k (3Nos.), 4.7k (1No.)
THEORY:
When is positive, diode conducts causing to go to negative by one diode drop
(N.6V). Hence Diode is reverse biased. The output voltage is zero, because for all
practical purposes no current flows through and the input current flows through .
For a negative input, <0. Diode conducts and is off. The negative input forces
the op amp output positive and causes to conducts.
The circuit then acts like an inverter for = and output becomes positive. The op
amp used must be a high speed op amp since it alternates between open loop and closed loop
operations.
CIRCUIT DIAGRAM:
XSC1
V2
15 V Ext Trig
R4 +
3 10k _
4 U1A A B
0 R1 2 + _ + _
3
D1
4.7k 1 1 6 0
7 R2
2 1N4007
V1 10k 11 LM324AD
4
V3
4 Vpk
15 V
1kHz
0
0
0 D2
1N4007
5 R3
10k
24
PROCEDURE:
WAVEFORM:
25
GRAPHSHEET:
RESULT:
26
EXPERIMENT-8
PRECISION FULLWAVE RECTIFIER
AIM:To construct and verify the output of a Precision full wave rectifier.
APPARATUS:
Operational Amplifier LM741 IC 2Nos.
Diode 1N4007 2Nos.
Resistors 4.7k -- 5Nos.
THEORY:
A full-wave rectifier or absolute value circuit works as follows. For positive input i.e.
>0. Diode is ON and is OFF both the Op amps and acts as inverter then = .
For negative input i. e. <0. Diode is OFF and is ON. Then after simplifying the
circuit the output will be equal to the input. Then,
= .
CIRCUIT DIAGRAM:
R5 8
1k 0
0
V4 XSC1
V3 15 V
15 V D2
Ext Trig
1N4007 +
10
4 _
A B
4 U2A + _ + _
4 U1A 3
0 3
1
1 0
R1 1 2
2 9
2 V2 11 LM324AD
1k 11 LM324AD
1 Vpk D1 11
3
1kHz 1N4007 V5
0 V1 15 V
15 V 7
0
0
0
R2 5 R3 6 R4
1k 1k 1k
27
PROCEDURE:
WAVEFORM:
28
GRAPHSHEET:
RESULT:
29
EXPERIMENT-9
DIGITAL TO ANALOG CONVERTER
(R-2R LADDER METHOD)
AIM:To construct a 4-bit R-2R ladder type of digital to analog converter for R = 1K.
APPARATUS:
Operational Amplifier LM741 IC 1No.
Resistors 1k (3Nos.), 2.2k (6Nos.), 3.3k (3Nos.)
Bread Board and a Voltmeter.
THEORY:
R-2R ladder DAC, avoids the use of wide range of resistors. This makes the circuit
suitable for monolithic fabrication. Typical range of values of R will be in 2-10K.
CIRCUIT DIAGRAM:
0
V1
15 V XMM1
1
4 U1A
0 3
1 0
R4 3 R3 4 R2 5 R1 6 2
1k 1k 1k 2k 11 LM324AD
8 2
V2
15 V 7
R7 R6 R8 R9 R10 0
2k 2k 2k 2k 2k
0
R5
9 10 11 12
J1 J2 J3 J4 3k
VCC
5V VCC
30
PROCEDURE:
MODEL GRAPH:
31
GRAPHSHEET:
RESULT:
32
EXPERIMENT-10
ASTABLE MULTIVIBRATOR USING A 555 TIMER
AIM: To design an astable multivibrator using a 555 timer and to generate a waveform for a
duty cycle of 25%.
APPARATUS:
Operational Amplifier 555 TIMER 1No.
Capacitors 0.01F, 0.1F 1No.each.
Resistors 4.7k(1No.), 2.2k(2Nos.), 1k(3Nos.), 100(2Nos.)
CRO and Bread Board.
SPECIFICATIONS OF LM324:
Supply voltage : 12V (nominal)
Maximum load current : 10A at 12V
Sensor temperature range : -40OC to +100OC
Controls : Off-Auto-On switch
Indicators : High and Low LEDs
THEORY:
An astable multivibrator, also known as free running multivibrator is nothing but an
oscillator that generates square waves. These waves are required to control the timing circuits.
These multivibrator circuits can be designed using an op-amp.
An astable multivibrator designed using a 555-Timer op-amp is shown. To explain the
principle operation, the internal circuit diagram of 555 Timer is also shown beside.
CIRCUIT DIAGRAM:
0
V1
15 V XSC1
1
Ext Trig
+
R2 _
8.2k A B
+ _ + _
2 VCC 0
RST
4
OUT
R1
DIS
3.3k
THR
U1
3 TRI
555_TIMER_RATED
CON
C2
5 GND
10nF
C1
0 0
10nF
33
Hz
PROCEDURE:
1. Calculate the values of R, R, and C for different duty cycles using the formulae given.
2. Connect the circuit as per the diagram.
3. Calculate the frequency of the astable multivibrator by noting the waveform and compare
it with the theoretical values.
4. Change the value of R and C to change the frequency of oscillation and verify the
theoretical values.
5. Note the output voltages at pin no. 3 and capacitor voltage at pin no.6 and plot it on a
graph sheet.
MODEL GRAPH:
For 25% Duty Cycle,
OBSERVATIONS:
34
GRAPHSHEET:
RESULT:
35
EXPERIMENT-11
MONOSTABLE MULTIVIBRATOR USING A 555 TIMER
APPARATUS:
IC 555 1No.
Resistors 22k, 33k, 10k, 20k -- 1No.each.
Capacitors 0.01F (2Nos.), 0.047F (1No.), 0.001F (2Nos.)
Diode 1N4007 1No.
SPECIFICATIONS OF LM324:
Supply voltage : 12V (nominal)
Maximum load current : 10A at 12V
Sensor temperature range : -40 C to +100OC
O
CIRCUIT DIAGRAM:
V1
4 15 V XSC1
Ext T rig
+
R2 _
10k A B
+ _ + _
VCC 0
8 1
RST OUT
C2 DIS
10nF THR
U1
TRI
0 555_TIMER_RATED
CON
6 GND
C1
0
10nF
36
PROCEDURE:
OBSERVATIONS:
WAVEFORMS:
37
GRAPHSHEET:
RESULT:
38
EXPERIMENT-12
Verilog Code:
AND GATE:
module and(a,b,c);
input a, b;
output c;
assign c=a&b;
endmodule
OR GATE:
module or(a,b,c);
input a, b;
output c;
assign c=a^b;
endmodule
39
Test Bench:
module add_tb_v;
// Inputs
reg a;
reg b;
// Outputs
wire c;
// Instantiate the Unit Under Test (UUT)
add uut (
.a(a),
.b(b),
.c(c)
);
initial begin
// Initialize Inputs
a = 0; b = 0; // Wait 100 ns for global reset to finish
#100;a=0;b=1;
#100;a=1;b=0;
#100;a=1;b=1;
end
endmodule
40
Simulation Result:
AND Gate:
OR Gate:
Schematic Diagram:
41
Truth Table:
42
EXPERIMENT-13
Aim: To write verilog code for half adder and Full adder.
Verilog Code:
module fulladder(a,b,c,sum,carry);
input a, b, c;
output sum, carry;
wire s1, c1, c2;
had h1(a,b,s1,c1);
had h2(s1,c,sum,c2);
assign carry=c1|c2;
endmodule
43
Verilog Code for half adder:
module had(a,b,s,c);
input a, b;
output s, c;
assign s=a^b;
assign c=a&b;
endmodule
44
Test Bench:
module fulladder_tb_v;
// Inputs
reg a;
reg b;
reg c;
// Outputs
wire sum;
wire carry;
// Instantiate the Unit Under Test (UUT)
fulladder uut (
.a(a),
.b(b),
.c(c),
.sum(sum),
.carry(carry)
);
initial begin
// Initialize Inputs
a = 0; b = 0; c = 0;
// Wait 100 ns for global reset to finish
#100;a=0;b=0;c=1;
#100;a=0;b=1;c=0;
#100;a=0;b=1;c=1;
#100;a=1;b=0;c=1;
#100;a=1;b=0;c=1;
#100;a=1;b=1;c=0;
#100;a=1;b=1;c=1;
end
endmodule
45
Simulation Result:
Schematic Diagram:
Block Diagram
46
Circuit diagram of full adder
47
Synthesis Report:
48
EXPERIMENT-14
HALF SUBTRACTOR
Aim: To write a verilog code for half subtractor.
Verilog code:
49
Test Bench:
module halfsub_tb_v;
reg a;
reg c;
wire b;
wire d;
halfsub uut (
.a(a),
.c(c),
.b(b),
.d(d));
always begin
a = 0;c = 0;
#100;a=0;c=1;
#100;a=1;c=0;
#100;a=1;c=1;
#100;
end
endmodule
50
Simulation Result:
Schematic Diagram:
Block diagram
51
Circuit diagram of half subtractor
52
EXPERIMENT-15
FULL SUBTRACTOR
Aim: To write a verilog code for full subtractor.
Verilog code:
53
Test Bench:
module fullsub_tb_v;
reg a;
reg c;
reg e;
wire b;
wire d;
fullsub uut (
.a(a),
.c(c),
.e(e),
.b(b),
.d(d) );
always begin
a = 0;c = 0;e = 0;
#100;a=0;c=0;e=1;
#100;a=0;c=1;e=0;
#100;a=0;c=1;e=1;
#100;a=1;c=0;e=0;
#100;a=1;c=0;e=1;
#100;a=1;c=0;e=0;
54
#100;a=1;c=0;e=1;
#100;a=1;c=1;e=0;
#100;a=1;c=1;e=1;
#100;
end
endmodule
Simulation result:
Schematic Diagram:
Block diagram
55
Circuit diagram of full subtractor
56
EXPERIMENT-16
MULTIPLEXER
Aim: To write a verilog code for 16x1 multiplexer using 2x1 multiplexer.
module mux16by1(e,i,s,y);
input [15:0]i;
input [3:0]s;
input e;
output y;
wire [7:0]i1;
wire [3:0]i2;
wire [1:0]i3;
mux2by1 m1(e,i[0],i[1],s[0],i1[0]);
mux2by1 m2(e,i[2],i[3],s[0],i1[1]);
mux2by1 m3(e,i[4],i[5],s[0],i1[2]);
mux2by1 m4(e,i[6],i[7],s[0],i1[3]);
mux2by1 m5(e,i[8],i[9],s[0],i1[4]);
mux2by1 m6(e,i[10],i[11],s[0],i1[5]);
mux2by1 m7(e,i[12],i[13],s[0],i1[6]);
mux2by1 m8(e,i[14],i[15],s[0],i1[7]);
mux2by1 m9(e,i1[0],i1[1],s[1],i2[0]);
mux2by1 m10(e,i1[2],i1[3],s[1],i2[1]);
mux2by1 m11(e,i1[4],i1[5],s[1],i2[2]);
mux2by1 m12(e,i1[6],i1[7],s[1],i2[3]);
mux2by1 m13(e,i2[0],i2[1],s[2],i3[0]);
57
mux2by1 m14(e,i2[2],i2[3],s[2],i3[1]);
mux2by1 m15(e,i3[0],i3[1],s[3],y);
endmodule
module mux2by1(e,a,b,s,y);
input s, e;
input a, b;
output y;
assign y=(e&~s&a)|(e&s&b);
endmodule
Test Bench:
module mux16by1_tb_v;
// Inputs
reg e;
reg [15:0] i;
reg [3:0] s;
// Outputs
wire y;
58
);
initial begin
// Initialize Inputs
e = 0;
i = 0;
s = 0;
end
endmodule
59
Simulation Result:
Schematic Diagram:
60
Circuit diagram of 16x1 mux
61
EXPERIMENT-17
2X4 DECODER
Test Bench:
module decode_tb_v;
// Inputs
reg A0;
reg A1;
// Outputs
wire D0;
wire D1;
wire D2;
wire D3;
62
decoder uut (
.A0(A0),
.A1(A1),
.D0(D0),
.D1(D1),
.D2(D2),
.D3(D3)
);
initial begin
// Initialize Inputs
A0 = 0;
A1 = 0;
end
endmodule
63
Simulation Result:
Circuit diagram:
Truth Table:
64
EXPERIMENT-17
D-FLIP FLOP
Verilog code:
module dflipflop(clk, e, d, q);
input clk;
input e;
input d;
output reg q;
always@(posedge clk or negedge e)
q=d;
endmodule
65
Test bench:
module dflipflop_tb_v;
// Inputs
reg clk;
reg e;
reg d;
// Outputs
wire q;
// Instantiate the Unit Under Test (UUT)
dflipflop uut (
.clk(clk),
.e(e),
.d(d),
.q(q)
);
initial begin
// Initialize Inputs
clk = 0;
e = 0;
d = 0;
end
// Wait 100 ns for global reset to finish
always#100 clk=~clk;
always begin
#100;e=1;d=0;
#100;d=1;
#100;
// Add stimulus here
end
endmodule
66
Simulation result:
Schematic:
67
Circuit diagram of D flip flop
68
EXPERIMENT-18
T-FLIP FLOP
Verilog code:
module t_ff(t, clk, rst, q);
input t;
input clk;
input rst;
output reg q;
always @ (posedge rst or negedge clk)
begin
if(rst)
q=1'b0;
else
q=~t;
end
endmodule
69
Test bench:
module t_ff_tb_v;
// Inputs
reg t;
reg clk;
reg rst;
// Outputs
wire q;
t_ff uut (
.t(t),
.clk(clk),
.rst(rst),
.q(q)
);
initial begin
// Initialize Inputs
clk = 0;
rst = 1;
t=0;
70
#100; rst=0;
end
always begin
#100; t=0;
#100; t=1;
end
endmodule
Simulation waveform:
71
Schematic:
72
EXPERIMENT-19
JK FLIP FLOP
Verilog code:
module jk_ff(j, k, clk, e, q);
input j;
input k;
input clk;
input e;
output reg q;
always @(posedge clk or negedge e)
if(e==0)
q=0;
else if(j==0&&k==0)
q=q;
else if(j==0&&k==1)
q=0;
else if(j==1&&k==0)
q=1;
else if(j==1&&k==1)
q=~q;
endmodule
73
Test Bench:
module jk_ff_tb_v;
// Inputs
reg j;
reg k;
reg clk;
reg e;
// Outputs
wire q;
jk_ff uut (
.j(j),
.k(k),
.clk(clk),
.e(e),
.q(q)
);
initial begin
// Initialize Inputs
j = 0;
k = 0;
clk = 0;
74
e = 0;
#50;e=0;j=0;k=0;
#50;e=0;j=0;k=1;
#50;e=0;j=1;k=0;
#50;e=0;j=1;k=1;
#50;e=1;j=0;k=0;
#50;e=1;j=0;k=1;
#50;e=1;j=1;k=0;
#50;e=1;j=1;k=1;
end
endmodule
75
Simulation waveform:
Schematic:
76
Circuit diagram of JK flipflop
77
Annexure:
1. LM741 IC
Operational Amplifiers often known as Op-Amps are used in a range of circuits. They are generally used
to amplify weak electrical current in a circuit. It is one of the most versatile devices in all of electronics.
Op-amps are integrated circuits that cram the equivalent of many transistors, resistors and capacitor into
a small silicon chip.
The most popular type of Op Amp is the 741 as shown below as 8 pin dual layout IC's. They are
represented in circuit diagrams as follows:
V + : non-
inverting input
V : inverting
input
Vout: output
VS + : positive
power supply
VS : negative
power supply
The op-amp is basically a differential amplifier having a large voltage gain, very high input impedance and
low output impedance. The op-amp has a "inverting" or (-) input and "non-inverting" or (+) input and a
single output. The op-amp is usually powered by a dual polarity power supply in the range of +/- 5 volts to
+/- 15 volts.
78
The chip can be used in a circuit in two ways. If the voltage goes into pin 2 then it is known as
an INVERTING AMPLIFIER.
If the voltage goes into pin 3 then the circuit becomes a NON-INVERTING AMPLIFIER.
2. 555 TIMER
The 555 timer IC is an integrated circuit (chip) used in a variety of timer, pulse generation,
and oscillator applications. The 555 can be used to provide time delays, as an oscillator, and as a flip-flop
element.
PIN DIAGRAM:
2 TRIG OUT rises, and interval starts, when this input falls below 1/3 VCC.
A timing interval may be reset by driving this input to GND, but the timing does not begin
4 RESET again until RESET rises above approximately 0.7 volts. Overrides TRIG which overrides
THR.
79
5 CTRL "Control" access to the internal voltage divider (by default, 2/3 VCC).
6 THR The interval ends when the voltage at THR is greater than at CTRL.
7 DIS Open collector output; may discharge a capacitor between intervals. In phase with output.
Modes
The 555 has three operating modes:
Monostable mode: in this mode, the 555 functions as a "one-shot" pulse generator. Applications
include timers, missing pulse detection, bounce free switches, touch switches, frequency divider,
capacitance measurement, pulse-width modulation (PWM) and so on.
Astable: free running mode: the 555 can operate as an oscillator. Uses include LED and lamp
flashers, pulse generation, logic clocks, tone generation, security alarms, pulse position
modulation and so on. The 555 can be used as a simple ADC, converting an analog value to a pulse
length. E.g. selecting a thermistor as timing resistor allows the use of the 555 in a temperature
sensor: the period of the output pulse is determined by the temperature. The use of a microprocessor
based circuit can then convert the pulse period to temperature, linearize it and even provide
calibration means.
Bistable mode or Schmitt trigger: the 555 can operate as a flip-flop, if the DIS pin is not connected
and no capacitor is used. Uses include bounce-free latched switches.
80
Introduction to Arduino
Arduino is an open source physical computing platform based on a simple input/output
(I/O) board and a development environment that implements the Processing language
(www.processing.org). Arduino can be used to develop standalone interactive objects or can
be connected to software on your computer (such as Flash, Processing, VVVV, or Max/MSP).
The boards can be assembled by hand or purchased preassembled; the open source IDE
(Integrated Development Environment) can be downloaded for free from www.arduino.cc.
Arduino is different from other platforms on the market because of these features:
You program it via a USB cable, not a serial port. This feature is useful, because many
modern computers dont have serial ports.
It is open source hardware and softwareif you wish, you can download the circuit
diagram, buy all the components, and make your own, without paying anything to the
makers of Arduino.
There is an active community of users, so there are plenty of people who can help you.
The Arduino Project was developed in an educational environment and is therefore great
for newcomers to get things working quickly.
Arduino is composed of two major parts: the Arduino board, which is the piece of
hardware you work on when you build your objects; and the Arduino IDE, the piece of software
you run on your computer. You use the IDE to create a sketch (a little computer program)
that you upload to the Arduino board. The sketch tells the board what to do.
Arduino UNO
81
14 Digital IO pins (pins 013)
These can be inputs or outputs, which is specified by the sketch you create in the IDE.
Upload this sketch to the board through the USB connection and wait a couple of
seconds for the board to restart.
Download the file and double-click on it to open it it; on Windows or Linux, this creates
a folder named arduino-[version], such as arduino-1.0. Drag the folder to wherever you want
it: your desktop, your Program Files folder (on Windows), etc. On the Mac, double-clicking it
will open a disk image with an Arduino application (drag it to your Applications folder). Now
whenever you want to run the Arduino IDE, youll open up the arduino (Windows and Linux)
or Applications folder (Mac), and double-click the Arduino icon. Dont do this yet, though;
there is one more step.
82
Installing Drivers: Windows
Plug the Arduino board into the computer; when the Found New Hard- ware Wizard
window comes up, Windows will first try to find the driver on the Windows Update site.
Windows XP will ask you whether to check Windows Update; if you dont want to use
Windows Update, select the No, not at this time option and click Next.
On the next screen, choose Install from a list or specific location and click Next.
Navigate to and select the Unos driver file, named ArduinoUNO.inf, located in the
Drivers folder of the Arduino Software download (not the FTDI USB Drivers sub-
directory). Windows will finish up the driver installation from there.
If you have an older board, look for instructions here:
www.arduino.cc/en/Guide/Windows.
Once the drivers are installed, you can launch the Arduino IDE and start using Arduino.
Next, you must figure out which serial port is assigned to your Arduino boardyoull
need that information to program it later.
Look for the Arduino device in the list under Ports (COM & LPT). The Arduino will appear
as Arduino UNO and will have a name like COM7, as shown in Figure.
83
Once youve figured out the COM port assignment, you can select that port from the
Tools > Serial Port menu in the Arduino IDE.
Now the Arduino development environment can talk to the Arduino board and program it.
Program Editor
84
Basic Knowledge about Arduino Programming
structure
The basic structure of the Arduino programming language is fairly simple and runs in at least two
parts. These two required parts, or functions, enclose blocks of statements.
void setup()
{
statements;
}
void loop()
{
statements;
}
Where setup() is the preparation, loop() is the execution. Both functions are required for the
program to work.
The setup function should follow the declaration of any variables at the very beginning of the
program. It is the first function to run in the program, is run only once, and is used to set pinMode or
initialize serial communication.
The loop function follows next and includes the code to be executed continuously reading
inputs, triggering outputs, etc. This function is the core of all Arduino programs and does the bulk of the
work.
setup()
The setup() function is called once when your program starts. Use it to initialize pin modes, or
begin serial. It must be included in a program even if there are no statements to run.
void setup()
{
pinMode(pin, OUTPUT); // sets the 'pin' as output
}
loop()
After calling the setup() function, the loop() function does precisely what its name suggests,
and loops consecutively, allowing the program to change, respond, and control the Arduino board.
void loop()
{
digitalWrite(pin, HIGH); // turns 'pin' on
delay(1000); // pauses for one second
digitalWrite(pin, LOW); // turns 'pin' off
delay(1000); // pauses for one second
}
85
functions
A function is a block of code that has a name and a block of statements that are executed when
the function is called. The functions void setup() and void loop() have already been discussed and other
built-in functions will be discussed later.
Custom functions can be written to perform repetitive tasks and reduce clutter in a program.
Functions are declared by first declaring the function type. This is the type of value to be returned by the
function such as 'int' for an integer type function. If no value is to be returned the function type would be
void. After type, declare the name given to the function and in parenthesis any parameters being passed
to the function.
type functionName(parameters)
{
statements;
}
The following integer type function delayVal() is used to set a delay value in a program by
reading the value of a potentiometer. It first declares a local variable v, sets v to the value of the
potentiometer which gives a number between 0-1023, then divides that value by 4 for a final value
between 0-255, and finally returns that value back to the main program.
int delayVal()
{
int v; // create temporary variable 'v'
v = analogRead(pot); // read potentiometer value
v /= 4; // converts 0-1023 to 0-255
return v; // return final value
}
{} curly braces
Curly braces (also referred to as just "braces" or "curly brackets") define the beginning and
end of function blocks and statement blocks such as the void loop() function and the for and if
statements.
type function()
{
statements;
}
An opening curly brace { must always be followed by a closing curly brace }. This is often
referred to as the braces being balanced. Unbalanced braces can often lead to cryptic, impenetrable
compiler errors that can sometimes be hard to track down in a large program.
The Arduino environment includes a convenient feature to check the balance of curly braces.
Just select a brace, or even click the insertion point immediately following a brace, and its logical
companion will be highlighted.
; semicolon
A semicolon must be used to end a statement and separate elements of the program. A
semicolon is also used to separate elements in a for loop.
86
Note: Forgetting to end a line in a semicolon will result in a compiler error. The error text may be
obvious, and refer to a missing semicolon, or it may not. If an impenetrable or seemingly illogical
compiler error comes up, one of the first things to check is a missing semicolon, near the line where the
compiler complained.
/* */ block comments
Block comments, or multi-line comments, are areas of text ignored by the program and are used
for large text descriptions of code or comments that help others understand parts of the program. They
begin with /* and end with */ and can span multiple lines.
Because comments are ignored by the program and take no memory space they should be used
generously and can also be used to comment out blocks of code for debugging purposes.
Note: While it is possible to enclose single line comments within a block comment, enclosing a second
block comment is not allowed.
// line comments
Single line comments begin with // and end with the next line of code. Like block comments,
they are ignored by the program and take no memory space.
Single line comments are often used after a valid statement to provide more information about
what the statement accomplishes or to provide a future reminder.
variables
A variable is a way of naming and storing a numerical value for later use by the program. As their
namesake suggests, variables are numbers that can be continually changed as opposed to constants
whose value never changes. A variable needs to be declared and optionally assigned to the value
needing to be stored. The following code declares a variable called inputVariable and then assigns it the
value obtained on analog input pin 2:
inputVariable is the variable itself. The first line declares that it will contain an int, short for
integer. The second line sets the variable to the value at analog pin 2. This makes the value of pin 2
accessible elsewhere in the code.
Once a variable has been assigned, or re-assigned, you can test its value to see if it meets
certain conditions, or you can use its value directly. As an example to illustrate three useful operations
with variables, the following code tests whether the inputVariable is less than 100, if true it assigns the
value 100 to inputVariable, and then sets a delay based on inputVariable which is now a minimum of 100:
87
if (inputVariable < 100) // tests variable if less than 100
{
inputVariable = 100; // if true assigns value of 100
}
delay(inputVariable); // uses variable as delay
variable declaration
All variables have to be declared before they can be used. Declaring a variable means defining its
value type, as in int, long, float, etc., setting a specified name, and optionally assigning an initial value.
This only needs to be done once in a program but the value can be changed at any time using arithmetic
and various assignments.
The following example declares that inputVariable is an int, or integer type, and that its initial
value equals zero. This is called a simple assignment.
int inputVariable = 0;
A variable can be declared in a number of locations throughout the program and where this
definition takes place determines what parts of the program can use the variable.
byte
Byte stores an 8-bit numerical value without decimal points. They have a range of 0-255.
int
Integers are the primary datatype for storage of numbers without decimal points and store a 16-
bit value with a range of 32,767 to -32,768.
Note: Integer variables will roll over if forced past their maximum or minimum values by an assignment
or comparison. For example, if x = 32767 and a subsequent statement adds 1 to x, x = x + 1 or x++, x
will then rollover and equal -32,768.
long
Extended size datatype for long integers, without decimal points, stored in a 32-bit value with
a range of 2,147,483,647 to -2,147,483,648.
float
A datatype for floating-point numbers, or numbers that have a decimal point. Floating-point
88
numbers have greater resolution than integers and are stored as a 32-bit value with a range of
3.4028235E+38 to -3.4028235E+38.
Note: Floating-point numbers are not exact, and may yield strange results when compared. Floating
point math is also much slower than integer math in performing calculations, so should be avoided if
possible.
arrays
An array is a collection of values that are accessed with an index number. Any value in the array
may be called upon by calling the name of the array and the index number of the value. Arrays are zero
indexed, with the first value in the array beginning at index number 0. An array needs to be declared and
optionally assigned values before they can be used.
Likewise it is possible to declare an array by declaring the array type and size and later assign values
to an index position:
To retrieve a value from an array, assign a variable to the array and index position:
Arrays are often used in for loops, where the increment counter is also used as the index position
for each array value. The following example uses an array to flicker an LED. Using a for loop, the counter
begins at 0, writes the value contained at index position 0 in the array flicker[], in this case 180, to the
PWM pin 10, pauses for 200ms, then moves to the next index position.
void loop()
{
for(int i=0; i<7; i++) // loop equals number
{ // of values in array
analogWrite(ledPin, flicker[i]); // write index value
delay(200); // pause 200ms
}
}
arithmetic
Arithmetic operators include addition, subtraction, multiplication, and division. They return the
sum, difference, product, or quotient (respectively) of two operands.
89
Y=y+ 3;
x = x - 7;
i = j * 6;
r = r / 5;
The operation is conducted using the data type of the operands, so, for example, 9 / 4
results in 2 instead of 2.25 since 9 and 4 are ints and are incapable of using decimal points.
This also means that the operation can overflow if the result is larger than what can be
stored in the data type.
If the operands are of different types, the larger type is used for the calculation. For example, if
one of the numbers (operands) are of the type float and the other of type integer, floating point math will
be used for the calculation.
comparison operators
Comparisons of one variable or constant against another are often used in if statements to
test if a specified condition is true. In the examples found on the following pages, ?? is used to
indicate any of the following conditions:
// x is equal to y
// x is not equal to y
// x is less than y
// x is greater than y
// x is less than or equal to y
// x is greater than or equal to y
logical operators
Logical operators are usually a way to compare two expressions and return a TRUE or FALSE
depending on the operator. There are three logical operators, AND, OR, and NOT, that are often used in
if statements:
Logical AND:
if (x > 0 && x < 5) // true only if both // expressions are true
Logical OR:
if (x > 0 || y > 0) // true if either
// expression is true
Logical NOT:
if (!x > 0) // true only if
// expression is false
constants
The Arduino language has a few predefined values, which are called constants. They are used to
make the programs easier to read. Constants are classified in groups.
true/false
These are Boolean constants that define logic levels. FALSE is easily defined as 0 (zero) while
TRUE is often defined as 1, but can also be anything else except zero. So in a Boolean sense, -1, 2,
and -200 are all also defined as TRUE.
90
if (b == TRUE);
{
doSomething;
}
high/low
These constants define pin levels as HIGH or LOW and are used when reading or writing to
digital pins. HIGH is defined as logic level 1, ON, or 5 volts while LOW is logic level 0, OFF, or 0 volts.
digitalWrite(13, HIGH);
input/output
Constants used with the pinMode() function to define the mode of a digital pin as either
INPUT or OUTPUT.
pinMode(13, OUTPUT);
if
if statements test whether a certain condition has been reached, such as an analog value being
above a certain number, and executes any statements inside the brackets if the statement is true. If false
the program skips over the statement. The format for an if test is:
if (someVariable ?? value)
{
doSomething;
}
The above example compares some Variable to another value, which can be either a variable or
constant. If the comparison, or condition in parentheses is true, the statements inside the brackets are
run. If not, the program skips over them and continues on after the brackets.
if else
if else allows for either-or decisions to be made. For example, if you wanted to test a digital input, and
do one thing if the input went HIGH or instead do another thing if the input was LOW, you would write that
this way:
if (inputPin == HIGH)
{
doThingA;
}
else
{
doThingB;
}
else can also precede another if test, so that multiple, mutually exclusive tests can be run at the same
time. It is even possible to have an unlimited number of these else branches. Remember though, only
one set of statements will be run depending on the condition tests:
91
doThingA;
}
else if (inputPin >= 1000)
{
doThingB;
}
else
{
doThingC;
}
Note: An if statement simply tests whether the condition inside the parenthesis is true or false. This
statement can be any valid C statement as in the first example, if (inputPin == HIGH). In this example, the
if statement only checks to see if indeed the specified input is at logic level high, or +5v.
for
The for statement is used to repeat a block of statements enclosed in curly braces a specified
number of times. An increment counter is often used to increment and terminate the loop. There are
three parts, separated by semicolons (;), to the for loop header:
The initialization of a local variable, or increment counter, happens first and only once. Each time
through the loop, the following condition is tested. If the condition remains true, the following statements
and expression are executed and the condition is tested again. When the condition becomes false, the
loop ends.
The following example starts the integer i at 0, tests to see if i is still less than 20 and if true,
increments i by 1 and executes the enclosed statements:
while
while loops will loop continuously, and infinitely, until the expression inside the parenthesis
becomes false. Something must change the tested variable, or the while loop will never exit. This could
be in your code, such as an incremented variable, or an external condition, such as testing a sensor.
The following example tests whether someVariable is less than 200 and if true executes
the statements inside the brackets and will continue looping until someVariable is no longer less
than 200.
92
while (someVariable < 200) // tests if less than 200
{
doSomething; // executes enclosed statements
someVariable++; // increments variable by 1
}
do while
The do loop is a bottom driven loop that works in the same manner as the while loop, with the
exception that the condition is tested at the end of the loop, so the do loop will always run at least once.
do
{
doSomething;
} while (someVariable ?? value);
do
{
x = readSensors(); // assigns the value of
// readSensors() to x
delay (50); // pauses 50 milliseconds
} while (x < 100); // loops if x is less than 100
pinMode(pin, mode)
Used in void setup() to configure a specified pin to behave either as an INPUT or an OUTPUT.
Arduino digital pins default to inputs, so they don't need to be explicitly declared as inputs with
pinMode(). Pins configured as INPUT are said to be in a high-impedance state.
There are also convenient 20K pullup resistors built into the Atmega chip that can be
accessed from software. These built-in pullup resistors are accessed in the following manner:
Pullup resistors would normally be used for connecting inputs like switches. Notice in the above
example it does not convert pin to an output, it is merely a method for activating the internal pull-ups.
Pins configured as OUTPUT are said to be in a low-impedance state and can provide 40 mA
(milliamps) of current to other devices/circuits. This is enough current to brightly light up an LED (don't
forget the series resistor), but not enough current to run most relays, solenoids, or motors.
Short circuits on Arduino pins and excessive current can damage or destroy the output pin, or
damage the entire Atmega chip. It is often a good idea to connect an OUTPUT pin to an external
device in series with a 470 or 1K resistor.
digitalRead(pin)
Reads the value from a specified digital pin with the result either HIGH or LOW. The pin can be
specified as either a variable or constant (0-13).
93
value = digitalRead(Pin); // sets 'value' equal to
// the input pin
digitalWrite(pin, value)
Outputs either logic level HIGH or LOW at (turns on or off) a specified digital pin. The pin can be
specified as either a variable or constant (0-13).
The following example reads a pushbutton connected to a digital input and turns on an LED
connected to a digital output when the button has been pressed:
void setup()
{
pinMode(led, OUTPUT); // sets pin 13 as output
pinMode(pin, INPUT); // sets pin 7 as input
}
void loop()
{
value = digitalRead(pin); // sets 'value' equal to
// the input pin
digitalWrite(led, value); // sets 'led' to the
} // button's value
analogRead(pin)
Reads the value from a specified analog pin with a 10-bit resolution. This function only works
on the analog in pins (0-5). The resulting integer values range from 0 to 1023.
Note: Analog pins unlike digital ones, do not need to be first declared as INPUT nor OUTPUT.
analogWrite(pin, value)
Writes a pseudo-analog value using hardware enabled pulse width modulation (PWM) to an
output pin marked PWM. On newer Arduinos with the ATmega168 chip, this function works on pins 3, 5,
6, 9, 10, and 11. Older Arduinos with an ATmega8 only support pins 9, 10, and 11. The value can be
specified as a variable or constant with a value from 0-255.
A value of 0 generates a steady 0 volts output at the specified pin; a value of 255 generates a
steady 5 volts output at the specified pin. For values in between 0 and 255, the pin rapidly alternates
between 0 and 5 volts - the higher the value, the more often the pin is HIGH (5 volts). For example, a
value of 64 will be 0 volts three-quarters of the time, and 5 volts one quarter of the time; a value of 128
will be at 0 half the time and 255 half the time; and a value of 192 will be 0 volts one quarter of the time
and 5 volts three-quarters of the time.
94
Because this is a hardware function, the pin will generate a steady wave after a call to
analogWrite in the background until the next call to analogWrite (or a call to digitalRead or digitalWrite on
the same pin).
Note: Analog pins unlike digital ones, do not need to be first declared as INPUT nor OUTPUT.
The following example reads an analog value from an analog input pin, converts the value by dividing
by 4, and outputs a PWM signal on a PWM pin:
void loop()
{
value = analogRead(pin); // sets 'value' equal to 'pin'
value /= 4; // converts 0-1023 to 0-255
analogWrite(led, value); // outputs PWM signal to led
}
delay(ms)
Pauses a program for the amount of time as specified in milliseconds, where 1000 equals 1
second.
millis()
Returns the number of milliseconds since the Arduino board began running the current
program as an unsigned long value.
Note: This number will overflow (reset back to zero), after approximately 9 hours.
min(x, y)
Calculates the minimum of two numbers of any data type and returns the smaller number.
Serial.begin(rate)
Opens serial port and sets the baud rate for serial data transmission. The typical baud rate for
communicating with the computer is 9600 although other speeds are supported.
95
void setup()
{
Serial.begin(9600); // opens serial port
} // sets data rate to 9600 bps
Note: When using serial communication, digital pins 0 (RX) and 1 (TX) cannot be used at the same
time.
Serial.println(data)
Prints data to the serial port, followed by an automatic carriage return and line feed. This
command takes the same form as Serial.print(), but is easier for reading data on the Serial Monitor.
Note: For more information on the various permutations of the Serial.println() and Serial.print()
functions please refer to the Arduino website.
The following simple example takes a reading from analog pin0 and sends this data to the computer
every 1 second.
void setup()
{
Serial.begin(9600); // sets serial to 9600bps
}
void loop()
{
Serial.println(analogRead(0)); // sends analog value
secon
delay(1000); // pauses for 1 d
}
96
Appendix
digital output
This is the basic hello world program used to simply turn something on or off. In this example, an LED is
connected to pin13, and is blinked every second. The resistor may be omitted on this pin since the Arduino has one
built in.
digital input
This is the simplest form of input with only two possible states: on or off. This example reads a simple switch or
pushbutton connected to pin2. When the switch is closed the input pin will read HIGH and turn on an LED.
void setup()
{
pinMode(ledPin, OUTPUT); // declare LED as output
pinMode(inPin, INPUT); // declare switch as input
}
void loop()
{
if (digitalRead(inPin) == HIGH) // check if input is HIGH
{
digitalWrite(ledPin, HIGH); // turns the LED on
97
delay(1000); // pause for 1 second
digitalWrite(ledPin, LOW); // turns the LED off
delay(1000); // pause for 1 second
}
}
Sometimes it is necessary to control more than 40ma from the Arduino. In this case a MOSFET
or transistor could be used to switch higher current loads. The following example quickly turns on and off
the MOSFET 5 times every second.
Note: The schematic shows a motor and protection diode but other non-inductive loads could be used
without the diode.
void setup()
{
pinMode(outPin, OUTPUT); // sets pin5 as output
}
void loop()
{
for (int i=0; i<=5; i++) // loops 5 times
{
digitalWrite(outPin, HIGH); // turns MOSFET on
98
pwm output
Pulsewidth Modulation (PWM) is a way to fake an analog output by pulsing the output. This could
be used to dim and brighten an LED or later to control a servo motor. The following example slowly
brightens and dims an LED using for loops.
void loop()
{
for (int i=0; i<=255; i++) // ascending value for i
{
analogWrite(ledPin, i); // sets brightess level to i
delay(100); // pauses for 100ms
}
for (int i=255; i>=0; i--) // descending value for i
{
analogWrite(ledPin, i); // sets brightess level to i
delay(100); // pauses for 100ms
}
}
potentiometer input
Using a potentiometer and one of the Arduinos analog-to-digital conversion (ADC) pins it is
possible to read analog values from 0-1024. The following example uses a potentiometer to control an
LEDs rate of blinking.
int potPin = 0; // input pin for the potentiometer int ledPin = 13; // output pin for the LED
void setup()
{
pinMode(ledPin, OUTPUT); // declare ledPin as OUTPUT
}
void loop()
{
99
digitalWrite(ledPin, HIGH); // turns ledPin on
delay(analogRead(potPin)); // pause program
digitalWrite(ledPin, LOW); // turns ledPin off
delay(analogRead(potPin)); // pause program
}
variable resistor input
Variable resistors include CdS light sensors, thermistors, flex sensors, and so on. This example
makes use of a function to read the analog value and set a delay time. This controls the speed at which
an LED brightens and dims.
void loop()
{
for (int i=0; i<=255; i++) // ascending value for i
{
analogWrite(ledPin, i); // sets brightess level to i
delay(delayVal()); // gets time value and pauses
}
for (int i=255; i>=0; i--) // descending value for i
{
analogWrite(ledPin, i); // sets brightess level to i
delay(delayVal()); // gets time value and pauses
}
}
int delayVal()
{
int v; // create temporary variable
v = analogRead(analogPin); // read analog value
v /= 8; // convert 0-1024 to 0-128
return v; // returns final value
}
servo output
100
Hobby servos are a type of self-contained motor that can move in a 180 arc. All that is needed is a pulse
sent every 20ms. This example uses a servoPulse function to move the servo from 10 -170 and back
again.
void setup()
{
pinMode(servoPin, OUTPUT); // sets pin 2 as output
}
void loop()
{
// servo starts at 10 deg and rotates to 170 deg for (myAngle=10; myAngle<=170;
myAngle++)
{
servoPulse(servoPin, myAngle); // send pin and angle
delay(20); // refresh cycle
}
// servo starts at 170 deg and rotates to 10 deg for (myAngle=170; myAngle>=10;
myAngle--)
{
servoPulse(servoPin, myAngle); // send pin and angle
delay(20); // refresh cycle
}
}
101
ARDUINO Examples
Blink
// Turns on an LED on for one second, then off for one second, repeatedly.
*/
/*
Fade
102
// wait for 30 milliseconds to see the dimming effect
delay(30);
}
Turns on and off a light emitting diode(LED) connected to a digital pin, without using the delay()
function. This means that other code can run at the same time without being interrupted by the LED
code.
*/
void setup() {
// set the digital pin as output:
pinMode(ledPin, OUTPUT);
}
void loop()
{
// here is where you'd put code that needs to be running all the time.
// check to see if it's time to blink the LED; that is, if the
// difference between the current time and last time you blinked
// the LED is bigger than the interval at which you want to
// blink the LED.
unsigned long currentMillis = millis();
103
Demonstrates one technique for calibrating sensor input. The sensor readings during the first five
seconds of the sketch execution define the minimum and maximum of expected values
attached to the sensor pin.
The sensor minimum and maximum initial values may seem backwards. Initially, you set the minimum
high and listen for anything lower, saving it as the new minimum. Likewise, you set the maximum low
and listen for anything higher as the new maximum.
// variables:
int sensorValue = 0; // the sensor value
int sensorMin = 1023; // minimum sensor value
int sensorMax = 0; // maximum sensor value
void setup() {
// turn on LED to signal the start of the calibration period:
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);
void loop() {
// read the sensor:
sensorValue = analogRead(sensorPin);
// in case the sensor value is outside the range seen during calibration
sensorValue = constrain(sensorValue, 0, 255);
104