Oled scherm Arduino programma

Ik ben wat aan het spelen met een Arduino en een 128x32 Oled scherm.
Wat ik wil maken is een scherm waarbij 10 rechthoekjes staan.
En elke rechthoekje moet de status van een ingangspin weergeven.
Dus leeg vakje, is ingang laag, gevuld vakje, is ingang hoog.

Nu heb ik heel basic iets geschreven, echter is de refresh time zeer langzaam. Enig idee hoe ik dit kan versnellen zodat alles teglijk gewijzigd wordt?
In onderstaande video is dit duidelijk te zien:
https://youtu.be/XPRiIRFke18

c code:

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

Adafruit_SSD1306 display(-1);

// constants won't change. They're used here to set pin numbers:
const int Loop_1Pin = 2;     // Loop 1
const int Loop_2Pin = 3;     // Loop 2
const int Loop_3Pin = 4;     // Loop 3
const int Loop_4Pin = 5;     // Loop 4
const int Loop_5Pin = 6;     // Loop 5
const int Loop_6Pin = 7;     // Loop 6
const int Loop_7Pin = 8;     // Loop 7
const int Loop_8Pin = 9;     // Loop 8
const int Amp_1Pin = 10;     // Amp 1
const int Amp_2Pin = 11;     // Amp 2


// variables will change:
int Loop_1State = 0;         
int Loop_2State = 0;        
int Loop_3State = 0;      
int Loop_4State = 0;         
int Loop_5State = 0;         
int Loop_6State = 0;         
int Loop_7State = 0;      
int Loop_8State = 0;
int Amp_1State = 0;      
int Amp_2State = 0;
        

void setup()   
{                
  // initialize with the I2C addr 0x3C
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  

  // Clear the buffer.
  display.clearDisplay();


    // Display Text
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.println("Loop");
display.setCursor(108,0);
display.println("Amp");
    
display.setCursor(2,8);
display.println("1");

display.setCursor(14,8);
display.println("2");
    
display.setCursor(26,8);
display.println("3");

display.setCursor(38,8);
display.println("4");

display.setCursor(50,8);
display.println("5");

display.setCursor(62,8);
display.println("6");

display.setCursor(74,8);
display.println("7");

display.setCursor(86,8);
display.println("8");

display.setCursor(110,8);
display.println("1");

display.setCursor(122,8);
display.println("2");
}

void loop() {

 // read the state of the pushbutton value:
  Loop_1State = digitalRead(Loop_1Pin);
  Loop_2State = digitalRead(Loop_2Pin);
  Loop_3State = digitalRead(Loop_3Pin);
  Loop_4State = digitalRead(Loop_4Pin);
  Loop_5State = digitalRead(Loop_5Pin);
  Loop_6State = digitalRead(Loop_6Pin);
  Loop_7State = digitalRead(Loop_7Pin);
  Loop_8State = digitalRead(Loop_8Pin);
  Amp_1State = digitalRead(Amp_1Pin);
  Amp_2State = digitalRead(Amp_2Pin);
  
//Loop 1
  if (Loop_1State == HIGH) {
    // turn Loop 1 on:
    display.fillRect(0, 16, 8, 16, WHITE);
    display.display();
  } else {
    display.fillRect(0, 16, 8, 16, BLACK);   
    display.drawRect(0, 16, 8, 16, WHITE);
    display.display();
 }
 
//Loop 2
  if (Loop_1State == HIGH) {
    // turn Loop 2 on: 
    display.fillRect(12, 16, 8, 16, WHITE);
    display.display();
  } else {
    display.fillRect(12, 16, 8, 16, BLACK);
    display.drawRect(12, 16, 8, 16, WHITE);
    display.display();
 }

//Loop 3
  if (Loop_3State == HIGH) {
    // turn Loop 3 on:
    display.fillRect(24, 16, 8, 16, WHITE);
    display.display();
  } else {
    display.fillRect(24, 16, 8, 16, BLACK);   
    display.drawRect(24, 16, 8, 16, WHITE);
    display.display();
 }
 
//Loop 4
  if (Loop_4State == HIGH) {
    // turn Loop 4 on: 
    display.fillRect(36, 16, 8, 16, WHITE);
    display.display();
  } else {
    display.fillRect(36, 16, 8, 16, BLACK);
    display.drawRect(36, 16, 8, 16, WHITE);
    display.display();
 } 

//Loop 5
  if (Loop_5State == HIGH) {
    // turn Loop 5 on:
    display.fillRect(48, 16, 8, 16, WHITE);
    display.display();
  } else {
    display.fillRect(48, 16, 8, 16, BLACK);   
    display.drawRect(48, 16, 8, 16, WHITE);
    display.display();
 }
 
//Loop 6
  if (Loop_6State == HIGH) {
    // turn Loop 6 on: 
    display.fillRect(60, 16, 8, 16, WHITE);
    display.display();
  } else {
    display.fillRect(60, 16, 8, 16, BLACK);
    display.drawRect(60, 16, 8, 16, WHITE);
    display.display();
 }

//Loop 7
  if (Loop_7State == HIGH) {
    // turn Loop 7 on:
    display.fillRect(72, 16, 8, 16, WHITE);
    display.display();
  } else {
    display.fillRect(72, 16, 8, 16, BLACK);   
    display.drawRect(72, 16, 8, 16, WHITE);
    display.display();
 }
 
//Loop 8
  if (Loop_8State == HIGH) {
    // turn Loop 8 on: 
    display.fillRect(84, 16, 8, 16, WHITE);
    display.display();
  } else {
    display.fillRect(84, 16, 8, 16, BLACK);
    display.drawRect(84, 16, 8, 16, WHITE);
    display.display();
 } 
 
//Amp 1
  if (Amp_1State == HIGH) {
    // turn Amp 1 on:
    display.fillRect(108, 16, 8, 16, WHITE);
    display.display();
  } else {
    display.fillRect(108, 16, 8, 16, BLACK);   
    display.drawRect(108, 16, 8, 16, WHITE);
    display.display();
 }
 
//Amp 2
  if (Amp_2State == HIGH) {
    // turn Amp 2 on: 
    display.fillRect(120, 16, 8, 16, WHITE);
    display.display();
  } else {
    display.fillRect(120, 16, 8, 16, BLACK);
    display.drawRect(120, 16, 8, 16, WHITE);
    display.display();
 } 
 
}

c code:

//Loop 1
  if (Loop_1State == HIGH) {
    // turn Loop 1 on:
    display.fillRect(0, 16, 8, 16, WHITE);
    display.display();
  } else {
    display.fillRect(0, 16, 8, 16, BLACK);   
    display.drawRect(0, 16, 8, 16, WHITE);
    display.display();
 }

display.display(); zorgt waarschijnlijk voor het tonen, dit moet je maar 1x doen aan het einde van de loop.

als je het helemaal netjes wilt doen, moet je het alleen doen als er 1 of meerdere zijn gewijzigd.

verder kun je het iets sneller maken door alleen de binnenkant van het vierkant te wissen.

[Bericht gewijzigd door Progger op dinsdag 9 maart 2021 21:47:59 (11%)

GMT+1

Wat progger zei... De display.display() schrijft de hele display buffer naar het display over i2c en dat verslindt best veel tijd.
Iets anders is dat je een deprecated constructor gebruikt. Even in de code gekeken van Adafruit en het lijkt erop dat de nieuwe constructors ervoor zorgen dat de i2c clock naar 400 kHz wordt gezet ipv 100 kHz.

Vervang

c code:

Adafruit_SSD1306 display(-1);

met

c code:

Adafruit_SSD1306 display(128, 32, &Wire, -1);

Ook zou ik de code wat opruimen door een loopje te gebruiken. Dit is niet voor performance, maar wel voor de leesbaarheid.

c code:


  const int pins[10]  = { 2,  3,  4,  5,  6,  7,  8,  9,  10,  11 };
  const int x_pos[10] = { 0, 12, 24, 36, 48, 60, 72, 84, 108, 120 };
  for (int i = 0; i<10; i++) {
    if (digitalRead(pins[i]) == HIGH) {
      display.fillRect(x_pos[i], 16, 8, 16, WHITE);
    }
    else {
      display.fillRect(x_pos[i], 16, 8, 16, BLACK);   
      display.drawRect(x_pos[i], 16, 8, 16, WHITE);
    }
  }
  display.display();

EDIT: foutje uit code

Op 10 maart 2021 12:08:29 schreef Deskinspin:
Wat progger zei... De display.display() schrijft de hele display buffer naar het display over i2c en dat verslindt best veel tijd.
Iets anders is dat je een deprecated constructor gebruikt. Even in de code gekeken van Adafruit en het lijkt erop dat de nieuwe constructors ervoor zorgen dat de i2c clock naar 400 kHz wordt gezet ipv 100 kHz.

Vervang

c code:

Adafruit_SSD1306 display(-1);

met

c code:

Adafruit_SSD1306 display(128, 32, &Wire, -1);

Ook zou ik de code wat opruimen door een loopje te gebruiken. Dit is niet voor performance, maar wel voor de leesbaarheid.

c code:


  const int pins[10]  = { 2,  3,  4,  5,  6,  7,  8,  9,  10,  11 };
  const int x_pos[10] = { 0, 12, 24, 36, 48, 60, 72, 84, 108, 120 };
  for (int i = 0; i<10; i++) {
    if (digitalRead(pins[i]) == HIGH) {
      display.fillRect(x_pos[i], 16, 8, 16, WHITE);
    }
    else {
      display.fillRect(x_pos[i], 16, 8, 16, BLACK);   
      display.drawRect(x_pos[i], 16, 8, 16, WHITE);
    }
  }
  display.display();

EDIT: foutje uit code

Bedankt voor de tip betreft die kloksnelheid.
Dat was nog een van de vraagstukken, want ik vond dat vakjes te traag gevuld werden. Nu gaat dat goed.

Ik ben aan het kijken naar je versimpelde code.
Maar wat ik zie wat er nu gebeurd, is dat alle 10 de vakjes tegelijk gevuld worden. Zonder te kijken naar de afzonderlijke ingangen.
Edit: Tijdens het reageren, zie ik dat je de code hebt gewijzigd. Deze werkte in eerste instantie niet goed. Nu wel. Dank daarvoor!!

Je zou ook een switch case constructie kunnen gebruiken ipv al de if else.