Using SPI with arduino MEGA 2560 to communicate with ENC28J60 and MAX6675

Hi, I am building a smart system for garden care, and I need to measure the temperature with a thermocouple for my temp control system, the problem is that I also need to connect my system to internet, reason why I am using the ENC28J60 module. When I am using those individually, everything works fine but when I try to use both at the same time, the Ethernet module works fine but the MAX6675 says me that the temperature is 0 (IN OTHER WORDS IT DOESNT WORK). Any idea of how to resolve my problem. The other small problem that I have, is that while my module is waiting for the DHCP to assign it an IP, my LCD is not showing any information.

Thank you,

I leave my code here.

//LCD config (i2c LCD screen, you need to install the LiquidCrystal_I2C if you don't have it )
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7);  //sometimes the adress is not 0x3f. Change to 0x27 if it dosn't work.

//LCD config (i2c LCD screen, you need to install the LiquidCrystal_I2C if you don't have it )
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7);  //sometimes the adress is not 0x3f. Change to 0x27 if it dosn't work.

#include <max6675.h>
#include <SPI.h>
//We define the SPI pìns
#define SO_PIN    50
#define CK_PIN    52 
#define CS_PIN_A  25  

MAX6675 thermocouple(CK_PIN, CS_PIN_A, SO_PIN);  // Creacion del objeto MAX6675 para lectura de termocupla

//BLYNK
#define BLYNK_PRINT Serial
#include <UIPEthernet.h>
#include <BlynkSimpleUIPEthernet.h>
char auth[] = "c9d17da1a5ac40bd962d76366322e149";
BlynkTimer timer; // Create a Timer object called "timer"!

//Pins
int PINRELAY = 3;
int PINBOTONMAS = 4;
int PINBOTONMENOS = 9;
int PINSENHUMEDAD = A0;
int PINRELAYLUZ = 5;
int PININTERRUPTOR = 6;
int PINRELAYBOMBA = 7;
int PINSENSORDENIVEL = 8;

//Variables
float temperature_read = 0.0;
int set_temperature = 20;
float PID_error = 0;
float previous_error = 0;
float elapsedTime, Time, timePrev;
int PID_value = 0;
int Valuetouse = 0;
int BotonMenos; 
int BotonMas; 
int ValeurSensorHumedad = 0;
int pourcentageHumedad = 0;
int Interruptorluz;
int Nivel;
int Interruptorcalefaccion;

//PID constants
int kp = 9.1;   int ki = 0.3;   int kd = 1.8;
int PID_p = 0;    int PID_i = 0;    int PID_d = 0;

//BLYNK
BLYNK_WRITE(V0)//Permite leer el valor del virtual PIN 1 en BLYNK
{
  Interruptorluz = param.asInt(); // Asigna los valores que lee del Virtual PIN 1 a una variable
}
BLYNK_WRITE(V1)//Permite leer el valor del virtual PIN 1 en BLYNK
{
  Interruptorcalefaccion = param.asInt(); // Asigna los valores que lee del Virtual PIN 1 a una variable
}
BLYNK_WRITE(V2)//Permite leer el valor del virtual PIN 2 en BLYNK
{
  set_temperature = param.asInt(); // Asigna los valores que lee del Virtual PIN 2 a una variable
}

BLYNK_READ(V3) // Widget in the app READs Virtal Pin V3 with the certain frequency
{
  // This command writes Arduino's uptime in seconds to Virtual Pin V3
  Blynk.virtualWrite(3, set_temperature);
}

BLYNK_READ(V4) // Widget in the app READs Virtal Pin V4 with the certain frequency
{
  // This command writes Arduino's uptime in seconds to Virtual Pin V4
  Blynk.virtualWrite(4, pourcentageHumedad);
}

BLYNK_READ(V9) // Widget in the app READs Virtal Pin V4 with the certain frequency
{
  // This command writes Arduino's uptime in seconds to Virtual Pin V4
  Blynk.virtualWrite(9, temperature_read);
}

WidgetLED led1(V5); //register to virtual pin 5
WidgetLED led2(V6); //register to virtual pin 6

void lednivelaguablynk(){
  if (Nivel==1){
    led1.off();
  }
  else{
    led1.on();
  }
}

void ledpumpstateblynk(){
  if (pourcentageHumedad <= 60 or Nivel !=1) {
    led2.on();
  }
  else {
    led2.off();
  }
}

void setup() {
  pinMode(PINRELAY,OUTPUT);
  pinMode(PINBOTONMAS,INPUT);
  pinMode(PINBOTONMENOS,INPUT);
  pinMode(PININTERRUPTOR,INPUT);
  pinMode(PINRELAYLUZ,OUTPUT); 
  pinMode(PINRELAYBOMBA,OUTPUT);
  pinMode(PINSENSORDENIVEL,INPUT);
  Time = millis(); 
  lcd.setBacklightPin(3,POSITIVE);
  lcd.setBacklight(HIGH);
  lcd.begin(16, 2);

  //Blynk 
  Serial.begin(9600);
  Blynk.begin(auth);
  Blynk.begin(auth, "blynk-cloud.com", 80);
  timer.setInterval(1000L, lednivelaguablynk);
  timer.setInterval(1000L, ledpumpstateblynk);
}

void loop() {
  Blynk.run();
  timer.run();
 // First we read the real value of temperature
  temperature_read = thermocouple.readCelsius();
  //Next we calculate the error between the setpoint and the real value
  PID_error = set_temperature - temperature_read;
  //Calculate the P value
  PID_p = kp * PID_error;
  //Calculate the I value in a range on +-3
  if(-3 < PID_error <3)
  {
    PID_i = PID_i + (ki * PID_error);
  }

  //For derivative we need real time to calculate speed change rate
  timePrev = Time;                            // the previous time is stored before the actual time read
  Time = millis();                            // actual time read
  elapsedTime = (Time - timePrev) / 1000; 
  //Now we can calculate the D calue
  PID_d = kd*((PID_error - previous_error)/elapsedTime);
  //Final total PID value is the sum of P + I + D
  PID_value = PID_p + PID_i + PID_d;

  //We define PWM range between 0 and 255
  if(PID_value < 0)
  {    PID_value = 0;    }
  if(PID_value > 100)  
  {    PID_value = 100;  }

  Valuetouse=(100-PID_value);

  if (Interruptorluz==0){
    digitalWrite(PINRELAYLUZ,LOW);
  }

  else{
    digitalWrite(PINRELAYLUZ,HIGH);
  }
  
  if (Interruptorcalefaccion==0){
  //HIGH ES APAGADO - LOW ES PRENDIDO 
  if (temperature_read > set_temperature*(1-(Valuetouse/100))){
    digitalWrite(PINRELAY,HIGH);
  }
  else{
    digitalWrite(PINRELAY,LOW);
  }
  }
  else{
   digitalWrite(PINRELAY,HIGH); 
  }
  
  previous_error = PID_error;     //Remember to store the previous error for next loop.
  
  Nivel = digitalRead(PINSENSORDENIVEL);
  ValeurSensorHumedad = readhumidity();
  pourcentageHumedad = ConvertEnPorcentaje(ValeurSensorHumedad);

  if (pourcentageHumedad > 100){
  pourcentageHumedad = 100;
 }
  if (pourcentageHumedad < 0){
  pourcentageHumedad = 0;
 }

  if (pourcentageHumedad <= 60 or Nivel !=1) {
    digitalWrite(PINRELAYBOMBA,LOW);
  }
  else {
    digitalWrite(PINRELAYBOMBA,HIGH);
  }

  BotonMenos = digitalRead(PINBOTONMENOS);
  BotonMas= digitalRead(PINBOTONMAS);
  
  if (BotonMenos != 1){
  set_temperature--;
  }
  if (BotonMas != 1){
  set_temperature++;
  }

  delay(500);
  lcd.clear();
  
  lcd.setCursor(0,0);
  lcd.print("H:");
  lcd.setCursor(2,0);
  lcd.print(pourcentageHumedad);
  lcd.setCursor(5,0);
  lcd.print("%");
  lcd.setCursor(0,1);
  lcd.print("S:");
  lcd.setCursor(2,1);
  lcd.print(set_temperature,1);
  lcd.setCursor(9,1);
  lcd.print("R:");
  lcd.setCursor(11,1);
  lcd.print(temperature_read,1);
}

int ConvertEnPorcentaje(int value){
 int ValeurPorcentage = 0;
 ValeurPorcentage = map(value, 1023, 350, 0, 100);
 return ValeurPorcentage;
}

int readhumidity(){
  int valorhumedad = 0;
  valorhumedad = analogRead(PINSENHUMEDAD);
  return valorhumedad;
}

/*    Max6675 Module  ==>   Arduino
 *    CS              ==>     D25
 *    SO              ==>     D50
 *    SCK             ==>     D52
 *    Vcc             ==>     Vcc (5v)
 *    Gnd             ==>     Gnd      */

/*    Temp             ==>   Arduino
 *    RelayIN1         ==>     D3

/*    Botones              ==>   Arduino
 *    Boton+Temp           ==>     D4
 *    Boton-Temp           ==>     D9 */

/*    i2c LCD Module  ==>   Arduino
 *    SCL             ==>     D21
 *    SDA             ==>    D20
 *    Vcc             ==>     Vcc (5v)
 *    Gnd             ==>     Gnd      */

 /*   YL-69           ==>   Arduino
  *   A0              ==>     A0
  *   D0              ==>     --
  *   Gnd             ==>     Gnd 
  *   Vcc             ==>     Vcc (5v)
  */

 /*   Foco (interruptor+relay) ==>   Arduino
  *   Interruport (iz)         ==>     D6
  *   Interruptor (cen)        ==>     Vcc (5v)
  *   Interruptor (iz2)        ==>     GND
  *   RelayIN2                 ==>     D5
  */

  /*  Bomba de agua       ==>   Arduino
  *   RelayIN3            ==>     D7
  */

  /*  Sensor de nivel     ==>   Arduino
  *   Sensor              ==>     D8
  */
  
  /*   Modulo Ethernet ENC28J60 ==> Arduino
  *   CS                        ==>   D53
  *   SI                        ==>   D51
  *   SCK                       ==>   D52
  *   SO                        ==>   D50
  *   INT                       ==>   D19
  *   Gnd                       ==>   GND 
  *   Vcc                       ==>   Vcc (5v)
  */

Your little connection table at the end of your code seems to show that you have both the temperature module and the Ethernet module connected to pins 50 and 52. Is that correct?

You should alos read this:

Pete.

Hi PeteKnight thank you to answer, yes it is correct they are connected to the same PIN because they use SPI communication where you only need to hace one different PIN (CS) that is set to LOW when the module wants to communicate with the arduino (this peace of code is in the libraries that use SPI).

But that only works if your SPI master (your Arduino) tells your SPI slaves which device the data relates to. This is done using the Chip Select (AKA Slave Select) pin, which also needs to be connected to both slave devices.

You appear to be connecting the CS pins your slaves to different pins on the Arduino (D25 and D53)

Pete.

Sorry if what I will say is incorrect but I thought that the Slave Select must be different for each device.
Img_54_5

Of course, you’re 100% correct.
I managed to confuse myself when trying to pull your code apart - not difficult in my case!

How does your UIPEthernet.h library know that you’re using CS on pin D53? Is this hard coded in the library file?

Pete.

Yes Pete those PINS are set by default because they are the “official” Pins for Arduino SPI communication.

In that case it may be that your wiring is correct and it’s your void loop that’s too cluttered to allow the two devices to work together with Blynk.

Pete.

Yes it is probably that, I created a virtual SPI, with three other Pins and it works great. Pete one last question, do you know why I have the problem with my I2c LCD display that start to works only after the connexion with Blynk server is established ?

Thank you for your help.

From memory, Blynk.begin is a blocking command, so your void loop won’t run until it’s completed.
I think Blynk.connect is an alternative that can allow code execution to continue without a connection.
(I don’t use Blynk in this way, so it’s not my area of expertise, but a bit of searching g of the forum should shed more light on it).

Pete.

why not use DS18B sensors?

MAX6675’s are better for measuring fires and stuff, not gardens…