I'm new to arduino and currently trying to build a small program with multiple screens and buttons and a counter. when I try to convert a int to a chararray it messes up the world. with out it what I have so far works any suggestions on what I'm doing wrong? with the code to convert the int to chararray it seems to lock up the program when I switch from main screen to options screen then back. I put some serial outs to narrow down where the flaw is.
My results are it is between
test1++; Serial.println("oops check");
str = String(test1); Serial.println("sanity check");
Something hangs it up after it outputs "oops check" so I figure it is str = String(test1);
I have been searching and trying every thing I can find. if someone can give me a kick in the right direction. I'm usin the tft seedstudio v2 display with the modified tft library for text direction.
/*
Title: TouchScreenButton Tutorial
About: Example/tutorial file for how to create buttons with the TouchScreenButtons library
Author: Richard Kirkpatrick
Date: 20 July 2014
*/
// Libraries
#include <stdint.h>
#include <SeeedTouchScreen.h> // Library for the Seeed Studio TFT Touch Shield
#include <TFTv2.h> // Library for the Seeed Studio TFT Touch Shield
#include <TouchScreenGeometry.h> // Library for drawing geometric shapes for the touch screen
#include <TouchScreenStrings.h> // Library for drawing strings for the touch screen
#include <TouchScreenButtons.h> // Library for creating buttons for the keypad
#include <SPI.h>
//Measured ADC values for (0,0) and (210-1,320-1)
//TS_MINX corresponds to ADC value when X = 0
//TS_MINY corresponds to ADC value when Y = 0
//TS_MAXX corresponds to ADC value when X = 240 -1
//TS_MAXY corresponds to ADC value when Y = 320 -1
#define TS_MINX 890*2
#define TS_MAXX 116*2
#define TS_MINY 913*2
#define TS_MAXY 83*2
TouchScreen ts = TouchScreen(XP, YP, XM, YM);
// Global variables
String str;
Button bigButton;
Button buttons[12];
Button reset;
Button back;
int screen = 1;
int test;
int test1 = 0;
char b[5];
void setup()
{
// Initializes the TFT library
Tft.TFTinit();
// Start the Serial port. Used to determine which button was pressed.
Serial.begin(9600);
screen = 1;
}
void loop()
{ test1++; Serial.println("oops check");
str = String(test1); Serial.println("sanity check");
str.toCharArray(b,5);
Serial.print("screen = "); Serial.print(screen );
// A point objects holds x, y, and z coordinates
Point p = ts.getPoint();
p.x = map(p.x, TS_MINX, TS_MAXX, 240, 0);
p.y = map(p.y, TS_MINY, TS_MAXY, 320, 0);
// Determine which button was pressed
int userInput = -1; // -1 means no button is pressed
if (p.z > __PRESURE){
userInput = getButtonNumber(p.x, p.y);
Serial.print("X = "); Serial.print(p.x);
Serial.print("\tY = "); Serial.print(p.y);
Serial.print("\tPressure = "); Serial.println(p.z);
}
// Show which button was pressed on the Serial monitor
if (userInput == 13) {
Serial.println("Options button was pressed!");
bigButton.buttonDisplay();
}
if (userInput == 15) {
Serial.println("back button was pressed!");
back.buttonDisplay();
}
else if (userInput == 14) {
Serial.println("reset button was pressed!");
reset.buttonDisplay();
}
delay(10);
if (screen == 1) {
if (test == 1) {
Tft.fillScreen(); }
Serial.print("test1 = "); Serial.println(b); // prints "Hello String"
// Draw reset button
reset.setValues(75, 215, 35, 100);
reset.draw();
// Draw the big button
bigButton.setValues(15, 185, 35, 130);
bigButton.draw();
Tft.drawRectangle(40, 15, 70, 120,BLUE);
Tft.setDisplayDirect(UP2DOWN);
Tft.drawString("Frays",100,20,2,RED);
Tft.drawString(b,65,20, 2, BLUE);
//Draw reset buttons text
TouchScreenString resetText("RESET", 100, 230, 2, RED);
resetText.drawText();
Serial.println("a"); // prints "Hello String"
// Draw the big button's text
TouchScreenString bigButtonText("OPTIONS", 40, 197, 2, WHITE);
bigButtonText.drawText();
test = 0;
}
if (screen == 2) {
if (test == 0) {Tft.fillScreen();}
// draw back button
back.setValues(15, 15, 35, 85);
back.draw();
Tft.setDisplayDirect(UP2DOWN);
// Draw the back button's text
TouchScreenString backText("BACK", 40, 30, 2, WHITE);
backText.drawText();
test = 1;
}}
// Gets which button was pressed. If no button is pressed, -1 is returned.
int getButtonNumber(int xInput, int yInput)
{
if (screen == 1) {
if (bigButton.isPressed(xInput, yInput)) {
screen = 2;
return 13; // Signifies big button was pressed
} }
if (screen ==2) {
if (back.isPressed(xInput, yInput)) {
screen = 1;
return 15; // Signifies big button was pressed
}}
if (screen == 1) {
if (reset.isPressed(xInput, yInput)) {
test1 = 0;
return 14; // Signifies reset button was pressed
}}
else {
return -1; // Signifies no button was pressed
}
}
1 Answer 1
My guess is you are running out of RAM. Your various string constants alone take up 202 bytes. Then there is this:
test1++;
str = String(test1);
str.toCharArray(b,5);
That is very likely to fragment memory, as test1
gets larger and larger. So you are fragmenting RAM, of which you don't have much to start with.
Why are you even converting test1 into a String object? And then converting it back into an array?
The array b
can only hold 4 digits as it needs one byte for the trailing null-terminator.
I suggest you stop doing that String stuff, and also use the F()
macro like this ...
Change:
Serial.println("Options button was pressed!");
to:
Serial.println(F("Options button was pressed!"));
Ditto for all the other places you are displaying stuff.
-
I agree with this solution, too. Although I find it curious that it runs out of memory during the first iteration. Printing using flash memory strings is something that I do most of the time now with my Uno/Mega, although if you're using a small micro-c there may be limited flash space to use (you probably wouldn't be printing anything then anyway as smaller devices often don't have serial ports).bladepanthera– bladepanthera2015年09月02日 09:31:22 +00:00Commented Sep 2, 2015 at 9:31
-
I agree it is running out of ram and fragmenting. as far as the
Serial.println
and all the other serial stuff I do not need. the reason for the String stuff is this. the device I'm trying to make I wanted the screen orientated so it is wider than it is tall. I can get the characters to display in the correct orientation but when I try toTft.drawNumber(1024, 0, 0, 1, RED);
the numbers are turned the right way but reads from bottom to top not left to right. can't get it to do right. this was my work around. I used to use avrgcc but been years. any suggestions?Michael– Michael2015年09月03日 01:29:15 +00:00Commented Sep 3, 2015 at 1:29 -
Thanks for the responses I'm still learning and trying to remember.Michael– Michael2015年09月03日 01:35:00 +00:00Commented Sep 3, 2015 at 1:35
str = String(test1);
I can't figure why. the way the screen acts it's like the program corrupts. I'm getting stray lines and shapes on the screen at times.str.toCharArray(b,5);
andtest1++
and it still fragments. which I find odd. if I set test1=20 it locks up. am I still running out of ram? it just doesn't seem right. I know I'm over looking something. guess I will go back to trying to get the drawnumber to work again.