• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
SSD1606 nie działa (black screen)
#1
Information 
Cześć jestem na finishu ukonczenia projektu i mam problem z wyswietlaczem oled ssd1306, 
Bylem przekonany że wyswietlacz jest uszkodzony zamowilem drugi to samo zamowilem tez 1,3" na innym sterowniku i tez to samo

Nie działa mi nawet na przykladowym programie "helo world" na roznych bibliotekach adafruit czy U8ug 

Podłączalem do arduino iot 33 (A4 i A5) jak i wemos esp8266 (scl sda) efekt ten sam nawet podswietlenie sie nie zapla

zasilam 3.3v jak 5V z pinow kontrolera jak i externalne 5v

Pin resetu ustawiony jest na -1 

Błąd musi byc banalny ale nie jestem w stanie dojsc do rozwiazania
 
Odpowiedź
#2
No my też nie, bo nam działa.. A z fusów nie wróżymy...
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#3
analizator saleae z Allegro i sprawdzenie czy program w ogóle coś wysyła. Nie każda biblioteka obsługuje ESP czy tym bardziej arduino iot 33. Dopasowanie poziomu napięć - oba uC są na 3V, oledy czasem są na 3.3V, czasem na 5V, użyj zwykłego UNO i sprawdź czy nie zadziała lepiej.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#4
(26-11-2021, 19:41)Jarewa0606 napisał(a): No my też nie, bo nam działa..  A z fusów nie wróżymy...
Nie zależy mi na wróżbach a na pomocy, moze ktoś się spotkał z podobnym problemem.
 
Odpowiedź
#5
(27-11-2021, 07:50)kaczakat napisał(a): analizator saleae z Allegro i sprawdzenie czy program w ogóle coś wysyła. Nie każda biblioteka obsługuje ESP czy tym bardziej arduino iot 33. Dopasowanie poziomu napięć - oba uC są na 3V, oledy czasem są na 3.3V, czasem na 5V, użyj zwykłego UNO i sprawdź czy nie zadziała lepiej.
Dziękuję na namiar co robić
Zwyklego UNO nie posiadam podpiołem pod klona nano bo tylko to mam. 
Efekt ten sam czarny wyswietlac
zasialnie z plytki 3.3V A4 i A5 piny
 
Odpowiedź
#6
(27-11-2021, 15:38)eldzi napisał(a):
(26-11-2021, 19:41)Jarewa0606 napisał(a): No my też nie, bo nam działa..  A z fusów nie wróżymy...
Nie zależy mi na wróżbach a na pomocy, moze ktoś się spotkał z podobnym problemem.


Wiesz ale chociaż minimum zaangażowania  z twojej strony by się przydało.. Zapodanie kodu który próbujesz i model wyświetlacza. Bo "oled ssd1306" mówi tylko tyle z jakim driverem a takich wyświetlaczy jest trochę i się znacząco różnią, chyba nie uważasz że 128x64 jest to samo co 128x32?? (pixele) a od strony programowej jest to bardzo duża różnica.


Ja się z tym spotkałem i przeważnie to wina złej konfiguracji wyświetlacza w programie.. 
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#7
(27-11-2021, 20:08)Jarewa0606 napisał(a):
(27-11-2021, 15:38)eldzi napisał(a):
(26-11-2021, 19:41)Jarewa0606 napisał(a): No my też nie, bo nam działa..  A z fusów nie wróżymy...
Nie zależy mi na wróżbach a na pomocy, moze ktoś się spotkał z podobnym problemem.


Wiesz ale chociaż minimum zaangażowania  z twojej strony by się przydało.. Zapodanie kodu który próbujesz i model wyświetlacza. Bo "oled ssd1306" mówi tylko tyle z jakim driverem a takich wyświetlaczy jest trochę i się znacząco różnią, chyba nie uważasz że 128x64 jest to samo co 128x32?? (pixele) a od strony programowej jest to bardzo duża różnica.






Ja się z tym spotkałem i przeważnie to wina złej konfiguracji wyświetlacza w programie.. 
Zle sie zrozumielismy nie wrzucalem kodu bo stwierdzilem ze senu nie ma wrzucania kodu z przykladu ze zmienionym jednym parametrem ale jasne wrzuce to mi zalezy na rozwiązaniu

Kod do aplikacji
Kod:
#include <FlashStorage.h>
#include <MovingAverageFilter.h>
#include <ArduinoBLE.h>
#include <Arduino_LSM6DS3.h>
#include <SPI.h>
#include <Wire.h>

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


#define SCREEN_WIDTH 128     // OLED display width, in pixels
#define SCREEN_HEIGHT 64     // OLED display height, in pixels
#define buttonUpPin 5        // For the keypad
#define buttonDownPin 6      // For the keypad
#define buttonCommonPin 7    // For the keypad
#define actuatorOutPin1 2    // To the level shifter and then to the H Bridge
#define actuatorOutPin2 3    // To the level shifter and then to the H Bridge
#define resetPin 19          // Pin linked to RST to allow software to do hard reset

// Declare our filters
MovingAverageFilter movingAverageFilter_x(9);        //
MovingAverageFilter movingAverageFilter_y(9);        // Moving average filters for the accelerometers
MovingAverageFilter movingAverageFilter_z(9);        //
MovingAverageFilter movingAverageFilter_power(8);    // 2 second power average at 4 samples per sec
MovingAverageFilter movingAverageFilter_speed(2);    // 0.5 second speed average at 4 samples per sec


// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     -1         // No reset pin on cheap OLED display
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// For incline declare some variables and set some default values

float versionNumber = 0.01;       // version
long previousMillis = 0;          // last time in ms
long weightPrevMillis = 0;        // last time for weight setting
long weightMillis = 0;            // time for weight setting
long actuatorMillis = 0;          // time for moving the actuator
float smoothRadPitch = 0;         // variable for the pitch
int incline = 0;                  // variable for the % incline (actual per accelerometers)
int gradeCalculated = 15;         // variable for the calculated grade (aim)
FlashStorage(weight_storage, int);// place to store rider weight
int riderWeight = 76;             // variable for combined rider and bike weight
int powerTrainer = 0;             // variable for the power (W) read from bluetooth
int speedTrainer = 0;             // variable for the speed (kph) read from bluetooth
float speedMpersec = 0;           // for calculation
float resistanceWatts = 0;        // for calculation
float powerMinusResistance = 0;   // for calculation
bool weightIsSet = false;         // note whether the weight setting is done
int buttonStateUp = 0;            // variable for reading the UP pushbutton status
int buttonStateDown = 0;          // variable for reading the UP pushbutton status

// For power and speed declare some variables and set some default values

int wheelCircCM = 2300;           // Wheel circumference in centimeters (700c 32 road wheel)
long WheelRevs1;                  // For speed data set 1
long Time_1;                      // For speed data set 1
long WheelRevs2;                  // For speed data set 2
long Time_2;                      // For speed data set 2
bool firstData = true;
int speedKMH;                     // Calculated speed in KM per Hr

// Custom Char Bluetooth Logo

byte customChar[] = {
  B00000,
  B00110,
  B00101,
  B10110,
  B01100,
  B10110,
  B00101,
  B00110
};

// Our BLE peripheral and characteristics

BLEDevice cablePeripheral;
BLECharacteristic speedCharacteristic;
BLECharacteristic powerCharacteristic;

///////////////////////////////// Setup ///////////////////////////////////////

void setup() {
  Serial.begin(9600);

//  riderWeight = weight_storage.read();    // Need to sort out saving the weight in the weightset method

 
  delay(2000);

//  setup control pins and set to lower trainer by default
  pinMode(actuatorOutPin1, OUTPUT);
  pinMode(actuatorOutPin2, OUTPUT);
  digitalWrite(actuatorOutPin1, LOW);
  digitalWrite(actuatorOutPin2, HIGH);

//  setup input pins for keypad and set adjacent pin to output low to act as a sink
  pinMode (buttonUpPin, INPUT_PULLUP);
  pinMode (buttonDownPin, INPUT_PULLUP);
  pinMode (buttonCommonPin, OUTPUT);
  digitalWrite (buttonCommonPin, LOW);

//   setup a pin connected to RST (A5, pin 19) to pull reset low if reset is required
  pinMode (resetPin, OUTPUT);
  digitalWrite (resetPin, HIGH);
 
  Serial.begin(9600);
  
   if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3c)) { // Address 0x3C for 128x32
   Serial.println(F("SSD1306 allocation failed"));
   resetSystem();
   }

// Show initial display buffer contents on the screen --
// the library initializes this with a splash screen (edit the splash.h in the library).

  display.setRotation(0);
  display.display();
  delay(1000);                    // Pause for 1 seconds
  display.clearDisplay();

// Show the firmware version

  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(5, 10);
  display.print(F("FW Version: "));
  display.print(versionNumber);
  display.display();
  delay(1000);                    // Pause for 2 seconds
  display.clearDisplay();


// Check that the accelerometer is up and running else reset

  if (!IMU.begin()) {
    Serial.println("Failed to initialize IMU!");
    resetSystem();
  }


  // begin BLE initialization reset if fails
  if (!BLE.begin()) {
    Serial.println("starting BLE failed!");
    resetSystem();
  }

}

////////////////////////////////  loop  ///////////////////////////////////////

void loop() {

// BLE setup begins

  while (!cablePeripheral.connected()) { 
    Serial.println("BLE Central");
    Serial.println("Turn on trainer");
     // Scan or rescan for BLE services
    
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(5, 10);
  display.print(F("BLE Scanning"));
  display.setCursor(5, 20);
  display.print(F("for CABLE Device"));
  display.display();
  display.clearDisplay();


    
    BLE.scan();

  // check if a peripheral has been discovered and allocate it
  cablePeripheral = BLE.available();

  if (cablePeripheral) {
    // discovered a peripheral, print out address, local name, and advertised service
    Serial.print("Found ");
    Serial.print(cablePeripheral.address());
    Serial.print(" '");
    Serial.print(cablePeripheral.localName());
    Serial.print("' ");
    Serial.print(cablePeripheral.advertisedServiceUuid());
    Serial.println();


    if (cablePeripheral.localName() == "QD") {
      // stop scanning
      BLE.stopScan();
      Serial.println("got CABLE device scan stopped");

      display.setTextSize(1);
      display.setTextColor(SSD1306_WHITE);
      display.setCursor(5, 10);
      display.print(F("CABLE Found"));
      display.setCursor(5, 20);
      display.print(F("Authenticating"));
      display.display();
      display.clearDisplay();


      // Do the BLE niceties and subscribe to speed and power
      getsubscribedtoSensor(cablePeripheral);
   
    }
  }
  }

  // Get any updated data
  refreshSpeedandpower();

  long currentMillis = millis();

// Call the set weight method

if (weightIsSet==false){
  weightMillis = millis();
  setWeight();

   if (weightMillis - weightPrevMillis >=5000){weightIsSet = true;}   // times up, set weight set
}


// if 100ms have passed and weight is set, check the variables and update the system
    if ((currentMillis - previousMillis >= 100) && (weightIsSet)){
    previousMillis = currentMillis;

// read the accelerometer
      findTrainerIncline();

// Calculate the incline
      calculateGrade();

// Display the current data
      lcdDisplayData();

// Update the actuator positon only if the trainer is in use and time is at least 2.5s since last move

if ((currentMillis > (actuatorMillis + 250)) &&(powerTrainer > 10) && (speedTrainer > 5))
{
  moveActuator();
    actuatorMillis = currentMillis;
}
 
}
    }  // end of loop

////////////////////////   method declarations  ///////////////////////////////

void getsubscribedtoSensor(BLEDevice cablePeripheral) {
  //   connect to the peripheral
  Serial.println("Connecting ...");
  if (cablePeripheral.connect()) {
    Serial.println("Connected");

  } else {
    Serial.println("Failed to connect to CABLE device");
    return;
  }

  // discover Cycle Speed and Cadence attributes
  Serial.println("Discovering Cycle Speed and Cadence service ...");
  if (cablePeripheral.discoverService("1816")) {
    Serial.println("Cycle Speed and Cadence Service discovered");


  } else {
    Serial.println("Cycle Speed and Cadence Attribute discovery failed.");
    cablePeripheral.disconnect();
   
    resetSystem();
    return;
  }

  // discover Cycle Power attributes
  Serial.println("Discovering Cycle Power service ...");
  if (cablePeripheral.discoverService("1818")) {
  Serial.println("Cycle Power Service discovered");


  } else {
    Serial.println("Cycle Power Attribute discovery failed.");
    cablePeripheral.disconnect();
   
    resetSystem();
    return;
  }

  // retrieve the characteristics

  speedCharacteristic = cablePeripheral.characteristic("2a5B");
  powerCharacteristic = cablePeripheral.characteristic("2a63");


  // subscribe to the characteristics (note authentication not supported on ArduinoBLE library v1.1.2)
 
  if (!speedCharacteristic.subscribe()) {
    Serial.println("can not subscribe to speed");
    }else{
    Serial.println("subscribed to speed");
    };
 
 
  if (!powerCharacteristic.subscribe()) {
  Serial.println("can not subscribe to speed and power");

  // outcome display on OLED
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(5, 10);
  display.print(F("Subscribe FAILED"));
  display.setCursor(5, 20);
  display.print(F("Speed and Power"));
  display.display();
  display.clearDisplay();

  delay(5000);
  resetSystem();
   
  } else {
  Serial.println("subscribed to speed and power");

  // outcome display on OLED
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(5, 10);
  display.print(F("Subscribed to"));
  display.setCursor(5, 20);
  display.print(F("Speed and Power"));
  display.display();
  display.clearDisplay();

  };

    //  The time consuming BLE setup is done, set timer for the weight setting routine
    weightPrevMillis = millis(); 


}

void refreshSpeedandpower(void){ 
 
// Get updated power value

if (powerCharacteristic.valueUpdated()) {

// Define an array for the value

uint8_t holdpowervalues[6] = {0,0,0,0,0,0} ;

// Read value into array

powerCharacteristic.readValue(holdpowervalues, 6);

// Power is returned as watts in location 2 and 3 (loc 0 and 1 is 8 bit flags)

byte rawpowerValue2 = holdpowervalues[2];       // power least sig byte in HEX
byte rawpowerValue3 = holdpowervalues[3];       // power most sig byte in HEX

long rawpowerTotal = (rawpowerValue2 + (rawpowerValue3 * 256));

//   Serial.print("Power: ");
//   Serial.println(rawpowerTotal);
   
// Use moving average filter to give '3s power'
    powerTrainer = movingAverageFilter_power.process(rawpowerTotal);

       Serial.print("rawpowerValue2");
       Serial.println(rawpowerValue2);
       Serial.print("rawpowerValue3");
       Serial.println(rawpowerValue3);
   
}

// Get speed - a bit more complication as the GATT specification calls for Cumulative Wheel Rotations and Time since wheel event
// So we'll need to do some maths

    if (speedCharacteristic.valueUpdated()) {

//  This value needs a 16 byte array

      uint8_t holdvalues[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} ;

//  But I'm only going to read the first 7

      speedCharacteristic.readValue(holdvalues, 7);
      byte rawValue0 = holdvalues[0];       // binary flags 8 bit int
      byte rawValue1 = holdvalues[1];       // revolutions least significant byte in HEX       
      byte rawValue2 = holdvalues[2];       // revolutions next most significant byte in HEX   
      byte rawValue3 = holdvalues[3];       // revolutions next most significant byte in HEX
      byte rawValue4 = holdvalues[4];       // revolutions most significant byte in HEX
      byte rawValue5 = holdvalues[5];       // time since last wheel event least sig byte in HEX
      byte rawValue6 = holdvalues[6];       // time since last wheel event most sig byte in HEX

      if (firstData) {
        // Get cumulative wheel revolutions as little endian hex in loc 2,3 and 4 (least significant octet first)
        WheelRevs1 = (rawValue1 + (rawValue2 * 256) + (rawValue3 * 65536) + (rawValue4 * 16777216));
        // Get time since last wheel event in 1024ths of a second
        Time_1 = (rawValue5 + (rawValue6 * 256));

        firstData = false;

      } else {

        // Get second set of data
        long WheelRevsTemp = (rawValue1 + (rawValue2 * 256) + (rawValue3 * 65536) + (rawValue4 * 16777216));
        long TimeTemp = (rawValue5 + (rawValue6 * 256));

        if (WheelRevsTemp > WheelRevs1) {           // make sure the bicycle is moving
          WheelRevs2 = WheelRevsTemp;
          Time_2 = TimeTemp;
          firstData = true;

          // Find distance difference in cm and convert to km
          float distanceTravelled = ((WheelRevs2 - WheelRevs1) * wheelCircCM);
          float kmTravelled = distanceTravelled / 1000000;

          // Find time in 1024ths of a second and convert to hours
          float timeDifference = (Time_2 - Time_1);
          float timeSecs = timeDifference / 1024;
          float timeHrs = timeSecs / 3600;

          // Find speed kmh
          speedKMH = (kmTravelled / timeHrs);

          Serial.print("  speed: ");
          Serial.println(speedKMH, DEC);


          // Reject zero values
          if (speedKMH < 0){}else{
          speedTrainer = movingAverageFilter_speed.process(speedKMH);  // use moving average filter to find 3s average speed
         // speedTrainer =  speedKMH;               // redundant step to allow experiments with filters


         
          }
        }
      }

    }
   
// we only need to do all this 4 or 5 times a second!
  delay(100);
  }

void findTrainerIncline(void){
    //Serial.print("findTrainerIncline");
       float rawx, rawy, rawz;
       float x, y, z;
 
    if (IMU.accelerationAvailable()) {
      IMU.readAcceleration(rawx, rawy, rawz);
     
      x = movingAverageFilter_x.process(rawx);      //
      y = movingAverageFilter_y.process(rawy);      //   Apply moving average filters to reduce noise
      z = movingAverageFilter_z.process(rawz);      //
     
      // find pitch in radians
      float radpitch = atan2(( x) , sqrt(y * y + z * z)) ; // equal should be modified acc. position arduino in the enclouser //eldzi

      smoothRadPitch = radpitch;

      // find the % grade from the pitch
      incline = tan(smoothRadPitch) * 100;
      Serial.print("incline=");
   Serial.println(incline);
    }}
 
void lcdDisplayData(void) {


  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);

// Display power top left

  display.setCursor(0, 0);
  display.print(powerTrainer);
  display.print(F(" W"));

// Display speed top right if more than 4kph

if(speedTrainer>4){
  display.setCursor(80, 0);
  display.print(speedTrainer);
  display.print(F(" kph"));}
  else{
  display.setCursor(80, 0);
  display.print("-- ");
  display.print(F(" kph"));
  }

// Display weight bottom left

  display.setCursor(0, 24);
  display.print(riderWeight);
  display.print(F(" kg"));

// Display target incline bottom right
if(gradeCalculated>0){
  display.setCursor(80, 24);
  display.print(gradeCalculated);
  display.print(F(" %"));}
  else{
  display.setCursor(80, 24);
  display.print(F("0 %"));}
 

//  Display current incline centred and large
  display.setTextSize(2); // Draw 2X-scale text
  display.setCursor(50, 9);
  display.print(incline);
  display.print(F("%"));

//  Update the display
  display.display();
 
  }

void moveActuator(void) {

// This method is ugly - just pausing the script while the actuator moves - there are many better ways - if only I had the time!
// That said there will be more noise whilst moving so maybe some advantage

int difference = incline-gradeCalculated;   // Find the difference
int absDifference = abs(difference);        // Find the absolute (like rms)
Serial.print("Setpoint=");
Serial.println(gradeCalculated);

if (incline>gradeCalculated){
  digitalWrite(actuatorOutPin1, LOW);                          
  digitalWrite(actuatorOutPin2, HIGH);    
  Serial.println("up");                     
  }                                    
  else if (incline<gradeCalculated){               
  digitalWrite(actuatorOutPin1, HIGH);                          
  digitalWrite(actuatorOutPin2, LOW);      
  Serial.println("down");                  
  }
 
if ((absDifference >0) && (absDifference <2)){
  delay(10);
}
if ((absDifference >=2) && (absDifference <3)){
  delay(20);
}
if ((absDifference >=3) && (absDifference <4)){
  delay(30);
}
if (absDifference >=4) {
  delay(40);
}

  digitalWrite(actuatorOutPin1, LOW);
  digitalWrite(actuatorOutPin2, LOW);


 
  }

void calculateGrade(void) {
  float speed28 = pow(speedTrainer,2.8);                                              // pow() needed to raise y^x where x is decimal
  resistanceWatts = (0.0102*speed28)+9.428;                                           // calculate power from rolling / wind resistance
  powerMinusResistance = powerTrainer - resistanceWatts;                              // find power from climbing
  speedMpersec = speedTrainer/3.6;                                                    // find speed in SI units
  gradeCalculated = ((powerMinusResistance/(riderWeight*9.8))/speedMpersec)*100;      // calculate grade of climb in %

// Sense check
if (gradeCalculated < -10){gradeCalculated = -10;}
if (gradeCalculated > 20){gradeCalculated = 20;}
  } 

void resetSystem(void){
digitalWrite (19, LOW);
  } 

void setWeight(void){

// Read the buttons
// If button state chaged then update value and reset timer

  buttonStateUp = digitalRead(buttonUpPin);
  buttonStateDown = digitalRead(buttonDownPin);

    if (buttonStateUp == LOW) {
    // turn LED on:
    riderWeight = riderWeight+1;
    delay (100);                             // low tech button debounce and limit autorepeat rate
    weightPrevMillis = weightMillis;
  }

    if (buttonStateDown == LOW) {
    // turn LED on:
    riderWeight = riderWeight-1;
    delay (100);
    weightPrevMillis = weightMillis;
  }
 
// Update the display

  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(50, 9);
  display.print(riderWeight);
  display.print(F(" Kg"));
  display.display();

 
  } 


 



Kod testowy  np


Kod:
/**************************************************************************
This is an example for our Monochrome OLEDs based on SSD1306 drivers

Pick one up today in the adafruit shop!
------> http://www.adafruit.com/category/63_98

This example is for a 128x64 pixel display using I2C to communicate
3 pins are required to interface (two I2C and one reset).

Adafruit invests time and resources providing this open
source code, please support Adafruit and open-source
hardware by purchasing products from Adafruit!

Written by Limor Fried/Ladyada for Adafruit Industries,
with contributions from the open source community.
BSD license, check license.txt for more information
All text above, and the splash screen below must be
included in any redistribution.
**************************************************************************/

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.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)
// The pins for I2C are defined by the Wire-library.
// On an arduino UNO:       A4(SDA), A5(SCL)
// On an arduino MEGA 2560: 20(SDA), 21(SCL)
// On an arduino LEONARDO:   2(SDA),  3(SCL), ...
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define NUMFLAKES     10 // Number of snowflakes in the animation example

#define LOGO_HEIGHT   16
#define LOGO_WIDTH    16
static const unsigned char PROGMEM logo_bmp[] =
{ 0b00000000, 0b11000000,
  0b00000001, 0b11000000,
  0b00000001, 0b11000000,
  0b00000011, 0b11100000,
  0b11110011, 0b11100000,
  0b11111110, 0b11111000,
  0b01111110, 0b11111111,
  0b00110011, 0b10011111,
  0b00011111, 0b11111100,
  0b00001101, 0b01110000,
  0b00011011, 0b10100000,
  0b00111111, 0b11100000,
  0b00111111, 0b11110000,
  0b01111100, 0b11110000,
  0b01110000, 0b01110000,
  0b00000000, 0b00110000 };

void setup() {
  Serial.begin(9600);

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

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  delay(2000); // Pause for 2 seconds

  // Clear the buffer
  display.clearDisplay();

  // Draw a single pixel in white
  display.drawPixel(10, 10, SSD1306_WHITE);

  // Show the display buffer on the screen. You MUST call display() after
  // drawing commands to make them visible on screen!
  display.display();
  delay(2000);
  // display.display() is NOT necessary after every single drawing command,
  // unless that's what you want...rather, you can batch up a bunch of
  // drawing operations and then update the screen all at once by calling
  // display.display(). These examples demonstrate both approaches...

  testdrawline();      // Draw many lines

  testdrawrect();      // Draw rectangles (outlines)

  testfillrect();      // Draw rectangles (filled)

  testdrawcircle();    // Draw circles (outlines)

  testfillcircle();    // Draw circles (filled)

  testdrawroundrect(); // Draw rounded rectangles (outlines)

  testfillroundrect(); // Draw rounded rectangles (filled)

  testdrawtriangle();  // Draw triangles (outlines)

  testfilltriangle();  // Draw triangles (filled)

  testdrawchar();      // Draw characters of the default font

  testdrawstyles();    // Draw 'stylized' characters

  testscrolltext();    // Draw scrolling text

  testdrawbitmap();    // Draw a small bitmap image

  // Invert and restore display, pausing in-between
  display.invertDisplay(true);
  delay(1000);
  display.invertDisplay(false);
  delay(1000);

  testanimate(logo_bmp, LOGO_WIDTH, LOGO_HEIGHT); // Animate bitmaps
}

void loop() {
}

void testdrawline() {
  int16_t i;

  display.clearDisplay(); // Clear display buffer

  for(i=0; i<display.width(); i+=4) {
    display.drawLine(0, 0, i, display.height()-1, SSD1306_WHITE);
    display.display(); // Update screen with each newly-drawn line
    delay(1);
  }
  for(i=0; i<display.height(); i+=4) {
    display.drawLine(0, 0, display.width()-1, i, SSD1306_WHITE);
    display.display();
    delay(1);
  }
  delay(250);

  display.clearDisplay();

  for(i=0; i<display.width(); i+=4) {
    display.drawLine(0, display.height()-1, i, 0, SSD1306_WHITE);
    display.display();
    delay(1);
  }
  for(i=display.height()-1; i>=0; i-=4) {
    display.drawLine(0, display.height()-1, display.width()-1, i, SSD1306_WHITE);
    display.display();
    delay(1);
  }
  delay(250);

  display.clearDisplay();

  for(i=display.width()-1; i>=0; i-=4) {
    display.drawLine(display.width()-1, display.height()-1, i, 0, SSD1306_WHITE);
    display.display();
    delay(1);
  }
  for(i=display.height()-1; i>=0; i-=4) {
    display.drawLine(display.width()-1, display.height()-1, 0, i, SSD1306_WHITE);
    display.display();
    delay(1);
  }
  delay(250);

  display.clearDisplay();

  for(i=0; i<display.height(); i+=4) {
    display.drawLine(display.width()-1, 0, 0, i, SSD1306_WHITE);
    display.display();
    delay(1);
  }
  for(i=0; i<display.width(); i+=4) {
    display.drawLine(display.width()-1, 0, i, display.height()-1, SSD1306_WHITE);
    display.display();
    delay(1);
  }

  delay(2000); // Pause for 2 seconds
}

void testdrawrect(void) {
  display.clearDisplay();

  for(int16_t i=0; i<display.height()/2; i+=2) {
    display.drawRect(i, i, display.width()-2*i, display.height()-2*i, SSD1306_WHITE);
    display.display(); // Update screen with each newly-drawn rectangle
    delay(1);
  }

  delay(2000);
}

void testfillrect(void) {
  display.clearDisplay();

  for(int16_t i=0; i<display.height()/2; i+=3) {
    // The INVERSE color is used so rectangles alternate white/black
    display.fillRect(i, i, display.width()-i*2, display.height()-i*2, SSD1306_INVERSE);
    display.display(); // Update screen with each newly-drawn rectangle
    delay(1);
  }

  delay(2000);
}

void testdrawcircle(void) {
  display.clearDisplay();

  for(int16_t i=0; i<max(display.width(),display.height())/2; i+=2) {
    display.drawCircle(display.width()/2, display.height()/2, i, SSD1306_WHITE);
    display.display();
    delay(1);
  }

  delay(2000);
}

void testfillcircle(void) {
  display.clearDisplay();

  for(int16_t i=max(display.width(),display.height())/2; i>0; i-=3) {
    // The INVERSE color is used so circles alternate white/black
    display.fillCircle(display.width() / 2, display.height() / 2, i, SSD1306_INVERSE);
    display.display(); // Update screen with each newly-drawn circle
    delay(1);
  }

  delay(2000);
}

void testdrawroundrect(void) {
  display.clearDisplay();

  for(int16_t i=0; i<display.height()/2-2; i+=2) {
    display.drawRoundRect(i, i, display.width()-2*i, display.height()-2*i,
      display.height()/4, SSD1306_WHITE);
    display.display();
    delay(1);
  }

  delay(2000);
}

void testfillroundrect(void) {
  display.clearDisplay();

  for(int16_t i=0; i<display.height()/2-2; i+=2) {
    // The INVERSE color is used so round-rects alternate white/black
    display.fillRoundRect(i, i, display.width()-2*i, display.height()-2*i,
      display.height()/4, SSD1306_INVERSE);
    display.display();
    delay(1);
  }

  delay(2000);
}

void testdrawtriangle(void) {
  display.clearDisplay();

  for(int16_t i=0; i<max(display.width(),display.height())/2; i+=5) {
    display.drawTriangle(
      display.width()/2  , display.height()/2-i,
      display.width()/2-i, display.height()/2+i,
      display.width()/2+i, display.height()/2+i, SSD1306_WHITE);
    display.display();
    delay(1);
  }

  delay(2000);
}

void testfilltriangle(void) {
  display.clearDisplay();

  for(int16_t i=max(display.width(),display.height())/2; i>0; i-=5) {
    // The INVERSE color is used so triangles alternate white/black
    display.fillTriangle(
      display.width()/2  , display.height()/2-i,
      display.width()/2-i, display.height()/2+i,
      display.width()/2+i, display.height()/2+i, SSD1306_INVERSE);
    display.display();
    delay(1);
  }

  delay(2000);
}

void testdrawchar(void) {
  display.clearDisplay();

  display.setTextSize(1);      // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE); // Draw white text
  display.setCursor(0, 0);     // Start at top-left corner
  display.cp437(true);         // Use full 256 char 'Code Page 437' font

  // Not all the characters will fit on the display. This is normal.
  // Library will draw what it can and the rest will be clipped.
  for(int16_t i=0; i<256; i++) {
    if(i == '\n') display.write(' ');
    else          display.write(i);
  }

  display.display();
  delay(2000);
}

void testdrawstyles(void) {
  display.clearDisplay();

  display.setTextSize(1);             // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE);        // Draw white text
  display.setCursor(0,0);             // Start at top-left corner
  display.println(F("Hello, world!"));

  display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); // Draw 'inverse' text
  display.println(3.141592);

  display.setTextSize(2);             // Draw 2X-scale text
  display.setTextColor(SSD1306_WHITE);
  display.print(F("0x")); display.println(0xDEADBEEF, HEX);

  display.display();
  delay(2000);
}

void testscrolltext(void) {
  display.clearDisplay();

  display.setTextSize(2); // Draw 2X-scale text
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(10, 0);
  display.println(F("scroll"));
  display.display();      // Show initial text
  delay(100);

  // Scroll in various directions, pausing in-between:
  display.startscrollright(0x00, 0x0F);
  delay(2000);
  display.stopscroll();
  delay(1000);
  display.startscrollleft(0x00, 0x0F);
  delay(2000);
  display.stopscroll();
  delay(1000);
  display.startscrolldiagright(0x00, 0x07);
  delay(2000);
  display.startscrolldiagleft(0x00, 0x07);
  delay(2000);
  display.stopscroll();
  delay(1000);
}

void testdrawbitmap(void) {
  display.clearDisplay();

  display.drawBitmap(
    (display.width()  - LOGO_WIDTH ) / 2,
    (display.height() - LOGO_HEIGHT) / 2,
    logo_bmp, LOGO_WIDTH, LOGO_HEIGHT, 1);
  display.display();
  delay(1000);
}

#define XPOS   0 // Indexes into the 'icons' array in function below
#define YPOS   1
#define DELTAY 2

void testanimate(const uint8_t *bitmap, uint8_t w, uint8_t h) {
  int8_t f, icons[NUMFLAKES][3];

  // Initialize 'snowflake' positions
  for(f=0; f< NUMFLAKES; f++) {
    icons[f][XPOS]   = random(1 - LOGO_WIDTH, display.width());
    icons[f][YPOS]   = -LOGO_HEIGHT;
    icons[f][DELTAY] = random(1, 6);
    Serial.print(F("x: "));
    Serial.print(icons[f][XPOS], DEC);
    Serial.print(F(" y: "));
    Serial.print(icons[f][YPOS], DEC);
    Serial.print(F(" dy: "));
    Serial.println(icons[f][DELTAY], DEC);
  }

  for(;;) { // Loop forever...
    display.clearDisplay(); // Clear the display buffer

    // Draw each snowflake:
    for(f=0; f< NUMFLAKES; f++) {
      display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, SSD1306_WHITE);
    }

    display.display(); // Show the display buffer on the screen
    delay(200);        // Pause for 1/10 second

    // Then update coordinates of each flake...
    for(f=0; f< NUMFLAKES; f++) {
      icons[f][YPOS] += icons[f][DELTAY];
      // If snowflake is off the bottom of the screen...
      if (icons[f][YPOS] >= display.height()) {
        // Reinitialize to a random position, just off the top
        icons[f][XPOS]   = random(1 - LOGO_WIDTH, display.width());
        icons[f][YPOS]   = -LOGO_HEIGHT;
        icons[f][DELTAY] = random(1, 6);
      }
    }
  }
}


Załączone pliki Miniatury
       
 
Odpowiedź
#8
Jednak używaj zwykłego klona i najmniej rzeczy które mogą interferować dopóki nie wiesz czy na pewno działa.
W kodzie masz #define SCREEN_ADDRESS 0x3C a na obrazku pokazujesz coś innego. Użyj szkicu - skaner I2C i ustal faktyczne adresy jeśli nie ma ich na ekranach lub są nieczytelne, jak nie znajdzie żadnego urządzenia to też informacja, że coś nie działa, jest uszkodzone, albo coś nie tak na liniach komunikacji. Tu się przydaje też ten analizator logiczny, podpinasz i widzisz, czy coś się dzieje na tych liniach komunikacyjnych.
Kod:
/**
* I2CScanner.ino -- I2C bus scanner for Arduino
*
* 2009,2014, Tod E. Kurt, http://todbot.com/blog/
*
*/

#include "Wire.h"
extern "C" {
#include "utility/twi.h"  // from Wire library, so we can do bus scanning
}

// Scan the I2C bus between addresses from_addr and to_addr.
// On each address, call the callback function with the address and result.
// If result==0, address was found, otherwise, address wasn't found
// (can use result to potentially get other status on the I2C bus, see twi.c)
// Assumes Wire.begin() has already been called
void scanI2CBus(byte from_addr, byte to_addr,
                void(*callback)(byte address, byte result) )
{
  byte rc;
  byte data = 0; // not used, just an address to feed to twi_writeTo()
  for( byte addr = from_addr; addr <= to_addr; addr++ ) {
    rc = twi_writeTo(addr, &data, 0, 1, 0);
    callback( addr, rc );
  }
}

// Called when address is found in scanI2CBus()
// Feel free to change this as needed
// (like adding I2C comm code to figure out what kind of I2C device is there)
void scanFunc( byte addr, byte result ) {
  Serial.print("addr: ");
 
  Serial.print(addr,DEC);
  Serial.print(", hex: ");
  Serial.print(addr,HEX);
  Serial.print( (result==0) ? " found!":"       ");
  Serial.print( (addr%4) ? "\t":"\n");
}


byte start_address = 8;       // lower addresses are reserved to prevent conflicts with other protocols
byte end_address = 119;       // higher addresses unlock other modes, like 10-bit addressing

// standard Arduino setup()
void setup()
{
    Wire.begin();

    Serial.begin(115200);                   // Changed from 19200 to 9600 which seems to be default for Arduino serial monitor
    Serial.println("\nI2CScanner ready!");

    Serial.print("starting scanning of I2C bus from ");
    Serial.print(start_address,DEC);
    Serial.print(" to ");
    Serial.print(end_address,DEC);
    Serial.println("...");

    // start the scan, will call "scanFunc()" on result from each address
    scanI2CBus( start_address, end_address, scanFunc );

    Serial.println("\ndone");
   
    // Set pin mode so the loop code works ( Not required for the functionality)
    pinMode(13, OUTPUT);
}

// standard Arduino loop()
void loop()
{
    // Nothing to do here, so we'll just blink the built-in LED
    digitalWrite(13,HIGH);
    delay(300);
    digitalWrite(13,LOW);
    delay(300);
}
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#9
(28-11-2021, 21:37)kaczakat napisał(a): Jednak używaj zwykłego klona i najmniej rzeczy które mogą interferować dopóki nie wiesz czy na pewno działa.
W kodzie masz #define SCREEN_ADDRESS 0x3C a na obrazku pokazujesz coś innego. Użyj szkicu - skaner I2C i ustal faktyczne adresy jeśli nie ma ich na ekranach lub są nieczytelne, jak nie znajdzie żadnego urządzenia to też informacja, że coś nie działa, jest uszkodzone, albo coś nie tak na liniach komunikacji. Tu się przydaje też ten analizator logiczny, podpinasz i widzisz, czy coś się dzieje na tych liniach komunikacyjnych.
Kod:
/**
* I2CScanner.ino -- I2C bus scanner for Arduino
*
* 2009,2014, Tod E. Kurt, http://todbot.com/blog/
*
*/

#include "Wire.h"
extern "C" {
#include "utility/twi.h"  // from Wire library, so we can do bus scanning
}

// Scan the I2C bus between addresses from_addr and to_addr.
// On each address, call the callback function with the address and result.
// If result==0, address was found, otherwise, address wasn't found
// (can use result to potentially get other status on the I2C bus, see twi.c)
// Assumes Wire.begin() has already been called
void scanI2CBus(byte from_addr, byte to_addr,
                void(*callback)(byte address, byte result) )
{
  byte rc;
  byte data = 0; // not used, just an address to feed to twi_writeTo()
  for( byte addr = from_addr; addr <= to_addr; addr++ ) {
    rc = twi_writeTo(addr, &data, 0, 1, 0);
    callback( addr, rc );
  }
}

// Called when address is found in scanI2CBus()
// Feel free to change this as needed
// (like adding I2C comm code to figure out what kind of I2C device is there)
void scanFunc( byte addr, byte result ) {
  Serial.print("addr: ");
 
  Serial.print(addr,DEC);
  Serial.print(", hex: ");
  Serial.print(addr,HEX);
  Serial.print( (result==0) ? " found!":"       ");
  Serial.print( (addr%4) ? "\t":"\n");
}


byte start_address = 8;       // lower addresses are reserved to prevent conflicts with other protocols
byte end_address = 119;       // higher addresses unlock other modes, like 10-bit addressing

// standard Arduino setup()
void setup()
{
    Wire.begin();

    Serial.begin(115200);                   // Changed from 19200 to 9600 which seems to be default for Arduino serial monitor
    Serial.println("\nI2CScanner ready!");

    Serial.print("starting scanning of I2C bus from ");
    Serial.print(start_address,DEC);
    Serial.print(" to ");
    Serial.print(end_address,DEC);
    Serial.println("...");

    // start the scan, will call "scanFunc()" on result from each address
    scanI2CBus( start_address, end_address, scanFunc );

    Serial.println("\ndone");
   
    // Set pin mode so the loop code works ( Not required for the functionality)
    pinMode(13, OUTPUT);
}

// standard Arduino loop()
void loop()
{
    // Nothing to do here, so we'll just blink the built-in LED
    digitalWrite(13,HIGH);
    delay(300);
    digitalWrite(13,LOW);
    delay(300);
}
testowalem skanerem i adres 3C wychodzi.
jutro od kolegi bede mial uno oryginalne do testow
skaner stanow logicznych zamowilem jak i kolejny inaczej wygladajacy wyswketlacz.
 
Odpowiedź
#10
To warto pisać co zrobiłeś i co sprawdziłeś, UNO oryginalne czy klon NANO nie ma znaczenia. Są też inne biblioteki, niektórzy sprzedają sh1106 jako 1306.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości