Function with struct as argument now requires struct explicitly declared

I was trying to Upload a sketch that i created 2 years ago onto an UNO, it is Sketch that runs a TFT-touch handheld DMX-controller. I have one, it has been very practical and since i had both another TFT-screen and an UNO to spare i thought to make another one for a friend. Now the Sketch started spitting out a whole heap of error messages on compile, which disappeared after i changed uint8_t ReadMainScreen( Button * BS[], uint8_t NRbutts) { to uint8_t ReadMainScreen(struct Button * BS[], uint8_t NRbutts) { (and all it's similar functions arguments)
Now i probably never got the whole thing about structs and pointers to structs and passing them to functions and all fully correct (at least i know i struggled with the concept at the time) and i did update the IDE in the mean time (from something old to something less old .. sorry i'm slow with that sort of stuff)
But anyway the main thing is that the a pointer to Button

struct Button 
{
  uint16_t x1;
  uint16_t y1;
  uint16_t sx;
  uint16_t sy,tsize;
  char * cname;
  uint16_t color;
};

could be passed without explicitly stating it as a struct before and now it somehow can't be. Could someone please elaborate.

Not very nice of you to not post at least the whole error. Those are the key to the problem...

And better, try to make a MCVE so we can test it as well. And good thing about MCVE's is that in a lot of cases you spot the problem while making the MCVE :slight_smile:

I tried to make a MCVE but I don't get any errors...

struct Button
{
  uint16_t x1;
  uint16_t y1;
  uint16_t sx;
  uint16_t sy,tsize;
  char * cname;
  uint16_t color;
};

void setup(){
  Serial.begin(115200);
}

void loop(){
  
}

uint8_t ReadMainScreen(Button * BS[], uint8_t NRbutts) {

  return NRbutts * (*BS[0]).x1;
}

And for someone who has little experence with pointers you do use it a lot... Why do you want to have a pointer to an array of structs? Which basically is a pointer to a pointer. Isn't it enough to just have an array passed?

uint8_t ReadMainScreen(Button BS[], uint8_t NRbutts) {

Not very nice of you to not post at least the whole error. Those are the key to the problem...

Oh i am sorry i am not being nice.. i have nightshift this weekend, and usually i am not so nice, matter of habit.. anyway, after the first few errors the functions also do no longer exist so it all becomes cascaded. The warnings about the C++ ISo i should still fix, having a non defined size for the 'cname' is probably not such a good idea.

Arduino: 1.6.5 (Windows 8.1), Board: "Arduino/Genuino Uno"

Build options changed, rebuilding all

DMX_TFT_TS_Controller_v2a:13: error: 'Button' was not declared in this scope
DMX_TFT_TS_Controller_v2a:13: error: 'BS' was not declared in this scope
DMX_TFT_TS_Controller_v2a:13: error: expected primary-expression before ']' token
DMX_TFT_TS_Controller_v2a:13: error: expected primary-expression before 'NRbutts'
DMX_TFT_TS_Controller_v2a.ino:13:54: warning: expression list treated as compound expression in initializer [-fpermissive]
DMX_TFT_TS_Controller_v2a:14: error: variable or field 'DrawMainScreen' declared void
DMX_TFT_TS_Controller_v2a:14: error: 'Button' was not declared in this scope
DMX_TFT_TS_Controller_v2a:14: error: 'BS' was not declared in this scope
DMX_TFT_TS_Controller_v2a:14: error: expected primary-expression before ']' token
DMX_TFT_TS_Controller_v2a:14: error: expected primary-expression before 'NRbutts'
DMX_TFT_TS_Controller_v2a:14: error: expected primary-expression before 'bool'
DMX_TFT_TS_Controller_v2a:17: error: variable or field 'DrawScreen' declared void
DMX_TFT_TS_Controller_v2a:17: error: 'Button' was not declared in this scope
DMX_TFT_TS_Controller_v2a:17: error: 'BS' was not declared in this scope
DMX_TFT_TS_Controller_v2a:17: error: expected primary-expression before ']' token
DMX_TFT_TS_Controller_v2a:17: error: expected primary-expression before 'NRbutts'
DMX_TFT_TS_Controller_v2a:17: error: expected primary-expression before 'char'
DMX_TFT_TS_Controller_v2a:17: error: expected primary-expression before 'char'
DMX_TFT_TS_Controller_v2a:18: error: variable or field 'DrawButton' declared void
DMX_TFT_TS_Controller_v2a:18: error: 'Button' was not declared in this scope
DMX_TFT_TS_Controller_v2a:18: error: 'B' was not declared in this scope
DMX_TFT_TS_Controller_v2a:20: error: variable or field 'DrawFader' declared void
DMX_TFT_TS_Controller_v2a:20: error: 'Fader' was not declared in this scope
DMX_TFT_TS_Controller_v2a:20: error: 'Fad' was not declared in this scope
DMX_TFT_TS_Controller_v2a:20: error: expected primary-expression before 'level'
DMX_TFT_TS_Controller_v2a:20: error: expected primary-expression before 'color'
DMX_TFT_TS_Controller_v2a:22: error: variable or field 'MoveFader' declared void
DMX_TFT_TS_Controller_v2a:22: error: 'Fader' was not declared in this scope
DMX_TFT_TS_Controller_v2a:22: error: 'Fad' was not declared in this scope
DMX_TFT_TS_Controller_v2a:22: error: expected primary-expression before 'currentvalue'
DMX_TFT_TS_Controller_v2a:22: error: expected primary-expression before 'newvalue'
DMX_TFT_TS_Controller_v2a:22: error: expected primary-expression before 'color'
DMX_TFT_TS_Controller_v2a:24: error: 'Fader' was not declared in this scope
DMX_TFT_TS_Controller_v2a:24: error: 'Fad' was not declared in this scope
DMX_TFT_TS_Controller_v2a:26: error: 'Button' was not declared in this scope
DMX_TFT_TS_Controller_v2a:26: error: 'BS' was not declared in this scope
DMX_TFT_TS_Controller_v2a:26: error: expected primary-expression before ']' token
DMX_TFT_TS_Controller_v2a:26: error: expected primary-expression before 'NRbutts'
DMX_TFT_TS_Controller_v2a:26: error: expected primary-expression before 'bool'
DMX_TFT_TS_Controller_v2a.ino:26:73: warning: expression list treated as compound expression in initializer [-fpermissive]
DMX_TFT_TS_Controller_v2a:27: error: 'Fader' was not declared in this scope
DMX_TFT_TS_Controller_v2a:27: error: 'FAD' was not declared in this scope
DMX_TFT_TS_Controller_v2a:27: error: expected primary-expression before ']' token
DMX_TFT_TS_Controller_v2a:27: error: expected primary-expression before 'NRfads'
DMX_TFT_TS_Controller_v2a:27: error: 'Button' was not declared in this scope
DMX_TFT_TS_Controller_v2a:27: error: 'BS' was not declared in this scope
DMX_TFT_TS_Controller_v2a:27: error: expected primary-expression before ']' token
DMX_TFT_TS_Controller_v2a:27: error: expected primary-expression before 'NRbutts'
DMX_TFT_TS_Controller_v2a.ino:27:86: warning: expression list treated as compound expression in initializer [-fpermissive]
DMX_TFT_TS_Controller_v2a:28: error: 'Button' was not declared in this scope
DMX_TFT_TS_Controller_v2a:28: error: 'B' was not declared in this scope
DMX_TFT_TS_Controller_v2a:28: error: expected primary-expression before 'tftx'
DMX_TFT_TS_Controller_v2a:28: error: expected primary-expression before 'tfty'
DMX_TFT_TS_Controller_v2a.ino:28:58: warning: expression list treated as compound expression in initializer [-fpermissive]
DMX_TFT_TS_Controller_v2a.ino: In function 'void MainScreen()':
DMX_TFT_TS_Controller_v2a.ino:144:11: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
DMX_TFT_TS_Controller_v2a.ino:145:11: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
DMX_TFT_TS_Controller_v2a.ino:146:11: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
DMX_TFT_TS_Controller_v2a.ino:147:11: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
DMX_TFT_TS_Controller_v2a.ino:148:11: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
DMX_TFT_TS_Controller_v2a.ino:149:11: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
DMX_TFT_TS_Controller_v2a.ino:150:11: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
DMX_TFT_TS_Controller_v2a.ino:151:54: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
DMX_TFT_TS_Controller_v2a:154: error: 'DrawMainScreen' was not declared in this scope
DMX_TFT_TS_Controller_v2a:157: error: 'ReadMainScreen' cannot be used as a function
DMX_TFT_TS_Controller_v2a.ino: In function 'uint8_t ReadMainScreen(Button**, uint8_t)':
DMX_TFT_TS_Controller_v2a:162: error: 'uint8_t ReadMainScreen(Button**, uint8_t)' redeclared as different kind of symbol
DMX_TFT_TS_Controller_v2a.ino:13:9: note: previous declaration 'uint8_t ReadMainScreen'
DMX_TFT_TS_Controller_v2a:163: error: 'CheckButtonPressed' cannot be used as a function
DMX_TFT_TS_Controller_v2a.ino:188:83: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
DMX_TFT_TS_Controller_v2a.ino:188:83: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
DMX_TFT_TS_Controller_v2a.ino:207:92: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
DMX_TFT_TS_Controller_v2a.ino: In function 'void DrawMainScreen(Button**, uint8_t, bool)':
DMX_TFT_TS_Controller_v2a:222: error: 'DrawButton' was not declared in this scope
DMX_TFT_TS_Controller_v2a.ino: In function 'int16_t DecimalScreen(char*, char*, uint16_t)':
DMX_TFT_TS_Controller_v2a.ino:234:11: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
DMX_TFT_TS_Controller_v2a.ino:235:11: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
DMX_TFT_TS_Controller_v2a.ino:236:11: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
DMX_TFT_TS_Controller_v2a.ino:237:11: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
DMX_TFT_TS_Controller_v2a.ino:238:11: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
DMX_TFT_TS_Controller_v2a.ino:239:11: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]

---  ...   post exceeds 900 chars ----
DMX_TFT_TS_Controller_v2a.ino:28:6: note: previous declaration 'bool CompareRange'
Multiple libraries were found for "Adafruit_GFX.h"

 Used: C:\Program Files (x86)\Arduino\libraries\Adafruit_GFX

 Not used: C:\Arduino Files\Sketches\libraries\Adafruit_GFX_Library

'Button' was not declared in this scope

  This report would have more information with
  "Show verbose output during compilation"
  enabled in File > Preferences.

Just to be really 'nice' i should post the whole sketch, shouldn't i.

/*  TFT Touchscreen DMX Controller

 */


#include <Adafruit_GFX.h>    // Core graphics library

#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;       // hard-wired for UNO shields anyway.
#include <TouchScreen.h>

#if defined(__SAM3X8E__)
#undef __FlashStringHelper::F(string_literal)
#define F(string_literal) string_literal
#endif
 
//#include <SPI.h>     // these 2 includes take 2.7 kb mem even if not used
//#include <SD_alt.h>  // commented out all reference to Serial in this Library

#include <Conceptinetics_alt.h>  // DMX lib altered version include DMXmaster::getChannelValue() so we can easily do without the mirror array
#define DMX_MASTER_CHANNELS   512
#define RXEN_PIN 19 // on my Mega shield this is pin 48 (not pin 19 (A5))


DMX_Master  dmx_master ( DMX_MASTER_CHANNELS, RXEN_PIN );

int16_t firstSC = 1;  //  the first channel we show. if we substract 6 we may end up below zero, hence the int16
uint16_t selchannel=0;

struct Button 
{
  uint16_t x1;
  uint16_t y1;
  uint16_t sx;
  uint16_t sy,tsize;
  char * cname;
  uint16_t color;
};

struct Fader 
{
  uint16_t x1;
  uint16_t y1;
  uint16_t sx;
  uint16_t sy;
  uint8_t orientation;
  uint16_t range; 
  uint16_t color;
};


//File root;

//#define CS_PIN  10 for the sdcard-reader

//uint32_t allbytes=0;
//uint16_t allfiles=0;

// most mcufriend shields use these pins and Portrait mode:
const uint8_t YP = A1;  // must be an analog pin, use "An" notation!
uint8_t XM = A2;  // must be an analog pin, use "An" notation!
uint8_t YM = 7;   // can be a digital pin
uint8_t XP = 6;   // can be a digital pin


uint8_t SwapXY = 1; // depends on the TFT shield

uint16_t TS_LEFT = 910;
uint16_t TS_RT = 205;
uint16_t TS_TOP = 160;  // this is actually the usb end at the start of the program
uint16_t TS_BOT = 920;

uint16_t TFT_X_RANGE = 240;
uint16_t TFT_Y_RANGE = 320;


// For better pressure precision, we need to know the resistance
// between X+ and X- Use any multimeter to read it
// For the one we're using, its 300 ohms across the X plate
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 455);
TSPoint tp;

#define MINPRESSURE 5
#define MAXPRESSURE 1000
#define RELEASECYCLES 100

#define SWAP(a, b) {uint16_t tmp = a; a = b; b = tmp;}


uint16_t identifier;
uint8_t orientation = 1;    //Landscape
//uint8_t linecounter=0;


// 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
#define BACKGND 0xFFF8
#define CHANNEL 0xFFF0
#define CHSELCT 0xFF88
#define B1COL   0xCF3F
#define B2COL   0x12AD
#define B3COL   0x9437

uint16_t BgColor=0xFFF8;
uint16_t TextColor=BLACK;

void setup() {
  
  dmx_master.enable ();
    
  tft.begin(9600);
  tft.reset();
  identifier = tft.readID();
  tft.begin(identifier);
  tft.setRotation(orientation);  // we use orientation here to set the TFT rotation

  TS_Rotation(orientation);  
  ts = TouchScreen(XP, YP, XM, YM, 300);     //  call the constructor  

  selchannel=0;  // the channel lit up when selected
  firstSC=1; // the first channel shown on screen
  
  //if (SdCardOpen(CS_PIN)) SdCardDirectory(); 
  
}

void loop() {
  MainScreen();
}

void MainScreen() {
  const uint8_t NRbutts=13; // 0 is fader area, last 6 are go buttons
  Button butt[NRbutts]; 
  Button* BS[NRbutts];
  for (uint8_t i=0; i<NRbutts; i++)   BS[i]=&butt[i];  // initialize the pointers  we can do that before filling the Buttons
   
  butt[0] = {79,42,240,216,1,"",BLACK};  // the area where the faders are won't be drawn by DrawButton but is read by ReadMainScreen.
  butt[1] = {3,208,35,30,1,"<<",B1COL};
  butt[2] = {41,208,35,30,1,">>",B1COL};
  butt[3] = {3,176,35,30,1,"<",B1COL};
  butt[4] = {41,176,35,30,1,">",B1COL};
  butt[5] = {3,144,73,30,1,"GOTO",B1COL}; 
  butt[6] = {3,112,73,30,1,"Calibrate",B1COL};  
  for (uint16_t i=0; i<6; i++)   butt[(NRbutts-6)+i] = {80 + (i*40),2,38,38,1,"",BLACK};  // the GO buttons
  

  DrawMainScreen(BS,NRbutts-6,true);  // we don't draw the GO buttons
  uint8_t RMS=0;   // RMS (ReadMainScreen) exitvalue=0 : don't draw the new screen at all
  while (RMS<2) {  // exitvalue=2 : redraw the whole screen
    RMS=ReadMainScreen(BS,NRbutts);
    if (RMS==1) DrawMainScreen(BS,NRbutts-6,false);  // exitvalue=1 only redraw the faders
  }
}

uint8_t ReadMainScreen(Button * BS[], uint8_t NRbutts) {
  uint8_t i=CheckButtonPressed(BS,NRbutts,false);
  int16_t value=0;
  uint8_t exitvalue=0;
  switch (i) {
    case 0:   //fader
      ChannelAdjustFader();
      exitvalue=0;
      break; 
    case 1:  // <<
      firstSC=firstSC-6;
      exitvalue=1;
      break;
    case 2: // >>
      firstSC=firstSC+6;
      exitvalue=1;
      break;
    case 3:  // <
      firstSC--;  
      exitvalue=1;
      break;
    case 4:  // >
      firstSC++;
      exitvalue=1;
      break; 
    case 5:  // goto
      value=DecimalScreen("GOTO CHANNEL","Set leftmost DMX channel (1-507)", B1COL);
      if ((value>0) && (value<508)) firstSC=value;
      exitvalue=2;
      break;
    case 6: // Calibrate
      CalibrateScreen();
      exitvalue=2;
      break;
  }
  if ((i>NRbutts-7) && (i<NRbutts)) {  // GO button
    int ch=firstSC+i-(NRbutts-6);  // we start at butt{6] then i==6  
     
    String str;    // concatenating the strings takes 1.5 kb mem 
    str=String("Set Channel ");
    str=str+String(ch);
    str=str+String (" DMX Value:"); 
    char discrpt[str.length() + 1];    
    str.toCharArray(discrpt,str.length() + 1);

    int16_t value=DecimalScreen("GO DMX VALUE",/*"Set DMX channel to value"*/discrpt, B1COL);
    if (value<256) {
      dmx_master.setChannelValue(ch,value);
    }
    exitvalue=2;
  }
  if (firstSC<1) firstSC=1;
  if (firstSC>507) firstSC=507;
  return exitvalue;
}

void DrawMainScreen(Button*  BS[], uint8_t NRbutts, bool draw_all ) {
  tft.setTextColor(TextColor);
  if (draw_all) {
    tft.fillScreen(BgColor);
    for (uint8_t i=1; i<NRbutts; i++)  DrawButton(&(*BS[i]));
  }
  for (uint8_t i=0; i<6; i++)  DrawChannel(firstSC+i,i,((firstSC+i)==selchannel));
}

int16_t DecimalScreen(char * cname,char * discrpt,uint16_t color) {
  const uint8_t NRbutts=11;
  Button butt[NRbutts];   // we may have more buttons eventually
  Button* BS[NRbutts];   // but it is vital that these amounts match
  for (uint8_t i=0; i<NRbutts; i++)   BS[i]=&butt[i]; // assigning the pointers in the array
  
  const uint16_t offset=130;
  butt[7] = {10+offset,50,40,40,2,"7",color};
  butt[4] = {10+offset,95,40,40,2,"4",color};
  butt[1] = {10+offset,140,40,40,2,"1",color};
  butt[0] = {10+offset,185,40,40,2,"0",color};
  butt[8] = {55+offset,50,40,40,2,"8",color};
  butt[5] = {55+offset,95,40,40,2,"5",color};
  butt[2] = {55+offset,140,40,40,2,"2",color};
  butt[10] = {55+offset,185,85,40,2,"ENTER",color};
  butt[9] = {100+offset,50,40,40,2,"9",color};
  butt[6] = {100+offset,95,40,40,2,"6",color};
  butt[3] = {100+offset,140,40,40,2,"3",color};  

  tft.setTextColor(TextColor);
  DrawScreen (BS,NRbutts,cname,discrpt);  // we can draw the first 11 or less
  int16_t value=0; 
  tft.drawRect(10,80,105,60,BLACK);
  tft.fillRect(10,80,105,60,B2COL);
  tft.fillRect(15,85,95,50,B3COL);
  tft.setCursor(25,95);
  tft.setTextSize(4); 
  tft.setTextColor(YELLOW);
  for (uint8_t i=0; i<3; i++) {
    uint8_t pressed=CheckButtonPressed(BS,NRbutts,false);
    if (pressed==10) break;
    value=value*10+pressed;
    tft.print(pressed, DEC);
  }
  delay(500);
  return value;  
}
void CalibrateScreen() {
  const uint8_t NRbutts=5;
  Button butt[NRbutts];   
  Button* BS[NRbutts];   
  for (uint8_t i=0; i<NRbutts; i++)   BS[i]=&butt[i];
  Fader fad[2];
  Fader* FD[2];
  for (uint8_t i=0; i<2; i++) FD[i]=&fad[i]; 
  uint16_t CBx,CBy;
  uint8_t pressed=NRbutts;
  CBx=((TFT_X_RANGE-40)/2); // buttons 40x40
  CBy=((TFT_Y_RANGE-40)/2);
  butt[0] = {CBx,CBy,40,40,2,"OK",B3COL};
  butt[1] = {CBx-42,CBy,40,40,2,"<-",B3COL};
  butt[2] = {CBx+42,CBy,40,40,2,"->",B3COL};
  butt[3] = {CBx-20,CBy-42,80,40,1,"Top",B3COL};
  butt[4] = {CBx-20,CBy+42,80,40,1,"Bottom",B3COL};

  fad[0] = {10,10,200,40,3,255,B1COL};
  fad[1] = {30,80,100,40,1,200,B1COL};

  DrawFader(&fad[1],20,B1COL);
  delay(2000);

  tft.setTextColor(TextColor);
  /*while (true) {
    DrawScreen (BS,NRbutts,"Calibrate","");
    pressed=CheckButtonPressed(BS,NRbutts,true);
    if (pressed==0) return;
    else if (pressed==1) { 
      String str;    
      str=String("Current Left Margin is: ");
      str=str+String(TS_LEFT); 
      char discrpt[str.length() + 1];    
      str.toCharArray(discrpt,str.length() + 1);
      TS_LEFT=DecimalScreen("Set Left Margin",discrpt, B1COL); 
    }
    else if (pressed==2) {
      String str;    
      str=String("Current Right Margin is: ");
      str=str+String(TS_RT); 
      char discrpt[str.length() + 1];    
      str.toCharArray(discrpt,str.length() + 1);
      TS_RT=DecimalScreen("Set Right Margin",discrpt, B1COL);    
    }
    else if (pressed==3) {
      String str;    
      str=String("Current Top Margin is: ");
      str=str+String(TS_TOP); 
      char discrpt[str.length() + 1];    
      str.toCharArray(discrpt,str.length() + 1);
      TS_TOP=DecimalScreen("Set Top Margin",discrpt, B1COL);    
    }
    else if (pressed==4) {       
      String str;    
      str=String("Current Bottom Margin is: ");
      str=str+String(TS_BOT); 
      char discrpt[str.length() + 1];    
      str.toCharArray(discrpt,str.length() + 1);
      TS_BOT=DecimalScreen("Set Bottom Margin",discrpt, B1COL);       
    }
  }*/
}

void DrawScreen(Button * BS[],uint8_t NRbutts, char * cname,char * discrpt){
    tft.fillScreen(BgColor);
    tft.setTextSize(2);
    tft.setCursor((TFT_X_RANGE/2) - strlen(cname)*6,10);
    tft.print(cname);
    tft.setTextSize(1);
    tft.setCursor((TFT_X_RANGE/2) - strlen(discrpt)*3,35);
    tft.print(discrpt);
    for (uint8_t i=0; i<NRbutts; i++)  DrawButton(&(*BS[i]));
}


void DrawButton (Button* B) {
  tft.fillRect(B->x1,B->y1,B->sx,B->sy,B->color);
  tft.drawRect(B->x1,B->y1,B->sx,B->sy,BLACK);
  tft.drawRect(B->x1+2,B->y1+2,B->sx-4,B->sy-4,BLACK);
  tft.setTextSize(B->tsize);
  tft.setCursor(B->x1+(B->sx/2)-(strlen(B->cname)*3*B->tsize),B->y1+(B->sy/2)-(4*B->tsize));
  tft.print(B->cname);                  
}

void DrawChannel(uint16_t channel, uint8_t fadnr, bool select) {
  uint16_t color=CHANNEL;
  if (select) color=CHSELCT;
  uint16_t offset=40*fadnr;
  tft.fillRect(79+offset,1,40,238,color); 
  tft.drawRect(80+offset,42,38,196,BLACK);
  tft.drawLine(80+offset,218,116+offset,218,BLACK);
  tft.drawLine(98+offset,42,98+offset,218,BLACK);
  tft.drawLine(101+offset,42,101+offset,218,BLACK); 

  tft.drawRect(80+offset,2,38,38,BLACK);  // draw special button
  tft.drawRect(82+offset,4,34,34,BLACK);
  tft.setTextSize(2);
  tft.setCursor(88+offset,8);
  tft.print("GO");
  tft.setTextSize(1);
  tft.setCursor(100+offset-HasDigits(dmx_master.getChannelValue(channel))*3,27);
  tft.print(dmx_master.getChannelValue(channel), DEC);
  
  tft.setCursor(101+offset-HasDigits(channel)*3,224);
  tft.print(channel,DEC);
  
  uint16_t faderlevel=((uint16_t) dmx_master.getChannelValue(channel)*166)/255;
  tft.drawRect(84+offset,211-faderlevel,30,4,BLACK);
  tft.drawRect(85+offset,212-faderlevel,28,2,RED);
  
}


void DrawFader(Fader * Fad, uint16_t level, uint16_t color) {
  if (!color) color=Fad->color;
  tft.fillRect(Fad->x1,Fad->y1,Fad->sx,Fad->sy,color);
  tft.drawRect(Fad->x1,Fad->y1,Fad->sx,Fad->sy,BLACK);
  uint16_t faderlevel;
  if (Fad->orientation%2) { // horizontal
    tft.drawLine(Fad->x1+0,Fad->y1+(Fad->sy/2)-2,Fad->x1+Fad->sx,Fad->y1+(Fad->sy/2)-2,BLACK);
    tft.drawLine(Fad->x1, Fad->y1 + (Fad->sy/2)+1, Fad->x1+Fad->sx, Fad->y1+(Fad->sy/2)+1,BLACK);
    faderlevel=(level*(Fad->sx-12))/Fad->range;
    if (Fad->orientation/2) { // left to right
      tft.drawRect(Fad->x1+5+faderlevel,Fad->y1+5,4,Fad->sy-10,BLACK);
      tft.drawRect(Fad->x1+6+faderlevel,Fad->y1+6,2,Fad->sy-12,RED);
    }
    else {  // right to left 
      tft.drawRect(Fad->x1 + Fad->sx -faderlevel - 12,Fad->y1 + 5, 4, Fad->sy - 10,BLACK);
      tft.drawRect(Fad->x1+Fad->sx-faderlevel-11,Fad->y1+6,2,Fad->sy-12,RED);      
    }
  }
  else { // vertical
    tft.drawLine(Fad->x1+(Fad->sx/2)-2,Fad->y1,Fad->x1+(Fad->sx/2)-2,Fad->y1+Fad->sy,BLACK);
    tft.drawLine(Fad->x1+(Fad->sx/2)+1,Fad->y1,Fad->x1+(Fad->sx/2)+1,Fad->y1+Fad->sy,BLACK);
    faderlevel=(level*(Fad->sy-12))/Fad->range;
    if (Fad->orientation/2) { // bottom to top
      tft.drawRect(Fad->x1+5,Fad->y1+Fad->sy-faderlevel-12,Fad->sx-10,4,BLACK);
      tft.drawRect(Fad->x1+6,Fad->y1+Fad->sy-faderlevel-11,Fad->sx-12,2,RED);          
    }
    else {  // Top to bottom
      tft.drawRect(Fad->x1+5,Fad->y1+5+faderlevel,Fad->sx-10,4,BLACK);
      tft.drawRect(Fad->x1+6,Fad->y1+6+faderlevel,Fad->sx-12,2,RED);
    }
  }
}

void ChannelAdjustFader() {      // still needs to be made universal   
  int16_t tftx,tfty;  
  tftx = CalcTftx(tp.x);
  uint8_t selectedCH=(tftx-79)/40;  // that should give us the fadernr (0-6)
  
  tfty = CalcTfty(tp.y);     
  uint8_t newvalue=RangeValueFader(212-tfty,166,255);
  
  if ((selectedCH+firstSC) != selchannel) {  // if it is not the current highlighted one
    if (firstSC<=selchannel  && (firstSC+5)>=selchannel) { // but the highlighted was on screen
      DrawChannel(selchannel,selchannel-firstSC,false);  // we need to draw it not highlighted
    } 
    dmx_master.setChannelValue(firstSC+selectedCH,newvalue);  // assign newvalue to the dmxbuffer  
     
    DrawChannel(firstSC+selectedCH,selectedCH, true); // draw the selected one highlighted
    selchannel=selectedCH+firstSC; // set it as the new selected channel
  }
  else ChannelMoveFader(newvalue,selectedCH); // we only draw it the first time if we haven't redrawn the channel.

  while (!ConfirmRelease()) {
    tfty = CalcTfty(tp.y);     
    newvalue=RangeValueFader(212-tfty,166,255);
    ChannelMoveFader(newvalue,selectedCH);
  }  
}

uint16_t AdjustFader(Fader* Fad, uint16_t currentvalue, uint16_t color=0x0) {
  if (!color) color=Fad->color;
  uint16_t newvalue;
  newvalue=CalculateFaderValue(Fad);
  MoveFader(Fad,currentvalue,newvalue,color);
  currentvalue=newvalue;
  while (!ConfirmRelease()) {
    newvalue=CalculateFaderValue(Fad);
    MoveFader(Fad,currentvalue,newvalue,color);
    currentvalue=newvalue;
  }
  return currentvalue;
}
void MoveFader(Fader* Fad, uint16_t currentvalue, uint16_t newvalue, uint16_t color) {
  uint16_t oldfaderlevel,newfaderlevel;
  if (Fad->orientation%2){
    oldfaderlevel=(currentvalue*(Fad->sx-12))/Fad->range;
    newfaderlevel=(newvalue*(Fad->sx-12))/Fad->range;
    if (Fad->orientation/2) { // left to right
      tft.fillRect(Fad->x1+5+oldfaderlevel,Fad->y1+5,4,Fad->sy-10,color);
      tft.drawLine(Fad->x1+5+oldfaderlevel,Fad->y1+(Fad->sy/2)-1,Fad->x1+9+oldfaderlevel,Fad->y1+(Fad->sy/2)-1,BLACK);
      tft.drawLine(Fad->x1+5+oldfaderlevel,Fad->y1+(Fad->sy/2)+2,Fad->x1+9+oldfaderlevel,Fad->y1+(Fad->sy/2)+2,BLACK);
      tft.drawRect(Fad->x1+5+newfaderlevel,Fad->y1+5,4,Fad->sy-10,BLACK);
      tft.drawRect(Fad->x1+6+newfaderlevel,Fad->y1+6,2,Fad->sy-12,RED);
    }
    else {  // right to left 
      tft.fillRect(Fad->x1 + Fad->sx -oldfaderlevel - 12,Fad->y1+5,4,Fad->sy-10,color);
      tft.drawLine(Fad->x1 + Fad->sx -oldfaderlevel - 12,Fad->y1+(Fad->sy/2)-1,Fad->x1 + Fad->sx -oldfaderlevel - 8,Fad->y1+(Fad->sy/2)-1,BLACK);
      tft.drawLine(Fad->x1 + Fad->sx -oldfaderlevel - 12,Fad->y1+(Fad->sy/2)+2,Fad->x1 + Fad->sx -oldfaderlevel - 8,Fad->y1+(Fad->sy/2)+2,BLACK);
      tft.drawRect(Fad->x1 + Fad->sx -newfaderlevel - 12,Fad->y1 + 5, 4, Fad->sy - 10,BLACK);
      tft.drawRect(Fad->x1+Fad->sx-newfaderlevel-11,Fad->y1+6,2,Fad->sy-12,RED);   
    }
  }
  else {
    oldfaderlevel=(currentvalue*(Fad->sy-12))/Fad->range; 
    newfaderlevel=(newvalue*(Fad->sy-12))/Fad->range;
    if (Fad->orientation/2) {// bottom to top
      tft.fillRect(Fad->x1+5,Fad->y1+Fad->sy-oldfaderlevel-12,Fad->sx-10,4,color);
      tft.drawLine(Fad->x1+(Fad->sx/2)-1,Fad->y1+Fad->sy-oldfaderlevel-12,Fad->x1+(Fad->sx/2)-1,Fad->y1+Fad->sy-oldfaderlevel-8,BLACK);
      tft.drawLine(Fad->x1+(Fad->sx/2)-2,Fad->y1+Fad->sy-oldfaderlevel-12,Fad->x1+(Fad->sx/2)+2,Fad->y1+Fad->sy-oldfaderlevel-8,BLACK);
      tft.drawRect(Fad->x1+5,Fad->y1+Fad->sy-newfaderlevel-12,Fad->sx-10,4,BLACK);
      tft.drawRect(Fad->x1+6,Fad->y1+Fad->sy-newfaderlevel-11,Fad->sx-12,2,RED);      
    }
    else {
      tft.fillRect(Fad->x1+5,Fad->y1+5+oldfaderlevel-12,Fad->sx-10,4,color);
      tft.drawLine(Fad->x1+(Fad->sx/2)-1,Fad->y1+oldfaderlevel+5,Fad->x1+(Fad->sx/2)-1,Fad->y1+oldfaderlevel+9,BLACK);
      tft.drawLine(Fad->x1+(Fad->sx/2)-2,Fad->y1+oldfaderlevel+5,Fad->x1+(Fad->sx/2)+2,Fad->y1+oldfaderlevel+9,BLACK);
      tft.drawRect(Fad->x1+5,Fad->y1+Fad->sy-newfaderlevel-12,Fad->sx-10,4,BLACK);
      tft.drawRect(Fad->x1+6,Fad->y1+Fad->sy-newfaderlevel-11,Fad->sx-12,2,RED);              
    }
  }
}void ChannelMoveFader(uint8_t newvalue, uint8_t faderNR) {
  uint16_t channel=firstSC+faderNR;
  uint16_t faderlevel=((uint16_t) dmx_master.getChannelValue(channel)*166)/255; //dmxvalue[channel-1]*166)/255;
  uint16_t offset=40*faderNR;
  tft.fillRect(84+offset,211-faderlevel,30,4,CHSELCT);    // cover the old fader
  tft.drawLine(98+offset,211-faderlevel,98+offset,214-faderlevel,BLACK);
  tft.drawLine(101+offset,211-faderlevel,101+offset,214-faderlevel,BLACK); 
  dmx_master.setChannelValue(channel,newvalue);  // set new value to the dmxbuffer
  faderlevel=((uint16_t) dmx_master.getChannelValue(channel)*166)/255; //dmxvalue[channel-1]*166)/255;  // and draw the new fader
  tft.drawRect(84+offset,211-faderlevel,30,4,BLACK);
  tft.drawRect(85+offset,212-faderlevel,28,2,RED);
  tft.fillRect(84+offset,27,30,10,CHSELCT); // and print the new value
  tft.setTextSize(1);
  tft.setCursor(100+offset-HasDigits(dmx_master.getChannelValue(channel))*3,27);
  tft.print(dmx_master.getChannelValue(channel), DEC);  
}

uint16_t CalculateFaderValue(Fader* Fad) {
  uint16_t tftxy,newvalue;
  if (Fad->orientation%2)  {  // Horizontal
    tftxy = CalcTftx(tp.x);
    if (Fad->orientation/2) newvalue=RangeValueFader(tftxy-Fad->x1,Fad->sx-12,Fad->range);
    else newvalue=RangeValueFader(Fad->x1+Fad->sx-tftxy,Fad->sx-12,Fad->range);
  }
  else  {  // Vertical
    tftxy = CalcTfty(tp.y);
    if (Fad->orientation/2) newvalue=RangeValueFader(Fad->y1+Fad->sy-tftxy,Fad->sy-12,Fad->range);
    else newvalue=RangeValueFader(tftxy-Fad->y1,Fad->sy-12,Fad->range);
  }
  return newvalue;  
}

uint16_t RangeValueFader(int16_t faderpixel,int16_t pixelrange, uint16_t faderrange) {
  int32_t value = ((int32_t) faderpixel*255)/pixelrange;
  if (value<0) value=0;
  if (value>faderrange) value=faderrange;
  return (uint16_t) value;
}

uint8_t CheckButtonPressed(Button * BS[],uint8_t NRbutts,bool printcoord) {
  uint8_t i=NRbutts;
  while (i==NRbutts) {
    int16_t tftx,tfty;
    WaitReleaseReadPress(true);
    tftx = CalcTftx(tp.x); 
    tfty = CalcTfty(tp.y);
    i=0;
    while ((!CompareRange(BS[i],tftx,tfty)) && (i<NRbutts)) i++;
    if ((printcoord) && (i==NRbutts)) {
      while (!ConfirmRelease()) PrintCoordinatesAt(140,194,tp.x,tp.y,1);     
    }
  }
  return i;
}

uint8_t CheckFaderPressed(Fader* FAD[], uint8_t NRfads,Button * BS[], uint8_t NRbutts) {
  uint8_t i=NRfads+NRbutts;
  while (i==NRfads+NRbutts) {
    int16_t tftx,tfty;
    WaitReleaseReadPress(true);
    tftx = CalcTftx(tp.x);
    tfty = CalcTfty(tp.y);
    i=0;
    Button butt;
    Button * BS;
    BS= &butt;
    
    BS->x1=FAD[i]->x1; BS->y1=FAD[i]->y1; BS->sx=FAD[i]->sx; BS->sy=FAD[i]->sy;
    while ((!CompareRange(BS,tftx,tfty)));
  }
}


bool CompareRange(Button * B,uint16_t tftx, uint16_t tfty) {
  if (tftx > B->x1 && tftx < (B->x1+B->sx)  && tfty > B->y1 && tfty < (B->y1+B->sy)) return true;
  return false;
}

bool ConfirmRelease() {
  uint8_t prs=0;
  while (prs<RELEASECYCLES) {
    tp = ts.getPoint();
    ResetPins();
    if (tp.z > MINPRESSURE && tp.z < MAXPRESSURE) return false ;
    delay(1);
    prs++;
  }
  return true;
}void WaitReleaseReadPress(bool waitrelease) {
  if (waitrelease) {
    while (!ConfirmRelease());
  }
  while (tp.z < MINPRESSURE || tp.z > MAXPRESSURE) {
    tp = ts.getPoint();
    ResetPins();
  }
  delay (100);
}

int16_t CalcTftx(uint16_t tpx) {
  uint32_t TX;
  if (TS_LEFT>TS_RT) {
    TX = ((uint32_t)(tpx-TS_RT)) * TFT_X_RANGE;
    TX = TX / (TS_LEFT-TS_RT);
  }
  else {
    TX = ((uint32_t)(tpx-TS_LEFT)) * TFT_X_RANGE;
    TX = TFT_X_RANGE-(TX / (TS_RT-TS_LEFT));
  }
  return (int16_t) TX;
}

int16_t CalcTfty(uint16_t tpy) {
  uint32_t TY;
  if (TS_BOT>TS_TOP) {    
    TY = ((uint32_t)(tpy-TS_TOP)) * TFT_Y_RANGE;
    TY = TFT_Y_RANGE - (TY / (TS_BOT-TS_TOP));
  }
  else {
    TY = ((uint32_t)(tpy-TS_BOT)) * TFT_Y_RANGE;
    TY = TY / (TS_TOP-TS_BOT);
  }
  return (int16_t) TY;
}

uint8_t HasDigits(size_t number) {
  uint8_t digits=1;
  while (number/10) {
    digits++;
    number=number/10;
  }
  return digits;
}

void ResetPins(){
  pinMode(XM, OUTPUT);  // reset the pins after use.
  pinMode(YP, OUTPUT);
  pinMode(XP, OUTPUT);
  pinMode(YM, OUTPUT);
}

void TS_Rotation(uint8_t rotation) {  // as this function is now it only works if we run it once, not more often.
  uint16_t tmp; 
  switch (rotation) {      // adjust for different aspects
      case 0:   break;        // no change,  calibrated for PORTRAIT
      case 1:   tmp = TS_LEFT, TS_LEFT = TS_BOT, TS_BOT = TS_RT, TS_RT = TS_TOP, TS_TOP = tmp;
                SWAP (TFT_X_RANGE,TFT_Y_RANGE); break;
      case 2:   SWAP(TS_LEFT, TS_RT);  SWAP(TS_TOP, TS_BOT); break;
      case 3:   tmp = TS_LEFT, TS_LEFT = TS_TOP, TS_TOP = TS_RT, TS_RT = TS_BOT, TS_BOT = tmp;  
                SWAP (TFT_X_RANGE,TFT_Y_RANGE); break;
  }
}

void PrintCoordinatesAt(uint8_t x, uint8_t y, uint16_t cx, uint16_t cy, uint8_t tsize) {
    tft.fillRect(x, y, x+70,y+20 , BgColor);
    tft.setCursor(x,y);
    tft.setTextSize(tsize);
    tft.print("tp.x=" + String(cx) + "   ");
    tft.setCursor(x,y+10);
    tft.print("tp.y=" + String(cy) + "   ");
}

uint16_t Color16Bit(uint8_t r, uint8_t g, uint8_t b) {
  r=r>>2; g=g>>2; b=b>>2;
  return (((uint16_t) r<<11) | ((uint16_t) g<<5) | ((uint16_t) b));
}

uint16_t ChooseColor() {
  
}

void ShowColor() {
  uint16_t col=Color16Bit(200,130,220);
  tft.fillRect(1,1,40,30,col);
  tft.setCursor(10,10);
  tft.print(col, HEX);
}

So here it is.

Multiple libraries were found for "Adafruit_GFX.h"

 Used: C:\Program Files (x86)\Arduino\libraries\Adafruit_GFX

 Not used: C:\Arduino Files\Sketches\libraries\Adafruit_GFX_Library

Maybe the IDE is using the wrong library? Try forcing it to use the other library.

tf68:

Multiple libraries were found for "Adafruit_GFX.h"

Used: C:\Program Files (x86)\Arduino\libraries\Adafruit_GFX

Not used: C:\Arduino Files\Sketches\libraries\Adafruit_GFX_Library




Maybe the IDE is using the wrong library? Try forcing it to use the other library.

No i thought that, but actually the one used is the newer but they are nearly the same, and it is not related to that.

And for someone who has little experence with pointers you do use it a lot... Why do you want to have a pointer to an array of structs? Which basically is a pointer to a pointer. Isn't it enough to just have an array passed?

I am not sure if remember correctly but of the top of my head, if i pass the array i can not pass part of the array onto another function from within that, it was something like that, or i could not pass the whole thing in one go and i would have to pass all pointers individually, i can't quite remember but i think it was this sort of lineRMS=ReadMainScreen(BS,NRbutts); where i can pass the array of pointers in 1 go, where as when i just passed the array, something would go wrong, as i said i don't quite remember, but this worked and that didn't (i started out with that) i may even be related to the char * in the structure . Anyway i wasn't related to this so much, i ran into something similar with structs the other day, where in declaration i had to explicitly (re)declare it a struct, but this was in the ATtiny core

Sorry no help here but, what's a DMX controller?

-jim lee

DMX 512 a 30 year old system to control stage lights digitally remotely using RS-485 protocol where devices can have an address from 1-511 (actually it should called DMX511 since 0 isn't used) and any number of channels. Control desks come in all shapes and sizes and vary in prices but are usually not cheap. Software in combination with USB dongles also start around $100,-
For me, who builds devices that can be DMX controlled a $10,- pocket, standalone, TFT-touch-controller is really practical.