Chris Styles
/
EA_RotaryEncoder
This example positions a lit LED in the I2C LED array using the rotary encoder
Revision 0:498b9b4a7bb9, committed 2010-03-02
- Comitter:
- chris
- Date:
- Tue Mar 02 08:27:23 2010 +0000
- Commit message:
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PCA9532.cpp Tue Mar 02 08:27:23 2010 +0000 @@ -0,0 +1,186 @@ +/* +PCA9532 +(c) 2009, cstyles +*/ + +#include "PCA9532.h" +#include "mbed.h" + +/* + Constructor, pin names for I2C and the I2C addrss of the device + */ + + +PCA9532::PCA9532(PinName scl, PinName sda, int addr) + : _i2c(scl, sda) { + + _addr = addr; + +} + + + + + +/* + force the LEDs on or off according to thier corresponding bits + in the vector + */ + +void PCA9532::write (int leds) { + + // cycle through the array + for (int i=0; i < 16; i++) { + + // if the ith bit is '1' + if (leds & (0x1 << i)) { + _rmw(i,PCA9532_MODE_SET); + } + + else { + _rmw(i,PCA9532_MODE_CLEAR); + } + } +} + + + +/* + this is one hot encoding for the LED array + any bit set will have it's corresponding LED switched on + */ + +void PCA9532::set (int leds) { + for (int i=0; i < 16; i++) { + if (leds & (0x1 << i)) { + _rmw(i,PCA9532_MODE_SET); + } + } +} + + +void PCA9532::clear (int leds) { + for (int i=0; i < 16; i++) { + if (leds & (0x1 << i)) { + _rmw(i,PCA9532_MODE_CLEAR); + } + } +} + + +void PCA9532::pwm0 (int leds) { + for (int i=0; i < 16; i++) { + if (leds & (0x1 << i)) { + _rmw(i,PCA9532_MODE_PWM0); + } + } +} + + +void PCA9532::pwm1 (int leds) { + for (int i=0; i < 16; i++) { + if (leds & (0x1 << i)) { + _rmw(i,PCA9532_MODE_PWM1); + } + } +} + + +void PCA9532::duty0 (float d) { + +char duty = 0; + +if (d > 1.0) { duty = 255; } +else if ( d < 0.0 ) { duty = 0; } +else { duty = 256 * d; } + +_write(PCA9532_REG_PWM0,duty); + +} + + +void PCA9532::duty1 (float d) { + +char duty = 0; + +if (d > 1.0) { duty = 255; } +else if ( d < 0.0 ) { duty = 0; } +else { duty = 256 * d; } + +_write(PCA9532_REG_PWM1,duty); + +} + + + + + + + +/* + led is in the range 0-15 + mode is inthe range 0-3 + */ + +void PCA9532::_rmw(int led, int mode) { + + int reg = 0; + int offset = (led % 4); + + // makesure mode is within bounds + if ( (mode < 0) || (mode > 3) ) { + return; + } + + + // determine which register this is, + if (led < 4) { + reg = PCA9532_REG_LS0;} + + else if ( (led > 3) && (led < 8) ) { + reg = PCA9532_REG_LS1;} + + else if ( (led > 7) && (led < 12) ) { + reg = PCA9532_REG_LS2;} + + else if ( (led > 11) && (led < 16) ) { + reg = PCA9532_REG_LS3;} + + else { return; } + + // read the current status of the register + char regval = _read(reg); + + // clear the two bit slice at the calculated offset + regval &= ~(0x3 << (2 * offset)); + + // now OR in the mode, shifted by 2 8 offset + regval |= (mode << (2 * offset)); + + // write this back + + _write(reg,regval); + + return; +} + + +void PCA9532::_write(int reg, int data) { + char args[2]; + args[0] = reg; + args[1] = data; + _i2c.write(_addr,args,2); +} + + +int PCA9532::_read(int reg) { + char args[2]; + args[0] = reg; + _i2c.write(_addr,args,2); + return(args[1]); +} + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PCA9532.h Tue Mar 02 08:27:23 2010 +0000 @@ -0,0 +1,64 @@ +/* PCA9532 + * (c) 2009, cstyles + */ + +#ifndef PCA9532_H +#define PCA9532_H + +#include "mbed.h" + +// register names +#define PCA9532_REG_INPUT0 0 +#define PCA9532_REG_INPUT1 1 +#define PCA9532_REG_PSC0 2 +#define PCA9532_REG_PWM0 3 +#define PCA9532_REG_PSC1 4 +#define PCA9532_REG_PWM1 5 +#define PCA9532_REG_LS0 6 +#define PCA9532_REG_LS1 7 +#define PCA9532_REG_LS2 8 +#define PCA9532_REG_LS3 9 + +#define PCA9532_MODE_CLEAR 0 +#define PCA9532_MODE_SET 1 +#define PCA9532_MODE_PWM0 2 +#define PCA9532_MODE_PWM1 3 + + + + + +class PCA9532 { + +public: + + PCA9532(PinName sda, PinName scl, int addr); + + void write (int leds); + + void set (int leds); + void clear (int leds); + void pwm0 (int leds); + void pwm1 (int leds); + + void duty0 (float d); + void duty1 (float d); + + void period0 (float t); + void period1 (float t); + +protected: + + void _write(int reg, int data); + int _read(int reg); + + void _rmw(int led, int mode); + + int _addr; + + I2C _i2c; + +}; + + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RotaryEncode.cpp Tue Mar 02 08:27:23 2010 +0000 @@ -0,0 +1,81 @@ +/* +RotaryEncode +(c) 2009, cstyles +*/ + +#include "RotaryEncode.h" +#include "mbed.h" + +/* + Constructor, pin names for I2C and the I2C addrss of the device + */ + + +RotaryEncode::RotaryEncode(PinName A, PinName B) + : _rotary_in(A,B) { + + _position = 0; + + // Attach ticker + _ticker.attach(this, &RotaryEncode::_ticker_handler, 0.010); +} + + + +int RotaryEncode::read(void) { + int rval = _position; + _position = 0; + return (rval); +} + + + + +void RotaryEncode::_ticker_handler(void) { + + _state = _rotary_in; + _e = R_W; + + // we're in the no-change state + if (_state == 0x03) { + return; + } + + while (_state != 0x03) { + switch (_e) { + case R_W: + if (_state == 0x02) + _e = R_R1; + else if (_state == 0x01) + _e = R_L1; + break; + + case R_L1: + if (_state == 0x00) + _e = R_R2; + break; + case R_L2: + if (_state == 0x01) { + _e = R_R3; + _position++; + } + break; + case R_R1: + if (_state == 0x00) + _e = R_L2; + break; + case R_R2: + if (_state == 0x02) { + _e = R_L3; + _position--; + } + break; + } + _state = _rotary_in; + } + +} + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RotaryEncode.h Tue Mar 02 08:27:23 2010 +0000 @@ -0,0 +1,38 @@ +/* Rotary Encoder + * (c) 2009, cstyles + */ + +#ifndef ROTARY_ENCODE_H +#define ROTARY_ENCODE_H + +#include "mbed.h" + +#define R_W 0 +#define R_L1 1 +#define R_L2 2 +#define R_L3 3 +#define R_R1 4 +#define R_R2 5 +#define R_R3 6 + + +class RotaryEncode { + +public: + + RotaryEncode(PinName A, PinName B); + int read (void); + +protected: + + BusIn _rotary_in; + Ticker _ticker; + void _ticker_handler (void); + + int _position; + int _state; + int _e; + +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Mar 02 08:27:23 2010 +0000 @@ -0,0 +1,29 @@ +#include "mbed.h" +#include "RotaryEncode.h" +#include "PCA9532.h" + +RotaryEncode RE(p16,p17); +PCA9532 leds (p28,p27,0xc0); + +int main() { + + int position = 0; + + while(1) { + + int offset = RE.read(); + + if ((offset > 0) && (position < 15)) { + position++; + } + else if ((offset < 0) && (position > 0)) { + position--; + } + + leds.write(0x1 << position); + wait (0.2); + + } +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Tue Mar 02 08:27:23 2010 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/49a220cc26e0