First init.

This commit is contained in:
2025-10-12 09:13:56 +02:00
commit 1548aeaf9b
458 changed files with 118808 additions and 0 deletions

View File

@@ -0,0 +1,65 @@
#include "Adafruit_Crickit.h"
// the pwm pins
#define CRICKIT_NUM_PWM 12
static const uint8_t CRICKIT_pwms[CRICKIT_NUM_PWM] = {
CRICKIT_SERVO4, CRICKIT_SERVO3, CRICKIT_SERVO2, CRICKIT_SERVO1,
CRICKIT_MOTOR_B1, CRICKIT_MOTOR_B2, CRICKIT_MOTOR_A1, CRICKIT_MOTOR_A2,
CRICKIT_DRIVE4, CRICKIT_DRIVE3, CRICKIT_DRIVE2, CRICKIT_DRIVE1};
// the adc pin
#define CRICKIT_NUM_ADC 8
static const uint8_t CRICKIT_adc[CRICKIT_NUM_ADC] = {
CRICKIT_SIGNAL1, CRICKIT_SIGNAL2, CRICKIT_SIGNAL3, CRICKIT_SIGNAL4,
CRICKIT_SIGNAL5, CRICKIT_SIGNAL6, CRICKIT_SIGNAL7, CRICKIT_SIGNAL8};
void Adafruit_Crickit::analogWrite(uint8_t pin, uint16_t value, uint8_t width) {
(void)width;
int8_t p = -1;
for (int i = 0; i < CRICKIT_NUM_PWM; i++) {
if (CRICKIT_pwms[i] == pin) {
p = i;
break;
}
}
if (p > -1) {
uint8_t cmd[] = {(uint8_t)p, (uint8_t)(value >> 8), (uint8_t)value};
this->write(SEESAW_TIMER_BASE, SEESAW_TIMER_PWM, cmd, 3);
}
}
uint16_t Adafruit_Crickit::analogRead(uint8_t pin) {
uint8_t buf[2];
int8_t p = -1;
for (int i = 0; i < CRICKIT_NUM_ADC; i++) {
if (CRICKIT_adc[i] == pin) {
p = i;
break;
}
}
if (p > -1) {
this->read(SEESAW_ADC_BASE, SEESAW_ADC_CHANNEL_OFFSET + p, buf, 2, 500);
uint16_t ret = ((uint16_t)buf[0] << 8) | buf[1];
delay(1);
return ret;
} else
return 0;
}
void Adafruit_Crickit::setPWMFreq(uint8_t pin, uint16_t freq) {
int8_t p = -1;
for (int i = 0; i < CRICKIT_NUM_PWM; i++) {
if (CRICKIT_pwms[i] == pin) {
p = i;
break;
}
}
if (p > -1) {
uint8_t cmd[] = {(uint8_t)p, (uint8_t)(freq >> 8), (uint8_t)freq};
this->write(SEESAW_TIMER_BASE, SEESAW_TIMER_FREQ, cmd, 3);
}
}

View File

@@ -0,0 +1,53 @@
#ifndef _CRICKIT_TERSTER_H
#define _CRICKIT_TERSTER_H
#include "Adafruit_seesaw.h"
#define CRICKIT_SIGNAL1 2
#define CRICKIT_SIGNAL2 3
#define CRICKIT_SIGNAL3 40
#define CRICKIT_SIGNAL4 41
#define CRICKIT_SIGNAL5 11
#define CRICKIT_SIGNAL6 10
#define CRICKIT_SIGNAL7 9
#define CRICKIT_SIGNAL8 8
#define CRICKIT_SERVO4 14
#define CRICKIT_SERVO3 15
#define CRICKIT_SERVO2 16
#define CRICKIT_SERVO1 17
#define CRICKIT_MOTOR_A1 22
#define CRICKIT_MOTOR_A2 23
#define CRICKIT_MOTOR_B1 19
#define CRICKIT_MOTOR_B2 18
#define CRICKIT_DRIVE1 13
#define CRICKIT_DRIVE2 12
#define CRICKIT_DRIVE3 43
#define CRICKIT_DRIVE4 42
#define CRICKIT_TOUCH1 0
#define CRICKIT_TOUCH2 1
#define CRICKIT_TOUCH3 2
#define CRICKIT_TOUCH4 3
#define CRICKIT_DUTY_CYCLE_OFF 0
#define CRICKIT_DUTY_CYCLE_MAX 65535
/**************************************************************************/
/*!
@brief Class that stores state and functions for interacting with Crickit
variant of seesaw helper IC
*/
/**************************************************************************/
class Adafruit_Crickit : public Adafruit_seesaw {
public:
Adafruit_Crickit(){};
~Adafruit_Crickit(){};
void analogWrite(uint8_t pin, uint16_t value, uint8_t width = 8);
uint16_t analogRead(uint8_t pin);
void setPWMFreq(uint8_t pin, uint16_t freq);
};
#endif

View File

@@ -0,0 +1,336 @@
#include "Adafruit_NeoKey_1x4.h"
/**************************************************************************/
/*!
@brief Class constructor
@param addr the I2C address this neotrellis object uses
@param i2c_bus the I2C bus connected to this neokey, defaults to "Wire"
*/
/**************************************************************************/
Adafruit_NeoKey_1x4::Adafruit_NeoKey_1x4(uint8_t addr, TwoWire *i2c_bus)
: Adafruit_seesaw(i2c_bus), pixels(NEOKEY_1X4_KEYS, NEOKEY_1X4_NEOPIN,
NEO_GRB + NEO_KHZ800, i2c_bus) {
for (int i = 0; i < NEOKEY_1X4_KEYS; i++) {
_callbacks[i] = NULL;
}
this->_addr = addr;
}
/**************************************************************************/
/*!
@brief Begin communication with the RGB trellis.
@param addr optional i2c address where the device can be found. Defaults to
NEOKEY_1X4_ADDR
@param flow optional flow control pin
@returns true on success, false on error.
*/
/**************************************************************************/
bool Adafruit_NeoKey_1x4::begin(uint8_t addr, int8_t flow) {
_addr = addr;
bool ret = pixels.begin(addr, flow);
if (!ret)
return ret;
ret = Adafruit_seesaw::begin(addr, flow, false);
if (!ret)
return ret;
pixels.setBrightness(40);
pixels.show(); // Initialize all pixels to 'off'
delay(5);
pinModeBulk(NEOKEY_1X4_BUTTONMASK, INPUT_PULLUP);
setGPIOInterrupts(NEOKEY_1X4_BUTTONMASK, 1);
return ret;
}
/**************************************************************************/
/*!
@brief register a callback function on the passed key.
@param key the key number to register the callback on
@param cb the callback function that should be called when an event on that
key happens
*/
/**************************************************************************/
void Adafruit_NeoKey_1x4::registerCallback(uint8_t key,
NeoKey1x4Callback (*cb)(keyEvent)) {
_callbacks[key] = cb;
}
/**************************************************************************/
/*!
@brief unregister a callback on a given key
@param key the key number the callback is currently mapped to.
*/
/**************************************************************************/
void Adafruit_NeoKey_1x4::unregisterCallback(uint8_t key) {
_callbacks[key] = NULL;
}
/**************************************************************************/
/*!
@brief Read key GPIO pins, possibly generating callback events
@returns Byte with the bottom 4 bits corresponding to each keypress status
*/
/**************************************************************************/
uint8_t Adafruit_NeoKey_1x4::read(void) {
uint32_t buttons = digitalReadBulk(NEOKEY_1X4_BUTTONMASK);
buttons ^= NEOKEY_1X4_BUTTONMASK;
buttons &= NEOKEY_1X4_BUTTONMASK;
buttons >>= NEOKEY_1X4_BUTTONA;
uint8_t just_pressed = (buttons ^ last_buttons) & buttons;
uint8_t just_released = (buttons ^ last_buttons) & ~buttons;
if (just_pressed | just_released) {
// Serial.print("pressed 0x"); Serial.println(just_pressed, HEX);
// Serial.print("released 0x"); Serial.println(just_released, HEX);
for (int b = 0; b < 4; b++) {
if (just_pressed & (1 << b)) { // if button b is pressed
if (_callbacks[b] != NULL) {
keyEvent evt = {SEESAW_KEYPAD_EDGE_RISING, (uint16_t)b};
_callbacks[b](evt);
}
}
if (just_released & (1 << b)) { // if button b is released
if (_callbacks[b] != NULL) {
keyEvent evt = {SEESAW_KEYPAD_EDGE_FALLING, (uint16_t)b};
_callbacks[b](evt);
}
}
}
}
last_buttons = buttons;
return buttons;
}
/**************************************************************************/
/*!
@brief class constructor
@param neokeys pointer to a multidimensional array of Adafruit_NeoKey_1x4
objects. these object must have their I2C addresses specified in the class
constructors.
@param rows the number of individual neokey boards in the Y direction
of your matrix.
@param cols the number of individual neokey boards in the X direction
of your matrix.
*/
/**************************************************************************/
Adafruit_MultiNeoKey1x4::Adafruit_MultiNeoKey1x4(Adafruit_NeoKey_1x4 *neokeys,
uint8_t rows, uint8_t cols) {
this->_rows = rows;
this->_cols = cols;
this->_neokeys = neokeys;
}
/**************************************************************************/
/*!
@brief begin communication with the matrix of neotrellis boards.
@returns true on success, false otherwise.
*/
/**************************************************************************/
bool Adafruit_MultiNeoKey1x4::begin() {
Adafruit_NeoKey_1x4 *t;
for (int n = 0; n < _rows; n++) {
for (int m = 0; m < _cols; m++) {
t = (_neokeys + n * _cols) + m;
if (!t->begin(t->_addr))
return false;
}
}
return true;
}
/**************************************************************************/
/*!
@brief register a callback for a key addressed by key index.
@param x the column index of the key. column 0 is on the lefthand side of
the matix.
@param y the row index of the key. row 0 is at the top of the matrix and
the numbers increase downwards.
@param cb the function to be called when an event from the specified key is
detected.
*/
/**************************************************************************/
void Adafruit_MultiNeoKey1x4::registerCallback(
uint8_t x, uint8_t y, NeoKey1x4Callback (*cb)(keyEvent)) {
Adafruit_NeoKey_1x4 *t =
(_neokeys + y / NEOKEY_1X4_ROWS * _cols) + x / NEOKEY_1X4_COLS;
int xkey = NEOKEY_1X4_X(x);
int ykey = NEOKEY_1X4_Y(y % NEOKEY_1X4_ROWS * NEOKEY_1X4_COLS);
t->registerCallback(NEOKEY_1X4_XY(xkey, ykey), cb);
}
/**************************************************************************/
/*!
@brief register a callback for a key addressed by key number.
@param num the keynumber to set the color of. Key 0 is in the top left
corner of the trellis matrix, key 1 is directly to the right of it,
and the last key number is in the bottom righthand corner.
@param cb the function to be called when an event from the specified key is
detected.
*/
/**************************************************************************/
void Adafruit_MultiNeoKey1x4::registerCallback(
uint16_t num, NeoKey1x4Callback (*cb)(keyEvent)) {
uint8_t x = num % (NEOKEY_1X4_COLS * _cols);
uint8_t y = num / (NEOKEY_1X4_COLS * _cols);
registerCallback(x, y, cb);
}
/**************************************************************************/
/*!
@brief Unregister a callback for a key addressed by key index.
@param x the column index of the key. column 0 is on the lefthand side of
the matix.
@param y the row index of the key. row 0 is at the top of the matrix and
the numbers increase downwards.
*/
/**************************************************************************/
void Adafruit_MultiNeoKey1x4::unregisterCallback(uint8_t x, uint8_t y) {
Adafruit_NeoKey_1x4 *t =
(_neokeys + y / NEOKEY_1X4_ROWS * _cols) + x / NEOKEY_1X4_COLS;
int xkey = NEOKEY_1X4_X(x);
int ykey = NEOKEY_1X4_Y(y % NEOKEY_1X4_ROWS * NEOKEY_1X4_COLS);
t->unregisterCallback(NEOKEY_1X4_XY(xkey, ykey));
}
/**************************************************************************/
/*!
@brief Unregister a callback for a key addressed by key number.
@param num the keynumber to set the color of. Key 0 is in the top left
corner of the trellis matrix, key 1 is directly to the right of it,
and the last key number is in the bottom righthand corner.
*/
/**************************************************************************/
void Adafruit_MultiNeoKey1x4::unregisterCallback(uint16_t num) {
uint8_t x = num % (NEOKEY_1X4_COLS * _cols);
uint8_t y = num / (NEOKEY_1X4_COLS * _cols);
unregisterCallback(x, y);
}
/**************************************************************************/
/*!
@brief set the color of a neopixel at a key index.
@param x the column index of the key. column 0 is on the lefthand side of
the matix.
@param y the row index of the key. row 0 is at the top of the matrix and
the numbers increase downwards.
@param color the color to set the pixel to. This is a 24 bit RGB value.
for example, full brightness red would be 0xFF0000, and full
brightness blue would be 0x0000FF.
*/
/**************************************************************************/
void Adafruit_MultiNeoKey1x4::setPixelColor(uint8_t x, uint8_t y,
uint32_t color) {
Adafruit_NeoKey_1x4 *t =
(_neokeys + y / NEOKEY_1X4_ROWS * _cols) + x / NEOKEY_1X4_COLS;
int xkey = NEOKEY_1X4_X(x);
int ykey = NEOKEY_1X4_Y(y % NEOKEY_1X4_ROWS * NEOKEY_1X4_COLS);
t->pixels.setPixelColor(NEOKEY_1X4_XY(xkey, ykey), color);
}
/**************************************************************************/
/*!
@brief set the color of a neopixel at a key number.
@param num the keynumber to set the color of. Key 0 is in the top left
corner of the trellis matrix, key 1 is directly to the right of it,
and the last key number is in the bottom righthand corner.
@param color the color to set the pixel to. This is a 24 bit RGB value.
for example, full brightness red would be 0xFF0000, and full
brightness blue would be 0x0000FF.
*/
/**************************************************************************/
void Adafruit_MultiNeoKey1x4::setPixelColor(uint16_t num, uint32_t color) {
uint8_t x = num % (NEOKEY_1X4_COLS * _cols);
uint8_t y = num / (NEOKEY_1X4_COLS * _cols);
setPixelColor(x, y, color);
}
/**************************************************************************/
/*!
@brief call show for all connected neotrellis boards to show all neopixels
*/
/**************************************************************************/
void Adafruit_MultiNeoKey1x4::show() {
Adafruit_NeoKey_1x4 *t;
for (int n = 0; n < _rows; n++) {
for (int m = 0; m < _cols; m++) {
t = (_neokeys + n * _cols) + m;
t->pixels.show();
}
}
}
/**************************************************************************/
/*!
@brief read all events currently stored in the seesaw fifo and call any
callbacks.
*/
/**************************************************************************/
void Adafruit_MultiNeoKey1x4::read() {
Adafruit_NeoKey_1x4 *nk;
for (int n = 0; n < _rows; n++) {
for (int m = 0; m < _cols; m++) {
// get the individual breakout
nk = (_neokeys + n * _cols) + m;
// query what buttons are pressed
nk->digitalReadBulk(
NEOKEY_1X4_BUTTONMASK); // not sure why we have to do it 2ce
uint32_t buttons = nk->digitalReadBulk(NEOKEY_1X4_BUTTONMASK);
// Serial.print("Neokey number "); Serial.print(n * _cols + m);
// Serial.print(" buttons: 0x"); Serial.println(buttons, HEX);
buttons ^= NEOKEY_1X4_BUTTONMASK;
buttons &= NEOKEY_1X4_BUTTONMASK;
buttons >>= NEOKEY_1X4_BUTTONA;
// compared to last time
uint8_t just_pressed = (buttons ^ nk->last_buttons) & buttons;
uint8_t just_released = (buttons ^ nk->last_buttons) & ~buttons;
// stash for next run
nk->last_buttons = buttons;
if (just_pressed | just_released) {
// Serial.print("pressed 0x"); Serial.println(just_pressed, HEX);
// Serial.print("released 0x"); Serial.println(just_released, HEX);
// for each key, process the event
for (int b = 0; b < 4; b++) {
int x = b; // column is the button
int y = 0; // a 1x4 neokey only has one row
// extend into whole grid
x = x + m * NEOKEY_1X4_COLS;
y = y + n * NEOKEY_1X4_ROWS;
int event_key = y * NEOKEY_1X4_COLS * _cols + x;
if (just_pressed & (1 << b)) { // if button b is pressed
if (nk->_callbacks[b] != NULL) {
keyEvent evt = {SEESAW_KEYPAD_EDGE_RISING, (uint16_t)event_key};
nk->_callbacks[b](evt);
}
}
if (just_released & (1 << b)) { // if button b is pressed
if (nk->_callbacks[b] != NULL) {
keyEvent evt = {SEESAW_KEYPAD_EDGE_FALLING, (uint16_t)event_key};
nk->_callbacks[b](evt);
}
}
}
}
}
}
}

View File

@@ -0,0 +1,96 @@
#ifndef _NEOKEY_1X4_H
#define _NEOKEY_1X4_H
#include "Adafruit_seesaw.h"
#include "seesaw_neopixel.h"
#include <Arduino.h>
#define NEOKEY_1X4_ADDR 0x30
#define NEOKEY_1X4_NEOPIN 3
#define NEOKEY_1X4_BUTTONA 4
#define NEOKEY_1X4_BUTTONB 5
#define NEOKEY_1X4_BUTTONC 6
#define NEOKEY_1X4_BUTTOND 7
#define NEOKEY_1X4_BUTTONMASK ((1 << 4) | (1 << 5) | (1 << 6) | (1 << 7))
#define NEOKEY_1X4_ROWS 1
#define NEOKEY_1X4_COLS 4
#define NEOKEY_1X4_KEYS (NEOKEY_1X4_ROWS * NEOKEY_1X4_COLS)
#define NEOKEY_1X4_MAX_CALLBACKS 32
/* NEOKEY_1X4_KEY depends on PCB routing */
// #define NEOKEY_1X4_KEY(x) (((x) / 4) * 8 + ((x) % 4))
#define NEOKEY_1X4_KEY(x) (((x) / 8) * 4 + ((x) % 8))
#define NEOKEY_1X4_X(k) ((k) % 4)
#define NEOKEY_1X4_Y(k) ((k) / 4)
#define NEOKEY_1X4_XY(x, y) ((y)*NEOKEY_1X4_ROWS + (x))
typedef void (*NeoKey1x4Callback)(keyEvent evt);
/**************************************************************************/
/*!
@brief Class that stores state and functions for interacting with the
seesaw NeoKey module
*/
/**************************************************************************/
class Adafruit_NeoKey_1x4 : public Adafruit_seesaw {
public:
Adafruit_NeoKey_1x4(uint8_t addr = NEOKEY_1X4_ADDR, TwoWire *i2c_bus = &Wire);
~Adafruit_NeoKey_1x4(){};
bool begin(uint8_t addr = NEOKEY_1X4_ADDR, int8_t flow = -1);
void registerCallback(uint8_t key, NeoKey1x4Callback (*cb)(keyEvent));
void unregisterCallback(uint8_t key);
uint8_t read(void);
seesaw_NeoPixel pixels; ///< the onboard neopixel matrix
friend class Adafruit_MultiNeoKey1x4; ///< for allowing use of protected
///< methods by aggregate class
protected:
uint8_t last_buttons = 0; ///< The last reading for the buttons
uint8_t _addr; ///< the I2C address of this board
NeoKey1x4Callback (*_callbacks[NEOKEY_1X4_KEYS])(
keyEvent); ///< the array of callback functions
};
/**************************************************************************/
/*!
@brief Class that stores state and functions for interacting with multiple
neotrellis boards
*/
/**************************************************************************/
class Adafruit_MultiNeoKey1x4 {
public:
Adafruit_MultiNeoKey1x4(Adafruit_NeoKey_1x4 *neokeys, uint8_t rows,
uint8_t cols);
~Adafruit_MultiNeoKey1x4(){};
bool begin();
void registerCallback(uint16_t num, NeoKey1x4Callback (*cb)(keyEvent));
void registerCallback(uint8_t x, uint8_t y,
NeoKey1x4Callback (*cb)(keyEvent));
void unregisterCallback(uint16_t num);
void unregisterCallback(uint8_t x, uint8_t y);
void setPixelColor(uint8_t x, uint8_t y, uint32_t color);
void setPixelColor(uint16_t num, uint32_t color);
void show();
void read();
protected:
uint8_t _rows; ///< the number of trellis boards in the Y direction
uint8_t _cols; ///< the number of trellis boards in the X direction
Adafruit_NeoKey_1x4 *_neokeys; ///< a multidimensional array of neokey objects
};
#endif

View File

@@ -0,0 +1,353 @@
#include "Adafruit_NeoTrellis.h"
/**************************************************************************/
/*!
@brief Class constructor
@param addr the I2C address this neotrellis object uses
@param i2c_bus the I2C bus connected to this neotrellis, defaults to "Wire"
*/
/**************************************************************************/
Adafruit_NeoTrellis::Adafruit_NeoTrellis(uint8_t addr, TwoWire *i2c_bus)
: Adafruit_seesaw(i2c_bus),
pixels(NEO_TRELLIS_NUM_KEYS, NEO_TRELLIS_NEOPIX_PIN, NEO_GRB + NEO_KHZ800,
i2c_bus) {
for (int i = 0; i < NEO_TRELLIS_NUM_KEYS; i++) {
_callbacks[i] = NULL;
}
this->_addr = addr;
}
/**************************************************************************/
/*!
@brief Begin communication with the RGB trellis.
@param addr optional i2c address where the device can be found. Defaults to
NEO_TRELLIS_ADDR
@param flow optional flow control pin
@returns true on success, false on error.
*/
/**************************************************************************/
bool Adafruit_NeoTrellis::begin(uint8_t addr, int8_t flow) {
_addr = addr;
bool ret = pixels.begin(addr, flow);
ret = Adafruit_seesaw::begin(addr, flow, false);
if (!ret)
return ret;
enableKeypadInterrupt();
return ret;
}
/**************************************************************************/
/*!
@brief register a callback function on the passed key.
@param key the key number to register the callback on
@param cb the callback function that should be called when an event on that
key happens
*/
/**************************************************************************/
void Adafruit_NeoTrellis::registerCallback(uint8_t key,
TrellisCallback (*cb)(keyEvent)) {
_callbacks[key] = cb;
}
/**************************************************************************/
/*!
@brief unregister a callback on a given key
@param key the key number the callback is currently mapped to.
*/
/**************************************************************************/
void Adafruit_NeoTrellis::unregisterCallback(uint8_t key) {
_callbacks[key] = NULL;
}
/**************************************************************************/
/*!
@brief activate or deactivate a given key event
@param key the key number to map the event to
@param edge the edge sensitivity of the event
@param enable pass true to enable the passed event, false to disable it.
*/
/**************************************************************************/
void Adafruit_NeoTrellis::activateKey(uint8_t key, uint8_t edge, bool enable) {
setKeypadEvent(NEO_TRELLIS_KEY(key), edge, enable);
}
/**************************************************************************/
/*!
@brief read all events currently stored in the seesaw fifo and call any
callbacks.
@param polling pass true if the interrupt pin is not being used, false if
it is. Defaults to true.
*/
/**************************************************************************/
void Adafruit_NeoTrellis::read(bool polling) {
uint8_t count = getKeypadCount();
delayMicroseconds(500);
if (count > 0) {
if (polling)
count = count + 2;
keyEventRaw e[count];
readKeypad(e, count);
for (int i = 0; i < count; i++) {
// call any callbacks associated with the key
e[i].bit.NUM = NEO_TRELLIS_SEESAW_KEY(e[i].bit.NUM);
if (e[i].bit.NUM < NEO_TRELLIS_NUM_KEYS &&
_callbacks[e[i].bit.NUM] != NULL) {
keyEvent evt = {e[i].bit.EDGE, e[i].bit.NUM};
_callbacks[e[i].bit.NUM](evt);
}
}
}
}
/**************************************************************************/
/*!
@brief class constructor
@param trelli pointer to a multidimensional array of neotrellis objects.
these object must have their I2C addresses specified in the class
constructors.
@param rows the number of individual neotrellis boards in the Y direction
of your matrix.
@param cols the number of individual neotrellis boards in the X direction
of your matrix.
*/
/**************************************************************************/
Adafruit_MultiTrellis::Adafruit_MultiTrellis(Adafruit_NeoTrellis *trelli,
uint8_t rows, uint8_t cols) {
this->_rows = rows;
this->_cols = cols;
this->_trelli = trelli;
}
/**************************************************************************/
/*!
@brief begin communication with the matrix of neotrellis boards.
@returns true on success, false otherwise.
*/
/**************************************************************************/
bool Adafruit_MultiTrellis::begin() {
Adafruit_NeoTrellis *t;
for (int n = 0; n < _rows; n++) {
for (int m = 0; m < _cols; m++) {
t = (_trelli + n * _cols) + m;
if (!t->begin(t->_addr))
return false;
}
}
return true;
}
/**************************************************************************/
/*!
@brief register a callback for a key addressed by key index.
@param x the column index of the key. column 0 is on the lefthand side of
the matix.
@param y the row index of the key. row 0 is at the top of the matrix and
the numbers increase downwards.
@param cb the function to be called when an event from the specified key is
detected.
*/
/**************************************************************************/
void Adafruit_MultiTrellis::registerCallback(uint8_t x, uint8_t y,
TrellisCallback (*cb)(keyEvent)) {
Adafruit_NeoTrellis *t =
(_trelli + y / NEO_TRELLIS_NUM_ROWS * _cols) + x / NEO_TRELLIS_NUM_COLS;
int xkey = NEO_TRELLIS_X(x);
int ykey = NEO_TRELLIS_Y(y % NEO_TRELLIS_NUM_ROWS * NEO_TRELLIS_NUM_COLS);
t->registerCallback(NEO_TRELLIS_XY(xkey, ykey), cb);
}
/**************************************************************************/
/*!
@brief register a callback for a key addressed by key number.
@param num the keynumber to set the color of. Key 0 is in the top left
corner of the trellis matrix, key 1 is directly to the right of it,
and the last key number is in the bottom righthand corner.
@param cb the function to be called when an event from the specified key is
detected.
*/
/**************************************************************************/
void Adafruit_MultiTrellis::registerCallback(uint16_t num,
TrellisCallback (*cb)(keyEvent)) {
uint8_t x = num % (NEO_TRELLIS_NUM_COLS * _cols);
uint8_t y = num / (NEO_TRELLIS_NUM_COLS * _cols);
registerCallback(x, y, cb);
}
/**************************************************************************/
/*!
@brief Unregister a callback for a key addressed by key index.
@param x the column index of the key. column 0 is on the lefthand side of
the matix.
@param y the row index of the key. row 0 is at the top of the matrix and
the numbers increase downwards.
*/
/**************************************************************************/
void Adafruit_MultiTrellis::unregisterCallback(uint8_t x, uint8_t y) {
Adafruit_NeoTrellis *t =
(_trelli + y / NEO_TRELLIS_NUM_ROWS * _cols) + x / NEO_TRELLIS_NUM_COLS;
int xkey = NEO_TRELLIS_X(x);
int ykey = NEO_TRELLIS_Y(y % NEO_TRELLIS_NUM_ROWS * NEO_TRELLIS_NUM_COLS);
t->unregisterCallback(NEO_TRELLIS_XY(xkey, ykey));
}
/**************************************************************************/
/*!
@brief Unregister a callback for a key addressed by key number.
@param num the keynumber to set the color of. Key 0 is in the top left
corner of the trellis matrix, key 1 is directly to the right of it,
and the last key number is in the bottom righthand corner.
*/
/**************************************************************************/
void Adafruit_MultiTrellis::unregisterCallback(uint16_t num) {
uint8_t x = num % (NEO_TRELLIS_NUM_COLS * _cols);
uint8_t y = num / (NEO_TRELLIS_NUM_COLS * _cols);
unregisterCallback(x, y);
}
/**************************************************************************/
/*!
@brief Activate or deactivate a key by number.
@param x the column index of the key. column 0 is on the lefthand side of
the matix.
@param y the row index of the key. row 0 is at the top of the matrix and
the numbers increase downwards.
@param edge the edge that the key triggers an event on. Use
SEESAW_KEYPAD_EDGE_FALLING or SEESAW_KEYPAD_EDGE_RISING.
@param enable pass true to enable the key on the passed edge, false to
disable.
*/
/**************************************************************************/
void Adafruit_MultiTrellis::activateKey(uint8_t x, uint8_t y, uint8_t edge,
bool enable) {
Adafruit_NeoTrellis *t =
(_trelli + y / NEO_TRELLIS_NUM_ROWS * _cols) + x / NEO_TRELLIS_NUM_COLS;
int xkey = NEO_TRELLIS_X(x);
int ykey = NEO_TRELLIS_Y(y % NEO_TRELLIS_NUM_ROWS * NEO_TRELLIS_NUM_COLS);
t->activateKey(NEO_TRELLIS_XY(xkey, ykey), edge, enable);
}
/**************************************************************************/
/*!
@brief Activate or deactivate a key by number.
@param num the keynumber to set the color of. Key 0 is in the top left
corner of the trellis matrix, key 1 is directly to the right of it,
and the last key number is in the bottom righthand corner.
@param edge the edge that the key triggers an event on. Use
SEESAW_KEYPAD_EDGE_FALLING or SEESAW_KEYPAD_EDGE_RISING.
@param enable pass true to enable the key on the passed edge, false to
disable.
*/
/**************************************************************************/
void Adafruit_MultiTrellis::activateKey(uint16_t num, uint8_t edge,
bool enable) {
uint8_t x = num % (NEO_TRELLIS_NUM_COLS * _cols);
uint8_t y = num / (NEO_TRELLIS_NUM_COLS * _cols);
activateKey(x, y, edge, enable);
}
/**************************************************************************/
/*!
@brief set the color of a neopixel at a key index.
@param x the column index of the key. column 0 is on the lefthand side of
the matix.
@param y the row index of the key. row 0 is at the top of the matrix and
the numbers increase downwards.
@param color the color to set the pixel to. This is a 24 bit RGB value.
for example, full brightness red would be 0xFF0000, and full
brightness blue would be 0x0000FF.
*/
/**************************************************************************/
void Adafruit_MultiTrellis::setPixelColor(uint8_t x, uint8_t y,
uint32_t color) {
Adafruit_NeoTrellis *t =
(_trelli + y / NEO_TRELLIS_NUM_ROWS * _cols) + x / NEO_TRELLIS_NUM_COLS;
int xkey = NEO_TRELLIS_X(x);
int ykey = NEO_TRELLIS_Y(y % NEO_TRELLIS_NUM_ROWS * NEO_TRELLIS_NUM_COLS);
t->pixels.setPixelColor(NEO_TRELLIS_XY(xkey, ykey), color);
}
/**************************************************************************/
/*!
@brief set the color of a neopixel at a key number.
@param num the keynumber to set the color of. Key 0 is in the top left
corner of the trellis matrix, key 1 is directly to the right of it,
and the last key number is in the bottom righthand corner.
@param color the color to set the pixel to. This is a 24 bit RGB value.
for example, full brightness red would be 0xFF0000, and full
brightness blue would be 0x0000FF.
*/
/**************************************************************************/
void Adafruit_MultiTrellis::setPixelColor(uint16_t num, uint32_t color) {
uint8_t x = num % (NEO_TRELLIS_NUM_COLS * _cols);
uint8_t y = num / (NEO_TRELLIS_NUM_COLS * _cols);
setPixelColor(x, y, color);
}
/**************************************************************************/
/*!
@brief call show for all connected neotrellis boards to show all neopixels
*/
/**************************************************************************/
void Adafruit_MultiTrellis::show() {
Adafruit_NeoTrellis *t;
for (int n = 0; n < _rows; n++) {
for (int m = 0; m < _cols; m++) {
t = (_trelli + n * _cols) + m;
t->pixels.show();
}
}
}
/**************************************************************************/
/*!
@brief read all events currently stored in the seesaw fifo and call any
callbacks.
*/
/**************************************************************************/
void Adafruit_MultiTrellis::read() {
Adafruit_NeoTrellis *t;
for (int n = 0; n < _rows; n++) {
for (int m = 0; m < _cols; m++) {
t = (_trelli + n * _cols) + m;
uint8_t count = t->getKeypadCount();
delayMicroseconds(500);
if (count > 0) {
count = count + 2;
keyEventRaw e[count];
t->readKeypad(e, count);
for (int i = 0; i < count; i++) {
// call any callbacks associated with the key
e[i].bit.NUM = NEO_TRELLIS_SEESAW_KEY(e[i].bit.NUM);
if (e[i].bit.NUM < NEO_TRELLIS_NUM_KEYS &&
t->_callbacks[e[i].bit.NUM] != NULL) {
// update the event with the multitrellis number
keyEvent evt = {e[i].bit.EDGE, e[i].bit.NUM};
int x = NEO_TRELLIS_X(e[i].bit.NUM);
int y = NEO_TRELLIS_Y(e[i].bit.NUM);
x = x + m * NEO_TRELLIS_NUM_COLS;
y = y + n * NEO_TRELLIS_NUM_ROWS;
evt.bit.NUM = y * NEO_TRELLIS_NUM_COLS * _cols + x;
t->_callbacks[e[i].bit.NUM](evt);
}
}
}
}
}
}

View File

@@ -0,0 +1,95 @@
#ifndef _NEO_TRELLIS_H
#define _NEO_TRELLIS_H
#include "Adafruit_seesaw.h"
#include "seesaw_neopixel.h"
#include <Arduino.h>
#define NEO_TRELLIS_ADDR 0x2E
#define NEO_TRELLIS_NEOPIX_PIN 3
#define NEO_TRELLIS_NUM_ROWS 4
#define NEO_TRELLIS_NUM_COLS 4
#define NEO_TRELLIS_NUM_KEYS (NEO_TRELLIS_NUM_ROWS * NEO_TRELLIS_NUM_COLS)
#define NEO_TRELLIS_MAX_CALLBACKS 32
#define NEO_TRELLIS_KEY(x) (((x) / 4) * 8 + ((x) % 4))
#define NEO_TRELLIS_SEESAW_KEY(x) (((x) / 8) * 4 + ((x) % 8))
#define NEO_TRELLIS_X(k) ((k) % 4)
#define NEO_TRELLIS_Y(k) ((k) / 4)
#define NEO_TRELLIS_XY(x, y) ((y)*NEO_TRELLIS_NUM_COLS + (x))
typedef void (*TrellisCallback)(keyEvent evt);
/**************************************************************************/
/*!
@brief Class that stores state and functions for interacting with the
seesaw keypad module
*/
/**************************************************************************/
class Adafruit_NeoTrellis : public Adafruit_seesaw {
public:
Adafruit_NeoTrellis(uint8_t addr = NEO_TRELLIS_ADDR,
TwoWire *i2c_bus = &Wire);
~Adafruit_NeoTrellis(){};
bool begin(uint8_t addr = NEO_TRELLIS_ADDR, int8_t flow = -1);
void registerCallback(uint8_t key, TrellisCallback (*cb)(keyEvent));
void unregisterCallback(uint8_t key);
void activateKey(uint8_t key, uint8_t edge, bool enable = true);
void read(bool polling = true);
seesaw_NeoPixel pixels; ///< the onboard neopixel matrix
friend class Adafruit_MultiTrellis; ///< for allowing use of protected methods
///< by aggregate class
protected:
uint8_t _addr; ///< the I2C address of this board
TrellisCallback (*_callbacks[NEO_TRELLIS_NUM_KEYS])(
keyEvent); ///< the array of callback functions
};
/**************************************************************************/
/*!
@brief Class that stores state and functions for interacting with multiple
neotrellis boards
*/
/**************************************************************************/
class Adafruit_MultiTrellis {
public:
Adafruit_MultiTrellis(Adafruit_NeoTrellis *trelli, uint8_t rows,
uint8_t cols);
~Adafruit_MultiTrellis(){};
bool begin();
void registerCallback(uint16_t num, TrellisCallback (*cb)(keyEvent));
void registerCallback(uint8_t x, uint8_t y, TrellisCallback (*cb)(keyEvent));
void unregisterCallback(uint16_t num);
void unregisterCallback(uint8_t x, uint8_t y);
void activateKey(uint16_t num, uint8_t edge, bool enable = true);
void activateKey(uint8_t x, uint8_t y, uint8_t edge, bool enable = true);
void setPixelColor(uint8_t x, uint8_t y, uint32_t color);
void setPixelColor(uint16_t num, uint32_t color);
void show();
void read();
protected:
uint8_t _rows; ///< the number of trellis boards in the Y direction
uint8_t _cols; ///< the number of trellis boards in the X direction
Adafruit_NeoTrellis
*_trelli; ///< a multidimensional array of neotrellis objects
};
#endif

View File

@@ -0,0 +1,65 @@
#include "Adafruit_TFTShield18.h"
/**************************************************************************/
/*!
@brief set up the TFT shield
@param addr optional address the seesaw chip can be found on
@param flow optional flow control pin to use
@returns true on success, false on error
*/
/**************************************************************************/
bool Adafruit_TFTShield18::begin(uint8_t addr, int8_t flow) {
if (!Adafruit_seesaw::begin(addr, flow)) {
return false;
}
pinMode(TFTSHIELD_RESET_PIN, OUTPUT);
pinModeBulk(TFTSHIELD_BUTTON_ALL, INPUT_PULLUP);
return true;
}
/**************************************************************************/
/*!
@brief set the intensity of the backlight
@param value to set the backlight to,
0x0000 = 0% (TFTSHIELD_BACKLIGHT_OFF)
to
0xFFFF = 100% (TFTSHIELD_BACKLIGHT_ON)
*/
/**************************************************************************/
void Adafruit_TFTShield18::setBacklight(uint16_t value) {
uint8_t cmd[] = {0x00, (uint8_t)(value >> 8), (uint8_t)value};
this->write(SEESAW_TIMER_BASE, SEESAW_TIMER_PWM, cmd, 3);
}
/**************************************************************************/
/*!
@brief set the PWM frequency for the backlight
@param freq the frequency to set the backlight to
*/
/**************************************************************************/
void Adafruit_TFTShield18::setBacklightFreq(uint16_t freq) {
uint8_t cmd[] = {0x0, (uint8_t)(freq >> 8), (uint8_t)freq};
this->write(SEESAW_TIMER_BASE, SEESAW_TIMER_FREQ, cmd, 3);
}
/**************************************************************************/
/*!
@brief reset the TFT screen by setting the value of the reset pin
@param rst the value to set the reset pin to
*/
/**************************************************************************/
void Adafruit_TFTShield18::tftReset(bool rst) {
digitalWrite(TFTSHIELD_RESET_PIN, rst);
}
/**************************************************************************/
/*!
@brief read all buttons on the wing and return as a 32 bit integer
@returns the value of the buttons
*/
/**************************************************************************/
uint32_t Adafruit_TFTShield18::readButtons() {
return digitalReadBulk(TFTSHIELD_BUTTON_ALL);
}

View File

@@ -0,0 +1,60 @@
#ifndef _TFT_SHIELD_18_H
#define _TFT_SHIELD_18_H
#include "Adafruit_seesaw.h"
#define TFTSHIELD_ADDR 0x2E
#define TFTSHIELD_RESET_PIN 3
#define TFTSHIELD_BACKLIGHT_ON 0xFFFF
#define TFTSHIELD_BACKLIGHT_OFF 0x0000
#define TFTSHIELD_BUTTON_UP_PIN 5
#define TFTSHIELD_BUTTON_UP (1UL << TFTSHIELD_BUTTON_UP_PIN)
#define TFTSHIELD_BUTTON_DOWN_PIN 8
#define TFTSHIELD_BUTTON_DOWN (1UL << TFTSHIELD_BUTTON_DOWN_PIN)
#define TFTSHIELD_BUTTON_LEFT_PIN 6
#define TFTSHIELD_BUTTON_LEFT (1UL << TFTSHIELD_BUTTON_LEFT_PIN)
#define TFTSHIELD_BUTTON_RIGHT_PIN 9
#define TFTSHIELD_BUTTON_RIGHT (1UL << TFTSHIELD_BUTTON_RIGHT_PIN)
#define TFTSHIELD_BUTTON_IN_PIN 7
#define TFTSHIELD_BUTTON_IN (1UL << TFTSHIELD_BUTTON_IN_PIN)
#define TFTSHIELD_BUTTON_1_PIN 10
#define TFTSHIELD_BUTTON_1 (1UL << TFTSHIELD_BUTTON_1_PIN)
#define TFTSHIELD_BUTTON_2_PIN 11
#define TFTSHIELD_BUTTON_2 (1UL << TFTSHIELD_BUTTON_2_PIN)
#define TFTSHIELD_BUTTON_3_PIN 14
#define TFTSHIELD_BUTTON_3 (1UL << TFTSHIELD_BUTTON_3_PIN)
#define TFTSHIELD_BUTTON_ALL \
(TFTSHIELD_BUTTON_UP | TFTSHIELD_BUTTON_DOWN | TFTSHIELD_BUTTON_LEFT | \
TFTSHIELD_BUTTON_RIGHT | TFTSHIELD_BUTTON_IN | TFTSHIELD_BUTTON_1 | \
TFTSHIELD_BUTTON_2 | TFTSHIELD_BUTTON_3)
/**************************************************************************/
/*!
@brief Class that stores state and functions for interacting with 1.8" tft
shield variant of seesaw helper IC
*/
/**************************************************************************/
class Adafruit_TFTShield18 : public Adafruit_seesaw {
public:
Adafruit_TFTShield18(){};
~Adafruit_TFTShield18(){};
bool begin(uint8_t addr = TFTSHIELD_ADDR, int8_t flow = -1);
void setBacklight(uint16_t value);
void setBacklightFreq(uint16_t freq);
void tftReset(bool rst = true);
uint32_t readButtons();
};
#endif

View File

@@ -0,0 +1,140 @@
#include "Adafruit_miniTFTWing.h"
// These are the default SAMD09 version pins! (for back compatibility)
uint8_t TFTWING_RESET_PIN = 8;
uint8_t TFTWING_BUTTON_UP_PIN = 2;
uint32_t TFTWING_BUTTON_UP = (1UL << TFTWING_BUTTON_UP_PIN);
uint8_t TFTWING_BUTTON_DOWN_PIN = 4;
uint32_t TFTWING_BUTTON_DOWN = (1UL << TFTWING_BUTTON_DOWN_PIN);
uint8_t TFTWING_BUTTON_LEFT_PIN = 3;
uint32_t TFTWING_BUTTON_LEFT = (1UL << TFTWING_BUTTON_LEFT_PIN);
uint8_t TFTWING_BUTTON_RIGHT_PIN = 7;
uint32_t TFTWING_BUTTON_RIGHT = (1UL << TFTWING_BUTTON_RIGHT_PIN);
uint8_t TFTWING_BUTTON_SELECT_PIN = 11;
uint32_t TFTWING_BUTTON_SELECT = (1UL << TFTWING_BUTTON_SELECT_PIN);
uint8_t TFTWING_BUTTON_A_PIN = 10;
uint32_t TFTWING_BUTTON_A = (1UL << TFTWING_BUTTON_A_PIN);
uint8_t TFTWING_BUTTON_B_PIN = 9;
uint32_t TFTWING_BUTTON_B = (1UL << TFTWING_BUTTON_B_PIN);
uint32_t TFTWING_BUTTON_ALL =
(TFTWING_BUTTON_UP | TFTWING_BUTTON_DOWN | TFTWING_BUTTON_LEFT |
TFTWING_BUTTON_RIGHT | TFTWING_BUTTON_SELECT | TFTWING_BUTTON_A |
TFTWING_BUTTON_B);
/**************************************************************************/
/*!
@brief set up the miniTFTWing
@param addr optional address the seesaw chip can be found on
@param Wi optional alternative I2C port to use, e.g. &Wire1 etc. Defaults
to &Wire
@returns true on success, false on error
*/
/**************************************************************************/
bool Adafruit_miniTFTWing::begin(uint8_t addr, TwoWire *Wi) {
if (Wi != NULL) {
Adafruit_seesaw::_i2cbus = Wi;
}
if (!Adafruit_seesaw::begin(addr, -1)) {
return false;
}
if ((getVersion() >> 16) == 3322) {
// check if we have a product ID burned in, if so its the ATtiny816 version!
TFTWING_BUTTON_UP_PIN = 16;
TFTWING_BUTTON_UP = (1UL << TFTWING_BUTTON_UP_PIN);
TFTWING_BUTTON_DOWN_PIN = 13;
TFTWING_BUTTON_DOWN = (1UL << TFTWING_BUTTON_DOWN_PIN);
TFTWING_BUTTON_LEFT_PIN = 12;
TFTWING_BUTTON_LEFT = (1UL << TFTWING_BUTTON_LEFT_PIN);
TFTWING_BUTTON_RIGHT_PIN = 14;
TFTWING_BUTTON_RIGHT = (1UL << TFTWING_BUTTON_RIGHT_PIN);
TFTWING_BUTTON_SELECT_PIN = 15;
TFTWING_BUTTON_SELECT = (1UL << TFTWING_BUTTON_SELECT_PIN);
TFTWING_BUTTON_A_PIN = 11;
TFTWING_BUTTON_A = (1UL << TFTWING_BUTTON_A_PIN);
TFTWING_BUTTON_B_PIN = 10;
TFTWING_BUTTON_B = (1UL << TFTWING_BUTTON_B_PIN);
TFTWING_BUTTON_ALL =
(TFTWING_BUTTON_UP | TFTWING_BUTTON_DOWN | TFTWING_BUTTON_LEFT |
TFTWING_BUTTON_RIGHT | TFTWING_BUTTON_SELECT | TFTWING_BUTTON_A |
TFTWING_BUTTON_B);
TFTWING_RESET_PIN = 6;
}
this->pinMode(TFTWING_RESET_PIN, OUTPUT);
this->pinModeBulk(TFTWING_BUTTON_ALL, INPUT_PULLUP);
return true;
}
/**************************************************************************/
/*!
@brief set the value of the backlight
@param value the backlight value to set NOTE: 0xFFFF is all the way on
0x0000 is off.
*/
/**************************************************************************/
void Adafruit_miniTFTWing::setBacklight(uint16_t value) {
if ((getVersion() >> 16) == 3322) {
// this->analogWrite(7, value);
this->pinMode(7, OUTPUT);
if (value == TFTWING_BACKLIGHT_ON) {
this->digitalWrite(7, LOW);
} else {
this->digitalWrite(7, HIGH);
}
} else {
uint8_t cmd[] = {0x00, (uint8_t)(value >> 8), (uint8_t)value};
this->write(SEESAW_TIMER_BASE, SEESAW_TIMER_PWM, cmd, 3);
}
}
/**************************************************************************/
/*!
@brief set the PWM frequency for the backlight
@param freq the frequency to set the backlight to
*/
/**************************************************************************/
void Adafruit_miniTFTWing::setBacklightFreq(uint16_t freq) {
if ((getVersion() >> 16) == 3322) {
} else {
uint8_t cmd[] = {0x0, (uint8_t)(freq >> 8), (uint8_t)freq};
this->write(SEESAW_TIMER_BASE, SEESAW_TIMER_FREQ, cmd, 3);
}
}
/**************************************************************************/
/*!
@brief reset the TFT screen by setting the value of the reset pin
@param rst the value to set the reset pin to
*/
/**************************************************************************/
void Adafruit_miniTFTWing::tftReset(bool rst) {
this->digitalWrite(TFTWING_RESET_PIN, rst);
}
/**************************************************************************/
/*!
@brief read all buttons on the wing and return as a 32 bit integer
@returns the value of the buttons
*/
/**************************************************************************/
uint32_t Adafruit_miniTFTWing::readButtons() {
return this->digitalReadBulk(TFTWING_BUTTON_ALL);
}

View File

@@ -0,0 +1,36 @@
#pragma once
#ifndef _MINI_TFT_WING_H
#define _MINI_TFT_WING_H
#include "Adafruit_seesaw.h"
#define TFTWING_ADDR 0x5E
#define TFTWING_BACKLIGHT_ON 0 // inverted output!
#define TFTWING_BACKLIGHT_OFF 0xFFFF // inverted output!
extern uint32_t TFTWING_BUTTON_UP, TFTWING_BUTTON_DOWN, TFTWING_BUTTON_LEFT,
TFTWING_BUTTON_RIGHT, TFTWING_BUTTON_A, TFTWING_BUTTON_B,
TFTWING_BUTTON_SELECT;
/**************************************************************************/
/*!
@brief Class that stores state and functions for interacting with mini tft
wing variant of seesaw helper IC
*/
/**************************************************************************/
class Adafruit_miniTFTWing : public Adafruit_seesaw {
public:
Adafruit_miniTFTWing(){};
~Adafruit_miniTFTWing(){};
bool begin(uint8_t addr = TFTWING_ADDR, TwoWire *Wi = NULL);
void setBacklight(uint16_t value);
void setBacklightFreq(uint16_t freq);
void tftReset(bool rst = true);
uint32_t readButtons();
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,351 @@
/*!
* @file Adafruit_seesaw.h
*
* This is part of Adafruit's seesaw driver for the Arduino platform. It is
* designed specifically to work with the Adafruit products that use seesaw
* technology.
*
* These chips use I2C to communicate, 2 pins (SCL+SDA) are required
* to interface with the board.
*
* Adafruit invests time and resources providing this open source code,
* please support Adafruit and open-source hardware by purchasing
* products from Adafruit!
*
* Written by Dean Miller for Adafruit Industries.
*
* BSD license, all text here must be included in any redistribution.
*
*/
#ifndef LIB_SEESAW_H
#define LIB_SEESAW_H
#include "Adafruit_I2CDevice.h"
#include <Arduino.h>
#include <Wire.h>
/*=========================================================================
I2C ADDRESS/BITS
-----------------------------------------------------------------------*/
#define SEESAW_ADDRESS (0x49) ///< Default Seesaw I2C address
/*=========================================================================*/
/*=========================================================================
REGISTERS
-----------------------------------------------------------------------*/
/** Module Base Addreses
* The module base addresses for different seesaw modules.
*/
enum {
SEESAW_STATUS_BASE = 0x00,
SEESAW_GPIO_BASE = 0x01,
SEESAW_SERCOM0_BASE = 0x02,
SEESAW_TIMER_BASE = 0x08,
SEESAW_ADC_BASE = 0x09,
SEESAW_DAC_BASE = 0x0A,
SEESAW_INTERRUPT_BASE = 0x0B,
SEESAW_DAP_BASE = 0x0C,
SEESAW_EEPROM_BASE = 0x0D,
SEESAW_NEOPIXEL_BASE = 0x0E,
SEESAW_TOUCH_BASE = 0x0F,
SEESAW_KEYPAD_BASE = 0x10,
SEESAW_ENCODER_BASE = 0x11,
SEESAW_SPECTRUM_BASE = 0x12,
SEESAW_SOIL_BASE = 0x13,
};
/** GPIO module function address registers
*/
enum {
SEESAW_GPIO_DIRSET_BULK = 0x02,
SEESAW_GPIO_DIRCLR_BULK = 0x03,
SEESAW_GPIO_BULK = 0x04,
SEESAW_GPIO_BULK_SET = 0x05,
SEESAW_GPIO_BULK_CLR = 0x06,
SEESAW_GPIO_BULK_TOGGLE = 0x07,
SEESAW_GPIO_INTENSET = 0x08,
SEESAW_GPIO_INTENCLR = 0x09,
SEESAW_GPIO_INTFLAG = 0x0A,
SEESAW_GPIO_PULLENSET = 0x0B,
SEESAW_GPIO_PULLENCLR = 0x0C,
};
/** status module function address registers
*/
enum {
SEESAW_STATUS_HW_ID = 0x01,
SEESAW_STATUS_VERSION = 0x02,
SEESAW_STATUS_OPTIONS = 0x03,
SEESAW_STATUS_TEMP = 0x04,
SEESAW_STATUS_SWRST = 0x7F,
};
/** timer module function address registers
*/
enum {
SEESAW_TIMER_STATUS = 0x00,
SEESAW_TIMER_PWM = 0x01,
SEESAW_TIMER_FREQ = 0x02,
};
/** ADC module function address registers
*/
enum {
SEESAW_ADC_STATUS = 0x00,
SEESAW_ADC_INTEN = 0x02,
SEESAW_ADC_INTENCLR = 0x03,
SEESAW_ADC_WINMODE = 0x04,
SEESAW_ADC_WINTHRESH = 0x05,
SEESAW_ADC_CHANNEL_OFFSET = 0x07,
};
/** Sercom module function address registers
*/
enum {
SEESAW_SERCOM_STATUS = 0x00,
SEESAW_SERCOM_INTEN = 0x02,
SEESAW_SERCOM_INTENCLR = 0x03,
SEESAW_SERCOM_BAUD = 0x04,
SEESAW_SERCOM_DATA = 0x05,
};
/** neopixel module function address registers
*/
enum {
SEESAW_NEOPIXEL_STATUS = 0x00,
SEESAW_NEOPIXEL_PIN = 0x01,
SEESAW_NEOPIXEL_SPEED = 0x02,
SEESAW_NEOPIXEL_BUF_LENGTH = 0x03,
SEESAW_NEOPIXEL_BUF = 0x04,
SEESAW_NEOPIXEL_SHOW = 0x05,
};
/** touch module function address registers
*/
enum {
SEESAW_TOUCH_CHANNEL_OFFSET = 0x10,
};
/** keypad module function address registers
*/
enum {
SEESAW_KEYPAD_STATUS = 0x00,
SEESAW_KEYPAD_EVENT = 0x01,
SEESAW_KEYPAD_INTENSET = 0x02,
SEESAW_KEYPAD_INTENCLR = 0x03,
SEESAW_KEYPAD_COUNT = 0x04,
SEESAW_KEYPAD_FIFO = 0x10,
};
/** keypad module edge definitions
*/
enum {
SEESAW_KEYPAD_EDGE_HIGH = 0,
SEESAW_KEYPAD_EDGE_LOW,
SEESAW_KEYPAD_EDGE_FALLING,
SEESAW_KEYPAD_EDGE_RISING,
};
/** encoder module edge definitions
*/
enum {
SEESAW_ENCODER_STATUS = 0x00,
SEESAW_ENCODER_INTENSET = 0x10,
SEESAW_ENCODER_INTENCLR = 0x20,
SEESAW_ENCODER_POSITION = 0x30,
SEESAW_ENCODER_DELTA = 0x40,
};
/** Audio spectrum module function address registers
*/
enum {
SEESAW_SPECTRUM_RESULTS_LOWER = 0x00, // Audio spectrum bins 0-31
SEESAW_SPECTRUM_RESULTS_UPPER = 0x01, // Audio spectrum bins 32-63
// If some future device supports a larger spectrum, can add additional
// "bins" working upward from here. Configurable setting registers then
// work downward from the top to avoid collision between spectrum bins
// and configurables.
SEESAW_SPECTRUM_CHANNEL = 0xFD,
SEESAW_SPECTRUM_RATE = 0xFE,
SEESAW_SPECTRUM_STATUS = 0xFF,
};
/** soil moisture module function address registers
*/
enum {
// 0x00..0x0F Global Settings
SEESAW_SOIL_STATUS = 0x00,
SEESAW_SOIL_RATE = 0x01,
// 0x10..0xF0 Sensor Settings
// lower four bits = sensor number
// upper four bits = setting type
SEESAW_SOIL_VALUE = 0x10,
SEESAW_SOIL_SAMPLES = 0x20,
SEESAW_SOIL_XDELAY = 0x30,
SEESAW_SOIL_TIMEOUT = 0x40,
};
#define ADC_INPUT_0_PIN 2 ///< default ADC input pin
#define ADC_INPUT_1_PIN 3 ///< default ADC input pin
#define ADC_INPUT_2_PIN 4 ///< default ADC input pin
#define ADC_INPUT_3_PIN 5 ///< default ADC input pin
#define PWM_0_PIN 4 ///< default PWM output pin
#define PWM_1_PIN 5 ///< default PWM output pin
#define PWM_2_PIN 6 ///< default PWM output pin
#define PWM_3_PIN 7 ///< default PWM output pin
#ifndef INPUT_PULLDOWN
#define INPUT_PULLDOWN \
0x03 ///< for compatibility with platforms that do not already define
///< INPUT_PULLDOWN
#endif
/*=========================================================================*/
// clang-format off
#define SEESAW_HW_ID_CODE_SAMD09 0x55 ///< seesaw HW ID code for SAMD09
#define SEESAW_HW_ID_CODE_TINY806 0x84 ///< seesaw HW ID code for ATtiny806
#define SEESAW_HW_ID_CODE_TINY807 0x85 ///< seesaw HW ID code for ATtiny807
#define SEESAW_HW_ID_CODE_TINY816 0x86 ///< seesaw HW ID code for ATtiny816
#define SEESAW_HW_ID_CODE_TINY817 0x87 ///< seesaw HW ID code for ATtiny817
#define SEESAW_HW_ID_CODE_TINY1616 0x88 ///< seesaw HW ID code for ATtiny1616
#define SEESAW_HW_ID_CODE_TINY1617 0x89 ///< seesaw HW ID code for ATtiny1617
// clang-format on
/** raw key event stucture for keypad module */
union keyEventRaw {
struct {
uint8_t EDGE : 2; ///< the edge that was triggered
uint8_t NUM : 6; ///< the event number
} bit; ///< bitfield format
uint8_t reg; ///< register format
};
/** extended key event stucture for keypad module */
union keyEvent {
struct {
uint8_t EDGE : 2; ///< the edge that was triggered
uint16_t NUM : 14; ///< the event number
} bit; ///< bitfield format
uint16_t reg; ///< register format
};
/** key state struct that will be written to seesaw chip keypad module */
union keyState {
struct {
uint8_t STATE : 1; ///< the current state of the key
uint8_t ACTIVE : 4; ///< the registered events for that key
} bit; ///< bitfield format
uint8_t reg; ///< register format
};
/**************************************************************************/
/*!
@brief Class that stores state and functions for interacting with seesaw
helper IC
*/
/**************************************************************************/
class Adafruit_seesaw : public Print {
public:
// constructors
Adafruit_seesaw(TwoWire *Wi = NULL);
~Adafruit_seesaw(void){};
bool begin(uint8_t addr = SEESAW_ADDRESS, int8_t flow = -1,
bool reset = true);
uint32_t getOptions();
uint32_t getVersion();
bool getProdDatecode(uint16_t *pid, uint8_t *year, uint8_t *mon,
uint8_t *day);
bool SWReset();
void pinMode(uint8_t pin, uint8_t mode);
void pinModeBulk(uint32_t pins, uint8_t mode);
void pinModeBulk(uint32_t pinsa, uint32_t pinsb, uint8_t mode);
virtual void analogWrite(uint8_t pin, uint16_t value, uint8_t width = 8);
void digitalWrite(uint8_t pin, uint8_t value);
void digitalWriteBulk(uint32_t port_values);
void digitalWriteBulk(uint32_t pins, uint8_t value);
void digitalWriteBulk(uint32_t pinsa, uint32_t pinsb, uint8_t value);
bool digitalRead(uint8_t pin);
uint32_t digitalReadBulk(uint32_t pins);
uint32_t digitalReadBulkB(uint32_t pins);
void setGPIOInterrupts(uint32_t pins, bool enabled);
virtual uint16_t analogRead(uint8_t pin);
uint16_t touchRead(uint8_t pin);
virtual void setPWMFreq(uint8_t pin, uint16_t freq);
void enableSercomDataRdyInterrupt(uint8_t sercom = 0);
void disableSercomDataRdyInterrupt(uint8_t sercom = 0);
char readSercomData(uint8_t sercom = 0);
void EEPROMWrite8(uint8_t addr, uint8_t val);
void EEPROMWrite(uint8_t addr, uint8_t *buf, uint8_t size);
uint8_t EEPROMRead8(uint8_t addr);
void setI2CAddr(uint8_t addr);
uint8_t getI2CAddr();
void UARTSetBaud(uint32_t baud);
void setKeypadEvent(uint8_t key, uint8_t edge, bool enable = true);
void enableKeypadInterrupt();
void disableKeypadInterrupt();
uint8_t getKeypadCount();
bool readKeypad(keyEventRaw *buf, uint8_t count);
float getTemp();
int32_t getEncoderPosition(uint8_t encoder = 0);
int32_t getEncoderDelta(uint8_t encoder = 0);
bool enableEncoderInterrupt(uint8_t encoder = 0);
bool disableEncoderInterrupt(uint8_t encoder = 0);
void setEncoderPosition(int32_t pos, uint8_t encoder = 0);
virtual size_t write(uint8_t);
virtual size_t write(const char *str);
protected:
TwoWire *_i2cbus; /*!< The I2C Bus used to communicate with the seesaw */
Adafruit_I2CDevice *_i2c_dev = NULL; ///< The BusIO device for I2C control
int8_t _flow; /*!< The flow control pin to use */
uint8_t _hardwaretype = 0; /*!< what hardware type is attached! */
uint8_t getI2CaddrEEPROMloc();
bool write8(byte regHigh, byte regLow, byte value);
uint8_t read8(byte regHigh, byte regLow, uint16_t delay = 250);
bool read(uint8_t regHigh, uint8_t regLow, uint8_t *buf, uint8_t num,
uint16_t delay = 250);
bool write(uint8_t regHigh, uint8_t regLow, uint8_t *buf, uint8_t num);
/*=========================================================================
REGISTER BITFIELDS
-----------------------------------------------------------------------*/
/** Sercom interrupt enable register
*/
union sercom_inten {
struct {
uint8_t DATA_RDY : 1; ///< this bit is set when data becomes available
} bit; ///< bitfields
uint8_t reg; ///< full register
};
sercom_inten _sercom_inten; ///< sercom interrupt enable register instance
/*=========================================================================*/
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,5 @@
# Adafruit_Seesaw [![Build Status](https://github.com/adafruit/Adafruit_Seesaw/workflows/Arduino%20Library%20CI/badge.svg)](https://github.com/adafruit/Adafruit_Seesaw/actions)[![Documentation](https://github.com/adafruit/ci-arduino/blob/master/assets/doxygen_badge.svg)](http://adafruit.github.io/Adafruit_Seesaw/html/index.html)
Arduino driver for seesaw multi-use chip
Check out the [documentation](https://adafruit.github.io/Adafruit_Seesaw/html/class_adafruit__seesaw.html) for a listing and explanation of the available methods!

View File

@@ -0,0 +1,34 @@
#include "Adafruit_Crickit.h"
Adafruit_Crickit crickit;
void setup() {
Serial.begin(9600);
if(!crickit.begin()){
Serial.println("ERROR!");
while(1) delay(1);
}
else Serial.println("seesaw started");
//set the PWM freq for all the servo pins
crickit.setPWMFreq(CRICKIT_SERVO1, 50);
}
void loop() {
//set some PWMS
crickit.analogWrite(CRICKIT_SERVO1, 10000);
crickit.analogWrite(CRICKIT_SERVO2, 5000);
crickit.analogWrite(CRICKIT_SERVO3, 20000);
crickit.analogWrite(CRICKIT_SERVO4, 45000);
// read an ADC
Serial.print(crickit.analogRead(CRICKIT_SIGNAL4));
Serial.print(",");
// read a captouch
Serial.println(crickit.touchRead(CRICKIT_TOUCH2));
delay(1);
}

View File

@@ -0,0 +1,37 @@
// Adafruit Crickit Capacitive Touch Demo for Arduino
//
// Displays the value of Adafruit Crickit touchpad values when touched
//
// Tested with the Crickit + micro:bit, all good
#include "Adafruit_Crickit.h"
Adafruit_Crickit crickit;
#define CRICKIT_NUM_TOUCH 4
#define CAPTOUCH_THRESH 500
void setup() {
Serial.begin(9600); // Set up serial monitor - be sure it is set to 9600
Serial.println("Cap Touch Demo");
if(!crickit.begin()) { // Check if Crickit is attached
Serial.println("ERROR Starting crickit"); // If an error, print and
while(1) ; // go to a infinite loop to stop
}
else Serial.println("seesaw started"); // success, we have a Crickit
}
void loop() {
for(int i=0; i<CRICKIT_NUM_TOUCH; i++){ // check each touch input
uint16_t val = crickit.touchRead(i); // read the touch input
if(val > CAPTOUCH_THRESH){ // if the value read is > the threshold
Serial.print("CT"); // print info to serial monitor
Serial.print(i + 1);
Serial.print(" touched! value: ");
Serial.println(val);
}
}
delay(100); // wait tiny bit between checks
}

View File

@@ -0,0 +1,34 @@
#include "Adafruit_Crickit.h"
Adafruit_Crickit crickit;
#define NUM_DRIVES 4
int drives[] = {CRICKIT_DRIVE1, CRICKIT_DRIVE2, CRICKIT_DRIVE3, CRICKIT_DRIVE4};
void setup() {
Serial.begin(115200);
Serial.println("4 Drive demo!");
if(!crickit.begin()){
Serial.println("ERROR!");
while(1) delay(1);
}
else Serial.println("Crickit started");
//our default frequency is 1khz
for(int i=0; i<NUM_DRIVES; i++)
crickit.setPWMFreq(drives[i], 1000);
}
void loop() {
for(int i=0; i<NUM_DRIVES; i++){
//turn all the way on
crickit.analogWrite(drives[i], CRICKIT_DUTY_CYCLE_OFF);
delay(100);
//turn all the way off
crickit.analogWrite(drives[i], CRICKIT_DUTY_CYCLE_MAX);
delay(100);
}
}

View File

@@ -0,0 +1,27 @@
#include "Adafruit_Crickit.h"
Adafruit_Crickit crickit;
void setup() {
Serial.begin(115200);
Serial.println("1 Drive demo!");
if(!crickit.begin()){
Serial.println("ERROR!");
while(1) delay(1);
}
else Serial.println("Crickit started");
//our default frequency is 1khz
crickit.setPWMFreq(CRICKIT_DRIVE1, 1000);
}
void loop() {
//turn all the way on
crickit.analogWrite(CRICKIT_DRIVE1, CRICKIT_DUTY_CYCLE_OFF);
delay(500);
//turn all the way off
crickit.analogWrite(CRICKIT_DRIVE1, CRICKIT_DUTY_CYCLE_MAX);
delay(500);
}

View File

@@ -0,0 +1,108 @@
#include "Adafruit_Crickit.h"
#include "seesaw_neopixel.h"
#include "seesaw_servo.h"
#define NEOPIX_PIN 20
#define USE_NEOPIX
seesaw_NeoPixel strip = seesaw_NeoPixel(24, NEOPIX_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_Crickit crickit;
seesaw_Servo s1(&crickit);
seesaw_Servo s2(&crickit);
seesaw_Servo s3(&crickit);
seesaw_Servo s4(&crickit);
#define NUM_SERVOS 4
seesaw_Servo *servos[NUM_SERVOS] = {&s1, &s2, &s3, &s4};
#define COLOR_MAX 150
#define RED strip.Color(COLOR_MAX, 0, 0)
#define YELLOW strip.Color(COLOR_MAX, 150, 0)
#define GREEN strip.Color(0, COLOR_MAX, 0)
#define CYAN strip.Color(0, COLOR_MAX, 255)
#define BLUE strip.Color(0, 0, COLOR_MAX)
#define PURPLE strip.Color(180, 0, COLOR_MAX)
#define CRICKIT_NUM_ADC 8
static const uint8_t crickit_adc[CRICKIT_NUM_ADC] = { CRICKIT_SIGNAL1, CRICKIT_SIGNAL2, CRICKIT_SIGNAL3, CRICKIT_SIGNAL4,
CRICKIT_SIGNAL5, CRICKIT_SIGNAL6, CRICKIT_SIGNAL7, CRICKIT_SIGNAL8 };
#define CRICKIT_NUM_TOUCH 4
static const uint8_t crickit_drive[CRICKIT_NUM_TOUCH] = {CRICKIT_DRIVE1, CRICKIT_DRIVE2, CRICKIT_DRIVE3, CRICKIT_DRIVE4};
#define CAPTOUCH_THRESH 500
void setup() {
Serial.begin(9600);
while(!Serial);
if(!crickit.begin(0x49, A0)){
Serial.println("ERROR Starting crickit");
while(1) delay(1);
}
else Serial.println("seesaw started");
if(!strip.begin(0x49, A0)){
Serial.println("ERROR Starting neopix");
while(1) delay(1);
}
Serial.println("neopix started!");
s1.attach(CRICKIT_SERVO1);
s2.attach(CRICKIT_SERVO2);
s3.attach(CRICKIT_SERVO3);
s4.attach(CRICKIT_SERVO4);
}
void loop() {
#ifdef USE_NEOPIX
for(uint16_t i=0; i<strip.numPixels(); i++)
strip.setPixelColor(i, RED);
strip.show();
#endif
for(int i=0; i<CRICKIT_NUM_ADC; i++){
Serial.print(crickit.analogRead(crickit_adc[i]));
Serial.print("\t");
}
Serial.println("");
//TODO: fix drive3 and drive4
for(int i=0; i<4; i++){
uint16_t val = crickit.touchRead(i);
if(val > CAPTOUCH_THRESH){
crickit.analogWrite(crickit_drive[i], (1UL << 16) - 1);
Serial.print("CT");
Serial.print(i + 1);
Serial.print(" touched! value: ");
Serial.println(val);
}
else
crickit.analogWrite(crickit_drive[i], 0);
}
#ifdef USE_NEOPIX
for(uint16_t i=0; i<strip.numPixels(); i++)
strip.setPixelColor(i, GREEN);
strip.show();
#endif
for(int i=0; i<NUM_SERVOS; i++){
seesaw_Servo *s = servos[i];
s->write(1000);
}
delay(500);
#ifdef USE_NEOPIX
for(uint16_t i=0; i<strip.numPixels(); i++)
strip.setPixelColor(i, BLUE);
strip.show();
#endif
for(int i=0; i<NUM_SERVOS; i++){
seesaw_Servo *s = servos[i];
s->write(2000);
}
delay(500);
}

View File

@@ -0,0 +1,51 @@
#include "Adafruit_Crickit.h"
#include "seesaw_motor.h"
Adafruit_Crickit crickit;
seesaw_Motor motor_a(&crickit);
seesaw_Motor motor_b(&crickit);
void setup() {
Serial.begin(115200);
Serial.println("Dual motor demo!");
if(!crickit.begin()){
Serial.println("ERROR!");
while(1) delay(1);
}
else Serial.println("Crickit started");
//attach motor a
motor_a.attach(CRICKIT_MOTOR_A1, CRICKIT_MOTOR_A2);
//attach motor b
motor_b.attach(CRICKIT_MOTOR_B1, CRICKIT_MOTOR_B2);
}
void loop() {
motor_a.throttle(1);
motor_b.throttle(-1);
delay(1000);
motor_a.throttle(.5);
motor_b.throttle(-.5);
delay(1000);
motor_a.throttle(0);
motor_b.throttle(0);
delay(1000);
motor_a.throttle(-.5);
motor_b.throttle(.5);
delay(1000);
motor_a.throttle(-1);
motor_b.throttle(1);
delay(1000);
motor_a.throttle(0);
motor_b.throttle(0);
delay(500);
}

View File

@@ -0,0 +1,45 @@
#include "Adafruit_Crickit.h"
#include "seesaw_servo.h"
Adafruit_Crickit crickit;
#define NUM_SERVOS 4
//create an array of 4 servos with our crickit object
seesaw_Servo servos[] = { seesaw_Servo(&crickit),
seesaw_Servo(&crickit),
seesaw_Servo(&crickit),
seesaw_Servo(&crickit) };
//these are the pins they will be attached to
int servoPins[] = { CRICKIT_SERVO1, CRICKIT_SERVO2, CRICKIT_SERVO3, CRICKIT_SERVO4 };
void setup() {
Serial.begin(115200);
//begin the crickit
if(!crickit.begin()){
Serial.println("ERROR!");
while(1) delay(1);
}
else Serial.println("Crickit started");
//attach the servos to their pins
for(int i=0; i<NUM_SERVOS; i++)
servos[i].attach(servoPins[i]); // attaches the servo to the pin
}
void loop() {
//repeat for all 4 servos
for(int i=0; i<NUM_SERVOS; i++){
servos[i].write(0);
delay(1000);
servos[i].write(90);
delay(1000);
servos[i].write(180);
delay(1000);
servos[i].write(90);
delay(1000);
}
}

View File

@@ -0,0 +1,29 @@
#include "Adafruit_Crickit.h"
#include "seesaw_servo.h"
Adafruit_Crickit crickit;
seesaw_Servo myservo(&crickit); // create servo object to control a servo
void setup() {
Serial.begin(115200);
if(!crickit.begin()){
Serial.println("ERROR!");
while(1) delay(1);
}
else Serial.println("Crickit started");
myservo.attach(CRICKIT_SERVO1); // attaches the servo to CRICKIT_SERVO1 pin
}
void loop() {
myservo.write(0);
delay(1000);
myservo.write(90);
delay(1000);
myservo.write(180);
delay(1000);
myservo.write(90);
delay(1000);
}

View File

@@ -0,0 +1,40 @@
#include "Adafruit_Crickit.h"
Adafruit_Crickit crickit;
#define BUTTON_1 CRICKIT_SIGNAL1
#define BUTTON_2 CRICKIT_SIGNAL2
#define LED_1 CRICKIT_SIGNAL3
#define LED_2 CRICKIT_SIGNAL4
void setup() {
Serial.begin(9600);
if(!crickit.begin()){
Serial.println("ERROR!");
while(1) delay(1);
}
else Serial.println("Crickit started");
//Two buttons are pullups, connect to ground to activate
crickit.pinMode(BUTTON_1, INPUT_PULLUP);
crickit.pinMode(BUTTON_2, INPUT_PULLUP);
// Two LEDs are outputs, on by default
crickit.pinMode(LED_1, OUTPUT);
crickit.pinMode(LED_2, OUTPUT);
crickit.digitalWrite(LED_1, HIGH);
crickit.digitalWrite(LED_2, HIGH);
}
void loop() {
if(!crickit.digitalRead(BUTTON_1))
crickit.digitalWrite(LED_1, HIGH);
else
crickit.digitalWrite(LED_1, LOW);
if(!crickit.digitalRead(BUTTON_2))
crickit.digitalWrite(LED_2, HIGH);
else
crickit.digitalWrite(LED_2, LOW);
}

View File

@@ -0,0 +1,38 @@
/*
* This example shows how to read and write EEPROM data. Try writing
* then removing power from both devices, commenting out the write, and
* uploading again.
*/
#include "Adafruit_seesaw.h"
Adafruit_seesaw ss;
void setup() {
uint8_t eepromval;
Serial.begin(115200);
while (!Serial) delay(10); // wait until serial port is opened
if(!ss.begin()){
Serial.println(F("seesaw not found!"));
while(1) delay(10);
}
Serial.println(F("seesaw started OK!"));
Serial.print(F("Initial read from address 0x02...0x"));
eepromval = ss.EEPROMRead8(0x02);
Serial.println(eepromval, HEX);
Serial.println(F("Incrementing value to address 0x02"));
ss.EEPROMWrite8(0x02, eepromval+1);
Serial.print(F("Second read from address 0x02...0x"));
Serial.println(ss.EEPROMRead8(0x02), HEX);
}
void loop() {
//DONT WRITE EEPROM IN A LOOP!!!! YOU WILL DESTROY YOUR FLASH!!!
}

View File

@@ -0,0 +1,96 @@
/*
* This example shows how read arcade buttons and PWM the LEDs on the Adafruit Arcade QT!
*/
#include "Adafruit_seesaw.h"
#include <seesaw_neopixel.h>
#define DEFAULT_I2C_ADDR 0x3A
#define SWITCH1 18 // PA01
#define SWITCH2 19 // PA02
#define SWITCH3 20 // PA03
#define SWITCH4 2 // PA06
#define PWM1 12 // PC00
#define PWM2 13 // PC01
#define PWM3 0 // PA04
#define PWM4 1 // PA05
Adafruit_seesaw ss;
void setup() {
Serial.begin(115200);
while (!Serial) delay(10); // wait until serial port is opened
Serial.println(F("Adafruit PID 5296 I2C QT 4x LED Arcade Buttons test!"));
if (!ss.begin(DEFAULT_I2C_ADDR)) {
Serial.println(F("seesaw not found!"));
while(1) delay(10);
}
uint16_t pid;
uint8_t year, mon, day;
ss.getProdDatecode(&pid, &year, &mon, &day);
Serial.print("seesaw found PID: ");
Serial.print(pid);
Serial.print(" datecode: ");
Serial.print(2000+year); Serial.print("/");
Serial.print(mon); Serial.print("/");
Serial.println(day);
if (pid != 5296) {
Serial.println(F("Wrong seesaw PID"));
while (1) delay(10);
}
Serial.println(F("seesaw started OK!"));
ss.pinMode(SWITCH1, INPUT_PULLUP);
ss.pinMode(SWITCH2, INPUT_PULLUP);
ss.pinMode(SWITCH3, INPUT_PULLUP);
ss.pinMode(SWITCH4, INPUT_PULLUP);
ss.analogWrite(PWM1, 127);
ss.analogWrite(PWM2, 127);
ss.analogWrite(PWM3, 127);
ss.analogWrite(PWM4, 127);
}
uint8_t incr = 0;
void loop() {
if (! ss.digitalRead(SWITCH1)) {
Serial.println("Switch 1 pressed");
ss.analogWrite(PWM1, incr);
incr += 5;
} else {
ss.analogWrite(PWM1, 0);
}
if (! ss.digitalRead(SWITCH2)) {
Serial.println("Switch 2 pressed");
ss.analogWrite(PWM2, incr);
incr += 5;
} else {
ss.analogWrite(PWM2, 0);
}
if (! ss.digitalRead(SWITCH3)) {
Serial.println("Switch 3 pressed");
ss.analogWrite(PWM3, incr);
incr += 5;
} else {
ss.analogWrite(PWM3, 0);
}
if (! ss.digitalRead(SWITCH4)) {
Serial.println("Switch 4 pressed");
ss.analogWrite(PWM4, incr);
incr += 5;
} else {
ss.analogWrite(PWM4, 0);
}
delay(10);
}

View File

@@ -0,0 +1,91 @@
#include "Adafruit_seesaw.h"
Adafruit_seesaw ss;
#define BUTTON_X 6
#define BUTTON_Y 2
#define BUTTON_A 5
#define BUTTON_B 1
#define BUTTON_SELECT 0
#define BUTTON_START 16
uint32_t button_mask = (1UL << BUTTON_X) | (1UL << BUTTON_Y) | (1UL << BUTTON_START) |
(1UL << BUTTON_A) | (1UL << BUTTON_B) | (1UL << BUTTON_SELECT);
//#define IRQ_PIN 5
void setup() {
Serial.begin(115200);
while(!Serial) {
delay(10);
}
Serial.println("Gamepad QT example!");
if(!ss.begin(0x50)){
Serial.println("ERROR! seesaw not found");
while(1) delay(1);
}
Serial.println("seesaw started");
uint32_t version = ((ss.getVersion() >> 16) & 0xFFFF);
if (version != 5743) {
Serial.print("Wrong firmware loaded? ");
Serial.println(version);
while(1) delay(10);
}
Serial.println("Found Product 5743");
ss.pinModeBulk(button_mask, INPUT_PULLUP);
ss.setGPIOInterrupts(button_mask, 1);
#if defined(IRQ_PIN)
pinMode(IRQ_PIN, INPUT);
#endif
}
int last_x = 0, last_y = 0;
void loop() {
delay(10); // delay in loop to slow serial output
// Reverse x/y values to match joystick orientation
int x = 1023 - ss.analogRead(14);
int y = 1023 - ss.analogRead(15);
if ( (abs(x - last_x) > 3) || (abs(y - last_y) > 3)) {
Serial.print("x: "); Serial.print(x); Serial.print(", "); Serial.print("y: "); Serial.println(y);
last_x = x;
last_y = y;
}
#if defined(IRQ_PIN)
if(!digitalRead(IRQ_PIN)) {
return;
}
#endif
uint32_t buttons = ss.digitalReadBulk(button_mask);
//Serial.println(buttons, BIN);
if (! (buttons & (1UL << BUTTON_A))) {
Serial.println("Button A pressed");
}
if (! (buttons & (1UL << BUTTON_B))) {
Serial.println("Button B pressed");
}
if (! (buttons & (1UL << BUTTON_Y))) {
Serial.println("Button Y pressed");
}
if (! (buttons & (1UL << BUTTON_X))) {
Serial.println("Button X pressed");
}
if (! (buttons & (1UL << BUTTON_SELECT))) {
Serial.println("Button SELECT pressed");
}
if (! (buttons & (1UL << BUTTON_START))) {
Serial.println("Button START pressed");
}
}

View File

@@ -0,0 +1,85 @@
#include "Adafruit_NeoKey_1x4.h"
#include "seesaw_neopixel.h"
Adafruit_NeoKey_1x4 neokey; // Create the NeoKey object
void setup() {
Serial.begin(115200);
while (! Serial) delay(10);
if (! neokey.begin(0x30)) { // begin with I2C address, default is 0x30
Serial.println("Could not start NeoKey, check wiring?");
while(1) delay(10);
}
Serial.println("NeoKey started!");
// Pulse all the LEDs on to show we're working
for (uint16_t i=0; i<neokey.pixels.numPixels(); i++) {
neokey.pixels.setPixelColor(i, 0x808080); // make each LED white
neokey.pixels.show();
delay(50);
}
for (uint16_t i=0; i<neokey.pixels.numPixels(); i++) {
neokey.pixels.setPixelColor(i, 0x000000);
neokey.pixels.show();
delay(50);
}
}
void loop() {
uint8_t buttons = neokey.read();
// Check each button, if pressed, light the matching neopixel
if (buttons & (1<<0)) {
Serial.println("Button A");
neokey.pixels.setPixelColor(0, 0xFF0000); // red
} else {
neokey.pixels.setPixelColor(0, 0);
}
if (buttons & (1<<1)) {
Serial.println("Button B");
neokey.pixels.setPixelColor(1, 0xFFFF00); // yellow
} else {
neokey.pixels.setPixelColor(1, 0);
}
if (buttons & (1<<2)) {
Serial.println("Button C");
neokey.pixels.setPixelColor(2, 0x00FF00); // green
} else {
neokey.pixels.setPixelColor(2, 0);
}
if (buttons & (1<<3)) {
Serial.println("Button D");
neokey.pixels.setPixelColor(3, 0x00FFFF); // blue
} else {
neokey.pixels.setPixelColor(3, 0);
}
neokey.pixels.show();
delay(10); // don't print too fast
}
/******************************************/
// Input a value 0 to 255 to get a color value.
// The colors are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
if(WheelPos < 85) {
return seesaw_NeoPixel::Color(WheelPos * 3, 255 - WheelPos * 3, 0);
} else if(WheelPos < 170) {
WheelPos -= 85;
return seesaw_NeoPixel::Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return seesaw_NeoPixel::Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
return 0;
}

View File

@@ -0,0 +1,81 @@
#include "Adafruit_NeoKey_1x4.h"
#include "seesaw_neopixel.h"
Adafruit_NeoKey_1x4 neokey; // Create the NeoKey object
//define a callback for key presses
NeoKey1x4Callback blink(keyEvent evt) {
uint8_t key = evt.bit.NUM;
if (evt.bit.EDGE == SEESAW_KEYPAD_EDGE_RISING) {
Serial.print("Key press ");
Serial.println(key);
neokey.pixels.setPixelColor(key, Wheel(map(key, 0, neokey.pixels.numPixels(), 0, 255)));
} else if (evt.bit.EDGE == SEESAW_KEYPAD_EDGE_FALLING) {
Serial.print("Key release ");
Serial.println(key);
neokey.pixels.setPixelColor(key, 0);
}
// Turn on/off the neopixels!
neokey.pixels.show();
return 0;
}
void setup() {
Serial.begin(115200);
while (! Serial) delay(10);
if (! neokey.begin(0x30)) { // begin with I2C address, default is 0x30
Serial.println("Could not start NeoKey, check wiring?");
while(1) delay(10);
}
Serial.println("NeoKey started!");
// Pulse all the LEDs on to show we're working
for (uint16_t i=0; i<neokey.pixels.numPixels(); i++) {
neokey.pixels.setPixelColor(i, 0x808080); // make each LED white
neokey.pixels.show();
delay(50);
}
for (uint16_t i=0; i<neokey.pixels.numPixels(); i++) {
neokey.pixels.setPixelColor(i, 0x000000);
neokey.pixels.show();
delay(50);
}
// set callbacks
for(int i=0; i<NEOKEY_1X4_KEYS; i++){
neokey.registerCallback(i, blink);
}
}
void loop() {
// we handle all key events with the callbacks
neokey.read();
delay(10); // don't print too fast
}
/******************************************/
// Input a value 0 to 255 to get a color value.
// The colors are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
if(WheelPos < 85) {
return seesaw_NeoPixel::Color(WheelPos * 3, 255 - WheelPos * 3, 0);
} else if(WheelPos < 170) {
WheelPos -= 85;
return seesaw_NeoPixel::Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return seesaw_NeoPixel::Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
return 0;
}

View File

@@ -0,0 +1,92 @@
#include "Adafruit_NeoKey_1x4.h"
#include "seesaw_neopixel.h"
#define Y_DIM 2 //number of rows of keys
#define X_DIM 4 //number of columns of keys
// create a matrix of NeoKey 1x4's
// this example is just two, one on top of another to make a 2x4 grid
Adafruit_NeoKey_1x4 nk_array[Y_DIM][X_DIM/4] = {
{ Adafruit_NeoKey_1x4(0x30) },
{ Adafruit_NeoKey_1x4(0x31) },
};
// pass this matrix to the multi-neokey object
Adafruit_MultiNeoKey1x4 neokey((Adafruit_NeoKey_1x4 *)nk_array, Y_DIM, X_DIM/4);
void setup() {
Serial.begin(115200);
while (! Serial) delay(10);
if (! neokey.begin()) { // start matrix
Serial.println("Could not start NeoKeys, check wiring?");
while(1) delay(10);
}
Serial.println("NeoKey started!");
// Pulse all the LEDs on to show we're working
for (uint16_t i=0; i< X_DIM*Y_DIM; i++) {
neokey.setPixelColor(i, 0x808080); // make each LED white
neokey.show();
delay(50);
}
for (uint16_t i=0; i< X_DIM*Y_DIM; i++) {
neokey.setPixelColor(i, 0x000000);
neokey.show();
delay(50);
}
// activate all keys and set callbacks
for(int y=0; y<Y_DIM; y++){
for(int x=0; x<X_DIM; x++){
neokey.registerCallback(x, y, blink);
}
}
}
void loop() {
neokey.read();
delay(10); // don't print too fast
}
//define a callback for key presses
NeoKey1x4Callback blink(keyEvent evt) {
uint8_t key = evt.bit.NUM;
if (evt.bit.EDGE == SEESAW_KEYPAD_EDGE_RISING) {
Serial.print("Key press ");
Serial.println(key);
neokey.setPixelColor(key, Wheel(map(key, 0, X_DIM*Y_DIM, 0, 255)));
} else if (evt.bit.EDGE == SEESAW_KEYPAD_EDGE_FALLING) {
Serial.print("Key release ");
Serial.println(key);
neokey.setPixelColor(key, 0);
}
// Turn on/off the neopixels!
neokey.show();
return 0;
}
/******************************************/
// Input a value 0 to 255 to get a color value.
// The colors are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
if(WheelPos < 85) {
return seesaw_NeoPixel::Color(WheelPos * 3, 255 - WheelPos * 3, 0);
} else if(WheelPos < 170) {
WheelPos -= 85;
return seesaw_NeoPixel::Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return seesaw_NeoPixel::Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
return 0;
}

View File

@@ -0,0 +1,86 @@
#include "Adafruit_NeoKey_1x4.h"
#include "seesaw_neopixel.h"
Adafruit_NeoKey_1x4 neokey;
void setup() {
Serial.begin(115200);
while (! Serial) delay(10);
if (! neokey.begin(0x30)) {
Serial.println("Could not start NeoKey, check wiring?");
while(1) delay(10);
}
Serial.println("NeoKey started!");
for (uint16_t i=0; i<neokey.pixels.numPixels(); i++) {
neokey.pixels.setPixelColor(i, Wheel(map(i, 0, neokey.pixels.numPixels(), 0, 255)));
neokey.pixels.show();
delay(50);
}
for (uint16_t i=0; i<neokey.pixels.numPixels(); i++) {
neokey.pixels.setPixelColor(i, 0x000000);
neokey.pixels.show();
delay(50);
}
}
uint8_t j=0; // this variable tracks the colors of the LEDs cycle.
void loop() {
uint8_t buttons = neokey.read();
for (int i=0; i< neokey.pixels.numPixels(); i++) {
neokey.pixels.setPixelColor(i, Wheel(((i * 256 / neokey.pixels.numPixels()) + j) & 255));
}
if (buttons & (1<<0)) {
Serial.println("Button A");
} else {
neokey.pixels.setPixelColor(0, 0);
}
if (buttons & (1<<1)) {
Serial.println("Button B");
} else {
neokey.pixels.setPixelColor(1, 0);
}
if (buttons & (1<<2)) {
Serial.println("Button C");
} else {
neokey.pixels.setPixelColor(2, 0);
}
if (buttons & (1<<3)) {
Serial.println("Button D");
} else {
neokey.pixels.setPixelColor(3, 0);
}
neokey.pixels.show();
delay(10); // don't print too fast
j++; // make colors cycle
}
/******************************************/
// Input a value 0 to 255 to get a color value.
// The colors are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
if(WheelPos < 85) {
return seesaw_NeoPixel::Color(WheelPos * 3, 255 - WheelPos * 3, 0);
} else if(WheelPos < 170) {
WheelPos -= 85;
return seesaw_NeoPixel::Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return seesaw_NeoPixel::Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
return 0;
}

View File

@@ -0,0 +1,133 @@
#include <seesaw_neopixel.h>
#define PIN 10
// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
// NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
seesaw_NeoPixel strip = seesaw_NeoPixel(12, PIN, NEO_GRB + NEO_KHZ800);
// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel. Avoid connecting
// on a live circuit...if you must, connect GND first.
void setup() {
Serial.begin(115200);
while (!Serial) delay(10); // wait until serial port is opened
if(!strip.begin()){
Serial.println("seesaw not found!");
while(1) delay(10);
}
Serial.println(F("seesaw started OK!"));
strip.show(); // Initialize all pixels to 'off'
}
void loop() {
// Some example procedures showing how to display to the pixels:
colorWipe(strip.Color(255, 0, 0), 50); // Red
colorWipe(strip.Color(0, 255, 0), 50); // Green
colorWipe(strip.Color(0, 0, 255), 50); // Blue
//colorWipe(strip.Color(0, 0, 0, 255), 50); // White RGBW
// Send a theater pixel chase in...
theaterChase(strip.Color(127, 127, 127), 50); // White
theaterChase(strip.Color(127, 0, 0), 50); // Red
theaterChase(strip.Color(0, 0, 127), 50); // Blue
rainbow(20);
rainbowCycle(20);
theaterChaseRainbow(50);
}
// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}
void rainbow(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256; j++) {
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel((i+j) & 255));
}
strip.show();
delay(wait);
}
}
// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
for(i=0; i< strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
}
strip.show();
delay(wait);
}
}
//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
for (int j=0; j<10; j++) { //do 10 cycles of chasing
for (int q=0; q < 3; q++) {
for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, c); //turn every third pixel on
}
strip.show();
delay(wait);
for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}
//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
for (int j=0; j < 256; j++) { // cycle all 256 colors in the wheel
for (int q=0; q < 3; q++) {
for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, Wheel( (i+j) % 255)); //turn every third pixel on
}
strip.show();
delay(wait);
for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if(WheelPos < 85) {
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

View File

@@ -0,0 +1,96 @@
// SPDX-FileCopyrightText: 2021 Kattni Rembor for Adafruit Industries
// SPDX-License-Identifier: MIT
/*
* This example shows how read the potentiometer on two I2C QT Slide Potentiometers
* and make the NeoPixels change too!
*/
#include "Adafruit_seesaw.h"
#include <seesaw_neopixel.h>
#define DEFAULT_I2C_ADDR 0x30
#define ANALOGIN 18
#define NEOPIXELOUT 14
Adafruit_seesaw seesaw1;
Adafruit_seesaw seesaw2;
seesaw_NeoPixel pixels1 = seesaw_NeoPixel(4, NEOPIXELOUT, NEO_GRB + NEO_KHZ800);
seesaw_NeoPixel pixels2 = seesaw_NeoPixel(4, NEOPIXELOUT, NEO_GRB + NEO_KHZ800);
void setup() {
Serial.begin(115200);
//while (!Serial) delay(10); // wait until serial port is opened
Serial.println(F("Adafruit PID 5295 I2C QT Slide Potentiometer test!"));
if (!seesaw1.begin(DEFAULT_I2C_ADDR) || !seesaw2.begin(DEFAULT_I2C_ADDR+1)) {
Serial.println(F("seesaws not found!"));
while(1) delay(10);
}
uint16_t pid;
uint8_t year, mon, day;
seesaw1.getProdDatecode(&pid, &year, &mon, &day);
Serial.print("seesaw found PID: ");
Serial.print(pid);
Serial.print(" datecode: ");
Serial.print(2000+year); Serial.print("/");
Serial.print(mon); Serial.print("/");
Serial.println(day);
if (pid != 5295) {
Serial.println(F("Wrong seesaw PID"));
while (1) delay(10);
}
if (!pixels1.begin(DEFAULT_I2C_ADDR) || !pixels2.begin(DEFAULT_I2C_ADDR+1)){
Serial.println("seesaw pixels not found!");
while(1) delay(10);
}
Serial.println(F("seesaw started OK!"));
pixels1.setBrightness(255); // half bright
pixels2.setBrightness(255); // half bright
pixels1.show(); // Initialize all pixels to 'off'
pixels2.show(); // Initialize all pixels to 'off'
}
void loop() {
// read the potentiometer
uint16_t slide1_val = seesaw1.analogRead(ANALOGIN);
uint16_t slide2_val = seesaw2.analogRead(ANALOGIN);
Serial.print(slide1_val);
Serial.print(", ");
Serial.println(slide2_val);
for (uint8_t i=0; i< pixels1.numPixels(); i++) {
pixels1.setPixelColor(i, Wheel(slide1_val / 4));
pixels2.setPixelColor(i, Wheel(slide2_val / 4));
}
pixels1.show();
pixels2.show();
delay(50);
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if(WheelPos < 85) {
return seesaw_NeoPixel::Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if(WheelPos < 170) {
WheelPos -= 85;
return seesaw_NeoPixel::Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return seesaw_NeoPixel::Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

View File

@@ -0,0 +1,87 @@
// SPDX-FileCopyrightText: 2021 Kattni Rembor for Adafruit Industries
// SPDX-License-Identifier: MIT
/*
* This example shows how read the potentiometer on the I2C QT Slide Potentiometer
* and make the NeoPixels change too!
*/
#include "Adafruit_seesaw.h"
#include <seesaw_neopixel.h>
#define DEFAULT_I2C_ADDR 0x30
#define ANALOGIN 18
#define NEOPIXELOUT 14
Adafruit_seesaw seesaw;
seesaw_NeoPixel pixels = seesaw_NeoPixel(4, NEOPIXELOUT, NEO_GRB + NEO_KHZ800);
void setup() {
Serial.begin(115200);
//while (!Serial) delay(10); // wait until serial port is opened
Serial.println(F("Adafruit PID 5295 I2C QT Slide Potentiometer test!"));
if (!seesaw.begin(DEFAULT_I2C_ADDR)) {
Serial.println(F("seesaw not found!"));
while(1) delay(10);
}
uint16_t pid;
uint8_t year, mon, day;
seesaw.getProdDatecode(&pid, &year, &mon, &day);
Serial.print("seesaw found PID: ");
Serial.print(pid);
Serial.print(" datecode: ");
Serial.print(2000+year); Serial.print("/");
Serial.print(mon); Serial.print("/");
Serial.println(day);
if (pid != 5295) {
Serial.println(F("Wrong seesaw PID"));
while (1) delay(10);
}
if (!pixels.begin(DEFAULT_I2C_ADDR)){
Serial.println("seesaw pixels not found!");
while(1) delay(10);
}
Serial.println(F("seesaw started OK!"));
pixels.setBrightness(255); // half bright
pixels.show(); // Initialize all pixels to 'off'
}
void loop() {
// read the potentiometer
uint16_t slide_val = seesaw.analogRead(ANALOGIN);
Serial.println(slide_val);
for (uint8_t i=0; i< pixels.numPixels(); i++) {
pixels.setPixelColor(i, Wheel(slide_val / 4));
}
pixels.show();
delay(50);
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if(WheelPos < 85) {
return seesaw_NeoPixel::Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if(WheelPos < 170) {
WheelPos -= 85;
return seesaw_NeoPixel::Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return seesaw_NeoPixel::Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

View File

@@ -0,0 +1,79 @@
/* This example shows basic usage of the NeoTrellis.
The buttons will light up various colors when pressed.
The interrupt pin is not used in this example.
*/
#include "Adafruit_NeoTrellis.h"
Adafruit_NeoTrellis trellis;
//define a callback for key presses
TrellisCallback blink(keyEvent evt){
// Check is the pad pressed?
if (evt.bit.EDGE == SEESAW_KEYPAD_EDGE_RISING) {
trellis.pixels.setPixelColor(evt.bit.NUM, Wheel(map(evt.bit.NUM, 0, trellis.pixels.numPixels(), 0, 255))); //on rising
} else if (evt.bit.EDGE == SEESAW_KEYPAD_EDGE_FALLING) {
// or is the pad released?
trellis.pixels.setPixelColor(evt.bit.NUM, 0); //off falling
}
// Turn on/off the neopixels!
trellis.pixels.show();
return 0;
}
void setup() {
Serial.begin(9600);
// while(!Serial) delay(1);
if (!trellis.begin()) {
Serial.println("Could not start trellis, check wiring?");
while(1) delay(1);
} else {
Serial.println("NeoPixel Trellis started");
}
//activate all keys and set callbacks
for(int i=0; i<NEO_TRELLIS_NUM_KEYS; i++){
trellis.activateKey(i, SEESAW_KEYPAD_EDGE_RISING);
trellis.activateKey(i, SEESAW_KEYPAD_EDGE_FALLING);
trellis.registerCallback(i, blink);
}
//do a little animation to show we're on
for (uint16_t i=0; i<trellis.pixels.numPixels(); i++) {
trellis.pixels.setPixelColor(i, Wheel(map(i, 0, trellis.pixels.numPixels(), 0, 255)));
trellis.pixels.show();
delay(50);
}
for (uint16_t i=0; i<trellis.pixels.numPixels(); i++) {
trellis.pixels.setPixelColor(i, 0x000000);
trellis.pixels.show();
delay(50);
}
}
void loop() {
trellis.read(); // interrupt management does all the work! :)
delay(20); //the trellis has a resolution of around 60hz
}
/******************************************/
// Input a value 0 to 255 to get a color value.
// The colors are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
if(WheelPos < 85) {
return trellis.pixels.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
} else if(WheelPos < 170) {
WheelPos -= 85;
return trellis.pixels.Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return trellis.pixels.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
return 0;
}

View File

@@ -0,0 +1,77 @@
/* This example shows basic usage of the NeoTrellis
with the interrupt pin.
The buttons will light up various colors when pressed.
*/
#include "Adafruit_NeoTrellis.h"
Adafruit_NeoTrellis trellis;
#define INT_PIN 10
// Input a value 0 to 255 to get a color value.
// The colors are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
if(WheelPos < 85) {
return trellis.pixels.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
} else if(WheelPos < 170) {
WheelPos -= 85;
return trellis.pixels.Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return trellis.pixels.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
}
//define a callback for key presses
TrellisCallback blink(keyEvent evt){
if(evt.bit.EDGE == SEESAW_KEYPAD_EDGE_RISING)
trellis.pixels.setPixelColor(evt.bit.NUM, Wheel(map(evt.bit.NUM, 0, trellis.pixels.numPixels(), 0, 255))); //on rising
else if(evt.bit.EDGE == SEESAW_KEYPAD_EDGE_FALLING)
trellis.pixels.setPixelColor(evt.bit.NUM, 0); //off falling
trellis.pixels.show();
return 0;
}
void setup() {
Serial.begin(9600);
//while(!Serial);
pinMode(INT_PIN, INPUT);
if(!trellis.begin()){
Serial.println("could not start trellis");
while(1) delay(1);
}
else{
Serial.println("trellis started");
}
//activate all keys and set callbacks
for(int i=0; i<NEO_TRELLIS_NUM_KEYS; i++){
trellis.activateKey(i, SEESAW_KEYPAD_EDGE_RISING);
trellis.activateKey(i, SEESAW_KEYPAD_EDGE_FALLING);
trellis.registerCallback(i, blink);
}
//do a little animation to show we're on
for(uint16_t i=0; i<trellis.pixels.numPixels(); i++) {
trellis.pixels.setPixelColor(i, Wheel(map(i, 0, trellis.pixels.numPixels(), 0, 255)));
trellis.pixels.show();
delay(50);
}
for(uint16_t i=0; i<trellis.pixels.numPixels(); i++) {
trellis.pixels.setPixelColor(i, 0x000000);
trellis.pixels.show();
delay(50);
}
}
void loop() {
if(!digitalRead(INT_PIN)){
trellis.read(false);
}
delay(2);
}

View File

@@ -0,0 +1,102 @@
/* This example shows basic usage of the
MultiTrellis object controlling an array of
NeoTrellis boards
As is this example shows use of two NeoTrellis boards
connected together with the leftmost board having the
default I2C address of 0x2E, and the rightmost board
having the address of 0x2F (the A0 jumper is soldered)
*/
#include "Adafruit_NeoTrellis.h"
#define Y_DIM 4 //number of rows of key
#define X_DIM 8 //number of columns of keys
//create a matrix of trellis panels
Adafruit_NeoTrellis t_array[Y_DIM/4][X_DIM/4] = {
{ Adafruit_NeoTrellis(0x2E), Adafruit_NeoTrellis(0x2F) }
};
/*
If you were using a 2x2 array of NeoTrellis boards, the above lines would be:
#define Y_DIM 8 //number of rows of key
#define X_DIM 8 //number of columns of keys
//create a matrix of trellis panels
Adafruit_NeoTrellis t_array[Y_DIM/4][X_DIM/4] = {
{ Adafruit_NeoTrellis(0x2E), Adafruit_NeoTrellis(0x2F) },
{ Adafruit_NeoTrellis(LOWER_LEFT_I2C_ADDR), Adafruit_NeoTrellis(LOWER_RIGHT_I2C_ADDR) }
};
*/
//pass this matrix to the multitrellis object
Adafruit_MultiTrellis trellis((Adafruit_NeoTrellis *)t_array, Y_DIM/4, X_DIM/4);
// Input a value 0 to 255 to get a color value.
// The colors are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
if(WheelPos < 85) {
return seesaw_NeoPixel::Color(WheelPos * 3, 255 - WheelPos * 3, 0);
} else if(WheelPos < 170) {
WheelPos -= 85;
return seesaw_NeoPixel::Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return seesaw_NeoPixel::Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
return 0;
}
//define a callback for key presses
TrellisCallback blink(keyEvent evt){
if(evt.bit.EDGE == SEESAW_KEYPAD_EDGE_RISING)
trellis.setPixelColor(evt.bit.NUM, Wheel(map(evt.bit.NUM, 0, X_DIM*Y_DIM, 0, 255))); //on rising
else if(evt.bit.EDGE == SEESAW_KEYPAD_EDGE_FALLING)
trellis.setPixelColor(evt.bit.NUM, 0); //off falling
trellis.show();
return 0;
}
void setup() {
Serial.begin(9600);
//while(!Serial) delay(1);
if(!trellis.begin()){
Serial.println("failed to begin trellis");
while(1) delay(1);
}
/* the array can be addressed as x,y or with the key number */
for(int i=0; i<Y_DIM*X_DIM; i++){
trellis.setPixelColor(i, Wheel(map(i, 0, X_DIM*Y_DIM, 0, 255))); //addressed with keynum
trellis.show();
delay(50);
}
for(int y=0; y<Y_DIM; y++){
for(int x=0; x<X_DIM; x++){
//activate rising and falling edges on all keys
trellis.activateKey(x, y, SEESAW_KEYPAD_EDGE_RISING, true);
trellis.activateKey(x, y, SEESAW_KEYPAD_EDGE_FALLING, true);
trellis.registerCallback(x, y, blink);
trellis.setPixelColor(x, y, 0x000000); //addressed with x,y
trellis.show(); //show all LEDs
delay(50);
}
}
}
void loop() {
trellis.read();
delay(20);
}

View File

@@ -0,0 +1,157 @@
/* Small game for Adafruit NeoTrellis
* Works fine with smaller chips like Nano
*/
#include "Adafruit_NeoTrellis.h"
Adafruit_NeoTrellis trellis;
#define RED 0xFF00000
#define GREEN 0x00FF000
/*Defines the maximum difficulty (16 patterns in a row)*/
#define MAX_DIFFICULTY 16
int game_sequence[MAX_DIFFICULTY] = {};
int current_difficulty = 2;
int cur = 0;
//define a callback for key presses
// Release event will trigger the game check
TrellisCallback blink(keyEvent evt){
// Check is the pad pressed?
if (evt.bit.EDGE == SEESAW_KEYPAD_EDGE_RISING) {
trellis.pixels.setPixelColor(evt.bit.NUM, Wheel(map(evt.bit.NUM, 0, trellis.pixels.numPixels(), 0, 255))); //on rising
} else if (evt.bit.EDGE == SEESAW_KEYPAD_EDGE_FALLING) {
// or is the pad released?
trellis.pixels.setPixelColor(evt.bit.NUM, 0); //off falling
// Check if the pressed button it correct
if (game_sequence[cur] == evt.bit.NUM){
flash(GREEN);
cur++;
if (cur == current_difficulty){
flash(GREEN);
flash(GREEN);
flash(GREEN);
cur = 0;
restart_game();
}
} else{
flash(RED);
cur = 0;
show_solution(game_sequence, current_difficulty);
}
}
// Turn on/off the neopixels!
trellis.pixels.show();
return 0;
}
/*Increse difficulty and restart the game*/
void restart_game(){
if (current_difficulty <= MAX_DIFFICULTY){
current_difficulty++;
}
start_game(current_difficulty);
}
/*
* Flash all leds for a short time
*/
void flash(uint32_t color){
for (uint16_t i=0; i<trellis.pixels.numPixels(); i++) {
trellis.pixels.setPixelColor(i, color);
}
trellis.pixels.show();
delay(200);
for (uint16_t i=0; i<trellis.pixels.numPixels(); i++) {
trellis.pixels.setPixelColor(i, 0x000000);
}
trellis.pixels.show();
}
void setup() {
randomSeed(analogRead(0));
Serial.begin(9600);
//while(!Serial);
if (!trellis.begin()) {
Serial.println("Could not start trellis, check wiring?");
while(1) delay(1);
} else {
Serial.println("NeoPixel Trellis started");
}
//activate all keys and set callbacks
for(int i=0; i<NEO_TRELLIS_NUM_KEYS; i++){
trellis.activateKey(i, SEESAW_KEYPAD_EDGE_RISING);
trellis.activateKey(i, SEESAW_KEYPAD_EDGE_FALLING);
trellis.registerCallback(i, blink);
}
//do a little animation to show we're on
for (uint16_t i=0; i<trellis.pixels.numPixels(); i++) {
trellis.pixels.setPixelColor(i, Wheel(map(i, 0, trellis.pixels.numPixels(), 0, 255)));
trellis.pixels.show();
delay(50);
}
delay(50);
for (uint16_t i=0; i<trellis.pixels.numPixels(); i++) {
trellis.pixels.setPixelColor(i, 0x000000);
trellis.pixels.show();
delay(50);
}
trellis.pixels.show();
delay(1000);
start_game(current_difficulty);
}
void start_game(int level){
for (int x = 0; x <= level; x++){
int led = random(trellis.pixels.numPixels());
game_sequence[x] = led;
}
show_solution(game_sequence, level);
}
void show_solution(int solution[], int level){
for (int x=0; x < level; x++){
int led = solution[x];
trellis.pixels.setPixelColor(led, Wheel(map(led, 0, trellis.pixels.numPixels(), 0, 255)));
trellis.pixels.show();
delay(500);
trellis.pixels.setPixelColor(led, 0x000000);
trellis.pixels.show();
delay(50);
}
}
void loop() {
trellis.read(); // interrupt management does all the work! :)
delay(20); //the trellis has a resolution of around 60hz
}
/******************************************/
// Input a value 0 to 255 to get a color value.
// The colors are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
if(WheelPos < 85) {
return trellis.pixels.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
} else if(WheelPos < 170) {
WheelPos -= 85;
return trellis.pixels.Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return trellis.pixels.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
return 0;
}

View File

@@ -0,0 +1,180 @@
/* This example shows a more complex LED pattern
using a NeoTrellis board.
Note that due to memory requirements this example
will not work on boards with very limited memory such
as the Adafruit Metro (with ATMega328p)
*/
#include "Adafruit_NeoTrellis.h"
Adafruit_NeoTrellis trellis;
#define MAX_RIPPLES 16
#define FALLOFF_TIME 30
#define FALLOFF (0xFF/FALLOFF_TIME)
#define NUM_POINTS 8
#define RIPPLE_RATE .4
#define INT_PIN 10
#define MATRIX_POINT(x,y) ((y)*4+(x))
uint32_t colors[] = {
0xFF0000, 0x00FF00, 0x0000FF,
0xFF00FF, 0x00FFFF, 0xFFFFFF
};
union color {
struct {
uint8_t blue:8;
uint8_t green:8;
uint8_t red:8;
} bit;
uint32_t reg;
};
color matrix[4][4];
struct point {
float x;
float y;
};
struct ripple {
int8_t center;
uint32_t t;
color c;
point points[NUM_POINTS];
};
static struct ripple ripples[MAX_RIPPLES];
//define a callback for key presses
TrellisCallback blink(keyEvent evt){
for(int i=0; i<MAX_RIPPLES; i++){
if(ripples[i].center == -1){
//create a new ripple here
ripples[i].center = evt.bit.NUM;
ripples[i].t = 0;
for(int j=0; j<NUM_POINTS; j++){
ripples[i].points[j].x = NEO_TRELLIS_X(evt.bit.NUM);
ripples[i].points[j].y = NEO_TRELLIS_Y(evt.bit.NUM);
}
ripples[i].c.reg = colors[random(sizeof(colors)/sizeof(uint32_t))];
break;
}
}
return 0;
}
void setup() {
Serial.begin(9600);
//while(!Serial);
pinMode(INT_PIN, INPUT);
randomSeed(analogRead(0));
if(!trellis.begin()){
Serial.println("could not start trellis");
while(1) delay(1);
}
else{
Serial.println("trellis started");
}
for(int i=0; i<MAX_RIPPLES; i++)
ripples[i].center = -1;
//activate all keys and set callbacks
for(int i=0; i<NEO_TRELLIS_NUM_KEYS; i++){
trellis.activateKey(i, SEESAW_KEYPAD_EDGE_RISING);
trellis.registerCallback(i, blink);
}
//do a little animation to show we're on
for(uint16_t i=0; i<trellis.pixels.numPixels(); i++) {
trellis.pixels.setPixelColor(i, 0x0000FF);
trellis.pixels.show();
delay(50);
}
for(uint16_t i=0; i<trellis.pixels.numPixels(); i++) {
trellis.pixels.setPixelColor(i, 0x000000);
trellis.pixels.show();
delay(50);
}
}
void processRipples(){
for(int x=0; x<4; x++){
for(int y=0; y<4; y++)
matrix[x][y].reg = 0;
}
bool update = false;
for(int i=0; i<MAX_RIPPLES; i++){
if(ripples[i].center > -1){
update = true;
//push all points out from the center
point *p = ripples[i].points;
p[0].x += RIPPLE_RATE;
p[1].x += RIPPLE_RATE/2;
p[1].y += RIPPLE_RATE/2;
p[2].y += RIPPLE_RATE;
p[3].x -= RIPPLE_RATE/2;
p[3].y += RIPPLE_RATE/2;
p[4].x -= RIPPLE_RATE;
p[5].x -= RIPPLE_RATE/2;
p[5].y -= RIPPLE_RATE/2;
p[6].y -= RIPPLE_RATE;
p[7].x += RIPPLE_RATE/2;
p[7].y -= RIPPLE_RATE/2;
for(int j=0; j<NUM_POINTS; j++){
int x = round(p[j].x);
int y = round(p[j].y);
if(x < 4 && x >= 0 && y < 4 && y >= 0){
byte red = min(255, matrix[x][y].bit.red + ripples[i].c.bit.red);
byte green = min(255, matrix[x][y].bit.green + ripples[i].c.bit.green);
byte blue = min(255, matrix[x][y].bit.blue + ripples[i].c.bit.blue);
matrix[x][y].bit.red = red;
matrix[x][y].bit.green = green;
matrix[x][y].bit.blue = blue;
}
}
ripples[i].t++;
if(ripples[i].t >= FALLOFF_TIME) ripples[i].center = -1;
}
}
if(update){
for(int x=0; x<4; x++){
for(int y=0; y<4; y++)
trellis.pixels.setPixelColor(MATRIX_POINT(x,y), matrix[x][y].reg);
}
trellis.pixels.show();
}
}
void loop() {
if(!digitalRead(INT_PIN)){
trellis.read(false);
}
processRipples();
delay(20);
}

View File

@@ -0,0 +1,93 @@
#include "Adafruit_seesaw.h"
// creates seesaw on I2C0 port
Adafruit_seesaw ss = Adafruit_seesaw(&Wire);
// uncomment this for using I2C1, such as STEMMA port on QT Py RP2040
// Adafruit_seesaw ss = Adafruit_seesaw(&Wire1);
#define BUTTON_1 3
#define BUTTON_2 13
#define BUTTON_3 2
#define BUTTON_4 14
uint32_t button_mask = (1UL << BUTTON_1) | (1UL << BUTTON_2) |
(1UL << BUTTON_3) | (1UL << BUTTON_4);
#define JOY1_X 1
#define JOY1_Y 15
#define JOY2_X 0
#define JOY2_Y 16
//#define IRQ_PIN 5
void setup() {
Serial.begin(115200);
while(!Serial) {
delay(10);
}
Serial.println("PC Joystick QT example!");
ss.begin(0x49);
Serial.println("seesaw started");
uint32_t version = ((ss.getVersion() >> 16) & 0xFFFF);
if (version != 5753) {
Serial.print("Wrong firmware loaded? ");
Serial.println(version);
while(1) delay(10);
}
Serial.println("Found Product 5753");
ss.pinModeBulk(button_mask, INPUT_PULLUP);
ss.setGPIOInterrupts(button_mask, 1);
#if defined(IRQ_PIN)
pinMode(IRQ_PIN, INPUT);
#endif
}
float last_x = 0, last_y = 0;
void loop() {
delay(10); // delay in loop to slow serial output
float x = 0, y = 0;
// These joysticks are really jittery so lets take 4 samples of each axis
for (int s=0; s<4; s++) {
x += ss.analogRead(JOY1_X);
y += ss.analogRead(JOY1_Y);
}
x /= 4.0; // Take the average of the 4 samples
y /= 4.0;
// PC joysticks aren't "true" voltage divider, because we have a fixed 10K
// we dont know the 'normalized' value so we're just going to give you
// the result in 'Kohms' for easier printing
x = (1024.0/(float)x - 1);
y = (1024.0/(float)y - 1);
if ( (fabs(x - last_x) > 0.1) || (fabs(y - last_y) > 0.1)) {
Serial.print(x); Serial.print(", "); Serial.println(y);
last_x = x;
last_y = y;
}
#if defined(IRQ_PIN)
if(!digitalRead(IRQ_PIN)) {
return;
}
#endif
uint32_t buttons = ss.digitalReadBulk(button_mask);
//Serial.println(buttons, BIN);
if (! (buttons & (1UL << BUTTON_1))) {
Serial.println("Button 1 pressed");
}
if (! (buttons & (1UL << BUTTON_2))) {
Serial.println("Button 2 pressed");
}
if (! (buttons & (1UL << BUTTON_3))) {
Serial.println("Button 3 pressed");
}
if (! (buttons & (1UL << BUTTON_4))) {
Serial.println("Button 4 pressed");
}
}

View File

@@ -0,0 +1,48 @@
/*
Fade
This example shows how to fade an LED on pin 6 of a seesaw board using the analogWrite()
function.
The analogWrite() function uses PWM, so if you want to change the pin you're
using, be sure to use another PWM capable pin.
On the SAMD09 breakout these are pins 5, 6, and 7
On the ATtinyxy7 breakout these are pins 0, 1, 9, 12, 13
On the ATtinyxy6 breakout these are pins 0, 1, 7, 11, 16
*/
#include "Adafruit_seesaw.h"
Adafruit_seesaw ss;
int led = 6; // the PWM pin the LED is attached to
int brightness = 0; // how bright the LED is
int fadeAmount = 5; // how many points to fade the LED by
// the setup routine runs once when you press reset:
void setup() {
Serial.begin(115200);
while (!Serial) delay(10); // wait until serial port is opened
if(!ss.begin()){
Serial.println("seesaw not found!");
while(1) delay(10);
}
}
// the loop routine runs over and over again forever:
void loop() {
// set the brightness of the LED:
ss.analogWrite(led, brightness);
// change the brightness for next time through the loop:
brightness = brightness + fadeAmount;
// reverse the direction of the fading at the ends of the fade:
if (brightness <= 0 || brightness >= 255) {
fadeAmount = -fadeAmount;
}
// wait for 30 milliseconds to see the dimming effect
delay(30);
}

View File

@@ -0,0 +1,30 @@
/*
* This example shows how read the ADC on a seesaw.
* The default ADC pins on the SAMD09 Breakout are 2, 3, and 4.
*/
#include "Adafruit_seesaw.h"
Adafruit_seesaw ss;
// on SAMD09, analog in can be 2, 3, or 4
// on Attinyxy7, analog in can be 0-3, 6, 7, 18-20
// on Attinyxy6, analog in can be 0-5, 14-16
#define ANALOGIN 2
void setup() {
Serial.begin(115200);
while (!Serial) delay(10); // wait until serial port is opened
if(!ss.begin()){
Serial.println(F("seesaw not found!"));
while(1) delay(10);
}
Serial.println(F("seesaw started OK!"));
}
void loop() {
Serial.println(ss.analogRead(ANALOGIN));
delay(50);
}

View File

@@ -0,0 +1,45 @@
/*
Audio Spectrum.
This example shows how to set the audio sampling rate and read
audio spectrum data from a compatible Seesaw device.
*/
#include <seesaw_spectrum.h>
seesaw_Audio_Spectrum ss;
// The setup routine runs once when you press reset:
void setup() {
Serial.begin(115200);
while (!Serial) delay(10); // wait until serial port is opened
Serial.println("A");
if (!ss.begin()) {
Serial.println("seesaw not found!");
while(1) delay(10);
}
Serial.println("B");
// Configure audio sampling rate, which determines the peak
// frequency of the spectrum output. There are 32 possible values
// (0-31), where lower numbers = higher frequency.
// The corresponding frequency for each setting will depend on the
// F_CPU frequency on the Seesaw device, which has not yet been
// determined. 10 or 20 MHz would be ideal, but others may happen,
// so specific numbers are not documented here yet.
// If 10 or 20 MHz, value of 12 here maps to 6250 Hz:
ss.setRate(12);
}
// The loop routine runs over and over again forever:
void loop() {
ss.getData(); // Pull audio spectrum data from device
// Print contents of each of the 64 spectrum bins...
for (uint8_t i=0; i<64; i++) {
Serial.print(ss.getLevel(i));
Serial.write(' ');
}
Serial.println();
}

View File

@@ -0,0 +1,31 @@
//This example takes UART data given to the seesaw, reads it and then loops it back
#include "Adafruit_seesaw.h"
Adafruit_seesaw ss;
void setup()
{
Serial.begin(9600);
if(!ss.begin()){
Serial.println("ERROR!");
while(1) delay(1);
}
else Serial.println("seesaw started");
//enable interrupt
ss.enableSercomDataRdyInterrupt();
}
void loop()
{
if(!digitalRead(3)){
char c = ss.readSercomData();
Serial.print(c); //print to arduino console
//delay after reading data
delayMicroseconds(100);
ss.print(c); //send back to the seesaw to print
}
}

View File

@@ -0,0 +1,32 @@
/*
* This example shows how to blink a pin on a seesaw.
* It is written to use the built-in LED on the ATtiny817 breakout with seesaw.
*/
#include "Adafruit_seesaw.h"
Adafruit_seesaw ss;
#define BLINK_PIN 5
void setup() {
Serial.begin(115200);
while (!Serial) delay(10); // wait until serial port is opened
if(!ss.begin()){
Serial.println("seesaw not found!");
while(1) delay(10);
}
Serial.println(F("seesaw started OK!"));
ss.pinMode(BLINK_PIN, OUTPUT);
}
void loop() {
ss.digitalWrite(BLINK_PIN, LOW); // turn the LED on (the LED is tied low)
delay(1000); // wait for a second
ss.digitalWrite(BLINK_PIN, HIGH); // turn the LED off
delay(1000);
}

View File

@@ -0,0 +1,33 @@
/*
* This example shows how to blink a pin on a seesaw.
* Attach the positive (longer lead) of the LED to pin 15 on the seesaw, and
* the negative lead of the LED to ground through a 1k ohm resistor.
*/
#include "Adafruit_seesaw.h"
Adafruit_seesaw ss;
#define BLINK_PIN 15
void setup() {
Serial.begin(115200);
while (!Serial) delay(10); // wait until serial port is opened
if(!ss.begin()){
Serial.println("seesaw not found!");
while(1) delay(10);
}
Serial.println(F("seesaw started OK!"));
ss.pinMode(BLINK_PIN, OUTPUT);
}
void loop() {
ss.digitalWrite(BLINK_PIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(100); // wait for a second
ss.digitalWrite(BLINK_PIN, LOW); // turn the LED off by making the voltage LOW
delay(100);
}

View File

@@ -0,0 +1,39 @@
/*
* This example shows how set GPIO interrupts on a seesaw.
*/
#include "Adafruit_seesaw.h"
//connect the interrupt pin on the seesaw (pin 8 on samd09 breakout) to this pin on your arduino
#define INT_PIN 3
//the interrupt will fire when this pin on the seesaw changes state
#define SCAN_PIN 9
Adafruit_seesaw ss;
uint32_t mask = ((uint32_t)0b1 << SCAN_PIN);
void setup() {
Serial.begin(115200);
while (!Serial) delay(10); // wait until serial port is opened
if(!ss.begin()){
Serial.println(F("seesaw not found!"));
while(1) delay(10);
}
Serial.println(F("seesaw started OK!"));
pinMode(INT_PIN, INPUT_PULLUP);
ss.pinModeBulk(mask, INPUT_PULLUP);
ss.setGPIOInterrupts(mask, 1);
}
void loop() {
if(!digitalRead(INT_PIN)){
Serial.print(F("Interrupt fired! pin state: "));
Serial.println(ss.digitalRead(SCAN_PIN));
}
}

View File

@@ -0,0 +1,30 @@
/*
* This example shows how to blink multiple pins at once on a seesaw.
* pin 13 is attached to the LED on the samd11 xplained board
*/
#include "Adafruit_seesaw.h"
Adafruit_seesaw ss;
//blink pins PA11, PA12, PA13
uint32_t mask = ((uint32_t)0b111 << 11);
void setup() {
Serial.begin(115200);
if(!ss.begin()){
Serial.println("ERROR!");
while(1) delay(1);
}
else Serial.println("seesaw started");
ss.pinModeBulk(mask, OUTPUT); //set pin modes
}
void loop() {
ss.digitalWriteBulk(mask, HIGH); //set pins
delay(1000); // wait for a second
ss.digitalWriteBulk(mask, LOW); //clear pins
delay(1000);
}

View File

@@ -0,0 +1,27 @@
/*
* This example shows how to read multiple pins at once on a seesaw.
*/
#include "Adafruit_seesaw.h"
Adafruit_seesaw ss;
//read pins A8, A9, A10
uint32_t mask = ((uint32_t)0b111 << 8);
void setup() {
Serial.begin(9600);
if(!ss.begin()){
Serial.println("ERROR!");
while(1) delay(1);
}
else Serial.println("seesaw started");
ss.pinModeBulk(mask, INPUT);
}
void loop() {
Serial.println(ss.digitalReadBulk(mask), BIN);
delay(500);
}

View File

@@ -0,0 +1,101 @@
/*
* This is a demo for a QT Py RP2040 connected to an ANO encoder breakout and a 7-segment breakout
* using the onboard Stemma QT Port
* https://www.adafruit.com/product/878
* https://www.adafruit.com/product/5740
*
*/
#include "Adafruit_seesaw.h"
#include "Adafruit_LEDBackpack.h"
#define SS_SWITCH_SELECT 1
#define SS_SWITCH_UP 2
#define SS_SWITCH_LEFT 3
#define SS_SWITCH_DOWN 4
#define SS_SWITCH_RIGHT 5
#define SEESAW_ADDR 0x49
Adafruit_7segment seven = Adafruit_7segment();
Adafruit_seesaw ss = Adafruit_seesaw(&Wire1);
int32_t encoder_position;
void setup() {
Serial.begin(115200);
//while (!Serial) delay(10);
seven.begin(0x70, &Wire1);
Serial.println("Looking for seesaw!");
if (! ss.begin(SEESAW_ADDR)) {
Serial.println("Couldn't find seesaw on default address");
while(1) delay(10);
}
Serial.println("seesaw started");
uint32_t version = ((ss.getVersion() >> 16) & 0xFFFF);
if (version != 5740){
Serial.print("Wrong firmware loaded? ");
Serial.println(version);
while(1) delay(10);
}
Serial.println("Found Product 5740");
ss.pinMode(SS_SWITCH_UP, INPUT_PULLUP);
ss.pinMode(SS_SWITCH_DOWN, INPUT_PULLUP);
ss.pinMode(SS_SWITCH_LEFT, INPUT_PULLUP);
ss.pinMode(SS_SWITCH_RIGHT, INPUT_PULLUP);
ss.pinMode(SS_SWITCH_SELECT, INPUT_PULLUP);
// get starting position
encoder_position = ss.getEncoderPosition();
seven.print(encoder_position, DEC);
seven.writeDisplay();
Serial.println("Turning on interrupts");
ss.enableEncoderInterrupt();
ss.setGPIOInterrupts((uint32_t)1 << SS_SWITCH_UP, 1);
}
void loop() {
if (! ss.digitalRead(SS_SWITCH_UP)) {
seven.println(" UP ");
seven.writeDisplay();
Serial.println("UP pressed!");
}
else if (! ss.digitalRead(SS_SWITCH_DOWN)) {
seven.println("DOWN");
seven.writeDisplay();
Serial.println("DOWN pressed!");
}
else if (! ss.digitalRead(SS_SWITCH_SELECT)) {
seven.println("SELE");
seven.writeDisplay();
Serial.println("SELECT pressed!");
}
else if (! ss.digitalRead(SS_SWITCH_LEFT)) {
seven.println("LEFT");
seven.writeDisplay();
Serial.println("LEFT pressed!");
}
else if (! ss.digitalRead(SS_SWITCH_RIGHT)) {
seven.println("RIGT");
seven.writeDisplay();
Serial.println("RIGHT pressed!");
} else {
seven.print(encoder_position, DEC);
seven.writeDisplay();
}
int32_t new_position = ss.getEncoderPosition();
// did we move around?
if (encoder_position != new_position) {
Serial.println(new_position); // display new position
encoder_position = new_position; // and save for next round
}
// don't overwhelm serial port
delay(10);
}

View File

@@ -0,0 +1,83 @@
/*
* This example shows how to read from a seesaw encoder module.
* The available encoder API is:
* int32_t getEncoderPosition();
int32_t getEncoderDelta();
void enableEncoderInterrupt();
void disableEncoderInterrupt();
*/
#include "Adafruit_seesaw.h"
#define SS_SWITCH_SELECT 1
#define SS_SWITCH_UP 2
#define SS_SWITCH_LEFT 3
#define SS_SWITCH_DOWN 4
#define SS_SWITCH_RIGHT 5
#define SEESAW_ADDR 0x49
Adafruit_seesaw ss;
int32_t encoder_position;
void setup() {
Serial.begin(115200);
while (!Serial) delay(10);
Serial.println("Looking for seesaw!");
if (! ss.begin(SEESAW_ADDR)) {
Serial.println("Couldn't find seesaw on default address");
while(1) delay(10);
}
Serial.println("seesaw started");
uint32_t version = ((ss.getVersion() >> 16) & 0xFFFF);
if (version != 5740){
Serial.print("Wrong firmware loaded? ");
Serial.println(version);
while(1) delay(10);
}
Serial.println("Found Product 5740");
ss.pinMode(SS_SWITCH_UP, INPUT_PULLUP);
ss.pinMode(SS_SWITCH_DOWN, INPUT_PULLUP);
ss.pinMode(SS_SWITCH_LEFT, INPUT_PULLUP);
ss.pinMode(SS_SWITCH_RIGHT, INPUT_PULLUP);
ss.pinMode(SS_SWITCH_SELECT, INPUT_PULLUP);
// get starting position
encoder_position = ss.getEncoderPosition();
Serial.println("Turning on interrupts");
ss.enableEncoderInterrupt();
ss.setGPIOInterrupts((uint32_t)1 << SS_SWITCH_UP, 1);
}
void loop() {
if (! ss.digitalRead(SS_SWITCH_UP)) {
Serial.println("UP pressed!");
}
if (! ss.digitalRead(SS_SWITCH_DOWN)) {
Serial.println("DOWN pressed!");
}
if (! ss.digitalRead(SS_SWITCH_SELECT)) {
Serial.println("SELECT pressed!");
}
if (! ss.digitalRead(SS_SWITCH_LEFT)) {
Serial.println("LEFT pressed!");
}
if (! ss.digitalRead(SS_SWITCH_RIGHT)) {
Serial.println("RIGHT pressed!");
}
int32_t new_position = ss.getEncoderPosition();
// did we move around?
if (encoder_position != new_position) {
Serial.println(new_position); // display new position
encoder_position = new_position; // and save for next round
}
// don't overwhelm serial port
delay(10);
}

View File

@@ -0,0 +1,143 @@
/*
* This is a demo for a Feather ESP32-S2 TFT connected to a Quad
* Rotary Encoder board
* https://www.adafruit.com/product/5300
* https://www.adafruit.com/product/5752
*
*/
#include "Adafruit_seesaw.h"
#include <seesaw_neopixel.h>
#include <Adafruit_ST7789.h>
#include <Fonts/FreeSans12pt7b.h>
// we hvae loooots of PSRAM so lets use a GFX canvas for flicker-free graphics!
GFXcanvas16 canvas(240, 135);
Adafruit_ST7789 display = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
#define SS_NEO_PIN 18
#define SS_ENC0_SWITCH 12
#define SS_ENC1_SWITCH 14
#define SS_ENC2_SWITCH 17
#define SS_ENC3_SWITCH 9
#define SEESAW_ADDR 0x49
Adafruit_seesaw ss = Adafruit_seesaw(&Wire);
seesaw_NeoPixel pixels = seesaw_NeoPixel(4, SS_NEO_PIN, NEO_GRB + NEO_KHZ800);
int32_t enc_positions[4] = {0, 0, 0, 0};
void setup() {
Serial.begin(115200);
//while (!Serial) delay(10);
pinMode(TFT_BACKLITE, OUTPUT);
digitalWrite(TFT_BACKLITE, LOW);
// turn on the TFT / I2C power supply
pinMode(TFT_I2C_POWER, OUTPUT);
digitalWrite(TFT_I2C_POWER, HIGH);
delay(10);
Serial.println("Looking for seesaw!");
if (! ss.begin(SEESAW_ADDR) || !pixels.begin(SEESAW_ADDR)) {
Serial.println("Couldn't find seesaw on default address");
while(1) delay(10);
}
Serial.println("seesaw started");
uint32_t version = ((ss.getVersion() >> 16) & 0xFFFF);
if (version != 5752){
Serial.print("Wrong firmware loaded? ");
Serial.println(version);
while(1) delay(10);
}
Serial.println("Found Product 5752");
ss.pinMode(SS_ENC0_SWITCH, INPUT_PULLUP);
ss.pinMode(SS_ENC1_SWITCH, INPUT_PULLUP);
ss.pinMode(SS_ENC2_SWITCH, INPUT_PULLUP);
ss.pinMode(SS_ENC3_SWITCH, INPUT_PULLUP);
ss.setGPIOInterrupts(1UL << SS_ENC0_SWITCH | 1UL << SS_ENC1_SWITCH |
1UL << SS_ENC2_SWITCH | 1UL << SS_ENC3_SWITCH, 1);
// get starting positions
for (int e=0; e<4; e++) {
enc_positions[e] = ss.getEncoderPosition(e);
ss.enableEncoderInterrupt(e);
}
Serial.println("Turning on interrupts");
pixels.setBrightness(255);
pixels.show(); // Initialize all pixels to 'off'
display.init(135, 240); // Init ST7789 240x135
display.setRotation(3);
display.fillScreen(ST77XX_BLUE);
digitalWrite(TFT_BACKLITE, HIGH);
canvas.setFont(&FreeSans12pt7b);
canvas.setTextColor(ST77XX_WHITE);
}
uint8_t switch_pins[] = {SS_ENC0_SWITCH, SS_ENC1_SWITCH, SS_ENC2_SWITCH, SS_ENC3_SWITCH};
void loop() {
bool changed = false;
canvas.fillScreen(ST77XX_BLACK);
canvas.setCursor(0, 25);
canvas.setTextColor(ST77XX_WHITE);
//canvas.println("Quad Encoder QT Demo");
for (int e=0; e<4; e++) {
int32_t new_enc_position = ss.getEncoderPosition(e);
// did we move around?
if (enc_positions[e] != new_enc_position) {
Serial.print("Rot. #");
Serial.print(e);
Serial.print(" -> ");
Serial.println(new_enc_position); // display new position
enc_positions[e] = new_enc_position; // and save for next round
// change the neopixel color, mulitply the new positiion by 4 to speed it up
pixels.setPixelColor(e, Wheel((new_enc_position*4) & 0xFF));
pixels.show();
changed = true;
}
canvas.setTextColor(ST77XX_WHITE);
canvas.print("Rotary #");
canvas.print(e);
canvas.print(": ");
canvas.print(enc_positions[e]);
if (! ss.digitalRead(switch_pins[e])) {
Serial.print("ENC");
Serial.print("e");
Serial.println("pressed!");
canvas.setTextColor(ST77XX_RED);
canvas.print(" DOWN");
changed = true;
}
canvas.println();
}
if (changed) {
display.drawRGBBitmap(0, 0, canvas.getBuffer(), 240, 135);
}
}
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if (WheelPos < 85) {
return seesaw_NeoPixel::Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if (WheelPos < 170) {
WheelPos -= 85;
return seesaw_NeoPixel::Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return seesaw_NeoPixel::Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

View File

@@ -0,0 +1,111 @@
/*
* This is a demo for a QT Py RP2040 connected to a quad rotary encoder breakout
* using the onboard Stemma QT Port
* https://www.adafruit.com/product/4900
* https://www.adafruit.com/product/5752
*
*/
#include "Adafruit_seesaw.h"
#include <seesaw_neopixel.h>
#define SS_NEO_PIN 18
#define SS_ENC0_SWITCH 12
#define SS_ENC1_SWITCH 14
#define SS_ENC2_SWITCH 17
#define SS_ENC3_SWITCH 9
#define SEESAW_ADDR 0x49
Adafruit_seesaw ss = Adafruit_seesaw(&Wire);
seesaw_NeoPixel pixels = seesaw_NeoPixel(4, SS_NEO_PIN, NEO_GRB + NEO_KHZ800);
int32_t enc_positions[4] = {0, 0, 0, 0};
void setup() {
Serial.begin(115200);
while (!Serial) delay(10);
Serial.println("Looking for seesaw!");
if (! ss.begin(SEESAW_ADDR) || !pixels.begin(SEESAW_ADDR)) {
Serial.println("Couldn't find seesaw on default address");
while(1) delay(10);
}
Serial.println("seesaw started");
uint32_t version = ((ss.getVersion() >> 16) & 0xFFFF);
if (version != 5752){
Serial.print("Wrong firmware loaded? ");
Serial.println(version);
while(1) delay(10);
}
Serial.println("Found Product 5752");
ss.pinMode(SS_ENC0_SWITCH, INPUT_PULLUP);
ss.pinMode(SS_ENC1_SWITCH, INPUT_PULLUP);
ss.pinMode(SS_ENC2_SWITCH, INPUT_PULLUP);
ss.pinMode(SS_ENC3_SWITCH, INPUT_PULLUP);
ss.setGPIOInterrupts(1UL << SS_ENC0_SWITCH | 1UL << SS_ENC1_SWITCH |
1UL << SS_ENC2_SWITCH | 1UL << SS_ENC3_SWITCH, 1);
// get starting positions
for (int e=0; e<4; e++) {
enc_positions[e] = ss.getEncoderPosition(e);
ss.enableEncoderInterrupt(e);
}
Serial.println("Turning on interrupts");
pixels.setBrightness(255);
pixels.show(); // Initialize all pixels to 'off'
}
void loop() {
if (! ss.digitalRead(SS_ENC0_SWITCH)) {
Serial.println("ENC0 pressed!");
}
if (! ss.digitalRead(SS_ENC1_SWITCH)) {
Serial.println("ENC1 pressed!");
}
if (! ss.digitalRead(SS_ENC2_SWITCH)) {
Serial.println("ENC2 pressed!");
}
if (! ss.digitalRead(SS_ENC3_SWITCH)) {
Serial.println("ENC3 pressed!");
}
for (int e=0; e<4; e++) {
int32_t new_enc_position = ss.getEncoderPosition(e);
// did we move around?
if (enc_positions[e] != new_enc_position) {
Serial.print("Encoder #");
Serial.print(e);
Serial.print(" -> ");
Serial.println(new_enc_position); // display new position
enc_positions[e] = new_enc_position; // and save for next round
// change the neopixel color, mulitply the new positiion by 4 to speed it up
pixels.setPixelColor(e, Wheel((new_enc_position*4) & 0xFF));
pixels.show();
}
}
// don't overwhelm serial port
delay(10);
}
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if (WheelPos < 85) {
return seesaw_NeoPixel::Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if (WheelPos < 170) {
WheelPos -= 85;
return seesaw_NeoPixel::Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return seesaw_NeoPixel::Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

View File

@@ -0,0 +1,91 @@
/*
* This example shows how to read from a seesaw encoder module.
* The available encoder API is:
* int32_t getEncoderPosition();
int32_t getEncoderDelta();
void enableEncoderInterrupt();
void disableEncoderInterrupt();
void setEncoderPosition(int32_t pos);
*/
#include "Adafruit_seesaw.h"
#include <seesaw_neopixel.h>
#define SS_SWITCH 24
#define SS_NEOPIX 6
#define SEESAW_ADDR 0x36
Adafruit_seesaw ss;
seesaw_NeoPixel sspixel = seesaw_NeoPixel(1, SS_NEOPIX, NEO_GRB + NEO_KHZ800);
int32_t encoder_position;
void setup() {
Serial.begin(115200);
while (!Serial) delay(10);
Serial.println("Looking for seesaw!");
if (! ss.begin(SEESAW_ADDR) || ! sspixel.begin(SEESAW_ADDR)) {
Serial.println("Couldn't find seesaw on default address");
while(1) delay(10);
}
Serial.println("seesaw started");
uint32_t version = ((ss.getVersion() >> 16) & 0xFFFF);
if (version != 4991){
Serial.print("Wrong firmware loaded? ");
Serial.println(version);
while(1) delay(10);
}
Serial.println("Found Product 4991");
// set not so bright!
sspixel.setBrightness(20);
sspixel.show();
// use a pin for the built in encoder switch
ss.pinMode(SS_SWITCH, INPUT_PULLUP);
// get starting position
encoder_position = ss.getEncoderPosition();
Serial.println("Turning on interrupts");
delay(10);
ss.setGPIOInterrupts((uint32_t)1 << SS_SWITCH, 1);
ss.enableEncoderInterrupt();
}
void loop() {
if (! ss.digitalRead(SS_SWITCH)) {
Serial.println("Button pressed!");
}
int32_t new_position = ss.getEncoderPosition();
// did we move arounde?
if (encoder_position != new_position) {
Serial.println(new_position); // display new position
// change the neopixel color
sspixel.setPixelColor(0, Wheel(new_position & 0xFF));
sspixel.show();
encoder_position = new_position; // and save for next round
}
// don't overwhelm serial port
delay(10);
}
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if (WheelPos < 85) {
return sspixel.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if (WheelPos < 170) {
WheelPos -= 85;
return sspixel.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return sspixel.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

View File

@@ -0,0 +1,160 @@
/* Demo with 128x64 OLED display and multiple I2C encoders wired up. The sketch will auto-
* detect up to 4 encoder on the first 4 addresses. Twisting will display text on OLED
* and change neopixel color.
* set USE_OLED to true t
*/
#define USE_OLED false // set to false to skip the OLED, true to use it!
#include "Adafruit_seesaw.h"
#include <seesaw_neopixel.h>
#if USE_OLED
#include <Adafruit_SH110X.h>
#include <Fonts/FreeSans9pt7b.h>
Adafruit_SH1107 display = Adafruit_SH1107(64, 128, &Wire);
#endif
#define SS_SWITCH 24 // this is the pin on the encoder connected to switch
#define SS_NEOPIX 6 // this is the pin on the encoder connected to neopixel
#define SEESAW_BASE_ADDR 0x36 // I2C address, starts with 0x36
// create 4 encoders!
Adafruit_seesaw encoders[4];
// create 4 encoder pixels
seesaw_NeoPixel encoder_pixels[4] = {
seesaw_NeoPixel(1, SS_NEOPIX, NEO_GRB + NEO_KHZ800),
seesaw_NeoPixel(1, SS_NEOPIX, NEO_GRB + NEO_KHZ800),
seesaw_NeoPixel(1, SS_NEOPIX, NEO_GRB + NEO_KHZ800),
seesaw_NeoPixel(1, SS_NEOPIX, NEO_GRB + NEO_KHZ800)};
int32_t encoder_positions[] = {0, 0, 0, 0};
bool found_encoders[] = {false, false, false, false};
void setup() {
Serial.begin(115200);
// wait for serial port to open
while (!Serial) delay(10);
Serial.println("128x64 OLED + seesaw Encoders test");
#if USE_OLED
display.begin(0x3C, true); // Address 0x3C default
Serial.println("OLED begun");
display.display();
delay(500); // Pause for half second
display.setRotation(1);
display.setFont(&FreeSans9pt7b);
display.setTextColor(SH110X_WHITE);
#endif
Serial.println("Looking for seesaws!");
for (uint8_t enc=0; enc<sizeof(found_encoders); enc++) {
// See if we can find encoders on this address
if (! encoders[enc].begin(SEESAW_BASE_ADDR + enc) ||
! encoder_pixels[enc].begin(SEESAW_BASE_ADDR + enc)) {
Serial.print("Couldn't find encoder #");
Serial.println(enc);
} else {
Serial.print("Found encoder + pixel #");
Serial.println(enc);
uint32_t version = ((encoders[enc].getVersion() >> 16) & 0xFFFF);
if (version != 4991){
Serial.print("Wrong firmware loaded? ");
Serial.println(version);
while(1) delay(10);
}
Serial.println("Found Product 4991");
// use a pin for the built in encoder switch
encoders[enc].pinMode(SS_SWITCH, INPUT_PULLUP);
// get starting position
encoder_positions[enc] = encoders[enc].getEncoderPosition();
Serial.println("Turning on interrupts");
delay(10);
encoders[enc].setGPIOInterrupts((uint32_t)1 << SS_SWITCH, 1);
encoders[enc].enableEncoderInterrupt();
// set not so bright!
encoder_pixels[enc].setBrightness(30);
encoder_pixels[enc].show();
found_encoders[enc] = true;
}
}
Serial.println("Encoders started");
}
void loop() {
#if USE_OLED
display.clearDisplay();
uint16_t display_line = 1;
#endif
for (uint8_t enc=0; enc<sizeof(found_encoders); enc++) {
if (found_encoders[enc] == false) continue;
int32_t new_position = encoders[enc].getEncoderPosition();
// did we move around?
if (encoder_positions[enc] != new_position) {
Serial.print("Encoder #");
Serial.print(enc);
Serial.print(" -> ");
Serial.println(new_position); // display new position
encoder_positions[enc] = new_position;
// change the neopixel color, mulitply the new positiion by 4 to speed it up
encoder_pixels[enc].setPixelColor(0, Wheel((new_position*4) & 0xFF));
encoder_pixels[enc].show();
}
#if USE_OLED
// draw the display
display.setCursor(0, 20*display_line++);
display.print("Enc #");
display.print(enc);
display.print(" : ");
display.print(encoder_positions[enc]);
#endif
if (! encoders[enc].digitalRead(SS_SWITCH)) {
Serial.print("Encoder #");
Serial.print(enc);
Serial.println(" pressed");
#if USE_OLED
display.print(" P");
#endif
}
}
#if USE_OLED
display.display();
#endif
// don't overwhelm serial port
yield();
delay(10);
}
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if (WheelPos < 85) {
return seesaw_NeoPixel::Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if (WheelPos < 170) {
WheelPos -= 85;
return seesaw_NeoPixel::Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return seesaw_NeoPixel::Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

View File

@@ -0,0 +1,64 @@
/*
* This example helps demonstrates getEncoderDelta().
*
* position = the current encoder position
* delta = the change in position since last read
*
* With this sketch running, open the Serial Monitor. It may also help
* to turn on "Show timestamp". Then play with turning the encoder between
* print outs to see how the values change.
*
* If the encoder does ~not~ move between reads, then:
* - position will be the same value
* - delta will be zero
*
* NOTE: reading position or delta resets delta to zero
*/
#include "Adafruit_seesaw.h"
#include <seesaw_neopixel.h>
#define SEESAW_ADDR 0x36
Adafruit_seesaw ss;
void setup() {
Serial.begin(115200);
while (!Serial) delay(10);
Serial.println("Looking for seesaw!");
if (! ss.begin(SEESAW_ADDR)) {
Serial.println("Couldn't find seesaw on default address");
while(1) delay(10);
}
Serial.println("seesaw started");
uint16_t pid;
uint8_t year, mon, day;
ss.getProdDatecode(&pid, &year, &mon, &day);
Serial.print("PID: "); Serial.println(pid);
Serial.print("Firmware:");
Serial.print(2000+year); Serial.print("/");
Serial.print(mon); Serial.print("/");
Serial.println(day);
}
void loop() {
int32_t position;
int32_t delta;
// get delta and position
delta = ss.getEncoderDelta(); // also resets delta to zero
position = ss.getEncoderPosition(); // this also resets delta to zero
// so getEncoderDelta() is called first
// print info
Serial.print("position: "); Serial.println(position);
Serial.print(" delta: "); Serial.println(delta);
// read once every two seconds
// this is intentionally slow to allow user to easily turn encoder between reads
delay(2000);
}

View File

@@ -0,0 +1,291 @@
// This code is only for use with ESP chips and demonstrates how to perform background operations against the I2C bus to
// communicate with the Joy Featherwing peripheral in a non-blocking fashion. As ESP's FreeRTOS does not play nicely with
// performing operations against I2C from within an ISR, a queue is used to signal to a worker task that a button has been
// pressed rather than reading from I2C within the ISR itself. To read from the analog controller, a separate task running
// in a loop polls for changes. It also attempts to calibrate the controller and deterine a center point while compensating
// for any controller drift. All operations over I2C are synchronized with a semaphore to prevent crashes or corruption
// resulting from concurrent operations as the Wire library is not thread safe.
#if !defined(ESP8266) && !defined(ESP32)
#error This sketch only supports ESP32 and ESP8266
#endif // ESP8266 / ESP32
#include "Adafruit_seesaw.h"
// This can be enabled to get extra logging about the position of the controller relative to the correction values
//#define JOY_CALIBRATION_MODE
// This sketch requires that one of the optional interrupt pins on the Joy Featherwing is soldered. This value should match the
// complimentary GPIO pin on the ESP device. See: https://learn.adafruit.com/joy-featherwing/pinouts
#define IRQ_PIN 14 // Pin 14 is the pin directly to the left of the SCL pin on an ESP32
Adafruit_seesaw ss;
// GPIO pins on the Joy Featherwing for reading button presses. These should not be changed.
#define BUTTON_RIGHT 6
#define BUTTON_DOWN 7
#define BUTTON_LEFT 9
#define BUTTON_UP 10
#define BUTTON_SEL 14
// GPIO Analog pins on the Joy Featherwing for reading the analog stick. These should not be changed.
#define STICK_H 3
#define STICK_V 2
// When the analog stick is moved and returns to its center point there may be a deviation from the true center of 512. A calibration will
// occur when the analog stick read task begins. Even after this calibration there may be some drift on the stick that can make determining
// the center point error prone. In order to compensate for this, values can be specified to determine a reasonable center point. If you have
// a use case where you don't care about drift or the center point of the stick, this can all be ignored entirely.
#ifndef STICK_CENTER_POINT
#define STICK_CENTER_POINT 512 // Analog stick will read 0...1024 along each axis
#endif
#ifndef STICK_L_CORRECTION
#define STICK_L_CORRECTION -55
#endif
#ifndef STICK_R_CORRECTION
#define STICK_R_CORRECTION 50
#endif
#ifndef STICK_U_CORRECTION
#define STICK_U_CORRECTION 20
#endif
#ifndef STICK_D_CORRECTION
#define STICK_D_CORRECTION -20
#endif
// Every time the analog values are read they will be slightly different. In order
// to only detect movement when the stick is actually moved, these values can tune
// the minimum amount of movement + or - before it is considered as moved.
#ifndef MIN_STICK_H_MOVE
#define MIN_STICK_H_MOVE 5
#endif
#ifndef MIN_STICK_V_MOVE
#define MIN_STICK_V_MOVE 5
#endif
uint32_t button_mask = (1 << BUTTON_RIGHT) | (1 << BUTTON_DOWN) |
(1 << BUTTON_LEFT) | (1 << BUTTON_UP) | (1 << BUTTON_SEL);
QueueHandle_t buttonPressQueue; // Queue for notifying of button press changes
SemaphoreHandle_t i2cSem = xSemaphoreCreateBinary(); // This semaphore is used to synchronize calls to I2C to prevent concurrent operations
// ISR that gets triggered when a button is pressed.
void IRAM_ATTR onButtonPress()
{
// The ISR just sends a signal to the queue. Value doesn't matter.
uint8_t v = 0;
if (!xQueueSend(buttonPressQueue, &v, portMAX_DELAY))
{
Serial.println("WARNING: Could not queue message because queue is full.");
}
}
// Log the pressed buttons to the serial port
void outputPressedButtons(uint32_t mask)
{
#ifdef JOY_DEBUG
Serial.print("Mask: ");
Serial.println(mask, BIN);
#endif
if (!(mask & (1 << BUTTON_RIGHT)))
{
Serial.println(F("Button A pressed"));
}
if (!(mask & (1 << BUTTON_DOWN)))
{
Serial.println(F("Button B pressed"));
}
if (!(mask & (1 << BUTTON_LEFT)))
{
Serial.println(F("Button Y pressed"));
}
if (!(mask & (1 << BUTTON_UP)))
{
Serial.println(F("Button X pressed"));
}
if (!(mask & (1 << BUTTON_SEL)))
{
Serial.println(F("Button SEL pressed"));
}
}
// Queue consumer for responding to button presses
void buttonPressConsumer(void *)
{
Serial.println(F("buttonPressConsumer() begin"));
uint32_t lastValue = 0;
while (true)
{
void *p; // Don't care about this value, only that we get queued
// This will yield until the queue gets signalled
xQueueReceive(buttonPressQueue, &p, portMAX_DELAY);
xSemaphoreTake(i2cSem, portMAX_DELAY);
uint32_t v = ss.digitalReadBulk(button_mask);
// Debounce by discarding duplicate reads
if (lastValue != v)
{
outputPressedButtons(v);
lastValue = v;
}
xSemaphoreGive(i2cSem);
}
vTaskDelete(NULL);
}
void analogStickTask(void *)
{
Serial.println(F("analogStickTask() begin"));
int16_t x_ctr, y_ctr;
xSemaphoreTake(i2cSem, portMAX_DELAY);
x_ctr = ss.analogRead(STICK_H);
y_ctr = ss.analogRead(STICK_V);
xSemaphoreGive(i2cSem);
Serial.printf("Initial center point x=%d y=%d\n", x_ctr, y_ctr);
Serial.printf("Calibration values:\n\tCenter point: x=%d y=%d\n\tCorrections: u=%d d=%d l=%d r=%d\n\tCenter range: x=%d...%d y=%d...%d\n",
x_ctr,
y_ctr,
STICK_U_CORRECTION,
STICK_D_CORRECTION,
STICK_L_CORRECTION,
STICK_R_CORRECTION,
x_ctr + STICK_L_CORRECTION,
x_ctr + STICK_R_CORRECTION,
y_ctr + STICK_U_CORRECTION,
y_ctr + STICK_D_CORRECTION);
int16_t x = -1;
int16_t y = -1;
bool isCentered = true;
while (true)
{
xSemaphoreTake(i2cSem, portMAX_DELAY);
int16_t new_x = ss.analogRead(STICK_H);
int16_t new_y = ss.analogRead(STICK_V);
xSemaphoreGive(i2cSem);
// Ignore minute position changes as the values will change slightly with
// every read. This can be tuned with MIN_STICK_H_MOVE and MIN_STICK_V_MOVE
if (new_x <= x - MIN_STICK_H_MOVE ||
new_x >= x + MIN_STICK_H_MOVE ||
new_y <= y - MIN_STICK_V_MOVE ||
new_y >= y + MIN_STICK_V_MOVE)
{
#ifdef JOY_CALIBRATION_MODE
Serial.printf("x=%d xc=%d x+c(L)=%d x+c(R)=%d <=%d >=%d\n",
new_x,
x_ctr,
new_x + STICK_L_CORRECTION,
new_x + STICK_R_CORRECTION,
x_ctr >= new_x + STICK_L_CORRECTION,
x_ctr <= new_x + STICK_R_CORRECTION);
Serial.printf("y=%d yc=%d y+c(U)=%d y-c(D)=%d <=%d >=%d\n",
new_y,
y_ctr,
new_y + STICK_U_CORRECTION,
new_y + STICK_D_CORRECTION,
y_ctr <= new_y + STICK_U_CORRECTION,
y_ctr >= new_y + STICK_D_CORRECTION);
#endif
// Make a best effort guess as to if the stick is centered or not based on
// initial calibration and corrections
isCentered = x_ctr >= max(0, new_x + STICK_L_CORRECTION) &&
x_ctr <= max(0, new_x + STICK_R_CORRECTION) &&
y_ctr <= max(0, new_y + STICK_U_CORRECTION) &&
y_ctr >= max(0, new_y + STICK_D_CORRECTION);
// Ensure value is always 0...1024 and account for any corrections and/or calibrations to prevent over/underflows
x = new_x < 0 ? 0 : new_x > 1024 ? 1024
: new_x;
y = new_y < 0 ? 0 : new_y > 1024 ? 1024
: new_y;
double x_rad = x / 4 - 128;
double y_rad = y / 4 - 128;
double angle = -atan2(-x_rad, y_rad) * (180.0 / PI);
double velocity = sqrt(pow(x_rad, 2) + pow(y_rad, 2));
// Log the position of the analog stick in various ways for different kinds of application
Serial.printf("Analog stick position change!\n\tIs centered: %s\n\tPosition: X=%d Y=%d\n\tRadian: X=%f Y=%f\n\tDegrees: %f\n\tPosition from center: %f\n",
isCentered ? "true" : "false",
x, y,
x_rad, y_rad,
angle,
velocity);
}
// Tune this to be quick enough to read the controller position in a reasonable amount of time but not so fast that it
// saturates the I2C bus and delays or blocks other operations.
delay(100);
}
vTaskDelete(NULL);
}
void setup()
{
Serial.begin(115200);
while (!Serial)
{
delay(10);
}
Serial.println("Joy FeatherWing example!");
if (!ss.begin(0x49))
{
Serial.println("ERROR! seesaw not found");
while (1)
{
delay(1);
}
}
else
{
Serial.println("seesaw started");
Serial.print("version: ");
Serial.println(ss.getVersion(), HEX);
}
ss.pinModeBulk(button_mask, INPUT_PULLUP);
ss.setGPIOInterrupts(button_mask, 1);
pinMode(IRQ_PIN, INPUT);
xSemaphoreGive(i2cSem); // Initialize the semaphore to 0 (default state is uninitialized which will cause a crash)
buttonPressQueue = xQueueCreate(10, sizeof(uint8_t));
// Task for listening to button presses
xTaskCreate(
buttonPressConsumer,
"ButtonPressConsumer",
10000, // Stack size -- too low and ESP will eventually crash within the task
NULL,
1,
NULL);
// Task for reading the analog stick value
xTaskCreate(
analogStickTask,
"AnalogStickTask",
10000, // Stack size -- too low and ESP will eventually crash within the task
NULL,
2,
NULL);
// Respond to changes from button presses
attachInterrupt(IRQ_PIN, onButtonPress, FALLING);
}
void loop()
{
// Do nothing. Everything we're doing here is in a Task
delay(10000);
}

View File

@@ -0,0 +1,86 @@
#include "Adafruit_seesaw.h"
Adafruit_seesaw ss;
#define BUTTON_RIGHT 6
#define BUTTON_DOWN 7
#define BUTTON_LEFT 9
#define BUTTON_UP 10
#define BUTTON_SEL 14
uint32_t button_mask = (1 << BUTTON_RIGHT) | (1 << BUTTON_DOWN) |
(1 << BUTTON_LEFT) | (1 << BUTTON_UP) | (1 << BUTTON_SEL);
#if defined(ESP8266)
#define IRQ_PIN 2
#elif defined(ESP32) && !defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S2)
#define IRQ_PIN 14
#elif defined(ARDUINO_NRF52832_FEATHER)
#define IRQ_PIN 27
#elif defined(TEENSYDUINO)
#define IRQ_PIN 8
#elif defined(ARDUINO_ARCH_WICED)
#define IRQ_PIN PC5
#else
#define IRQ_PIN 5
#endif
void setup() {
Serial.begin(115200);
while(!Serial) {
delay(10);
}
Serial.println("Joy FeatherWing example!");
if(!ss.begin(0x49)){
Serial.println("ERROR! seesaw not found");
while(1) delay(1);
} else {
Serial.println("seesaw started");
Serial.print("version: ");
Serial.println(ss.getVersion(), HEX);
}
ss.pinModeBulk(button_mask, INPUT_PULLUP);
ss.setGPIOInterrupts(button_mask, 1);
pinMode(IRQ_PIN, INPUT);
}
int last_x = 0, last_y = 0;
void loop() {
int x = ss.analogRead(2);
int y = ss.analogRead(3);
if ( (abs(x - last_x) > 3) || (abs(y - last_y) > 3)) {
Serial.print(x); Serial.print(", "); Serial.println(y);
last_x = x;
last_y = y;
}
/* if(!digitalRead(IRQ_PIN)) { // Uncomment to use IRQ */
uint32_t buttons = ss.digitalReadBulk(button_mask);
//Serial.println(buttons, BIN);
if (! (buttons & (1 << BUTTON_RIGHT))) {
Serial.println("Button A pressed");
}
if (! (buttons & (1 << BUTTON_DOWN))) {
Serial.println("Button B pressed");
}
if (! (buttons & (1 << BUTTON_LEFT))) {
Serial.println("Button Y pressed");
}
if (! (buttons & (1 << BUTTON_UP))) {
Serial.println("Button X pressed");
}
if (! (buttons & (1 << BUTTON_SEL))) {
Serial.println("Button SEL pressed");
}
/* } // Uncomment to use IRQ */
delay(10);
}

View File

@@ -0,0 +1,149 @@
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SPI.h>
#include "Adafruit_seesaw.h"
Adafruit_seesaw ss;
#define BUTTON_RIGHT 6
#define BUTTON_DOWN 7
#define BUTTON_LEFT 9
#define BUTTON_UP 10
#define BUTTON_START 14
uint32_t button_mask = (1 << BUTTON_RIGHT) | (1 << BUTTON_DOWN) |
(1 << BUTTON_LEFT) | (1 << BUTTON_UP) | (1 << BUTTON_START);
#if defined(ESP8266)
#define IRQ_PIN 2
#elif defined(ESP32) && !defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S2)
#define IRQ_PIN 14
#elif defined(ARDUINO_NRF52832_FEATHER)
#define IRQ_PIN 27
#elif defined(TEENSYDUINO)
#define IRQ_PIN 8
#elif defined(ARDUINO_ARCH_WICED)
#define IRQ_PIN PC5
#else
#define IRQ_PIN 5
#endif
// For the breakout, you can use any 2 or 3 pins
// These pins will also work for the 1.8" TFT shield
#define TFT_CS 6
#define TFT_DC 10
#define TFT_RST 9 // you can also connect this to the Arduino reset
// in which case, set this #define pin to -1!
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
void setup() {
//while (!Serial);
Serial.begin(115200);
if(!ss.begin(0x49)){
Serial.println("ERROR!");
while(1) delay(1);
}
else{
Serial.println("seesaw started");
Serial.print("version: ");
Serial.println(ss.getVersion(), HEX);
}
ss.pinModeBulk(button_mask, INPUT_PULLUP);
ss.setGPIOInterrupts(button_mask, 1);
pinMode(IRQ_PIN, INPUT);
Serial.println(F("TFT TIME"));
tft.initR(INITR_MINI160x80); // initialize a ST7735S chip, mini display
Serial.println("Initialized");
tft.setRotation(1);
uint16_t time = millis();
tft.fillScreen(ST7735_BLACK);
time = millis() - time;
Serial.println(time, DEC);
delay(500);
// large block of text
tft.fillScreen(ST7735_BLACK);
}
int last_x = 0, last_y = 0;
void loop() {
int y = ss.analogRead(2);
int x = ss.analogRead(3);
if(x > 600 && last_x < 600){
tft.fillTriangle(120, 30, 120, 50, 110, 40, ST7735_WHITE);
Serial.println(F("LEFT"));
}
else if(last_x > 600 && x < 600){
tft.fillTriangle(120, 30, 120, 50, 110, 40, ST7735_BLACK);
}
if(x < 400 && last_x > 400){
tft.fillTriangle(150, 30, 150, 50, 160, 40, ST7735_WHITE);
Serial.println(F("RIGHT"));
}
else if(last_x < 400 && x > 400){
tft.fillTriangle(150, 30, 150, 50, 160, 40, ST7735_BLACK);
}
if(y > 600 && last_y < 600){
tft.fillTriangle(125, 26, 145, 26, 135, 16, ST7735_WHITE);
Serial.println(F("DOWN"));
}
else if(last_y > 600 && y < 600){
tft.fillTriangle(125, 26, 145, 26, 135, 16, ST7735_BLACK);
}
if(y < 400 && last_y > 400){
tft.fillTriangle(125, 53, 145, 53, 135, 63, ST7735_WHITE);
Serial.println(F("UP"));
}
else if(last_y < 400 && y > 400){
tft.fillTriangle(125, 53, 145, 53, 135, 63, ST7735_BLACK);
}
if ( (abs(x - last_x) > 3) || (abs(y - last_y) > 3)) {
Serial.print(x); Serial.print(", "); Serial.println(y);
last_x = x;
last_y = y;
}
if(!digitalRead(IRQ_PIN)){
uint32_t buttons = ss.digitalReadBulk(button_mask);
//Serial.println(buttons, BIN);
if (! (buttons & (1 << BUTTON_DOWN))) {
tft.fillCircle(30, 18, 10, ST7735_GREEN);
Serial.println("B");
}
else tft.fillCircle(30, 18, 10, ST7735_BLACK);
if (! (buttons & (1 << BUTTON_RIGHT))) {
tft.fillCircle(10, 40, 10, ST7735_RED);
Serial.println("A");
}
else tft.fillCircle(10, 40, 10, ST7735_BLACK);
if (! (buttons & (1 << BUTTON_LEFT))) {
tft.fillCircle(50, 40, 10, ST7735_BLUE);
Serial.println("Y");
}
else tft.fillCircle(50, 40, 10, ST7735_BLACK);
if (! (buttons & (1 << BUTTON_UP))) {
tft.fillCircle(30, 57, 10, ST7735_YELLOW);
Serial.println("X");
}
else tft.fillCircle(30, 57, 10, ST7735_BLACK);
if (! (buttons & (1 << BUTTON_START))) {
tft.fillCircle(80, 40, 7, ST7735_WHITE);
Serial.println(F("START"));
}
else tft.fillCircle(80, 40, 7, ST7735_BLACK);
}
delay(10);
}

View File

@@ -0,0 +1,26 @@
#include "Adafruit_seesaw.h"
Adafruit_seesaw ss;
void setup() {
Serial.begin(115200);
Serial.println("seesaw Soil Sensor example!");
if (!ss.begin(0x36)) {
Serial.println("ERROR! seesaw not found");
while(1) delay(1);
} else {
Serial.print("seesaw started! version: ");
Serial.println(ss.getVersion(), HEX);
}
}
void loop() {
float tempC = ss.getTemp();
uint16_t capread = ss.touchRead(0);
Serial.print("Temperature: "); Serial.print(tempC); Serial.println("*C");
Serial.print("Capacitive: "); Serial.println(capread);
delay(100);
}

View File

@@ -0,0 +1,10 @@
name=Adafruit seesaw Library
version=1.7.8
author=Adafruit
maintainer=Adafruit <info@adafruit.com>
sentence=This is a library for the Adafruit seesaw helper IC.
paragraph=This is a library for the Adafruit seesaw helper IC.
category=Other
url=https://github.com/adafruit/Adafruit_Seesaw
architectures=*
depends=Adafruit BusIO, Adafruit ST7735 and ST7789 Library

View File

@@ -0,0 +1,82 @@
#ifndef _SEESAW_MOTOR_H
#define _SEESAW_MOTOR_H
#include "Adafruit_seesaw.h"
/**************************************************************************/
/*!
@brief Class that stores state and functions for seesaw motor interface
*/
/**************************************************************************/
class seesaw_Motor {
public:
/**************************************************************************/
/*!
@brief class constructor
@param ss the seesaw object to use
*/
/**************************************************************************/
seesaw_Motor(Adafruit_seesaw *ss) {
_ss = ss;
_pina = -1;
_pinb = -1;
_throttle = 0;
}
~seesaw_Motor() {}
/**************************************************************************/
/*!
@brief attach the motor to the specified PWM pins
@param pina the positive pin to use
@param pinb the negative pin to use
*/
/**************************************************************************/
void attach(int pina, int pinb) {
_pina = pina;
_pinb = pinb;
}
/**************************************************************************/
/*!
@brief set the throttle
@param value the throttle value to set between -1 and 1. Passing 0 will turn
the motor off.
*/
/**************************************************************************/
void throttle(float value) {
if (_pina < 0 || _pinb < 0)
return;
value = constrain(value, -1.0, 1.0);
_throttle = value;
uint16_t absolute = fabs(value) * 65535;
if (value > 0) {
_ss->analogWrite(_pina, 0);
_ss->analogWrite(_pinb, absolute);
} else if (value < 0) {
_ss->analogWrite(_pina, absolute);
_ss->analogWrite(_pinb, 0);
} else {
// both are off
_ss->analogWrite(_pina, 0);
_ss->analogWrite(_pinb, 0);
}
}
/**************************************************************************/
/*!
@brief get the current throttle value
@returns the current throttle value between -1 and 1
*/
/**************************************************************************/
float getThrottle() { return _throttle; }
private:
Adafruit_seesaw *_ss;
int8_t _pina, _pinb;
float _throttle;
};
#endif

View File

@@ -0,0 +1,297 @@
/*-------------------------------------------------------------------------
Arduino library to control a wide variety of WS2811- and WS2812-based RGB
LED devices such as Adafruit FLORA RGB Smart Pixels and NeoPixel strips.
Currently handles 400 and 800 KHz bitstreams on 8, 12 and 16 MHz ATmega
MCUs, with LEDs wired for various color orders. Handles most output pins
(possible exception with upper PORT registers on the Arduino Mega).
Written by Phil Burgess / Paint Your Dragon for Adafruit Industries,
contributions by PJRC, Michael Miller and other members of the open
source community.
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing products
from Adafruit!
-------------------------------------------------------------------------
This file is part of the Adafruit NeoPixel library.
NeoPixel is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
NeoPixel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with NeoPixel. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
#include "seesaw_neopixel.h"
#include "Adafruit_seesaw.h"
// Constructor when length, pin and type are known at compile-time:
seesaw_NeoPixel::seesaw_NeoPixel(uint16_t n, uint8_t p, neoPixelType t,
TwoWire *Wi)
: Adafruit_seesaw(Wi), begun(false), numLEDs(n), pin(p), brightness(0),
pixels(NULL), endTime(0), type(t) {}
// via Michael Vogt/neophob: empty constructor is used when strand length
// isn't known at compile-time; situations where program config might be
// read from internal flash memory or an SD card, or arrive via serial
// command. If using this constructor, MUST follow up with updateType(),
// updateLength(), etc. to establish the strand type, length and pin number!
seesaw_NeoPixel::seesaw_NeoPixel(TwoWire *Wi)
: Adafruit_seesaw(Wi),
#ifdef NEO_KHZ400
is800KHz(true),
#endif
begun(false), numLEDs(0), numBytes(0), pin(-1), brightness(0),
pixels(NULL), rOffset(1), gOffset(0), bOffset(2), wOffset(1), endTime(0) {
}
seesaw_NeoPixel::~seesaw_NeoPixel() {
if (pixels)
free(pixels);
}
bool seesaw_NeoPixel::begin(uint8_t addr, int8_t flow) {
if (!Adafruit_seesaw::begin(addr, flow))
return false;
updateType(type);
updateLength(numLEDs);
setPin(pin);
return true;
}
void seesaw_NeoPixel::updateLength(uint16_t n) {
if (pixels)
free(pixels); // Free existing data (if any)
// Allocate new data -- note: ALL PIXELS ARE CLEARED
numBytes = n * ((wOffset == rOffset) ? 3 : 4);
if ((pixels = (uint8_t *)malloc(numBytes))) {
memset(pixels, 0, numBytes);
numLEDs = n;
} else {
numLEDs = numBytes = 0;
}
uint8_t buf[] = {(uint8_t)(numBytes >> 8), (uint8_t)(numBytes & 0xFF)};
this->write(SEESAW_NEOPIXEL_BASE, SEESAW_NEOPIXEL_BUF_LENGTH, buf, 2);
}
void seesaw_NeoPixel::updateType(neoPixelType t) {
boolean oldThreeBytesPerPixel = (wOffset == rOffset); // false if RGBW
wOffset = (t >> 6) & 0b11; // See notes in header file
rOffset = (t >> 4) & 0b11; // regarding R/G/B/W offsets
gOffset = (t >> 2) & 0b11;
bOffset = t & 0b11;
is800KHz = (t < 256); // 400 KHz flag is 1<<8
this->write8(SEESAW_NEOPIXEL_BASE, SEESAW_NEOPIXEL_SPEED, is800KHz);
// If bytes-per-pixel has changed (and pixel data was previously
// allocated), re-allocate to new size. Will clear any data.
if (pixels) {
boolean newThreeBytesPerPixel = (wOffset == rOffset);
if (newThreeBytesPerPixel != oldThreeBytesPerPixel)
updateLength(numLEDs);
}
}
void seesaw_NeoPixel::show(void) {
if (!pixels)
return;
// Data latch = 300+ microsecond pause in the output stream. Rather than
// put a delay at the end of the function, the ending time is noted and
// the function will simply hold off (if needed) on issuing the
// subsequent round of data until the latch time has elapsed. This
// allows the mainline code to start generating the next frame of data
// rather than stalling for the latch.
while (!canShow())
;
this->write(SEESAW_NEOPIXEL_BASE, SEESAW_NEOPIXEL_SHOW, NULL, 0);
endTime = micros(); // Save EOD time for latch on next call
}
// Set the output pin number
void seesaw_NeoPixel::setPin(uint8_t p) {
this->write8(SEESAW_NEOPIXEL_BASE, SEESAW_NEOPIXEL_PIN, p);
pin = p;
}
// Set pixel color from separate R,G,B components:
void seesaw_NeoPixel::setPixelColor(uint16_t n, uint8_t r, uint8_t g,
uint8_t b) {
if (n < numLEDs) {
if (brightness) { // See notes in setBrightness()
r = (r * brightness) >> 8;
g = (g * brightness) >> 8;
b = (b * brightness) >> 8;
}
uint8_t *p;
if (wOffset == rOffset) { // Is an RGB-type strip
p = &pixels[n * 3]; // 3 bytes per pixel
} else { // Is a WRGB-type strip
p = &pixels[n * 4]; // 4 bytes per pixel
p[wOffset] = 0; // But only R,G,B passed -- set W to 0
}
p[rOffset] = r; // R,G,B always stored
p[gOffset] = g;
p[bOffset] = b;
uint8_t len = (wOffset == rOffset ? 3 : 4);
uint16_t offset = n * len;
uint8_t writeBuf[6];
writeBuf[0] = (offset >> 8);
writeBuf[1] = offset;
memcpy(&writeBuf[2], p, len);
this->write(SEESAW_NEOPIXEL_BASE, SEESAW_NEOPIXEL_BUF, writeBuf, len + 2);
}
}
void seesaw_NeoPixel::setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b,
uint8_t w) {
if (n < numLEDs) {
if (brightness) { // See notes in setBrightness()
r = (r * brightness) >> 8;
g = (g * brightness) >> 8;
b = (b * brightness) >> 8;
w = (w * brightness) >> 8;
}
uint8_t *p;
if (wOffset == rOffset) { // Is an RGB-type strip
p = &pixels[n * 3]; // 3 bytes per pixel (ignore W)
} else { // Is a WRGB-type strip
p = &pixels[n * 4]; // 4 bytes per pixel
p[wOffset] = w; // Store W
}
p[rOffset] = r; // Store R,G,B
p[gOffset] = g;
p[bOffset] = b;
uint8_t len = (wOffset == rOffset ? 3 : 4);
uint16_t offset = n * len;
uint8_t writeBuf[6];
writeBuf[0] = (offset >> 8);
writeBuf[1] = offset;
memcpy(&writeBuf[2], p, len);
this->write(SEESAW_NEOPIXEL_BASE, SEESAW_NEOPIXEL_BUF, writeBuf, len + 2);
}
}
// Set pixel color from 'packed' 32-bit RGB color:
void seesaw_NeoPixel::setPixelColor(uint16_t n, uint32_t c) {
if (n < numLEDs) {
uint8_t *p, r = (uint8_t)(c >> 16), g = (uint8_t)(c >> 8), b = (uint8_t)c;
if (brightness) { // See notes in setBrightness()
r = (r * brightness) >> 8;
g = (g * brightness) >> 8;
b = (b * brightness) >> 8;
}
if (wOffset == rOffset) {
p = &pixels[n * 3];
} else {
p = &pixels[n * 4];
uint8_t w = (uint8_t)(c >> 24);
p[wOffset] = brightness ? ((w * brightness) >> 8) : w;
}
p[rOffset] = r;
p[gOffset] = g;
p[bOffset] = b;
uint8_t len = (wOffset == rOffset ? 3 : 4);
uint16_t offset = n * len;
uint8_t writeBuf[6];
writeBuf[0] = (offset >> 8);
writeBuf[1] = offset;
memcpy(&writeBuf[2], p, len);
this->write(SEESAW_NEOPIXEL_BASE, SEESAW_NEOPIXEL_BUF, writeBuf, len + 2);
}
}
// Convert separate R,G,B into packed 32-bit RGB color.
// Packed format is always RGB, regardless of LED strand color order.
uint32_t seesaw_NeoPixel::Color(uint8_t r, uint8_t g, uint8_t b) {
return ((uint32_t)r << 16) | ((uint32_t)g << 8) | b;
}
// Convert separate R,G,B,W into packed 32-bit WRGB color.
// Packed format is always WRGB, regardless of LED strand color order.
uint32_t seesaw_NeoPixel::Color(uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
return ((uint32_t)w << 24) | ((uint32_t)r << 16) | ((uint32_t)g << 8) | b;
}
// Query color from previously-set pixel (returns packed 32-bit RGB value)
uint32_t seesaw_NeoPixel::getPixelColor(uint16_t n) const {
if (n >= numLEDs)
return 0; // Out of bounds, return no color.
uint8_t *p;
if (wOffset == rOffset) { // Is RGB-type device
p = &pixels[n * 3];
if (brightness) {
// Stored color was decimated by setBrightness(). Returned value
// attempts to scale back to an approximation of the original 24-bit
// value used when setting the pixel color, but there will always be
// some error -- those bits are simply gone. Issue is most
// pronounced at low brightness levels.
return (((uint32_t)(p[rOffset] << 8) / brightness) << 16) |
(((uint32_t)(p[gOffset] << 8) / brightness) << 8) |
((uint32_t)(p[bOffset] << 8) / brightness);
} else {
// No brightness adjustment has been made -- return 'raw' color
return ((uint32_t)p[rOffset] << 16) | ((uint32_t)p[gOffset] << 8) |
(uint32_t)p[bOffset];
}
} else { // Is RGBW-type device
p = &pixels[n * 4];
if (brightness) { // Return scaled color
return (((uint32_t)(p[wOffset] << 8) / brightness) << 24) |
(((uint32_t)(p[rOffset] << 8) / brightness) << 16) |
(((uint32_t)(p[gOffset] << 8) / brightness) << 8) |
((uint32_t)(p[bOffset] << 8) / brightness);
} else { // Return raw color
return ((uint32_t)p[wOffset] << 24) | ((uint32_t)p[rOffset] << 16) |
((uint32_t)p[gOffset] << 8) | (uint32_t)p[bOffset];
}
}
}
// Returns pointer to pixels[] array. Pixel data is stored in device-
// native format and is not translated here. Application will need to be
// aware of specific pixel data format and handle colors appropriately.
uint8_t *seesaw_NeoPixel::getPixels(void) const { return pixels; }
uint16_t seesaw_NeoPixel::numPixels(void) const { return numLEDs; }
void seesaw_NeoPixel::clear() {
// Clear local pixel buffer
memset(pixels, 0, numBytes);
// Now clear the pixels on the seesaw
uint8_t writeBuf[32];
memset(writeBuf, 0, 32);
for (uint8_t offset = 0; offset < numBytes; offset += 32 - 4) {
writeBuf[0] = (offset >> 8);
writeBuf[1] = offset;
this->write(SEESAW_NEOPIXEL_BASE, SEESAW_NEOPIXEL_BUF, writeBuf, 32);
}
}
void seesaw_NeoPixel::setBrightness(uint8_t b) { brightness = b; }

View File

@@ -0,0 +1,135 @@
/*--------------------------------------------------------------------
This file is part of the Adafruit NeoPixel library.
NeoPixel is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
NeoPixel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with NeoPixel. If not, see
<http://www.gnu.org/licenses/>.
--------------------------------------------------------------------*/
#ifndef SEESAW_NEOPIXEL_H
#define SEESAW_NEOPIXEL_H
#include "Adafruit_seesaw.h"
#include <Arduino.h>
// The order of primary colors in the NeoPixel data stream can vary
// among device types, manufacturers and even different revisions of
// the same item. The third parameter to the seesaw_NeoPixel
// constructor encodes the per-pixel byte offsets of the red, green
// and blue primaries (plus white, if present) in the data stream --
// the following #defines provide an easier-to-use named version for
// each permutation. e.g. NEO_GRB indicates a NeoPixel-compatible
// device expecting three bytes per pixel, with the first byte
// containing the green value, second containing red and third
// containing blue. The in-memory representation of a chain of
// NeoPixels is the same as the data-stream order; no re-ordering of
// bytes is required when issuing data to the chain.
// Bits 5,4 of this value are the offset (0-3) from the first byte of
// a pixel to the location of the red color byte. Bits 3,2 are the
// green offset and 1,0 are the blue offset. If it is an RGBW-type
// device (supporting a white primary in addition to R,G,B), bits 7,6
// are the offset to the white byte...otherwise, bits 7,6 are set to
// the same value as 5,4 (red) to indicate an RGB (not RGBW) device.
// i.e. binary representation:
// 0bWWRRGGBB for RGBW devices
// 0bRRRRGGBB for RGB
// RGB NeoPixel permutations; white and red offsets are always same
// Offset: W R G B
#define NEO_RGB ((0 << 6) | (0 << 4) | (1 << 2) | (2))
#define NEO_RBG ((0 << 6) | (0 << 4) | (2 << 2) | (1))
#define NEO_GRB ((1 << 6) | (1 << 4) | (0 << 2) | (2))
#define NEO_GBR ((2 << 6) | (2 << 4) | (0 << 2) | (1))
#define NEO_BRG ((1 << 6) | (1 << 4) | (2 << 2) | (0))
#define NEO_BGR ((2 << 6) | (2 << 4) | (1 << 2) | (0))
// RGBW NeoPixel permutations; all 4 offsets are distinct
// Offset: W R G B
#define NEO_WRGB ((0 << 6) | (1 << 4) | (2 << 2) | (3))
#define NEO_WRBG ((0 << 6) | (1 << 4) | (3 << 2) | (2))
#define NEO_WGRB ((0 << 6) | (2 << 4) | (1 << 2) | (3))
#define NEO_WGBR ((0 << 6) | (3 << 4) | (1 << 2) | (2))
#define NEO_WBRG ((0 << 6) | (2 << 4) | (3 << 2) | (1))
#define NEO_WBGR ((0 << 6) | (3 << 4) | (2 << 2) | (1))
#define NEO_RWGB ((1 << 6) | (0 << 4) | (2 << 2) | (3))
#define NEO_RWBG ((1 << 6) | (0 << 4) | (3 << 2) | (2))
#define NEO_RGWB ((2 << 6) | (0 << 4) | (1 << 2) | (3))
#define NEO_RGBW ((3 << 6) | (0 << 4) | (1 << 2) | (2))
#define NEO_RBWG ((2 << 6) | (0 << 4) | (3 << 2) | (1))
#define NEO_RBGW ((3 << 6) | (0 << 4) | (2 << 2) | (1))
#define NEO_GWRB ((1 << 6) | (2 << 4) | (0 << 2) | (3))
#define NEO_GWBR ((1 << 6) | (3 << 4) | (0 << 2) | (2))
#define NEO_GRWB ((2 << 6) | (1 << 4) | (0 << 2) | (3))
#define NEO_GRBW ((3 << 6) | (1 << 4) | (0 << 2) | (2))
#define NEO_GBWR ((2 << 6) | (3 << 4) | (0 << 2) | (1))
#define NEO_GBRW ((3 << 6) | (2 << 4) | (0 << 2) | (1))
#define NEO_BWRG ((1 << 6) | (2 << 4) | (3 << 2) | (0))
#define NEO_BWGR ((1 << 6) | (3 << 4) | (2 << 2) | (0))
#define NEO_BRWG ((2 << 6) | (1 << 4) | (3 << 2) | (0))
#define NEO_BRGW ((3 << 6) | (1 << 4) | (2 << 2) | (0))
#define NEO_BGWR ((2 << 6) | (3 << 4) | (1 << 2) | (0))
#define NEO_BGRW ((3 << 6) | (2 << 4) | (1 << 2) | (0))
// If 400 KHz support is enabled, the third parameter to the constructor
// requires a 16-bit value (in order to select 400 vs 800 KHz speed).
// If only 800 KHz is enabled (as is default on ATtiny), an 8-bit value
// is sufficient to encode pixel color order, saving some space.
#define NEO_KHZ800 0x0000 // 800 KHz datastream
#define NEO_KHZ400 0x0100 // 400 KHz datastream
typedef uint16_t neoPixelType;
/** Adafruit_NeoPixel-compatible 'wrapper' for LED control over seesaw
*/
class seesaw_NeoPixel : public Adafruit_seesaw {
public:
seesaw_NeoPixel(uint16_t n, uint8_t p = 6,
neoPixelType t = NEO_GRB + NEO_KHZ800, TwoWire *Wi = NULL);
seesaw_NeoPixel(TwoWire *Wi = NULL);
~seesaw_NeoPixel();
bool begin(uint8_t addr = SEESAW_ADDRESS, int8_t flow = -1);
void show(void), setPin(uint8_t p),
setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b),
setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w),
setPixelColor(uint16_t n, uint32_t c), setBrightness(uint8_t), clear(),
updateLength(uint16_t n), updateType(neoPixelType t);
uint8_t *getPixels(void) const, getBrightness(void) const;
int8_t getPin(void) { return pin; };
uint16_t numPixels(void) const;
static uint32_t Color(uint8_t r, uint8_t g, uint8_t b),
Color(uint8_t r, uint8_t g, uint8_t b, uint8_t w);
uint32_t getPixelColor(uint16_t n) const;
inline bool canShow(void) { return (micros() - endTime) >= 300L; }
protected:
boolean is800KHz, // ...true if 800 KHz pixels
begun; // true if begin() previously called
uint16_t numLEDs, // Number of RGB LEDs in strip
numBytes; // Size of 'pixels' buffer below (3 or 4 bytes/pixel)
int8_t pin;
uint8_t brightness,
*pixels, // Holds LED color values (3 or 4 bytes each)
rOffset, // Index of red byte within each 3- or 4-byte pixel
gOffset, // Index of green byte
bOffset, // Index of blue byte
wOffset; // Index of white byte (same as rOffset if no white)
uint32_t endTime; // Latch timing reference
uint16_t type;
};
#endif // seesaw_NeoPixel_H

View File

@@ -0,0 +1,91 @@
#include "seesaw_servo.h"
#define MIN_PULSE 3277
#define MAX_PULSE 6554
/**************************************************************************/
/*!
@brief begin the seesaw. This is only necessary if the seesaw is not
already started
@param addr the address to begin on
@param flow the flow control pin to use
@returns true on success, false otherwise
*/
/**************************************************************************/
bool seesaw_Servo::begin(uint8_t addr, int8_t flow) {
return _ss->begin(addr, flow);
}
/**************************************************************************/
/*!
@brief attach the given pin to the next free channel, sets pinMode.
@param pin the pin to use
@returns 0
*/
/**************************************************************************/
uint8_t seesaw_Servo::attach(int pin) {
_pin = pin;
// set frequency to 50 hz
_ss->setPWMFreq(_pin, 50);
_attached = true;
min = MIN_PULSE;
max = MAX_PULSE;
return 0;
}
/**************************************************************************/
/*!
@brief attach the given pin to the next free channel but also sets min and
max values for writes.
@param pin the pin to use
@param min the minimum pulse width value in microseconds
@param max the maximum pulse width value in microseconds
@returns 0
*/
/**************************************************************************/
uint8_t seesaw_Servo::attach(int pin, int min, int max) {
attach(pin);
this->min = min * 3.2767;
this->max = max * 3.2767;
return 0;
}
/**************************************************************************/
/*!
@brief write a value. if value is < 200 its treated as an angle, otherwise
as pulse width in microseconds
@param value the value to write
*/
/**************************************************************************/
void seesaw_Servo::write(int value) {
if (value < 200) {
// angle
uint16_t val = map(value, 0, 180, min, max);
val = constrain(val, min, max);
_ss->analogWrite(_pin, val);
_sval = val;
} else
writeMicroseconds(value);
}
/**************************************************************************/
/*!
@brief get current value
@returns current pulse width as an angle between 0 and 180 degrees
*/
/**************************************************************************/
int seesaw_Servo::read() { return map(_sval, MIN_PULSE, MAX_PULSE, 0, 180); }
/**************************************************************************/
/*!
@brief Write pulse width in microseconds
@param value the value to write
*/
/**************************************************************************/
void seesaw_Servo::writeMicroseconds(int value) {
uint16_t val = 3.2767 * value;
_ss->analogWrite(_pin, val);
_sval = val;
}

View File

@@ -0,0 +1,66 @@
#ifndef _SEESAW_SERVO_H
#define _SEESAW_SERVO_H
#include "Adafruit_seesaw.h"
/**************************************************************************/
/*!
@brief Class that stores state and functions for seesaw servo interface
*/
/**************************************************************************/
class seesaw_Servo {
public:
/**************************************************************************/
/*!
@brief class constructor
@param ss the seesaw object to use
*/
/**************************************************************************/
seesaw_Servo(Adafruit_seesaw *ss) {
_ss = ss;
_attached = false;
}
~seesaw_Servo() {}
bool begin(uint8_t addr = SEESAW_ADDRESS, int8_t flow = -1);
uint8_t attach(int pin);
uint8_t attach(int pin, int min, int max);
/**************************************************************************/
/*!
@brief set attached to false
*/
/**************************************************************************/
void detach() { _attached = false; }
void write(int value);
void writeMicroseconds(int value);
int read();
/**************************************************************************/
/*!
@brief get current value in microseconds
@returns current pulse width in microseconds for this servo
*/
/**************************************************************************/
int readMicroseconds() { return _sval / 3.2768; }
/**************************************************************************/
/*!
@brief check if the servo is attached yet
@returns true if this servo is attached, otherwise false
*/
/**************************************************************************/
bool attached() { return _attached; }
private:
Adafruit_seesaw *_ss;
bool _attached;
uint16_t _sval;
uint8_t _pin;
uint16_t min;
uint16_t max;
};
#endif

View File

@@ -0,0 +1,53 @@
#include "seesaw_spectrum.h"
/**************************************************************************/
/*!
@brief Pull latest audio spectrum data from device.
*/
/**************************************************************************/
void seesaw_Audio_Spectrum::getData(void) {
read(SEESAW_SPECTRUM_BASE, SEESAW_SPECTRUM_RESULTS_LOWER, bins, 32, 0);
read(SEESAW_SPECTRUM_BASE, SEESAW_SPECTRUM_RESULTS_UPPER, &bins[32], 32, 0);
}
/**************************************************************************/
/*!
@brief Set the audio sampling rate.
@param value Sampling rate index, 0-31. Values outside this range
will be clipped on the Seesaw device side.
*/
/**************************************************************************/
void seesaw_Audio_Spectrum::setRate(uint8_t value) {
write8(SEESAW_SPECTRUM_BASE, SEESAW_SPECTRUM_RATE, value);
}
/**************************************************************************/
/*!
@brief Set the analog input channel.
@param value Channel index, 0-TBD (probably 1). Values outside the
valid range will be clipped on the Seesaw device side.
*/
/**************************************************************************/
void seesaw_Audio_Spectrum::setChannel(uint8_t value) {
write8(SEESAW_SPECTRUM_BASE, SEESAW_SPECTRUM_CHANNEL, value);
}
/**************************************************************************/
/*!
@brief Query the current audio sampling rate.
@return Sampling rate index, 0-31.
*/
/**************************************************************************/
uint8_t seesaw_Audio_Spectrum::getRate(void) {
return read8(SEESAW_SPECTRUM_BASE, SEESAW_SPECTRUM_RATE);
}
/**************************************************************************/
/*!
@brief Query the current analog input channel.
@return Active ADC channel, 0-TBD (probably 1).
*/
/**************************************************************************/
uint8_t seesaw_Audio_Spectrum::getChannel(void) {
return read8(SEESAW_SPECTRUM_BASE, SEESAW_SPECTRUM_CHANNEL);
}

View File

@@ -0,0 +1,70 @@
#ifndef _SEESAW_SPECTRUM_H
#define _SEESAW_SPECTRUM_H
#include "Adafruit_seesaw.h"
#include <Arduino.h>
/**************************************************************************/
/*!
@brief Class that stores state and functions for seesaw audio spectrum
interface
*/
/**************************************************************************/
class seesaw_Audio_Spectrum : public Adafruit_seesaw {
public:
/**************************************************************************/
/*!
@brief seesaw_Audio_Spectrum class constructor.
@param Wi TwoWire interface this works through.
*/
/**************************************************************************/
seesaw_Audio_Spectrum(TwoWire *Wi = NULL) : Adafruit_seesaw(Wi) {}
~seesaw_Audio_Spectrum() {}
/**************************************************************************/
/*!
@brief Begin communication with Seesaw audio spectrum device.
@param addr Optional i2c address where the device can be found.
Defaults to SEESAW_ADDRESS.
@param flow Optional flow control pin.
@return true on success, false on error.
*/
/**************************************************************************/
bool begin(uint8_t addr = SEESAW_ADDRESS, int8_t flow = -1) {
if (Adafruit_seesaw::begin(addr, flow)) {
memset(bins, 0, sizeof bins);
return true;
}
return false;
}
void getData(void); // Fetch latest audio spectrum data
void setRate(uint8_t value); // Set audio sampling rate 0-31
void setChannel(uint8_t value); // Set ADC input channel
uint8_t getRate(void); // Query current audio sampling rate 0-31
uint8_t getChannel(void); // Query current ADC channel
/**************************************************************************/
/*!
@brief Get value of individual spectrum bin, as determined during
most recent get_data() call.
@param idx Spectrum bin index (0-63) to query.
@return Level: 0 (silent) to 255 (loudest) for bin.
*/
/**************************************************************************/
uint8_t getLevel(uint8_t idx) const { return bins[idx < 64 ? idx : 63]; }
/**************************************************************************/
/*!
@brief Get pointer to spectrum bin buffer directly. Use with caution!
@return uint8_t base pointer to 64 spectrum bins.
*/
/**************************************************************************/
uint8_t *getBuffer(void) const { return (uint8_t *)bins; }
private:
uint8_t bins[64]; // Audio spectrum "bins"
};
#endif // end _SEESAW_SPECTRUM_H