TABLE OF CONTENTS

BBAI

 

INTRODUCTION

Presently, the BeagleBone AI is in what feels like a beta state requiring a certain combination of a particular kernel version and additional code tweaks to get the examples working.  This is because the time-tested BeagleBoard code libraries at the time of hardware release were still developed for the past architectures.  This guide is from my notes and hours of research as a BeagleBone newcomer to get the AI utilizing its GPIO.

 

After I did all the steps in the checklist below and the Pinmux Procedure, I did a shutdown and burned an image of it so I can recover faster from future bricks.  Also, way below are some key references to keep your eye on as the AI develops.  Last, for document versioning, I'll use this convention to keep track of changes to this blog:  Whole versions for when new software is added, decimal versions when I change the instructions only, and no version increments if I'm just correcting my Kentucky English.

 

BBAI SETUP CHECKLIST

 

  1. Download the latest image - be sure it is for BeagleBone AI:
    https://beagleboard.org/latest-images
    https://debian.beagleboard.org/images/am57xx-debian-9.9-lxqt-armhf-2019-08-03-4gb.img.xz
  2. Burn it with Etcher to an SD card 8 to 32 Gig.  (other sizes have reported problems)
    https://www.techspot.com/downloads/6931-etcher.html
    BeagleBoard.org - getting-started
  3. Put the card in BBAI, power it, connect PC to it using wifi SSID BeagleBoneXXXX, and connect to Cloud9 by navigating to 192.168.8.1.
  4. Follow on screen instructions in cloud9 to connect BBAI to your home wifi summarized here:
    sudo connmanctl⏎
    scan wifi⏎  (wait for response)
    services⏎ (copy the long string representing your wifi)
    agent on⏎
    connect <paste your string>
    quit⏎
  5. Get the max storage capacity out of your SD Card:
    sudo /opt/scripts/tools/grow_partition.sh
    sudo reboot
  6. Get latest Cloud9 Examples:
    cd /var/lib/cloud9⏎
    git pull⏎  (in Cloud9, rightclick on the BeagleBone directory and click refresh to get the tidl directory)
  7. Get latest updates:
    sudo apt update⏎
    sudo apt upgrade⏎
  8. Download the MPGStreamer for use with embedded vision projects
    sudo apt install -y ti-tidl mjpg-streamer-opencv-python
  9. Install Jason Kridner's perl package to show BeagleBone AI Pins (see useful commands below):
    sudo apt install libinline-files-perl
  10. Install an even better package to show pins by Matt Van Duin:
    cd /usr/local/sbin
    sudo wget -N https://raw.githubusercontent.com/mvduin/bbb-pin-utils/bbai-experimental/show-pins
    sudo chmod a+x show-pins
  11. Install BoneScript and setup a pin for use:
    cd /usr/local/lib
    sudo npm install --unsafe-perm bonescript@0.7.4-beta1
    node -pe "require('bonescript').bone.getPinObject('p9.15').ai.gpio"   (this sets up the pin in /sys/class/gpio)
  12. Update the Kernal - Note be sure to stay in the 4.14x range or the classification.cpp example will not work.
    cd /opt/scripts
    git pull
    sudo tools/update_kernel.sh
  13. Update /var/lib/cloud9/BeagleBone/AI/tidl code to get a flashing LED:

        blinkLED.py (this is because the Adafruit Python Library is still mapped to the BeagleBone Black)
               out="P8_13" #actually 8_22 on BBAI, line 14
                    or
               out="P8_39" #for pin 9_15 on BBAI, line 14

 

blinkLED.js

const leds = ["USR3", "P9_15"];  //change line 13 to this to get processing improvement.

  14.  Perform the Pimuxing Procedure a couple of sections below.

  15.  Use Win32DiskImager to make a backup of your SD card.

 

GOOD STUFF TO KNOW

  • BBAI means BeagleBone AI (artificial intelligence).  BBB means BeagleBone Black.
  • Cloud9 is scary at first, but you'll love it after a week playing with it.
  • To add code to Cloud9, just right click on an existing directory such as the AI folder under Beaglebone on the left and then select "new file".
  • There are two pin headers on the BBAI.  With the ethernet port on top, P9 is on the left and P8 is on the right.  Pins are often referred to in the format P9.2, which would be the top right pin.
  • Anytime I say "type", I mean type in a Linux terminal window.  You can pull up a new terminal window in Cloud9 by right clicking over a folder such as the AI folder and selecting "new terminal here".
  • Dropping executables in the "autorun" directory in Cloud9 will have them start on boot up.
  • PinMuxing means to configure the pin multiplexing of the BeagleBone chip to establish the optimal pin configuration of the headers that matches the peripherals that you will be using such as I2C devices, servos, leds, switches, etc.
  • The "/sys" directory is a virtual directory in memory.  You'll use subdirectories within it to set pins, but since its in memory, you don't have to be worried about read and writing a million times like you would an SD card.  In fact, your programming language calls are identical to how you would access an SD card file.  It's unsettling, but works well even for PWM.
  • The show-pins utilities and BeagleBone Adafruit IO library are mismatched to the pin names because they are still developed for the BeagleBone Black which has a different chipset.
  • You should only type "sudo" if you are doing something under the /boot or /lib directory.  Don't do it for most "git" calls or you'll set root access required permissions to those local folders.  So, if in doubt, don't use sudo unless you are told to by the system in response to not using it.
  • If you accidentally use sudo on a git repository that you shouldn't have, use sudo chown -R debian: the_folder, where debian is your username and the_folder is the folder created when you made the repository.  This will strip the root permission requirement back off of it.
  • In C, PWM settings on pins are set with fprintf in /sys/class/pwm/.  Type "ls /sys/class/pwm/" to study it from the bash window.
  • In C, Digital GPIO pins can be set through fprintf at /sys/class/gpio/.  Use the spreadsheet in the References to understand the cross reference from P9.X notation and the integer you see like gpiochip128 (which is P9.12).  Do "ls /sys/class/gpio/" to study it from the bash window.

 

USEFUL COMMANDS

  • Show pin configuration (aka the pinmux) - note the pin IDs in column 2 are off due to architecture differences with the BBB
    /opt/scripts/device/bone/show-pins.pl⏎ or
    show-pins
  • Show BoneScript Version
    node -pe "require('bonescript').getPlatform().bonescript"⏎
  • Show Debian Image Date
    cat /etc/dogtag⏎
  • Show kernel and boot up device tree info
    sudo /opt/scripts/tools/version.sh⏎
  • Show an internal pin number as BoneScript sees it and set it up for access from code
    node -pe "require('bonescript').bone.getPinObject('p9.15').ai.gpio"⏎
  • Install the 4.14x kernel if you accidentally went to 4.19+ (which will cause classification.cpp to fail)
    sudo /opt/scripts/tools/update_kernel.sh --lts-4_14 --ti-channel⏎
  • Auto run a debugged application at startup by copying to the cloud9 directory:
    cp <filename> /var/lib/cloud9/

 

PINMUXING

Pinmux Procedure

Here is a procedure for setting your pinmux configuration to the one that was used for my board:

cd #(or wherever you want to clone the next line to)
git clone https://github.com/beagleboard/BeagleBoard-DeviceTrees -b v4.14.x-ti
nano BeagleBoard-DeviceTrees/src/arm/am5729-beagleboneai-custom.dts #(paste the dts file below)
make BeagleBoard-DeviceTrees/src/arm/am5729-beagleboneai-custom.dtb
sudo cp BeagleBoard-DeviceTrees/src/arm/am5729-beagleboneai-custom.dtb /boot/dtbs
sudo nano /boot/uEnv.txt #(configure: dtb=am5729-beagleboneai-custom.dtb)
sudo reboot

 

a BBAI compatible dts file

A dts file (Device Tree Source) to match my setup.  Use the Pinmux Procedure in the previous section and paste the text below in the nano editor at step 3.

#include "am5729-beagleboneai.dts"
// make it easy to determine which dtb you're currently running on
// (via /proc/device-tree/chosen/)
/ {
 chosen {
  base_dtb = "am5729-beagleboneai-custom.dts";
  base_dtb_timestamp = __TIMESTAMP__;
 };
};
// eventually these should be available in a header
#define P9_14  (0x3400 + 4 * 107)
#define P9_16  (0x3400 + 4 * 108)
#define P9_19a (0x3400 + 4 * 16)
#define P9_19b (0x3400 + 4 * 95)
#define P9_20a (0x3400 + 4 * 17)
#define P9_20b (0x3400 + 4 * 94)
// enable i2c-3 on P9.19 (scl) + P9.20 (sda)
&i2c4 {
 status = "okay";
 clock-frequency = <400000>;
 pinctrl-names = "default";
 pinctrl-0 = <&i2c4_pins>;
};
&dra7_pmx_core {
 i2c4_pins: i2c4 {
  pinctrl-single,pins = <
   DRA7XX_CORE_IOPAD( P9_19a, PIN_INPUT_PULLUP | MUX_MODE7  )  // scl
   DRA7XX_CORE_IOPAD( P9_19b, PIN_INPUT_PULLUP | MUX_MODE14 )  // (shared pin)
   DRA7XX_CORE_IOPAD( P9_20a, PIN_INPUT_PULLUP | MUX_MODE7  )  // sda
   DRA7XX_CORE_IOPAD( P9_20b, PIN_INPUT_PULLUP | MUX_MODE14 )  // (shared pin)
  >;
 };
};
// enable pwm-2 on P9.14 (out-A) + P9.16 (out-B)
&epwmss2 {
 status = "okay";
};
&ehrpwm2 {
 status = "okay";
 pinctrl-names = "default";
 pinctrl-0 = <&ehrpwm2_pins>;
};
&dra7_pmx_core {
 ehrpwm2_pins: ehrpwm2 {
  pinctrl-single,pins = <
   DRA7XX_CORE_IOPAD( P9_14, PIN_OUTPUT_PULLDOWN | MUX_MODE10 )  // out A
   DRA7XX_CORE_IOPAD( P9_16, PIN_OUTPUT_PULLDOWN | MUX_MODE10 )  // out B
  >;
 };
};

// Here's the obnoxious part: since u-boot doesn't have same pin defaults yet, all pins not
// explicitly setup above should be overridden here.  This will eventually no longer be needed.
&cape_pins_default {
 pinctrl-single,pins = <
  DRA7XX_CORE_IOPAD( 0x372C, PIN_INPUT_PULLDOWN | MUX_MODE15 ) // P9.11a (no gpio)
  DRA7XX_CORE_IOPAD( 0x3620, PIN_INPUT          | MUX_MODE14 ) // P9.11b
  DRA7XX_CORE_IOPAD( 0x36AC, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P9.12
  DRA7XX_CORE_IOPAD( 0x3730, PIN_INPUT_PULLDOWN | MUX_MODE15 ) // P9.13  (no gpio)
 // DRA7XX_CORE_IOPAD( 0x35AC, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P9.14
  DRA7XX_CORE_IOPAD( 0x3514, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P9.15
 // DRA7XX_CORE_IOPAD( 0x35B0, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P9.16
  DRA7XX_CORE_IOPAD( 0x37CC, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P9.17a
  DRA7XX_CORE_IOPAD( 0x36B8, PIN_INPUT          | MUX_MODE14 ) // P9.17b
  DRA7XX_CORE_IOPAD( 0x37C8, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P9.18a
  DRA7XX_CORE_IOPAD( 0x36B4, PIN_INPUT          | MUX_MODE14 ) // P9.18b
 // DRA7XX_CORE_IOPAD( 0x3440, PIN_INPUT_PULLUP   | MUX_MODE14 ) // P9.19a
 // DRA7XX_CORE_IOPAD( 0x357C, PIN_INPUT          | MUX_MODE14 ) // P9.19b
 // DRA7XX_CORE_IOPAD( 0x3444, PIN_INPUT_PULLUP   | MUX_MODE14 ) // P9.20a
 // DRA7XX_CORE_IOPAD( 0x3578, PIN_INPUT          | MUX_MODE14 ) // P9.20b
  DRA7XX_CORE_IOPAD( 0x34F0, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P9.21a
  DRA7XX_CORE_IOPAD( 0x37C4, PIN_INPUT          | MUX_MODE14 ) // P9.21b
  DRA7XX_CORE_IOPAD( 0x369C, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P9.22a
  DRA7XX_CORE_IOPAD( 0x37C0, PIN_INPUT          | MUX_MODE14 ) // P9.22b
  DRA7XX_CORE_IOPAD( 0x37B4, PIN_INPUT_PULLUP   | MUX_MODE14 ) // P9.23
  DRA7XX_CORE_IOPAD( 0x368C, PIN_INPUT_PULLUP   | MUX_MODE14 ) // P9.24
  DRA7XX_CORE_IOPAD( 0x3694, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P9.25
  DRA7XX_CORE_IOPAD( 0x3688, PIN_INPUT_PULLUP   | MUX_MODE14 ) // P9.26a
  DRA7XX_CORE_IOPAD( 0x3544, PIN_INPUT          | MUX_MODE14 ) // P9.26b
  DRA7XX_CORE_IOPAD( 0x35A0, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P9.27a
  DRA7XX_CORE_IOPAD( 0x36B0, PIN_INPUT          | MUX_MODE14 ) // P9.27b
  DRA7XX_CORE_IOPAD( 0x36E0, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P9.28
  DRA7XX_CORE_IOPAD( 0x36D8, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P9.29a
  DRA7XX_CORE_IOPAD( 0x36A8, PIN_INPUT          | MUX_MODE14 ) // P9.29b
  DRA7XX_CORE_IOPAD( 0x36DC, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P9.30
  DRA7XX_CORE_IOPAD( 0x36D4, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P9.31a
  DRA7XX_CORE_IOPAD( 0x36A4, PIN_INPUT          | MUX_MODE14 ) // P9.31b
  DRA7XX_CORE_IOPAD( 0x36A0, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P9.41a
  DRA7XX_CORE_IOPAD( 0x3580, PIN_INPUT          | MUX_MODE14 ) // P9.41b
  DRA7XX_CORE_IOPAD( 0x36E4, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P9.42a
  DRA7XX_CORE_IOPAD( 0x359C, PIN_INPUT          | MUX_MODE14 ) // P9.42b
  DRA7XX_CORE_IOPAD( 0x379C, PIN_INPUT_PULLUP   | MUX_MODE14 ) // P8.3
  DRA7XX_CORE_IOPAD( 0x37A0, PIN_INPUT_PULLUP   | MUX_MODE14 ) // P8.4
  DRA7XX_CORE_IOPAD( 0x378C, PIN_INPUT_PULLUP   | MUX_MODE14 ) // P8.5
  DRA7XX_CORE_IOPAD( 0x3790, PIN_INPUT_PULLUP   | MUX_MODE14 ) // P8.6
  DRA7XX_CORE_IOPAD( 0x36EC, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.7
  DRA7XX_CORE_IOPAD( 0x36F0, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.8
  DRA7XX_CORE_IOPAD( 0x3698, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.9
  DRA7XX_CORE_IOPAD( 0x36E8, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.10
  DRA7XX_CORE_IOPAD( 0x3510, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.11
  DRA7XX_CORE_IOPAD( 0x350C, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.12
  DRA7XX_CORE_IOPAD( 0x3590, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.13
  DRA7XX_CORE_IOPAD( 0x3598, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.14
  DRA7XX_CORE_IOPAD( 0x3570, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.15a
  DRA7XX_CORE_IOPAD( 0x35B4, PIN_INPUT          | MUX_MODE14 ) // P8.15b
  DRA7XX_CORE_IOPAD( 0x35BC, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.16
  DRA7XX_CORE_IOPAD( 0x3624, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.17
  DRA7XX_CORE_IOPAD( 0x3588, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.18
  DRA7XX_CORE_IOPAD( 0x358C, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.19
  DRA7XX_CORE_IOPAD( 0x3780, PIN_INPUT_PULLUP   | MUX_MODE14 ) // P8.20
  DRA7XX_CORE_IOPAD( 0x377C, PIN_INPUT_PULLUP   | MUX_MODE14 ) // P8.21
  DRA7XX_CORE_IOPAD( 0x3798, PIN_INPUT_PULLUP   | MUX_MODE14 ) // P8.22
  DRA7XX_CORE_IOPAD( 0x3794, PIN_INPUT_PULLUP   | MUX_MODE14 ) // P8.23
  DRA7XX_CORE_IOPAD( 0x3788, PIN_INPUT_PULLUP   | MUX_MODE14 ) // P8.24
  DRA7XX_CORE_IOPAD( 0x3784, PIN_INPUT_PULLUP   | MUX_MODE14 ) // P8.25
  DRA7XX_CORE_IOPAD( 0x35B8, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.26
  DRA7XX_CORE_IOPAD( 0x35D8, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.27a
  DRA7XX_CORE_IOPAD( 0x3628, PIN_INPUT          | MUX_MODE14 ) // P8.27b
  DRA7XX_CORE_IOPAD( 0x35C8, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.28a
  DRA7XX_CORE_IOPAD( 0x362C, PIN_INPUT          | MUX_MODE14 ) // P8.28b
  DRA7XX_CORE_IOPAD( 0x35D4, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.29a
  DRA7XX_CORE_IOPAD( 0x3630, PIN_INPUT          | MUX_MODE14 ) // P8.29b
  DRA7XX_CORE_IOPAD( 0x35CC, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.30a
  DRA7XX_CORE_IOPAD( 0x3634, PIN_INPUT          | MUX_MODE14 ) // P8.30b
  DRA7XX_CORE_IOPAD( 0x3614, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.31a
  DRA7XX_CORE_IOPAD( 0x373C, PIN_INPUT_PULLDOWN | MUX_MODE15 ) // P8.31b (no gpio)
  DRA7XX_CORE_IOPAD( 0x3618, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.32a
  DRA7XX_CORE_IOPAD( 0x3740, PIN_INPUT_PULLDOWN | MUX_MODE15 ) // P8.32b (no gpio)
  DRA7XX_CORE_IOPAD( 0x3610, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.33a
  DRA7XX_CORE_IOPAD( 0x34E8, PIN_INPUT          | MUX_MODE14 ) // P8.33b
  DRA7XX_CORE_IOPAD( 0x3608, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.34a
  DRA7XX_CORE_IOPAD( 0x3564, PIN_INPUT          | MUX_MODE14 ) // P8.34b
  DRA7XX_CORE_IOPAD( 0x360C, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.35a
  DRA7XX_CORE_IOPAD( 0x34E4, PIN_INPUT          | MUX_MODE14 ) // P8.35b
  DRA7XX_CORE_IOPAD( 0x3604, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.36a
  DRA7XX_CORE_IOPAD( 0x3568, PIN_INPUT          | MUX_MODE14 ) // P8.36b
  DRA7XX_CORE_IOPAD( 0x35FC, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.37a
  DRA7XX_CORE_IOPAD( 0x3738, PIN_INPUT_PULLDOWN | MUX_MODE15 ) // P8.37b (no gpio)
  DRA7XX_CORE_IOPAD( 0x3600, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.38a
  DRA7XX_CORE_IOPAD( 0x3734, PIN_INPUT_PULLDOWN | MUX_MODE15 ) // P8.38b (no gpio)
  DRA7XX_CORE_IOPAD( 0x35F4, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.39
  DRA7XX_CORE_IOPAD( 0x35F8, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.40
  DRA7XX_CORE_IOPAD( 0x35EC, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.41
  DRA7XX_CORE_IOPAD( 0x35F0, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.42
  DRA7XX_CORE_IOPAD( 0x35E4, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.43
  DRA7XX_CORE_IOPAD( 0x35E8, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.44
  DRA7XX_CORE_IOPAD( 0x35DC, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.45a
  DRA7XX_CORE_IOPAD( 0x361C, PIN_INPUT          | MUX_MODE14 ) // P8.45b
  DRA7XX_CORE_IOPAD( 0x35E0, PIN_INPUT_PULLDOWN | MUX_MODE14 ) // P8.46a
  DRA7XX_CORE_IOPAD( 0x3638, PIN_INPUT          | MUX_MODE14 ) // P8.46b
 >;
};

 

After booting, you can show the pin configuration (if you followed the checklist above):

Note:  the pin IDs shown in the second column are not yet correct as of 10/31/2019.  For example, P9.15 is actually 76, not 69.

 

debian@beaglebone:~$ sudo show-pins                                                                                                                 
[sudo] password for debian:
Caution: Uses peripheral names from <https://goo.gl/jiazTL>. See README there for details.
P9.19a                                16 fast rx  up   7 i²c 3 scl        i2c@4807a000 (i2c4)
P9.20a                                17 fast rx  up   7 i²c 3 sda        i2c@4807a000 (i2c4)
P8.35b                                57 fast rx      14 gpio 2.00
P8.33b                                58 fast rx      14 gpio 2.01
P9.21a                                60 fast rx down 14 gpio 2.03
P8.12                                 67 fast rx down 14 gpio 2.10
P8.11                                 68 fast rx down 14 gpio 2.11
P9.15                                 69 fast rx down 14 gpio 2.12 lo >>  sysfs
P9.26b                                81 fast rx      14 gpio 2.24
P8.34b                                89 fast rx      14 gpio 3.00
P8.36b                                90 fast rx      14 gpio 3.01
P8.15a                                92 fast rx down 14 gpio 3.03
P9.20b                                94 fast rx  up  14 gpio 3.05        i2c@4807a000 (i2c4)
P9.19b                                95 fast rx  up  14 gpio 3.06        i2c@4807a000 (i2c4)
P9.41b                                96 fast rx      14 gpio 3.07
P8.18                                 98 fast rx down 14 gpio 3.09
P8.19                                 99 fast rx down 14 gpio 3.10
P8.13                                100 fast rx down 14 gpio 3.11
P8.14                                102 fast rx down 14 gpio 3.13
P9.42b                               103 fast rx      14 gpio 3.14
P9.27a                               104 fast rx down 14 gpio 3.15
P9.14                                107 fast    down 10 pwm 2 A          pwm@48442200 (ehrpwm2)
P9.16                                108 fast    down 10 pwm 2 B          pwm@48442200 (ehrpwm2)
P8.15b                               109 fast rx      14 gpio 3.27
P8.26                                110 fast rx down 14 gpio 3.28
P8.16                                111 fast rx down 14 gpio 3.29
P8.28a                               114 fast rx down 14 gpio 3.19
P8.30a                               115 fast rx down 14 gpio 3.20
P8.29a                               117 fast rx down 14 gpio 3.22
P8.27a                               118 fast rx down 14 gpio 3.23
P8.45a                               119 fast rx down 14 gpio 7.00
P8.46a                               120 fast rx down 14 gpio 7.01
P8.43                                121 fast rx down 14 gpio 7.02
P8.44                                122 fast rx down 14 gpio 7.03
P8.41                                123 fast rx down 14 gpio 7.04
P8.42                                124 fast rx down 14 gpio 7.05
P8.39                                125 fast rx down 14 gpio 7.06
P8.40                                126 fast rx down 14 gpio 7.07
P8.37a                               127 fast rx down 14 gpio 7.08
P8.38a                               128 fast rx down 14 gpio 7.09
P8.36a                               129 fast rx down 14 gpio 7.10
P8.34a                               130 fast rx down 14 gpio 7.11
P8.35a                               131 fast rx down 14 gpio 7.12
P8.33a                               132 fast rx down 14 gpio 7.13
P8.31a                               133 fast rx down 14 gpio 7.14
P8.32a                               134 fast rx down 14 gpio 7.15
P8.45b                               135 fast rx      14 gpio 7.16
P9.11b                               136 fast rx      14 gpio 7.17
P8.17                                137 fast rx down 14 gpio 7.18
P8.27b                               138 fast rx      14 gpio 7.19
P8.28b                               139 fast rx      14 gpio 7.20
P8.29b                               140 fast rx      14 gpio 7.21
P8.30b                               141 fast rx      14 gpio 7.22
P8.46b                               142 fast rx      14 gpio 7.23
P9.13b ?                             160 fast    down 15 unused          
P9.26a                               162 fast rx  up  14 gpio 5.14
P9.24                                163 fast rx  up  14 gpio 5.15
P9.25                                165 fast rx down 14 gpio 5.17
P8.09                                166 fast rx down 14 gpio 5.18
P9.22a                               167 fast rx down 14 gpio 5.19
P9.41a                               168 fast rx down 14 gpio 5.20
P9.31b                               169 fast rx      14 gpio 6.31
P9.29b                               170 fast rx      14 gpio 6.30
P9.12                                171 fast rx down 14 gpio 4.00 << lo  sysfs
P9.27b                               172 fast rx      14 gpio 4.01
P9.18b                               173 fast rx      14 gpio 4.02
P9.17b                               174 fast rx      14 gpio 4.03
P9.31a                               181 fast rx down 14 gpio 4.10
P9.29a                               182 fast rx down 14 gpio 4.11
P9.30                                183 fast rx down 14 gpio 4.12
P9.28                                184 fast rx down 14 gpio 3.17
P9.42a                               185 fast rx down 14 gpio 3.18
P8.10                                186 fast rx down 14 gpio 5.04
P8.07                                187 fast rx down 14 gpio 5.05
P8.08                                188 fast rx down 14 gpio 5.06
P9.11a                               203 fast rx down 15 unused          
P9.13a                               204 fast rx down 15 unused          
P8.38b                               205 fast rx down 15 unused          
P8.37b                               206 fast rx down 15 unused          
P8.31b                               207 fast rx down 15 unused          
P8.32b                               208 fast rx down 15 unused          
P8.21                                223 fast rx  up  14 gpio 5.29
P8.20                                224 fast rx  up  14 gpio 5.30
P8.25                                225 fast rx  up  14 gpio 5.31
P8.24                                226 fast rx  up  14 gpio 6.00
P8.05                                227 fast rx  up  14 gpio 6.01
P8.06                                228 fast rx  up  14 gpio 6.02
P8.23                                229 fast rx  up  14 gpio 0.22
P8.22                                230 fast rx  up  14 gpio 0.23
P8.03                                231 fast rx  up  14 gpio 0.24
P8.04                                232 fast rx  up  14 gpio 0.25
P9.23                                237 fast rx  up  14 gpio 6.11
P9.22b                               240 fast rx      14 gpio 6.14
P9.21b                               241 fast rx      14 gpio 6.15
P9.18a                               242 fast rx down 14 gpio 6.16
P9.17a                               243 fast rx down 14 gpio 6.17

 

Above you can see that Pin 9.15 and 9.12 are in use by my blinkLED.js program.

 

ANALOG INPUT

Although the utility show-pins doesn't show it and the spreadsheet referenced in the References section doesn't reflect it, pin P9.33 is an analog in paired to "in_voltage7_raw" in the "sys" folder.  It reads 0-1.8V and outputs a range of 0-4095.  I found it testing the output as shown here:

debian@beaglebone:/var/lib/cloud9/BeagleBone/AI/backupcamera$ cat /sys/bus/iio/devices/iio:device0/in_voltage7_raw #jumper between P9.33 and P9.01 (GND)
0

debian@beaglebone:/var/lib/cloud9/BeagleBone/AI/backupcamera$ cat /sys/bus/iio/devices/iio:device0/in_voltage7_raw #jumper between P9.33 and P9.03 (3.3V)
4095

 

With this we can simply read using any language that reads a text file.  See analogIn.c in Code Examples below.

 

Note, the ADC reads 1.8Vs which can be supplied by Pin 9.32.  If you have an external source in your circuit, be sure to get it down to 1.8Vs with a voltage divider.

sys file pin mapping

I could only safely locate 3 pins for analog read, although the spreadsheet shows 8.

/sys/bus/iio/devices/iio:device0/in_voltage7_raw     P9.33

/sys/bus/iio/devices/iio:device0/in_voltage4_raw     P9.35

/sys/bus/iio/devices/iio:device0/in_voltage6_raw     P9.36

 

 

I2C USE

As found in the show-pins output above, pins 9.19 and 9.20 are I2C enabled SCL and SDA pins, respectively.  You can test this by hooking up an I2C device of your choice such as an I2C enabled LCD Display.  Run the i2cdetect command as shown here:

 

debian@beaglebone:~$ i2cdetect -r 3
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-3 using read byte commands.
I will probe address range 0x03-0x77.
Continue? [Y/n] y
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- 27 -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
debian@beaglebone:~$

 

My LCD Display address for i2C is x27 which received a confirmed hit with i2cdetect as shown above.  See Code Examples for an I2C LCD c program.

 

PWM CONTROL

The final pin feature to conquer for the early release BBAI state of things is PWM output - and here it is!  PWM lets you send a fine tuned pulsed signal that can be interpreted by a servo to determine its position.  It can also imply an analog signal between 0-3.3V.

 

Digging around the "/sys/class" directory, I found /sys/class/pwm/pwm-0:0 relates to P9.14 when you use the Pinmux procedure earlier in my blog.  See pwmout.c in Code Examples below for an example of controlling it.  It's a three step process:  enable the pin, set the frequency, set the duty.

 

AUDIO

To enable sound from the BBAI USB port, you first need a USB-to-Audio cable to hook to an external speaker (see the Hardware section).  To enable it on the system, you need to create a sound config file.  To create it, type the following at a terminal screen:

nano ~/.asoundrc

 

Then paste the following in the nano editor:

 

pcm.!default {  
        type plug  
        slave {  
                pcm "hw:1,0"  
        }  
}  
ctl.!default {  
        type hw  
        card 1  
}  


 

Then, from your C or C++ code, you can play sound files like with a line like this:

     system("aplay myfile.mp3 &");

 

SHARING FILES WITH A WINDOWS PC

There will be a time you will want to access a Windows PC on your network to easily share a file.  Most commonly, this would be sound or image files, but maybe even some code.  To do so, you'll need a package that let's you see Windows Shared Folders on your network.

 

Type the following in your terminal:

sudo apt-get install cifs-utils

Let it install.  No need to reboot.

 

Create a Linux directory to hold the share folder:

     cd ~

     mkdir windows

 

Then, to mount the drive in Linux on your BBAI, type the following:

     sudo mount.cifs "//windowscomputername/windowsfolderpath" "windows" -o user=yourwindowsusername

 

You can name the "windows" directory whatever you want as long as you did a mkdir that matches.  You can now browse the directory with Linux terminal commands.  Of course, the Windows computer better be turned on!

 

 

CODE EXAMPLES

Below are working code examples that make use of the PinMux Procedure earlier in this blog.  One extra thing to note is that when you click run on a .c or .cpp file, you must then change the "runner" of Cloud9 and then click run again.  Do this as shown in the boxed rectangle in the picture here:

Setting the Runner in Cloud 9 for C and C++

 

 

Augmented blinkLED.js

adds demonstration of digital read as well as write.  See comments section for wiring and setup.

#!/usr/bin/env node
////////////////////////////////////////
// blinkLED.js
//      Blinks the USR LEDs and P9_15 when you connect 3.3V to P9_12.
// Wiring: P9_15 connects to the plus lead of an LED.  The negative lead of the
//   LED goes to a 220 Ohm resistor.  The other lead of the resistor goes
//   to ground.  A jumper goes in the 3.3V header (not 5V!).  Other end goes into
//         P_12.  Take it in and out to watch light turn on.
// Setup:  first type the following into the terminal to set up your pins if you haven't...
//          node -pe "require('bonescript').bone.getPinObject('P9.12').ai.gpio"
//          node -pe "require('bonescript').bone.getPinObject('P9.15').ai.gpio"
//  Issues: On first execution, it may through and error due to permissions.  Try running
//          again.
////////////////////////////////////////
const b = require('bonescript');
const leds = ["USR3", "P9_15"];
for(var i in leds) {
    b.pinMode(leds[i], b.OUTPUT);
}
b.pinMode("P9_12",b.INPUT);
var state = b.HIGH;
for(var i in leds) {
    b.digitalWrite(leds[i], state);
}
setInterval(toggle, 100);
function toggle() {
    if (b.digitalRead("P9_12")==b.HIGH) 
        state = b.HIGH;
    else
        state = b.LOW;
    for(var i in leds) {
        b.digitalWrite(leds[i], state);
    }
}

 

classification.cpp

add the following else case shown on line 15 to get text even when an object is not seen.

if(is_object >= 0)  //excerpt from cloud9/BeagleBone/AI/tidl/classification.cpp, Line 310
    {
        cv::putText(
            dst,
            (*(labels_classes[is_object])).c_str(),
            cv::Point(15, 60),
            cv::FONT_HERSHEY_SIMPLEX,
            1.5,
            cv::Scalar(0,255,0),
            3,  /* thickness */
            8
        );
    }
    //new code is below that allows for a constant message or tweaking as you see fit.
    else
    {
        char my_message[]="Searching...";
        cv::putText(
            dst,
            my_message,
            cv::Point(30, 60),
            cv::FONT_HERSHEY_SIMPLEX,
            1.5,
            cv::Scalar(0,255,0),
            3,  /* thickness */
            8
        );
    }
    //end of new code

 

analogIn.c

program to show how to read 0.3.3 voltage on an analog input pin with C

////////////////////////////////////////
// analogIn.c
//      reports 0-3.3V on P9.33 as 0-4095
//  Author:  Sean J. Miller
//  Wiring: Jumper a 0-3.3V source to P9.33
//
// See: https://www.element14.com/community/community/designcenter/single-board-computers/next-genbeaglebone/blog/2019/10/27/beagleboard-ai-brick-recovery-procedure
////////////////////////////////////////
#include <stdio.h>
#include <unistd.h>


int analogRead(){
     FILE * my_in_pin = fopen("/sys/bus/iio/devices/iio:device0/in_voltage7_raw", "r");//P9.33 on the BBAI
     char the_voltage[5];//the characters in the file are 0 to 4095
     fgets(the_voltage,6,my_in_pin);
     fclose(my_in_pin);
     printf("Voltage:  %s\n", the_voltage);
     return 0;
}


int main() {
     while(1) {
          analogRead();
         usleep(1000000);
      }
}

 

i2cLCD.c

program to demonstrate talking to an I2C device.  In this case, an LCD.

/* ----------------------------------------------------------------------- *
 * Title:         i2clcd                                                   *
 * Description:   C-code for PCF8574T backpack controlling LCD through I2C *
 *                Tested on BeagleBone AI                                  *
 *                11/1/2019 Sean Miller                                    *
 * ported from:                                                            *
 * https://github.com/fm4dd/i2c-lcd/blob/master/pcf8574-lcd-demo.c         *
 * Prerequisites: apt-get libi2c-dev i2c-tools                             *
 * Compilation:   i2clcd.c -o i2clcd                                       *
 *------------------------------------------------------------------------ */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/i2c-dev.h>
#include <fcntl.h>


#define I2C_BUS        "/dev/i2c-3" // I2C bus device
#define I2C_ADDR       0x27         // I2C slave address for the LCD module
#define BINARY_FORMAT  " %c  %c  %c  %c  %c  %c  %c  %c\n"
#define BYTE_TO_BINARY(byte) \
  (byte & 0x80 ? '1' : '0'), \
  (byte & 0x40 ? '1' : '0'), \
  (byte & 0x20 ? '1' : '0'), \
  (byte & 0x10 ? '1' : '0'), \
  (byte & 0x08 ? '1' : '0'), \
  (byte & 0x04 ? '1' : '0'), \
  (byte & 0x02 ? '1' : '0'), \
  (byte & 0x01 ? '1' : '0') 
  
int lcd_backlight;
int debug;
char address; 
int i2cFile;


void i2c_start() {
   if((i2cFile = open(I2C_BUS, O_RDWR)) < 0) {
      printf("Error failed to open I2C bus [%s].\n", I2C_BUS);
      exit(-1);
   }
   // set the I2C slave address for all subsequent I2C device transfers
   if (ioctl(i2cFile, I2C_SLAVE, I2C_ADDR) < 0) {
      printf("Error failed to set I2C address [%s].\n", I2C_ADDR);
      exit(-1);
   }
}


void i2c_stop() { close(i2cFile); }


void i2c_send_byte(unsigned char data) {
   unsigned char byte[1];
   byte[0] = data;
   if(debug) printf(BINARY_FORMAT, BYTE_TO_BINARY(byte[0]));
   write(i2cFile, byte, sizeof(byte)); 
   /* -------------------------------------------------------------------- *
    * Below wait creates 1msec delay, needed by display to catch commands  *
    * -------------------------------------------------------------------- */
   usleep(1000);
}


void main() { 
   i2c_start(); 
   debug=0; //change to 1 to see messages.


   /* -------------------------------------------------------------------- *
    * Initialize the display, using the 4-bit mode initialization sequence *
    * -------------------------------------------------------------------- */
   if(debug) printf("Init Start:\n");


   usleep(15000);             // wait 15msec
   i2c_send_byte(0b00110100); // D7=0, D6=0, D5=1, D4=1, RS,RW=0 EN=1
   i2c_send_byte(0b00110000); // D7=0, D6=0, D5=1, D4=1, RS,RW=0 EN=0
   usleep(4100);              // wait 4.1msec
   i2c_send_byte(0b00110100); // 
   i2c_send_byte(0b00110000); // same
   usleep(100);               // wait 100usec
   i2c_send_byte(0b00110100); //
   i2c_send_byte(0b00110000); // 8-bit mode init complete
   usleep(4100);              // wait 4.1msec
   i2c_send_byte(0b00100100); //
   i2c_send_byte(0b00100000); // switched now to 4-bit mode


   /* -------------------------------------------------------------------- *
    * 4-bit mode initialization complete. Now configuring the function set *
    * -------------------------------------------------------------------- */
   usleep(40);                // wait 40usec
   i2c_send_byte(0b00100100); //
   i2c_send_byte(0b00100000); // keep 4-bit mode
   i2c_send_byte(0b10000100); //
   i2c_send_byte(0b10000000); // D3=2lines, D2=char5x8


   /* -------------------------------------------------------------------- *
    * Next turn display off                                                *
    * -------------------------------------------------------------------- */
   usleep(40);                // wait 40usec
   i2c_send_byte(0b00000100); //
   i2c_send_byte(0b00000000); // D7-D4=0
   i2c_send_byte(0b10000100); //
   i2c_send_byte(0b10000000); // D3=1 D2=display_off, D1=cursor_off, D0=cursor_blink


   /* -------------------------------------------------------------------- *
    * Display clear, cursor home                                           *
    * -------------------------------------------------------------------- */
   usleep(40);                // wait 40usec
   i2c_send_byte(0b00000100); //
   i2c_send_byte(0b00000000); // D7-D4=0
   i2c_send_byte(0b00010100); //
   i2c_send_byte(0b00010000); // D0=display_clear


   /* -------------------------------------------------------------------- *
    * Set cursor direction                                                 *
    * -------------------------------------------------------------------- */
   usleep(40);                // wait 40usec
   i2c_send_byte(0b00000100); //
   i2c_send_byte(0b00000000); // D7-D4=0
   i2c_send_byte(0b01100100); //
   i2c_send_byte(0b01100000); // print left to right


   /* -------------------------------------------------------------------- *
    * Turn on the display                                                  *
    * -------------------------------------------------------------------- */
   usleep(40);                // wait 40usec
   i2c_send_byte(0b00000100); //
   i2c_send_byte(0b00000000); // D7-D4=0
   i2c_send_byte(0b11100100); //
   i2c_send_byte(0b11100000); // D3=1 D2=display_on, D1=cursor_on, D0=cursor_blink


   if(debug) printf("Init End.\n");
   sleep(1);


   if(debug) printf("Writing HELLO to display\n");
   if(debug) printf("D7 D6 D5 D4 BL EN RW RS\n");


   /* -------------------------------------------------------------------- *
    * Start writing 'H' 'E' 'L' 'L' 'O' chars to the display, with BL=on.  *
    * -------------------------------------------------------------------- */
   i2c_send_byte(0b01001101); //
   i2c_send_byte(0b01001001); // send 0100=4
   i2c_send_byte(0b10001101); //
   i2c_send_byte(0b10001001); // send 1000=8 = 0x48 ='H'


   i2c_send_byte(0b01001101); //
   i2c_send_byte(0b01001001); // send 0100=4
   i2c_send_byte(0b01011101); // 
   i2c_send_byte(0b01011001); // send 0101=1 = 0x41 ='E'


   i2c_send_byte(0b01001101); //
   i2c_send_byte(0b01001001); // send 0100=4
   i2c_send_byte(0b11001101); //
   i2c_send_byte(0b11001001); // send 1100=12 = 0x4D ='L'


   i2c_send_byte(0b01001101); //
   i2c_send_byte(0b01001001); // send 0100=4
   i2c_send_byte(0b11001101); //
   i2c_send_byte(0b11001001); // send 1100=12 = 0x4D ='L'


   i2c_send_byte(0b01001101); //
   i2c_send_byte(0b01001001); // send 0100=4
   i2c_send_byte(0b11111101); //
   i2c_send_byte(0b11111001); // send 1111=15 = 0x4F ='O'


   if(debug) printf("Finished writing to display.\n");
   i2c_stop(); 
}

tfmini.c

This program will talk to an I2C enabled TFmini LIDAR distance sensor.

/* ----------------------------------------------------------------------- *
 * Title:         tfmini.c                                                 *
 * Description:   C-code for TFMini Plus                                   *
 *                Tested on BeagleBone AI                                  *
 *                11/6/2019 Sean J. Miller                                 *
 * Prerequisites: apt-get libi2c-dev i2c-tools                             *
 *------------------------------------------------------------------------ */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/i2c-dev.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <string.h>
#define I2C_BUS        "/dev/i2c-3" // I2C bus device
#define I2C_ADDR       0x10         // I2C slave address for the TFMini module
int debug;
int i2cFile;
void i2c_start() {
   if((i2cFile = open(I2C_BUS, O_RDWR)) < 0) {
      printf("Error failed to open I2C bus [%s].\n", I2C_BUS);
      exit(-1);
   } else {
       if (debug)printf("Opened I2C Bus\n");
   }
   // set the I2C slave address for all subsequent I2C device transfers
   if (ioctl(i2cFile, I2C_SLAVE, I2C_ADDR) < 0) {
      printf("Error failed to set I2C address [%s].\n", I2C_ADDR);
      exit(-1);
   } else {
      printf("Set Slave Address\n");
   }
}
void i2c_stop() { close(i2cFile); }
float readDistance() {
 //Routine to output the distance to the console
 int distance = 0; //distance
 int strength = 0; // signal strength
 int rangeType = 0; //range scale
 unsigned char incoming[7]; //an array of bytes to hold the returned data from the TFMini.
 unsigned char cmdBuffer[] = { 0x01, 0x02, 7 }; //the bytes to send the request of distance
 
   write( i2cFile, cmdBuffer, 3 );
   usleep(100000);
   read(i2cFile, incoming, 7);
 for (int x = 0; x < 7; x++)
 {
  if (x == 0)
  {
   //Trigger done
   if (incoming[x] == 0x00)
   {
   
   }
   else if (incoming[x] == 0x01)
   {
   
   }
  }
  else if (x == 2)
   distance = incoming[x]; //LSB of the distance value "Dist_L"
  else if (x == 3)
   distance |= incoming[x] << 8; //MSB of the distance value "Dist_H"
  else if (x == 4)
   strength = incoming[x]; //LSB of signal strength value
  else if (x == 5)
   strength |= incoming[x] << 8; //MSB of signal strength value
  else if (x == 6)
   rangeType = incoming[x]; //range scale
 }
 
 float the_return = distance / (12 * 2.54); //convert to feet.
 return the_return;
}
void main() {
   i2c_start(); 
   debug=1; //change to 1 to see messages.

   if(debug) printf("Init Start:\n");
   float my_distance = readDistance();
   if(debug) printf("the_distance: %f\n",my_distance);
   if(debug) printf("Finished reading.\n");
   i2c_stop();
   if(debug) printf("Finshed, Sean!\n\n");
}

pwmout.c

a program that will swell an LED on P9.14 using PWM

////////////////////////////////////////
//  pwmout.c
//      generates pwm on a pin to glow an LED
//  Author:  Sean J. Miller
//  Wiring: Jumper P9.14 to an LED through a 220ohm resistor to ground
//
// See: https://www.element14.com/community/community/designcenter/single-board-computers/next-genbeaglebone/blog/2019/10/27/beagleboard-ai-brick-recovery-procedure
////////////////////////////////////////
#include <stdio.h>
#include <unistd.h>


void setupPWM() {
    FILE *period, *pwm;
    pwm = fopen("/sys/class/pwm/pwm-0:0/enable", "w");
    fseek(pwm,0,SEEK_SET);
    fprintf(pwm,"%d",1);
    fflush(pwm);
    fclose(pwm);
    
    printf("Period...!\n");
    period = fopen("/sys/class/pwm/pwm-0:0/period", "w");
    fseek(period,0,SEEK_SET);
    fprintf(period,"%d",2500);
    fflush(period);
    fclose(period);
    
}
void pwm_duty(int the_duty_multiplier)
{
    FILE *duty;
    duty = fopen("/sys/class/pwm/pwm-0:0/duty_cycle", "w");
    fseek(duty,0,SEEK_SET);
    fprintf(duty,"%d",100*the_duty_multiplier);
    fflush(duty);
    fclose(duty);
}


int main() {
     int ii=0;int up=0;
     printf("Setting up\n");
     setupPWM();
     
     while(1) {
        printf("Swelling LED %d\n",ii);
         if (up==1) ii++; else ii--;
         if ((ii)>60) {
             up=0;
         }
         if (ii<3) {
             up=1;
         }
         pwm_duty(ii);
         usleep(25000);
      }
}

 

servoPot.c

reads a potentiometer and translates it to a servo's position

////////////////////////////////////////
//  servoPot.c
//      reads a pot and translates it to
//      a servos position.
//  Author:  Sean J. Miller, 11/3/2019
//  Wiring: Jumper P9.14 to a servo signal through a 220ohm resistor
//          Hook a potentiometers variable voltage to P9.33 (analog in).  It's source should be Pin 32 (VDADC of 1.8V)
//  See: https://www.element14.com/community/community/designcenter/single-board-computers/next-genbeaglebone/blog/2019/10/27/beagleboard-ai-brick-recovery-procedure
////////////////////////////////////////
#include <stdio.h>
#include <unistd.h>
int analogRead(){
    int i;
    FILE * my_in_pin = fopen("/sys/bus/iio/devices/iio:device0/in_voltage7_raw", "r");//P9.33 on the BBAI
    char the_voltage[5];//the characters in the file are 0 to 4095
    fgets(the_voltage,6,my_in_pin);
    fclose(my_in_pin);
    printf("Voltage:  %s\n", the_voltage);
    sscanf(the_voltage, "%d", &i);
    return (i);
}


void setupPWM() {
    FILE *period, *pwm;
    pwm = fopen("/sys/class/pwm/pwm-0:0/enable", "w");
    fseek(pwm,0,SEEK_SET);
    fprintf(pwm,"%d",1);
    fflush(pwm);
    fclose(pwm);
    
    
    period = fopen("/sys/class/pwm/pwm-0:0/period", "w");
    fseek(period,0,SEEK_SET);
    fprintf(period,"%d",20000000);//20ms
    fflush(period);
    fclose(period);
    
}
void pwm_duty(int the_duty_multiplier)
{
    FILE *duty; int duty_calc;
    duty = fopen("/sys/class/pwm/pwm-0:0/duty_cycle", "w");
    fseek(duty,0,SEEK_SET);
    duty_calc=(600000 + (1700000*(float)((float)the_duty_multiplier/4095))) ;
    printf("Duty: %d\n", duty_calc);//1ms
    fprintf(duty,"%d",duty_calc);//1ms
    fflush(duty);
    fclose(duty);
}


int main() {
     int ii=0;
     printf("Setting up\n");
     setupPWM();
     
     while(1) {
        ii=analogRead();
        pwm_duty(ii);
        usleep(20000);
     }
}

HARDWARE

Peripherals

Below are the hardware components that will help you get the most out of the board:

3 Pin Serial Debug Connector3 Pin Serial Debug Connector

Pins for 3 Pin Serial Debug ConnectorPins for 3 Pin Serial Debug Connector

3A USB C Power Plug3A USB C Power Plug

Cooling FanCooling Fan

Cooling Fan Machine Screws Size:  M3

$9 Web Cam

USB to Audio Cable

Board Connector Original Images From the System Manual

Power and Ground Pins

Warning:  Analog in is only 1.8V tolerant!!!*  Use the VDD_AADC as the reference voltage instead of 3.3V

*Note:  I'm going on hearsay on the 1.8V tolerant thing.  I tested 3.3V and it went to 0-4095 without issue, where 1.8V returned about half that.  But, since pin 32 puts out 1.8V as the ADV voltage, I'm going to stay using it as my analog reference voltage source until I hear otherwise.

DGND: this is the digital ground to connect any digital devices

GNDA_ADC: this is the analog ground used to connect any devices that return an analog signal such as a potentiometer

VDD_3V3 - use this to power 3.3v electronics

VDD_5V - use this to power the beagleboard (i.e. through a barrel jack, if you are going to put one on the cape/shield), NOT to power 5V electronics

SYS_5V - use this to power 5V electronics

VDD_ADC - use to connect power analog in devices such as Potentiometers.  (It is 1.8V!!!!)

Hardware Good Stuff to Know

  • PWR_BUT is 3.3V level as pulled up internally by the TPS6590379. It is activated by pulling the signal to GND.  It won't do a Power Off like the BB Black did.

  • GPIO max current is still a mystery.  I couldn't find it on the ARM 572 Sitara docs, yet.  Some BBB tutorials stated a 8mA limit - which seems safe compared to other microcontrollers.  So, I use a transistor as a switch to handle the load of any components that are doing anything but signal communication.  For example, LEDs, Piezos should be transistor switched.  Between the GPIO and transistor I use a 420 ohm current limiting resistor to keep the current under 8ma according to ohm's law.

 

 

REFERENCES

 

ACKNOWLEDGEMENTS

  • Thanks to @zMatt (on BB chat), BB-AI/Sphere (Clem), Jason Kridner, Clem Meyers, shabaz for the picture, my cat Tank (aka ping-pong-ball to the BBAI), and Jon Morss for their leads, tips, and troubleshooting help so far.

 

 

SURVIVAL GUIDE CHANGE LOG

11/13/2019:  V3.7 added Sharing Files with a Window PC

11/13/2019:  V3.6 added Audio section and linked a webcam under $10 and a cheap USB-to-Audio cable in the Hardware section.

11/09/2019:  V3.5 added pinout picture under hardware and warnings that the ADC is 1.8Vs which can be supplied by pin P9.32.

11/09/2019:  V3.4 added board images for pin reference in Hardware section as well as hardware good stuff to know.  Also, gave link to system manual

11/07/2019:  V3.3 added Hardware Add-ons Section

11/06/2019:  V3.2 added TFMini.c.  It shows how to read and write on I2C using a TFMini module.

11/03/2019:  V3.1 added servoPot.c code example.  It takes analog in from a potentiometer and translates it to a servo's position allowing you to control the servo with the potentiometer.

11/02/2019:  V3.0 added PWM section and pwmout.c code - all pin features are now achieved!!!!!!  Added Good Stuff to Know Section that sheds a lot of light on things.

11/02/2019:  V2.4 added analogIn.c example for reading analog in.

11/02/2019:  V2.3 added Analog Input Section

11/01/2019:  V2.2 added i2clcd.c code to demonstrate using I2C on bus 3

11/01/2019:  V2.1 added I2C section

10/31/2019:  V2.0 added Pinmuxing Section to show how to setup pins and added Matt Van Duin's show-pins utility to setup.  Move classification tweak to new Code Examples section.

10/31/2019:  V1.2 added augmented blinkLED.js code to demonstrate using digital read/write.

10/27/2019:  V1.1 added node -pe "require('bonescript').bone.getPinObject('p9.15').ai.gpio" to step 10.  It's needed to setup the pin for use.

10/27/2019:  V1.0 Published