VBA "With" statement - What is the Arduino method?

I have multiple I2C displays. I want to use subroutines that allow me to state which display I'm referring to. In VBA I often do this using a 'With' statement.

How can I obtain this functionality in an Arduino sketch?

Thanks!
Mike

Normally, I'd pass a reference to the requisite display object to the subroutine (function).

Let's take the "Hello World" example, assuming you are using LiquidCrystal I2C. Below is modified for 2 identical displays, one displaying "Hello" and the other "World"

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// Set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 16, 2);
// 2nd LCD, unique name, unique address...
LiquidCrystal_I2C lcd2(0x28, 16, 2);

void setup() {
  // initialize the LCD
  lcd.begin();
  lcd2.begin();
  // Turn on the blacklight and print a message.
  lcd.backlight();
  lcd2.backlight();
  lcd.print("Hello");
  lcd2.print("World");
}

void loop() {
  // Do nothing here...
}

I can't find the right library, so I cannot compile let alone test.

So please help me along here, never did like @wildbill and @Perehama doesn't hit the "with" concept… I'm more C than C++.

Is this a combination of your suggestions, shows one function handling any display object?

void displayText(LiquidCrystal_I2C theDisplay, char *theText)
{
	theDisplay.print(theText);
}

called like

displayText(lcd2, "World!");

?

TIA

a7

I'd go for

void displayText(LiquidCrystal_I2C& theDisplay,...
etc

@wildbill - I bet you are correct! But if I could understand that enough to put it to use I probably wouldn't have had to ask the question in the first place. :smiley:

@Perehama - Your example is close to where I am right now. I know how to set up and refer to each screen (they are OLED SSD1306, btw). But instead of hard coding the screen name into the code I want to select screens on the fly, programmatically.

@alto777 and @TheMemberFormerlyKnownAsAWOL- Yes, I think this will allow me to do what I want! But you seem to differ on the need for an "&". I can start experimenting, but any further direction? Thanks!!!

Thanks!!!
Mike

@AWOL So… what would the call look like please?

a7

alto777:
@AWOL So… what would the call look like please?

a7

Exactly the same as yours :wink:

Love it! Thank you so much!!!

Use Awol's method, it avoids putting a (possibly) large object on the stack, which saves memory, which tends to be in short supply on an Arduino.

Yes IC now, thank you both.

It's one of the places where I don't like C++! This use of & is something that obvsly has yet to sink in.

To my C brain, calls that are different should look different. I know it can be determined by looking around, maybe not even that hard. It's just one of those things like operator overloading that look fraught.

a7

Still on the same topic of addressing two OLED screens with one Nano, can someone tell me why my code does not work?

My code seems to work once on Screen 01, but never lights up Screen02 and never returns to Screen01. If I take out all the Screen02 lines, Screen01 works continuously. So I figure it is locking up on Screen02 but cannot figure out why.

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_GrayOLED.h>
#include <Adafruit_SPITFT.h>
#include <Adafruit_SPITFT_Macros.h>
#include <gfxfont.h>
#include <Adafruit_SSD1306.h>


#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels


// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
  Adafruit_SSD1306 Screen01(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
  Adafruit_SSD1306 Screen02(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
  
  
void setup() {
  Serial.begin(115200);


  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!Screen01.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { 
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }


  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!Screen02.begin(SSD1306_SWITCHCAPVCC, 0x3D)) { 
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }


}


void loop() {
  testScreen01();
  testScreen02();
}




void testScreen01(void) {
  Screen01.clearDisplay();
  delay(1000);
  Screen01.setTextSize(3);             
  Screen01.setTextColor(WHITE);       
  Screen01.setCursor(40,25);             
  Screen01.println(F("01"));
  Screen01.display();
  delay(1000);
}


void testScreen02(void) {
  Screen02.clearDisplay();
  delay(500);
  Screen02.setTextSize(3);             
  Screen02.setTextColor(WHITE);       
  Screen02.setCursor(40,25);             
  Screen02.println(F("01"));
  Screen02.display();
  delay(500);
}

Thanks,
Mike

Try the opposite test - does it work on screen2 by itself?

I expect you're running out of memory. The Adafruit library allocates memory for a buffer for each display at runtime. The compiler will report that you have plenty of RAM at compile time but once those buffers are allocated you will have very little left.

You likely need a device with more RAM or displays that don't need such big buffers.

The original question was:

mikemolang:
VBA "With" statement - What is the Arduino method?

And I'd like to know if there is one too!

For example, this is a piece of VBA code:

objectX.functionA()
objectX.functionB()

It can be replaced by this:

With objectX
  .functionA()
  .functionB()
End With

Which is a better way, because the pointer to objectX has to be created only once, so it works faster, and the code is easier to write as well as read. So, the question is, is there a direct replacement for the "With" statement in Arduino C++?

Erik_Baas:
Which is a better way, because the pointer to objectX has to be created only once, so it works faster,

You have proof of that?

Don't try to outsmart the compiler.

TheMemberFormerlyKnownAsAWOL:
You have proof of that?

Yes, I tested it, more than 25 years ago. In VBA, of course. I guess you were thinking of C++?

No, I haven't seen a VBA port for AVR.

A quarter of a century ago?
Things have moved on.

TheMemberFormerlyKnownAsAWOL:
No.

Finally. Thank you.

A quarter of a century ago?
Things have moved on.

I know. Does that mean that all experience older than 24 years can be thrown in the bin? Or 10? 5?

Erik_Baas:
Finally. Thank you.

So, you have the relative figures for VBA and C++ on AVR?
Care to share?

I know. Does that mean that all experience older than 24 years can be thrown in the bin? Or 10? 5?

The half-life of knowledge must now shorter than at any time in history.

Twenty five years ago, I was trying to get my head around MMX, then Intel introduced SSE, then SSE (where x is value between two and five inclusive), then AVX...
Meanwhile AMD were ploughing their own furrow...

Fifteen years ago, I was working on a project to port device drivers and filesystems to Linux 2.4. Long before the project was finished, we had to further port to 2.6.

Looking forward to those performance numbers.

It's hard to predict the behaviour of a language feature that doesn't exist. However I think that the current level of optimization would treat the alternate expressions presented in #14, with and without "with", identically. The only difference would be syntactic. I think when machine code is emitted, no object pointer is required except with dynamic object creation. IIRC it's only with that, or with polymorphic source code that function pointers are embedded in the target code. It's not hard to see that a call like 'object.function()' can easily refer to a hard memory location, as the function address will never change during the lifetime of the program, provided that 'object' is explicitly instantiated in the source code. The pointer to 'object' is then available to the compiler and can be discarded and collapsed to a hard address for 'function()' that compiles to an inline, direct subroutine call.