Correct syntax for draw.Bitmap

Hey gang,
I'm using an OLED screen for a project and it's working well. My question is about displaying a sequence of multiple images in a loop and I would love some help with the correct syntax, please.
I would like to know how to specify a variable in the middle of the display.drawBitmap command.

Unfortunately I would be unable to use simple code like this because of the number of images:
(please ignore the lack of display.display, I was just trying to keep my example simple.)

display.drawBitmap(95, 35, circleArrows1, 32, 29, WHITE);
delay(125);
display.drawBitmap(95, 35, circleArrows2, 32, 29, WHITE);
delay(125);
display.drawBitmap(95, 35, circleArrows3, 32, 29, WHITE);
delay(125);
display.drawBitmap(95, 35, circleArrows...n, 32, 29, WHITE);
delay(125);

I would like to use something more like this, but am not sure of the correct syntax:

while(i<50){
display.drawBitmap(95, 35, circleArrows(iconNumber), 32, 29, WHITE);
delay(125);
i++

As a refresher, this is the specified syntax for the drawBitmap command:

display.drawBitmap(x position, y position, bitmap data, bitmap width, bitmap height, color)

Any help would be greatly appreciated.

All the best!
Dax.

The argument that you are passing is either a pointer to the bitmap in RAM or in PROGMEM (the function is overloaded), if you want to use a function to, then this function should return that pointer. You can also use an array that holds the pointers. If the pointers themselves are put in PROGMEM it does become a tad more complex.

Okay thanks @Deva_Rishi, I will read up on how to create an array that can be populated with that variable.
Do you know how to use that array with the draw.Bitmap command?

Thanks again,
Dax

display.drawBitmap(95, 35, circleArrows[iconNumber], 32, 29, WHITE);

should do the trick.

No luck, I'm afraid. The compiler gives me the error 'circleArrows' was not declared in this scope.
I guess instead of building the array inside the display.drawBitmap operator, it should be built outside and then passed to it. So something like:

spinningCircle = ("circleArrows"iconNumber);
display.drawBitmap(95, 35, spinningCircle, 32, 29, WHITE);

I have no idea what the correct syntax would be, though.

EDIT: Err, wait, a string not an array, right?

Okay, so I think I made a breakthrough in understanding, but still have syntax problems.

I added this code:

String spinningCircle = "circleArrows" + iconNumber;
display.drawBitmap(95, 35, spinningCircle, 32, 29, WHITE);

It gives me an error of no matching function for call to 'Adafruit_SSD1306::drawBitmap(int, int, String&, int, int, int)'

I thought I should see what the actual values for spinningCircle and iconNumber were and I saw something very strange. This is the code for the entire section. It is intended to check the ttposition sensor every millisecond and while it's not equal to 1, it will display the first icon for 125ms, then the next for 125ms..until the fourth. Once the fourth icon has been displayed for 125ms, the iconNumber is reset to 1 and then first icon will be displayed, etc, etc.

During loop, the values of spinningCircle and iconNumber are "circleArrows" and "1", then "ircleArrows" and "2", "rcleArrows" and "3", "leArrows" and "4". I guess that means I haven't got the right syntax for the concatenation.

  while (ttposition == 0){ //tt reed not closed
     display.clearDisplay();
     String spinningCircle = "circleArrows" + iconNumber;
     Serial.println(spinningCircle);
     Serial.println(iconNumber);
//     display.drawBitmap(95, 35, spinningCircle, 32, 29, WHITE); // display.drawBitmap(x position, y position, bitmap data, bitmap width, bitmap height, color)
     display.display();
     ttposition = digitalRead(TT_REED);
     delay(1);
     displayTime++;

     if (displayTime >= 125){
        displayTime = 0;
        if(iconNumber <4){
           iconNumber++;
           }
        else{
           iconNumber = 1;
           }
     }
  }

You are making life complicated.

static const unsigned char PROGMEM horse00[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
...
};
...
static const unsigned char PROGMEM horse14[] = {
...
};
...
const uint8_t *horses[] = {
    horse00, horse01, horse02, horse03, horse04, horse05, horse06, horse07,
    horse08, horse09, horse10, horse11, horse12, horse13, horse14
};

Note that the bitmap arrays are stored in PROGMEM but the pointer array is in SRAM.

show all the frames with

     for(int framecount = 0; framecount < 15; framecount++) {
            display.drawBitmap(0, 0, horses[framecount], 128, 64, BLACK, WHITE);
            display.display();  //send to OLED
     }

drawBitmap() is pretty slow. You can generate arrays in the Adafruit_SSD1306 native buffer format. Store them in PROGMEM. Use memcpy_P() to transfer to the OLED buffer.

David.

Hi David, thanks for the reply. I've studied the code you suggested and I'm not sure how it fits my design requirement.

It also seems like the display.drawBitmap command doesn't like square brackets inside the argument, at least as far as I could get it to in my code.

I discovered that why my code (below) was delivering strange results (ircleArrows, rcleArrows, etc), thought I'm not sure why that exact weirdness.

I was able to fix this by changing it from iconNumber to String(iconNumber). I am now getting spinningCircle = circleArrows1..4

But I still can't get display.drawBitmap to accept spinningCircle or [spinningCircle]. I suspect I've probably got the wrong data type for spinningCircle which is why the string isn't working.

Any ideas?

I don't know if I can be more specific than this. Life would be easier if you posted a link to your actual data.

static const unsigned char PROGMEM circleArrows1[] = {
...
};
static const unsigned char PROGMEM circleArrows2[] = {
...
};
static const unsigned char PROGMEM circleArrows3[] = {
...
};
static const unsigned char PROGMEM circleArrows4[] = {
...
};
...
const uint8_t *circleArrowptrs[] = {
    circleArrows1, circleArrows2, circleArrows3, circleArrows4
};

show with

     for(int framecount = 0; framecount < 4; framecount++) {
            display.drawBitmap(95, 35, circleArrowptrs[framecount], 32, 29, WHITE);
            display.display();  //send to OLED
     }

Yes, it would be nice to know which Arduino and how many of these icons. My example expects you to store in PROGMEM because otherwise you waste dynamic memory (SRAM).
If you only have four small icons they only take 928 bytes. With another 8 bytes for the pointer array.

This is fine for a MEGA2560 but too much for a Uno.

David.

p.s. Judging by your code in #9 you are new to programming.
It would be wise to attach your actual sketch. Then we can show you how to write it correctly.

I wasn't even going to bother with advise until it would show up.

That is not true, what it expects is a pointer to the bitmap, either in progmem or in RAM

Because you have only provided snippets, we are guessing just as much.

I agree. It is very simple to attach a sketch INO. If it has multiple tabs you can ZIP up the sketch files and attach the ZIP. A few seconds from your life.

It is the same as my usual request for links to hardware displays.
A few seconds to find an Ebay sale page and post the link.

In this case I am guessing that it is a 0.96 inch SSD1306 OLED but it would be nice to know for certain.

My main point is : attachments or links take very little effort from the OP. Composing technical questions require much more time from a newcomer.

David.

Deva Rishi and David, thank you both for the learning opportunity. As David has noted, I am indeed new to programming.
As for the screen, it is indeed a small OLED, this one's a 1.3" running on SSD1315. No problems writing to it, though. Running it on an Uno. 4 icons, but need to check tt_position as regularly as possible to avoid overshoot. (it's a rotating platter and this part of the code is returning it to its start position.)
My reason for not attaching the whole code was to try to keep it simple so anyone willing to help didn't have a tonne of code to wade through.

Thanks again for your help. I would love to understand why it doesn't like the string created by String spinningCircle = "circleArrows" + iconNumber;

//OLED display code by www.diyusthad.com
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(128, 64, &Wire, OLED_RESET);

//LCD 16x2 display code
#include <LiquidCrystal.h>

#define DOOR_CLOSED    2 // Set this to an interrupt pin and 3.3v. HIGH should be closed
#define STOP_BUTTON    3 // Set this to an interrupt pin and 3.3v. HIGH should be pressed
#define TT_REED          4 // digital pin and 3.3v
#define TEMP_SENSOR      5 // digital pin and 5v
#define RELAY_UV         6 //
#define RELAY_TT         7 //Turntable
#define RELAY_FAN        8 //
#define RELAY_HEATER     9 //


const int pin_RS = 8;
const int pin_EN = 9;
const int pin_d4 = 4;
const int pin_d5 = 5;
const int pin_d6 = 6;
const int pin_d7 = 7;
const int pin_BL = 10;
LiquidCrystal lcd( pin_RS,  pin_EN,  pin_d4,  pin_d5,  pin_d6,  pin_d7);

int i = 0;
int uvtimer = 1;
int target_temp = 30;
int MB1; //multi-button 1 <60=right, <200=up, <400=down, <600=left, <800=select
int curingActive = 0;
int ttposition; //turntable platter returned to start position
int iconNumber = 1; //for display
int displayTime; //for display
bool InTemperatureMode = false;
char spinningCircle[13];

// 'ikeaLogo', 126x42px (xy offset 1,11)
const unsigned char ikeaLogo [] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 
  0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 
  0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 
  0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 
  0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 
  0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 
  0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 
  0x03, 0xff, 0x80, 0x07, 0xc0, 0x07, 0x00, 0x1f, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x1f, 0xff, 0x00, 
  0x07, 0xff, 0xc0, 0x07, 0xc0, 0x07, 0x00, 0x1f, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x1f, 0xff, 0xc0, 
  0x0f, 0xff, 0xc0, 0x07, 0xc0, 0x06, 0x00, 0x3f, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x1f, 0xff, 0xe0, 
  0x1f, 0xff, 0xc0, 0x07, 0xc0, 0x06, 0x00, 0x7f, 0x00, 0x00, 0x1f, 0xc0, 0x00, 0x0f, 0xff, 0xe0, 
  0x3f, 0xff, 0xc0, 0x07, 0xc0, 0x04, 0x00, 0xff, 0x00, 0x00, 0x1f, 0xc0, 0x00, 0x0f, 0xff, 0xf0, 
  0x3f, 0xff, 0xc0, 0x07, 0xc0, 0x00, 0x00, 0xff, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x07, 0xff, 0xf8, 
  0x7f, 0xff, 0xc0, 0x07, 0xc0, 0x00, 0x01, 0xff, 0x00, 0x00, 0x7f, 0x80, 0x00, 0x07, 0xff, 0xf8, 
  0x7f, 0xff, 0xc0, 0x07, 0xc0, 0x00, 0x01, 0xff, 0x00, 0x00, 0x7f, 0x80, 0x00, 0x07, 0xff, 0xf8, 
  0x7f, 0xff, 0xc0, 0x07, 0xc0, 0x00, 0x01, 0xff, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x03, 0xff, 0xf8, 
  0x7f, 0xff, 0xc0, 0x07, 0xc0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x7f, 0x00, 0x60, 0x03, 0xff, 0xf8, 
  0x7f, 0xff, 0xc0, 0x07, 0xc0, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x01, 0xff, 0xf8, 
  0x7f, 0xff, 0xc0, 0x07, 0xc0, 0x00, 0x00, 0x7f, 0x00, 0x3f, 0xfe, 0x00, 0x00, 0x01, 0xff, 0xf8, 
  0x3f, 0xff, 0xc0, 0x07, 0xc0, 0x04, 0x00, 0x3f, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x01, 0xff, 0xf8, 
  0x3f, 0xff, 0xc0, 0x07, 0xc0, 0x04, 0x00, 0x1f, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0xff, 0xf0, 
  0x1f, 0xff, 0xc0, 0x07, 0xc0, 0x06, 0x00, 0x1f, 0x00, 0x00, 0x1c, 0x00, 0xf0, 0x00, 0xff, 0xe0, 
  0x0f, 0xff, 0xc0, 0x0f, 0xc0, 0x06, 0x00, 0x0f, 0x00, 0x00, 0x1c, 0x01, 0xf8, 0x00, 0x7f, 0xe0, 
  0x07, 0xff, 0x80, 0x07, 0xc0, 0x07, 0x00, 0x07, 0x00, 0x00, 0x18, 0x01, 0xf8, 0x00, 0x7f, 0xc0, 
  0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 
  0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 
  0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 
  0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 
  0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 
  0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 
  0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 
  0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

// 'clockSymbol', 32x32px
const unsigned char clockSymbol [] PROGMEM = {
  0x00, 0x0f, 0xf0, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x01, 0xff, 0xff, 0x80, 0x03, 0xf8, 0x1f, 0xc0, 
  0x07, 0xe0, 0x03, 0xe0, 0x0f, 0x80, 0x01, 0xf0, 0x1f, 0x00, 0x00, 0x78, 0x3e, 0x00, 0x00, 0x3c, 
  0x3c, 0x03, 0x80, 0x3c, 0x78, 0x03, 0x80, 0x1e, 0x78, 0x03, 0x80, 0x0e, 0x70, 0x03, 0x80, 0x0e, 
  0xf0, 0x03, 0x80, 0x0f, 0xe0, 0x03, 0x80, 0x07, 0xe0, 0x03, 0x80, 0x07, 0xe0, 0x03, 0x80, 0x07, 
  0xe0, 0x03, 0x80, 0x07, 0xe0, 0x01, 0xe0, 0x07, 0xe0, 0x00, 0xf0, 0x07, 0xf0, 0x00, 0x7c, 0x0f, 
  0x70, 0x00, 0x1f, 0x0e, 0x70, 0x00, 0x07, 0x0e, 0x78, 0x00, 0x02, 0x1e, 0x3c, 0x00, 0x00, 0x3c, 
  0x3c, 0x00, 0x00, 0x3c, 0x1e, 0x00, 0x00, 0x78, 0x0f, 0x80, 0x01, 0xf0, 0x07, 0xc0, 0x03, 0xe0, 
  0x03, 0xf8, 0x1f, 0xc0, 0x01, 0xff, 0xff, 0x80, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x0f, 0xf0, 0x00
};

// 'thermometer', 21x32px
const unsigned char thermometerSymbol [] PROGMEM = {
  0x00, 0x70, 0x00, 0x00, 0xfc, 0x00, 0x01, 0x8c, 0x00, 0x03, 0x06, 0x00, 0x03, 0x06, 0x00, 0x03, 
  0x06, 0xf8, 0x03, 0x06, 0x00, 0x03, 0x06, 0x00, 0x03, 0x06, 0x00, 0x03, 0x06, 0xe0, 0x03, 0x76, 
  0x00, 0x03, 0x36, 0x00, 0x03, 0x36, 0x00, 0x03, 0x36, 0xf8, 0x03, 0x36, 0x00, 0x03, 0x36, 0x00, 
  0x03, 0x36, 0x00, 0x03, 0x36, 0x00, 0x03, 0x36, 0x00, 0x03, 0x36, 0x00, 0x07, 0x73, 0x00, 0x04, 
  0x71, 0x80, 0x0c, 0xf9, 0x80, 0x09, 0xfc, 0x80, 0x09, 0xfc, 0xc0, 0x09, 0xfc, 0xc0, 0x09, 0xfc, 
  0x80, 0x0c, 0xfd, 0x80, 0x04, 0x71, 0x80, 0x06, 0x03, 0x00, 0x03, 0xde, 0x00, 0x00, 0xf8, 0x00
};

// 'Radiation symbol, 32x29px
const unsigned char radiationSymbol [] PROGMEM = {
  0x00, 0x01, 0x80, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x0e, 0x70, 0x00, 
  0x00, 0x0c, 0x30, 0x00, 0x00, 0x1c, 0x38, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x38, 0x0c, 0x00, 
  0x00, 0x30, 0x0c, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0x60, 0x07, 0x00, 0x00, 0xc0, 0x03, 0x00, 
  0x01, 0xc0, 0x03, 0x80, 0x01, 0x98, 0x19, 0x80, 0x03, 0xbc, 0x3c, 0xc0, 0x03, 0x3c, 0x3c, 0xc0, 
  0x06, 0x7e, 0x7e, 0x60, 0x06, 0x7f, 0xfe, 0x70, 0x0c, 0x01, 0x80, 0x30, 0x1c, 0x01, 0x80, 0x38, 
  0x18, 0x01, 0x80, 0x18, 0x38, 0x03, 0xc0, 0x1c, 0x30, 0x03, 0xe0, 0x0c, 0x60, 0x07, 0xe0, 0x06, 
  0x60, 0x07, 0xe0, 0x06, 0xc0, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x07, 0x7f, 0xff, 0xff, 0xfe, 
  0x7f, 0xff, 0xff, 0xfe
};

// 'circleArrows1', 32x32px
const unsigned char circleArrows1 [] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x1f, 0xf8, 0x00, 
  0x00, 0x7f, 0xfe, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x01, 0xff, 0xfc, 0x00, 0x03, 0xf8, 0x10, 0x00, 
  0x07, 0xe0, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x10, 0x0f, 0x80, 0x00, 0x30, 0x1f, 0x00, 0x00, 0x38, 
  0x1f, 0x00, 0x00, 0x7c, 0x1e, 0x00, 0x00, 0x7c, 0x1e, 0x00, 0x00, 0xfe, 0xff, 0x80, 0x01, 0xff, 
  0x7f, 0x80, 0x01, 0xff, 0x7f, 0x00, 0x00, 0x78, 0x3e, 0x00, 0x00, 0x78, 0x3e, 0x00, 0x00, 0xf8, 
  0x1c, 0x00, 0x00, 0xf8, 0x0c, 0x00, 0x01, 0xf0, 0x08, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x07, 0xe0, 
  0x00, 0x08, 0x1f, 0xc0, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x7f, 0xff, 0x00, 0x00, 0x7f, 0xfe, 0x00, 
  0x00, 0x1f, 0xf8, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// 'circleArrows2', 32x32px
const unsigned char circleArrows2 [] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x1c, 0x00, 
  0x00, 0x78, 0x1f, 0x80, 0x01, 0xf8, 0x0f, 0xe0, 0x03, 0xf8, 0x0f, 0xc0, 0x03, 0xf8, 0x0f, 0xc0, 
  0x07, 0xe0, 0x0f, 0xe0, 0x0f, 0xc0, 0x07, 0xf0, 0x0f, 0x80, 0x05, 0xf0, 0x1f, 0x00, 0x00, 0xf8, 
  0x1f, 0x00, 0x00, 0xf8, 0x1e, 0x00, 0x00, 0x78, 0x1e, 0x00, 0x00, 0x7c, 0x3e, 0x00, 0x00, 0x7c, 
  0x3e, 0x00, 0x00, 0x7c, 0x3e, 0x00, 0x00, 0x7c, 0x1e, 0x00, 0x00, 0x78, 0x1f, 0x00, 0x00, 0xf8, 
  0x1f, 0x00, 0x00, 0xf8, 0x0f, 0xa0, 0x01, 0xf0, 0x0f, 0xe0, 0x03, 0xf0, 0x07, 0xf0, 0x07, 0xe0, 
  0x03, 0xf0, 0x0f, 0xe0, 0x03, 0xf0, 0x1f, 0xc0, 0x07, 0xf0, 0x1f, 0x80, 0x01, 0xf8, 0x1e, 0x00, 
  0x00, 0x38, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// 'circleArrows3', 32x32px
const unsigned char circleArrows3 [] PROGMEM = {
  0x00, 0x00, 0x80, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x1f, 0xf8, 0x00, 
  0x00, 0x7f, 0xfe, 0x00, 0x00, 0x3f, 0xff, 0x00, 0x00, 0x0f, 0xff, 0xc0, 0x00, 0x03, 0x9f, 0xc0, 
  0x00, 0x01, 0x87, 0xe0, 0x0c, 0x00, 0x03, 0xf0, 0x0e, 0x00, 0x01, 0xf0, 0x1e, 0x00, 0x00, 0xf8, 
  0x1f, 0x00, 0x00, 0xf8, 0x1e, 0x00, 0x00, 0x78, 0x3e, 0x00, 0x00, 0x7c, 0x3e, 0x00, 0x00, 0x7c, 
  0x3e, 0x00, 0x00, 0x7c, 0x1e, 0x00, 0x00, 0x7c, 0x1e, 0x00, 0x00, 0x78, 0x1f, 0x00, 0x00, 0xf8, 
  0x1f, 0x00, 0x00, 0x78, 0x0f, 0x80, 0x00, 0x70, 0x0f, 0xc0, 0x00, 0x30, 0x07, 0xe1, 0x80, 0x00, 
  0x03, 0xf9, 0xc0, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0xff, 0xfc, 0x00, 0x00, 0x7f, 0xfe, 0x00, 
  0x00, 0x1f, 0xf8, 0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x01, 0x80, 0x00
};
// 'circleArrows4', 32x32px
const unsigned char circleArrows4 [] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x1f, 0xf8, 0x00, 
  0x00, 0x7f, 0xfe, 0x00, 0x04, 0xff, 0xff, 0x80, 0x07, 0xff, 0xff, 0xc0, 0x0f, 0xf8, 0x1f, 0xe0, 
  0x0f, 0xe0, 0x07, 0xe0, 0x0f, 0xc0, 0x03, 0xf0, 0x1f, 0xe0, 0x01, 0xf0, 0x1f, 0x80, 0x00, 0xf8, 
  0x18, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x18, 
  0x1f, 0x00, 0x01, 0xf8, 0x0f, 0x80, 0x07, 0xf8, 0x0f, 0xc0, 0x03, 0xf0, 0x07, 0xe0, 0x07, 0xf0, 
  0x07, 0xf8, 0x1f, 0xf0, 0x03, 0xff, 0xff, 0xf0, 0x00, 0xff, 0xff, 0x20, 0x00, 0x7f, 0xfe, 0x00, 
  0x00, 0x1f, 0xf8, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};


void setup()
{
  pinMode(RELAY_UV, OUTPUT);
  pinMode(RELAY_TT, OUTPUT);
  pinMode(RELAY_FAN, OUTPUT);
  pinMode(RELAY_HEATER, OUTPUT);
  digitalWrite(RELAY_UV, LOW);
  digitalWrite(RELAY_TT, LOW);
  digitalWrite(RELAY_FAN, LOW);
  digitalWrite(RELAY_HEATER, LOW);
  pinMode(TT_REED, INPUT_PULLUP);
  pinMode(TEMP_SENSOR, INPUT);
  pinMode(DOOR_CLOSED, INPUT_PULLUP);
  pinMode(STOP_BUTTON, INPUT_PULLUP);
//  attachInterrupt(digitalPinToInterrupt(DOOR_CLOSED), doorOpened, FALLING);
attachInterrupt(digitalPinToInterrupt(STOP_BUTTON), stopAll, FALLING);
  
  lcd.begin(16, 2);
  lcd.clear();
  lcd.setCursor(10, 1);
  lcd.print(" READY");
  lcd.setCursor(0, 1);
  lcd.print(uvtimer, DEC), lcd.print(" mins ");

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();

  display.setTextSize(2);        // pixel scale 2, screen width 10 chars
  display.setTextColor(WHITE);   // Draw white text
  display.drawBitmap(1, 11, ikeaLogo, 126, 42, WHITE); // display.drawBitmap(x position, y position, bitmap data, bitmap width, bitmap height, color)
  display.display();
  delay(15); // **** CHANGE TO 1800 WHEN FINISHED ****
  display.clearDisplay();    
  Serial.begin(9600); // debug only
  Serial.println("serial monitoring enabled"); // debug only
}

void loop()
{
  if (InTemperatureMode)
    setTemperature(); 
  else
    setUVTimer();
}


// Functions //

void stopAll()
{
  digitalWrite(RELAY_UV, LOW);
  digitalWrite(RELAY_TT, LOW);
  digitalWrite(RELAY_FAN, LOW);
  digitalWrite(RELAY_HEATER, LOW);    
  setUVTimer();
}

void doorOpened() //Unless door was open when curing was started, pause until closed again
{
  if (curingActive == 0){
    do {digitalRead(DOOR_CLOSED);}
    while (DOOR_CLOSED == LOW);
  }
}

void  runCuring()
{
  curingActive = 1;
  lcd.setCursor(0, 0);
  lcd.print("UV time:        ");
  lcd.setCursor(10, 1);
  lcd.print("CURING");
    
  display.clearDisplay();
  display.setTextSize(2);
  display.setCursor(0,0);        // TOP ROW
  display.println(F("  CURING  "));
  display.display(); 

//  uvtimer = uvtimer * 60; //*** ACTIVATE WHEN CODE IS COMPLETE ***

//  if ((digitalRead(DOOR_CLOSED) == HIGH) && (uvtimer > 0) && (digitalRead(STOP_BUTTON) != HIGH)){
  if (uvtimer > 0) { //temporary override, use line above{
    display.fillRect(50, 40, 27, 21, BLACK); // Clear
    display.setTextSize(1);
    display.setCursor(54,54);
    display.print(F("secs"));
    display.display();
    
    digitalWrite(RELAY_UV, HIGH);
    digitalWrite(RELAY_TT, HIGH);
    digitalWrite(RELAY_FAN, HIGH);
  }
  

//  while ((digitalRead(DOOR_CLOSED) == HIGH) && (uvtimer > 0) && (digitalRead(STOP_BUTTON) != HIGH)){
  while (uvtimer > 0) { // line above probably isn't needed because interrupt pins are being used for them
    lcd.setCursor(0, 1);
    lcd.print(uvtimer, DEC), lcd.print(" secs "); 

    display.fillRect(0, 40, 51, 21, BLACK); // Clear
    display.setTextSize(3);
    display.setCursor(0,40);        // BOTTOM ROW, LARGE
    display.print(uvtimer, DEC);
    display.display();
    
    while (i < 2){
      display.fillRect(95, 35, 32, 29, BLACK); // Clear
      display.display();
      delay(125);
      display.drawBitmap(95, 35, radiationSymbol, 32, 29, WHITE); // display.drawBitmap(x position, y position, bitmap data, bitmap width, bitmap height, color)
      display.display();
      delay(375);
      i++;
    }
    i = 0;
  
    uvtimer--;
  }
  digitalWrite(RELAY_UV, LOW);
  digitalWrite(RELAY_FAN, LOW);
  digitalWrite(RELAY_HEATER, LOW);

  display.clearDisplay();
  display.setTextSize(2);
  display.setCursor(0,0);        // TOP ROW
  display.println(F("Returning")); 
  display.setCursor(0,20);       // SECOND ROW
  display.println(F("platter.."));
  display.display();
  
  displayTime = 1;
  ttposition = digitalRead(TT_REED);
  while (ttposition == 0){ //tt reed not closed
     display.clearDisplay();
     char spinningCircle = "circleArrows" + (String)iconNumber;
     Serial.println (spinningCircle);
     display.fillRect(95, 35, 32, 29, BLACK); // Clear
     display.drawBitmap(95, 35, spinningCircle, 32, 29, WHITE);
     display.display();
     ttposition = digitalRead(TT_REED);
     delay(1);
     displayTime++;

     if (displayTime >= 125){
        displayTime = 0;
        if(iconNumber <4){
           iconNumber++;
           }
        else{
           iconNumber = 1;
           }
     }
  }
  //turntable platter has been returned to start position

  digitalWrite(RELAY_TT, LOW);
  lcd.setCursor(10, 1);
  lcd.print(" READY");
  InTemperatureMode = false;
  display.clearDisplay();
  curingActive = 0;
  setUVTimer();
}


void setUVTimer()
{
  lcd.setCursor(0, 0);
  lcd.print("Set UV time:    ");

  display.setTextSize(2);
  display.setCursor(0,0);
  display.println(F("Set UV"));
  display.setCursor(0,20);
  display.println(F("time:"));
  display.drawBitmap(93, 32, clockSymbol, 32, 32, WHITE);
  display.display();
  
  MB1 = analogRead (0);
  if (MB1 < 60)   //right button
  {
    delay(200);
    display.clearDisplay();
    InTemperatureMode = true;
  }
  else if (MB1 < 200)   //up button
  {
    uvtimer++;
    if (uvtimer > 15)
    {
      uvtimer = 15;
    }
    delay(250);
  }
  else if (MB1 < 400)  //down button
  {
    uvtimer--;
    if (uvtimer < 1)
    {
      uvtimer = 1;
    }
    delay(250);
  }
  else if (MB1 < 600)  //left button
  {
    delay(200);
    display.clearDisplay();
    InTemperatureMode = true;
  }
  else if (MB1 < 800)  //select button
  {
    runCuring();
  }
  lcd.setCursor(0, 1);
  lcd.print(uvtimer, DEC), lcd.print(" mins    ");

  display.fillRect(50, 40, 27, 21, BLACK); // Clear
  display.setTextSize(1);
  display.setCursor(54,54);
  display.print(F("mins"));
  display.display();
  
  display.fillRect(0, 40, 51, 21, BLACK); // Clear
  display.setTextSize(3);
  display.setCursor(0,40);        // BOTTOM ROW, LARGE
  display.print(uvtimer, DEC);
  display.display();
}

void setTemperature()
{
  lcd.setCursor(0, 0);
  lcd.print("Set temperature:");

  display.setTextSize(2);
  display.setCursor(0,0);
  display.println(F("Set temp-"));
  display.setCursor(0,20);
  display.println(F("erature:"));
  display.drawBitmap(99, 32, thermometerSymbol, 21, 32, WHITE);
  display.display();
  
  MB1 = analogRead (0);
  if (MB1 < 60)   //right button
  {
    delay(200);
    display.clearDisplay();
    InTemperatureMode = false;
  }
  else if (MB1 < 200)   //up button
  {
    target_temp++;
    if (target_temp > 60)
    {
      target_temp = 60;
    }
    delay(180);
  }
  else if (MB1 < 400)  //down button
  {
    target_temp--;
    if (target_temp < 15)
    {
      target_temp = 15;
    }
    delay(180);
  }
  else if (MB1 < 600)  //left button
  {
    delay(200);
    display.clearDisplay();
    InTemperatureMode = false;
  }
  else if (MB1 < 800)  //select button
  {
    runCuring();
  }
  lcd.setCursor(0, 1);
  lcd.print(target_temp, DEC), lcd.print("\xDF""C     ");

    display.fillRect(50, 40, 27, 21, BLACK); // Clear
    display.fillRect(0, 40, 51, 21, BLACK); // Clear
    display.setTextSize(3);
    display.setCursor(0,40);        // BOTTOM ROW, LARGE
    display.print(target_temp, DEC);
    display.print((char)247);
    display.print("C");
    display.display();
}

By the way, the LCD code will be removed once I get the OLED working 100%. I started with an LCD screen and discovered it was slightly too large to fit where it needed to go.

Please try this. I hope that I have explained in the comments.


#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(128, 64, &Wire, OLED_RESET);

#include "bitmaps.h"   //all your icon data
// array of pointers to animation bitmaps in PROGMEM
const uint8_t *circleArrowptrs[] = {
    circleArrows1, circleArrows2, circleArrows3, circleArrows4
};

void setup()
{
    display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
    display.display();  //show Adafruit logo
    delay(2000); //
}

void loop()
{
    display.clearDisplay();  //fresh BLACK background
    for (int framecount = 0; framecount < 4; framecount++) {
        // you need to draw both background and foreground
        // drawBitmap(x, y, bitmap data, width, height, foreground, background)
        display.drawBitmap(95, 35, circleArrowptrs[framecount], 32, 29, WHITE, BLACK);
        display.display();  //send to OLED
        delay(200);
    }
    delay(1000);
    for (int framecount = 0; framecount < 4; framecount++) {
        // draw inverted image i.e. swap colours
        // drawBitmap(x, y, bitmap data, width, height, foreground, background)
        display.drawBitmap(0, 0, circleArrowptrs[framecount], 32, 32, BLACK, WHITE);
        display.display();  //send to OLED
        delay(200);
    }
    // only need to draw foreground because you know background is black
    // drawBitmap(x, y, bitmap data, width, height, foreground)
    display.drawBitmap(40, 10, clockSymbol, 32, 32, WHITE);
    display.display();  //send to OLED
    delay(1000);
    display.drawBitmap(80, 5, thermometerSymbol, 21, 32, WHITE);
    display.display();  //send to OLED
    delay(1000);
    display.drawBitmap(60, 35, radiationSymbol, 32, 29, WHITE);
    display.display();  //send to OLED
    delay(1000);
}

David.

Hey David.
Thanks again for all of your help. Your sketch worked first time, so I added sections to my code and it didn't work correctly until I realised that arrays are probably numbered from 0, not 1. So I changed a few things and got it working very nicely!

I also realised how to integrate it into a setup which still checks the sensor position every millisecond as opposed to pausing for 200ms.
If anyone is interested, here is the code:

//OLED display code by www.diyusthad.com  Help from David Prentice & Deva Rishi.
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(128, 64, &Wire, OLED_RESET);

#define DOOR_CLOSED    2 // Set this to an interrupt pin and 3.3v. HIGH should be closed
#define STOP_BUTTON    3 // Set this to an interrupt pin and 3.3v. HIGH should be pressed
#define TT_REED          4 // digital pin and 3.3v
#define TEMP_SENSOR      5 // digital pin and 5v
#define RELAY_UV         6 //
#define RELAY_TT         7 //Turntable
#define RELAY_FAN        8 //
#define RELAY_HEATER     9 //
#define BUZZER           10 //

int i = 0;
int uvtimer = 1;
int targetTemp = 30;
int preHeat = 0;
int MB1; //multi-button 1 <60=right, <200=up, <400=down, <600=left, <800=select
int curingActive = 0;
int ttposition; //turntable platter returned to start position
int iconNumber = 0; //for display
int displayTime; //for display

#include "UV_chamber_bitmaps.h"
// array of pointers to animation bitmaps in PROGMEM
const uint8_t *circleArrowptrs[] = {
  circleArrows0, circleArrows1, circleArrows2, circleArrows3
};

void setup()
{
  pinMode(RELAY_UV, OUTPUT);
  pinMode(RELAY_TT, OUTPUT);
  pinMode(RELAY_FAN, OUTPUT);
  pinMode(RELAY_HEATER, OUTPUT);
  digitalWrite(RELAY_UV, LOW);
  digitalWrite(RELAY_TT, LOW);
  digitalWrite(RELAY_FAN, LOW);
  digitalWrite(RELAY_HEATER, LOW);
  pinMode(TT_REED, INPUT_PULLUP);
  pinMode(TEMP_SENSOR, INPUT);
  pinMode(DOOR_CLOSED, INPUT_PULLUP);
  pinMode(STOP_BUTTON, INPUT_PULLUP);
  //  attachInterrupt(digitalPinToInterrupt(DOOR_CLOSED), doorOpened, FALLING);
  attachInterrupt(digitalPinToInterrupt(STOP_BUTTON), stopAll, FALLING);

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  display.setTextSize(2);        // pixel scale 2, screen width 10 chars
  display.setTextColor(WHITE);
  display.drawBitmap(0, 11, ikeaLogo, 126, 42, WHITE); // display.drawBitmap(x position, y position, bitmap data, bitmap width, bitmap height, foreground colour, background colour)
  display.display();
  delay(1000); // **** CHANGE TO 1800 WHEN FINISHED ****
  display.clearDisplay();
  display.drawBitmap(0, 0, solaLogo, 128, 64, WHITE); // display.drawBitmap(x position, y position, bitmap data, bitmap width, bitmap height, foreground colour, background colour)
  display.display();
  delay(1000); // **** CHANGE TO 1800 WHEN FINISHED ****
  display.clearDisplay();
  //Serial.begin(9600); // debug only
  //Serial.println("serial monitoring enabled"); // debug only
}

void loop()
{
  setUVTimer();
}


// Functions //

void stopAll()
{
  digitalWrite(RELAY_UV, LOW);
  digitalWrite(RELAY_TT, LOW);
  digitalWrite(RELAY_FAN, LOW);
  digitalWrite(RELAY_HEATER, LOW);
  setUVTimer();
}

void doorOpened() //Unless door was open when curing was started, pause until closed again
{
  if (curingActive == 0) {
    do {
      digitalRead(DOOR_CLOSED);
    }
    while (DOOR_CLOSED == LOW);
  }
}

void  runCuring()
{
  curingActive = 1;

  display.clearDisplay();
  display.setTextSize(2);
  display.setCursor(0, 0);       // TOP ROW
  display.println(F("  CURING  "));
  display.display();

  //  uvtimer = uvtimer * 60; //*** ACTIVATE WHEN CODE IS COMPLETE ***

  //  if ((digitalRead(DOOR_CLOSED) == HIGH) && (uvtimer > 0) && (digitalRead(STOP_BUTTON) != HIGH)){
  if (uvtimer > 0) { //temporary override, use line above{
    display.fillRect(50, 40, 27, 21, BLACK); // Clear
    display.setTextSize(1);
    display.setCursor(54, 54);
    display.print(F("secs"));
    display.display();

    digitalWrite(RELAY_UV, HIGH);
    digitalWrite(RELAY_TT, HIGH);
    digitalWrite(RELAY_FAN, HIGH);
  }

  //  while ((digitalRead(DOOR_CLOSED) == HIGH) && (uvtimer > 0) && (digitalRead(STOP_BUTTON) != HIGH)){
  while (uvtimer > 0) { // line above probably isn't needed because interrupt pins are being used for them
    display.fillRect(0, 40, 51, 21, BLACK); // Clear
    display.setTextSize(3);
    display.setCursor(0, 40);       // BOTTOM ROW, LARGE
    display.print(uvtimer, DEC);
    display.display();

    while (i < 2) {
      display.fillRect(95, 35, 32, 29, BLACK); // Clear
      display.display();
      delay(125);
      display.drawBitmap(95, 35, radiationSymbol, 32, 29, WHITE);
      display.display();
      delay(375);
      i++;
    }
    i = 0;

    uvtimer--;
  }
  digitalWrite(RELAY_UV, LOW);
  digitalWrite(RELAY_FAN, LOW);
  digitalWrite(RELAY_HEATER, LOW);

  returnPlatter();

  display.clearDisplay();
  curingActive = 0;
  setUVTimer();
}

void returnPlatter()
{
  display.clearDisplay();
  display.setTextSize(2);
  display.setCursor(0, 0);       // TOP ROW
  display.println(F("Returning"));
  display.setCursor(0, 20);      // SECOND ROW
  display.println(F("platter"));
  display.display();
  display.drawBitmap(97, 32, circleArrows0, 32, 32, WHITE, BLACK);
  display.display();

  displayTime = 1;
  ttposition = digitalRead(TT_REED); //check if tt reed is not closed
  while (ttposition == 0) { // ==0
    ttposition = digitalRead(TT_REED);
    delay(1);
    displayTime++;

    if (displayTime >= 125)
    {
      displayTime = 0;
      if (iconNumber < 3) {
        iconNumber++;
      }
      else {
        iconNumber = 0;
      }
      display.drawBitmap(97, 32, circleArrowptrs[iconNumber], 32, 32, WHITE, BLACK);
      display.display();
    }
  }
  //turntable platter has been returned to start position

  digitalWrite(RELAY_TT, LOW);
}

void setUVTimer() { //page 1
  for (;;) {
    display.setTextSize(2);
    display.setCursor(0, 0);
    display.println(F("Set UV"));
    display.setCursor(0, 20);
    display.println(F("time:"));
    display.drawBitmap(93, 32, clockSymbol, 32, 32, WHITE);
    display.display();

    MB1 = analogRead (0);
    if (MB1 < 60)   //right button
    {
      delay(200);
      display.clearDisplay();
      setTemperature();
    }
    else if (MB1 < 200)   //up button
    {
      uvtimer++;
      if (uvtimer > 15)
      {
        uvtimer = 15;
      }
      delay(250);
    }
    else if (MB1 < 400)  //down button
    {
      uvtimer--;
      if (uvtimer < 1)
      {
        uvtimer = 1;
      }
      delay(250);
    }
    else if (MB1 < 600)  //left button
    {
      delay(200);
      display.clearDisplay();
      setHeating();
    }
    else if (MB1 < 800)  //select button
    {
      runCuring();
    }
    display.fillRect(50, 40, 27, 21, BLACK); // Clear
    display.setTextSize(1);
    display.setCursor(54, 54);
    display.print(F("mins"));
    display.display();

    display.fillRect(0, 40, 51, 21, BLACK); // Clear
    display.setTextSize(3);
    display.setCursor(0, 40);       // BOTTOM ROW, LARGE
    display.print(uvtimer, DEC);
    display.display();
  }
}

void setTemperature() { //page 2
  for (;;) {
    display.setTextSize(2);
    display.setCursor(0, 0);
    display.println(F("Set temp-"));
    display.setCursor(0, 20);
    display.println(F("erature:"));
    display.drawBitmap(99, 32, thermometerSymbol, 21, 32, WHITE);
    display.display();

    MB1 = analogRead (0);
    if (MB1 < 60)   //right button
    {
      delay(200);
      display.clearDisplay();
      setHeating();
    }
    else if (MB1 < 200)   //up button
    {
      targetTemp++;
      if (targetTemp > 60)
      {
        targetTemp = 60;
      }
      delay(180);
    }
    else if (MB1 < 400)  //down button
    {
      targetTemp--;
      if (targetTemp < 15)
      {
        targetTemp = 15;
      }
      delay(180);
    }
    else if (MB1 < 600)  //left button
    {
      delay(200);
      display.clearDisplay();
      setUVTimer();
    }
    else if (MB1 < 800)  //select button
    {
      runCuring();
    }

    display.fillRect(50, 40, 27, 21, BLACK); // Clear
    display.fillRect(0, 40, 51, 21, BLACK); // Clear
    display.setTextSize(3);
    display.setCursor(0, 40);       // BOTTOM ROW, LARGE
    display.print(targetTemp, DEC);
    display.setTextSize(2);
    display.setCursor(36, 35);
    display.print("o");
    display.setTextSize(3);
    display.setCursor(49, 40);
    display.print("C");
    display.display();
  }
}

void setHeating() { //page 3
  for (;;) {
    display.setTextSize(2);
    display.setCursor(0, 0);
    display.println(F("Pre-heat?"));
    display.setTextSize(1);
    display.setCursor(0, 20);
    if (preHeat == 1) {
      display.fillRect(0, 20, 71, 7, BLACK);
      display.println(F("[ Enabled  ]"));
    }
    if (preHeat == 0) {
      display.fillRect(0, 20, 71, 7, BLACK);
      display.println(F("[ Disabled ]"));
    }
    display.setCursor(0, 43);
    display.println(F("Current"));
    display.setCursor(0, 56);
    display.println(F("temp:"));
    display.drawBitmap(99, 32, thermometerSymbol, 21, 32, WHITE);
    display.setTextSize(2);
    //   display.fillRect(50, 40, 27, 21, BLACK); // Clear
    //   display.fillRect(0, 40, 51, 21, BLACK); // Clear
    display.setCursor(53, 50);
    //   display.print(targetTemp, DEC); //replace with DHT11/22 sensor reading, rounded to 0 dec pl.
    display.print("22"); //temporary value until DHT11 is connected
    display.setTextSize(1);
    display.setCursor(76, 45);
    display.print("o");
    display.setTextSize(2);
    display.setCursor(84, 50);
    display.print("C");
    display.display();

    MB1 = analogRead (0);
    if (MB1 < 60)   //right button
    {
      delay(200);
      display.clearDisplay();
      setUVTimer();
    }
    else if (MB1 < 200)   //up button
    {
      //add option here (enable)
      if (preHeat == 1) {
        preHeat = 0;
      }
      else {
        preHeat = 1;
      }
      delay(180);
    }
    else if (MB1 < 400)  //down button
    {
      if (preHeat == 1) {
        preHeat = 0;
      }
      else {
        preHeat = 1;
      }
      delay(180);
    }
    else if (MB1 < 600)  //left button
    {
      delay(200);
      display.clearDisplay();
      setTemperature();
    }
    else if (MB1 < 800)  //select button
    {
      runCuring();
    }
  }
}

I strongly advise you to use ctrl-T to format your code. Consistently indented blocks make the logic easier to follow.

You can possibly find several repeated sequences. If you write well named "helper" functions you can shorten your blocks.
Personally, I am happier when I can see a complete logic block on one screen.

David.

CTRL+T!! OMG. I had no idea. Thanks a lot, David!
(code above now formatted)

The Arduino IDE is missing a lot of shortcuts (CTRL+D to duplicate a line, CTRL+up/down to move lines vertically, F3 to search for the last search term), so I would never have guessed it would have this feature. I keep thinking I'd like to do all my editing in Notepad++, but it's a bit of a pain to transfer back and forth.

Yes, each of the settings screens and the machine's processes are separated into individual subroutines.

You can setup Notepad++ as an external editor.
However I am reasonably happy with the IDE. Even if the multi-tab Search-Replace is painful.

In fact I often create a new sketch tab. Copy some non-Arduino code from AS7.0 to the tab. Format the code. Put it back in AS7.0.

David.