Hardware components | ||||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
Software apps and online services | ||||||
|
Images are a powerful way to communicate ideas and emotions. They can be used to inform, educate, entertain, and more.
Last year, we created a project called "Garrita: Image Shifter".
This project allowed users to show different images by simply touching a button.
In this project, we will update that project using an Arduino Giga board, Arduino Giga Display and a graphics library called LVGL.
With these updates, the project will be more powerful, interactive, and fun.
Upgrading the Experience: More Power, More Control, More Fun!Remember Michi?
Our lovable educational board with resistive sensors is still the star for creating custom buttons! Whether it's with clay, fruit, or metal, Michi turns any conductive material into a unique touch-sensitive control.
But what if we took the experience to the next level? Introducing Arduino Giga, the most powerful brain in the game! With it, we can manage images and visual effects more easily. And to enjoy them to the fullest, we use an amazing display (Arduino Giga Display), much larger and brighter.
But that's not all. To bring images to life, we have incorporated LVGL, a magical graphics library.
With just a touch, we can explore stylish galleries, navigate through different image options, and even customize how we see them on the screen. LVGL opens the door to endless possibilities for future projects with more interactive animations and interfaces.
Bringing Images to Life:To get started, download the Arduino code for this project that you can find below in this article. Once you have downloaded the code, save it in a folder with the same name as the file.
Ready to fill your display with vibrant pictures? Adding images to your project is easy with LVGL! Here's what you'll need:
- Images: Choose your favorite photos or illustrations, ideally sized for the Arduino Giga Display (800x400 pixels).
- LVGL Image Converter: Head over to https://lvgl.io/tools/imageconverter. This handy online tool will convert your images into formats ready for your project.
Converting Images with the Magic of LVGL:
- Pick Your Picture: Upload your image in BMP, PNG, or JPG format.
- Name It: Give your image a catchy name that LVGL will recognize.
- Choose Your Colors: Select the color format that best suits your needs.
- Variable or Binary?: Decide if you want your image stored as a C variable directly in your code (ideal for smaller images) or as a separate binary file (preferred for larger images).
- Hit Convert!: With a click, LVGL gets to work, generating the necessary files for your image.
Once the conversion is complete, download the file(s) and save it in the same folder of the Arduino code.
What is the next step?
Now that you have everything you need, it's time to upload the code to your Arduino and see how the images display!
Once the code has uploaded successfully, your Arduino will begin displaying the images. You can use Michi's sensors to interact with the images.
Have fun exploring the possibilities of this project!
Image_Shifter
Arduino#include "Arduino_H7_Video.h"
#include "lvgl.h"
Arduino_H7_Video Display(800, 480, GigaDisplayShield);
int inPin = 7;
bool val = false;
int count = 0;
void setup() {
pinMode(inPin, INPUT);
Display.begin();
Serial.begin(9600);
}
void loop() {
val = digitalRead(inPin);
lv_timer_handler();
if (count == 0) {
image1();
}
if (count == 1) {
image2();
}
if (count == 2) {
image3();
}
if (count == 3) {
image4();
}
if (count == 4) {
count = 0;
}
Serial.println(count);
delay(3000);
if (val == true) {
count = count + 1;
Serial.println(count);
delay(900);
}
}
void image1() {
lv_obj_t* screen = lv_obj_create(lv_scr_act());
lv_obj_set_size(screen, Display.width(), Display.height());
static lv_coord_t col_dsc[] = { 800, LV_GRID_TEMPLATE_LAST };
static lv_coord_t row_dsc[] = { 480, LV_GRID_TEMPLATE_LAST };
lv_obj_t* grid = lv_obj_create(lv_scr_act());
lv_obj_set_grid_dsc_array(grid, col_dsc, row_dsc);
lv_obj_set_size(grid, Display.width(), Display.height());
lv_obj_center(grid);
lv_obj_t* obj;
lv_obj_t* img1;
obj = lv_obj_create(grid);
lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, 0, 1,
LV_GRID_ALIGN_STRETCH, 0, 1);
LV_IMG_DECLARE(img_arduinologo);
img1 = lv_img_create(obj);
lv_img_set_src(img1, &img_arduinologo);
lv_obj_align(img1, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_size(img1, 600, 400);
}
void image2() {
lv_obj_t* screen = lv_obj_create(lv_scr_act());
lv_obj_set_size(screen, Display.width(), Display.height());
static lv_coord_t col_dsc[] = { 800, LV_GRID_TEMPLATE_LAST };
static lv_coord_t row_dsc[] = { 480, LV_GRID_TEMPLATE_LAST };
lv_obj_t* grid = lv_obj_create(lv_scr_act());
lv_obj_set_grid_dsc_array(grid, col_dsc, row_dsc);
lv_obj_set_size(grid, Display.width(), Display.height());
lv_obj_center(grid);
lv_obj_t* obj;
lv_obj_t* img1;
obj = lv_obj_create(grid);
lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, 0, 1,
LV_GRID_ALIGN_STRETCH, 0, 1);
LV_IMG_DECLARE(img_arduinologo2);
img1 = lv_img_create(obj);
lv_img_set_src(img1, &img_arduinologo2);
lv_obj_align(img1, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_size(img1, 400, 350);
}
void image3() {
lv_obj_t* screen = lv_obj_create(lv_scr_act());
lv_obj_set_size(screen, Display.width(), Display.height());
static lv_coord_t col_dsc[] = { 800, LV_GRID_TEMPLATE_LAST };
static lv_coord_t row_dsc[] = { 480, LV_GRID_TEMPLATE_LAST };
lv_obj_t* grid = lv_obj_create(lv_scr_act());
lv_obj_set_grid_dsc_array(grid, col_dsc, row_dsc);
lv_obj_set_size(grid, Display.width(), Display.height());
lv_obj_center(grid);
lv_obj_t* obj;
lv_obj_t* img1;
obj = lv_obj_create(grid);
lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, 0, 1,
LV_GRID_ALIGN_STRETCH, 0, 1);
LV_IMG_DECLARE(img_3);
img1 = lv_img_create(obj);
lv_img_set_src(img1, &img_3);
lv_obj_align(img1, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_size(img1, 380, 290);
}
void image4() {
lv_obj_t* screen = lv_obj_create(lv_scr_act());
lv_obj_set_size(screen, Display.width(), Display.height());
static lv_coord_t col_dsc[] = { 800, LV_GRID_TEMPLATE_LAST };
static lv_coord_t row_dsc[] = { 480, LV_GRID_TEMPLATE_LAST };
lv_obj_t* grid = lv_obj_create(lv_scr_act());
lv_obj_set_grid_dsc_array(grid, col_dsc, row_dsc);
lv_obj_set_size(grid, Display.width(), Display.height());
lv_obj_center(grid);
lv_obj_t* obj;
lv_obj_t* img1;
obj = lv_obj_create(grid);
lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, 0, 1,
LV_GRID_ALIGN_STRETCH, 0, 1);
LV_IMG_DECLARE(img_4);
img1 = lv_img_create(obj);
lv_img_set_src(img1, &img_4);
lv_obj_align(img1, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_size(img1, 700, 600);
}
/*
/////////////////////////////////////////////////
/////////////HOW TO EDIT THE KEYS ///////////////
/////////////////////////////////////////////////
- Edit keys in the settings.h file
- that file should be open in a tab above (in Arduino IDE)
- more instructions are in that file
//////////////////////////////////////////////////
///////// MICHI FIRMWARE v1.0.0 ////////////
//////////////////////////////////////////////////
/************************************************************
Michi - Using the Michi you can make anything into a key
just by connecting a few alligator clips
Andres Sabas @ Electronic Cats
Original Creation Date: Sept 6, 2022
https://github.com/ElectronicCats/MeowMeow
This example demonstrates how to use Meow Meow
Development environment specifics:
IDE: Arduino 1.8.19
Hardware Platform:
Michi
- RP2040
This code is beerware; if you see me (or any other Electronic Cats
member) at the local, and you've found our code helpful,
please buy us a round!
Distributed as-is; no warranty is given.
Based in the work by:
by: Eric Rosenbaum, Jay Silver, and Jim Lindblom
MIT Media Lab & Sparkfun
start date: 2/16/2012
release: 7/5/2012
***************************************************************************/
/////////////////////////
// DEBUG DEFINITIONS ////
/////////////////////////
//#define DEBUG
//#define DEBUG2
//#define DEBUG3
//#define DEBUG_TIMING
//#define DEBUG_MOUSE
//#define DEBUG_TIMING2
////////////////////////
// DEFINED CONSTANTS////
////////////////////////
#define BUFFER_LENGTH 3 // 3 bytes gives us 24 samples
#define NUM_INPUTS 10 // 6 on the front + 12 on the back
#define NUM_OUTPUTS 10 //
//#define TARGET_LOOP_TIME 694 // (1/60 seconds) / 24 samples = 694 microseconds per sample
//#define TARGET_LOOP_TIME 758 // (1/55 seconds) / 24 samples = 758 microseconds per sample
#define TARGET_LOOP_TIME 744 // (1/56 seconds) / 24 samples = 744 microseconds per sample
// id numbers for mouse movement inputs (used in settings.h)
#define MOUSE_MOVE_UP -1
#define MOUSE_MOVE_DOWN -2
#define MOUSE_MOVE_LEFT -3
#define MOUSE_MOVE_RIGHT -4
#include <Keyboard.h>
#include <Mouse.h>
#include "settings.h"
/////////////////////////
// STRUCT ///////////////
/////////////////////////
typedef struct {
byte pinNumber;
int keyCode;
byte measurementBuffer[BUFFER_LENGTH];
boolean oldestMeasurement;
byte bufferSum;
boolean pressed;
boolean prevPressed;
boolean isMouseMotion;
boolean isMouseButton;
boolean isKey;
}
MakeyMakeyInput;
MakeyMakeyInput inputs[NUM_INPUTS];
///////////////////////////////////
// VARIABLES //////////////////////
///////////////////////////////////
int bufferIndex = 0;
byte byteCounter = 0;
byte bitCounter = 0;
int mouseMovementCounter = 0; // for sending mouse movement events at a slower interval
int pressThreshold;
int releaseThreshold;
boolean inputChanged;
int mouseHoldCount[NUM_INPUTS]; // used to store mouse movement hold data
// Pin Numbers
// input pin numbers for kickstarter production board
int pinNumbers[NUM_INPUTS] = {
27, 25, 29, 23, 19, 21, // top of makey makey board
17, 14, 12, 10 // left side of female header, KEYBOARD
// right side of female header, MOUSE
};
int pinNumbers2[NUM_OUTPUTS] = {
9, 11, 13, 16, 18, 20, // top of makey makey board
22, 24, 26, 28 // left side of female header, KEYBOARD
// right side of female header, MOUSE
};
// input status LED pin numbers
const int inputLED_a = 15;
const int inputLED_b = 8;
const int inputLED_c = 7;
const int outputK = 0;
const int outputM = 1;
byte ledCycleCounter = 0;
// timing
int loopTime = 0;
int prevTime = 0;
int loopCounter = 0;
///////////////////////////
// FUNCTIONS //////////////
///////////////////////////
void initializeArduino();
void initializeInputs();
void updateMeasurementBuffers();
void updateBufferSums();
void updateBufferIndex();
void updateInputStates();
void sendMouseButtonEvents();
void sendMouseMovementEvents();
void addDelay();
void cycleLEDs();
void danceLeds();
void updateOutLEDs();
//////////////////////
// SETUP /////////////
//////////////////////
void setup()
{
initializeArduino();
initializeInputs();
danceLeds();
pinMode(D2, OUTPUT);
}
////////////////////
// MAIN LOOP ///////
////////////////////
void loop()
{
updateMeasurementBuffers();
updateBufferSums();
updateBufferIndex();
updateInputStates();
sendMouseButtonEvents();
sendMouseMovementEvents();
cycleLEDs();
updateOutLEDs();
addDelay();
}
//////////////////////////
// INITIALIZE ARDUINO
//////////////////////////
void initializeArduino() {
#ifdef DEBUG
Serial.begin(9600); // Serial for debugging
#endif
/* Set up input pins
DEactivate the internal pull-ups, since we're using external resistors */
for (int i=0; i<NUM_INPUTS; i++)
{
pinMode(pinNumbers[i], INPUT);
digitalWrite(pinNumbers[i], LOW);
}
for (int i=0; i<NUM_OUTPUTS; i++)
{
pinMode(pinNumbers2[i], OUTPUT);
digitalWrite(pinNumbers2[i], HIGH);
}
pinMode(inputLED_a, INPUT);
pinMode(inputLED_b, INPUT);
pinMode(inputLED_c, INPUT);
digitalWrite(inputLED_a, LOW);
digitalWrite(inputLED_b, LOW);
digitalWrite(inputLED_c, LOW);
pinMode(outputK, OUTPUT);
pinMode(outputM, OUTPUT);
digitalWrite(outputK, LOW);
digitalWrite(outputM, LOW);
#ifdef DEBUG
delay(4000); // allow us time to reprogram in case things are freaking out
#endif
Keyboard.begin();
Mouse.begin();
}
///////////////////////////
// INITIALIZE INPUTS
///////////////////////////
void initializeInputs() {
float thresholdPerc = SWITCH_THRESHOLD_OFFSET_PERC;
float thresholdCenterBias = SWITCH_THRESHOLD_CENTER_BIAS/50.0;
float pressThresholdAmount = (BUFFER_LENGTH * 8) * (thresholdPerc / 100.0);
float thresholdCenter = ( (BUFFER_LENGTH * 8) / 2.0 ) * (thresholdCenterBias);
pressThreshold = int(thresholdCenter + pressThresholdAmount);
releaseThreshold = int(thresholdCenter - pressThresholdAmount);
#ifdef DEBUG
Serial.println(pressThreshold);
Serial.println(releaseThreshold);
#endif
for (int i=0; i<NUM_INPUTS; i++) {
inputs[i].pinNumber = pinNumbers[i];
inputs[i].keyCode = keyCodes[i];
for (int j=0; j<BUFFER_LENGTH; j++) {
inputs[i].measurementBuffer[j] = 0;
}
inputs[i].oldestMeasurement = 0;
inputs[i].bufferSum = 0;
inputs[i].pressed = false;
inputs[i].prevPressed = false;
inputs[i].isMouseMotion = false;
inputs[i].isMouseButton = false;
inputs[i].isKey = false;
if (inputs[i].keyCode < 0) {
#ifdef DEBUG_MOUSE
Serial.println("GOT IT");
#endif
inputs[i].isMouseMotion = true;
}
else if ((inputs[i].keyCode == MOUSE_LEFT) || (inputs[i].keyCode == MOUSE_RIGHT)) {
inputs[i].isMouseButton = true;
}
else {
inputs[i].isKey = true;
}
#ifdef DEBUG
Serial.println(i);
#endif
}
}
//////////////////////////////
// UPDATE MEASUREMENT BUFFERS
//////////////////////////////
void updateMeasurementBuffers() {
for (int i=0; i<NUM_INPUTS; i++) {
// store the oldest measurement, which is the one at the current index,
// before we update it to the new one
// we use oldest measurement in updateBufferSums
byte currentByte = inputs[i].measurementBuffer[byteCounter];
inputs[i].oldestMeasurement = (currentByte >> bitCounter) & 0x01;
// make the new measurement
boolean newMeasurement = digitalRead(inputs[i].pinNumber);
// invert so that true means the switch is closed
newMeasurement = !newMeasurement;
// store it
if (newMeasurement) {
currentByte |= (1<<bitCounter);
}
else {
currentByte &= ~(1<<bitCounter);
}
inputs[i].measurementBuffer[byteCounter] = currentByte;
}
}
///////////////////////////
// UPDATE BUFFER SUMS
///////////////////////////
void updateBufferSums() {
// the bufferSum is a running tally of the entire measurementBuffer
// add the new measurement and subtract the old one
for (int i=0; i<NUM_INPUTS; i++) {
byte currentByte = inputs[i].measurementBuffer[byteCounter];
boolean currentMeasurement = (currentByte >> bitCounter) & 0x01;
if (currentMeasurement) {
inputs[i].bufferSum++;
}
if (inputs[i].oldestMeasurement) {
inputs[i].bufferSum--;
}
}
}
///////////////////////////
// UPDATE BUFFER INDEX
///////////////////////////
void updateBufferIndex() {
bitCounter++;
if (bitCounter == 8) {
bitCounter = 0;
byteCounter++;
if (byteCounter == BUFFER_LENGTH) {
byteCounter = 0;
}
}
}
///////////////////////////
// UPDATE INPUT STATES
///////////////////////////
void updateInputStates() {
inputChanged = false;
for (int i=0; i<NUM_INPUTS; i++) {
inputs[i].prevPressed = inputs[i].pressed; // store previous pressed state (only used for mouse buttons)
if (inputs[i].pressed) {
if (inputs[i].bufferSum < releaseThreshold) {
inputChanged = true;
inputs[i].pressed = false;
digitalWrite(D2, HIGH);
delay(1000);
digitalWrite(D2, LOW);
if (inputs[i].isKey) {
Keyboard.release(inputs[i].keyCode);
digitalWrite(D2, LOW);
}
if (inputs[i].isMouseMotion) {
mouseHoldCount[i] = 0; // input becomes released, reset mouse hold
}
}
else if (inputs[i].isMouseMotion) {
mouseHoldCount[i]++; // input remains pressed, increment mouse hold
}
}
else if (!inputs[i].pressed) {
if (inputs[i].bufferSum > pressThreshold) { // input becomes pressed
inputChanged = true;
inputs[i].pressed = true;
if (inputs[i].isKey) {
Keyboard.press(inputs[i].keyCode);
}
}
}
}
#ifdef DEBUG3
if (inputChanged) {
Serial.println("change");
}
#endif
}
/*
///////////////////////////
// SEND KEY EVENTS (obsolete, used in versions with pro micro bootloader)
///////////////////////////
void sendKeyEvents() {
if (inputChanged) {
KeyReport report = {
0 };
for (int i=0; i<6; i++) {
report.keys[i] = 0;
}
int count = 0;
for (int i=0; i<NUM_INPUTS; i++) {
if (inputs[i].pressed && (count < 6)) {
report.keys[count] = inputs[i].keyCode;
#ifdef DEBUG3
Serial.println(report.keys[count]);
#endif
count++;
}
}
if (count > 0) {
report.modifiers = 0x00;
report.reserved = 1;
Keyboard.sendReport(&report);
}
else {
report.modifiers = 0x00;
report.reserved = 0;
Keyboard.sendReport(&report);
}
}
else {
// might need a delay here to compensate for the time it takes to send keyreport
}
}
*/
/////////////////////////////
// SEND MOUSE BUTTON EVENTS
/////////////////////////////
void sendMouseButtonEvents() {
if (inputChanged) {
for (int i=0; i<NUM_INPUTS; i++) {
if (inputs[i].isMouseButton) {
if (inputs[i].pressed) {
if (inputs[i].keyCode == MOUSE_LEFT) {
Mouse.press(MOUSE_LEFT);
}
if (inputs[i].keyCode == MOUSE_RIGHT) {
Mouse.press(MOUSE_RIGHT);
}
}
else if (inputs[i].prevPressed) {
if (inputs[i].keyCode == MOUSE_LEFT) {
Mouse.release(MOUSE_LEFT);
}
if (inputs[i].keyCode == MOUSE_RIGHT) {
Mouse.release(MOUSE_RIGHT);
}
}
}
}
}
}
//////////////////////////////
// SEND MOUSE MOVEMENT EVENTS
//////////////////////////////
void sendMouseMovementEvents() {
byte right = 0;
byte left = 0;
byte down = 0;
byte up = 0;
int horizmotion = 0;
int vertmotion = 0;
mouseMovementCounter++;
mouseMovementCounter %= MOUSE_MOTION_UPDATE_INTERVAL;
if (mouseMovementCounter == 0) {
for (int i=0; i<NUM_INPUTS; i++) {
#ifdef DEBUG_MOUSE
// Serial.println(inputs[i].isMouseMotion);
#endif
if (inputs[i].isMouseMotion) {
if (inputs[i].pressed) {
if (inputs[i].keyCode == MOUSE_MOVE_UP) {
// JL Changes (x4): now update to 1 + a hold factor, constrained between 1 and mouse max movement speed
up=constrain(1+mouseHoldCount[i]/MOUSE_RAMP_SCALE, 1, MOUSE_MAX_PIXELS);
}
if (inputs[i].keyCode == MOUSE_MOVE_DOWN) {
down=constrain(1+mouseHoldCount[i]/MOUSE_RAMP_SCALE, 1, MOUSE_MAX_PIXELS);
}
if (inputs[i].keyCode == MOUSE_MOVE_LEFT) {
left=constrain(1+mouseHoldCount[i]/MOUSE_RAMP_SCALE, 1, MOUSE_MAX_PIXELS);
}
if (inputs[i].keyCode == MOUSE_MOVE_RIGHT) {
right=constrain(1+mouseHoldCount[i]/MOUSE_RAMP_SCALE, 1, MOUSE_MAX_PIXELS);
}
}
}
}
// diagonal scrolling and left/right cancellation
if(left > 0)
{
if(right > 0)
{
horizmotion = 0; // cancel horizontal motion because left and right are both pushed
}
else
{
horizmotion = -left; // left yes, right no
}
}
else
{
if(right > 0)
{
horizmotion = right; // right yes, left no
}
}
if(down > 0)
{
if(up > 0)
{
vertmotion = 0; // cancel vertical motion because up and down are both pushed
}
else
{
vertmotion = down; // down yes, up no
}
}
else
{
if (up > 0)
{
vertmotion = -up; // up yes, down no
}
}
// now move the mouse
if( !((horizmotion == 0) && (vertmotion==0)) )
{
Mouse.move(horizmotion * PIXELS_PER_MOUSE_STEP, vertmotion * PIXELS_PER_MOUSE_STEP);
}
}
}
///////////////////////////
// ADD DELAY
///////////////////////////
void addDelay() {
loopTime = micros() - prevTime;
if (loopTime < TARGET_LOOP_TIME) {
int wait = TARGET_LOOP_TIME - loopTime;
delayMicroseconds(wait);
}
prevTime = micros();
#ifdef DEBUG_TIMING
if (loopCounter == 0) {
int t = micros()-prevTime;
Serial.println(t);
}
loopCounter++;
loopCounter %= 999;
#endif
}
///////////////////////////
// CYCLE LEDS
///////////////////////////
void cycleLEDs() {
pinMode(inputLED_a, INPUT);
pinMode(inputLED_b, INPUT);
pinMode(inputLED_c, INPUT);
digitalWrite(inputLED_a, LOW);
digitalWrite(inputLED_b, LOW);
digitalWrite(inputLED_c, LOW);
ledCycleCounter++;
ledCycleCounter %= 6;
if ((ledCycleCounter == 0) && inputs[0].pressed) {
pinMode(inputLED_a, INPUT);
digitalWrite(inputLED_a, LOW);
pinMode(inputLED_b, OUTPUT);
digitalWrite(inputLED_b, HIGH);
pinMode(inputLED_c, OUTPUT);
digitalWrite(inputLED_c, LOW);
}
if ((ledCycleCounter == 1) && inputs[1].pressed) {
pinMode(inputLED_a, OUTPUT);
digitalWrite(inputLED_a, HIGH);
pinMode(inputLED_b, OUTPUT);
digitalWrite(inputLED_b, LOW);
pinMode(inputLED_c, INPUT);
digitalWrite(inputLED_c, LOW);
}
if ((ledCycleCounter == 2) && inputs[2].pressed) {
pinMode(inputLED_a, OUTPUT);
digitalWrite(inputLED_a, LOW);
pinMode(inputLED_b, OUTPUT);
digitalWrite(inputLED_b, HIGH);
pinMode(inputLED_c, INPUT);
digitalWrite(inputLED_c, LOW);
}
if ((ledCycleCounter == 3) && inputs[3].pressed) {
pinMode(inputLED_a, INPUT);
digitalWrite(inputLED_a, LOW);
pinMode(inputLED_b, OUTPUT);
digitalWrite(inputLED_b, LOW);
pinMode(inputLED_c, OUTPUT);
digitalWrite(inputLED_c, HIGH);
}
if ((ledCycleCounter == 4) && inputs[4].pressed) {
pinMode(inputLED_a, OUTPUT);
digitalWrite(inputLED_a, LOW);
pinMode(inputLED_b, INPUT);
digitalWrite(inputLED_b, LOW);
pinMode(inputLED_c, OUTPUT);
digitalWrite(inputLED_c, HIGH);
}
if ((ledCycleCounter == 5) && inputs[5].pressed) {
pinMode(inputLED_a, OUTPUT);
digitalWrite(inputLED_a, HIGH);
pinMode(inputLED_b, INPUT);
digitalWrite(inputLED_b, LOW);
pinMode(inputLED_c, OUTPUT);
digitalWrite(inputLED_c, LOW);
}
}
///////////////////////////
// DANCE LEDS
///////////////////////////
void danceLeds()
{
int delayTime = 50;
int delayTime2 = 100;
// CIRCLE
for(int i=0; i<4; i++)
{
// UP
pinMode(inputLED_a, INPUT);
digitalWrite(inputLED_a, LOW);
pinMode(inputLED_b, OUTPUT);
digitalWrite(inputLED_b, HIGH);
pinMode(inputLED_c, OUTPUT);
digitalWrite(inputLED_c, LOW);
delay(delayTime);
//RIGHT
pinMode(inputLED_a, INPUT);
digitalWrite(inputLED_a, LOW);
pinMode(inputLED_b, OUTPUT);
digitalWrite(inputLED_b, LOW);
pinMode(inputLED_c, OUTPUT);
digitalWrite(inputLED_c, HIGH);
delay(delayTime);
// DOWN
pinMode(inputLED_a, OUTPUT);
digitalWrite(inputLED_a, HIGH);
pinMode(inputLED_b, OUTPUT);
digitalWrite(inputLED_b, LOW);
pinMode(inputLED_c, INPUT);
digitalWrite(inputLED_c, LOW);
delay(delayTime);
// LEFT
pinMode(inputLED_a, OUTPUT);
digitalWrite(inputLED_a, LOW);
pinMode(inputLED_b, OUTPUT);
digitalWrite(inputLED_b, HIGH);
pinMode(inputLED_c, INPUT);
digitalWrite(inputLED_c, LOW);
delay(delayTime);
}
// WIGGLE
for(int i=0; i<4; i++)
{
// SPACE
pinMode(inputLED_a, OUTPUT);
digitalWrite(inputLED_a, HIGH);
pinMode(inputLED_b, INPUT);
digitalWrite(inputLED_b, LOW);
pinMode(inputLED_c, OUTPUT);
digitalWrite(inputLED_c, LOW);
delay(delayTime2);
// CLICK
pinMode(inputLED_a, OUTPUT);
digitalWrite(inputLED_a, LOW);
pinMode(inputLED_b, INPUT);
digitalWrite(inputLED_b, LOW);
pinMode(inputLED_c, OUTPUT);
digitalWrite(inputLED_c, HIGH);
delay(delayTime2);
}
}
void updateOutLEDs()
{
boolean keyPressed = 0;
boolean mousePressed = 0;
for (int i=0; i<NUM_INPUTS; i++)
{
if (inputs[i].pressed)
{
if (inputs[i].isKey)
{
keyPressed = 1;
#ifdef DEBUG
Serial.print("Key ");
Serial.print(i);
Serial.println(" pressed");
#endif
}
else
{
mousePressed = 1;
}
}
}
if (keyPressed)
{
digitalWrite(outputK, HIGH);
//TXLED1;
}
else
{
digitalWrite(outputK, LOW);
//TXLED0;
}
if (mousePressed)
{
digitalWrite(outputM, HIGH);
//RXLED1;
}
else
{
digitalWrite(outputM, LOW);
//RXLED0;
}
}
#include "Arduino.h"
/*
/////////////////////////////////////////////////////////////////////////
// KEY MAPPINGS: WHICH KEY MAPS TO WHICH PIN ON THE Michi BOARD? //
/////////////////////////////////////////////////////////////////////////
- edit the keyCodes array below to change the keys sent by the Michi for each input
- the comments tell you which input sends that key (for example, by default 'w' is sent by pin D5)
- change the keys by replacing them. for example, you can replace 'w' with any other individual letter,
number, or symbol on your keyboard
- you can also use codes for other keys such as modifier and function keys (see the
the list of additional key codes at the bottom of this file)
*/
int keyCodes[NUM_INPUTS] = {
// top side of the michi board
KEY_UP_ARROW, // up arrow pad
KEY_DOWN_ARROW, // down arrow pad
KEY_LEFT_ARROW, // left arrow pad
KEY_RIGHT_ARROW, // right arrow pad
' ', // space button pad
MOUSE_LEFT, // click button pad
// female header on the back left side
'w', // pin D5
'a', // pin D4
's', // pin D3
'd', // pin D2
};
///////////////////////////
// NOISE CANCELLATION /////
///////////////////////////
#define SWITCH_THRESHOLD_OFFSET_PERC 5 // number between 1 and 49
// larger value protects better against noise oscillations, but makes it harder to press and release
// recommended values are between 2 and 20
// default value is 5
#define SWITCH_THRESHOLD_CENTER_BIAS 55 // number between 1 and 99
// larger value makes it easier to "release" keys, but harder to "press"
// smaller value makes it easier to "press" keys, but harder to "release"
// recommended values are between 30 and 70
// 50 is "middle" 2.5 volt center
// default value is 55
// 100 = 5V (never use this high)
// 0 = 0 V (never use this low
/////////////////////////
// MOUSE MOTION /////////
/////////////////////////
#define MOUSE_MOTION_UPDATE_INTERVAL 35 // how many loops to wait between
// sending mouse motion updates
#define PIXELS_PER_MOUSE_STEP 4 // a larger number will make the mouse
// move faster
#define MOUSE_RAMP_SCALE 150 // Scaling factor for mouse movement ramping
// Lower = more sensitive mouse movement
// Higher = slower ramping of speed
// 0 = Ramping off
#define MOUSE_MAX_PIXELS 10 // Max pixels per step for mouse movement
/*
///////////////////////////
// ADDITIONAL KEY CODES ///
///////////////////////////
- you can use these codes in the keyCodes array above
- to get modifier keys, function keys, etc
KEY_LEFT_CTRL
KEY_LEFT_SHIFT
KEY_LEFT_ALT
KEY_LEFT_GUI
KEY_RIGHT_CTRL
KEY_RIGHT_SHIFT
KEY_RIGHT_ALT
KEY_RIGHT_GUI
KEY_BACKSPACE
KEY_TAB
KEY_RETURN
KEY_ESC
KEY_INSERT
KEY_DELETE
KEY_PAGE_UP
KEY_PAGE_DOWN
KEY_HOME
KEY_END
KEY_CAPS_LOCK
KEY_F1
KEY_F2
KEY_F3
KEY_F4
KEY_F5
KEY_F6
KEY_F7
KEY_F8
KEY_F9
KEY_F10
KEY_F11
KEY_F12
*/
Comments