summaryrefslogtreecommitdiff
path: root/user-code/servo/servo-python.tex
blob: b29cdebfc126342023dd8dd68376675d7df1abc3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
\section{Controlling servomotor through Python}
\subsection{Controlling the servomotor}
\label{sec:servo-py}
In this section, we discuss how to carry out the experiments of the
previous section from Python.  We will list the same four experiments,
in the same order. The Shield has to be attached to the \arduino\ board
before doing these experiments and the \arduino\ needs to be connected to the computer 
with a USB cable, as shown in \figref{arduino}. The reader should go through the instructions given in
\secref{sec:python-start} before getting started.

% In this section, we will carry out the servomotor control experiments
% using python.  We will follow the same order as in
% \secref{sec:servo-ard}.  We assume that the shield is attached to the
% \arduino\ board while doing these experiments.  They will work without
% the shield also, but in this case, our comments on colour LEDs
% lighting will not be applicable.  The reader should go through the
% instructions given in \secref{sec:py-start} before getting started.

\begin{enumerate}
  \item The first experiment makes the servomotor move by $30^\circ$. The code for this experiment is
        given in \pyref{py:servo-init}. As explained earlier in \secref{sec:light-py}, 
        we begin with importing necessary modules followed by setting up the serial port.
        Next, we attach the servomotor by issuing the command given below:
        \lstinputlisting[firstline=24,lastline=24]{\LocSERpycode/servo-init.py}
        As shown above, the servomotor is attached on board 1 (the first argument)
        to pin 1 (the second argument).  In Python-Arduino toolbox discussed 
        in \secref{sec:python-toolbox}, pin 1 and pin 5 are connected. As a result, we connect the wire physically to
        pin 5, which is achieved by the Shield as discussed in \secref{sec:servo-pril}.
        
        With this, we issue the command to move the servomotor by $30^\circ$ followed by a delay of 
        1 second:
        \lstinputlisting[firstline=25,lastline=26]
        {\LocSERpycode/servo-init.py}
        At last, we  detach the servomotor followed by closing the serial port. 
        
        Once this code is executed, the servomotor would move by
        $30^\circ$, as commanded.  What happens if this code is executed
        once again?  The motor will not move at all.  What is the reason?
        Recall that what we assign to the motor are absolute positions, with
        respect to a fixed origin.  As a result, there will be no change at
        all. 
        
  \item In the second experiment, we move the servomotor by $90^\circ$ in the
        forward direction and $45^\circ$ in the reverse direction.  This
        code is given in \pyref{py:servo-reverse}.  In this code, 
        we have added a delay of 1 second between the two instances of 
        moving the servomotor: 
        \lstinputlisting[firstline=25,lastline=27]
        {\LocSERpycode/servo-reverse.py}
        What is the reason behind this delay?  If the delay were not
        there, the motor will move only by the net angle of $90-45 = 45$
        degrees.  The reader should verify this by commenting on the delay
        command. 
        
        % In \sciref{sci:servo-reverse}, we make the servomotor rotate
        % to $90^\circ$, wait for a second and go to $45^\circ$.  As mentioned
        % earlier, the angles are absolute with respect to a fixed reference
        % point and not relative.  
        
        
  \item In the third experiment, we move the motor in increments of
        $20^\circ$.  This is achieved by the {\tt for} loop, as in
        \pyref{py:servo-loop}. The code helps the motor move in steps of $20^\circ$ all
        the way to $180^\circ$.  
        
  \item Finally, in the last experiment, we read the potentiometer value
        from the Shield and use it to drive the servomotor, see
        \pyref{py:servo-pot}.  The resistance of the potentiometer is
        represented in 10 bits.  As a result, the resistance value could be
        any one of 1024 values, from 0 to 1023.  This entire range is
        mapped to $180^\circ$, as shown below:
        \lstinputlisting[firstline=27,lastline=29]
        {\LocSERpycode/servo-pot.py}
        By rotating the potentiometer, one can make
        the motor move by different amounts.
        
        As mentioned in \chapref{potmeter}, the potentiometer on the Shield is connected 
        to analog pin 2 on \arduino. Through this pin, the resistance of the potentiometer, in the range of 0 to 1023,
        depending on its position, is read.  Thus, by rotating the
        potentiometer, we make different values appear on pin 2.  This value
        is used to move the servo.  For example, if the resistance is half
        of the total, the servomotor will go to $90^\circ$ and so on.  The
        servomotor stops for 500 milliseconds after every move.  The loop is
        executed for 50 iterations. During this period, the servomotor keeps moving as dictated by the
        resistance of the potentiometer. While running this experiment, the readers 
        must rotate the knob of the potentiometer by a fixed amount and observe 
        the change in the position (or angle) of the servomotor.   
        % In the first experiment, we will learn how to drive the servomotor motor
        % from Python. The code for this experiment is 
        % given in  \pyref{py:servo-init}. 
        
        % The first experiment makes the servomotor move by $30^\circ$,
        %       the code for which is given in \pyref{py:servo-init}.
        %       It first opens com port 2 in \arduino\ card number 1 with baud rate
        %       of 115200.  If the port opening is unsuccessful {\tt ok} will not be
        %       0 and the program terminates, asking the user to correct the
        %       problem.  Else If the port opening is successful, {\tt ok} will be 0
        %       and the program proceeds.  In Line number 3 of the code, \ie\
        %       \lstinputlisting[firstline=3,lastline=3]{\LocSERpycode/servo-init.py}
        %       we say that the servomotor is attached on board 1 (the first entry)
        %       to pin 1 (the second entry).  In the \scilab\ toolbox, pin 1 and pin
        %       9 are connected and as a result, we connect the wire physically to
        %       pin 9.  Similarly, pins 2 and 10 are connected through the
        %       \scilab\ toolbox.
        
        % \item In \sciref{py:servo-reverse}, we make the servomotor rotate
        %       to $90^\circ$, wait for a second and go to $45^\circ$.  As mentioned
        %       earlier, the angles are absolute with respect to a fixed reference
        %       point and not relative.  
        
        % \item In the next experiment, we rotate the servomotor in discrete
        %       steps of $20^\circ$.  This is achieved by multiplying $20^\circ$ by
        %       an integer {\tt i}, which varies from 0 to 10.  Once the maximum
        %       angle reaches $180^\circ$, it stops.  
        
        % \item Finally, in the last experiment, we position the servomotor
        %       through the potentiometer in the code \pyref{py:servo-pot}.  As we
        %       rotate the potentiometer, the servomotor's angle also changes.  The
        %       potentiometer value is read through pin 2, in line number 5, as
        %       below:
        %       \lstinputlisting[firstline=5,lastline=5]{\LocSERpycode/servo-pot.py}
        %       This value is mapped into a value between 0 and $180^\circ$ by
        %       multiplying with $180/1023$ in line 6:
        %       \lstinputlisting[firstline=6,lastline=6]{\LocSERpycode/servo-pot.py}
        %       The {\tt floor} function gets the integer part of the number by
        %       truncation.  This is the angle by which the potentiometer is to be
        %       moved.  Truncation is a not a crucial calculation, however.  In
        %       every iteration, the servomotor's position is calculated, and placed
        %       for half a second.  This loop is iterated upon 5,000 times.
\end{enumerate}

\subsection{Python Code}
\lstset{style=mystyle}
\label{sec:servo-python-code}
\addtocontents{pyd}{\protect\addvspace{\codclr}}

\begin{pycode}
  \pcaption{Rotating the servomotor to a specified degree} {Rotating
    the servomotor to a specified degree.  Available at
    \LocSERpybrief{servo-init.py}.}
  \label{py:servo-init}
  \lstinputlisting{\LocSERpycode/servo-init.py}
\end{pycode}

\begin{pycode}
  \pcaption{Rotating the servomotor to a specified degree and
    reversing} {Rotating
    the servomotor to a specified degree and reversing.  Available at
    \LocSERpybrief{servo-reverse.py}.}
  \label{py:servo-reverse}
  \lstinputlisting{\LocSERpycode/servo-reverse.py}
\end{pycode}

\begin{pycode}
  \pcaption{Rotating the servomotor in steps of $20^\circ$}{Rotating
    the servomotor in steps of $20^\circ$.  Available at 
    \LocSERpybrief{servo-loop.py}.}
  \label{py:servo-loop}
  \lstinputlisting{\LocSERpycode/servo-loop.py}
\end{pycode}

\begin{pycode}
  \pcaption{Rotating the servomotor to a degree specified by the
    potentiometer} {Rotating the servomotor to a degree specified by
    the potentiometer.  Available at \LocSERpybrief{servo-pot.py}.}
  \label{py:servo-pot}
  \lstinputlisting{\LocSERpycode/servo-pot.py}
\end{pycode}