Regarding SPI.h library pins

i am using built-in SPI.h library.
here my doubt is what exactly SPI.begin(); means.

SPI.h

/*
 * Copyright (c) 2010 by Cristian Maglie <c.maglie@arduino.cc>
 * Copyright (c) 2014 by Paul Stoffregen <paul@pjrc.com> (Transaction API)
 * Copyright (c) 2014 by Matthijs Kooijman <matthijs@stdin.nl> (SPISettings AVR)
 * Copyright (c) 2014 by Andrew J. Kroll <xxxajk@gmail.com> (atomicity fixes)
 * SPI Master library for arduino.
 *
 * This file is free software; you can redistribute it and/or modify
 * it under the terms of either the GNU General Public License version 2
 * or the GNU Lesser General Public License version 2.1, both as
 * published by the Free Software Foundation.
 */

#ifndef _SPI_H_INCLUDED
#define _SPI_H_INCLUDED

#include <Arduino.h>

// SPI_HAS_TRANSACTION means SPI has beginTransaction(), endTransaction(),
// usingInterrupt(), and SPISetting(clock, bitOrder, dataMode)
#define SPI_HAS_TRANSACTION 1

// SPI_HAS_NOTUSINGINTERRUPT means that SPI has notUsingInterrupt() method
#define SPI_HAS_NOTUSINGINTERRUPT 1

// SPI_ATOMIC_VERSION means that SPI has atomicity fixes and what version.
// This way when there is a bug fix you can check this define to alert users
// of your code if it uses better version of this library.
// This also implies everything that SPI_HAS_TRANSACTION as documented above is
// available too.
#define SPI_ATOMIC_VERSION 1

// Uncomment this line to add detection of mismatched begin/end transactions.
// A mismatch occurs if other libraries fail to use SPI.endTransaction() for
// each SPI.beginTransaction().  Connect an LED to this pin.  The LED will turn
// on if any mismatch is ever detected.
//#define SPI_TRANSACTION_MISMATCH_LED 5

#ifndef LSBFIRST
#define LSBFIRST 0
#endif
#ifndef MSBFIRST
#define MSBFIRST 1
#endif

#define SPI_CLOCK_DIV4 0x00
#define SPI_CLOCK_DIV16 0x01
#define SPI_CLOCK_DIV64 0x02
#define SPI_CLOCK_DIV128 0x03
#define SPI_CLOCK_DIV2 0x04
#define SPI_CLOCK_DIV8 0x05
#define SPI_CLOCK_DIV32 0x06

#define SPI_MODE0 0x00
#define SPI_MODE1 0x04
#define SPI_MODE2 0x08
#define SPI_MODE3 0x0C

#define SPI_MODE_MASK 0x0C  // CPOL = bit 3, CPHA = bit 2 on SPCR
#define SPI_CLOCK_MASK 0x03  // SPR1 = bit 1, SPR0 = bit 0 on SPCR
#define SPI_2XCLOCK_MASK 0x01  // SPI2X = bit 0 on SPSR

// define SPI_AVR_EIMSK for AVR boards with external interrupt pins
#if defined(EIMSK)
  #define SPI_AVR_EIMSK  EIMSK
#elif defined(GICR)
  #define SPI_AVR_EIMSK  GICR
#elif defined(GIMSK)
  #define SPI_AVR_EIMSK  GIMSK
#endif

class SPISettings {
public:
  SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) {
    if (__builtin_constant_p(clock)) {
      init_AlwaysInline(clock, bitOrder, dataMode);
    } else {
      init_MightInline(clock, bitOrder, dataMode);
    }
  }
  SPISettings() {
    init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0);
  }
private:
  void init_MightInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) {
    init_AlwaysInline(clock, bitOrder, dataMode);
  }
  void init_AlwaysInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode)
    __attribute__((__always_inline__)) {
    // Clock settings are defined as follows. Note that this shows SPI2X
    // inverted, so the bits form increasing numbers. Also note that
    // fosc/64 appears twice
    // SPR1 SPR0 ~SPI2X Freq
    //   0    0     0   fosc/2
    //   0    0     1   fosc/4
    //   0    1     0   fosc/8
    //   0    1     1   fosc/16
    //   1    0     0   fosc/32
    //   1    0     1   fosc/64
    //   1    1     0   fosc/64
    //   1    1     1   fosc/128

    // We find the fastest clock that is less than or equal to the
    // given clock rate. The clock divider that results in clock_setting
    // is 2 ^^ (clock_div + 1). If nothing is slow enough, we'll use the
    // slowest (128 == 2 ^^ 7, so clock_div = 6).
    uint8_t clockDiv;

    // When the clock is known at compiletime, use this if-then-else
    // cascade, which the compiler knows how to completely optimize
    // away. When clock is not known, use a loop instead, which generates
    // shorter code.
    if (__builtin_constant_p(clock)) {
      if (clock >= F_CPU / 2) {
        clockDiv = 0;
      } else if (clock >= F_CPU / 4) {
        clockDiv = 1;
      } else if (clock >= F_CPU / 8) {
        clockDiv = 2;
      } else if (clock >= F_CPU / 16) {
        clockDiv = 3;
      } else if (clock >= F_CPU / 32) {
        clockDiv = 4;
      } else if (clock >= F_CPU / 64) {
        clockDiv = 5;
      } else {
        clockDiv = 6;
      }
    } else {
      uint32_t clockSetting = F_CPU / 2;
      clockDiv = 0;
      while (clockDiv < 6 && clock < clockSetting) {
        clockSetting /= 2;
        clockDiv++;
      }
    }

    // Compensate for the duplicate fosc/64
    if (clockDiv == 6)
    clockDiv = 7;

    // Invert the SPI2X bit
    clockDiv ^= 0x1;

    // Pack into the SPISettings class
    spcr = _BV(SPE) | _BV(MSTR) | ((bitOrder == LSBFIRST) ? _BV(DORD) : 0) |
      (dataMode & SPI_MODE_MASK) | ((clockDiv >> 1) & SPI_CLOCK_MASK);
    spsr = clockDiv & SPI_2XCLOCK_MASK;
  }
  uint8_t spcr;
  uint8_t spsr;
  friend class SPIClass;
};


class SPIClass {
public:
  // Initialize the SPI library
  static void begin();

  // If SPI is used from within an interrupt, this function registers
  // that interrupt with the SPI library, so beginTransaction() can
  // prevent conflicts.  The input interruptNumber is the number used
  // with attachInterrupt.  If SPI is used from a different interrupt
  // (eg, a timer), interruptNumber should be 255.
  static void usingInterrupt(uint8_t interruptNumber);
  // And this does the opposite.
  static void notUsingInterrupt(uint8_t interruptNumber);
  // Note: the usingInterrupt and notUsingInterrupt functions should
  // not to be called from ISR context or inside a transaction.
  // For details see:
  // https://github.com/arduino/Arduino/pull/2381
  // https://github.com/arduino/Arduino/pull/2449

  // Before using SPI.transfer() or asserting chip select pins,
  // this function is used to gain exclusive access to the SPI bus
  // and configure the correct settings.
  inline static void beginTransaction(SPISettings settings) {
    if (interruptMode > 0) {
      uint8_t sreg = SREG;
      noInterrupts();

      #ifdef SPI_AVR_EIMSK
      if (interruptMode == 1) {
        interruptSave = SPI_AVR_EIMSK;
        SPI_AVR_EIMSK &= ~interruptMask;
        SREG = sreg;
      } else
      #endif
      {
        interruptSave = sreg;
      }
    }

    #ifdef SPI_TRANSACTION_MISMATCH_LED
    if (inTransactionFlag) {
      pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT);
      digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH);
    }
    inTransactionFlag = 1;
    #endif

    SPCR = settings.spcr;
    SPSR = settings.spsr;
  }

  // Write to the SPI bus (MOSI pin) and also receive (MISO pin)
  inline static uint8_t transfer(uint8_t data) {
    SPDR = data;
    /*
     * The following NOP introduces a small delay that can prevent the wait
     * loop form iterating when running at the maximum speed. This gives
     * about 10% more speed, even if it seems counter-intuitive. At lower
     * speeds it is unnoticed.
     */
    asm volatile("nop");
    while (!(SPSR & _BV(SPIF))) ; // wait
    return SPDR;
  }
  inline static uint16_t transfer16(uint16_t data) {
    union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } in, out;
    in.val = data;
    if (!(SPCR & _BV(DORD))) {
      SPDR = in.msb;
      asm volatile("nop"); // See transfer(uint8_t) function
      while (!(SPSR & _BV(SPIF))) ;
      out.msb = SPDR;
      SPDR = in.lsb;
      asm volatile("nop");
      while (!(SPSR & _BV(SPIF))) ;
      out.lsb = SPDR;
    } else {
      SPDR = in.lsb;
      asm volatile("nop");
      while (!(SPSR & _BV(SPIF))) ;
      out.lsb = SPDR;
      SPDR = in.msb;
      asm volatile("nop");
      while (!(SPSR & _BV(SPIF))) ;
      out.msb = SPDR;
    }
    return out.val;
  }
  inline static void transfer(void *buf, size_t count) {
    if (count == 0) return;
    uint8_t *p = (uint8_t *)buf;
    SPDR = *p;
    while (--count > 0) {
      uint8_t out = *(p + 1);
      while (!(SPSR & _BV(SPIF))) ;
      uint8_t in = SPDR;
      SPDR = out;
      *p++ = in;
    }
    while (!(SPSR & _BV(SPIF))) ;
    *p = SPDR;
  }
  // After performing a group of transfers and releasing the chip select
  // signal, this function allows others to access the SPI bus
  inline static void endTransaction(void) {
    #ifdef SPI_TRANSACTION_MISMATCH_LED
    if (!inTransactionFlag) {
      pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT);
      digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH);
    }
    inTransactionFlag = 0;
    #endif

    if (interruptMode > 0) {
      #ifdef SPI_AVR_EIMSK
      uint8_t sreg = SREG;
      #endif
      noInterrupts();
      #ifdef SPI_AVR_EIMSK
      if (interruptMode == 1) {
        SPI_AVR_EIMSK = interruptSave;
        SREG = sreg;
      } else
      #endif
      {
        SREG = interruptSave;
      }
    }
  }

  // Disable the SPI bus
  static void end();

  // This function is deprecated.  New applications should use
  // beginTransaction() to configure SPI settings.
  inline static void setBitOrder(uint8_t bitOrder) {
    if (bitOrder == LSBFIRST) SPCR |= _BV(DORD);
    else SPCR &= ~(_BV(DORD));
  }
  // This function is deprecated.  New applications should use
  // beginTransaction() to configure SPI settings.
  inline static void setDataMode(uint8_t dataMode) {
    SPCR = (SPCR & ~SPI_MODE_MASK) | dataMode;
  }
  // This function is deprecated.  New applications should use
  // beginTransaction() to configure SPI settings.
  inline static void setClockDivider(uint8_t clockDiv) {
    SPCR = (SPCR & ~SPI_CLOCK_MASK) | (clockDiv & SPI_CLOCK_MASK);
    SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((clockDiv >> 2) & SPI_2XCLOCK_MASK);
  }
  // These undocumented functions should not be used.  SPI.transfer()
  // polls the hardware flag which is automatically cleared as the
  // AVR responds to SPI's interrupt
  inline static void attachInterrupt() { SPCR |= _BV(SPIE); }
  inline static void detachInterrupt() { SPCR &= ~_BV(SPIE); }

private:
  static uint8_t initialized;
  static uint8_t interruptMode; // 0=none, 1=mask, 2=global
  static uint8_t interruptMask; // which interrupts to mask
  static uint8_t interruptSave; // temp storage, to restore state
  #ifdef SPI_TRANSACTION_MISMATCH_LED
  static uint8_t inTransactionFlag;
  #endif
};

extern SPIClass SPI;

#endif

here nowhere the pins ss , SCK , MOSI are defined above header file

the function definition of begin() is

void SPIClass::begin()
{
  uint8_t sreg = SREG;
  noInterrupts(); // Protect from a scheduler and prevent transactionBegin
  if (!initialized) {
    // Set SS to high so a connected chip will be "deselected" by default
    uint8_t port = digitalPinToPort(SS);
    uint8_t bit = digitalPinToBitMask(SS);
    volatile uint8_t *reg = portModeRegister(port);

    // if the SS pin is not already configured as an output
    // then set it high (to enable the internal pull-up resistor)
    if(!(*reg & bit)){
      digitalWrite(SS, HIGH);
    }

    // When the SS pin is set as OUTPUT, it can be used as
    // a general purpose output port (it doesn't influence
    // SPI operations).
    pinMode(SS, OUTPUT);

    // Warning: if the SS pin ever becomes a LOW INPUT then SPI
    // automatically switches to Slave, so the data direction of
    // the SS pin MUST be kept as OUTPUT.
    SPCR |= _BV(MSTR);
    SPCR |= _BV(SPE);

    // Set direction register for SCK and MOSI pin.
    // MISO pin automatically overrides to INPUT.
    // By doing this AFTER enabling SPI, we avoid accidentally
    // clocking in a single bit since the lines go directly
    // from "input" to SPI control.
    // http://code.google.com/p/arduino/issues/detail?id=888
    pinMode(SCK, OUTPUT);
    pinMode(MOSI, OUTPUT);
  }
  initialized++; // reference count
  SREG = sreg;
}

here as i mentioned above the pins of ss , SCK , MOSI are not defined.
now, if i consider that the pins used are default the if i want to use 3 slaves then how to use three chip select pins?
how in the code with out mentioning pin numbers the code is using

The SPI (SCK, MOSI, MISO) pins on e.g. an 328P (Uno, Nano, ProMini) / 2560 (Mega) are fixed by the processor's hardware; there is no need to define them.

Other processors have options to route the internal SPI hardware to different pins.

When you enable the Library for a SPI device, say LoRa or SD or TFT display, the constructor for that library will accept a definition for the devices select.

The SPI library will use the default hardware SPI pins for SCK, MOSI, MISO. On a lot of Arduinos these are fixed by the hardware and cannot be changed, so no need to specify them.

CS pins has nothing to do with hardware defined SS pin.
You should define the CS pin for each SPI slave in the code and It is your responsibility to ensure that these pins are switched correctly.
The SPI library itself does not know anything about the fact that it has many slaves; it always works with only one. You switch CS pins in the code and thereby control which slave will respond to the master’s requests.
If you work with a SPI device through a library, the CS pin switching usually performs by the library.

bro in my last topic i tagged you but i did not get any reply from you. so i thought i need to start a new topic so i can get answers.

i am using rep-rap display and lora both work on spi.
now i have two chip select pins but always my lora is not getting initialised i do not know how.
moreover in the SPI.begin() function if i have 2 chip select pins how it will work because in the above code SPI.h inside begin function it is mention only ss pin.

the SPI.begin() function has nothing to do with CS pins. You should pass a CS pin to the SPI slave device library, i e to the Lora and display

i also tagged you in the topic HOW USE 2 SPI'S AT A TIME.
you can get my full code and problem over there

yes i did that but always lora is not getting initialized.

hi guys i am using REP-RAP display with esp32.

REP RAP DISPLAY


this display will work on SPI protocol.
this display has a knob. i do not know how it works.

now this REP-RAP board is connect to ESP32.
this ESP32 is also connected to LORA which also works on SPI.

now my problem is LORA module is not getting initialize .

i do not know why???

the code is :slight_smile:



#include <Arduino.h>
#include <SPI.h>
#include <menu.h>
#include <menuIO/u8g2Out.h>
#include <menuIO/encoderIn.h>
#include <menuIO/chainStream.h>
#include <menuIO/serialOut.h>
#include <menuIO/serialIn.h>
#include <menuIO/U8GLibOut.h>
#include <ClickEncoder.h>
#include <menuIO/clickEncoderIn.h>
#include <EEPROM.h>

/*==============================================
  Declrations:Rotary Encoder pins
  ==============================================*/
#define encA    14
#define encB    15
#define encBtn  25
hw_timer_t * timer = NULL;
ClickEncoder clickEncoder(encA, encB, encBtn, 2);
ClickEncoderStream encStream(clickEncoder, 1);
MENU_INPUTS(in, &encStream);
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
void IRAM_ATTR onTimer() {
  portENTER_CRITICAL_ISR(&timerMux);
  clickEncoder.service();
  portEXIT_CRITICAL_ISR(&timerMux);
}

/*==============================================
  Declrations: Display Configuration
  ==============================================*/
#define USE_SWSPI
#define fontName  u8g2_font_5x7_tf
#define offsetX 0
#define offsetY 0
#define U8_Width 128
#define U8_Height 64
int x = 0;
int scroll_direction = 1;
U8G2_ST7920_128X64_F_SW_SPI u8g2(U8G2_R0, /* clock=*/ 18 /* A4 */ , /* data=*/ 23 /* A2 */, /* CS=*/ 5 /* A3 */, /* reset=*/ U8X8_PIN_NONE);
const colorDef<uint8_t> colors[6] MEMMODE = {
  {{0, 0}, {0, 1, 1}}, //bgColor
  {{1, 1}, {1, 0, 0}}, //fgColor
  {{1, 1}, {1, 0, 0}}, //valColor
  {{1, 1}, {1, 0, 0}}, //unitColor
  {{0, 1}, {0, 0, 1}}, //cursorColor
  {{1, 1}, {1, 0, 0}}, //titleColor
};

#define display_ss 5

//******************LORA PINS

#include <LoRa.h>

#define ss 4
#define rst 12
#define dio0 13
int counter=0;
void setup() 
{
  Serial.begin(115200);
  pinMode(display_ss, OUTPUT);
  pinMode(ss, OUTPUT);
  SPI.begin(18,19,23,5);
  u8g2.begin();
  //pinMode(encBtn, INPUT_PULLUP);
  x = x + scroll_direction;
  if (x > 40) scroll_direction = -1;
  if (x < 1) scroll_direction = 1;
  u8g2.setFont(fontName);
  nav.idleTask = idle;
  digitalWrite(display_ss,HIGH);
  digitalWrite(ss,LOW);
  
  Serial.println("WELCOME TO LORA TESTING");
  SPI.begin(18,19,23,ss);
  LoRa.setPins(ss, rst, dio0);
  while (!LoRa.begin(433E6)) 
  {
    Serial.println("Starting LoRa failed!");
    delay(1000);
  }
  Serial.println("LORA CONNECTED");
  digitalWrite(display_ss,LOW);
  digitalWrite(ss,HIGH);
  
}

void loop() 
{
  Encoderrun();
  delay(1000);
  sendMessage();

}

i do not understand what to do?
@UKHeliBob , @sterretje , @srnet , @b707

Then your doing something wrong, or one of the SPI devices on the bus is not able to correctly share the SPI bus with other devices..........

This is how I would setup a LoRa device and an SD card on same spi bus;

SPI.begin();
LoRa.begin(NSS, NRESET, DIO0, LORA_DEVICE);
SD.begin(SDCS);

And it works, no select pins passed to the SPI library .......

Start with the basic LoRa sender sketch, make sure it works, then start adding stuff to see when it fails.

There could be a hardware issue here, so searching through a long pile of code for an 'error' may not identify the problem. If a device does not share the SPI bus properly then you wont be able to tell that from looking at the code.

above i posted my code once have a look please.

In the last thread you insisted that you definitely need two separate SPI, although several users explained to you that there is no need for this. Finally I answered you how to rise a second SPI on the ESP... but now you asked how to connect a two SPI slaves to the single SPI.

Does this mean that I wasted my time on my answer to you?

1 Like

i also seen the link (some randon like that) i also copied the code from then and tried to implement it but i do not have enough pins and also i made a notes and kept with me b707.
that day i learned a lot from you. do not feel sad

you can't initialize SPI twice.

From your code I see that you absolutely do not understand how SPI works. And that’s why you insisted on using two SPI buses in the last thread...

Maybe you should start by reading some article about the spi interface and only then ask questions?

i did many trails like only declaring just single SPI.begin() and so on but no results

#include <Arduino.h>
#include <SPI.h>
#include <menu.h>
#include <menuIO/u8g2Out.h>
#include <menuIO/encoderIn.h>
#include <menuIO/chainStream.h>
#include <menuIO/serialOut.h>
#include <menuIO/serialIn.h>
#include <menuIO/U8GLibOut.h>
#include <ClickEncoder.h>
#include <menuIO/clickEncoderIn.h>
#include <EEPROM.h>
#include <SPIFFS.h>
#include <ArduinoJson.h>


char  SSerial[40];
char  SSerialSet[40]="ehstartcheybae";
String Mymessage = "";
String SenderNode = "";
String outgoing;
byte msgCount = 0;
String incoming = "";
int Nvalue, Pvalue , Kvalue;
float SMvalue, STvalue, PHvalue, ECvalue;
float ATemp, Ahum, Avpd, Aet, Abp, Asl, Adp;
/*==============================================
  Declrations : EEPROM
  ==============================================*/

int Ontimehr ;
int offtimehr;
int Ontimemin ;
int offtimemin;
int Slot1hr ;
int Slot1min;
int Slot1hroff ;
int Slot1minoff;
int Slot2hr ;
int Slot2min;
long ontime;
long offtime;
int Eepromhur1 = 10;
int Eeprommin1 = 20;
int Eepromhur2 = 30;
int Eeprommin2 = 40;
int Eepromhur1sl1 = 50;
int Eeprommin1sl1 = 60;
int Eepromhur2sl2 = 70;
int Eeprommin2sl2 = 80;
int Eepromhur1sl1off = 90;
int Eeprommin1sl1off = 100;
/*==============================================
  Declrations : BOOL
  ==============================================*/
bool Pumpstate;
bool Fertigationstate;
bool zonE11;
bool zonE22;
bool zonE33;
bool format = HIGH;
bool format1 = HIGH;
bool format2 = HIGH;
bool format3 = HIGH;
bool Schedulesstate;
bool Schedulesstate2;
bool Slot1z1;
bool Slot1z2;
bool Slot1z3;
bool Slot2z1;
bool  Slot2z2;
bool Slot2z3;
int Secs = 0;
/*==============================================
  Declrations : RELAY
  ==============================================*/
#define MainPumpA  33
#define FertSolenoid  32
#define ZonE1 35
#define ZonE2 22
/*==============================================
  Declrations:Rotary Encoder pins
  ==============================================*/
#define encA    14
#define encB    15
#define encBtn  25
hw_timer_t * timer = NULL;
ClickEncoder clickEncoder(encA, encB, encBtn, 2);
ClickEncoderStream encStream(clickEncoder, 1);
MENU_INPUTS(in, &encStream);
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
void IRAM_ATTR onTimer() {
  portENTER_CRITICAL_ISR(&timerMux);
  clickEncoder.service();
  portEXIT_CRITICAL_ISR(&timerMux);
}

/*==============================================
  Declrations: Display Configuration
  ==============================================*/
#define USE_SWSPI
#define fontName  u8g2_font_5x7_tf
#define offsetX 0
#define offsetY 0
#define U8_Width 128
#define U8_Height 64
int x = 0;
int scroll_direction = 1;
U8G2_ST7920_128X64_F_SW_SPI u8g2(U8G2_R0, /* clock=*/ 18 /* A4 */ , /* data=*/ 23 /* A2 */, /* CS=*/ 5 /* A3 */, /* reset=*/ U8X8_PIN_NONE);
const colorDef<uint8_t> colors[6] MEMMODE = {
  {{0, 0}, {0, 1, 1}}, //bgColor
  {{1, 1}, {1, 0, 0}}, //fgColor
  {{1, 1}, {1, 0, 0}}, //valColor
  {{1, 1}, {1, 0, 0}}, //unitColor
  {{0, 1}, {0, 0, 1}}, //cursorColor
  {{1, 1}, {1, 0, 0}}, //titleColor
};
result doAlert(eventMask e, prompt &item);
result showEvent(eventMask e, navNode& nav, prompt& item) {
  Serial.print("event: ");
  Serial.println(e);
  return proceed;
}
/*==============================================
  SubMenu-Section
  ==============================================*/

//*****************Manual Mode toggle//*****************

TOGGLE(Pumpstate, MainPump, "Mainpump", doNothing, noEvent, noStyle //,doExit,enterEvent,noStyle
       , VALUE(":ON", HIGH, doNothing, noEvent)
       , VALUE(":OFF", LOW, doNothing, noEvent)
      );

TOGGLE(Fertigationstate, Fertigation, "Fertigation", doNothing, noEvent, noStyle //,doExit,enterEvent,noStyle
       , VALUE(":ON", HIGH, doNothing, noEvent)
       , VALUE(":OFF", LOW, doNothing, noEvent)
      );
TOGGLE(zonE11, zonE1, "Zone1", doNothing, noEvent, noStyle //,doExit,enterEvent,noStyle
       , VALUE(":ON", HIGH, doNothing, noEvent)
       , VALUE(":OFF", LOW, doNothing, noEvent)
      );
TOGGLE(zonE22, zonE2, "Zone2", doNothing, noEvent, noStyle //,doExit,enterEvent,noStyle
       , VALUE(":ON", HIGH, doNothing, noEvent)
       , VALUE(":OFF", LOW, doNothing, noEvent)
      );

TOGGLE(zonE33, zonE3, "Zone3", doNothing, noEvent, noStyle //,doExit,enterEvent,noStyle
       , VALUE(":ON", HIGH, doNothing, noEvent)
       , VALUE(":OFF", LOW, doNothing, noEvent)
      );


MENU(Manual,       "->MANUAL", showEvent, anyEvent, noStyle
     , SUBMENU(MainPump)
     , SUBMENU(Fertigation)
     , SUBMENU(zonE1)
     , SUBMENU(zonE2)
     , SUBMENU(zonE3)
     , EXIT("<Back")
    );
//*****************Schedule-Section//*****************
TOGGLE(Slot1z1, slz1, "Zone1", doNothing, noEvent, noStyle //,doExit,enterEvent,noStyle
       , VALUE(":ON", HIGH, doNothing, noEvent)
       , VALUE(":OFF", LOW, doNothing, noEvent)
      );
TOGGLE(Slot1z2, slz2, "Zone2", doNothing, noEvent, noStyle //,doExit,enterEvent,noStyle
       , VALUE(":ON", HIGH, doNothing, noEvent)
       , VALUE(":OFF", LOW, doNothing, noEvent)
      );

TOGGLE(Slot1z3, slz3, "Zone3", doNothing, noEvent, noStyle //,doExit,enterEvent,noStyle
       , VALUE(":ON", HIGH, doNothing, noEvent)
       , VALUE(":OFF", LOW, doNothing, noEvent)
      );

//*****************Schedule-Sectionzone2//*****************
TOGGLE(Slot2z1, sl2z1, "Zone1", doNothing, noEvent, noStyle //,doExit,enterEvent,noStyle
       , VALUE(":ON", HIGH, doNothing, noEvent)
       , VALUE(":OFF", LOW, doNothing, noEvent)
      );
TOGGLE(Slot2z2, sl2z2, "Zone2", doNothing, noEvent, noStyle //,doExit,enterEvent,noStyle
       , VALUE(":ON", HIGH, doNothing, noEvent)
       , VALUE(":OFF", LOW, doNothing, noEvent)
      );

TOGGLE(Slot2z3, sl2z3, "Zone3", doNothing, noEvent, noStyle //,doExit,enterEvent,noStyle
       , VALUE(":ON", HIGH, doNothing, noEvent)
       , VALUE(":OFF", LOW, doNothing, noEvent)
      );
//*****************Schedule//*****************
TOGGLE(Schedulesstate, State, "       ", doNothing, noEvent, noStyle //,doExit,enterEvent,noStyle
       , VALUE(" <State: ON>   ", HIGH, doNothing, noEvent)
       , VALUE(" <State: OFF>  ", LOW, doNothing, noEvent)
      );
TOGGLE(Schedulesstate2, State2, "       ", doNothing, noEvent, noStyle //,doExit,enterEvent,noStyle
       , VALUE(" <State: ON>   ", HIGH, doNothing, noEvent)
       , VALUE(" <State: OFF>  ", LOW, doNothing, noEvent)
      );
TOGGLE(format1, Format1, "", doNothing, noEvent, noStyle //,doExit,enterEvent,noStyle
       , VALUE("                  AM", HIGH, doNothing, noEvent)
       , VALUE("                  PM", LOW, savetimepm1, enterEvent)
      );
TOGGLE(format, Format, "", doNothing, noEvent, noStyle //,doExit,enterEvent,noStyle
       , VALUE("                  AM", HIGH, doNothing, noEvent)
       , VALUE("                  PM", LOW, savetimepm, enterEvent)
      );
TOGGLE(format2, Format2, "", doNothing, noEvent, noStyle //,doExit,enterEvent,noStyle
       , VALUE("                  AM", HIGH, doNothing, noEvent)
       , VALUE("                  PM", LOW, savetime2pm, enterEvent)
      );
TOGGLE(format3, Format3, "", doNothing, noEvent, noStyle //,doExit,enterEvent,noStyle
       , VALUE("                  AM", HIGH, doNothing, noEvent)
       , VALUE("                  PM", LOW, savetime3pm, enterEvent)
      );
MENU(Slot1,         "         Slot1", showEvent, anyEvent, noStyle
     , FIELD(Slot1hr,     " OnHr    ->  ", "", 0, 12, 01, 0, saveonTIMEHRslot1, enterEvent, wrapStyle)
     , FIELD(Slot1min,    " OnMin   ->  ", "", 0, 59, 10, 1, saveonTIMEMINslot1, enterEvent, wrapStyle)
     , SUBMENU(Format)
     , FIELD(Slot1hroff,  " OffHr   ->  ", "", 0, 12, 01, 0, saveonTIMEHRslot1off, enterEvent, wrapStyle)
     , FIELD(Slot1minoff, " OffMin  ->  ", "", 0, 59, 10, 1, saveonTIMEMINslot1off, enterEvent, wrapStyle)
     , SUBMENU(Format1)
     , SUBMENU(slz1)
     , SUBMENU(slz2)
     , SUBMENU(slz3)
     , OP(         "         <Save>", Readsl1, enterEvent)
     , SUBMENU(State)
     , EXIT("<Back")
    );
MENU(Slot2,         "         Slot2", showEvent, anyEvent, noStyle
     , FIELD(Ontimehr,   " OnHr     ->  ", "", 0, 12, 01, 0, saveonTIMEHR, enterEvent, wrapStyle)
     , FIELD(Ontimemin,  " OnMin    ->  ", "", 0, 59, 10, 1, saveonTIMEMIN, enterEvent, wrapStyle)
     , SUBMENU(Format2)
     , FIELD(offtimehr,  " OffHr    ->  ", "", 0, 12, 01, 0, saveoffTIMEHR, enterEvent, wrapStyle)
     , FIELD(offtimemin, " OffMin   ->  ", "", 0, 59, 10, 1, saveoffTIMEMIN, enterEvent, wrapStyle)
     , SUBMENU(Format3)
     , SUBMENU(sl2z1)
     , SUBMENU(sl2z2)
     , SUBMENU(sl2z3)
     , OP(          "         <Save>", Readd, enterEvent)
     , SUBMENU(State2)
     , EXIT("<Back")
    );
MENU(Schedule,      "->SCHEDULE", showEvent, anyEvent, noStyle
     , SUBMENU(Slot1)
     , SUBMENU(Slot2)
     , EXIT("<Back")
    );
/*==============================================
  Sensor Section
  ==============================================*/
MENU(SensorMenu, "->MINDERS", doNothing, noEvent, wrapStyle
     , OP(         "       SoilMinder", Soilminder, enterEvent)
     , OP(         "      WeatherMinder", WeatherMinder, enterEvent)
     , EXIT("<Exit")
    );
/*==============================================
  EEPROM Section
  ==============================================*/

result saveonTIMEHRslot1()
{
  EEPROM.write(Eepromhur1sl1, Slot1hr);
  return proceed;
}
result saveonTIMEMINslot1()
{
  EEPROM.write(Eeprommin1sl1, Slot1min);
  return proceed;
}
result saveonTIMEHRslot1off()
{
  EEPROM.write(Eepromhur1sl1off, Slot1hroff);
  return proceed;
}
result saveonTIMEMINslot1off()
{
  EEPROM.write(Eeprommin1sl1off, Slot1minoff);
  return proceed;
}

result saveonTIMEHR()
{
  EEPROM.write(Eepromhur1, Ontimehr);
  return proceed;
}
result saveonTIMEMIN()
{
  EEPROM.write(Eeprommin1, Ontimemin);
  return proceed;
}
result saveoffTIMEHR()
{
  EEPROM.write(Eepromhur2, offtimehr);
  return proceed;
}
result saveoffTIMEMIN()
{
  EEPROM.write(Eeprommin2, offtimemin);
  return proceed;
}
result Readd()
{
  Ontimehr = EEPROM.read(Eepromhur1);
  Ontimemin = EEPROM.read(Eeprommin1);
  offtimehr = EEPROM.read(Eepromhur2);
  offtimemin = EEPROM.read(Eeprommin2);
  return proceed;
}
result Readsl1()
{
  Slot1hr = EEPROM.read(Eepromhur1sl1);
  Slot1min = EEPROM.read(Eeprommin1sl1);
  Slot1hroff = EEPROM.read(Eepromhur1sl1off);
  Slot1minoff = EEPROM.read(Eeprommin1sl1off);
  return proceed;
}
result savetimepm()
{
  if (Slot1hr < 12)
  {
    Slot1hr = Slot1hr + 12;
    Serial.println(Slot1hr);
    EEPROM.write(Eepromhur1sl1, Slot1hr);
  }
  return proceed;

}
result savetimepm1()
{
  if (Slot1hroff < 12)
  {
    Slot1hroff = Slot1hroff + 12;
    Serial.println(Slot1hroff);
    EEPROM.write(Eepromhur1sl1off, Slot1hroff);
  }
  return proceed;
}
result savetime2pm()
{
  if (Ontimehr < 12)
  {
    Ontimehr = Ontimehr + 12;
    Serial.println(Ontimehr);
    EEPROM.write(Eepromhur1, Ontimehr);
  }
  return proceed;
}
result savetime3pm()
{
  if (offtimehr < 12)
  {
    offtimehr = offtimehr + 12;
    Serial.println(offtimehr);
    EEPROM.write(Eepromhur2, offtimehr);
  }
  return proceed;
}
/*==============================================
  MAIN-Menu Section
  ==============================================*/
MENU(mainMenu,     "          MENU", doNothing, noEvent, wrapStyle
     , SUBMENU(SensorMenu)
     , SUBMENU(Manual)
     , SUBMENU(Schedule)
     , EXIT("<Exit")
    );
/*==============================================
  Declrations: Display Configuration
  ==============================================*/
#define MAX_DEPTH 2
serialIn serial(Serial);
#define fontX 3
#define fontY 10
#define MAX_DEPTH 10
MENU_OUTPUTS(out, MAX_DEPTH

             , U8G2_OUT(u8g2, colors, fontX, fontY, offsetX, offsetY, {0, 0, U8_Width / fontX, U8_Height / fontY})
             , SERIAL_OUT(Serial)
             , NONE
            );

NAVROOT(nav, mainMenu, MAX_DEPTH, in, out);
result alert(menuOut& o, idleEvent e) {
  if (e == idling) {
    o.setCursor(0, 0);
    o.print("alert test");
    o.setCursor(0, 1);
    o.print("press [select]");
    o.setCursor(0, 2);
    o.print("to continue...");
  }
  return proceed;
}
result doAlert(eventMask e, prompt &item) {
  nav.idleOn(alert);
  return proceed;
}
result Soilminder(eventMask e,  prompt& item)
{
  nav.idleOn(SoilInfo);
  return proceed;
}
result WeatherMinder(eventMask e,  prompt& item)
{
  nav.idleOn(SoilInfo1);
  return proceed;
}

/*==============================================
  Sensor Value display
  ==============================================*/

result SoilInfo(menuOut& o, idleEvent e)  {
  if (e == idling) {
    u8g2.drawFrame(0, 0, 128, 64);
    u8g2.drawFrame(0, 0, 128, 53);
    u8g2.drawFrame(0, 0, 128, 43);
    u8g2.drawFrame(0, 0, 128, 33);
    u8g2.drawFrame(0, 0, 128, 23);
    u8g2.drawFrame(0, 0, 128, 13);
    u8g2.drawFrame(64, 12, 128, 64);
    u8g2.drawStr(20, 10, "FERTIGATION MINDER");
    u8g2.setCursor(3, 21);
    u8g2.print("SM :");
    u8g2.print(SMvalue);
    u8g2.setCursor(3, 31);
    u8g2.print("N  :");
    u8g2.print(Nvalue);
    u8g2.setCursor(3, 41);
    u8g2.print("P  :");
    u8g2.print(Pvalue);
    u8g2.setCursor(3, 51);
    u8g2.print("K  :");
    u8g2.print(Kvalue);
    u8g2.setCursor(66, 21);

    u8g2.print("ST :");
    u8g2.print(STvalue);
    u8g2.setCursor(66, 31);
    u8g2.print("PH :");
    u8g2.print(PHvalue);
    u8g2.setCursor(66, 41);
    u8g2.print("EC :");
    u8g2.print(ECvalue);
    u8g2.setCursor(66, 51);
    u8g2.print("ET :");
    u8g2.print(SMvalue);
    u8g2.setCursor(3, 61);
    u8g2.print("ALERTS:");
    u8g2.print("None");
    u8g2.setCursor(66, 61);
    u8g2.print("EVENTS:");
    u8g2.print("None");
  }
  return proceed;

}


result SoilInfo1(menuOut& o, idleEvent e)  {
  {
    u8g2.drawFrame(0, 0, 128, 64);
    u8g2.drawFrame(0, 0, 128, 53);
    u8g2.drawFrame(0, 0, 128, 43);
    u8g2.drawFrame(0, 0, 128, 33);
    u8g2.drawFrame(0, 0, 128, 23);
    u8g2.drawFrame(0, 0, 128, 13);
    u8g2.drawFrame(64, 12, 128, 64);
    u8g2.drawStr(20, 10, "FERTIGATION MINDER");
    u8g2.setCursor(3, 21);
    u8g2.print("WD :");
    u8g2.print(SMvalue);
    u8g2.setCursor(3, 31);
    u8g2.print("WS  :");
    u8g2.print(SMvalue);
    u8g2.setCursor(3, 41);
    u8g2.print("RP  :");
    u8g2.print(SMvalue);
    u8g2.setCursor(3, 51);
    u8g2.print("SR  :");
    u8g2.print(SMvalue);
    u8g2.setCursor(66, 21);
    u8g2.print("DP :");
    u8g2.print(SMvalue);
    u8g2.setCursor(66, 31);
    u8g2.print("BP :");
    u8g2.print(SMvalue);
    u8g2.setCursor(66, 41);
    u8g2.print("HI :");
    u8g2.print(SMvalue);
    u8g2.setCursor(66, 51);
    u8g2.print("VP :");
    u8g2.print(SMvalue);
    u8g2.setCursor(3, 61);
    u8g2.print("ALERTS:");
    u8g2.print("None");
    u8g2.setCursor(66, 61);
    u8g2.print("EVENTS:");
    u8g2.print("None");

  }
}

result idle(menuOut& o, idleEvent e) {
  o.clear();
  switch (e) {
    case idleStart: o.println("suspending menu!"); break;
    case idling: o.println("suspended..."); break;
    case idleEnd: o.println("resuming menu."); break;
  }
  return proceed;
}
/*==============================================
  ManualMode Relay Section
  ==============================================*/
void Manualrun()
{

  if ((Schedulesstate == LOW) && (Schedulesstate2 == LOW))
  {

    if (Pumpstate == HIGH)
    {
      pinMode(MainPumpA, OUTPUT);
      digitalWrite( MainPumpA, LOW);
    }
    if (Pumpstate == LOW)
    {
      pinMode(MainPumpA, OUTPUT);
      digitalWrite( MainPumpA, HIGH);
    }

    if ( Fertigationstate ==  HIGH)
    {
      pinMode(FertSolenoid, OUTPUT);
      digitalWrite( FertSolenoid, LOW);
    }
    if ( Fertigationstate ==  LOW)
    {
      pinMode(FertSolenoid, OUTPUT);
      digitalWrite( FertSolenoid, HIGH);
    }
    if (zonE11 == HIGH)
    {
      pinMode(ZonE1, OUTPUT);
      digitalWrite( ZonE1, LOW);
    }
    if (zonE11 == LOW)
    {
      pinMode(ZonE1, OUTPUT);
      digitalWrite( ZonE1, HIGH);
    }
    if (zonE22 == HIGH)
    {
      pinMode(ZonE2, OUTPUT);
      digitalWrite( ZonE2, LOW);
    }
    if (zonE22 == LOW)
    {
      pinMode(ZonE2, OUTPUT);
      digitalWrite( ZonE2, HIGH);
    }
  }

}
/*==============================================
  Encoder Section
  ==============================================*/
void Encoderrun()
{
  x = x + scroll_direction;
  if (x > 40) scroll_direction = -1;
  if (x < 1) scroll_direction = 1;
  nav.doInput();
  Serial.println("INSIDE Encoderrum function");//edited by javid
  if (nav.changed(1)) 
  {
    Serial.println("INSIDE if part");//edited by javid
    u8g2.firstPage();
    do 
    {
      nav.doOutput();
      Serial.println("INSIDE do-while  part");//edited by javid 
    }while (u8g2.nextPage());
    
  }
  delay(500);//simulate other tasks delay

}
#define display_ss 5
//******************LORA PINS

#include <LoRa.h>

#define ss 4
#define rst 12
#define dio0 13
int counter=0;

void setup() 
{
  Serial.begin(115200);
  EEPROM.begin(150);
  pinMode(display_ss, OUTPUT);
  pinMode(ss, OUTPUT);
  //digitalWrite(display_ss,HIGH);
  //digitalWrite(ss,HIGH);
  SPI.begin();
//  u8g2.begin();
//  //pinMode(encBtn, INPUT_PULLUP);
//  x = x + scroll_direction;
//  if (x > 40) scroll_direction = -1;
//  if (x < 1) scroll_direction = 1;
//  u8g2.setFont(fontName);
//  nav.idleTask = idle;
//  Serial.println("setup done.");
//  Serial.flush();
//  pinMode(MainPumpA, OUTPUT);
//  digitalWrite( MainPumpA, HIGH);
//  pinMode(FertSolenoid, OUTPUT);
//  digitalWrite( FertSolenoid, HIGH);
//  pinMode(ZonE1, OUTPUT);
//  digitalWrite( ZonE1, HIGH);
//  pinMode(ZonE2, OUTPUT);
//  digitalWrite( ZonE2, HIGH);
//  Serial.println("FertigationMinder LORA");
//  if(SSerial==SSerialSet)
//  {
//  Serial.begin(115200);  
//  }
  
  //digitalWrite(ss,LOW);//enable lora slave 
  Serial.println("WELCOME TO LORA TESTING");
  LoRa.setPins(ss, rst, dio0);
  while (!LoRa.begin(433E6)) 
  {
    Serial.println("Starting LoRa failed!");
    delay(1000);
  }
  Serial.println("LORA CONNECTED");
  
}

void loop() 
{
  Encoderrun();
  delay(1000);
  sendMessage();
}

Read the explanation in the #4 and example in #10

i am working on it

Your code in #16 look like a chaotic mess of the snippets from the several sketches. Why do you start from such complex project without basic knowledge? Move gradually.

First run examples for Lora, then simple examples for display.
Then start adding other parts.
Try to write code yourself rather than copy someone else's.
If you copy code, you must understand what it does.

no actually it was written by another employee. he resigned then i am working on it