Multiple Loop functions in libraries

When using code examples from library items I repeatedly get the following error or a similar one indicating too many loop definitions. I'm a babe in the woods when it comes to coding and usually use examples to power my projects. I'm not creating anything I just like to see what is happening when you put things together.

main.cpp.o (symbol from plugin): In function atexit': (.text+0x0): multiple definition of loop'
C:\Users\nlkir\AppData\Local\Temp\arduino\sketches\1DEDCAB07D328BE4124A273397C3DF57\sketch\spfd5408_graphicstest.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here
collect2.exe: error: ld returned 1 exit status

exit status 1

Compilation error: exit status 1
/code
// IMPORTANT: Adafruit_TFTLCD LIBRARY MUST BE SPECIFICALLY
// CONFIGURED FOR EITHER THE TFT SHIELD OR THE BREAKOUT BOARD.
// SEE RELEVANT COMMENTS IN Adafruit_TFTLCD.h FOR SETUP.

// Modified for SPFD5408 Library by Joao Lopes
// Version 0.9.2 - Rotation for Mega and screen initial

// *** SPFD5408 change -- Begin
#include <SPFD5408_Adafruit_GFX.h> // Core graphics library
#include <SPFD5408_Adafruit_TFTLCD.h> // Hardware-specific library
#include <SPFD5408_TouchScreen.h>
// *** SPFD5408 change -- End

// The control pins for the LCD can be assigned to any digital or
// analog pins...but we'll use the analog pins as this allows us to
// double up the pins with the touch screen (see the TFT paint example).
#define LCD_CS A3 // Chip Select goes to Analog 3
#define LCD_CD A2 // Command/Data goes to Analog 2
#define LCD_WR A1 // LCD Write goes to Analog 1
#define LCD_RD A0 // LCD Read goes to Analog 0

#define LCD_RESET A4 // Can alternately just connect to Arduino's reset pin

// When using the BREAKOUT BOARD only, use these 8 data lines to the LCD:
// For the Arduino Uno, Duemilanove, Diecimila, etc.:
// D0 connects to digital pin 8 (Notice these are
// D1 connects to digital pin 9 NOT in order!)
// D2 connects to digital pin 2
// D3 connects to digital pin 3
// D4 connects to digital pin 4
// D5 connects to digital pin 5
// D6 connects to digital pin 6
// D7 connects to digital pin 7
// For the Arduino Mega, use digital pins 22 through 29
// (on the 2-row header at the end of the board).

// Assign human-readable names to some common 16-bit color values:
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF

Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
// If using the shield, all control and data lines are fixed, and
// a simpler declaration can optionally be used:
// Adafruit_TFTLCD tft;

// -- Setup

void setup(void) {

Serial.begin(9600);

progmemPrintln(PSTR("TFT LCD test"));

#ifdef USE_ADAFRUIT_SHIELD_PINOUT
progmemPrintln(PSTR("Using Adafruit 2.8" TFT Arduino Shield Pinout"));
#else
progmemPrintln(PSTR("Using Adafruit 2.8" TFT Breakout Board Pinout"));
#endif

tft.reset();

// *** SPFD5408 change -- Begin

// Original code commented

// uint16_t identifier = tft.readID();
//
// if(identifier == 0x9325) {
// Serial.println(F("Found ILI9325 LCD driver"));
// } else if(identifier == 0x9328) {
// Serial.println(F("Found ILI9328 LCD driver"));
// } else if(identifier == 0x7575) {
// Serial.println(F("Found HX8347G LCD driver"));
// } else if(identifier == 0x9341) {
// Serial.println(F("Found ILI9341 LCD driver"));
// } else if(identifier == 0x8357) {
// Serial.println(F("Found HX8357D LCD driver"));
// } else {
// Serial.print(F("Unknown LCD driver chip: "));
// Serial.println(identifier, HEX);
// Serial.println(F("If using the Adafruit 2.8" TFT Arduino shield, the line:"));
// Serial.println(F(" #define USE_ADAFRUIT_SHIELD_PINOUT"));
// Serial.println(F("should appear in the library header (Adafruit_TFT.h)."));
// Serial.println(F("If using the breakout board, it should NOT be #defined!"));
// Serial.println(F("Also if using the breakout, double-check that all wiring"));
// Serial.println(F("matches the tutorial."));
// return;
// }
//
// tft.begin(identifier);

// Code changed to works

tft.begin(0x9341); // SDFP5408

tft.setRotation(0); // Need for the Mega, please changed for your choice or rotation initial

// *** SPFD5408 change -- End

progmemPrintln(PSTR("Benchmark Time (microseconds)"));

progmemPrint(PSTR("Screen fill "));
Serial.println(testFillScreen());
delay(500);

progmemPrint(PSTR("Text "));
Serial.println(testText());
delay(3000);

progmemPrint(PSTR("Lines "));
Serial.println(testLines(CYAN));
delay(500);

progmemPrint(PSTR("Horiz/Vert Lines "));
Serial.println(testFastLines(RED, BLUE));
delay(500);

progmemPrint(PSTR("Rectangles (outline) "));
Serial.println(testRects(GREEN));
delay(500);

progmemPrint(PSTR("Rectangles (filled) "));
Serial.println(testFilledRects(YELLOW, MAGENTA));
delay(500);

progmemPrint(PSTR("Circles (filled) "));
Serial.println(testFilledCircles(10, MAGENTA));

progmemPrint(PSTR("Circles (outline) "));
Serial.println(testCircles(10, WHITE));
delay(500);

progmemPrint(PSTR("Triangles (outline) "));
Serial.println(testTriangles());
delay(500);

progmemPrint(PSTR("Triangles (filled) "));
Serial.println(testFilledTriangles());
delay(500);

progmemPrint(PSTR("Rounded rects (outline) "));
Serial.println(testRoundRects());
delay(500);

progmemPrint(PSTR("Rounded rects (filled) "));
Serial.println(testFilledRoundRects());
delay(500);

progmemPrintln(PSTR("Done!"));
}

void loop(void) {
for(uint8_t rotation=0; rotation<4; rotation++) {
tft.setRotation(rotation);
testText();
delay(2000);
}
}

unsigned long testFillScreen() {
unsigned long start = micros();
tft.fillScreen(BLACK);
tft.fillScreen(RED);
tft.fillScreen(GREEN);
tft.fillScreen(BLUE);
tft.fillScreen(BLACK);
return micros() - start;
}

unsigned long testText() {
tft.fillScreen(BLACK);
unsigned long start = micros();
tft.setCursor(0, 0);
tft.setTextColor(WHITE); tft.setTextSize(1);
tft.println("Hello World!");
tft.setTextColor(YELLOW); tft.setTextSize(2);
tft.println(1234.56);
tft.setTextColor(RED); tft.setTextSize(3);
tft.println(0xDEADBEEF, HEX);
tft.println();
tft.setTextColor(GREEN);
tft.setTextSize(5);
tft.println("Groop");
tft.setTextSize(2);
tft.println("I implore thee,");
tft.setTextSize(1);
tft.println("my foonting turlingdromes.");
tft.println("And hooptiously drangle me");
tft.println("with crinkly bindlewurdles,");
tft.println("Or I will rend thee");
tft.println("in the gobberwarts");
tft.println("with my blurglecruncheon,");
tft.println("see if I don't!");
return micros() - start;
}

unsigned long testLines(uint16_t color) {
unsigned long start, t;
int x1, y1, x2, y2,
w = tft.width(),
h = tft.height();

tft.fillScreen(BLACK);

x1 = y1 = 0;
y2 = h - 1;
start = micros();
for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
x2 = w - 1;
for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
t = micros() - start; // fillScreen doesn't count against timing

tft.fillScreen(BLACK);

x1 = w - 1;
y1 = 0;
y2 = h - 1;
start = micros();
for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
x2 = 0;
for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
t += micros() - start;

tft.fillScreen(BLACK);

x1 = 0;
y1 = h - 1;
y2 = 0;
start = micros();
for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
x2 = w - 1;
for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
t += micros() - start;

tft.fillScreen(BLACK);

x1 = w - 1;
y1 = h - 1;
y2 = 0;
start = micros();
for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
x2 = 0;
for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);

return micros() - start;
}

unsigned long testFastLines(uint16_t color1, uint16_t color2) {
unsigned long start;
int x, y, w = tft.width(), h = tft.height();

tft.fillScreen(BLACK);
start = micros();
for(y=0; y<h; y+=5) tft.drawFastHLine(0, y, w, color1);
for(x=0; x<w; x+=5) tft.drawFastVLine(x, 0, h, color2);

return micros() - start;
}

unsigned long testRects(uint16_t color) {
unsigned long start;
int n, i, i2,
cx = tft.width() / 2,
cy = tft.height() / 2;

tft.fillScreen(BLACK);
n = min(tft.width(), tft.height());
start = micros();
for(i=2; i<n; i+=6) {
i2 = i / 2;
tft.drawRect(cx-i2, cy-i2, i, i, color);
}

return micros() - start;
}

unsigned long testFilledRects(uint16_t color1, uint16_t color2) {
unsigned long start, t = 0;
int n, i, i2,
cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;

tft.fillScreen(BLACK);
n = min(tft.width(), tft.height());
for(i=n; i>0; i-=6) {
i2 = i / 2;
start = micros();
tft.fillRect(cx-i2, cy-i2, i, i, color1);
t += micros() - start;
// Outlines are not included in timing results
tft.drawRect(cx-i2, cy-i2, i, i, color2);
}

return t;
}

unsigned long testFilledCircles(uint8_t radius, uint16_t color) {
unsigned long start;
int x, y, w = tft.width(), h = tft.height(), r2 = radius * 2;

tft.fillScreen(BLACK);
start = micros();
for(x=radius; x<w; x+=r2) {
for(y=radius; y<h; y+=r2) {
tft.fillCircle(x, y, radius, color);
}
}

return micros() - start;
}

unsigned long testCircles(uint8_t radius, uint16_t color) {
unsigned long start;
int x, y, r2 = radius * 2,
w = tft.width() + radius,
h = tft.height() + radius;

// Screen is not cleared for this one -- this is
// intentional and does not affect the reported time.
start = micros();
for(x=0; x<w; x+=r2) {
for(y=0; y<h; y+=r2) {
tft.drawCircle(x, y, radius, color);
}
}

return micros() - start;
}

unsigned long testTriangles() {
unsigned long start;
int n, i, cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;

tft.fillScreen(BLACK);
n = min(cx, cy);
start = micros();
for(i=0; i<n; i+=5) {
tft.drawTriangle(
cx , cy - i, // peak
cx - i, cy + i, // bottom left
cx + i, cy + i, // bottom right
tft.color565(0, 0, i));
}

return micros() - start;
}

unsigned long testFilledTriangles() {
unsigned long start, t = 0;
int i, cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;

tft.fillScreen(BLACK);
start = micros();
for(i=min(cx,cy); i>10; i-=5) {
start = micros();
tft.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
tft.color565(0, i, i));
t += micros() - start;
tft.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
tft.color565(i, i, 0));
}

return t;
}

unsigned long testRoundRects() {
unsigned long start;
int w, i, i2,
cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;

tft.fillScreen(BLACK);
w = min(tft.width(), tft.height());
start = micros();
for(i=0; i<w; i+=6) {
i2 = i / 2;
tft.drawRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(i, 0, 0));
}

return micros() - start;
}

unsigned long testFilledRoundRects() {
unsigned long start;
int i, i2,
cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;

tft.fillScreen(BLACK);
start = micros();
for(i=min(tft.width(), tft.height()); i>20; i-=6) {
i2 = i / 2;
tft.fillRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(0, i, 0));
}

return micros() - start;
}

// Copy string from flash to serial port
// Source string MUST be inside a PSTR() declaration!
void progmemPrint(const char *str) {
char c;
while(c = pgm_read_byte(str++)) Serial.print(c);
}

// Same as above, with trailing newline
void progmemPrintln(const char *str) {
progmemPrint(str);
Serial.println();
}
/code

Hello nlkirchn

Welcome to the worldbest Arduino forum ever.

Check this error reported by the compiler first.

Have a nice day and enjoy coding in C++.

There is only one tab open, the error as I see it looks for loop in the libraries as well my sketch which has only one loop. I wouldn’t think that I would have to modify a library to get my sketch to run.

Do you have any other .ino or .cpp files in the same folder?

@nlkirchn -

Start your code repair with "escaping" (prefix the double quote with this ) or removing the "inches" double-quote in the PSTR...

  progmemPrintln(PSTR("Using Adafruit 2.8" TFT Arduino Shield Pinout"));
#else
  progmemPrintln(PSTR("Using Adafruit 2.8" TFT Breakout Board Pinout"));
#endif

... it prematurely stops the buffer being stored in flash thus jaming the whole program in flash.

It should be this:

  progmemPrintln(PSTR("Using Adafruit 2.8\" TFT Arduino Shield Pinout"));
#else
  progmemPrintln(PSTR("Using Adafruit 2.8\" TFT Breakout Board Pinout"));
#endif

I think I remember you from a year ago...

  tft.println("my foonting turlingdromes.");
  tft.println("And hooptiously drangle me");
  tft.println("with crinkly bindlewurdles,");
  tft.println("Or I will rend thee");
  tft.println("in the gobberwarts");
  tft.println("with my blurglecruncheon,");
  tft.println("see if I don't!");

You need to include the library files...

Here's what you need to do:

  1. Go to this Git repo:
    GitHub - JoaoLopesF/SPFD5408: Adafruit Libraries changed to works in TFT 2.4 shields with the SPFD5408 controller for Arduino Uno and Mega (Discontinued library)
  2. Download all the .H, .CPP and .C
  3. Include these files as TABS in your IDE
  4. You will get compile errors, "file not found" (or something), where you need to change library include "<" and ">" to double quotes to make those files "local"

I may have forgotten a couple simple things, but the errors you get will be easy to correct.

The result:

Sketch uses 16648 bytes (54%) of program storage space. Maximum is 30720 bytes.
Global variables use 474 bytes (23%) of dynamic memory, leaving 1574 bytes for local variables. Maximum is 2048 bytes.

(or, download and install the complete library and skip this mess... next time, know that downloading one file is not how to do this)

Hi mate, Welcome
OK Then you should absolutely go through this course
to not be a babe in the woods
it'll take you like 90mins to 2 hours, i'ts not a biggie and you'll gain so much from it.

Arduino Programming Course

I searched each file for loop and found a couple in comment lines and deleted them, it didn’t make a difference. I’ve attached the library.

SPFD5408-master.zip (192 KB)

@nlkirchn - Yes, "it" did work: I described how (and why) it worked on IDE, and even gave you a link to a simulator where all you need to do is press a green button... so discovering what you are doing differently will solve the issue.

@nlkirchn go to @xfpd's simulation and download the entire projext as a zip file.

Un-zip it and make sure the folder name is the same as the main *.ino file inside the folder.

Then when you open it with the IDE, all that tab work copy pasting and getting old will be done automagically.

a7

@alto777 - When I pasted the file contents into the tabs, I had to change a few #include calls from < system > to "local"... that is why I commented about avoiding my mess and download the main .zip and install with IDE library manager.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.