First init.
This commit is contained in:
65
libraries/Adafruit_seesaw_Library/Adafruit_Crickit.cpp
Normal file
65
libraries/Adafruit_seesaw_Library/Adafruit_Crickit.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
53
libraries/Adafruit_seesaw_Library/Adafruit_Crickit.h
Normal file
53
libraries/Adafruit_seesaw_Library/Adafruit_Crickit.h
Normal 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
|
||||
336
libraries/Adafruit_seesaw_Library/Adafruit_NeoKey_1x4.cpp
Normal file
336
libraries/Adafruit_seesaw_Library/Adafruit_NeoKey_1x4.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
96
libraries/Adafruit_seesaw_Library/Adafruit_NeoKey_1x4.h
Normal file
96
libraries/Adafruit_seesaw_Library/Adafruit_NeoKey_1x4.h
Normal 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
|
||||
353
libraries/Adafruit_seesaw_Library/Adafruit_NeoTrellis.cpp
Normal file
353
libraries/Adafruit_seesaw_Library/Adafruit_NeoTrellis.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
95
libraries/Adafruit_seesaw_Library/Adafruit_NeoTrellis.h
Normal file
95
libraries/Adafruit_seesaw_Library/Adafruit_NeoTrellis.h
Normal 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
|
||||
65
libraries/Adafruit_seesaw_Library/Adafruit_TFTShield18.cpp
Normal file
65
libraries/Adafruit_seesaw_Library/Adafruit_TFTShield18.cpp
Normal 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);
|
||||
}
|
||||
60
libraries/Adafruit_seesaw_Library/Adafruit_TFTShield18.h
Normal file
60
libraries/Adafruit_seesaw_Library/Adafruit_TFTShield18.h
Normal 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
|
||||
140
libraries/Adafruit_seesaw_Library/Adafruit_miniTFTWing.cpp
Normal file
140
libraries/Adafruit_seesaw_Library/Adafruit_miniTFTWing.cpp
Normal 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);
|
||||
}
|
||||
36
libraries/Adafruit_seesaw_Library/Adafruit_miniTFTWing.h
Normal file
36
libraries/Adafruit_seesaw_Library/Adafruit_miniTFTWing.h
Normal 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
|
||||
1047
libraries/Adafruit_seesaw_Library/Adafruit_seesaw.cpp
Normal file
1047
libraries/Adafruit_seesaw_Library/Adafruit_seesaw.cpp
Normal file
File diff suppressed because it is too large
Load Diff
351
libraries/Adafruit_seesaw_Library/Adafruit_seesaw.h
Normal file
351
libraries/Adafruit_seesaw_Library/Adafruit_seesaw.h
Normal 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
|
||||
2492
libraries/Adafruit_seesaw_Library/Doxyfile
Normal file
2492
libraries/Adafruit_seesaw_Library/Doxyfile
Normal file
File diff suppressed because it is too large
Load Diff
5
libraries/Adafruit_seesaw_Library/README.md
Normal file
5
libraries/Adafruit_seesaw_Library/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Adafruit_Seesaw [](https://github.com/adafruit/Adafruit_Seesaw/actions)[](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!
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
38
libraries/Adafruit_seesaw_Library/examples/EEPROM/EEPROM.ino
Normal file
38
libraries/Adafruit_seesaw_Library/examples/EEPROM/EEPROM.ino
Normal 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!!!
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
10
libraries/Adafruit_seesaw_Library/library.properties
Normal file
10
libraries/Adafruit_seesaw_Library/library.properties
Normal 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
|
||||
82
libraries/Adafruit_seesaw_Library/seesaw_motor.h
Normal file
82
libraries/Adafruit_seesaw_Library/seesaw_motor.h
Normal 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
|
||||
297
libraries/Adafruit_seesaw_Library/seesaw_neopixel.cpp
Normal file
297
libraries/Adafruit_seesaw_Library/seesaw_neopixel.cpp
Normal 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; }
|
||||
135
libraries/Adafruit_seesaw_Library/seesaw_neopixel.h
Normal file
135
libraries/Adafruit_seesaw_Library/seesaw_neopixel.h
Normal 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
|
||||
91
libraries/Adafruit_seesaw_Library/seesaw_servo.cpp
Normal file
91
libraries/Adafruit_seesaw_Library/seesaw_servo.cpp
Normal 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;
|
||||
}
|
||||
66
libraries/Adafruit_seesaw_Library/seesaw_servo.h
Normal file
66
libraries/Adafruit_seesaw_Library/seesaw_servo.h
Normal 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
|
||||
53
libraries/Adafruit_seesaw_Library/seesaw_spectrum.cpp
Normal file
53
libraries/Adafruit_seesaw_Library/seesaw_spectrum.cpp
Normal 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);
|
||||
}
|
||||
70
libraries/Adafruit_seesaw_Library/seesaw_spectrum.h
Normal file
70
libraries/Adafruit_seesaw_Library/seesaw_spectrum.h
Normal 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
|
||||
Reference in New Issue
Block a user