First init.

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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