Looking for guidance on structure and organization of code

Hello,

I am looking to improve my code and coding abilities, I have been looking to see what is best method but I need a push in the right direction. I am seeking to see if there is a better way to structure, write, and organize code.

I have been looking into object orientated programming using classes but unsure if this is the correct method to make my code better.

I will be continuing to add things for the Arduino to control but this is what I have so far

What my code does: Controls fish tank operations
Brief explanation

  • Checks water level, asks for permission to top off if low, if approved tops of water until water is at high level float switch.

  • When water change button is selected:
    checks sensor readings, pumps out water to low level sensor, pause, pumps water in until high level float switch

-manual fill/ drain:
if fill button is pressed fill
if drain button is pressed drain

Thanks for the help!

/* Verison 3.1 ignore top off with millis for 10 minutes
New: When sensor bypass is initiated drain and fill will show screen with option to cancel fill
and drain function


*/
#include <Elegoo_GFX.h>    // Core graphics library
#include <Elegoo_TFTLCD.h> // Hardware-specific library
#include <TouchScreen.h>

#if defined(__SAM3X8E__)
    #undef __FlashStringHelper::F(string_literal)
    #define F(string_literal) string_literal
#endif

#define YP A3  // must be an analog pin, use "An" notation!
#define XM A2  // must be an analog pin, use "An" notation!
#define YM 9   // can be a digital pin
#define XP 8   // can be a digital pin

#define TS_LEFT 85
#define TS_RIGHT 900

#define TS_TOP 105
#define TS_BOT 920

// pressure resisistance @300ohms
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);

#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
// optional
#define LCD_RESET A4

//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



Elegoo_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);


#define BOXSIZE 40 //size of boxes for button
#define PENRADIUS 3 //size of what how big of a line (circle)
int oldcolor, currentcolor;
//----------------------------------------

int on=LOW ;
int off=HIGH ;
int fillPin=23 ;
int drainPin=22 ;
int highlevelPin=24 ;
int lowlevelPin= 25 ;
int lowtopoffPin=26 ;
int lowtopOff ;
int SWCButtonNew ;
int highLevel ;
int lowLevel ;
int newState ;
int dt=250 ;
int NewlowLevel;
int drainfillDelay=3000 ;
int py ;
int px ;
int fillbucketlevelPin = 26 ;
int fillbucketLevel ;
int button ;
int d;
int menuChoice ;
int x ;
int currentScreen ;
int oldScreen ;
int topoffScreen ;
int y ;
int ignore ;
unsigned long ignoreStartMillis ;
unsigned long ignoreCurrentMillis ;
unsigned long ignoreTime ;
unsigned long currentMillis ;
const unsigned longPeriod = 1000 ;
int wait;

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600) ;
Serial.println("Program run") ;

pinMode(13,OUTPUT) ;
   pinMode(XM, OUTPUT);
  pinMode(YP, OUTPUT);
  pinMode(drainPin,OUTPUT);

pinMode(highlevelPin,INPUT) ;
pinMode(lowlevelPin,INPUT);
digitalWrite(drainPin,off);
digitalWrite(fillPin,off);
pinMode(fillPin,OUTPUT) ;
ignore = 0 ;
currentMillis ;
  

  tft.reset() ;
tft.begin(0x9341);
 tft.setRotation(3) ;



#define MINPRESSURE 5
#define MAXPRESSURE 1000

//create home screen--------------------------------------------------------------------
   //Draw white frame
    tft.fillScreen (BLUE) ;
    tft.drawRect (0,0,319,240,WHITE) ;

  //Print "hello" text
  tft.setCursor(100,30) ;
  tft.setTextColor (WHITE) ;
  tft.setTextSize(2) ;
  tft.print("Tankduino V3.0") ;

  //create water change button
  tft.fillRoundRect(40,180,260,40,6,GREEN) ;
  tft.drawRoundRect(40,180,260,40,6,WHITE) ;
  tft.setCursor(60,188) ;
  tft.setTextColor(BLACK) ;
  tft.setTextSize(2) ;
  tft.print("Begin Water Change") ;

  //create manual fill/drain
  tft.fillRoundRect(40,120,260,40,6,GREEN) ;
  tft.drawRoundRect(40,120,260,40,6,WHITE) ;
  tft.setCursor(60,128) ;
  tft.setTextColor(BLACK) ;
  tft.setTextSize(2) ;
  tft.print("manual fill/drain") ;

}

void loop() {
 //Serial.println ("restart code") ;
  digitalWrite (13,HIGH) ;
  TSPoint p = ts.getPoint() ;
  digitalWrite (13,LOW) ;
  menuChoice=1 ;
if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {

     py = map (p.x, TS_TOP, TS_BOT, 0, tft.height()) ;
    px = map (p.y, TS_LEFT, TS_RIGHT,0, tft.width()) ;

    Serial.print("("); Serial.print(px);
    Serial.print(", "); Serial.print(py);
    Serial.println(")");

 if (( px > 40 && px < 300) && (py > 180 && py < 220)) { // if the create water change button is selected
    
    menuChoice=3 ;
     }

 if (( px > 40 && px < 300) && (py > 120 && py < 160)) { // if the manual fill/drain button is selected
    menuChoice=2 ;
    }
}
Serial.print ("Menu choice is ");
Serial.println(menuChoice) ;
Serial.print ("Current screen is ") ;
Serial.println (currentScreen) ;
switch(menuChoice) {
  
  //Water change case ------------------------------------------------------------------------
        case 3 :  //water change case
      Serial.println("Water Change") ;

        pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
 
 //create water change in progress button
tft.fillRect(40,180,260,40,RED) ;
tft.drawRect(40,180,260,40,WHITE) ;
tft.setCursor(60,188) ;
tft.setTextColor(BLACK) ;
tft.setTextSize(1) ;
tft.print("Water change in progress") ;

highLevel=digitalRead(highlevelPin) ;
    lowLevel=digitalRead(lowlevelPin) ;
    Serial.print("low Level is ") ;
    Serial.println(lowLevel) ;
    Serial.print("High Level is ") ;
    Serial.println(highLevel) ;
    if (highLevel==1 && lowLevel==1) {
      Serial.println ("sensors working") ;
     lowLevel=digitalRead(lowlevelPin) ;
      while (lowLevel==1) {
      
             digitalWrite(drainPin,on) ;
             Serial.println ("Drain on") ;
             lowLevel=digitalRead(lowlevelPin) ;
             Serial.print("low level is ") ;
             Serial.println (lowLevel) ;
              }
      digitalWrite(drainPin,off) ;
      delay(drainfillDelay) ;

      highLevel=digitalRead(highlevelPin) ;

      while (highLevel==0) {
      
             digitalWrite(fillPin,on) ;
             Serial.println ("Filling") ;
             highLevel=digitalRead(highlevelPin) ;
             Serial.print("High level pin is ") ;
             Serial.println (highLevel) ;
              }
      digitalWrite(drainPin,off) ;
      digitalWrite(fillPin,off) ;
      
    
    }

// bypass sensor check screen

else {
   pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
    tft.fillScreen(RED) ;
  
  //Print "Sensor check" text
  tft.setCursor(75,30) ;
  tft.setTextColor (WHITE) ;
  tft.setTextSize(2) ;
  tft.print("Sensor reading low") ;
    
tft.fillRoundRect (24,128, 260, 40,6, WHITE) ;
tft.setCursor (28,140) ;
tft.setTextColor(BLACK) ;
tft.setTextSize(2) ;
tft.print("Bypass sensor check") ; 

tft.fillRoundRect(5,5,30,30,6,BLACK) ;
                 tft.drawRoundRect(5,5,30,30,6,WHITE) ;
                 tft.setCursor(11,6) ;
                 tft.setTextColor(RED) ;
                 tft.setTextSize(3) ;
                 tft.print("x") ;
                 wait=0 ;

while (wait==0) {
  
    digitalWrite (13,HIGH) ;
TSPoint p = ts.getPoint() ;
digitalWrite (13,LOW) ;

  
if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {

     py = map (p.x, TS_TOP, TS_BOT, 0, tft.height()) ;
    px = map (p.y, TS_LEFT, TS_RIGHT,0, tft.width()) ;

    Serial.print("("); Serial.print(px);
    Serial.print(", "); Serial.print(py);
    Serial.println(")");

    if (( px > 20 && px < 270) && (py > 120 && py < 260)) {
          highLevel=digitalRead(highlevelPin) ;
    lowLevel=digitalRead(lowlevelPin) ;
    Serial.print ("Bypass enabled") ;
    
          
    while (lowLevel==1) {
      
             digitalWrite(drainPin,on) ;
             Serial.println ("Drain on") ;
             lowLevel=digitalRead(lowlevelPin) ;
             Serial.print("low level is ") ;
             Serial.println (lowLevel) ;
              }
      digitalWrite(drainPin,off) ;
      delay(drainfillDelay) ;

      highLevel=digitalRead(highlevelPin) ;

      while (highLevel==0) {
      
             digitalWrite(fillPin,on) ;
             Serial.println ("Filling") ;
             highLevel=digitalRead(highlevelPin) ;
             Serial.print("High level pin is ") ;
             Serial.println (highLevel) ;
              }
      digitalWrite(drainPin,off) ;
      digitalWrite(fillPin,off) ;
      
    
    }



    
 
    menuChoice=1 ;
    currentScreen =0 ;
    break ;
    
    }

    if ((px > 5 && px < 35) && (py > 5 && py < 35)) {
      Serial.print ("Home") ;
     wait=1 ;
      menuChoice =1 ;
      currentScreen=0 ;
    }
                   
}

    
}

    
 
    menuChoice=1 ;
    currentScreen =0 ;
    break ;
    
  // Manual fill/drain case-------------------------------------------------------------------
        case 2 :

               Serial.println("Enter manual fill/Drain") ;
               //Print create fill and drain buttons
                pinMode(XM, OUTPUT);
                pinMode(YP, OUTPUT);

               

                //Print "hello" text
                 tft.setCursor(100,30) ;
                 tft.setTextColor (BLUE) ;
                 tft.setTextSize(4) ;
                 tft.print("Hello") ;

                 tft.setCursor(60,30) ;
                 tft.setTextColor (WHITE) ;
                 tft.setTextSize(2) ;
                 tft.print("Manual fill/drain") ;

                 //create fill button
                 tft.fillRoundRect(40,180,260,40,6,GREEN) ;
                 tft.drawRoundRect(40,180,260,40,6,WHITE) ;
                 tft.setCursor(60,188) ;
                 tft.setTextColor(BLACK) ;
                 tft.setTextSize(2) ;
                 tft.print("Fill") ;

                 //create drain
                 tft.fillRoundRect(40,120,260,40,6,GREEN) ;
                 tft.drawRoundRect(40,120,260,40,6,WHITE) ;
                 tft.setCursor(60,128) ;
                 tft.setTextColor(BLACK) ;
                 tft.setTextSize(2) ;
                 tft.print("Drain") ;

                 // create back to home button

                  tft.fillRoundRect(5,5,30,30,6,RED) ;
                 tft.drawRoundRect(5,5,30,30,6,WHITE) ;
                 tft.setCursor(11,6) ;
                 tft.setTextColor(BLACK) ;
                 tft.setTextSize(3) ;
                 tft.print("x") ;
                 x=0 ;

                  while (x==0) {
                    Serial.println ("x=0") ;
                   digitalWrite (13,HIGH) ;
                   TSPoint p = ts.getPoint() ;
                   digitalWrite (13,LOW) ;
                    
                   py = map (p.x, TS_TOP, TS_BOT, 0, tft.height()) ;
                   px = map (p.y, TS_LEFT, TS_RIGHT,0, tft.width()) ;
       
      /* Drain  */ while (  (px > 40 && px < 300) && (py > 120 && py < 160)) {

                   
                      Serial.println ("drain") ;
                      digitalWrite (drainPin, on) ;
        
                      pinMode(XM, OUTPUT);
                pinMode(YP, OUTPUT);

                      tft.fillRoundRect(40,120,260,40,6,RED) ;
                 tft.drawRoundRect(40,120,260,40,6,WHITE) ;
                 tft.setCursor(60,128) ;
                 tft.setTextColor(BLACK) ;
                 tft.setTextSize(2) ;
                 tft.print("Drain") ;

                         

                      digitalWrite (13,HIGH) ;
                      TSPoint p = ts.getPoint() ;
                      digitalWrite (13,LOW) ;

                      py = map (p.x, TS_TOP, TS_BOT, 0, tft.height()) ;
                      px = map (p.y, TS_LEFT, TS_RIGHT,0, tft.width()) ;
                      
                      
                      while (  (px > 40 && px < 300) && (py > 120 && py < 160)) {
                         digitalWrite (13,HIGH) ;
                      TSPoint p = ts.getPoint() ;
                      digitalWrite (13,LOW) ;

                      py = map (p.x, TS_TOP, TS_BOT, 0, tft.height()) ;
                      px = map (p.y, TS_LEFT, TS_RIGHT,0, tft.width()) ;
                        
                        
                      }

                          pinMode(XM, OUTPUT);
                pinMode(YP, OUTPUT);

                      tft.fillRoundRect(40,120,260,40,6,GREEN) ;
                 tft.drawRoundRect(40,120,260,40,6,WHITE) ;
                 tft.setCursor(60,128) ;
                 tft.setTextColor(BLACK) ;
                 tft.setTextSize(2) ;
                 tft.print("Drain") ;
                      }

                      
                      digitalWrite (drainPin,off) ;
                      /* pinMode(XM, OUTPUT);
                pinMode(YP, OUTPUT);

                      tft.fillRoundRect(40,120,260,40,6,GREEN) ;
                 tft.drawRoundRect(40,120,260,40,6,WHITE) ;
                 tft.setCursor(60,128) ;
                 tft.setTextColor(BLACK) ;
                 tft.setTextSize(2) ;
                 tft.print("Drain") ;
              */                  
                      
                      

       /* fill  */    while (  (px > 40 && px < 300) && (py > 180 && py < 220)) {
                      Serial.println ("fill") ;
                      digitalWrite (fillPin, on) ;

                      pinMode(XM, OUTPUT);
                pinMode(YP, OUTPUT);

                 tft.fillRoundRect(40,180,260,40,6,RED);
                 tft.drawRoundRect(40,180,260,40,6,WHITE) ;
                 tft.setCursor(60,188) ;
                 tft.setTextColor(BLACK) ;
                 tft.setTextSize(2) ;
                 tft.print("Fill") ;


                      digitalWrite (13,HIGH) ;
                      TSPoint p = ts.getPoint() ;
                      digitalWrite (13,LOW) ;

                      py = map (p.x, TS_TOP, TS_BOT, 0, tft.height()) ;
                      px = map (p.y, TS_LEFT, TS_RIGHT,0, tft.width()) ;
                      
                      while (  (px > 40 && px < 300) && (py > 180 && py < 220)) {
                        digitalWrite (13,HIGH) ;
                      TSPoint p = ts.getPoint() ;
                      digitalWrite (13,LOW) ;

                      py = map (p.x, TS_TOP, TS_BOT, 0, tft.height()) ;
                      px = map (p.y, TS_LEFT, TS_RIGHT,0, tft.width()) ;
                        
                      }
                      
                      pinMode(XM, OUTPUT);
                      pinMode(YP, OUTPUT);
                      tft.fillRoundRect(40,180,260,40,6,GREEN) ;
                 tft.drawRoundRect(40,180,260,40,6,WHITE) ;
                 tft.setCursor(60,188) ;
                 tft.setTextColor(BLACK) ;
                 tft.setTextSize(2) ;
                 tft.print("Fill") ;
                      
                      }
                      digitalWrite (fillPin,off) ;  
                       
                      
                     
                              

                 //------------------------

                

                 
                 if ((px>5 && px<35) && (py>5 && py <35)) {
                      x=1 ;
                      menuChoice=1 ;
                      currentScreen=0 ;
                      Serial.println ("Exit") ;
                      break ;
                    }
                 
                  }
                    
              

                 

               

    


// Main menu case ----------------------------------------------------------------------------
        case 1 :
  if (currentScreen ==0) {
  Serial.print ("Main Menu") ;
   pinMode(XM, OUTPUT);
                pinMode(YP, OUTPUT);
  //Draw white frame
    tft.fillScreen (BLUE) ;
    tft.drawRect (0,0,319,240,WHITE) ;

  //Print "hello" text
  tft.setCursor(100,30) ;
  tft.setTextColor (WHITE) ;
  tft.setTextSize(4) ;
  tft.print("Hello") ;

  //create water change button
  tft.fillRoundRect(40,180,260,40,6,GREEN) ;
  tft.drawRoundRect(40,180,260,40,6,WHITE) ;
  tft.setCursor(60,188) ;
  tft.setTextColor(BLACK) ;
  tft.setTextSize(2) ;
  tft.print("Begin Water Change") ;

  //create manual fill/drain
  tft.fillRoundRect(40,120,260,40,6,GREEN) ;
  tft.drawRoundRect(40,120,260,40,6,WHITE) ;
  tft.setCursor(60,128) ;
  tft.setTextColor(BLACK) ;
  tft.setTextSize(2) ;
  tft.print("manual fill/drain") ;

  currentScreen=1 ;
break ;
  }
}

// Automatic top off with approval of topping off from touchscreen user
 highLevel = digitalRead (highlevelPin) ;
 lowtopOff= digitalRead (lowtopoffPin) ;

 currentMillis= (millis());
 ignoreTime=currentMillis - ignoreStartMillis ;

 // Serial.println(ignoreTime) ;

 if (ignoreTime > 600000) {
  ignore=0 ;
 }

 if ((lowtopOff==0) && (ignore==0)) {

 /// Alert screen When fish tank needs to be topped off

  
  pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);

    tft.fillScreen(RED) ;
tft.fillRoundRect (24,128, 260, 40,6, WHITE) ;
tft.setCursor (28,140) ;
tft.setTextColor(BLACK) ;
tft.setTextSize(2) ;
tft.print("Approve water top off") ; 

tft.fillRoundRect(5,5,30,30,6,BLACK) ;
                 tft.drawRoundRect(5,5,30,30,6,WHITE) ;
                 tft.setCursor(11,6) ;
                 tft.setTextColor(RED) ;
                 tft.setTextSize(3) ;
                 tft.print("x") ;
                 x=0 ;

while ((lowtopOff==0) && (ignore==0)) {

digitalWrite (13,HIGH) ;
TSPoint p = ts.getPoint() ;
digitalWrite (13,LOW) ;

  
if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {

     py = map (p.x, TS_TOP, TS_BOT, 0, tft.height()) ;
    px = map (p.y, TS_LEFT, TS_RIGHT,0, tft.width()) ;

    Serial.print("("); Serial.print(px);
    Serial.print(", "); Serial.print(py);
    Serial.println(")");

    if ((px > 5 && px < 35) && (py > 5 && py < 35)) {
      Serial.print ("Ignore") ;
      ignore=1 ;
      ignoreStartMillis=(millis()) ;
      menuChoice =1 ;
      currentScreen=0 ;
    }
    
  if (( px > 20 && px < 270) && (py > 120 && py < 260)) {
    highLevel=digitalRead(highlevelPin) ;
    Serial.println ("Top off Approved") ;
    Serial.print("High level is ") ;
    Serial.println(highLevel) ;
    while (highLevel ==0) {
      Serial.println("Topping off") ;
       pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);

    tft.fillScreen(RED) ;
tft.fillRect (20,120, 250, 40, GREEN) ;
tft.setCursor (20,140) ;
tft.setTextColor(BLACK) ;
tft.setTextSize(2) ;
tft.print("Topping off water") ; 
      digitalWrite(fillPin,on);
      highLevel=digitalRead(highlevelPin) ;
    }
    digitalWrite (fillPin,off) ;
highLevel=digitalRead(highlevelPin) ;
lowtopOff= digitalRead (lowtopoffPin) ;
menuChoice=1 ;
currentScreen =0 ;
    
    
    
 
  }

 
 }

 }

 }
}

First of all: pretty format your code in the IDE.

Encapsulate the lengthy code blocks into functions so that the control flow can be recognized better.

1 Like

Also get rid of most of the blank lines...

Need to know how it is currently structured and organized before analysis. Currently it is hard to determine that.

Step 1: format your code with CTRL-T
Step 2: remove all multiple line breaks

Step 3: follow your description:

I would expect to find some functions in your code like:

checkWaterLevel()
checkForPermission()
fillWithWater()
checkSensorReading()
pumpOutWaterToLowlevel()
pumtInWaterUntilHighLevel()

just as an idea.

regarding your current code:
check each int if

  • you really need a two byte signed variable
  • it ever changes the value during runtime. If not - mark it const

Thank you did not know that was possible! I will have to look into encapsulating the code blocks!

Great thanks, I will work on that!

Sure, one thing I would focus on is the display code. You should create display functions that hide all that verbose TFT code.

Look at sections that are similar or identical, learn how to pass parameters so you only have to express them once.

                tft.fillRoundRect(40,180,260,40,6,RED);
                 tft.drawRoundRect(40,180,260,40,6,WHITE) ;
                 tft.setCursor(60,188) ;
                 tft.setTextColor(BLACK) ;
                 tft.setTextSize(2) ;
                 tft.print("Fill") ;

elsewhere you have:

    tft.fillScreen(RED) ;
tft.fillRoundRect (24,128, 260, 40,6, WHITE) ;
tft.setCursor (28,140) ;
tft.setTextColor(BLACK) ;
tft.setTextSize(2) ;
tft.print("Approve water top off") ; 

The main difference seems to be the text message so you should make something like

void printRedAndBlack(const char* message, int x, int y, int xSize, int ySize) {...

Again, I hesitate to delve into details because it would be a lot of work at this stage. I would also have a high level look at the visual interface, to find simplifications that I could make.

Great thank you! I will have to look into implementing those.
I also need to do some research to have a better understanding of when to use int, byte, and const. I know learned about int first so I resort to using that.

The 'int' type was really designed for that. It's been a "catch all" type since the beginning of C.

For your later self:
Add units...

#define somepressure 3000  // in mbar or Pa or whatever

Variables always like to be mentioned. Usually doing so is in the context of advancing the algorithm… that line of code does nothing and is probably optimised away.

Anyway, does your code currently do what you want?

There are a number of places where you stay in a loop until something finishes. This works, but makes it harder to do things like add a feature where a pump staying on for an implausibly long period would result in a system error and closing of valves and stuff like that.

So the biggest change would be to move it to a process based on finite state machinery and the IPO model of programming.

Neither of which will mean you need to learn new language features. Rather you will be changing the whole approach.

google

arduino blink without delay

and

 arduino finite state machine

and

arduino two things at once

For a high level look at this method see

Seems daunting; expect to need to have an Aha! moment at some point, after which you'll be programming differently.

HTH

a7

1 Like

My day to offend & anger numerous forum members.
Opinion:
Job #1: Working code producing correct results within the requirements.

If job #1 is satisfied, coding is complete; everything else is "extra." Many hobby programmers do not need to advance to the next-level.

As you are wishing to improve your "style", then the suggestions given previously by others are appropriate. Think of the results being that between eating at a fast-food restaurant and eating at a Michelin 5-star restaurant: you will be fed either way, but the presentation, ambiance, and cost is radically different. (Cost in programming equates to time spent coding.)

Did you know, code encapsulated in functions and classes actually slows down execution? All that jumping around adds extra cpu cycles to push the stack and initialize any dynamic structures. Professionals expend those extra clock cycles for code that is:

  • encapsulated, private variable usage
  • logic that can be separated from the main code
    -- easy to visualize & understand
    -- easy to test
    -- easy to reuse

Thus, the ideal "forum posted code" may appear as:


void loop() {
    analog_0();           // A0  Water temperature
    analog_1();           // A1  Oil temperature
    analog_2();           // A2  Oil Pressure    
}

The simple loop() structurer makes it easy to understand what the purpose of the sketch is designed to accomplish.
The reader does not at this point know if the functions do raw analog reads, perform averages, or even send information to serial/screen. The functions just represent steps in things to do.

Improve your code by creating functions you can reuse in the next project. IMO, it is better to copy & paste function-based code rather than class-based libraries for simple, straight-forward hobby use.

If you want to go farther and write C++ libraries, that is useful to create codebases where a single container encapsulates multiple related functions; GPS being a good example.

Take your programming skills as far as you wish, but always understand that job #1 is the most important programming goal.

Cost taken from one end to the other will include planning and design, coding and getting something to work correctly.

So a good design might take longer to code but cost less by the time the capsule is launched for the Moon.

I agree with what @mrburnette has said, and offer a different straw man for the loop(), viz:

void loop()
{
  ReadAllInputs();
  advanceTimers();

  decideOnActions();

  turnStuffOffAndOn();

// rinse and repeat
}

a7

Yes, my code does mostly what I want. I want to keep adding to it to make it better and more usable. I decided instead of adding more things (sensors and things to control) , I would take time to hopefully better organize and structure code. I am hoping by organizing my code it will make it run more efficient, be easier to add things in the future, and learn the proper way to code things. I enjoy learning how programming works. Thanks I will look into the IPO model

In my world, that of a retired hobbyists, only "time" carved out from spouse to-do-list is applicable as I was talking non-commercial. In industry, programmers in large companies have little say in how code will be generated... it is just an assembly line: write this 'need' using these 'tools' and these 'approved' methodologies.

Been there, managed that... little wiggle-room for injecting personal tastes.

For hobby, "time" is the "cost" ... well, maybe the occasional beer, too.

1 Like

Hello jemmag9

At first you have to make a decission how to generate code.

Either in a procedural or in an object-oriented way. This different approach creates different programme structures.

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

I agree. So you code stuff without any time "spent" in planning or designing it, and it works perfectly first time.

Therefore coding time = time. I get it.

a7

I can tell you worked for a profit oriented business rather than a government agency. Great narrative!

I evolved in an age where coding was on Fortran coding "ruled" paper. Thinking was required in those days; entire concepts were mind experiments and then put to code. Yes, lots of scrap pieces of notebook paper before using those coding-pads. Flowcharts (formal to turn in) came after a successful batch run.

I still approach problem solving and specifically coding as mainly "from brain to terminal." I once thought TSO terminals were Devine gifts.

@jemmag9 the functions that @noiasca expects to see raise some questions about the more detailed specifications.

Currently documented de facto style, or operationally, by the device as it is now.

Reading the code and analyzing it would be slower than ask these few.

So there may be more, but…

How many levels need signals? Is there a low level float?

Is the level reached for water change different than the level you want the drain button to go to?

Can you draw a fluidic schematic (!) that shows all the places water can go and stay and so forth, and how these are interconnected and what means there are for opening or closing valves or controlling pumps? As well as any sensors you may have float or whatever.

And a schematic of the Arduino and what is connected all to it with attention to be sure to show where power comes from and how it gets to where it is needed.

All of which I am sure you have already! :wink:

a7