|
| 1 | +/* SX1509 Library Example 03 |
| 2 | + Buttons with interrupts, and debouncing |
| 3 | + by: Jim Lindblom |
| 4 | + SparkFun Electronics |
| 5 | + license: Beerware. Please use, reuse, share, and modify this |
| 6 | + code. I'd ask that you maintain attribution and open-source. |
| 7 | + If you find it useful, you can buy me a beer when we meet |
| 8 | + some day. |
| 9 | + |
| 10 | + This example shows how you can use the following SX1509 |
| 11 | + library methods: |
| 12 | + - constructor |
| 13 | + - init() |
| 14 | + - pinDir |
| 15 | + - writePin |
| 16 | + - readPin |
| 17 | + - configClock |
| 18 | + - enableInterrupt |
| 19 | + - debounceConfig |
| 20 | + - debounceEnable |
| 21 | + - pwm |
| 22 | +
|
| 23 | + Hardware: The SX1509 should be hooked up like so: |
| 24 | + SX1509 Pin Arduino Pin |
| 25 | + 3.3V ---------- 3.3V |
| 26 | + GND ----------- GND |
| 27 | + SDA ----------- A4 (or SDA on newer boards) |
| 28 | + SCL ----------- A5 (or SCL on newer boards) |
| 29 | + nRST ---------- 8 (could be any digital pin) |
| 30 | + nINT ---------- 3 (could be any digital pin) |
| 31 | + OSCIO is not used in this example. |
| 32 | + |
| 33 | + See the SX1509_ADDRESS defines to decide which address you need |
| 34 | + to send to the constructor. By default the SX1509 Breakout |
| 35 | + sets both ADDR pins to 0 (so 0x3E I2C address). |
| 36 | +
|
| 37 | + In addition SX1509 i/o pins are used. The pwmPin should be |
| 38 | + sinking current to an LED. So the LED should be pulled |
| 39 | + (through a current-limiting resistor) to 3.3V. One button pin |
| 40 | + is active high, the other is active low to demo both functions. |
| 41 | + 14 - PWM'ing LED |
| 42 | + 1 and 5 - Input buttons. One tied high, other tied low. |
| 43 | +*/ |
| 44 | + |
| 45 | +#include <Wire.h> // Wire.h library is required to use SX1509 lib |
| 46 | +#include <sx1509_library.h> // Include the SX1509 library |
| 47 | + |
| 48 | +// Uncomment one of the four lines to match your SX1509's address |
| 49 | +// pin selects. SX1509 breakout defaults to [0:0] (0x3E). |
| 50 | +//const byte SX1509_ADDRESS = 0x3E; // SX1509 I2C address (00) |
| 51 | +const byte SX1509_ADDRESS = 0x3F; // SX1509 I2C address (01) |
| 52 | +//const byte SX1509_ADDRESS = 0x70; // SX1509 I2C address (10) |
| 53 | +//const byte SX1509_ADDRESS = 0x71; // SX1509 I2C address (11) |
| 54 | + |
| 55 | +// Arduino pin definitions |
| 56 | +const byte resetPin = 8; |
| 57 | +const byte interruptPin = 3; |
| 58 | + |
| 59 | +// SX1509 I/O pin definitions |
| 60 | +const byte upPin = 1; |
| 61 | +const byte downPin = 5; |
| 62 | +int pwmLED = 14; |
| 63 | + |
| 64 | +// Create a new sx1509Class object |
| 65 | +sx1509Class sx1509(SX1509_ADDRESS, resetPin, interruptPin); |
| 66 | + |
| 67 | +// global variables |
| 68 | +byte intensity = 0; |
| 69 | +const byte increment = 1; |
| 70 | + |
| 71 | +void setup() |
| 72 | +{ |
| 73 | + // Must first initialize the sx1509: |
| 74 | + sx1509.init(); |
| 75 | + |
| 76 | + // Configure the PWM'ing LED. For more info see example 2. |
| 77 | + sx1509.ledDriverInit(pwmLED); |
| 78 | + sx1509.pwm(pwmLED, intensity); |
| 79 | + |
| 80 | + // Setup the button pins. The upPin will be pulled low, while |
| 81 | + // the downPin will be pulled high. The upPin button will cause |
| 82 | + // that pin to go high. The downPin button will cause that pin |
| 83 | + // to go low. |
| 84 | + sx1509.pinDir(upPin, INPUT); // Configures the pin as an input |
| 85 | + sx1509.writePin(upPin, LOW); // Activates pull-down resistor |
| 86 | + // Now we enable the interrupt on upPin. A signal going from 0V |
| 87 | + // to 3.3V (rising) will mean the button is being pressed. |
| 88 | + // That's when we want the interrupt to trigger. |
| 89 | + sx1509.enableInterrupt(upPin, RISING); |
| 90 | + |
| 91 | + sx1509.pinDir(downPin, INPUT); // Configures the pin as an input |
| 92 | + sx1509.writePin(downPin, HIGH); // Activates pull-up resistor |
| 93 | + // Now we enable the interrupt on downPin. A signal going from 3.3V |
| 94 | + // to 0 (falling) will mean the button is being pressed. |
| 95 | + // That's when we want the interrupt to trigger. |
| 96 | + sx1509.enableInterrupt(downPin, FALLING); |
| 97 | + |
| 98 | + // Stuff to configure button debouncing: |
| 99 | + |
| 100 | + // The clock must be configured for debouncing to work: |
| 101 | + // The configClock command takes 4 parameters (all optional). |
| 102 | + // First is whether to use an external clock signal or external. |
| 103 | + // Internal is easier, requires less connections to SX1509. |
| 104 | + // Next two parameters can be used to configure OSCIO as an |
| 105 | + // output or input. And sets the output frequency (if config'd |
| 106 | + // as an output. |
| 107 | + // Last parameter sets the clock divider. This should be a value |
| 108 | + // between 1 and 7. clkX = fOSC / (2^(thisValue - 1) |
| 109 | + sx1509.configClock(INTERNAL_CLOCK, OUTPUT, 0xE, 1); |
| 110 | + // Sending this command with no parameters is also an option. |
| 111 | + // This will automatically select the internal oscillator. |
| 112 | + // Divider of 1 on the clock (so it'll go at 2MHz) |
| 113 | + // And leave the OSCIO pin unused: |
| 114 | + //sx1509.configClock(); |
| 115 | + |
| 116 | + // the debounceConfig function sets the debounce time. This |
| 117 | + // function's parameter should be a 3-bit value. |
| 118 | + // 0: 0.5ms * 2MHz/fOSC |
| 119 | + // 1: 1ms * 2MHz/fOSC |
| 120 | + // 2: 2ms * 2MHz/fOSC |
| 121 | + // 3: 4ms * 2MHz/fOSC |
| 122 | + // 4: 8ms * 2MHz/fOSC |
| 123 | + // 5: 16ms * 2MHz/fOSC |
| 124 | + // 6: 32ms * 2MHz/fOSC |
| 125 | + // 7: 64ms * 2MHz/fOSC |
| 126 | + sx1509.debounceConfig(7); // maximum debuonce time |
| 127 | + |
| 128 | + // Now we call debounceEnable on the pins we want to debounce: |
| 129 | + sx1509.debounceEnable(upPin); |
| 130 | + sx1509.debounceEnable(downPin); |
| 131 | +} |
| 132 | + |
| 133 | +// The loop will demo the interruptSource() function as well |
| 134 | +// as readPin and pwm. |
| 135 | +void loop() |
| 136 | +{ |
| 137 | + // The interrupt pin will go low when an interrupt has occured |
| 138 | + if (digitalRead(interruptPin) == 0) |
| 139 | + { |
| 140 | + // The interruptSource function will return a 16-bit value. |
| 141 | + // where each bit represents on of the pins. A 1-value |
| 142 | + // bit means that pin was the source of an interrupt. |
| 143 | + unsigned int interruptSource = sx1509.interruptSource(); |
| 144 | + |
| 145 | + // When need to check a particular bit against the |
| 146 | + // interruptSource return value. This will check if upPin |
| 147 | + // created the interrupt: |
| 148 | + if (interruptSource & (1<<upPin)) |
| 149 | + { |
| 150 | + // Let's stay here until the upPin is released. upPin is |
| 151 | + // pulled low, when the button is pressed it goes high. |
| 152 | + // So do this loop while the upPin remains high. |
| 153 | + while (sx1509.readPin(upPin) == 1) |
| 154 | + { |
| 155 | + // Increment intensity, and output that to the pwm'ing LED |
| 156 | + intensity+=increment; |
| 157 | + sx1509.pwm(pwmLED, intensity); |
| 158 | + } |
| 159 | + } |
| 160 | + |
| 161 | + // Now we'll check if downPin created the interrupt. |
| 162 | + if (interruptSource & (1<<downPin)) |
| 163 | + { |
| 164 | + // If so, do the same thing while this pin reads low. |
| 165 | + while (sx1509.readPin(downPin) == 0) |
| 166 | + { |
| 167 | + // Decrement intensity, and send that new value to the pwm |
| 168 | + intensity-=increment; |
| 169 | + sx1509.pwm(pwmLED, intensity); |
| 170 | + } |
| 171 | + } |
| 172 | + } |
| 173 | +} |
0 commit comments