Platform
- Attiny85 with AttinyCores
- 1306 OLED i2c with Tiny4KDisplay
Goal
- using a joystick for menu navigation
- up/down choose
- left enter (not finished yet)
- right back (not finished yet)
- inverse display the chosen item.
I come from python word which is why I am using a linked list for menu navigation. I found a weird bug that stops me from displaying some of the long text. I found that if the defined Nodes over a certain amount of number, item text over 5 chars will not display. I don't know why this is related to the number of instances. I managed to narrow down the range of the bug. In the code. if those 3 lines are commented, all the items are displayed correct, if not, only up to ccccc
but not dddddd
.
The flash and RAM consumption of the failure situation is
Sketch uses 5180 bytes (63%) of program storage space. Maximum is 8192 bytes.
Global variables use 280 bytes (54%) of dynamic memory, leaving 232 bytes for local variables. Maximum is 512 bytes.
My code is as below. I broke it into parts to highlighted the problem. But it is a continuous file actually.
Thank you for any insight.
PS: I know there are methods that avoid oop, but I think this weird bug is so close to being fixed, (or proved to be an actual bug in the package/compiler). So I would like to pursue an answer to this question.
Update:
I tried to use another method that uses a List of Strings instead of a class to achieve the same function. The Bug is still there. I guess it is because there are too many instances of String. The question is not changed: "Is there a limitation of how many instances of the String
class?".
#include <Tiny4kOLED.h>
// input setup
int x = 512;
int y = 512;
int lastx = 512;
int lasty = 512;
bool left = false;
bool right = false;
bool up = false;
bool down = false;
char input() {
x = analogRead(A2);
y = analogRead(A3);
if( (lastx > 256) & (x <= 256) ){
left = true;
}
if( (lastx < 768) & (x >= 768) ){
right = true;
}
if( (lasty > 256) & (y <= 256) ){
down = true;
}
if( (lasty < 768) & (y >= 768) ){
up = true;
}
lastx = x;
lasty = y;
}
// item data
class Node
{
public:
String text;
uint8_t id;
Node * next;
Node * previous;
Node * parent;
Node * child;
Node(String s, int n){
text = s;
id = n;
next = NULL;
previous = NULL;
parent = NULL;
child = NULL;
}
void append_next(Node * other){
this->next = other;
other->previous = this;
other->parent = this->parent;
}
void append_child(Node * other){
this->child = other;
other->parent = this;
}
};
Node main_0("aaa", 1);
Node main_1("bbbb", 2);
Node main_2("ccccc", 3);
Node main_3("dddddd", 4);
Node main_4("eeeeeee", 5);
Node main_5("ffffffff", 6);
This is how the error can be repeated.
/* Uncomment The following 3 lines will cause the problem*/
//Node item_0_0("aaa", 7);
//Node item_0_1("bbb", 8);
//Node item_0_2("ccc", 9);
Node * current_sel = (&main_0);
Node * screen_top = (&main_0);
void setup() {
// oled setup
oled.begin(0,0);
oled.enableChargePump();
oled.setRotation(1);
// oled.setInternalIref(true);
oled.enableZoomIn();
oled.setFont(FONT6X8);
oled.clear();
oled.switchRenderFrame();
oled.clear();
oled.switchFrame();
oled.on();
// oled setup end
// input setup
pinMode(A2, INPUT); // X
pinMode(A3, INPUT); // Y
// input setup end
// data
main_0.append_next(&main_1);
main_1.append_next(&main_2);
main_2.append_next(&main_3);
main_3.append_next(&main_4);
main_4.append_next(&main_5);
}
void loop() {
// input read
input();
// move current;
if(up){
up = false;
if(current_sel->previous != NULL){
if(screen_top == current_sel){
screen_top = screen_top->previous;
}
current_sel = current_sel->previous;
}
}
if(down){
down = false;
if(current_sel->next != NULL){
if(screen_top->next->next->next == current_sel){
screen_top = screen_top->next;
}
current_sel = current_sel->next;
}
}
// oled update
oled.clear();
oled.setCursor(64, 0);
oled.print(current_sel->text);
Node * current_draw = screen_top;
int i = 0;
while(true){
oled.setCursor(0,i);
if(current_draw == current_sel){
oled.invertOutput(true);
}
oled.print(current_draw->text);
oled.invertOutput(false);
if(current_draw->next == NULL){
break;
}
current_draw = current_draw->next;
i++;
if(i >= 4){
break;
}
}
oled.switchFrame();
delay(50);
}