From 24dd78154bd0a5b8decbf64ac2c17d6a577889d7 Mon Sep 17 00:00:00 2001 From: Jacquot-SFE Date: Thu, 3 Apr 2014 16:56:18 -0600 Subject: [PATCH] Adding software examples Using wiringPi to demonstrate C applications that access GPIO, SPI and I2C. --- software/gpiotest.cpp | 105 ++++++++++++++++++++++++++++++++++ software/i2ctest.cpp | 100 ++++++++++++++++++++++++++++++++ software/spitest.cpp | 130 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 335 insertions(+) create mode 100644 software/gpiotest.cpp create mode 100644 software/i2ctest.cpp create mode 100644 software/spitest.cpp diff --git a/software/gpiotest.cpp b/software/gpiotest.cpp new file mode 100644 index 0000000..5719d5b --- /dev/null +++ b/software/gpiotest.cpp @@ -0,0 +1,105 @@ +/****************************************************************************** +gpiotest.cpp +Raspberry Pi GPIO demo +Byron Jacquot @ SparkFun Electronics> +4/2/2014 +https://github.com/sparkfun/Pi_Wedge + +A brief demonstration of GPIO features on the Raspberry Pi, to demonstrate +the SparkFun Pi Wedge breakout board. + +Resources: + +This example makes use of the Wiring Pi library, which streamlines the inteface +the the I/O pins on the Raspberry Pi, providing an API that is similar to the +Arduino. You can learn about installing Wiring Pi here: +http://wiringpi.com/download-and-install/ + +The GPIO API is documented here: +https://projects.drogon.net/raspberry-pi/wiringpi/functions/ + +WiringPi also installs the very useful command-line utility called 'gpio' +which allows you to configure and query pin status. Check it's man page for +more details. + +To build this file, I use the command: +> g++ gpiotest.cpp -lwiringPi + +Then to run it, I have to use sudo, as it creates restricted file resources. +> sudo ./a.out + +WiringPi defines its own pin numbers, in a contiguous range, from 0 to 16. +These numbers account for the V1/V2 hardware differences. You can alternately +use the RPi/Broadcom pin numbers. + +This test will repurpose the UART pins. If you're using a terminal on the UART, +constrain it to pins 0 through 14. If you're using SSH/telnet, you can include +pins 15 and 16. + +Development environment specifics: +Tested on Raspberry Pi V2 hardware, running Raspbian. +Building with GCC 4.6.3 (Debian 4.6.3-14+rpi1) + +This code is beerware; if you see me (or any other SparkFun employee) at the +local, and you've found our code helpful, please buy us a round! + +Distributed as-is; no warranty is given. +******************************************************************************/ + +#include +#include +#include + +using namespace std; + +// This will only touch 0 through 14. 15 and 16 are the UART, which we +// wouldn't want to reconfigure is you're using them for a terminal. +// If you're using SSH, you can run up to 16. +static const int MAX_PIN = 14; + +int main() +{ + int result; + + // Init using the wiring Pi numbering scheme ( GPIOs referenced as + // a contiguous 0 through 16 range). + // + // Could alternately call: + // - wiringPiSetupGpio() to use the native Pi pin numbers + // - wiringPiSetupSys() to use pre-exported /sys/class/gpio pins. This + // requires that the pins be pre-exported, but doesn't + // require root access to run the application. + result = wiringPiSetup(); + + // Result of -1 indicates error + cout << "Setup result: " << result << endl; + + // set all pins as outputs + for(int i = 0; i <= MAX_PIN; i++) + { + pinMode(i, OUTPUT); + + cout << "init'd pin: " << i << endl; + } + + // Cycle through the pins, setting one at a time high. + // Repeat 10 times. + // This allows us to check them with a meter or oscilloscope. + for(int i = 0; i < MAX_PIN; i++) + { + for(int j = 0; j <= MAX_PIN; j++) + { + if( (i % 17) == j) + { + cout << "Pin " << j << " set high." < +4/2/2014 +https://github.com/sparkfun/Pi_Wedge + +A brief demonstration of the Raspberry Pi I2C interface, using the SparkFun +Pi Wedge breakout board. + +Resources: + +This example makes use of the Wiring Pi library, which streamlines the inteface +the the I/O pins on the Raspberry Pi, providing an API that is similar to the +Arduino. You can learn about installing Wiring Pi here: +http://wiringpi.com/download-and-install/ + +The I2C API is documented here: +https://projects.drogon.net/raspberry-pi/wiringpi/i2c-library/ + +The init call returns a standard file descriptor. More detailed configuration +of the interface can be performed using ioctl calls on that descriptor. +See the wiringPi I2C implementation (wiringPi/wiringPiI2C.c) for some examples. +Parameters configurable with ioctl are documented here: +http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/i2c/dev-interface + +Hardware connections: + +This file interfaces with the SparkFun MCP4725 breakout board: +https://www.sparkfun.com/products/8736 + +The board was connected as follows: +(Raspberry Pi)(MCP4725) +GND -> GND +3.3V -> Vcc +SCL -> SCL +SDA -> SDA + +An oscilloscope probe was connected to the analog output pin of the MCP4725. + +To build this file, I use the command: +> g++ i2ctest.cpp -lwiringPi + +Then to run it, first the I2C kernel module needs to be loaded. This can be +done using the GPIO utility. +> gpio load i2c 400 +> ./a.out + +This will run the MCP through it's output range several times. A rising +sawtooth will be seen on the analog output. + +Development environment specifics: +Tested on Raspberry Pi V2 hardware, running Raspbian. +Building with GCC 4.6.3 (Debian 4.6.3-14+rpi1) + +This code is beerware; if you see me (or any other SparkFun employee) at the +local, and you've found our code helpful, please buy us a round! + +Distributed as-is; no warranty is given. +******************************************************************************/ + +#include +#include +#include + +using namespace std; + +int main() +{ + int fd, result; + + // Initialize the interface by giving it an external device ID. + // The MCP4725 defaults to address 0x60. + // + // It returns a standard file descriptor. + // + fd = wiringPiI2CSetup(0x60); + + cout << "Init result: "<< fd << endl; + + for(int i = 0; i < 0x0000ffff; i++) + { + // I tried using the "fast write" command, but couldn't get it to work. + // It's not entirely obvious what's happening behind the scenes as + // regards to endianness or length of data sent. I think it's only + // sending one byte, when we really need two. + // + // So instead I'm doing a 16 bit register access. It appears to + // properly handle the endianness, and the length is specified by the + // call. The only question was the register address, which is the + // concatenation of the command (010x = write DAC output) + // and power down (x00x = power up) bits. + result = wiringPiI2CWriteReg16(fd, 0x40, (i & 0xfff) ); + + if(result == -1) + { + cout << "Error. Errno is: " << errno << endl; + } + } +} diff --git a/software/spitest.cpp b/software/spitest.cpp new file mode 100644 index 0000000..95c05fc --- /dev/null +++ b/software/spitest.cpp @@ -0,0 +1,130 @@ +/****************************************************************************** +i2ctest.cpp +Raspberry Pi I2C interface demo +Byron Jacquot @ SparkFun Electronics> +4/2/2014 +https://github.com/sparkfun/Pi_Wedge + +A brief demonstration of the Raspberry Pi I2C interface, using the SparkFun +Pi Wedge breakout board. + +Resources: + +This example makes use of the Wiring Pi library, which streamlines the inteface +the the I/O pins on the Raspberry Pi, providing an API that is similar to the +Arduino. You can learn about installing Wiring Pi here: +http://wiringpi.com/download-and-install/ + +The wiringPi SPI API is documented here: +https://projects.drogon.net/raspberry-pi/wiringpi/spi-library/ + +The init call returns a standard file descriptor. More detailed configuration +of the interface can be performed using ioctl calls on that descriptor. +See the wiringPi SPI implementation (wiringPi/wiringPiSPI.c) for some examples. +Parameters configurable with ioctl are documented here: +http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/spi/spidev + + +Hardware connections: + +This file interfaces with the SparkFun Serial 7 Segment display: +https://www.sparkfun.com/products/11629 + +The board was connected as follows: +(Raspberry Pi)(Serial 7 Segment) +GND -> GND +3.3V -> Vcc +CE1 -> SS (Shift Select) +SCK -> SCK +MOSI -> SDI +MISO -> SDO + +To build this file, I use the command: +> g++ spitest.cpp -lwiringPi + +Then to run it, first the spi kernel module needs to be loaded. This can be +done using the GPIO utility. +> gpio load spi +> ./a.out + +This test uses the single-segment mode of the 7 segment display. It shifts a +bit through the display characters, lighting a single character of each at a +time. + +Development environment specifics: +Tested on Raspberry Pi V2 hardware, running Raspbian. +Building with GCC 4.6.3 (Debian 4.6.3-14+rpi1) + +This code is beerware; if you see me (or any other SparkFun employee) at the +local, and you've found our code helpful, please buy us a round! + +Distributed as-is; no warranty is given. +******************************************************************************/ + +#include +#include +#include + +using namespace std; + +// channel is the wiringPi name for the chip select (or chip enable) pin. +// Set this to 0 or 1, depending on how it's connected. +static const int CHANNEL = 1; + +int main() +{ + int fd, result; + unsigned char buffer[100]; + + cout << "Initializing" << endl ; + + // Configure the interface. + // CHANNEL insicates chip select, + // 500000 indicates bus speed. + fd = wiringPiSPISetup(CHANNEL, 500000); + + cout << "Init result: " << fd << endl; + + // clear display + buffer[0] = 0x76; + wiringPiSPIDataRW(CHANNEL, buffer, 1); + + sleep(5); + + // Do a one-hot bit selection for each field of the display + for(int i = 1; i <= 0x7f; i <<= 1) + { + // the decimals, colon and apostrophe dots + buffer[0] = 0x77; + buffer[1] = i; + result = wiringPiSPIDataRW(CHANNEL, buffer, 2); + + // The first character + buffer[0] = 0x7b; + buffer[1] = i; + result = wiringPiSPIDataRW(CHANNEL, buffer, 2); + + // The second character + buffer[0] = 0x7c; + buffer[1] = i; + result = wiringPiSPIDataRW(CHANNEL, buffer, 2); + + // The third character + buffer[0] = 0x7d; + buffer[1] = i; + result = wiringPiSPIDataRW(CHANNEL, buffer, 2); + + // The last character + buffer[0] = 0x7e; + buffer[1] = i; + result = wiringPiSPIDataRW(CHANNEL, buffer, 2); + + // Pause so we can see them + sleep(5); + } + + // clear display again + buffer[0] = 0x76; + wiringPiSPIDataRW(CHANNEL, buffer, 1); + +}