error message, custom function not included in loop scope

Not sure what is wrong, here is the error message. I don't even know what to put as the subject of this post, but if someone couldhelp me out I'd sure appreciate it.

userint2.0:47: error: 'assignSetpoints' was not declared in this scope

   assignSetpoints();

                   ^

C:\Users\Ford\Documents\Arduino\userint2.0\userint2.0.ino: In function 'void userInt()':

userint2.0:68: error: 'submenu' was not declared in this scope

       subMenuPrev = submenu;

                     ^

userint2.0:76: error: 'potB' was not declared in this scope

       lcd.print(potB);

                 ^

userint2.0:81: error: a function-definition is not allowed here before '{' token

   {

   ^

userint2.0:100: error: expected '}' at end of input

     }

     ^

exit status 1
'assignSetpoints' was not declared in this scope

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

and here is the code.

int menu = 1;
int subMenu = 1;
int subMenuPrev = 0;
int menuPrev = 0;

float temp_f;
long co2ppm = 1100;

long co2Low;
long co2High;

float tempLow;
float tempHigh;

long dayCO2Low = 1000;
long dayCO2High = 1200;
long nightCO2Low = 500;
long nightCO2High = 600;

float dayTempLow90;
float dayTempHigh100;
float mornTempLow65;
float mornTempHigh75;
float nightTempLow75;
float nightTempHigh85;

// include the library code:
#include "Wire.h"
#include "Adafruit_LiquidCrystal.h"

// Connect via i2c, default address #0 (A0-A2 not jumpered)
Adafruit_LiquidCrystal lcd(0);



void setup() {
  
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  // set up the LCD's number of rows and columns:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("hello, world!");
}
void loop() {
  assignSetpoints();
  userInt();
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 0);
  lcd.setBacklight(HIGH);
}

void userInt()
{

  if (menu == !menuPrev || subMenu == !subMenuPrev)
  {
    if (menu == 1 && subMenu == 1)
    {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("co2");
      lcd.setCursor(0, 1);
      lcd.print(co2ppm );
      menuPrev = menu;
      subMenuPrev = submenu;
    }

    if (menu == 1&&subMenu == 2)
    {
      lcd.setCursor(0, 0);
      lcd.print("dayCO2Low");
      lcd.setCursor(0, 1);
      lcd.print(potB);
    }
  }

  void assignSetpoints()
  {
    if (day)
    {
      co2Low = 1000;
      co2High = 1200;
      tempLow = 90;
      tempHigh = 100;
    }
    if (morning)
    {
      tempLow = 65;
      tempHigh = 75;
    }
    if (!day)
    {
      co2Low = 500;
      co2High = 600;
      tempLow = 75;
      tempHigh = 85;
    }

Looks like you're missing a "}" in your assignSetpoints function.

Thank you sir, I fixed that but its still telling me I can't use asignSetpoints().

also I changed potB to dayCO2Low

Missing one in the function above it too.

Hit Control - T in the IDE and it will autoformat. That will point out the brace errors pretty quick.

Where are ‘morning’ and ‘day’ declared?

I have fixed everything but the assignSetpoints () errors. Somehow I am not creating the function properly…

So I created a new sketch and cut and paste everything into the new sketch and it seems to be compiling properly… don’t know what happened.

Thank you for the input, sorry I posted such a hastily thrown together sketch with numerous stupid errors. I was trying not to include too much stuff that didn’t pertain to the question I had.

Show your updated code.

I added a bunch of stuff but here is the work in progress, I am currently working on debounceing the button presses. I posted another topic asking about that.

int menu = 1;
int subMenu = 1;
int subMenuPrev = 0;
int menuPrev = 0;
int varNumb=0;
int pumpDelay = 30;
int soilMoistureSetpoint = 430;
int soilMoisture = 500;
int rh = 60;

int mornHours = 2;
int dayCount = 0;
int hoursOff;
int hoursOn;

boolean morning = false;
boolean day = true;

int uvOnSecs = 3;

int increase = 23;
int decrease = 24;
int left = 25;
int right = 26;
int up = 27;
int down = 28;

float temp_f;
long co2ppm = 1100;

long co2Low;
long co2High;

int fanMins = 15;
unsigned long fanDelay = fanMins * 60 * 1000UL;

float tempLow;
float tempHigh;

long dayCO2Low = 1000;
long dayCO2High = 1200;
long nightCO2Low = 500;
long nightCO2High = 600;

float dayTempLow = 90;
float dayTempHigh = 100;
float mornTempLow = 65;
float mornTempHigh = 75;
float nightTempLow = 75;
float nightTempHigh = 85;

// include the library code:
#include "Wire.h"
#include "Adafruit_LiquidCrystal.h"

// Connect via i2c, default address #0 (A0-A2 not jumpered)
Adafruit_LiquidCrystal lcd(0);



void setup() {

  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  // set up the LCD's number of rows and columns:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("hello, world!");
}

void loop()
{
  unsigned long uvDelay = uvOnSecs * 1000UL;
  userInt();
  assignSetpoints();
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 0);
  lcd.setBacklight(HIGH);
}
//#######################################################
void userInt()
{
  if(digitalRead(up)==HIGH)
  {
    subMenu++;
    updateLCD();
  }
  if(digitalRead(down)==HIGH)
  {
    subMenu--;
    updateLCD();
  }
  if(digitalRead(right)==HIGH)
  {
    menu++;
    updateLCD();
  }
  if(digitalRead(left)==HIGH)
  {
    menu--;
    updateLCD();
  }
  if(digitalRead(increase)==HIGH)
  {
    
  }
}
void assignSetpoints()
{
  if (day)
  {
    co2Low = 1000;
    co2High = 1200;
    tempLow = 90;
    tempHigh = 100;
  }
  if (morning)
  {
    tempLow = 65;
    tempHigh = 75;
  }
  if (!day)
  {
    co2Low = 500;
    co2High = 600;
    tempLow = 75;
    tempHigh = 85;
  }
}
void updateLCD()
{
   if (menu == 1 && subMenu == 1)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("co2");
    lcd.setCursor(0, 1);
    lcd.print(co2ppm );
    menuPrev = menu;
    subMenuPrev = subMenu;
    varNumb=0; 
  }

  if (menu == 1 && subMenu == 2)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("dayCO2Low");
    lcd.setCursor(0, 1);
    lcd.print(dayCO2Low);
    menuPrev = menu;
    subMenuPrev = subMenu;
  }
  if (menu == 1 && subMenu == 3)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("dayCO2High");
    lcd.setCursor(0, 1);
    lcd.print(dayCO2High);
    menuPrev = menu;
    subMenuPrev = subMenu;
  }
  if (menu == 1 && subMenu == 4)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("nightCO2Low");
    lcd.setCursor(0, 1);
    lcd.print(nightCO2Low);
    menuPrev = menu;
    subMenuPrev = subMenu;
  }
  if (menu == 1 && subMenu == 5)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("nightCO2High");
    lcd.setCursor(0, 1);
    lcd.print(nightCO2High);
    menuPrev = menu;
    subMenuPrev = subMenu;
  }
  if (menu == 1 && subMenu > 5)
  {
    subMenu = 1;
  }
  if (menu == 1 && subMenu < 1)
  {
    subMenu = 5;
  }
  //_________________________________________________________
  if (menu == 2 && subMenu == 1)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Temperature");
    lcd.setCursor(0, 1);
    lcd.print(temp_f);
    menuPrev = menu;
    subMenuPrev = subMenu;
  }
  if (menu == 2 && subMenu == 2)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("dayTempLow");
    lcd.setCursor(0, 1);
    lcd.print(dayTempLow);
    menuPrev = menu;
    subMenuPrev = subMenu;
  }
  if (menu == 2 && subMenu == 3)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("dayTempHigh");
    lcd.setCursor(0, 1);
    lcd.print(dayTempHigh);
    menuPrev = menu;
    subMenuPrev = subMenu;
  }
  if (menu == 2 && subMenu == 4)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("mornTempLow");
    lcd.setCursor(0, 1);
    lcd.print(mornTempLow);
    menuPrev = menu;
    subMenuPrev = subMenu;
  }
  if (menu == 2 && subMenu == 5)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("mornTempHigh");
    lcd.setCursor(0, 1);
    lcd.print(mornTempHigh);
    menuPrev = menu;
    subMenuPrev = subMenu;
  }
  if (menu == 2 && subMenu == 6)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("nightTempLow");
    lcd.setCursor(0, 1);
    lcd.print(nightTempLow);
    menuPrev = menu;
    subMenuPrev = subMenu;
  }
  if (menu == 2 && subMenu == 7)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("nightTempHigh");
    lcd.setCursor(0, 1);
    lcd.print(nightTempHigh);
    menuPrev = menu;
    subMenuPrev = subMenu;
  }
  if (menu == 2 && subMenu > 7)
  {
    subMenu = 1;
  }
  if (menu == 2 && subMenu < 1)
  {
    subMenu = 7;
  }
  //_______________________________________________________
  if (menu == 3 && subMenu == 1)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("RH");
    lcd.setCursor(0, 1);
    lcd.print(rh);
    menuPrev = menu;
    subMenuPrev = subMenu;
  }
  if (menu == 3 && subMenu > 7)
  {
    subMenu = 1;
  }
  if (menu == 3 && subMenu < 1)
  {
    subMenu = 7;
  }
  //___________________________________________________________
  if (menu == 4 && subMenu == 1)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Soil Moisture");
    lcd.setCursor(0, 1);
    lcd.print(soilMoisture);
    menuPrev = menu;
    subMenuPrev = subMenu;
  }
  if (menu == 4 && subMenu == 2)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("soilMoisture");
    lcd.setCursor(0, 1);
    lcd.print(soilMoistureSetpoint);
    menuPrev = menu;
    subMenuPrev = subMenu;
  }
  if (menu == 4 && subMenu == 3)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("pumpDelay");
    lcd.setCursor(0, 1);
    lcd.print(pumpDelay);
    menuPrev = menu;
    subMenuPrev = subMenu;
  }
  if (menu == 4 && subMenu > 3)
  {
    subMenu = 1;
  }
  if (menu == 4 && subMenu < 1)
  {
    subMenu = 3;
  }
  if (menu == 5 && subMenu == 1)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Lighting");
    lcd.setCursor(0, 1);
    if (day)
    {
      lcd.print("on");
    }
    else
    {
      lcd.print("off");
    }
    menuPrev = menu;
    subMenuPrev = subMenu;
  }
  if (menu == 5 && subMenu == 2)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("hoursOn");
    lcd.setCursor(0, 1);
    lcd.print(hoursOn);
    menuPrev = menu;
    subMenuPrev = subMenu;
  }
  if (menu == 5 && subMenu == 3)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("hoursOff");
    lcd.setCursor(0, 1);
    lcd.print(hoursOff);
    menuPrev = menu;
    subMenuPrev = subMenu;
  }
  if (menu == 5 && subMenu == 4)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("mornHours");
    lcd.setCursor(0, 1);
    lcd.print(mornHours);
    menuPrev = menu;
    subMenuPrev = subMenu;
  }
  if (menu == 5 && subMenu == 5)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("fanMins");
    lcd.setCursor(0, 1);
    lcd.print(fanMins);
    menuPrev = menu;
    subMenuPrev = subMenu;
  }
  if (menu == 5 && subMenu == 6)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("uvOnSecs");
    lcd.setCursor(0, 1);
    lcd.print(uvOnSecs);
    menuPrev = menu;
    subMenuPrev = subMenu;
  }
  if (menu == 5 && subMenu < 1)
  {
    subMenu = 6;
  }
  if (menu == 5 && subMenu > 6)
  {
    subMenu = 1;
  }
}

increase and decrease buttons will do different things based on the value of varNumb

The code would be much easier to follow using switch/case statements and a separate function for each main menu.

void updateLCD() {
    switch (menu) {
case 0:  menu=5; break
case 1:  MenuOne(); break;

case 2:  MenuTwo(); break;
case 3:  MenuThree(); break;

case 4:  MenuFour(); break;
case 5:  MenuFive(); break;

default: menu = 1;
    }
}


void MenuOne() {
  switch (subMenu) {
case 0: subMenu = 5; break;
case 1:  Show("co2", co2ppm); break;
case 2:  Show("dayCO2Low", dayCO2Low); break;
case 3:  Show("dayCO2High", dayCO2High); break;
case 4:  Show("nightCO2Low", nightCO2Low); break;
case 5:  Show("nightCO2High", nightCO2High); break;
default: subMenu = 1;
    }
  menuPrev = menu;
  subMenuPrev = subMenu;
}

void Show(char *label, long value) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print(label);
    lcd.setCursor(0, 1);
    lcd.print(value);
}

johnwasser that is sooo much better. I thought I was done tonight. I uploaded the sketch, without the sensors and relays hooked up to test the UI, and it was running super slow. I created debugging sketch using the serial monitor and it is taking 4.5 seconds to complete one cycle.

there is more code than what I have posted here, but is this typical?

will the change you posted help with that?

I did some google research and found this

"•Slow digitalRead and digitalWrite – these two functions are orders of magnitude (~60 cycles) slower than direct port access (~1 cycle!). Heavy I/O can look slow or latent as a result. •Bad code – the Arduino is exceptionally easy to use without understanding any of the underlying concepts of microcontrollers. As a result, code is sometimes simply bad. " can you point me in the right direction to understand how to implement "direct port access" and learn how to use interrupts?

roosterqmoney: I uploaded the sketch, without the sensors and relays hooked up to test the UI, and it was running super slow. I created debugging sketch using the serial monitor and it is taking 4.5 seconds to complete one cycle.

That sounds like there is something blocking somewhere. Maybe there is something waiting for a response from a sensor that is not attached?

roosterqmoney: there is more code than what I have posted here, but is this typical?

I don't see any obvious problems in the portion you posted (unless "uvDelay" is used in a delay() call somewhere). Perhaps there is a problem in the part you didn't post.

roosterqmoney: twill the change you posted help with that?

It will help a lot with readability but should not change the execution speed.

roosterqmoney: I did some google research and found this

"•Slow digitalRead and digitalWrite – these two functions are orders of magnitude (~60 cycles) slower than direct port access (~1 cycle!). Heavy I/O can look slow or latent as a result. •Bad code – the Arduino is exceptionally easy to use without understanding any of the underlying concepts of microcontrollers. As a result, code is sometimes simply bad. " can you point me in the right direction to understand how to implement "direct port access" and learn how to use interrupts?

DigitalWrite() takes about 6 microseconds. Unless you need to do more than 10,000 per second you don't need Direct Port Access. Interrupts are usually not the right answer either. The loop() function shouldn't take more that about 0.01 seconds. Find where you are spending the other 4.49 seconds and fix that.

its probably the fact that none of the sensors are hooked up then, I'll try running just the ui portion. I was going to use delay in some portions but larryd convinced me otherwise and so none of it should be blocking. I know the CO2 sensor code is taking .5 seconds because it doesn't start being used until it has had 3 mins to warm up. sure enough at 3 mins it goes from a 4 sec cycle to a 4.5 sec cycle.

I commented out the function that checks all the sensors and I'm down to 3-4 ms. Still gonna use your formatting for the UI though. As I was writing my UI I almost decided to use switch for the UI but decided it wouldn't really be much different, but seeing it done, it is way cleaner.

roosterqmoney: As I was writing my UI I almost decided to use switch for the UI but decided it wouldn't really be much different, but seeing it done, it is way cleaner.

When you have code like:

if (var == 1) {
    // Do something
} else if (var == 2 || var == 3) {
    // Do something
} else if (var == 4) { ...
} else {
    // Do the default
}

It is almost always better to use a switch statement. As long as all of the if's compare the same variable is equal to one or more integer constants you have a good candidate. Making each menu a separate function cleans up the nesting quite a bit. This is a case where having a function that is called only from one place makes sense. Since the code being executed in each case was the same except for two values, it made sense to use the Show() function to avoid writing the same code over and over.

yeah the show function was the missing piece in my mind. I wasn't sure how to grab different variables like that and use them inside the function. Thanks again.