Since last time I blogged, I've made some improvements on the Doodle Band.
My new 2.4" displays came in, so I've switched over to that display instead of the 2.6". This made a considerable difference in terms of how it will fit on the wrist when it's a bracelet.
Something I noticed a few days ago was that after playing with the Doodle Band for even a minute I would quickly get bored. I would only end up with simple drawings of lines and curls, and this was only to make sure that it was working correctly. I had no motivation to draw and play with it as it is intended, and this was because the color scheme given was discordant, simple and extremely difficult to draw anything sophisticated with.
I decided to add some color palettes to choose from on the device that can inspire and make way for creative art. I gathered my color palettes from a design company called Canva.
I ran into an issue with integrating internet colors into my program, however. When I would put a color's hex value into the code, it would turn out an entirely different color on the display. For example a pale blue, #DDE2E3, came out scarlet red. After looking at how the built-in colors were formatted in the Adafruit_ILI9341 library, I discovered that instead of using the standard 3 byte color (8 bits each for R, G, and B) they use 2 byte color (5 bits for R, 6 bits for G, and 5 bits for B). So I wrote a program to convert a 3 byte color to 2 byte format:
My new 2.4" displays came in, so I've switched over to that display instead of the 2.6". This made a considerable difference in terms of how it will fit on the wrist when it's a bracelet.
Something I noticed a few days ago was that after playing with the Doodle Band for even a minute I would quickly get bored. I would only end up with simple drawings of lines and curls, and this was only to make sure that it was working correctly. I had no motivation to draw and play with it as it is intended, and this was because the color scheme given was discordant, simple and extremely difficult to draw anything sophisticated with.
I decided to add some color palettes to choose from on the device that can inspire and make way for creative art. I gathered my color palettes from a design company called Canva.
I ran into an issue with integrating internet colors into my program, however. When I would put a color's hex value into the code, it would turn out an entirely different color on the display. For example a pale blue, #DDE2E3, came out scarlet red. After looking at how the built-in colors were formatted in the Adafruit_ILI9341 library, I discovered that instead of using the standard 3 byte color (8 bits each for R, G, and B) they use 2 byte color (5 bits for R, 6 bits for G, and 5 bits for B). So I wrote a program to convert a 3 byte color to 2 byte format:
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial.print("0x");
colors(0x81afd7); // insert hex color (in 0x______ format) to be re-formatted
}
void loop() {}
void colors(byte long val) {
// represent the colors as two nibbles each in hex
byte long red = (val & 0xFF0000) >> 16;
byte long green = (val & 0x00FF00) >> 8;
byte long blue = (val & 0x0000FF);
// scale from 2 nibbles to 5 bits (for red and blue) or 6 bits (for green)
byte long newRed = map(red, 0, 255, 0, 31);
byte long newGreen = map(green, 0, 255, 0, 63);
byte long newBlue = map(blue, 0, 255, 0, 31);
// shift the scaled colors back
byte long shiftRed = newRed << 11;
byte long shiftGreen = newGreen << 5;
byte long shiftBlue = newBlue;
// add RGB
long newHex = shiftRed + shiftGreen + shiftBlue;
// print as hex
Serial.print(newHex, HEX);
}
// put your setup code here, to run once:
Serial.begin(9600);
Serial.print("0x");
colors(0x81afd7); // insert hex color (in 0x______ format) to be re-formatted
}
void loop() {}
void colors(byte long val) {
// represent the colors as two nibbles each in hex
byte long red = (val & 0xFF0000) >> 16;
byte long green = (val & 0x00FF00) >> 8;
byte long blue = (val & 0x0000FF);
// scale from 2 nibbles to 5 bits (for red and blue) or 6 bits (for green)
byte long newRed = map(red, 0, 255, 0, 31);
byte long newGreen = map(green, 0, 255, 0, 63);
byte long newBlue = map(blue, 0, 255, 0, 31);
// shift the scaled colors back
byte long shiftRed = newRed << 11;
byte long shiftGreen = newGreen << 5;
byte long shiftBlue = newBlue;
// add RGB
long newHex = shiftRed + shiftGreen + shiftBlue;
// print as hex
Serial.print(newHex, HEX);
}
In order to switch between color palettes on the device, I added a "next" button that looks like an arrow which toggles between five groups of five colors. This ran me into my next issue: debouncing. I could press the arrow once and it would detect it was three presses then land on a color scheme which was not the subsequent one.
So I had to figure out how to incorporate debouncing into a touch screen. I used Arduino's built-in Debounce code, but had to make some edits to it, as I am not dealing with a button and LED which have binary states. I needed it to detect whether I was pressing a specific area of the screen for long enough after having not been pressing it. These are the pieces of code I have added for debounce so far, which work almost perfectly:
So I had to figure out how to incorporate debouncing into a touch screen. I used Arduino's built-in Debounce code, but had to make some edits to it, as I am not dealing with a button and LED which have binary states. I needed it to detect whether I was pressing a specific area of the screen for long enough after having not been pressing it. These are the pieces of code I have added for debounce so far, which work almost perfectly:
// variables for debouncing:
int lastButtonState = 0; // the previous reading from the input pin
long lastDebounceTime; // the last time the output pin was toggled
long debounceDelay = 50; // the debounce time; increase if the output flickers
int reading;
void setup() {
// current color palette:
current1 = frost;
current2 = lead;
current3 = amber;
current4 = nightfall;
current5 = bark;
counter = 0;
reading = 0;
}
void loop() {
if (p.y > BOXSIZE) {
reading = 0; // "next" button has not been pressed
}
else if (p.y < BOXSIZE) {
oldcolor = currentcolor;
if (p.x < BOXSIZE) {
currentcolor = current1;
tft.drawRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
reading = 0;
} else if (p.x < BOXSIZE*2) {
currentcolor = current2;
tft.drawRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
reading = 0;
} else if (p.x < BOXSIZE*3) {
currentcolor = current3;
tft.drawRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
reading = 0;
} else if (p.x < BOXSIZE*4) {
currentcolor = current4;
tft.drawRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
reading = 0;
} else if (p.x < BOXSIZE*5) {
currentcolor = current5;
tft.drawRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
reading = 0;
} else if (p.x < BOXSIZE*6) {
reading = 1; // "next" button has been pressed
tft.fillRect(0, 0, BOXSIZE, BOXSIZE, current1);
tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, current2);
tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, current3);
tft.fillRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, current4);
tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, current5);
}
}
/*------------------------- DEBOUNCE ---------------------------*/
if (reading != lastButtonState) {
lastDebounceTime = millis();
}
if ((lastDebounceTime != 0) && ((millis() - lastDebounceTime) > 50)) {
if (reading == 1) { // if "next" is the current state
if (counter == 0) {
current1 = crema;
current2 = peche;
current3 = cafe;
current4 = rosada;
current5 = sangria;
counter = 1;
}
else if (counter == 1) {
current1 = frost;
current2 = lead;
current3 = amber;
current4 = nightfall;
current5 = bark;
counter = 0;
}
lastDebounceTime = 0;
}
}
lastButtonState = reading;
}
int lastButtonState = 0; // the previous reading from the input pin
long lastDebounceTime; // the last time the output pin was toggled
long debounceDelay = 50; // the debounce time; increase if the output flickers
int reading;
void setup() {
// current color palette:
current1 = frost;
current2 = lead;
current3 = amber;
current4 = nightfall;
current5 = bark;
counter = 0;
reading = 0;
}
void loop() {
if (p.y > BOXSIZE) {
reading = 0; // "next" button has not been pressed
}
else if (p.y < BOXSIZE) {
oldcolor = currentcolor;
if (p.x < BOXSIZE) {
currentcolor = current1;
tft.drawRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
reading = 0;
} else if (p.x < BOXSIZE*2) {
currentcolor = current2;
tft.drawRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
reading = 0;
} else if (p.x < BOXSIZE*3) {
currentcolor = current3;
tft.drawRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
reading = 0;
} else if (p.x < BOXSIZE*4) {
currentcolor = current4;
tft.drawRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
reading = 0;
} else if (p.x < BOXSIZE*5) {
currentcolor = current5;
tft.drawRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
reading = 0;
} else if (p.x < BOXSIZE*6) {
reading = 1; // "next" button has been pressed
tft.fillRect(0, 0, BOXSIZE, BOXSIZE, current1);
tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, current2);
tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, current3);
tft.fillRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, current4);
tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, current5);
}
}
/*------------------------- DEBOUNCE ---------------------------*/
if (reading != lastButtonState) {
lastDebounceTime = millis();
}
if ((lastDebounceTime != 0) && ((millis() - lastDebounceTime) > 50)) {
if (reading == 1) { // if "next" is the current state
if (counter == 0) {
current1 = crema;
current2 = peche;
current3 = cafe;
current4 = rosada;
current5 = sangria;
counter = 1;
}
else if (counter == 1) {
current1 = frost;
current2 = lead;
current3 = amber;
current4 = nightfall;
current5 = bark;
counter = 0;
}
lastDebounceTime = 0;
}
}
lastButtonState = reading;
}
Again, this is NOT the full code, but the pieces of my code that incorporate debouncing. As it is, it does not have the quick toggling issue. The debounce functionality is working, however I have to press a different part of the screen before I press the "next" button in order for it to work. This is because it is looking for a significant CHANGE. I am still working on this, but it's not a bad start! Here are some "paintings" I made today with my new colors (I don't know why I just did flowers):