Part of code stops working when display is changed.

This is a bit hard to explain, but I’m going to try my best. I am modifying someone else’s code to change it from using a 7 segment display to an I2C LCD display. All I’ve needed to do to change it is setup the pins for the LCD, add some libraries, setup such as turning the backlight on, changing disp.print (disp is the 7 segment display’s name) to lcd.print, and some various lcd.clear and lcd.setCursor when needed. For the most part, it works perfectly. It all displays fine and functions ok, until one section. In this section, turning the rotary encoder should change the number on the display.

void writeTargetTemperature() {
  if (debug) {
    Serial.println(target_temp);
  }
  setDecimals(0b010000);
  sprintf(buff, "T %2d", (int) target_temp);
  disp.print(buff);

  delay(500);
}

When I turn debug on, I can see if it’s actually changing even without showing on the display. When disp.print(buff); is used, everything works perfectly. The number shows on the 7 segment and in the serial monitor. But when I change it to lcd.print(buff);, suddenly the number does not change when turning the rotary encoder. The number on the screen doesn’t change and the number in the serial monitor doesn’t either. I don’t understand how changing the display affects how the rotary encoder changes the number, but I’ve had no luck fixing it. Please keep in mind, I am not very familiar with arduinos, so I may be overlooking something simple. I have also attached the entire sketch in case it helps with diagnosing the issue. Thanks!

proofing_box.ino (5.49 KB)

You have an obvious conflict with pin 4, which is assigned to the LCD and to Software serial, as well as conflicts with pin 5 and 6. There are probably other problems.

You haven't described enough about your project to make much sense of it. In the future, please read and follow the instructions in the "How to use the forum" post.

jremington:
You have an obvious conflict with pin 4, which is assigned to the LCD and to Software serial, as well as conflicts with pin 5 and 6. There are probably other problems.

You haven't described enough about your project to make much sense of it. In the future, please read and follow the instructions in the "How to use the forum" post.

How can I fix the conflict? Sorry for not being very detailed, I'll give a full explanation and link to the github page for the project.

The purpose of it is to control the temperature of a box. There is a rotary encoder, a relay with a lightbulb connected, a temperature sensor, and the display connected. When the arduino is turned on, it displays the target temperature then changes to the current temperature. If the current temp is below the target temp, the relay turns on to heat up the box. Once it passes the target temp, the relay switches off so the box can cool down. The issue is with setting the target temperature. This is the way it is intended to work: When the rotary encoder button is held, it switches to temperature setting mode. Turning the rotary encoder increases or decreases the temperature it is set at. The temperature checking doesn't happen again until the button is held again and it switches back to the current temp mode. It will then use the new temperature as the target. What happens instead is the target temp doesn't change when using the lcd and the target setting mode can not be exited. If there is a pin conflict that might be the issue but I don't know how to fix that. Here is the github link for the project: GitHub - tehmantra/proofing_box: Temperature controlled proofing box for dough/bread.
Hope this is enough info, if you need anything else just ask.

Hope this is enough info

Nope. Pretend we know nothing about your project, and are unwilling to do a lot of research to "get up to speed". Because we don't, and aren't.

Read the sticky, follow the instructions, post a wiring diagram and links to all the modules and devices.

Or, you could use common sense, go through the code line by line, and eliminate the conflicts yourself. One function per pin!

I don't know for sure if there is a pin conflict. The LCD uses i2c so I don't know if those other pins are actually being used. I see lots of code like this floating around

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

But all the versions of the LCD display that I found does not have this signature. Can you provide a link to this library?

jremington:
Nope. Pretend we know nothing about your project, and are unwilling to do a lot of research to "get up to speed". Because we don't, and aren't.

Read the sticky, follow the instructions, post a wiring diagram and links to all the modules and devices.

Or, you could use common sense, go through the code line by line, and eliminate the conflicts yourself. One function per pin!

This page should have a wiring diagram with links to everything. As I said, I am not familiar with arduinos or much programming in general. I tried to use common sense to fix the conflict, but I couldn't find where it was. I also now see that you named other conflicts. The only thing I changed from the original code and design involving the pins is connecting the LCD to A4 and A5. Would fixing any of the conflicts affect any of this since they use completely different pins? Thanks for the help. So sorry for not giving enough details, I now know for next time.

blh64:
I don't know for sure if there is a pin conflict. The LCD uses i2c so I don't know if those other pins are actually being used. I see lots of code like this floating around

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

But all the versions of the LCD display that I found does not have this signature. Can you provide a link to this library?

As I said above, I also don't know if there is a conflict since nothing else using A4 and A5. I was following this tutorial and I just downloaded the library from Step 3 there. If there is a better alternative that could fix any of the problems, I would be happy to use it. Thanks

We generally recommend that Instructables be avoided, because so many of them are misleading or wrong, and that one is no exception.

After taking a look at the library code and documentation, this instantiation command

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

may work in that worthless tutorial (which involves only a display), but is obviously not correct for the standard type of I2C LCD display that you seem to have.

Look for another LCD example that requires only the I2C address and/or pin identifiers in the constructor.

That makes sense. I followed a makerguides.com guide. I downloaded the latest LCD_I2C library from GitLab. and replaced the long initiation command with just LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27,16,2);

It did seem simpler and I understand what that command does now, but it didn’t seem to fix the problem. It is having the same issues. Thank you for telling me about it anyway. I’m still thinking it might be a pin conflict, but nothing else uses any of the analog pins as far as I can tell.

First get the display working, with nothing else connected, using the simplest library example program. Baby steps!

jremington:
First get the display working, with nothing else connected, using the simplest library example program. Baby steps!

I'm pretty sure I get what you mean by this, but the display is working fine with the example code and the one I'm using. What's happening is using the display breaks other parts of the code, specifically whats being done with the rotary encoder. If I'm misunderstanding this, I'm sorry, but I don't see how testing the display will fix anything.

Sorry, I have no idea what rotary encoder you are using, or how you have wired it and I will NOT go wandering around off site to find out.

This page should have a wiring diagram with links to everything.

I get a pop up asking me to confirm the terms of service. I don't think so...

aarg:
I get a pop up asking me to confirm the terms of service. I don't think so...

Sorry about that, it's just an interactive wiring diagram that the original creator of the project used. I took a screenshot of the diagram (would use fritzing but the download website is currently down) since it seems like that's preferred.


Hope that helps!

jremington:
Sorry, I have no idea what rotary encoder you are using, or how you have wired it and I will NOT go wandering around off site to find out.

This is the rotary encoder I used. Diagram is above. Sorry if it's low quality as I can't install fritzing right now.

blh64:
I don't know for sure if there is a pin conflict. The LCD uses i2c so I don't know if those other pins are actually being used. I see lots of code like this floating around

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

But all the versions of the LCD display that I found does not have this signature. Can you provide a link to this library?

There is nothing wrong with that statement if the display is working in the remainder of your sketch. The 0x27 is the I2C address of the display, the following numbers describe how the I2C backplane chip is wired to the LCD display, and DO NOT refer to pins on the arduino. The libraries that use a constructor that only has the I2C address, or the I2C address and a couple of numbers specifying the characters per line and number of lines on the LCD display, are assuming a specific wiring between the I2C backplane and the LCD display.

void writeTargetTemperature() {
  if (debug) {
    Serial.println(target_temp);
  }
  setDecimals(0b010000);
  sprintf(buff, "T %2d", (int) target_temp);
  disp.print(buff);

  delay(500);
}

When you change the disp.print to lcd.print, you may need to set the lcd cursor position before doing the print, unless you already have the cursor positioned correctly before calling this function. I don't see any obvious problems, buff has plenty of space for the 4 characters so there should not be a buffer overrun. You might want to put a Serial.println(buff) immediately before the lcd.print for testing. Also comment out the setDecimals() function call, that should only be needed for the LED display, but really should have no effect on the lcd.print.

david_2018:
When you change the disp.print to lcd.print, you may need to set the lcd cursor position before doing the print, unless you already have the cursor positioned correctly before calling this function. I don’t see any obvious problems, buff has plenty of space for the 4 characters so there should not be a buffer overrun. You might want to put a Serial.println(buff) immediately before the lcd.print for testing. Also comment out the setDecimals() function call, that should only be needed for the LED display, but really should have no effect on the lcd.print.

I appreciate the help, thank you. I have since added an lcd.clear to fix the cursor issue, so that not an issue. Although, I don’t know if you understand the issue. “buff” is displaying fine and the lcd display works perfectly. No problems whatsoever. The issue is with the rotary encoder. When I change the code to print to lcd instead of disp, the rotary encoder stops working in the target set mode and won’t exit it. I can hold the button once to enter the target temp setting mode, but I can not use the rotary encoder to change the value or exit it. It works flawlessly using the “disp” display. So far nobody has given a solution that has worked, so I’m hoping you might be able to. Thanks!

david_2018:
There is nothing wrong with that statement if the display is working in the remainder of your sketch. The 0x27 is the I2C address of the display, the following numbers describe how the I2C backplane chip is wired to the LCD display, and DO NOT refer to pins on the arduino. The libraries that use a constructor that only has the I2C address, or the I2C address and a couple of numbers specifying the characters per line and number of lines on the LCD display, are assuming a specific wiring between the I2C backplane and the LCD display.

I can not locate a LCD library that has that signature. Can anyone provide a link to the lcd library being used?

With some testing, I've determined that any code involving the lcd in the writeTargetTemperature section causes the same problems. Displaying on disp and even just clearing the lcd causes the problems. For some reason using the lcd at all changes how this section functions. I don't know if this would help anyone in finding the issue though.

There is an incredibly stupid mistake in that code. The encoder interrupt routine attempts to perform serial input/output, which would freeze I2C and other types of communication.

Remove the writeTargetTemperature() function call from updateEncoder() and put it somewhere that would make sense.

Given an error this fundamental, this is probably not the only problem. An unfortunate place for a beginner to start!

void updateEncoder() {
  if (!setup_mode) {
    return;
  }
  
  int msb = digitalRead(pin_enco_1);
  int lsb = digitalRead(pin_enco_2);

  int enco = (msb << 1) | lsb; // convert the 2 pin value to single number
  int sum = (enco_prev << 2) | enco; // compare to the previous value

  // add or subtract based on rotation
  if (sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) { enco_value++; }
  if (sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) { enco_value--; }

  enco_prev = enco; // save for next time

  target_temp = enco_value * enco_sensitivity;
  writeTargetTemperature();
}

jremington:
There is a really stupid mistake in that code. The encoder interrupt routine attempts to perform serial input/output, which can freeze the Arduino.

Remove the writeTargetTemperature() function call and put it somewhere that would make sense.

Thanks a lot! After a few minutes of trying to fix that, I think you're definitely right. Since I didn't know where it would make sense to put it, I started out by just commenting it out. Doing that solved the problem, but created the problem that changing the target temp would also use the 2000ms delay used for the current temp function. Disabling that caused bad flickering, so I knew I was not doing it right. After all, you didn't tell me to get rid of the function. Like I said, I don't know where it would make sense to put the function, other than where it currently is. I would really appreciate it if you or someone else could tell me what I need to add, remove, or change in order to call the writeTargetTemperature() function without causing any other problems. I'm still learning all this so I just don't yet know how to fix it. Thanks!