Go Down

Topic: [bitte um Test] Konstruktorwerte von globalem Objekt im setup einstellen (Read 219 times) previous topic - next topic

HTML-Fan

Und - zack! - habe ich wieder ein Problem. :-\

Code: [Select]
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
//#include "splash.h"

Adafruit_SSD1306 display;// = Adafruit_SSD1306(128, 64, &Wire, -1, 800000);
void setup(){
  Serial.begin(115200);
  Wire.begin(4, 5);
 
  byte addr = 0;
  for(byte i = 0x3C;i <= 0x3D;i++){
    Wire.beginTransmission(i);
    if(Wire.endTransmission() == 0){
      addr = i;
      break;
    }
  }
  Serial.println(addr);
  if(addr){
    display = Adafruit_SSD1306(128, 64, &Wire, -1, 800000);
  }
  else{
    display = Adafruit_SSD1306(128, 64, &SPI, -1, SS, 800000);
  }
}
void loop(){/* ... */}

Dieses ESP8266-Programm soll herausfinden, ob das Display über SPI oder I²C angeschlossen ist. Oder besser gesagt: Wenn es kein I²C-Gerät an den Adressen 0x3C oder 0x3D vorfindet, "glaubt" es, dass das Display über SPI verbunden ist. Ferner soll es dann im loop Zeug auf dem Display ausgeben, das funktioniert und ist daher egal.
Mein Problem: Wenn ich das Programm kompiliere, kommt diese Fehlermeldung, die Zeile 25 betreffend:
Code: [Select]
exit status 1
use of deleted function 'Adafruit_SSD1306& Adafruit_SSD1306::operator=(const Adafruit_SSD1306&)'

Wieso funktioniert das nicht? Es hat doch auch funktioniert, als ich direkt bei der "display"-Deklarierung dieses " = Adafruit_SSD1306(128, 64, &Wire, -1, 800000)" hingeschrieben habe (siehe Auskommentiertes in Zeile 7). Kann mir da jemand helfen?

Serenifly

Quote
Wieso funktioniert das nicht?
Weil Konstrukturen so nicht funktionieren

Quote
Es hat doch auch funktioniert, als ich direkt bei der "display"-Deklarierung dieses " =
Im Resultat geht das, aber was da wirklich geschah ist etwas anderes als du gedacht hast

Lerne den Unterschied zwischen Initialisierung und Zuweisung. Das sieht gleich aus, aber wird völlig unterschiedlich behandelt.


Was du willst, geht wenn du die Objekte dynamisch mit new/delete verwaltest

HTML-Fan

Was du willst, geht wenn du die Objekte dynamisch mit new/delete verwaltest
Kannst du mir dafür vielleicht ein Beispiel geben? Würde mich freuen.

Serenifly

Google kann dir das auch erklären

http://www.foerterer.com/cpp/dynamisch/newAndDelete.htm
Statt das ein einer Zeile zu machen deklarierst du global nur einen Zeiger. Und machst new erst in setup()

HTML-Fan

Gut. Was ist eigentlich der Unterschied zwischen free und delete? Und kann man es irgendwie hinkriegen, dass ich nicht überall (*display).irgendwas oder display->irgendwas eingeben muss, sondern display.irgendwas nutzen kann?

Serenifly

free ist aus C. new ist C++. Du programmierst hier C++

Quote
oder display->irgendwas eingeben muss, sondern display.irgendwas nutzen kann?
Hier nicht. Du hast nunmal einen Zeiger. Und Referenzen lassen sich in diesem Zusammenhang nicht verwenden

HTML-Fan

Gibt es vielleicht eine Möglichkeit mit #define oder sowas? Das der Kompiler z.B. display durch (*disp) ersetzt?

Serenifly

Das mit (*). macht niemand. Es ist sinnvoll das zu wissen, weil man dann auch versteht was da gemacht wird. Aber praktisch ist es nicht. Die normale Notation ist ->. Damit sieht man auch dass man mit Zeigern hantiert.

HTML-Fan

Oder "display." durch "disp->" ersetzen. Ich weiß nämlich, dass ich das tausende Male vergessen werde.

Tommy56

Suchen und Ersetzen gibt es schon länger, um bestehenden Code anzupassen.
Bei neuen Zeilen erinnert Dich der Compiler.

Solche Sachen durch Modifikation zu verschleiern erschwert einen Informationsaustausch mit anderen Entwicklern unheimlich.

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

HTML-Fan

Gut. Danke für die Hilfe, @Serenifly und @Tommy56!

HTML-Fan

Noch eine kleine Bitte: Ich habe bei mir gerade nur I²C-Displays und kann daher nicht testen, ob SPI funktioniert. Kann vielleicht jemand mit einem SSD-1306-OLED, welches über SPI angesteuert wird, testen, ob mein Programm auch bei einem SPI-Display läuft? Das Programm ist für den ESP8266, es muss aber nur Wire.begin(4, 5) durch Wire.begin() ersetzt werden, dann sollte es auch auf dem Uno und Ähnlichem laufen.
Code: [Select]
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "splash.h"

Adafruit_SSD1306 *display;// = Adafruit_SSD1306(128, 64, &Wire, -1, 1000000);
void setup(){
  Serial.begin(115200);
  Wire.begin(4, 5);
 
  byte addr = 0;
  for(byte i = 0x3C;i <= 0x3D;i++){
    Wire.beginTransmission(i);
    if(Wire.endTransmission() == 0){
      addr = i;
      break;
    }
  }
  Serial.println(addr, HEX);
  if(addr){
    display = new Adafruit_SSD1306(128, 64, &Wire, -1, 1000000);
  }
  else{
    display = new Adafruit_SSD1306(128, 64, &SPI, -1, SS, 1000000);
  }
  (*display).begin(SSD1306_SWITCHCAPVCC, addr);
  (*display).clearDisplay();
  (*display).invertDisplay(true);
  (*display).display();
  delay(1000);
  (*display).invertDisplay(false);
  Serial.println("ready");
}
void filter(byte type, bool color, byte val){
  switch(type){
    case 0:
      uint8_t len = random(25, 75);
      uint8_t ran[len];
      long _time = millis();
      for(byte j = 0;j < len;j++){
        ran[j] = 0;
        for(byte k = 0;k < 8;k++){
          ran[j] |= (random(255) < val) << k;
        }
      }
      uint8_t *buf = (*display).getBuffer();
      if(color){
        for(uint16_t j = 0;j < 1024;j++){
          *buf |= ran[j % len];
          buf++;
        }
      }
      else{
        for(uint16_t j = 0;j < 1024;j++){
          *buf &= ~ran[j % len];
          buf++;
        }
      }
      break;
  }
}
void draw(int8_t x, int8_t y, byte val){
  uint64_t time = millis();
  (*display).clearDisplay();
  (*display).drawBitmap(((128 - splash1_width) >> 1) + x, y, splash1_data, splash1_width, splash1_height, 1);
  filter(0, BLACK, val);
  (*display).display();
  //Serial.println(uint32_t(millis() - time));
}
void loop(){
  int8_t x = random(-32, 32);
  int8_t y = random(-8, 4);
  float i = 255;
  while(i > 0){
    uint64_t time = millis();
    draw(x, y, i);
    i -= map(float(millis() - time), 0, 1000, 0, 255);
  }
  draw(x, y, 0);
  delay(2000);
  i = 0;
  while(i < 255){
    uint64_t time = millis();
    draw(x, y, i);
    i += map(float(millis() - time), 0, 1000, 0, 255);
  }
  draw(x, y, 255);
  delay(2000);
}

HTML-Fan

Ups, habe mich in der Programm-Version vertan. Und die #define s müssen geändert werden.
Code: [Select]
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "splash.h"

#define DC 16
#define CS SS
Adafruit_SSD1306 *display;// = Adafruit_SSD1306(128, 64, &Wire, -1, 1000000);
void setup(){
  Serial.begin(115200);
  Wire.begin(4, 5);
 
  byte addr = 0;
  for(byte i = 0x3C;i <= 0x3D;i++){
    Wire.beginTransmission(i);
    if(Wire.endTransmission() == 0){
      addr = i;
      break;
    }
  }
  Serial.println(addr, HEX);
  if(addr){
    display = new Adafruit_SSD1306(128, 64, &Wire, -1, 1000000);
  }
  else{
    display = new Adafruit_SSD1306(128, 64, &SPI, DC, -1, CS, 1000000);
  }
  (*display).begin(SSD1306_SWITCHCAPVCC, addr);
  (*display).clearDisplay();
  (*display).invertDisplay(true);
  (*display).display();
  delay(1000);
  (*display).invertDisplay(false);
  Serial.println("ready");
}
void filter(byte type, bool color, byte val){
  switch(type){
    case 0:
      uint8_t len = random(25, 75);
      uint8_t ran[len];
      long _time = millis();
      for(byte j = 0;j < len;j++){
        ran[j] = 0;
        for(byte k = 0;k < 8;k++){
          ran[j] |= (random(255) < val) << k;
        }
      }
      uint8_t *buf = (*display).getBuffer();
      if(color){
        for(uint16_t j = 0;j < 1024;j++){
          *buf |= ran[j % len];
          buf++;
        }
      }
      else{
        for(uint16_t j = 0;j < 1024;j++){
          *buf &= ~ran[j % len];
          buf++;
        }
      }
      break;
  }
}
void draw(int8_t x, int8_t y, byte val){
  uint64_t time = millis();
  (*display).clearDisplay();
  (*display).drawBitmap(((128 - splash1_width) >> 1) + x, y, splash1_data, splash1_width, splash1_height, 1);
  filter(0, BLACK, val);
  (*display).display();
  //Serial.println(uint32_t(millis() - time));
}
void loop(){
  int8_t x = random(-32, 32);
  int8_t y = random(-8, 4);
  float i = 255;
  while(i > 0){
    uint64_t time = millis();
    draw(x, y, i);
    i -= map(float(millis() - time), 0, 1000, 0, 255);
  }
  draw(x, y, 0);
  delay(2000);
  i = 0;
  while(i < 255){
    uint64_t time = millis();
    draw(x, y, i);
    i += map(float(millis() - time), 0, 1000, 0, 255);
  }
  draw(x, y, 255);
  delay(2000);
}

agmue

Ups, habe mich in der Programm-Version vertan.
Du darfst Deine eignenen Beiträge verändern. Bitte sparsam und transparent verwenden.
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

Whandall

Gut. Was ist eigentlich der Unterschied zwischen free und delete?
delete ruft den Destructor auf, bevor es mit free den Speicher wieder freigibt.

Ebenso benutzt new malloc egfolgt von einem Konstruktor Aufruf
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

Go Up