Oled-1.3 Sh1106-не отображает информацию.

Seling
Offline
Зарегистрирован: 29.07.2018

Здравствуйте, помогите пожалуйста разобраться. Собрал на макетной плате "метеостанцию" на ESP-01 и Oled-1.3 Sh1106 загрузил скетч , все подключил а экран ничего не отображает.Esp-01 подключается к точке доступа телефона.Oled рабочий проверял на другом скетче.

Подключил вроде правильно -

Esp-VCC-3.3 , 

GPIO0 -SDA ,

GPIO2 -SCL ,

CH_PD - Vcc.



/**The MIT License (MIT)

Copyright (c) 2015 by Daniel Eichhorn

Changed/updated by:

Main changes are

1) Driver for OLED changed to SH1106

2) Some more data fields added to the Weather

3) Commented out "Thingspeak" function

4) Added a shutown timer (and a reset/wake button)

5) Added a shaker vibration switch to toggle weather location

Copyright (c) 2017 by Simon Jowett

Permission is hereby granted, free of charge, to any person obtaining a copy

of this software and associated documentation files (the "Software"), to deal

in the Software without restriction, including without limitation the rights

to use, copy, modify, merge, publish, distribute, sublicense, and/or sell

copies of the Software, and to permit persons to whom the Software is

furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all

copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE

AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE

SOFTWARE.

See more at Squix – TechBlog

*/

#include <Ticker.h>

#include <JsonListener.h>

#include "SH1106.h"

#include "SH1106Ui.h"

#include "Wire.h"

#include <ESP8266WiFi.h>

#include "WundergroundClient.h"

#include "WeatherStationFonts.h"

#include "WeatherStationImages.h"

#include "TimeClient.h"

//#include "ThingspeakClient.h"

#include "DHT.h"

/***************************

* Begin Settings

**************************/

// WIFI

const char* WIFI_SSID = "AndroidAP";

const char* WIFI_PWD = "1988000088";

// Setup

const int UPDATE_INTERVAL_SECS = 10 * 60; // Update every 10 minutes

// Display Settings

const int I2C_DISPLAY_ADDRESS = 0x3d;

const int SDA_PIN = 12;

const int SDC_PIN = 13;

// TimeClient settings

const float UTC_OFFSET = 0;

float utcoh = 0;

// Wunderground Settings

const boolean IS_METRIC = true;

const String WUNDERGRROUND_API_KEY = "86d9b7fd1bd1d096e1a01cb429117558";

String WUNDERGROUND_COUNTRY = "UK";

String WUNDERGROUND_CITY = "Leeds_Bradford";

// NB!!! - if the city has a 'space' in it ie Cape Town, use an underscore _

const String city1 = "Leeds_Bradford";

const String country1 = "UK";

const String city2 = "Sydney";

const String country2 = "AU";

//Thingspeak Settings

//const String THINGSPEAK_CHANNEL_ID = "67284";

//const String THINGSPEAK_API_READ_KEY = "L2VIW20QVNZJBLAK";

// Initialize the oled display for address 0x3c or 0x3d

// sda-pin and sdc-pin

SH1106 display(I2C_DISPLAY_ADDRESS, SDA_PIN, SDC_PIN);

SH1106Ui ui ( &display );

// DHT Settings

#define DHTPIN 14 // what digital pin we're connected to.

// Uncomment whatever type you're using!

//#define DHTTYPE DHT11 // DHT 11

#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321

//#define DHTTYPE DHT21 // DHT 21 (AM2301)

#define shakerPin 5 // what digital pin the shaker switch is connect to

volatile int state = LOW; // Volatile to toggls low to high and back when vibration sensor is shaken

int currState = state; // variable to compare to see if the state has changed

volatile long lastVibration = millis(); // required to debounce the shaker.

unsigned long timerSleep = 0; // timer for esp8266 shutdown

/***************************

* End Settings

**************************/

Seling
Offline
Зарегистрирован: 29.07.2018

Seling
Offline
Зарегистрирован: 29.07.2018

Seling
Offline
Зарегистрирован: 29.07.2018

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

А в какой строке, по-вашему, он должен что-то отображать?

nikolaki
nikolaki аватар
Offline
Зарегистрирован: 14.02.2013

В Етой? - "Copyright (c) 2017 by Simon Jowett"

 

Seling
Offline
Зарегистрирован: 29.07.2018
// Display Settings
const int I2C_DISPLAY_ADDRESS = 0x3d;
const int SDA_PIN = 12;
const int SDC_PIN = 13;
 
также менял 0x3d на 0x3с не помогло.
b707
Offline
Зарегистрирован: 26.05.2017

Seling, у вас на дисплей ничего и не должно выводится.  В вашем коде нет ни одной строчки, где хоть что-то выводилось бы на дисплей.

Вообще, такое впечатление, что вы запостили не весь код. Вы что, ничего  не понимаете в программировании?

Seling
Offline
Зарегистрирован: 29.07.2018

я извиняюсь, что ввожу вас в заблуждение: код просто не весь влез в сообщение и помимо есть ещё 11 вкладок. Проект взял отсюда https://www.instructables.com/id/Minitaure-Weather-Station-ESP8266/  Немного, только учусь.

 

Seling
Offline
Зарегистрирован: 29.07.2018

b707
Offline
Зарегистрирован: 26.05.2017

Seling, вставляйте скетч целиком, но только делайте это правильно, в виде кода - красная иконка над окошком ввода сообщения. Тогда код влезет.

И не надо постить "слепые" скриншоты - их никто разглядывать не будет.

Seling
Offline
Зарегистрирован: 29.07.2018
#include <Ticker.h>
#include <JsonListener.h>
#include "SH1106.h"
#include "SH1106Ui.h"
#include "Wire.h"
#include <ESP8266WiFi.h>
#include "WundergroundClient.h"
#include "WeatherStationFonts.h"
#include "WeatherStationImages.h"
#include "TimeClient.h"
//#include "ThingspeakClient.h"
#include "DHT.h"




/***************************
 * Begin Settings
 **************************/

// WIFI
const char* WIFI_SSID = "AndroidAP";
const char* WIFI_PWD = "1988000088";


// Setup
const int UPDATE_INTERVAL_SECS = 10 * 60; // Update every 10 minutes

// Display Settings
const int I2C_DISPLAY_ADDRESS = 0x3d;
const int SDA_PIN = 12;
const int SDC_PIN = 13;

// TimeClient settings
const float UTC_OFFSET = 0;
float utcoh = 0;

// Wunderground Settings
const boolean IS_METRIC = true;
const String WUNDERGRROUND_API_KEY = "86d9b7fd1bd1d096e1a01cb429117558";
String WUNDERGROUND_COUNTRY = "UK";
String WUNDERGROUND_CITY = "Leeds_Bradford";

// NB!!! - if the city has a 'space' in it ie Cape Town, use an underscore _
const String city1 = "Leeds_Bradford";
const String country1 = "UK";

const String city2 = "Sydney";
const String country2 = "AU";

//Thingspeak Settings
//const String THINGSPEAK_CHANNEL_ID = "67284";
//const String THINGSPEAK_API_READ_KEY = "L2VIW20QVNZJBLAK";

// Initialize the oled display for address 0x3c or 0x3d
// sda-pin and sdc-pin
SH1106   display(I2C_DISPLAY_ADDRESS, SDA_PIN, SDC_PIN);
SH1106Ui ui     ( &display );

// DHT Settings
#define DHTPIN 14     // what digital pin we're connected to.

// Uncomment whatever type you're using!
//#define DHTTYPE DHT11   // DHT 11
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

#define shakerPin 5         // what digital pin the shaker switch is connect to
volatile int state = LOW;   // Volatile to toggls low to high and back when vibration sensor is shaken
int currState = state;      // variable to compare to see if the state has changed
volatile long lastVibration = millis(); // required to debounce the shaker.

unsigned long timerSleep = 0; // timer for esp8266 shutdown

/***************************
 * End Settings
 **************************/

TimeClient timeClient(UTC_OFFSET);

// Set to false, if you prefere imperial/inches, Fahrenheit
WundergroundClient wunderground(IS_METRIC);

//ThingspeakClient thingspeak;

// Initialize the temperature/ humidity sensor
DHT dht(DHTPIN, DHTTYPE);

// this array keeps function pointers to all frames
// frames are the single views that slide from right to left
bool (*frames[])(SH1106 *display, SH1106UiState* state, int x, int y)  { drawFrame1, drawFrame2, drawFrame3, drawFrame4, drawFrame6 };
int numberOfFrames = 5;

// flag changed in the ticker function every 10 minutes
bool readyForWeatherUpdate = true;

String lastUpdate = "--";

float humidity = 0.;
float temperature = 0.;

Ticker ticker;

void setup() {

  Serial.begin(115200);
  Serial.println();
  Serial.println();

  // initialize dispaly
  display.init();
  display.clear();
  display.display();

  display.flipScreenVertically();
  display.setFont(ArialMT_Plain_10);
  display.setTextAlignment(TEXT_ALIGN_CENTER);
  display.setContrast(255);

  wificonnect();

  ui.setTargetFPS(30);

  ui.setActiveSymbole(activeSymbole);
  ui.setInactiveSymbole(inactiveSymbole);

  // You can change this to
  // TOP, LEFT, BOTTOM, RIGHT
  ui.setIndicatorPosition(BOTTOM);

  // Defines where the first frame is located in the bar.
  ui.setIndicatorDirection(LEFT_RIGHT);

  // You can change the transition that is used
  // SLIDE_LEFT, SLIDE_RIGHT, SLIDE_TOP, SLIDE_DOWN
  ui.setFrameAnimation(SLIDE_LEFT);

  // Add frames
  ui.setFrames(frames, numberOfFrames);

  // Inital UI takes care of initalising the display too.
  ui.init();
  display.flipScreenVertically();

  Serial.println("");

 // updateData(&display);

  ticker.attach(UPDATE_INTERVAL_SECS, setReadyForWeatherUpdate);
  
  pinMode(shakerPin, INPUT_PULLUP);             // Vibration sensor input 
  attachInterrupt(shakerPin, shaker, FALLING);  // Set an inturrupt that will toggle the city location when the vibration switch is shaken
}

void loop() {

  if (readyForWeatherUpdate && ui.getUiState().frameState == FIXED) {
    if (WiFi.status() != WL_CONNECTED) {
      wificonnect();
    }
    if (WiFi.status() == WL_CONNECTED){
      updateData(&display);
    }
  }

  int remainingTimeBudget = ui.update();

  if (remainingTimeBudget > 0) {
    // You can do some work here
    // Don't do stuff if you are below your
    // time budget.
    //read the pushbutton value into a variable

    delay(remainingTimeBudget);
  }

    if (state != currState) {
      Serial.println(state);
      currState = state;
      changecity();
  }

   // Shutdown and go to sleep function
  
  timerSleep = millis();
  if (timerSleep >= 10*60000 && ui.getUiState().frameState == FIXED){ // after 2 minutes go to sleep
    drawSleep(&display);
        // go to deepsleep for xx minutes or 0 = permanently
        ESP.deepSleep(0,  WAKE_RF_DEFAULT);                       // 0 delay = permanently to sleep
        delay(1000);                                              // delay to allow the ESP to go to sleep.
  }
}

void updateData(SH1106 *display) {


  drawProgress(display, 10, "Updating conditions...");
  wunderground.updateConditions(WUNDERGRROUND_API_KEY, WUNDERGROUND_COUNTRY, WUNDERGROUND_CITY);

  drawProgress(display, 30, "Updating forecasts...");
  wunderground.updateForecast(WUNDERGRROUND_API_KEY, WUNDERGROUND_COUNTRY, WUNDERGROUND_CITY);

  //drawProgress(display, 50, "Updating thingspeak...");
  //thingspeak.getLastChannelItem(THINGSPEAK_CHANNEL_ID, THINGSPEAK_API_READ_KEY);
  //lastUpdate = timeClient.getFormattedTime();

  setUTCOffset();

  drawProgress(display, 80, "Updating time...");
  timeClient.updateTime();

  drawProgress(display, 90, "Updating local temperature and humidity");
  humidity = dht.readHumidity();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  temperature = dht.readTemperature(!IS_METRIC);
  drawProgress(display, 100, "Done...");
  readyForWeatherUpdate = false;
  delay(1000);


}

void drawProgress(SH1106 *display, int percentage, String label) {
  display->clear();
  display->setTextAlignment(TEXT_ALIGN_CENTER);
  display->setFont(ArialMT_Plain_10);
  display->drawString(64, 0, "Getting data for " + WUNDERGROUND_CITY);
  display->drawString(64, 10, label);
  display->drawRect(10, 28, 108, 12);
  display->fillRect(12, 30, 104 * percentage / 100 , 9);
  display->display();
}


bool drawFrame1(SH1106 *display, SH1106UiState* state, int x, int y) {
  display->setTextAlignment(TEXT_ALIGN_CENTER);
  display->setFont(ArialMT_Plain_10);
  display->drawString(64 + x, 0 + y, "Time in " + WUNDERGROUND_CITY);
  String date = wunderground.getDate();
  int textWidth = display->getStringWidth(date);
  display->drawString(64 + x, 10 + y, date);
  display->setFont(ArialMT_Plain_24);
  String time = timeClient.getFormattedTime();
  int timehour = time.substring(0, 2).toInt();
  // Serial.println(timehour);
  timehour = timehour + utcoh;
  if (timehour >= 24 ) { // remove 24 hrs if hours is > 24
    timehour = timehour - 24;
  }
  // Serial.println(timehour);
  String timeh = String(timehour);
  if (timehour < 10 ) { // add a leading zero if the hours is less thsn 10
    timeh = "0" + timeh;
  }

  // Serial.println(timeh);
  textWidth = display->getStringWidth(time);
  display->drawString(64 + x, 20 + y, timeh + ":" + time.substring(3));
  display->setTextAlignment(TEXT_ALIGN_LEFT);

}

bool drawFrame2(SH1106 *display, SH1106UiState* state, int x, int y) {
  display->setFont(ArialMT_Plain_10);
  display->drawString(49 + x, 10 + y, wunderground.getWeatherText());

  display->setFont(ArialMT_Plain_24);
  String temp = wunderground.getCurrentTemp() + "°C";
  display->drawString(49 + x, 20 + y, temp);
  int tempWidth = display->getStringWidth(temp);

  display->setFont(Meteocons_0_42);
  String weatherIcon = wunderground.getTodayIcon();
  int weatherIconWidth = display->getStringWidth(weatherIcon);
  display->drawString(25 + x - weatherIconWidth / 2, 10 + y, weatherIcon);
}

bool drawFrame3(SH1106 *display, SH1106UiState* state, int x, int y) {
  display->setTextAlignment(TEXT_ALIGN_CENTER);
  display->setFont(ArialMT_Plain_10);
  display->drawString(32 + x, 0 + y, "Humidity");
  display->drawString(96 + x, 0 + y, "Pressure");
  display->drawString(32 + x, 28 + y, "Precipit.");
  display->drawString(96 + x, 28 + y, "UV index");

  display->setFont(ArialMT_Plain_16);
  display->drawString(32 + x, 10 + y, wunderground.getHumidity());
  display->drawString(96 + x, 10 + y, wunderground.getPressure());
  display->drawString(32 + x, 38 + y, wunderground.getPrecipitationToday());
  display->drawString(96 + x, 38 + y, wunderground.getUv());
}

bool drawFrame4(SH1106 *display, SH1106UiState* state, int x, int y) {
  drawForecast(display, x, y, 0);
  drawForecast(display, x + 44, y, 2);
  drawForecast(display, x + 88, y, 4);
}
/*
bool drawFrame5(SH1106 *display, SH1106UiState* state, int x, int y) {
  display->setTextAlignment(TEXT_ALIGN_CENTER);
  display->setFont(ArialMT_Plain_10);
  display->drawString(64 + x, 0 + y, "Outdoor");
  display->setFont(ArialMT_Plain_24);
  display->drawString(64 + x, 10 + y, thingspeak.getFieldValue(0) + "°C");
  display->drawString(64 + x, 30 + y, thingspeak.getFieldValue(1) + "%");
}
*/
bool drawFrame6(SH1106 *display, SH1106UiState* state, int x, int y) {
  display->setTextAlignment(TEXT_ALIGN_CENTER);
  display->setFont(ArialMT_Plain_10);
  display->drawString(64 + x, 0 + y, "Indoor");
  display->setFont(ArialMT_Plain_24);
  display->drawString(64 + x, 10 + y, String(temperature) + "°C");
  display->drawString(64 + x, 30 + y, String(humidity) + "%");
}

void drawForecast(SH1106 *display, int x, int y, int dayIndex) {
  display->setTextAlignment(TEXT_ALIGN_CENTER);
  display->setFont(ArialMT_Plain_10);
  String day = wunderground.getForecastTitle(dayIndex).substring(0, 3);
  day.toUpperCase();
  display->drawString(x + 20, y, day);

  display->setFont(Meteocons_0_21);
  display->drawString(x + 20, y + 15, wunderground.getForecastIcon(dayIndex));

  display->setFont(ArialMT_Plain_16);
  display->drawString(x + 20, y + 37, wunderground.getForecastLowTemp(dayIndex) + "/" + wunderground.getForecastHighTemp(dayIndex));
  //display.drawString(x + 20, y + 51, );
  display->setTextAlignment(TEXT_ALIGN_LEFT);
}
void drawSleep(SH1106 *display) {

        display->clear();
        display->setTextAlignment(TEXT_ALIGN_CENTER);
        display->setFont(ArialMT_Plain_10);
        display->drawString(64, 0, "Going to Sleep!");
        display->display();
        delay(5000);
        display->displayOff();
        Serial.println();
        Serial.println("closing connection. going to sleep...");
        delay(1000);
        timerSleep = 0;


}

void setReadyForWeatherUpdate() {
  Serial.println("Setting readyForUpdate to true");
  readyForWeatherUpdate = true;
}

void setUTCOffset() {
  String currUTCOffset = wunderground.getCurrUTCOffset();
  String currUTCOffsetSign = wunderground.getCurrUTCOffsetSign();
  Serial.print ("UTC Offset = ");
  Serial.println (currUTCOffset);
  Serial.print ("UTC Offset Sign = ");
  Serial.println (currUTCOffsetSign);
  utcoh = currUTCOffset.substring(0, 2).toInt();
  float utcom = currUTCOffset.substring(2, 4).toInt();
  if (currUTCOffsetSign == "-") {
    utcoh = utcoh * -1;
  }
  Serial.println (utcoh);  // number of hours offest from UTC
  Serial.println (utcom);   // number of minutes offset from utc (to capture the 30 minute time zones)
}

void shaker(){
  long timeNow = millis();

  if (timeNow - lastVibration > 10000){
  state=!state;
}
  lastVibration = timeNow;
}

void changecity(){
  // toggle city

  if (WiFi.status() != WL_CONNECTED)  {
    Serial.println("unable to toggle city data as wifi not connected");
    display.clear();
    display.setFont(ArialMT_Plain_10);
    display.setTextAlignment(TEXT_ALIGN_CENTER);
    display.drawString(60, 10, "Unable to toggle city as");
    display.drawString(60, 20, "WiFi not connected");
    display.display();
    delay (6000);
    wificonnect();
  }
  else{
    if ( WUNDERGROUND_CITY == city1){
      WUNDERGROUND_CITY = city2;
      WUNDERGROUND_COUNTRY = country2;
    }
    else{
      WUNDERGROUND_CITY = city1;
      WUNDERGROUND_COUNTRY = country1;
    }
   readyForWeatherUpdate = true;
   Serial.println("Toggled city to " + WUNDERGROUND_CITY);
  }
}

void wificonnect(){

  WiFi.begin(WIFI_SSID, WIFI_PWD);
  long timer = millis(); // only search for a wifi for 30 seconds - stop burn in on OLED
  int counter = 0;
  while (WiFi.status() != WL_CONNECTED && timer+10000 > millis()) {
    delay(500);
    Serial.print(".");
    display.clear();
    display.setFont(ArialMT_Plain_10);
    display.setTextAlignment(TEXT_ALIGN_CENTER);
    display.drawString(64, 10, "Connecting to WiFi");
    display.drawXbm(46, 30, 8, 8, counter % 3 == 0 ? activeSymbole : inactiveSymbole);
    display.drawXbm(60, 30, 8, 8, counter % 3 == 1 ? activeSymbole : inactiveSymbole);
    display.drawXbm(74, 30, 8, 8, counter % 3 == 2 ? activeSymbole : inactiveSymbole);
    display.display();

    counter++;
  }
  if (timer + 10000 < millis()){
    
    Serial.println();
    Serial.println("Connecting to wifi failed - continuing with old data");
    display.clear();
    display.setFont(ArialMT_Plain_10);
    display.setTextAlignment(TEXT_ALIGN_CENTER);
    display.drawString(60, 10, "Connection to WiFi failed");
    display.drawString(60, 20, "Try again in 10mins");
    display.drawString(60, 30, "Continue with old data");
    display.display();
    delay (6000);
    readyForWeatherUpdate = false;
   }
}

 

Seling
Offline
Зарегистрирован: 29.07.2018
Credits for parts of this code go to Mike Rankin. Thank you so much for sharing!
*/

#include "SH1106.h"
#include <Wire.h>


SH1106::SH1106(int i2cAddress, int sda, int sdc) {
  myI2cAddress = i2cAddress;
  mySda = sda;
  mySdc = sdc;
}

void SH1106::init() {
  Wire.begin(mySda, mySdc);
  Wire.setClock(400000);
  sendInitCommands();
  resetDisplay();
}

void SH1106::resetDisplay(void) {
  displayOff();
  clear();
  display();
  displayOn();
}

void SH1106::reconnect() {
  Wire.begin(mySda, mySdc);
}

void SH1106::displayOn(void) {
    sendCommand(0xaf);        //display on
}

void SH1106::displayOff(void) {
  sendCommand(0xae);          //display off
}

void SH1106::setContrast(char contrast) {
  sendCommand(0x81);
  sendCommand(contrast);
}

void SH1106::flipScreenVertically() {
  sendCommand(0xA0 | 0x1);      //SEGREMAP   //Rotate screen 180 deg
  sendCommand(0xC8);            //COMSCANDEC  Rotate screen 180 Deg
}

void SH1106::clear(void) {
    memset(buffer, 0, (128 * 64 / 8));
}

void SH1106::display(void) {

 for (uint8_t k=0; k<8; k++) 
    {
      sendCommand(0xB0+k);//set page addressSSD_Data_Mode;
      sendCommand(0x02) ;//set lower column address
      sendCommand(0x10) ;//set higher column address

       for (uint16_t i=0; i< 128; i++) {
          // send a bunch of data in one xmission
          //Wire.begin(mySda, mySdc);
          Wire.beginTransmission(myI2cAddress);
          Wire.write(0x40);
          for (uint8_t x=0; x<16; x++) {
          Wire.write(buffer[128*k+i]);
          i++;
          }
        i--;
        yield();
        Wire.endTransmission();
        }
      }
}

void SH1106::setPixel(int x, int y) {
  if (x >= 0 && x < 128 && y >= 0 && y < 64) {

     switch (myColor) {
      case WHITE:   buffer[x + (y/8)*128] |=  (1 << (y&7)); break;
      case BLACK:   buffer[x + (y/8)*128] &= ~(1 << (y&7)); break;
      case INVERSE: buffer[x + (y/8)*128] ^=  (1 << (y&7)); break;
    }
  }
}

void SH1106::setChar(int x, int y, unsigned char data) {
  for (int i = 0; i < 8; i++) {
    if (bitRead(data, i)) {
     setPixel(x,y + i);
    }
  }
}

// Code form http://playground.arduino.cc/Main/Utf8ascii
byte SH1106::utf8ascii(byte ascii) {
    if ( ascii<128 ) {   // Standard ASCII-set 0..0x7F handling
       lastChar=0;
       return( ascii );
    }

    // get previous input
    byte last = lastChar;   // get last char
    lastChar=ascii;         // remember actual character

    switch (last)     // conversion depnding on first UTF8-character
    {   case 0xC2: return  (ascii);  break;
        case 0xC3: return  (ascii | 0xC0);  break;
        case 0x82: if(ascii==0xAC) return(0x80);       // special case Euro-symbol
    }

    return  (0);                                     // otherwise: return zero, if character has to be ignored
}

// Code form http://playground.arduino.cc/Main/Utf8ascii
String SH1106::utf8ascii(String s) {
        String r= "";
        char c;
        for (int i=0; i<s.length(); i++)
        {
                c = utf8ascii(s.charAt(i));
                if (c!=0) r+=c;
        }
        return r;
}

void SH1106::drawString(int x, int y, String text) {
  text = utf8ascii(text);
  unsigned char currentByte;
  int charX, charY;
  int currentBitCount;
  int charCode;
  int currentCharWidth;
  int currentCharStartPos;
  int cursorX = 0;
  int numberOfChars = pgm_read_byte(myFontData + CHAR_NUM_POS);
  // iterate over string
  int firstChar = pgm_read_byte(myFontData + FIRST_CHAR_POS);
  int charHeight = pgm_read_byte(myFontData + HEIGHT_POS);
  int currentCharByteNum = 0;
  int startX = 0;
  int startY = y;

  if (myTextAlignment == TEXT_ALIGN_LEFT) {
    startX = x;
  } else if (myTextAlignment == TEXT_ALIGN_CENTER) {
    int width = getStringWidth(text);
    startX = x - width / 2;
  } else if (myTextAlignment == TEXT_ALIGN_RIGHT) {
    int width = getStringWidth(text);
    startX = x - width;
  }

  for (int j=0; j < text.length(); j++) {

    charCode = text.charAt(j)-0x20;

    currentCharWidth = pgm_read_byte(myFontData + CHAR_WIDTH_START_POS + charCode);
    // Jump to font data beginning
    currentCharStartPos = CHAR_WIDTH_START_POS + numberOfChars;

    for (int m = 0; m < charCode; m++) {

      currentCharStartPos += pgm_read_byte(myFontData + CHAR_WIDTH_START_POS + m)  * charHeight / 8 + 1;
    }

    currentCharByteNum = ((charHeight * currentCharWidth) / 8) + 1;
    // iterate over all bytes of character
    for (int i = 0; i < currentCharByteNum; i++) {

      currentByte = pgm_read_byte(myFontData + currentCharStartPos + i);
      //Serial.println(String(charCode) + ", " + String(currentCharWidth) + ", " + String(currentByte));
      // iterate over all bytes of character
      for(int bit = 0; bit < 8; bit++) {
         //int currentBit = bitRead(currentByte, bit);

         currentBitCount = i * 8 + bit;

         charX = currentBitCount % currentCharWidth;
         charY = currentBitCount / currentCharWidth;

         if (bitRead(currentByte, bit)) {
          setPixel(startX + cursorX + charX, startY + charY);
         }

      }
      yield();
    }
    cursorX += currentCharWidth;

  }
}

void SH1106::drawStringMaxWidth(int x, int y, int maxLineWidth, String text) {
  int currentLineWidth = 0;
  int startsAt = 0;
  int endsAt = 0;
  int lineNumber = 0;
  char currentChar = ' ';
  int lineHeight = pgm_read_byte(myFontData + HEIGHT_POS);
  String currentLine = "";
  for (int i = 0; i < text.length(); i++) {
    currentChar = text.charAt(i);
    if (currentChar == ' ' || currentChar == '-') {
      String lineCandidate = text.substring(startsAt, i);
      if (getStringWidth(lineCandidate) <= maxLineWidth) {
        endsAt = i;
      } else {

        drawString(x, y + lineNumber * lineHeight, text.substring(startsAt, endsAt));
        lineNumber++;
        startsAt = endsAt + 1;
      }
    }

  }
  drawString(x, y + lineNumber * lineHeight, text.substring(startsAt));
}

int SH1106::getStringWidth(String text) {
  text = utf8ascii(text);
  int stringWidth = 0;
  char charCode;
  for (int j=0; j < text.length(); j++) {
    charCode = text.charAt(j)-0x20;
    stringWidth += pgm_read_byte(myFontData + CHAR_WIDTH_START_POS + charCode);
  }
  return stringWidth;
}

void SH1106::setTextAlignment(int textAlignment) {
  myTextAlignment = textAlignment;
}

void SH1106::setFont(const char *fontData) {
  myFontData = fontData;
}

void SH1106::drawBitmap(int x, int y, int width, int height, const char *bitmap) {
  for (int i = 0; i < width * height / 8; i++ ){
    unsigned char charColumn = 255 - pgm_read_byte(bitmap + i);
    for (int j = 0; j < 8; j++) {
      int targetX = i % width + x;
      int targetY = (i / (width)) * 8 + j + y;
      if (bitRead(charColumn, j)) {
        setPixel(targetX, targetY);
      }
    }
  }
}

void SH1106::setColor(int color) {
  myColor = color;
}

void SH1106::drawRect(int x, int y, int width, int height) {
  for (int i = x; i < x + width; i++) {
    setPixel(i, y);
    setPixel(i, y + height);
  }
  for (int i = y; i < y + height; i++) {
    setPixel(x, i);
    setPixel(x + width, i);
  }
}

void SH1106::fillRect(int x, int y, int width, int height) {
  for (int i = x; i < x + width; i++) {
    for (int j = y; j < y + height; j++) {
      setPixel(i, j);
    }
  }
}

void SH1106::drawXbm(int x, int y, int width, int height, const char *xbm) {
  if (width % 8 != 0) {
    width =  ((width / 8) + 1) * 8;
  }
  for (int i = 0; i < width * height / 8; i++ ){
    unsigned char charColumn = pgm_read_byte(xbm + i);
    for (int j = 0; j < 8; j++) {
      int targetX = (i * 8 + j) % width + x;
      int targetY = (8 * i / (width)) + y;
      if (bitRead(charColumn, j)) {
        setPixel(targetX, targetY);
      }
    }
  }
}

void SH1106::sendCommand(unsigned char com) {
  Wire.beginTransmission(myI2cAddress);     //begin transmitting
  Wire.write(0x80);                          //command mode
  Wire.write(com);
  Wire.endTransmission();                    // stop transmitting
}

void SH1106::sendInitCommands(void) {
  sendCommand(DISPLAYOFF);
  sendCommand(NORMALDISPLAY);
  sendCommand(SETDISPLAYCLOCKDIV);
  sendCommand(0x80);
  sendCommand(SETMULTIPLEX);
  sendCommand(0x3F);
  sendCommand(SETDISPLAYOFFSET);
  sendCommand(0x00);
  sendCommand(SETSTARTLINE | 0x00);
  sendCommand(CHARGEPUMP);
  sendCommand(0x14);
  sendCommand(MEMORYMODE);
  sendCommand(0x00);
  sendCommand(SEGREMAP);
  sendCommand(COMSCANINC);
  sendCommand(SETCOMPINS);
  sendCommand(0x12);
  sendCommand(SETCONTRAST);
  sendCommand(0xCF);
  sendCommand(SETPRECHARGE);
  sendCommand(0xF1);
  sendCommand(SETVCOMDETECT);
  sendCommand(0x40);
  sendCommand(DISPLAYALLON_RESUME);
  sendCommand(NORMALDISPLAY);
  sendCommand(0x2e);            // stop scroll
  sendCommand(DISPLAYON);
}

 

Seling
Offline
Зарегистрирован: 29.07.2018

есть ещё вкладки SH1106.h, SH1106Front.h, SH1106Ui ,SH1106Ui.cpp, SH1106Ui.h, TimeClient.ccp, TimeClient.h, WeatherStationFonts.h, WeatherStationilmages.h, WundergraundClient.cpp, WundergraundClient.h

Владимир 2018
Offline
Зарегистрирован: 17.03.2018

Seling пишет:

есть ещё вкладки SH1106.h, SH1106Front.h, SH1106Ui ,SH1106Ui.cpp, SH1106Ui.h, TimeClient.ccp, TimeClient.h, WeatherStationFonts.h, WeatherStationilmages.h, WundergraundClient.cpp, WundergraundClient.h

Запустился Ваш дисплей?

У меня подобная схема и дисплей также не запускается.

b707
Offline
Зарегистрирован: 26.05.2017

Владимир 2018 пишет:

Запустился Ваш дисплей?

У меня подобная схема и дисплей также не запускается.

у топикстартера проблема была не в дисплее, а в том. что он нифига не понимая в программировании - сразу схватился делать сложный проект.

Не повторяйте его ошибок. Возьмите для начала примеры из библиоттеки SH1106.h и добейтесь на простых скетчах. чтобы у вас просто выводилось на экран "Hello world"

Владимир 2018
Offline
Зарегистрирован: 17.03.2018

b707 пишет:

Владимир 2018 пишет:

Запустился Ваш дисплей?

У меня подобная схема и дисплей также не запускается.

у топикстартера проблема была не в дисплее, а в том. что он нифига не понимая в программировании - сразу схватился делать сложный проект.

Не повторяйте его ошибок. Возьмите для начала примеры из библиоттеки SH1106.h и добейтесь на простых скетчах. чтобы у вас просто выводилось на экран "Hello world"

Я сам не являюь програмистом, а считаю себя больше электорнщиком. Дисплей OLED 1306 подключал к ардуино, рисовал даже самостоятельно на нем собственные картинки и шрифты. Информация при этом отображалась корректно, а вот к ESP8266 напрямую этот дисплей не подключал. Вот сейчас решил повторить подобный проект метеостанции и такая же у меня возникает проблема.