Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* === ROTARY ENCODER I2C SLAVE ===
- * Program takes input from a rotary encoder on a AtTiny85 and
- * sends the position and button data back via IĀ²C upon request
- *
- * Code and Library borrowed from: https://github.com/lucullusTheOnly/TinyWire
- *
- * KY-040 Rotary Encoder: http://henrysbench.capnfatz.com/henrys-bench/arduino-sensors-and-input/keyes-ky-040-arduino-rotary-encoder-user-manual/
- *
- * Transmit byte:
- * 1 0100000
- * ^ \_____/
- * | ^-- Offset from 63
- * |
- * |---- Is the button pressed? (0: No, 1: Yes)
- *
- * ===== PINOUT ======
- *
- * Rotary Encoder: AtTiny85:
- * - CLK (Pin 1) _____
- * - DT (Pin 2) 5 -|O |- +5v
- * - SW (Switch) DT 3 -| |- 2 SCL
- * - + (+5v) CLK 4 -| |- 1 SW
- * - GND (Ground) GND -|_____|- 0 SDA
- *
- */
- #include <TinyWire.h>
- // Size of one edge of the matrix
- #define I2C_SLAVE_ADDRESS 0x6
- // Rotary encoder pins
- #define PIN_1 4
- #define PIN_2 3
- #define SWITCH_PIN 1
- const byte buttonBit = B10000000; // the bit the button is stored on to transmit
- const int defPos = 63; // The default encoder position
- volatile int8_t encoderOffset = 0; // The offset from the default position
- boolean pressed = false; // Is the button pressed?
- int pinALast;
- int aVal;
- const byte def_tx = B00111111; // Default transmit byte
- byte i2c_tx = def_tx; // Byte for transmitting data
- //===================================================================
- // CUSTOM FUNCTIONS
- //===================================================================
- //*******************************************************************
- // Gets the displacement of the rotary encoder
- // Code based on: http://henrysbench.capnfatz.com/henrys-bench/arduino-sensors-and-input/keyes-ky-040-arduino-rotary-encoder-user-manual/
- void readRotaryEncoder() {
- aVal = digitalRead(PIN_1);
- if (aVal != pinALast) { // Means the knob is rotating
- // if the knob is rotating, we need to determine direction
- // We do that by reading pin B.
- if (digitalRead(PIN_2) != aVal) { // Means pin A Changed first - We're Rotating Clockwise
- encoderOffset ++;
- //value++;
- }
- else { // Otherwise B changed first and we're moving CCW
- encoderOffset--;
- //value--;
- }
- }
- pinALast = aVal;
- }
- //*******************************************************************
- // Returns if the switch is pressed or not
- boolean getSwitchState(){
- return !digitalRead(SWITCH_PIN);
- }
- //*******************************************************************
- // Make the byte to transmit
- byte getTransmitByte() {
- byte b = 0; // byte to return
- int pos = defPos + encoderOffset; // get the position of the encoder relative to the center
- pos = constrain(pos, 0, 127); // make sure that the position is between 0 to 127
- b = pos; // set the byte to the offset from 64
- // if the button is pressed
- if (pressed) b |= buttonBit; // set the buttonBit on
- else b &= ~buttonBit; // set the buttonBit off
- return b; // return the byte to be transmitted
- }
- //===================================================================
- // MAIN FUNCTIONS
- //===================================================================
- void setup() {
- // set pinsto input for rotary encoder
- pinMode(PIN_1, INPUT);
- pinMode(PIN_2, INPUT);
- pinMode(SWITCH_PIN, INPUT_PULLUP);
- // config TinyWire library for I2C slave functionality
- TinyWire.begin(I2C_SLAVE_ADDRESS);
- // register a handler function in case of a request from a master
- TinyWire.onRequest(onI2CRequest);
- pinALast = digitalRead(PIN_1);
- }
- void loop() {
- // Update the offset
- readRotaryEncoder();
- // Get if the button is pressed or not
- pressed = getSwitchState();
- // Update the I2C transfer buffer
- i2c_tx = getTransmitByte();
- }
- //*******************************************************************
- // Request Event handler function
- // --> Keep in mind, that this is executed in an interrupt service routine. It shouldn't take long to execute
- // Based on code from: https://github.com/lucullusTheOnly/TinyWire/blob/master/examples/slave_sender/slave_sender.ino
- void onI2CRequest() {
- // sends one byte 'i2c_tx' to the master containing encoder offset and button state
- TinyWire.send(i2c_tx);
- // clear the transmit byte
- i2c_tx = def_tx;
- //reset the encoder offset
- encoderOffset = 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement