Rotary encoder issue on Arduino Mega 2560

Hi
I need some help with a code for brewery controller that i found on the internet. A video of it can be seen here Arduino Brewery Controller - YouTube
I have connected the LCD and the rotary encoder but it do not work. I have tried to monitor the serial while turning the knob but there is nothing. I am not very experienced in using Arduino.
I first tried to use it on a UNO board but got an error. I then changed to am Mega 2560.
I have tried the rotary encoder with a basic code and it worked. The pins are correct.
I appriciate all help on this.
Link to the code GitHub - rkeithryan/Arduino-Brewery-Controller

"I have removed the code from the post"

Welcome to the forums. Please read the sticky post at the beginning of the forum about how to post your code using code tags. It helps people help you.

As for your code, you should try using the Encoder library rather than doing it yourself. It is much easier. It also looks like you did not post all your code as it cuts off mid loop()....

This encoder library may help to simplify your code.

I could not post the whole code:

[code]
#include <LiquidCrystal_I2C.h>
//i2c pins

#include <OneWire.h> // Library for Temp sensor
#include <DallasTemperature.h> // Library for Temp conversion


#define ONE_WIRE_BUS A0
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

DeviceAddress tempDeviceAddress;

int  resolution = 12;
unsigned long lastTempRequest = 0;
int  delayInMillis = 0;
float Temperature = 0.0;
int  idle = 0;

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); //

const int LED_RED = 10; //Red LED
const int LED_GREEN = 11; //Green LED
const int RELAY = 13; //Relay

static int pinA = 3; // Our first hardware interrupt pin is digital pin 2
static int pinB = 2; // Our second hardware interrupt pin is digital pin 3
volatile int aFlag = 0; // let's us know when we're expecting a rising edge on pinA to signal that the encoder has arrived at a detent
volatile int bFlag = 0; // let's us know when we're expecting a rising edge on pinB to signal that the encoder has arrived at a detent (opposite direction to when aFlag is set)
volatile int encoderPos = 0; //this variable stores our current value of encoder position. Change to int or uin16_t instead of byte if you want to record a larger range than 0-255
volatile int oldEncPos = 0; //stores the last encoder position value so we can compare to the current reading and see if it has changed (so we know when to print to the serial monitor)
volatile int reading = 0; //somewhere to store the direct values we read from our interrupt pins before checking to see if we have moved a whole detent

const int selectSwitch = 12;
unsigned int mashSet = 60;
unsigned int mashTemp;
unsigned int timeSet = 60;
unsigned int mashTime;
unsigned int boilTime;
int seconds = 59;
int secondsCount;
unsigned long time_countdown = 0;
int menuValue = 0;


void setup() {

  sensors.begin();
  sensors.getAddress(tempDeviceAddress, 0);
  sensors.setResolution(tempDeviceAddress, resolution);

  sensors.setWaitForConversion(false);
  sensors.requestTemperatures();
  delayInMillis = 750 / (1 << (12 - resolution));
  lastTempRequest = millis();

  pinMode(LED_RED, OUTPUT);
  pinMode(LED_GREEN, OUTPUT);
  pinMode(RELAY, OUTPUT);
  pinMode(selectSwitch, INPUT);
  pinMode(pinA, INPUT); // set pinA as an input, pulled HIGH to the logic voltage (5V or 3.3V for most cases)
  pinMode(pinB, INPUT); // set pinB as an input, pulled HIGH to the logic voltage (5V or 3.3V for most cases)
  attachInterrupt(0, PinA, RISING); // set an interrupt on PinA, looking for a rising edge signal and executing the "PinA" Interrupt Service Routine (below)
  attachInterrupt(1, PinB, RISING); // set an interrupt on PinB, looking for a rising edge signal and executing the "PinB" Interrupt Service Routine (below)
  Serial.begin(9600);

  digitalWrite (selectSwitch, HIGH);

  lcd.begin(16, 2);

  digitalWrite(LED_GREEN, HIGH); //Green LED ON
  digitalWrite(LED_RED, LOW);    //Red LED OFF
  digitalWrite(RELAY, LOW);      //Turn off Relay

  lcd.setCursor (3, 0);
  lcd.print("Welcome");
  lcd.setCursor (3, 1);
  lcd.print("Beerduino");

  delay(2500);
  lcd.clear();
}
void PinA() {
  cli(); //stop interrupts happening before we read pin values
  reading = PIND & 0xC; // read all eight pin values then strip away all but pinA and pinB's values
  if (reading == B00001100 && aFlag) { //check that we have both pins at detent (HIGH) and that we are expecting detent on this pin's rising edge
    encoderPos ++; //decrement the encoder's position count
    bFlag = 0; //reset flags for the next turn
    aFlag = 0; //reset flags for the next turn
  }
  else if (reading == B00000100) bFlag = 1; //signal that we're expecting pinB to signal the transition to detent from free rotation
  sei(); //restart interrupts
}
void PinB() {
  cli(); //stop interrupts happening before we read pin values
  reading = PIND & 0xC; //read all eight pin values then strip away all but pinA and pinB's values
  if (reading == B00001100 && bFlag) { //check that we have both pins at detent (HIGH) and that we are expecting detent on this pin's rising edge
    encoderPos --; //increment the encoder's position count
    bFlag = 0; //reset flags for the next turn
    aFlag = 0; //reset flags for the next turn
  }
  else if (reading == B00001000) aFlag = 1; //signal that we're expecting pinA to signal the transition to detent from free rotation
  sei(); //restart interrupts
}

void loop() {

  //============================================================================================//
  //                Get user input for mash temp setpoint                                       //
  //============================================================================================//

  encoderPos = 60;
  while (menuValue == 0)
  {
    //Display Mash Set point on LCD

    lcd.setCursor(1, 0);
    lcd.print("Mesketemperatur:");
    lcd.setCursor(6, 1);
    lcd.print(encoderPos);
    lcd.print(" C");

    if (digitalRead(selectSwitch) == LOW)
    {
      mashTemp = encoderPos;
      menuValue++;
      lcd.clear();
    }
    delay (1);
  }
  if (menuValue == 1)
  {
    delay (500);
  }

  //============================================================================================//
  //                Get user input for mash time setpoint                                       //
  //============================================================================================//

  encoderPos = 60;
  while (menuValue == 1)
  {

    //Display Mash Time Set point on LCD

    lcd.setCursor(1, 0);
    lcd.print("Set Mash Time:");
    lcd.setCursor(4, 1);
    lcd.print(encoderPos);
    lcd.print(" Mins");

    if (digitalRead(selectSwitch) == LOW)
    {
      mashTime = encoderPos;
      menuValue ++;
      lcd.clear();
    }
    delay(1);
    if (menuValue == 2)
    {
      delay (500);
    }
  }


  //============================================================================================//
  //          Display user selected set points before starting for user to confirm              //
  //============================================================================================//

  while (menuValue == 2)
  {
    //Display Set Mash Time and Set Mash Temp point on LCD
    lcd.setCursor(0, 0);
    lcd.print("Temp:");
    lcd.print(mashTemp);
    lcd.print(" Time:");
    lcd.print(mashTime);
    lcd.setCursor(1, 1);
    lcd.print("PRESS TO START");

    if (digitalRead(selectSwitch) == LOW)
    {
      menuValue ++;
      lcd.clear();
    }
    delay(100);
  }
  while (menuValue == 3)
  {
    delay (500);
    menuValue ++;
  }

  //============================================================================================//
  //                Heating up to temp for mash. User to confirm once ready                     //
  //============================================================================================//

  while (menuValue == 4)
  {
    lcd.setCursor(1, 0);
    lcd.print("Mash Temp: ");
    lcd.print(Temperature);
    lcd.setCursor(3, 1);
    lcd.print("HEATING UP");

    if (millis() - lastTempRequest >= delayInMillis) // waited long enough??
    {

      Temperature = sensors.getTempCByIndex(0);
      idle = 0;

      // immediately after fetching the temperature we request a new sample
      // in the async modus
      // for the demo we let the resolution change to show differences
      resolution++;
      if (resolution > 12) resolution = 9;

      sensors.setResolution(tempDeviceAddress, resolution);
      sensors.requestTemperatures();
      delayInMillis = 750 / (1 << (12 - resolution));
      lastTempRequest = millis();
    }
    if (Temperature > mashTemp)
    {
      digitalWrite(RELAY, LOW);   //Turn off heater
      digitalWrite(LED_RED, LOW);
      digitalWrite(LED_GREEN, HIGH); //Turn on Green LED
      for (int i = 0; i < 5; i++) {
        tone (A1, 500);
        delay (500);
        noTone (A1);
        delay (500);

      }
      menuValue ++;

    }
    if (Temperature < mashTemp)
    {
      digitalWrite(RELAY, HIGH);   //Turn on heater
      digitalWrite(LED_GREEN, LOW);
      digitalWrite(LED_RED, HIGH); //Turn on RED LED
    }
  }
  lcd.clear();
  delay (500);

  while (menuValue == 5) {

    lcd.setCursor(0, 0);
    lcd.print("Temp Reached: ");
    lcd.print(Temperature);
    lcd.setCursor(1, 1);
    lcd.print("PRESS TO START");

    if (digitalRead(selectSwitch) == LOW)
    {
      menuValue ++;
    }


  }
  delay(500);

[/code]

[code]

  //============================================================================================//
  //                Heating up to temp for mash. User to confirm once ready                     //
  //============================================================================================//

  while (menuValue == 4)
  {
    lcd.setCursor(1, 0);
    lcd.print("Mash Temp: ");
    lcd.print(Temperature);
    lcd.setCursor(3, 1);
    lcd.print("HEATING UP");

    if (millis() - lastTempRequest >= delayInMillis) // waited long enough??
    {

      Temperature = sensors.getTempCByIndex(0);
      idle = 0;

      // immediately after fetching the temperature we request a new sample
      // in the async modus
      // for the demo we let the resolution change to show differences
      resolution++;
      if (resolution > 12) resolution = 9;

      sensors.setResolution(tempDeviceAddress, resolution);
      sensors.requestTemperatures();
      delayInMillis = 750 / (1 << (12 - resolution));
      lastTempRequest = millis();
    }
    if (Temperature > mashTemp)
    {
      digitalWrite(RELAY, LOW);   //Turn off heater
      digitalWrite(LED_RED, LOW);
      digitalWrite(LED_GREEN, HIGH); //Turn on Green LED
      for (int i = 0; i < 5; i++) {
        tone (A1, 500);
        delay (500);
        noTone (A1);
        delay (500);

      }
      menuValue ++;

    }
    if (Temperature < mashTemp)
    {
      digitalWrite(RELAY, HIGH);   //Turn on heater
      digitalWrite(LED_GREEN, LOW);
      digitalWrite(LED_RED, HIGH); //Turn on RED LED
    }
  }
  lcd.clear();
  delay (500);

  while (menuValue == 5) {

    lcd.setCursor(0, 0);
    lcd.print("Temp Reached: ");
    lcd.print(Temperature);
    lcd.setCursor(1, 1);
    lcd.print("PRESS TO START");

    if (digitalRead(selectSwitch) == LOW)
    {
      menuValue ++;
    }


  }
  delay(500);

  //-------------------------- MASH PROCESS ----------------------------------------------------//

  //============================================================================================//
  //               Mash timer countdown                                                         //
  //============================================================================================//

  time_countdown = millis();
  int minsCount = mashTime;
  mashTime = mashTime - 1;

  while (minsCount > 0 && seconds >= 0 && menuValue == 6)
  {
    //Display Mash Temp and Time on LCD
    lcd.setCursor(0, 0);
    lcd.print("Mash Temp: ");
    lcd.print(Temperature);
    lcd.setCursor(0, 1);
    lcd.print("Mash Time: ");
    if (mashTime < 10) {
      lcd.print ("0");
      lcd.print (mashTime);
    } else {
      lcd.print(mashTime);
    }
    lcd.print(":");
    if (seconds < 10) {
      lcd.print ("0");
      lcd.print (seconds);
    } else {
      lcd.print (seconds);
    }


    if (millis() - time_countdown >= 999) { //The while loop ends when 'minsCount' become zero
      seconds = seconds - 1;
      secondsCount ++;
      if (secondsCount == 60) {
        mashTime = mashTime - 1;
        secondsCount = 0;
        seconds = 59;
        minsCount = minsCount - 1;
      }
      time_countdown = millis();
    }


    //============================================================================================//
    //                Reading temp and cotrolling heater                                          //
    //============================================================================================//

    if (millis() - lastTempRequest >= delayInMillis) // waited long enough??
    {

      Temperature = sensors.getTempCByIndex(0);
      idle = 0;

      // immediately after fetching the temperature we request a new sample
      // in the async modus
      // for the demo we let the resolution change to show differences
      resolution++;
      if (resolution > 12) resolution = 9;

      sensors.setResolution(tempDeviceAddress, resolution);
      sensors.requestTemperatures();
      delayInMillis = 750 / (1 << (12 - resolution));
      lastTempRequest = millis();
    }

    if (Temperature > mashTemp)
    {
      digitalWrite(RELAY, LOW);   //Turn off heater
      digitalWrite(LED_RED, LOW);
      digitalWrite(LED_GREEN, HIGH); //Turn on Green LED
    }
    else
    {
      digitalWrite(RELAY, HIGH);   //Turn on heater
      digitalWrite(LED_GREEN, LOW);
      digitalWrite(LED_RED, HIGH); //Turn on RED LED
    }

    //delay(100); //Update at every 100mSeconds
  }


  //============================================================================================//
  //               Mash finished. User has option to continue to boil                           //
  //============================================================================================//

  menuValue++;
  while (menuValue == 7) {
    digitalWrite(RELAY, LOW);   //Turn off heater
    digitalWrite(LED_RED, LOW);
    digitalWrite(LED_GREEN, HIGH); //Turn on Green LED
    lcd.clear();
    lcd.setCursor(1, 0);
    lcd.print("Finished Mash");
    for (int i = 0; i < 5; i++) {
      tone (A1, 500);
      delay (500);
      noTone (A1);
      delay (500);
    }
    menuValue++;
  }
  while (menuValue == 8) {
    lcd.setCursor (1, 1);
    lcd.print ("PRESS FOR BOIL");

    if (digitalRead(selectSwitch) == LOW)
    {
      lcd.clear();
      menuValue ++;
      delay (1000);
    }
  }

 
  //--------------------------------- BOIL PROCESS ---------------------------------------------//


  //============================================================================================//
  //                Getting user defined boil time                                              //
  //============================================================================================//

  encoderPos = 60;
  while (menuValue == 9)  {

    lcd.setCursor(3, 0);
    lcd.print("Boil Time: ");
    lcd.setCursor(5, 1);
    lcd.print(encoderPos);
    lcd.print(" Mins");

    if (digitalRead(selectSwitch) == LOW)
    {
      boilTime = encoderPos;
      menuValue ++;
      lcd.clear();
    }
    delay(1);
    if (menuValue == 10)
    {
      delay (500);
    }
  }

[/code]

You cannot use pins 2 & 3 for LCD and encoder interrupts at the same time.

Hi,

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks.. Tom... :slight_smile:

You are trying to do too much too quickly.
You have to do code a small step at a time, especially seeing how new you are to it all.

Just write code to read the encoder and send the results to the serial monitor. Get that working before you add any other stuff. Your code will than be easy to follow and we can help.
When that is working add the next small bit and see if that works. Proceed slowly until you are finished.

Thank you for your feedbacks.
I have to mention that this is not my code. I am more of a brewer than a programmer :slight_smile: I just wanted to learn more about the possibilities of Arduino boards and use. I have managed to use an encoder library by it selfs on the mega board but are struggling to insert it into the code.
I have a library called Encoder.h and need to divide by 4 to get singel numbers on the serial monitor.
The schematic picture is underneath. I have not yet attached sensors and rely since I wanted to test the code with just the LCD and the rotary encoder. The LCD is 20X4 IC2

Here we go!
Beerduino.jpg

Paul__B:
Here we go!
Beerduino.jpg

Thank you :slight_smile:
I have tried to change the pins to 8 and 9 and it is still the same. I forgot that LCD is using the 0-7 pins.
The setup of the code is very good except for the rotary encoder part, so I do not want to rewrite it.

My assumption is that the creater of this code uses a 16x2 LCD and I use a 20X4 LCD and some of the pins on the LCD is in conflict with the code.
I cannot find which pins are in conflict.
I am not sure if someone is up for the task to edit the code so that it works for me :grinning:

I manage to use the encoder with a library and make get the welcome menu start.

edit:
The issue is that the original code is for a 16x2 LCD and I use 20x4 LCD. When I change the library to LiquidCrystal_I2C.h i get an error when using it on a Arduino Uno. The same code is ok when using for Mega but when uploaded to the board I do not get the encoder to work.

I got it to work on an UNO board
Included this to libraries:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>