├── License.md ├── README.md └── examples ├── I2C ├── i2c.cpp ├── i2c.h └── i2c.py ├── SPI ├── spi_test.cpp ├── spi_test.h └── spi_test.py ├── analog ├── analog.cpp ├── analog.h └── analog.py ├── gpio ├── gpio_test.cpp ├── gpio_test.h └── gpio_test.py ├── hello_world ├── hello_world.cpp └── hello_world.py └── serial_test ├── serial_test.cpp ├── serial_test.h └── serial_test.py /License.md: -------------------------------------------------------------------------------- 1 | SparkFun License Information 2 | ============================ 3 | 4 | SparkFun uses two different licenses for our files — one for hardware and one for code. 5 | 6 | Hardware 7 | --------- 8 | 9 | **SparkFun hardware is released under [Creative Commons Share-alike 4.0 International](http://creativecommons.org/licenses/by-sa/4.0/).** 10 | 11 | Note: This is a human-readable summary of (and not a substitute for) the [license](http://creativecommons.org/licenses/by-sa/4.0/legalcode). 12 | 13 | You are free to: 14 | 15 | Share — copy and redistribute the material in any medium or format 16 | Adapt — remix, transform, and build upon the material 17 | for any purpose, even commercially. 18 | The licensor cannot revoke these freedoms as long as you follow the license terms. 19 | Under the following terms: 20 | 21 | Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. 22 | ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original. 23 | No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. 24 | Notices: 25 | 26 | You do not have to comply with the license for elements of the material in the public domain or where your use is permitted by an applicable exception or limitation. 27 | No warranties are given. The license may not give you all of the permissions necessary for your intended use. For example, other rights such as publicity, privacy, or moral rights may limit how you use the material. 28 | 29 | 30 | Code 31 | -------- 32 | 33 | **SparkFun code, firmware, and software is released under the MIT License(http://opensource.org/licenses/MIT).** 34 | 35 | The MIT License (MIT) 36 | 37 | Copyright (c) 2016 SparkFun Electronics 38 | 39 | Permission is hereby granted, free of charge, to any person obtaining a copy 40 | of this software and associated documentation files (the "Software"), to deal 41 | in the Software without restriction, including without limitation the rights 42 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 43 | copies of the Software, and to permit persons to whom the Software is 44 | furnished to do so, subject to the following conditions: 45 | 46 | The above copyright notice and this permission notice shall be included in all 47 | copies or substantial portions of the Software. 48 | 49 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 50 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 51 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 52 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 53 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 54 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 55 | SOFTWARE. 56 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SparkFun pcDuino 2 | ========================================== 3 | 4 | ![pcDuino](https://cdn.sparkfun.com/assets/parts/7/8/9/5/11712-01.jpg) 5 | 6 | [*pcDuino (DEV-11712)*](https://www.sparkfun.com/products/retired/11712) 7 | 8 | **NOTE:** *This product has been retired from our catalog. If you are looking for more up-to-date info, please check out some of these resources to see how other users are still hacking and improving on this product.* 9 | 10 | * *[SparkFun Forum](https://forum.sparkfun.com/)* 11 | * *[Comments Here on GitHub](https://github.com/sparkfun/pcDuino/issues)* 12 | * *[IRC Channel](https://www.sparkfun.com/news/263)* 13 | 14 | * **Retired Tutorials** 15 | * *[pcDuino Hookup Guide (RETIRED)](https://learn.sparkfun.com/tutorials/pcduino-hookup-guide)* 16 | * *[Programming the pcDuino (RETIRED)](https://learn.sparkfun.com/tutorials/programming-the-pcduino)* 17 | * *[Using pcDuino's WiFi Dongle With the Pi (RETIRED)](https://learn.sparkfun.com/tutorials/using-pcduinos-wifi-dongle-with-the-pi)* 18 | 19 | 20 | 21 | 22 | https://www.sparkfun.com/products/retired/11712 23 | 24 | This repo contains useful projects to those getting started with the pcDuino. 25 | 26 | The wiki contains some useful information, as well, and will be expanded as new information becomes available. 27 | -------------------------------------------------------------------------------- /examples/I2C/i2c.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | i2c.cpp 3 | 4 | Example code for I2C access on the pcDuino via C++. Example is based on the 5 | SparkFun 6DOF digital board (SEN-10121). 6 | 7 | 26 Mar 2013 - Mike Hord, SparkFun Electronics 8 | 9 | This code is beerware- if you find it useful, please buy me (or, for that 10 | matter, any other SparkFun employee you met) a pint next time you meet us at 11 | the local. 12 | 13 | ***************************************************************************/ 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | int main(void) 25 | { 26 | // Set up some variables that we'll use along the way 27 | char rxBuffer[32]; // receive buffer 28 | char txBuffer[32]; // transmit buffer 29 | int gyroAddress = 0x68; // gyro device address 30 | int xlAddress = 0x53; // accelerometer device address 31 | int tenBitAddress = 0; // is the device's address 10-bit? Usually not. 32 | int opResult = 0; // for error checking of operations 33 | 34 | // Create a file descriptor for the I2C bus 35 | int i2cHandle = open("/dev/i2c-2", O_RDWR); 36 | 37 | // Tell the I2C peripheral that the device address is (or isn't) a 10-bit 38 | // value. Most probably won't be. 39 | opResult = ioctl(i2cHandle, I2C_TENBIT, tenBitAddress); 40 | 41 | // Tell the I2C peripheral what the address of the device is. We're going to 42 | // start out by talking to the gyro. 43 | opResult = ioctl(i2cHandle, I2C_SLAVE, gyroAddress); 44 | 45 | // Clear our buffers 46 | memset(rxBuffer, 0, sizeof(rxBuffer)); 47 | memset(txBuffer, 0, sizeof(txBuffer)); 48 | 49 | // The easiest way to access I2C devices is through the read/write 50 | // commands. We're going to ask the gyro to read back its "WHO_AM_I" 51 | // register, which contains the I2C address. The process is easy- write the 52 | // desired address, the execute a read command. 53 | txBuffer[0] = 0x00; // This is the address we want to read from. 54 | opResult = write(i2cHandle, txBuffer, 1); 55 | if (opResult != 1) printf("No ACK bit!\n"); 56 | opResult = read(i2cHandle, rxBuffer, 1); 57 | printf("Part ID: %d\n", (int)rxBuffer[0]); // should print 105 58 | 59 | // Next, we'll query the accelerometer using the same process- but first, 60 | // we need to change the slave address! 61 | opResult = ioctl(i2cHandle, I2C_SLAVE, xlAddress); 62 | txBuffer[0] = 0x00; // This is the address to read from. 63 | opResult = write(i2cHandle, txBuffer, 1); 64 | if (opResult != 1) printf("No ACK bit!\n"); 65 | opResult = read(i2cHandle, rxBuffer, 1); 66 | printf("Part ID: %d\n", (int)rxBuffer[0]); // should print 229 67 | } 68 | -------------------------------------------------------------------------------- /examples/I2C/i2c.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | i2c.h 3 | 4 | Header file for the i2c test program. Currently just a placeholder. 5 | 6 | 26 Mar 2013 - Mike Hord, SparkFun Electronics 7 | 8 | This code is beerware- if you find it useful, please buy me (or, for that 9 | matter, any other SparkFun employee you met) a pint next time you meet us at 10 | the local. 11 | 12 | ***************************************************************************/ 13 | 14 | #ifndef __i2c_h__ 15 | #define __i2c_h__ 16 | 17 | #endif -------------------------------------------------------------------------------- /examples/I2C/i2c.py: -------------------------------------------------------------------------------- 1 | ############################################################################## 2 | # i2c.py 3 | # 4 | # Example code for I2C bus access on the pcDuino via Python. Note that this 5 | # requires the python-smbus package to be installed 6 | # 7 | # 26 Mar 2013 - Mike Hord, SparkFun Electronics 8 | # 9 | # This code is beerware- if you find it useful, please buy me (or, for that 10 | # matter, any other SparkFun employee you met) a pint next time you meet us at 11 | # the local. 12 | # 13 | ############################################################################## 14 | 15 | #!/usr/bin/env python 16 | 17 | import smbus 18 | 19 | ## As before, we'll create an alias for our addresses, just to make things 20 | ## a bit easier and more readable later on. 21 | gyroAddress = 0x68 22 | xlAddress = 0x53 23 | 24 | ## Initialize an smbus object. The parameter passed is the number of the I2C 25 | ## bus; for the Arduino-ish headers on the pcDuino, it will be "2". 26 | i2c = smbus.SMBus(2) 27 | 28 | ## With both of these devices, the first byte written specifies the address of 29 | ## the register we want to read or write; for both devices, the device ID is 30 | ## stored in location 0. Writing that address, than issuing a read, will 31 | ## give us our answer. 32 | i2c.write_byte(gyroAddress, 0) 33 | print "Device ID: " + str(i2c.read_byte(gyroAddress)) ## should be 105 34 | 35 | i2c.write_byte(xlAddress, 0) 36 | print "Device ID: " + str(i2c.read_byte(xlAddress)) ## should be 229 37 | -------------------------------------------------------------------------------- /examples/SPI/spi_test.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | spi.cpp 3 | 4 | Example code for SPI access on the pcDuino via C++. This code *should* work 5 | in the future, but as of release, only SPI output works. Data presented on 6 | the MISO pin does not register with the device! 7 | 8 | 26 Mar 2013 - Mike Hord, SparkFun Electronics 9 | 10 | This code is beerware- if you find it useful, please buy me (or, for that 11 | matter, any other SparkFun employee you met) a pint next time you meet us at 12 | the local. 13 | 14 | ***************************************************************************/ 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include "spi_test.h" 23 | 24 | static const char *spi_name = "/dev/spidev0.0"; 25 | 26 | int main(void) 27 | { 28 | int res = 0; // We can use this to monitor the results of any operation. 29 | 30 | // The very first thing we need to do is make sure that the pins are set 31 | // to SPI mode, rather than, say, GPIO mode. 32 | char path[256]; 33 | 34 | for (int i = 10; i<=13; i++) 35 | { 36 | // Clear the path variable... 37 | memset(path,0,sizeof(path)); 38 | // ...then assemble the path variable for the current pin mode file... 39 | sprintf(path, "%s%s%d", GPIO_MODE_PATH, GPIO_FILENAME, i); 40 | // ...and create a file descriptor... 41 | int pinMode = open(path, O_RDWR); 42 | // ...which we then use to set the pin mode to SPI... 43 | setPinMode(pinMode, SPI); 44 | // ...and then, close the pinMode file. 45 | close(pinMode); 46 | } 47 | 48 | // As usual, we begin the relationship by establishing a file object which 49 | // points to the SPI device. 50 | int spiDev = open(spi_name, O_RDWR); 51 | 52 | // We'll want to configure our SPI hardware before we do anything else. To do 53 | // this, we use the ioctl() function. Calls to this function take the form 54 | // of a file descriptor, a "command", and a value. The returned value is 55 | // always the result of the operation; pass it a pointer to receive a value 56 | // requested from the SPI peripheral. 57 | 58 | // Start by setting the mode. If we wanted to *get* the mode, we could 59 | // use SPI_IOC_RD_MODE instead. In general, the "WR" can be replaced by 60 | // "RD" to fetch rather than write. Also note the somewhat awkward 61 | // setting a variable rather than passing the constant. *All* data sent 62 | // via ioctl() must be passed by reference! 63 | int mode = SPI_MODE0; 64 | ioctl(spiDev, SPI_IOC_WR_MODE, &mode); 65 | 66 | // The maximum speed of the SPI bus can be fetched. You'll find that, on the 67 | // pcDuino, it's 12MHz. 68 | int maxSpeed = 0; 69 | ioctl(spiDev, SPI_IOC_RD_MAX_SPEED_HZ, &maxSpeed); 70 | printf("Max speed: %dHz\n", maxSpeed); 71 | 72 | // In rare cases, you may find that a device expects data least significant 73 | // bit first; in that case, you'll need to set that up. Writing a 0 74 | // indicates MSb first; anything else indicates LSb first. 75 | int lsb_setting = 0; 76 | ioctl(spiDev, SPI_IOC_WR_LSB_FIRST, &lsb_setting); 77 | 78 | // Some devices may require more than 8 bits of data per transfer word. The 79 | // SPI_IOC_WR_BITS_PER_WORD command allows you to change this; the default, 80 | // 0, corresponds to 8 bits per word. 81 | int bits_per_word = 0; 82 | ioctl(spiDev, SPI_IOC_WR_BITS_PER_WORD, &bits_per_word); 83 | 84 | // Okay, now that we're all set up, we can start thinking about transferring 85 | // data. This, too, is done through ioctl(); in this case, there's a special 86 | // struct (spi_ioc_transfer) defined in spidev.h which holds the needful 87 | // info for completing a transfer. Its members are: 88 | // * tx_buf - a pointer to the data to be transferred 89 | // * rx_buf - a pointer to storage for received data 90 | // * len - length in bytes of tx and rx buffers 91 | // * speed_hz - the clock speed, in Hz 92 | // * delay_usecs - delay between last bit and deassertion of CS 93 | // * bits_per_word - override global word length for this transfer 94 | // * cs_change - strobe chip select between transfers? 95 | // * pad - ??? leave it alone. 96 | 97 | // For this example, we'll be reading the address location of an ADXL362 98 | // accelerometer, then writing a value to a register and reading it back. 99 | // We'll do two transfers, for ease of data handling: the first will 100 | // transfer the "read register" command (0x0B) and the address (0x02), the 101 | // second will dump the response back into the same buffer. 102 | 103 | struct spi_ioc_transfer xfer; 104 | memset(&xfer, 0, sizeof(xfer)); 105 | char dataBuffer[3]; 106 | char rxBuffer[3]; 107 | dataBuffer[0] = 0x0B; 108 | dataBuffer[1] = 0x02; 109 | dataBuffer[2] = 0x00; 110 | xfer.tx_buf = (unsigned long)dataBuffer; 111 | xfer.rx_buf = (unsigned long)rxBuffer; 112 | xfer.len = 3; 113 | xfer.speed_hz = 500000; 114 | xfer.cs_change = 1; 115 | xfer.bits_per_word = 8; 116 | res = ioctl(spiDev, SPI_IOC_MESSAGE(1), &xfer); 117 | printf("SPI result: %d\n", res); 118 | printf("Device ID: %d - %d - %d\n", rxBuffer[2], rxBuffer[1], rxBuffer[0]); 119 | } 120 | 121 | void setPinMode(int pinID, int mode) 122 | { 123 | writeFile(pinID, mode); 124 | } 125 | 126 | // While it seems okay to only *read* the first value from the file, you 127 | // seemingly must write four bytes to the file to get the I/O setting to 128 | // work properly. This function does that. 129 | void writeFile(int fileID, int value) 130 | { 131 | char buffer[4]; // A place to build our four-byte string. 132 | memset((void *)buffer, 0, sizeof(buffer)); // clear the buffer out. 133 | sprintf(buffer, "%d", value); 134 | lseek(fileID, 0, SEEK_SET); // Make sure we're at the top of the file! 135 | int res = write(fileID, buffer, sizeof(buffer)); 136 | } 137 | -------------------------------------------------------------------------------- /examples/SPI/spi_test.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | spi.h 3 | 4 | Header file for SPI test code for pcDuino. 5 | 6 | 26 Mar 2013 - Mike Hord, SparkFun Electronics 7 | 8 | This code is beerware- if you find it useful, please buy me (or, for that 9 | matter, any other SparkFun employee you met) a pint next time you meet us at 10 | the local. 11 | 12 | ***************************************************************************/ 13 | 14 | #ifndef __SPI_H__ 15 | #define __SPI_H__ 16 | 17 | // The SPI mode defines the resting polarity of the clock signal and the 18 | // clock edge upon which data is latched. 19 | #define SPI_MODE0 0x00 // rest = 0, latch on rise 20 | #define SPI_MODE1 0x01 // rest = 0, latch on fall 21 | #define SPI_MODE2 0x02 // rest = 1, latch on fall 22 | #define SPI_MODE3 0x03 // rest = 1, latch on rise 23 | 24 | #define SPI 2 25 | 26 | #define GPIO_MODE_PATH "/sys/devices/virtual/misc/gpio/mode/" 27 | #define GPIO_FILENAME "gpio" 28 | 29 | void writeFile(int fileID, int value); 30 | void setPinMode(int pinID, int mode); 31 | void configurePins(void); 32 | 33 | #endif -------------------------------------------------------------------------------- /examples/SPI/spi_test.py: -------------------------------------------------------------------------------- 1 | ############################################################################## 2 | # spi.py 3 | # 4 | # Example code for spi access on the pcDuino via Python. This code relies upon 5 | # the SPI-Py library by Lous Thiery and Connor Wolf, found at 6 | # https://github.com/lthiery/SPI-Py 7 | # 8 | # 26 Mar 2013 - Mike Hord, SparkFun Electronics 9 | # 10 | # This code is beerware- if you find it useful, please buy me (or, for that 11 | # matter, any other SparkFun employee you met) a pint next time you meet us at 12 | # the local. 13 | # 14 | ############################################################################## 15 | 16 | #!/usr/bin/env python 17 | 18 | import spi 19 | 20 | ## The openSPI() function is where the SPI interface is configured. There are 21 | ## three possible configuration options, and they all expect integer values: 22 | ## speed - the clock speed in Hz 23 | ## mode - the SPI mode (0, 1, 2, 3) 24 | ## bits - the length of each word, in bits (defaults to 8, which is standard) 25 | ## It is also possible to pass a device name, but the default, spidev0.0, is 26 | ## the only device currently supported by the pcDuino. 27 | 28 | spi.openSPI(speed=1000000, mode=0) 29 | 30 | ## Data is sent as a tuple, so you can construct a tuple as long as you want 31 | ## and the result will come back as a tuple of the same length. 32 | print spi.transfer((0x0B, 0x02, 0x00)) 33 | 34 | ## Finally, close the SPI connection. This is probably not necessary but it's 35 | ## good practice. 36 | spi.closeSPI() -------------------------------------------------------------------------------- /examples/analog/analog.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | analog.cpp 3 | 4 | Example code for analog I/O access on the pcDuino via C++. 5 | 6 | 26 Mar 2013 - Mike Hord, SparkFun Electronics 7 | 8 | This code is beerware- if you find it useful, please buy me (or, for that 9 | matter, any other SparkFun employee you met) a pint next time you meet us at 10 | the local. 11 | 12 | ***************************************************************************/ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include "analog.h" 20 | 21 | int adc[6]; // Array for file descriptors for the adc pins 22 | int PWMMaxVal[6]; // Store the max values for the PWM outputs 23 | char path[64]; // Nice big buffer for constructing file paths 24 | 25 | int main(void) 26 | { 27 | // For starters, let's create file descriptors for all the ADC pins. PWM is 28 | // handled differently; see the analogWrite() function for details. 29 | for(int i = 0; i<= 5; i++) 30 | { 31 | memset(path, 0, sizeof(path)); 32 | sprintf(path, "%s%s%d", ADC_IF_PATH, ADC_IF_FILE , i); 33 | adc[i] = open(path, O_RDONLY); 34 | memset(path, 0, sizeof(path)); 35 | sprintf(path, "%s%s%d/%s", PWM_IF_PATH, PWM_IF_FILE , i, PWM_MAX); 36 | int PWMMaxFD = open(path, O_RDONLY); 37 | char PWMMaxStr[4]; 38 | read(PWMMaxFD, PWMMaxStr, sizeof(PWMMaxStr)); 39 | PWMMaxVal[i] = atoi(PWMMaxStr); 40 | } 41 | 42 | // Now, we'll blast all the PWM pins to zero. 43 | for(int j = 0; j<=5; j++) 44 | { 45 | analogWrite(j, 0); 46 | } 47 | 48 | // Now we can go about the business of dimming some LEDs. 49 | for(int j = 0; j<=5; j++) 50 | { 51 | for(int i = 0; i<=255; i++) 52 | { 53 | analogWrite(j, i); 54 | usleep(10000); 55 | } 56 | analogWrite(j, 0); 57 | } 58 | 59 | // Analog input is handled by file streams. 60 | for (int i = 0; i <= 5; i++) 61 | { 62 | char ADCBuffer[16]; 63 | lseek(adc[i], 0, SEEK_SET); 64 | int res = read(adc[i], ADCBuffer, sizeof(ADCBuffer)); 65 | int ADCResult = atoi(ADCBuffer); 66 | printf("ADC Channel: %d Value: %s", i, ADCBuffer); 67 | } 68 | } 69 | 70 | // PWM pin access is handled by 71 | // using the system() command to invoke the command process to execute a 72 | // command. We assemble the command using sprintf()- the command takes 73 | // the form 74 | // echo > /sys/class/leds/pwmX/brightness 75 | // where should be replaced by an integer from 0-255 and X should 76 | // be replaced by an index value from 0-5 77 | void analogWrite(int pin, int value) 78 | { 79 | memset(path, 0, sizeof(path)); 80 | value = (PWMMaxVal[pin] * value)/255; 81 | sprintf(path, "echo %d > %s%s%d/%s", value, PWM_IF_PATH, PWM_IF_FILE, \ 82 | pin, PWM_IF); 83 | system(path); 84 | } -------------------------------------------------------------------------------- /examples/analog/analog.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | analog.h 3 | 4 | Header file for analog I/O access on the pcDuino via C++. 5 | 6 | 26 Mar 2013 - Mike Hord, SparkFun Electronics 7 | 8 | This code is beerware- if you find it useful, please buy me (or, for that 9 | matter, any other SparkFun employee you met) a pint next time you meet us at 10 | the local. 11 | 12 | ***************************************************************************/ 13 | 14 | #ifndef __analog_h__ 15 | #define __analog_h__ 16 | 17 | #define PWM_IF_PATH "/sys/class/leds/" 18 | #define PWM_IF_FILE "pwm" 19 | #define PWM_IF "brightness" 20 | #define PWM_MAX "max_brightness" 21 | 22 | #define ADC_IF_PATH "/proc/" 23 | #define ADC_IF_FILE "adc" 24 | 25 | void analogWrite(int pin, int value); 26 | 27 | #endif -------------------------------------------------------------------------------- /examples/analog/analog.py: -------------------------------------------------------------------------------- 1 | ############################################################################## 2 | # analog.py 3 | # 4 | # Example code for analog IO access on the pcDuino via Python. 5 | # 6 | # 26 Mar 2013 - Mike Hord, SparkFun Electronics 7 | # 8 | # This code is beerware- if you find it useful, please buy me (or, for that 9 | # matter, any other SparkFun employee you met) a pint next time you meet us at 10 | # the local. 11 | # 12 | ############################################################################## 13 | 14 | #!/usr/bin/env python 15 | 16 | import time, os 17 | 18 | ## For simplicity's sake, we'll create a strings and filenames for our paths 19 | ADC_PATH= os.path.normpath('/proc/') 20 | ADC_FILENAME = "adc" 21 | PWM_PATH= os.path.normpath('/sys/class/leds/') 22 | PWM_DIR = "pwm" 23 | PWM_FILENAME = "brightness" 24 | PWM_MAX = "max_brightness" 25 | 26 | ## create empty arrays to store the pointers for our files 27 | adcFiles = [] 28 | pwmFiles = [] 29 | pwmMaxFiles = [] 30 | 31 | ## create an empty array to store the maximum value for each channel of PWM 32 | pwmMaxVal = [] 33 | 34 | ## Populate the arrays with paths that we can use later. 35 | for i in range(0,6): 36 | adcFiles.append(os.path.join(ADC_PATH, ADC_FILENAME+str(i))) 37 | pwmFiles.append(os.path.join(PWM_PATH, PWM_DIR+str(i), PWM_FILENAME)) 38 | pwmMaxFiles.append(os.path.join(PWM_PATH, PWM_DIR+str(i), PWM_MAX)) 39 | 40 | ## Now, let's scan the PWM directories and pull out the values we should use 41 | ## for the maximum PWM level. 42 | for file in pwmMaxFiles: 43 | fd = open(file, 'r') 44 | pwmMaxVal.append(int(fd.read(16))) 45 | fd.close() 46 | 47 | ## Let's dim some LEDs! The method for controlling a PWM pin on the pcDuino is 48 | ## to send to the command interpreter (via os.system() this command: 49 | ## echo > /sys/class/leds/pwmX/brightness 50 | ## where varies from 0 to the maximum value found in the 51 | ## max_brightness file, and X can be from 0-5. 52 | for file in pwmFiles: 53 | j = pwmFiles.index(file) ## extract the PWM limit for this LED 54 | for i in range (0,pwmMaxVal[j]): 55 | os.system("echo " + str(i) + " >" + file) 56 | time.sleep(.01) 57 | os.system("echo 0 >" + file) 58 | 59 | ## Reading ADC values is a little more straightforward than PWM- it's just 60 | ## classic OS file reads. Note that the value that comes out of the file is 61 | ## a string, so you'll need to format it with int() if you want to do math 62 | ## with that value later on! 63 | for file in adcFiles: 64 | fd = open(file, 'r') 65 | fd.seek(0) 66 | print "ADC Channel: " + str(adcFiles.index(file)) + " Result: " + fd.read(16) 67 | fd.close() 68 | -------------------------------------------------------------------------------- /examples/gpio/gpio_test.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | gpio_test.cpp 3 | 4 | Example code for GPIO access on the pcDuino via C++. 5 | 6 | 26 Mar 2013 - Mike Hord, SparkFun Electronics 7 | 8 | This code is beerware- if you find it useful, please buy me (or, for that 9 | matter, any other SparkFun employee you met) a pint next time you meet us at 10 | the local. 11 | 12 | ***************************************************************************/ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include "gpio_test.h" 20 | 21 | // These arrays will become file descriptors for the 18 IO pin and mode files. 22 | int pinMode[18]; 23 | int pinData[18]; 24 | 25 | int main(void) 26 | { 27 | int i = 0; // Loop iterator 28 | 29 | char inputBuffer = HIGH; // create and clear a buffer for data from pins 30 | 31 | char path[256]; // nice, long buffer to hold the path name for pin access 32 | 33 | // This first loop does four things: 34 | // - initialize the file descriptors for the pin mode files 35 | // - initialize the file descriptors for the pin data files 36 | // - make the pins outputs 37 | // - set all the pins low 38 | for (i = 2; i <= 17; i++) 39 | { 40 | // Clear the path variable... 41 | memset(path,0,sizeof(path)); 42 | // ...then assemble the path variable for the current pin mode file... 43 | sprintf(path, "%s%s%d", GPIO_MODE_PATH, GPIO_FILENAME, i); 44 | // ...and create a file descriptor... 45 | pinMode[i] = open(path, O_RDWR); 46 | // ...then rinse, repeat, for the pin data files. 47 | memset(path,0,sizeof(path)); 48 | sprintf(path, "%s%s%d", GPIO_PIN_PATH, GPIO_FILENAME, i); 49 | pinData[i] = open(path, O_RDWR); 50 | // Now that we have descriptors, make the pin an output, then set it low. 51 | setPinMode(pinMode[i], OUTPUT); 52 | setPin(pinData[i], LOW); 53 | printf("Pin %d low\n", i); // Print info to the command line. 54 | } 55 | 56 | // Now, we're going to wait for a button connected to pin 2 to be pressed 57 | // before moving on with our demo. 58 | setPinMode(pinMode[2], INPUT_PU); 59 | 60 | do 61 | { 62 | printf("Waiting for button press...\n"); 63 | // This lseek() is very important- must read from the top of the file! 64 | lseek(pinData[2], 0, SEEK_SET); 65 | // Read one byte from the pinData register. The first byte will be '1' if 66 | // the pin is high and '0' if it is low. 67 | read(pinData[2], &inputBuffer, 1); 68 | usleep(100000); // Sleep for 1/10 second. 69 | } while (inputBuffer == HIGH); 70 | 71 | // After the button press, let's scan through and turn the lights on one 72 | // at a time, the back off again. After that, we're done. 73 | for (i = 3; i <= 17; i++) 74 | { 75 | setPin(pinData[i], HIGH); 76 | printf("Pin %d HIGH\n", i); 77 | usleep(250000); 78 | } 79 | 80 | for (i = 17; i >=3; i--) 81 | { 82 | setPin(pinData[i], LOW); 83 | printf("Pin %d LOW\n", i); 84 | usleep(250000); 85 | } 86 | } 87 | 88 | // These two 'set' functions are just wrappers to the writeFile() function to 89 | // make the code prettier. 90 | void setPinMode(int pinID, int mode) 91 | { 92 | writeFile(pinID, mode); 93 | } 94 | 95 | void setPin(int pinID, int state) 96 | { 97 | writeFile(pinID, state); 98 | } 99 | 100 | // While it seems okay to only *read* the first value from the file, you 101 | // seemingly must write four bytes to the file to get the I/O setting to 102 | // work properly. This function does that. 103 | void writeFile(int fileID, int value) 104 | { 105 | char buffer[4]; // A place to build our four-byte string. 106 | memset((void *)buffer, 0, sizeof(buffer)); // clear the buffer out. 107 | sprintf(buffer, "%d", value); 108 | lseek(fileID, 0, SEEK_SET); // Make sure we're at the top of the file! 109 | write(fileID, buffer, sizeof(buffer)); 110 | } 111 | -------------------------------------------------------------------------------- /examples/gpio/gpio_test.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | gpio_test.h 3 | 4 | Header file for pcDuino GPIO example code. 5 | 6 | 26 Mar 2013 - Mike Hord, SparkFun Electronics 7 | 8 | This code is beerware- if you find it useful, please buy me (or, for that 9 | matter, any other SparkFun employee you met) a pint next time you meet us at 10 | the local. 11 | 12 | ***************************************************************************/ 13 | 14 | #ifndef __gpio_test_h__ 15 | #define __gpio_test_h__ 16 | 17 | // These are the paths and filenames of the files for GPIO access. 18 | #define GPIO_MODE_PATH "/sys/devices/virtual/misc/gpio/mode/" 19 | #define GPIO_PIN_PATH "/sys/devices/virtual/misc/gpio/pin/" 20 | #define GPIO_FILENAME "gpio" 21 | 22 | void writeFile(int fileID, int value); 23 | void setPinMode(int pinID, int mode); 24 | void setPin(int pinID, int state); 25 | 26 | // Make some aliases to make the code more readable. 27 | #define HIGH '1' 28 | #define LOW '0' 29 | 30 | #define INPUT '0' 31 | #define OUTPUT '1' 32 | #define INPUT_PU '8' 33 | 34 | #endif -------------------------------------------------------------------------------- /examples/gpio/gpio_test.py: -------------------------------------------------------------------------------- 1 | ############################################################################## 2 | # gpio_test.py 3 | # 4 | # Example code for GPIO access on the pcDuino via Python 5 | # 6 | # 26 Mar 2013 - Mike Hord, SparkFun Electronics 7 | # 8 | # This code is beerware- if you find it useful, please buy me (or, for that 9 | # matter, any other SparkFun employee you met) a pint next time you meet us at 10 | # the local. 11 | # 12 | ############################################################################## 13 | 14 | #!/usr/bin/env python 15 | 16 | import time, os 17 | 18 | ## For simplicity's sake, we'll create a string for our paths. 19 | GPIO_MODE_PATH= os.path.normpath('/sys/devices/virtual/misc/gpio/mode/') 20 | GPIO_PIN_PATH=os.path.normpath('/sys/devices/virtual/misc/gpio/pin/') 21 | GPIO_FILENAME="gpio" 22 | 23 | ## create a couple of empty arrays to store the pointers for our files 24 | pinMode = [] 25 | pinData = [] 26 | 27 | ## Create a few strings for file I/O equivalence 28 | HIGH = "1" 29 | LOW = "0" 30 | INPUT = "0" 31 | OUTPUT = "1" 32 | INPUT_PU = "8" 33 | 34 | ## First, populate the arrays with file objects that we can use later. 35 | for i in range(0,18): 36 | pinMode.append(os.path.join(GPIO_MODE_PATH, 'gpio'+str(i))) 37 | pinData.append(os.path.join(GPIO_PIN_PATH, 'gpio'+str(i))) 38 | 39 | ## Now, let's make all the pins outputs... 40 | for pin in pinMode: 41 | file = open(pin, 'r+') ## open the file in r/w mode 42 | file.write(OUTPUT) ## set the mode of the pin 43 | file.close() ## IMPORTANT- must close file to make changes! 44 | 45 | ## ...and make them low. 46 | for pin in pinData: 47 | file = open(pin, 'r+') 48 | file.write(LOW) 49 | file.close() 50 | 51 | ## Next, let's wait for a button press on pin 2. 52 | file = open(pinMode[2], 'r+') ## accessing pin 2 mode file 53 | file.write(INPUT_PU) ## make the pin input with pull up 54 | file.close() ## write the changes 55 | 56 | temp = [''] ## a string to store the value 57 | file = open(pinData[2], 'r') ## open the file 58 | temp[0] = file.read() ## fetch the pin state 59 | 60 | ## Now, wait until the button gets pressed. 61 | while '0' not in temp[0]: 62 | file.seek(0) ## *MUST* be sure that we're at the start of the file! 63 | temp[0] = file.read() ## fetch the pin state 64 | print "Waiting for button press..." 65 | time.sleep(.1) ## sleep for 1/10 of a second. 66 | 67 | file.close() ## Make sure to close the file when you're done! 68 | 69 | ## Now, for the final trick, we're going to turn on all the pins, one at a 70 | ## time, then turn them off again. 71 | for i in range(3,17): 72 | file = open(pinData[i], 'r+') 73 | file.write(HIGH) 74 | file.close() 75 | time.sleep(.25) 76 | 77 | for i in range(17,2, -1): 78 | file = open(pinData[i], 'r+') 79 | file.write(LOW) 80 | file.close() 81 | time.sleep(.25) 82 | 83 | -------------------------------------------------------------------------------- /examples/hello_world/hello_world.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | hello_world.cpp 3 | 4 | Example code for C++ programming on the pcDuino. 5 | 6 | 26 Mar 2013 - Mike Hord, SparkFun Electronics 7 | 8 | This code is beerware- if you find it useful, please buy me (or, for that 9 | matter, any other SparkFun employee you met) a pint next time you meet us at 10 | the local. 11 | 12 | ***************************************************************************/ 13 | 14 | // First, let's include the standard io functions (things like printf, etc) 15 | #include 16 | 17 | int main(void) // main *must* have an int declared as return type for C++! 18 | { 19 | printf("Hello world!\n"); // print to the command line 20 | } 21 | -------------------------------------------------------------------------------- /examples/hello_world/hello_world.py: -------------------------------------------------------------------------------- 1 | ############################################################################## 2 | # hello_world.py 3 | # 4 | # Simple known-good Python test program for pcDuino 5 | # 6 | # 26 Mar 2013 - Mike Hord, SparkFun Electronics 7 | # 8 | # This code is beerware- if you find it useful, please buy me (or, for that 9 | # matter, any other SparkFun employee you met) a pint next time you meet us at 10 | # the local. 11 | # 12 | ############################################################################## 13 | 14 | #!/usr/bin/env python 15 | 16 | print "Hello, world!" 17 | -------------------------------------------------------------------------------- /examples/serial_test/serial_test.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | serial_test.cpp 3 | 4 | Example code for serial port access on the pcDuino via C++. 5 | 6 | 26 Mar 2013 - Mike Hord, SparkFun Electronics 7 | 8 | This code is beerware- if you find it useful, please buy me (or, for that 9 | matter, any other SparkFun employee you met) a pint next time you meet us at 10 | the local. 11 | 12 | ***************************************************************************/ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include "serial_test.h" 21 | 22 | // Life is easier if we make a constant for our port name. 23 | static const char* portName = "/dev/ttyS1"; 24 | 25 | int main(void) 26 | { 27 | 28 | // The very first thing we need to do is make sure that the pins are set 29 | // to SERIAL mode, rather than, say, GPIO mode. 30 | char path[256]; 31 | 32 | for (int i = 0; i<=1; i++) 33 | { 34 | // Clear the path variable... 35 | memset(path,0,sizeof(path)); 36 | // ...then assemble the path variable for the current pin mode file... 37 | sprintf(path, "%s%s%d", GPIO_MODE_PATH, GPIO_FILENAME, i); 38 | // ...and create a file descriptor... 39 | int pinMode = open(path, O_RDWR); 40 | // ...which we then use to set the pin mode to SERIAL... 41 | setPinMode(pinMode, SERIAL); 42 | // ...and then, close the pinMode file. 43 | close(pinMode); 44 | } 45 | 46 | int serialPort; // File descriptor for serial port 47 | struct termios portOptions; // struct to hold the port settings 48 | // Open the serial port as read/write, not as controlling terminal, and 49 | // don't block the CPU if it takes too long to open the port. 50 | serialPort = open(portName, O_RDWR | O_NOCTTY | O_NDELAY ); 51 | 52 | // Fetch the current port settings 53 | tcgetattr(serialPort, &portOptions); 54 | 55 | // Flush the port's buffers (in and out) before we start using it 56 | tcflush(serialPort, TCIOFLUSH); 57 | 58 | // Set the input and output baud rates 59 | cfsetispeed(&portOptions, B115200); 60 | cfsetospeed(&portOptions, B115200); 61 | 62 | // c_cflag contains a few important things- CLOCAL and CREAD, to prevent 63 | // this program from "owning" the port and to enable receipt of data. 64 | // Also, it holds the settings for number of data bits, parity, stop bits, 65 | // and hardware flow control. 66 | portOptions.c_cflag |= CLOCAL; 67 | portOptions.c_cflag |= CREAD; 68 | // Set up the frame information. 69 | portOptions.c_cflag &= ~CSIZE; // clear frame size info 70 | portOptions.c_cflag |= CS8; // 8 bit frames 71 | portOptions.c_cflag &= ~PARENB;// no parity 72 | portOptions.c_cflag &= ~CSTOPB;// one stop bit 73 | 74 | // Now that we've populated our options structure, let's push it back to the 75 | // system. 76 | tcsetattr(serialPort, TCSANOW, &portOptions); 77 | 78 | // Flush the buffer one more time. 79 | tcflush(serialPort, TCIOFLUSH); 80 | 81 | // Let's write the canonical test string to the serial port. 82 | write(serialPort, "Hello, World!", 13); 83 | 84 | // Now, let's wait for an input from the serial port. 85 | fcntl(serialPort, F_SETFL, 0); // block until data comes in 86 | 87 | char dataIn = 0; 88 | do 89 | { 90 | read(serialPort,&dataIn,1); 91 | } while(dataIn == 0); 92 | 93 | printf("You entered: %c\n", dataIn); 94 | 95 | // Don't forget to close the port! Failing to do so can cause problems when 96 | // attempting to execute code in another program. 97 | close(serialPort); 98 | } 99 | 100 | void setPinMode(int pinID, int mode) 101 | { 102 | writeFile(pinID, mode); 103 | } 104 | 105 | // While it seems okay to only *read* the first value from the file, you 106 | // seemingly must write four bytes to the file to get the I/O setting to 107 | // work properly. This function does that. 108 | void writeFile(int fileID, int value) 109 | { 110 | char buffer[4]; // A place to build our four-byte string. 111 | memset((void *)buffer, 0, sizeof(buffer)); // clear the buffer out. 112 | sprintf(buffer, "%d", value); 113 | lseek(fileID, 0, SEEK_SET); // Make sure we're at the top of the file! 114 | int res = write(fileID, buffer, sizeof(buffer)); 115 | } 116 | -------------------------------------------------------------------------------- /examples/serial_test/serial_test.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | serial_test.h 3 | 4 | Header file for serial port test code for pcDuino. 5 | 6 | 11 Apr 2013 - Mike Hord, SparkFun Electronics 7 | 8 | This code is beerware- if you find it useful, please buy me (or, for that 9 | matter, any other SparkFun employee you met) a pint next time you meet us at 10 | the local. 11 | 12 | ***************************************************************************/ 13 | 14 | #ifndef __SERIAL_TEST_H__ 15 | #define __SERIAL_TEST_H__ 16 | 17 | #define SERIAL 3 18 | 19 | #define GPIO_MODE_PATH "/sys/devices/virtual/misc/gpio/mode/" 20 | #define GPIO_FILENAME "gpio" 21 | 22 | void writeFile(int fileID, int value); 23 | void setPinMode(int pinID, int mode); 24 | void configurePins(void); 25 | 26 | #endif -------------------------------------------------------------------------------- /examples/serial_test/serial_test.py: -------------------------------------------------------------------------------- 1 | ############################################################################## 2 | # serial_test.py 3 | # 4 | # Example code for serial port access on the pcDuino via Python. Note that 5 | # this example assumes that you have the pyserial library installed on your 6 | # system. 7 | # 8 | # 26 Mar 2013 - Mike Hord, SparkFun Electronics 9 | # 10 | # This code is beerware- if you find it useful, please buy me (or, for that 11 | # matter, any other SparkFun employee you met) a pint next time you meet us at 12 | # the local. 13 | # 14 | ############################################################################## 15 | 16 | #!/usr/bin/env python 17 | 18 | import serial ## Load the serial library 19 | 20 | ## Select and configure the port 21 | myPort = serial.Serial('/dev/ttyS1', 115200, timeout = 10) 22 | 23 | ## Dump some data out of the port 24 | myPort.write("Hello, world!") 25 | 26 | ## Wait for data to come in- one byte, only 27 | x = myPort.read() 28 | 29 | ## Echo the data to the command prompt 30 | print "You entered " + x 31 | 32 | ## Close the port so other applications can use it. 33 | myPort.close() 34 | --------------------------------------------------------------------------------