Forum | Documentation | Website | Blog

Skip to content
Snippets Groups Projects
Commit 7fc0b646 authored by Jason Kridner's avatar Jason Kridner
Browse files

books/beaglebone-cookbook/capes: update callouts

Using style from https://github.com/ray-project/ray/pull/28376

The extension code would need to be added for this to work.
parent 4051a3bf
Branches
Tags
No related merge requests found
......@@ -85,7 +85,7 @@ You want to use a small LCD to display things other than the desktop.
Solution
---------
The `MiniDisplay <http://bit.ly/1xd0r8>`p_ is a 128 x 128 full-color LCD cape that just fits on the
The `MiniDisplay <http://bit.ly/1xd0r8p>`_ is a 128 x 128 full-color LCD cape that just fits on the
Bone, as shown in :ref:`capes_miniDisplay_fig`.
.. _capes_miniDisplay_fig:
......@@ -122,7 +122,7 @@ Attach to the Bone and apply power. Then run the following commands:
The MiniDisplay uses the Serial Peripheral Interface (SPI) interface, and it's not initialized.
The `manufacturer's website <http://bit.ly/1xd0r8p>`_ suggests enabling SPI0 by using the following commands:
.. code-block:: bash
.. code-block:: shell-session
bone$ export SLOTS=/sys/devices/bone_capemgr.*/slots
bone$ echo BB-SPIDEV0 &gt; $SLOTS
......@@ -130,53 +130,54 @@ The `manufacturer's website <http://bit.ly/1xd0r8p>`_ suggests enabling SPI0 by
Hmmm, something isn't working here. Here's how to see what happened:
.. code-block:: bash
.. callout::
.. code-block:: shell-session
bone$ dmesg | tail
[ 625.334497] bone_capemgr.9: part_number 'BB-SPIDEV0', version 'N/A'
[ 625.334673] bone_capemgr.9: slot #11: generic override
[ 625.334720] bone_capemgr.9: bone: Using override eeprom data at slot 11
[ 625.334769] bone_capemgr.9: slot #11: 'Override Board Name,00A0,Override \
Manuf,BB-SPIDEV0'
[ 625.335026] bone_capemgr.9: slot #11: \Requesting part number/version based \
'BB-SPIDEV0-00A0.dtbo
[ 625.335076] bone_capemgr.9: slot #11: Requesting firmware \
'BB-SPIDEV0-00A0.dtbo' \
for board-name 'Override Board Name', version '00A0'
[ 625.335144] bone_capemgr.9: slot #11: dtbo 'BB-SPIDEV0-00A0.dtbo' loaded; \
converting to live tree
[ 625.341842] bone_capemgr.9: slot #11: BB-SPIDEV0 conflict P9.21 \
(#10:bspwm_P9_21_b) <a class="co" id="capemgr_conflict_co" href="#capemgr_conflict" ><img src="callouts/1.png" alt="1"/></a>
[ 625.351296] bone_capemgr.9: slot #11: Failed verification
bone$ dmesg | tail
[ 625.334497] bone_capemgr.9: part_number 'BB-SPIDEV0', version 'N/A'
[ 625.334673] bone_capemgr.9: slot #11: generic override
[ 625.334720] bone_capemgr.9: bone: Using override eeprom data at slot 11
[ 625.334769] bone_capemgr.9: slot #11: 'Override Board Name,00A0,Override \
Manuf,BB-SPIDEV0'
[ 625.335026] bone_capemgr.9: slot #11: \Requesting part number/version based \
'BB-SPIDEV0-00A0.dtbo
[ 625.335076] bone_capemgr.9: slot #11: Requesting firmware \
'BB-SPIDEV0-00A0.dtbo' \
for board-name 'Override Board Name', version '00A0'
[ 625.335144] bone_capemgr.9: slot #11: dtbo 'BB-SPIDEV0-00A0.dtbo' loaded; \
converting to live tree
[ 625.341842] bone_capemgr.9: slot #11: BB-SPIDEV0 conflict P9.21 \
(#10:bspwm_P9_21_b) # <1>
[ 625.351296] bone_capemgr.9: slot #11: Failed verification
.. annotations::
<1> Shows there is a conflict for pin <code>P9_21</code>: it's already configured for pulse width modulation (PWM).
Here's how to see what's already configured:
.. <dl class="calloutlist">
.. <dt><a class="co" id="capemgr_conflict" href="#capemgr_conflict_co"><img src="callouts/1.png" alt="1"/></a></dt>
.. <dd>Shows there is a conflict for pin <code>P9_21</code>: it's already configured for pulse width modulation (PWM).</dd>
.. </dl>
Here's how to see what's already configured:
.. callout::
.. code-block:: bash
.. code-block:: shell-session
bone$ cat $SLOTS
0: 54:PF---
1: 55:PF---
2: 56:PF---
3: 57:PF---
4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G
5: ff:P-O-L Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI
7: ff:P-O-L Override Board Name,00A0,Override Manuf,bspm_P9_42_27
8: ff:P-O-L Override Board Name,00A0,Override Manuf,bspm_P9_41_27
9: ff:P-O-L Override Board Name,00A0,Override Manuf,am33xx_pwm
10: ff:P-O-L Override Board Name,00A0,Override Manuf,bspwm_P9_21_b <a class="co" id="capemgr_load_co" href="#capemgr_load"><img src="callouts/1.png" alt="1"/></a>
bone$ cat $SLOTS
0: 54:PF---
1: 55:PF---
2: 56:PF---
3: 57:PF---
4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G
5: ff:P-O-L Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI
7: ff:P-O-L Override Board Name,00A0,Override Manuf,bspm_P9_42_27
8: ff:P-O-L Override Board Name,00A0,Override Manuf,bspm_P9_41_27
9: ff:P-O-L Override Board Name,00A0,Override Manuf,am33xx_pwm
10: ff:P-O-L Override Board Name,00A0,Override Manuf,bspwm_P9_21_b # <1>
.. annotations::
.. <dl class="calloutlist">
.. <dt><a id="capemgr_load" href="#capemgr_load_co"><img src="callouts/1.png" alt="1"/></a></dt>
.. <dd>You can see the eMMC, HDMI, and three PWMs are already using some of the pins. Slot 10 shows <code>P9_21</code> is in use by a PWM.</dd>
.. </dl>
<1> You can see the eMMC, HDMI, and three PWMs are already using some of the pins. Slot 10 shows <code>P9_21</code> is in use by a PWM.
You can unconfigure it by using the following commands:
......@@ -431,147 +432,146 @@ the test status with the code in :ref:`capes_quickBot_motor_test_code`.
Testing the quickBot motors interface (quickBot_motor_test.js)
==============================================================
.. code-block:: bash
.. callout::
.. code-block:: javascript
#!/usr/bin/env node
var b = require('bonescript');
var M1_SPEED = 'P9_16'; // <1>
var M1_FORWARD = 'P8_15';
var M1_BACKWARD = 'P8_13';
var M2_SPEED = 'P9_14';
var M2_FORWARD = 'P8_9';
var M2_BACKWARD = 'P8_11';
var freq = 50; // <2>
var fast = 0.95;
var slow = 0.7;
var state = 0; // <3>
b.pinMode(M1_FORWARD, b.OUTPUT); // <4>
b.pinMode(M1_BACKWARD, b.OUTPUT);
b.pinMode(M2_FORWARD, b.OUTPUT);
b.pinMode(M2_BACKWARD, b.OUTPUT);
b.analogWrite(M1_SPEED, 0, freq); // <5>
b.analogWrite(M2_SPEED, 0, freq);
updateMotors(); // <6>
function updateMotors() {
//console.log("Setting state = " + state); // <7>
updateLEDs(state);
switch(state) { // <3>
case 0:
default:
M1_set(0); // <8>
M2_set(0);
state = 1; // <3>
break;
case 1:
M1_set(slow);
M2_set(slow);
state = 2;
break;
case 2:
M1_set(slow);
M2_set(-slow);
state = 3;
break;
case 3:
M1_set(-slow);
M2_set(slow);
state = 4;
break;
case 4:
M1_set(fast);
M2_set(fast);
state = 0;
break;
}
setTimeout(updateMotors, 2000); // <3>
}
#!/usr/bin/env node
var b = require('bonescript');
var M1_SPEED = 'P9_16'; <a class="co" id="co_hello_CO1-1_unique" href="#callout_hello_CO1-1_unique"><img src="callouts/1.png" alt="1"/></a>
var M1_FORWARD = 'P8_15';
var M1_BACKWARD = 'P8_13';
var M2_SPEED = 'P9_14';
var M2_FORWARD = 'P8_9';
var M2_BACKWARD = 'P8_11';
var freq = 50; <a class="co" id="co_hello_CO1-2_unique" href="#callout_hello_CO1-2_unique"><img src="callouts/2.png" alt="2"/></a>
var fast = 0.95;
var slow = 0.7;
var state = 0; <a class="co" id="co_hello_CO1-3_unique" href="#callout_hello_CO1-3_unique"><img src="callouts/3.png" alt="3"/></a>
b.pinMode(M1_FORWARD, b.OUTPUT); <a class="co" id="co_hello_CO1-4_unique" href="#callout_hello_CO1-4_unique"><img src="callouts/4.png" alt="4"/></a>
b.pinMode(M1_BACKWARD, b.OUTPUT);
b.pinMode(M2_FORWARD, b.OUTPUT);
b.pinMode(M2_BACKWARD, b.OUTPUT);
b.analogWrite(M1_SPEED, 0, freq); <a class="co" id="co_hello_CO1-5_unique" href="#callout_hello_CO1-5_unique"><img src="callouts/5.png" alt="5"/></a>
b.analogWrite(M2_SPEED, 0, freq);
updateMotors(); <a class="co" id="co_hello_CO1-6_unique" href="#callout_hello_CO1-6_unique"><img src="callouts/6.png" alt="6"/></a>
function updateMotors() { <img src="callouts/6.png" alt="6"/>
//console.log("Setting state = " + state); <a class="co" id="co_hello_CO1-7_unique" href="#callout_hello_CO1-7_unique"><img src="callouts/7.png" alt="7"/></a>
updateLEDs(state); <img src="callouts/7.png" alt="7"/>
switch(state) { <img src="callouts/3.png" alt="3"/>
function updateLEDs(state) { // <7>
switch(state) {
case 0:
default:
M1_set(0); <a class="co" id="co_hello_CO1-8_unique" href="#callout_hello_CO1-8_unique"><img src="callouts/8.png" alt="8"/></a>
M2_set(0);
state = 1; <img src="callouts/3.png" alt="3"/>
b.digitalWrite("USR0", b.LOW);
b.digitalWrite("USR1", b.LOW);
b.digitalWrite("USR2", b.LOW);
b.digitalWrite("USR3", b.LOW);
break;
case 1:
M1_set(slow);
M2_set(slow);
state = 2;
b.digitalWrite("USR0", b.HIGH);
b.digitalWrite("USR1", b.LOW);
b.digitalWrite("USR2", b.LOW);
b.digitalWrite("USR3", b.LOW);
break;
case 2:
M1_set(slow);
M2_set(-slow);
state = 3;
b.digitalWrite("USR0", b.LOW);
b.digitalWrite("USR1", b.HIGH);
b.digitalWrite("USR2", b.LOW);
b.digitalWrite("USR3", b.LOW);
break;
case 3:
M1_set(-slow);
M2_set(slow);
state = 4;
b.digitalWrite("USR0", b.LOW);
b.digitalWrite("USR1", b.LOW);
b.digitalWrite("USR2", b.HIGH);
b.digitalWrite("USR3", b.LOW);
break;
case 4:
M1_set(fast);
M2_set(fast);
state = 0;
b.digitalWrite("USR0", b.LOW);
b.digitalWrite("USR1", b.LOW);
b.digitalWrite("USR2", b.LOW);
b.digitalWrite("USR3", b.HIGH);
break;
}
}
setTimeout(updateMotors, 2000); <img src="callouts/3.png" alt="3"/>
}
function updateLEDs(state) { <img src="callouts/7.png" alt="7"/>
switch(state) {
case 0:
b.digitalWrite("USR0", b.LOW);
b.digitalWrite("USR1", b.LOW);
b.digitalWrite("USR2", b.LOW);
b.digitalWrite("USR3", b.LOW);
break;
case 1:
b.digitalWrite("USR0", b.HIGH);
b.digitalWrite("USR1", b.LOW);
b.digitalWrite("USR2", b.LOW);
b.digitalWrite("USR3", b.LOW);
break;
case 2:
b.digitalWrite("USR0", b.LOW);
b.digitalWrite("USR1", b.HIGH);
b.digitalWrite("USR2", b.LOW);
b.digitalWrite("USR3", b.LOW);
break;
case 3:
b.digitalWrite("USR0", b.LOW);
b.digitalWrite("USR1", b.LOW);
b.digitalWrite("USR2", b.HIGH);
b.digitalWrite("USR3", b.LOW);
break;
case 4:
b.digitalWrite("USR0", b.LOW);
b.digitalWrite("USR1", b.LOW);
b.digitalWrite("USR2", b.LOW);
b.digitalWrite("USR3", b.HIGH);
break;
}
}
function M1_set(speed) { <img src="callouts/8.png" alt="8"/>
speed = (speed &gt; 1) ? 1 : speed; <a class="co" id="co_hello_CO1-9_unique" href="#callout_hello_CO1-9_unique"><img src="callouts/9.png" alt="9"/></a>
speed = (speed &lt; -1) ? -1 : speed;
b.digitalWrite(M1_FORWARD, b.LOW);
b.digitalWrite(M1_BACKWARD, b.LOW);
if(speed &gt; 0) {
b.digitalWrite(M1_FORWARD, b.HIGH);
} else if(speed &lt; 0) {
b.digitalWrite(M1_BACKWARD, b.HIGH);
}
b.analogWrite(M1_SPEED, Math.abs(speed), freq); <a class="co" id="co_hello_CO1-10_unique" href="#callout_hello_CO1-10_unique"><img src="callouts/10.png" alt="10"/></a>
}
function M2_set(speed) {
speed = (speed &gt; 1) ? 1 : speed;
speed = (speed &lt; -1) ? -1 : speed;
b.digitalWrite(M2_FORWARD, b.LOW);
b.digitalWrite(M2_BACKWARD, b.LOW);
if(speed &gt; 0) {
b.digitalWrite(M2_FORWARD, b.HIGH);
} else if(speed &lt; 0) {
b.digitalWrite(M2_BACKWARD, b.HIGH);
function M1_set(speed) { <img src="callouts/8.png" alt="8"/>
speed = (speed &gt; 1) ? 1 : speed; // <9>
speed = (speed &lt; -1) ? -1 : speed;
b.digitalWrite(M1_FORWARD, b.LOW);
b.digitalWrite(M1_BACKWARD, b.LOW);
if(speed &gt; 0) {
b.digitalWrite(M1_FORWARD, b.HIGH);
} else if(speed &lt; 0) {
b.digitalWrite(M1_BACKWARD, b.HIGH);
}
b.analogWrite(M1_SPEED, Math.abs(speed), freq); // <10>
}
b.analogWrite(M2_SPEED, Math.abs(speed), freq);
function M2_set(speed) {
speed = (speed &gt; 1) ? 1 : speed;
speed = (speed &lt; -1) ? -1 : speed;
b.digitalWrite(M2_FORWARD, b.LOW);
b.digitalWrite(M2_BACKWARD, b.LOW);
if(speed &gt; 0) {
b.digitalWrite(M2_FORWARD, b.HIGH);
} else if(speed &lt; 0) {
b.digitalWrite(M2_BACKWARD, b.HIGH);
}
b.analogWrite(M2_SPEED, Math.abs(speed), freq);
.. <dl class="calloutlist">
.. <dt><a class="co" id="callout_hello_CO1-1_unique" href="#co_hello_CO1-1_unique"><img src="callouts/1.png" alt="1"/></a></dt>
.. <dd><p>Define each pin as a variable. This makes it easy to change to another pin if you decide that is necessary.</p></dd>
.. <dt><a class="co" id="callout_hello_CO1-2_unique" href="#co_hello_CO1-2_unique"><img src="callouts/2.png" alt="2"/></a></dt>
.. <dd><p>Make other simple parameters variables. Again, this makes it easy to update them. When creating this test, I found that the PWM frequency to drive the motors needed to be relatively low to get over the kickback shown in <a data-type="xref" href="#quickBot_motor_kickback"/>. I also found that I needed to get up to about 70 percent duty cycle for my circuit to reliably start the motors turning.</p></dd>
.. <dt><a class="co" id="callout_hello_CO1-3_unique" href="#co_hello_CO1-3_unique"><img src="callouts/3.png" alt="3"/></a></dt>
.. <dd><p>Use a simple variable such as <code>state</code> to keep track of the test phase. This is used in a <code>switch</code> statement to jump to the code to configure for that test phase and updated after configuring for the current phase in order to select the next phase. Note that the next phase isn&#8217;t entered until after a two-second delay, as specified in the call to <code>setTimeout()</code>.</p></dd>
.. <dt><a class="co" id="callout_hello_CO1-4_unique" href="#co_hello_CO1-4_unique"><img src="callouts/4.png" alt="4"/></a></dt>
.. <dd><p>Perform the initial setup of all the pins.</p></dd>
.. <dt><a class="co" id="callout_hello_CO1-5_unique" href="#co_hello_CO1-5_unique"><img src="callouts/5.png" alt="5"/></a></dt>
.. <dd><p>The first time a PWM pin is used, it is configured with the update frequency. It is important to set this just once to the right frequency, because other PWM channels might use the same PWM controller, and attempts to reset the PWM frequency might fail. The <code>pinMode()</code> function doesn&#8217;t have an argument for providing the update frequency, so use the <code>analogWrite()</code> function, instead. You can review using the PWM in <a data-type="xref" href="#motors_servo"/>.</p></dd>
.. <dt><a class="co" id="callout_hello_CO1-6_unique" href="#co_hello_CO1-6_unique"><img src="callouts/6.png" alt="6"/></a></dt>
.. <dd><p><code>updateMotors()</code> is the test function for the motors and is defined after all the setup and initialization code. The code calls this function every two seconds using the <code>setTimeout()</code> JavaScript function. The first call is used to prime the loop.</p></dd>
.. <dt><a class="co" id="callout_hello_CO1-7_unique" href="#co_hello_CO1-7_unique"><img src="callouts/7.png" alt="7"/></a></dt>
.. <dd><p>The call to <code>console.log()</code> was initially here to observe the state transitions in the debug console, but it was replaced with the <code>updateLEDs()</code> call. Using the <code>USER</code> LEDs makes it possible to note the state transitions without having visibility of the debug console. <code>updateLEDs()</code> is defined later.</p></dd>
.. <dt><a class="co" id="callout_hello_CO1-8_unique" href="#co_hello_CO1-8_unique"><img src="callouts/8.png" alt="8"/></a></dt>
.. <dd><p>The <code>M1_set()</code> and <code>M2_set()</code> functions are defined near the bottom and do the work of configuring the motor drivers into a particular state. They take a single argument of <code>speed</code>, as defined between <code>-1</code> (maximum reverse), <code>0</code> (stop), and <code>1</code> (maximum forward).</p></dd>
.. <dt><a class="co" id="callout_hello_CO1-9_unique" href="#co_hello_CO1-9_unique"><img src="callouts/9.png" alt="9"/></a></dt>
.. <dd><p>Perform simple bounds checking to ensure that speed values are between <code>-1</code> and <code>1</code>.</p></dd>
.. <dt><a class="co" id="callout_hello_CO1-10_unique" href="#co_hello_CO1-10_unique"><img src="callouts/10.png" alt="10"/></a></dt>
.. <dd><p>The <code>analogWrite()</code> call uses the absolute value of <code>speed</code>, making any negative numbers a positive magnitude.</p></dd>
.. </dl>
<1> Define each pin as a variable. This makes it easy to change to another pin if you decide that is necessary.
<2> Make other simple parameters variables. Again, this makes it easy to update them. When creating this test, I found that the PWM frequency to drive the motors needed to be relatively low to get over the kickback shown in :ref:`quickBot_motor_kickback`. I also found that I needed to get up to about 70 percent duty cycle for my circuit to reliably start the motors turning.
<3> Use a simple variable such as `state` to keep track of the test phase. This is used in a `switch` statement to jump to the code to configure for that test phase and updated after configuring for the current phase in order to select the next phase. Note that the next phase isn&#8217;t entered until after a two-second delay, as specified in the call to `setTimeout()`.
<4> Perform the initial setup of all the pins.
<5> The first time a PWM pin is used, it is configured with the update frequency. It is important to set this just once to the right frequency, because other PWM channels might use the same PWM controller, and attempts to reset the PWM frequency might fail. The <code>pinMode()</code> function doesn&#8217;t have an argument for providing the update frequency, so use the <code>analogWrite()</code> function, instead. You can review using the PWM in :ref:`motors_servo`.
<6> `updateMotors()` is the test function for the motors and is defined after all the setup and initialization code. The code calls this function every two seconds using the `setTimeout()` JavaScript function. The first call is used to prime the loop.
<7> The call to `console.log()` was initially here to observe the state transitions in the debug console, but it was replaced with the `updateLEDs()` call. Using the `USER` LEDs makes it possible to note the state transitions without having visibility of the debug console. `updateLEDs()` is defined later.
<8> The `M1_set()` and `M2_set()` functions are defined near the bottom and do the work of configuring the motor drivers into a particular state. They take a single argument of `speed`, as defined between `-1` (maximum reverse), `0` (stop), and `1` (maximum forward).
<9> Perform simple bounds checking to ensure that speed values are between `-1` and `1`.
<10> The `analogWrite()` call uses the absolute value of `speed`, making any negative numbers a positive magnitude.
.. _quickBot_motor_kickback:
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment