Arduino непонятки с проектом

Обсуждаем контроллеры компании Atmel.
Ответить
Друг Кота
Аватара пользователя
Сообщения: 4106
Зарегистрирован: Пн авг 10, 2009 01:18:55
Откуда: Электросталь

Сообщение Evgeny1 »

Привет народ!
Решил запилить этот девайс http://karman.cc/blog/archives/746
все работает, но вылезла проблема с инициализацией дисплея
дисплей SSD1306 имеет у себя в контроллере память и что-то там запоминает и после повторного включения питания девайс работать отказывается
друг сделал тестовую картинку и с ней все стартует нормально и дисплей включается и работает после повторного отключения питания
Спойлер

Код: Выделить всё

/*

  XBM.pde
  
  drawXBM example code.
  
  >>> Before compiling: Please remove comment from the constructor of the 
  >>> connected graphics display (see below).
  
  Universal 8bit Graphics Library, http://code.google.com/p/u8glib/
  
  Copyright (c) 2012, olikraus@gmail.com
  All rights reserved.

  Redistribution and use in source and binary forms, with or without modification, 
  are permitted provided that the following conditions are met:

  * Redistributions of source code must retain the above copyright notice, this list 
    of conditions and the following disclaimer.
    
  * Redistributions in binary form must reproduce the above copyright notice, this 
    list of conditions and the following disclaimer in the documentation and/or other 
    materials provided with the distribution.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
  CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
  
*/


#include "U8glib.h"

// setup u8g object, please remove comment from one of the following constructor calls
// IMPORTANT NOTE: The following list is incomplete. The complete list of supported 
// devices with all constructor calls is here: http://code.google.com/p/u8glib/wiki/device
//U8GLIB_NHD27OLED_BW u8g(13, 11, 10, 9);	// SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_NHD27OLED_2X_BW u8g(13, 11, 10, 9);	// SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_NHD27OLED_GR u8g(13, 11, 10, 9);	// SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_NHD27OLED_2X_GR u8g(13, 11, 10, 9);	// SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_NHD31OLED_BW u8g(13, 11, 10, 9);	// SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_NHD31OLED_2X_BW u8g(13, 11, 10, 9);	// SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_NHD31OLED_GR u8g(13, 11, 10, 9);	// SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_NHD31OLED_2X_GR u8g(13, 11, 10, 9);	// SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_DOGS102 u8g(13, 11, 10, 9);		// SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_DOGM132 u8g(13, 11, 10, 9);		// SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_DOGM128 u8g(13, 11, 10, 9);		// SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_DOGM128_2X u8g(13, 11, 10, 9);		// SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_ST7920_128X64_1X u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 17, 16);   // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, di=17,rw=16
//U8GLIB_ST7920_128X64_4X u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 17, 16);   // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, di=17,rw=16
//U8GLIB_ST7920_128X64_1X u8g(18, 16, 17);	// SPI Com: SCK = en = 18, MOSI = rw = 16, CS = di = 17
//U8GLIB_ST7920_128X64_4X u8g(18, 16, 17);	// SPI Com: SCK = en = 18, MOSI = rw = 16, CS = di = 17
//U8GLIB_ST7920_192X32_1X u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 17, 16);   // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, di=17,rw=16
//U8GLIB_ST7920_192X32_4X u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 17, 16);   // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, di=17,rw=16
//U8GLIB_ST7920_192X32_1X u8g(18, 16, 17);	// SPI Com: SCK = en = 18, MOSI = rw = 16, CS = di = 17
//U8GLIB_ST7920_192X32_4X u8g(18, 16, 17);	// SPI Com: SCK = en = 18, MOSI = rw = 16, CS = di = 17
//U8GLIB_ST7920_192X32_1X u8g(13, 11, 10);	// SPI Com: SCK = en = 13, MOSI = rw = 11, CS = di = 10
//U8GLIB_ST7920_192X32_4X u8g(10);		// SPI Com: SCK = en = 13, MOSI = rw = 11, CS = di = 10, HW SPI
//U8GLIB_ST7920_202X32_1X u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 17, 16);   // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, di=17,rw=16
//U8GLIB_ST7920_202X32_4X u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 17, 16);   // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, di=17,rw=16
//U8GLIB_ST7920_202X32_1X u8g(18, 16, 17);	// SPI Com: SCK = en = 18, MOSI = rw = 16, CS = di = 17
//U8GLIB_ST7920_202X32_4X u8g(18, 16, 17);	// SPI Com: SCK = en = 18, MOSI = rw = 16, CS = di = 17
//U8GLIB_LM6059 u8g(13, 11, 10, 9);		// SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_LM6063 u8g(13, 11, 10, 9);		// SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_DOGXL160_BW u8g(10, 9);		// SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_DOGXL160_GR u8g(13, 11, 10, 9);	// SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_DOGXL160_2X_BW u8g(13, 11, 10, 9);	// SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_DOGXL160_2X_GR u8g(13, 11, 10, 9);	// SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_PCD8544 u8g(13, 11, 10, 9, 8);		// SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, Reset = 8
//U8GLIB_PCF8812 u8g(13, 11, 10, 9, 8);		// SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, Reset = 8
//U8GLIB_KS0108_128 u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 14, 15, 17, 16); 		// 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, cs1=14, cs2=15,di=17,rw=16
//U8GLIB_LC7981_160X80 u8g(8, 9, 10, 11, 4, 5, 6, 7,  18, 14, 15, 17, 16); 	// 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, cs=14 ,di=15,rw=17, reset = 16
//U8GLIB_LC7981_240X64 u8g(8, 9, 10, 11, 4, 5, 6, 7,  18, 14, 15, 17, 16); 	// 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, cs=14 ,di=15,rw=17, reset = 16
//U8GLIB_LC7981_240X128 u8g(8, 9, 10, 11, 4, 5, 6, 7,  18, 14, 15, 17, 16); 	// 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, cs=14 ,di=15,rw=17, reset = 16
//U8GLIB_ILI9325D_320x240 u8g(18,17,19,U8G_PIN_NONE,16 );  			// 8Bit Com: D0..D7: 0,1,2,3,4,5,6,7 en=wr=18, cs=17, rs=19, rd=U8G_PIN_NONE, reset = 16
//U8GLIB_SBN1661_122X32 u8g(8,9,10,11,4,5,6,7,14,15, 17, U8G_PIN_NONE, 16); 	// 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 cs1=14, cs2=15,di=17,rw=16,reset = 16
//U8GLIB_SSD1306_128X64 u8g(13, 11, 10, 9);	// SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_SSD1306_128X64 u8g(10, 9);		// HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are  SCK = 13 and MOSI = 11)
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE);	// HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are  SCK = 13 and MOSI = 11)
//U8GLIB_SSD1306_128X32 u8g(13, 11, 10, 9);	// SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_SSD1306_128X32 u8g(10, 9);             // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are  SCK = 13 and MOSI = 11)
//U8GLIB_SSD1306_128X32 u8g(U8G_I2C_OPT_NONE);	// HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are  SCK = 13 and MOSI = 11)
//U8GLIB_SSD1309_128X64 u8g(13, 11, 10, 9);	// SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_SSD1327_96X96_GR u8g(U8G_I2C_OPT_NONE);	// I2C
//U8GLIB_SSD1327_96X96_2X_GR u8g(U8G_I2C_OPT_NONE);	// I2C
//U8GLIB_NHD_C12864 u8g(13, 11, 10, 9, 8);	// SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, RST = 8
//U8GLIB_NHD_C12832 u8g(13, 11, 10, 9, 8);	// SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, RST = 8
//U8GLIB_T6963_240X128 u8g(8, 9, 10, 11, 4, 5, 6, 7, 14, 15, 17, 18, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7, cs=14, a0=15, wr=17, rd=18, reset=16
//U8GLIB_T6963_240X64 u8g(8, 9, 10, 11, 4, 5, 6, 7, 14, 15, 17, 18, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7, cs=14, a0=15, wr=17, rd=18, reset=16
//U8GLIB_T6963_128X64 u8g(8, 9, 10, 11, 4, 5, 6, 7, 14, 15, 17, 18, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7, cs=14, a0=15, wr=17, rd=18, reset=16
//U8GLIB_HT1632_24X16 u8g(3, 2, 4);		// WR = 3, DATA = 2, CS = 4
//U8GLIB_SSD1351_128X128_332 u8g(13, 11, 8, 9, 7); // Arduino UNO: SW SPI Com: SCK = 13, MOSI = 11, CS = 8, A0 = 9, RESET = 7 (http://electronics.ilsoft.co.uk/ArduinoShield.aspx)
//U8GLIB_SSD1351_128X128_332 u8g(76, 75, 8, 9, 7); // Arduino DUE: SW SPI Com: SCK = 13, MOSI = 11, CS = 8, A0 = 9, RESET = 7 (http://electronics.ilsoft.co.uk/ArduinoShield.aspx)
//U8GLIB_SSD1351_128X128_332 u8g(8, 9, 7); // Arduino: HW SPI Com: SCK = 13, MOSI = 11, CS = 8, A0 = 9, RESET = 7 (http://electronics.ilsoft.co.uk/ArduinoShield.aspx)
//U8GLIB_SSD1351_128X128_4X_332 u8g(76, 75, 8, 9, 7); // Arduino DUE: SW SPI Com: SCK = 13, MOSI = 11, CS = 8, A0 = 9, RESET = 7 (http://electronics.ilsoft.co.uk/ArduinoShield.aspx)
//U8GLIB_SSD1351_128X128_4X_332 u8g(8, 9, 7); // Arduino : HW SPI Com: SCK = 13, MOSI = 11, CS = 8, A0 = 9, RESET = 7 (http://electronics.ilsoft.co.uk/ArduinoShield.aspx)
//U8GLIB_SSD1351_128X128_HICOLOR u8g(76, 75, 8, 9, 7); // Arduino DUE, SW SPI Com: SCK = 76, MOSI = 75, CS = 8, A0 = 9, RESET = 7 (http://electronics.ilsoft.co.uk/ArduinoShield.aspx)
//U8GLIB_SSD1351_128X128_HICOLOR u8g(8, 9, 7); // Arduino, HW SPI Com: SCK = 76, MOSI = 75, CS = 8, A0 = 9, RESET = 7 (http://electronics.ilsoft.co.uk/ArduinoShield.aspx)
//U8GLIB_SSD1351_128X128_4X_HICOLOR u8g(76, 75, 8, 9, 7); // Arduino DUE, HW SPI Com, 4x Memory: SCK = 76, MOSI = 75, CS = 8, A0 = 9, RESET = 7 (http://electronics.ilsoft.co.uk/ArduinoShield.aspx)
//U8GLIB_SSD1351_128X128_4X_HICOLOR u8g(8, 9, 7); // Arduino, HW SPI Com, 4x Memory: SCK = 76, MOSI = 75, CS = 8, A0 = 9, RESET = 7 (http://electronics.ilsoft.co.uk/ArduinoShield.aspx)
//U8GLIB_SSD1351_128X128GH_332 u8g(8, 9, 7); // Arduino, HW SPI Com: SCK = 76, MOSI = 75, CS = 8, A0 = 9, RESET = 7 (Freetronics OLED)
//U8GLIB_SSD1351_128X128GH_HICOLOR u8g(8, 9, 7); // Arduino, HW SPI Com: SCK = 76, MOSI = 75, CS = 8, A0 = 9, RESET = 7 (Freetronics OLED)

#define u8g_logo_width 128
#define u8g_logo_height 64
//static unsigned char u8g_logo_bits[] = {
static unsigned char u8g_logo_bits[] U8G_PROGMEM = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0xC0,0x3F,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0xFE,0xFF,0xCD,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x02,0x00,0x00,
0x00,0x00,0xC0,0x1F,0x00,0x07,0x03,0x00,0x00,0xF8,0x0F,0x00,0xF0,0x00,0x00,0x00,
0x00,0x00,0xF0,0x01,0xC0,0x34,0x1C,0xFE,0xFF,0xFF,0xFF,0x3F,0xC0,0x03,0x00,0x00,
0x00,0x00,0xBC,0x3F,0x40,0xEC,0x90,0xFF,0x07,0x00,0x00,0xFC,0x07,0x07,0x00,0x00,
0x00,0x00,0xCE,0x07,0x00,0xFC,0xE0,0x07,0x00,0x00,0x00,0x00,0x7F,0x0E,0x00,0x00,
0x00,0x00,0x03,0x01,0x0E,0xF4,0xFC,0x01,0x00,0x00,0x00,0x00,0xFC,0xFF,0x06,0x00,
0x00,0x80,0x01,0x00,0x08,0xFE,0x7F,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0x0F,0x00,
0x00,0xC0,0x00,0xE0,0x83,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,
0x00,0xC0,0x00,0x00,0xC0,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x07,0x00,
0x00,0xC0,0x00,0x00,0xF0,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x3F,0x00,
0x00,0xC0,0x00,0x00,0xFC,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xB8,0x7C,0x00,
0x00,0xA0,0x03,0x80,0xFF,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x7B,0x00,
0x00,0xF8,0x7F,0xFC,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x7F,0x00,
0x00,0x7C,0xFC,0xFF,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,
0x00,0x20,0xF8,0xFF,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,
0x00,0x80,0xE0,0xFF,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,
0x00,0x00,0x02,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0xCC,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0xF0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0xF8,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0xE0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0xC0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x80,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0xF8,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0xE0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x80,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xFE,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x80,0xFF,0xFF,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

void draw(void) {
  // graphic commands to redraw the complete screen should be placed here  
  u8g.drawXBMP( 0, 0, u8g_logo_width, u8g_logo_height, u8g_logo_bits);
}

void setup(void) {
  // flip screen, if required
  // u8g.setRot180();
}

void loop(void) {
  // picture loop
  u8g.firstPage();  
  do {
    draw();
  } while( u8g.nextPage() );
  
  // rebuild the picture after some delay
  delay(500);
}
а с этим GPS проектиком какая-то лажа после заливки скетча все работает отлично, но стоит вырубить питание и подождать минут 10, то дисплей намертво отказывается включаться (у него контроллер SSD1306 и i2c там вроде как программный)

подскажите как вылечить данный глюк
Спойлер

Код: Выделить всё

//======================//
//                                                          //
//    GPS Toy By KaR]V[aN, http://karman.homelinux.net      //
//    Thanks to the Arduino comunity for providing code,    //
//    libraries and platforms. Also many thanks to Nitz,    //
//    whose coding skills helped so much.                   //
//                                                          //
//======================//

/* 
 * This is a simple GPS Toy/'on board computer' that shows GPS
 * data in a tiny 128x64 OLED display (I2C driven, 0.96").
 * Because being I2C display the frame rate is very slow 
 * but saves pins for future use.
 */
 
#include <EEPROM.h>
#include "EEPROMAnything.h"
#include "mySoftwareSerial.h" 
#include <TinyGPS.h>
#include <Wire.h>
#include <avr/pgmspace.h>

// So, why use a custom software serial? This addresses a problem sharing 
// interrupts between pinchangeint and software serial, by disabling the 
// unsued ports on both of them. Meanwhile pinchangeint allows easy disabling,
// newsoftwareserial doesn't, so have to comment code. More info:
// http://code.google.com/p/arduino-pinchangeint/issues/detail?id=7

//---------------FONT + GRAPHIC-----------------------------//
#include "data.h"
//======================//

#define OLED_address  0x3c

// I'll attach interrupt to digital pins 4 and 5, both 
// on port D. Both ports B and C are to be disabled:
#define NO_PORTB_PINCHANGES // to indicate that port b will not be used for pin change interrupts
#define NO_PORTC_PINCHANGES // to indicate that port c will not be used for pin change interrupts
#include <PinChangeInt.h>

TinyGPS gps;
SoftwareSerial nss(9, 8);
static bool feedgps();
const int buttonA = 4;
const int buttonB = 5;
unsigned int buttonStateB = 0;      
unsigned int buttonStateA = 0;       
unsigned int mode=0;
bool course_degree = false;
bool control_blink = false;
bool control_clock = false;
bool interrupt = false;
bool doing_menu = false;
float SAVED_LAT = 0.0, SAVED_LON = 0.0, LAST_LAT = 0.0, LAST_LON = 0.0;
unsigned int TZ = 2;
unsigned long int tripDistance = 0;
static const byte settings_version = B00000001;
bool fix_first = 1;
float last_course = 0.0;


//---------------Saved Data Map-----------------------------//
// Bytes  Size  Purpose
// ····························································
// 0      1     Settings Version
// 1-4    4     Saved Latitude
// 5-8    4     Saved Longitude
// 9-10   2     Saved Mode
// 11     1     Saved Course preference (Degrees - Cardinal)
// 12     1     Saved Clock prefence (12h - 24h)
// 13-14  2     Saved Time Zone
// 15-18  4     Saved trip distance
//======================//


void setup()
{
  // Load previous Settings
  byte read_settings_version;
  EEPROM_readAnything(0, read_settings_version);
 
  if(settings_version == read_settings_version) // If version matchs, load vars from EEPROM
  {  
    EEPROM_readAnything(1, SAVED_LAT);
    EEPROM_readAnything(5, SAVED_LON);
    EEPROM_readAnything(9, mode);
    EEPROM_readAnything(11, course_degree);
    EEPROM_readAnything(12, control_clock);
    EEPROM_readAnything(13, TZ);
    EEPROM_readAnything(15, tripDistance);
  }
  else                                          // If not, initialize with defaults
  {
    EEPROM_writeAnything(0, settings_version);
    EEPROM_writeAnything(1, SAVED_LAT);
    EEPROM_writeAnything(5, SAVED_LON);
    EEPROM_writeAnything(9, mode);
    EEPROM_writeAnything(11, course_degree);
    EEPROM_writeAnything(12, control_clock);
    EEPROM_writeAnything(13, TZ);
    EEPROM_writeAnything(15, tripDistance);
  }
  
  // Buttons...
  pinMode(buttonA, INPUT);
  pinMode(buttonB, INPUT);    
  digitalWrite(buttonA, LOW);
  digitalWrite(buttonB, LOW);
  
  // Attach interrupts to both buttons on rising change
  PCintPort::attachInterrupt(buttonA, &interrupt_button, RISING); 
  PCintPort::attachInterrupt(buttonB, &interrupt_button, RISING); 
  
  // Initialize Software Serial, I2C and OLED Display
  nss.begin(9600);
  Wire.begin();
  init_OLED();

  reset_display();           // Clear logo and load saved mode
  nss.listen();
  //Serial.begin(115200);
}


//======================//
void loop()
{  
  // Read Button state
  if (buttonStateA == HIGH || buttonStateB == HIGH)
  {
    doing_menu = true;                            // we are in button fuctions, ignore interrupt bool
    unsigned long button_delay = millis();
    
    while (millis() - button_delay < 50) 
    {
      if (buttonStateA == LOW) 
        buttonStateA = digitalRead(buttonA);
      if (buttonStateB == LOW) 
        buttonStateB = digitalRead(buttonB);
    }
      
    // Both buttons pushed
    if (buttonStateB == HIGH && buttonStateA == HIGH)
    {
      displayOff();
      setXY(0,0);
  
      for(int i=0;i<128*8;i++)     // show 128* 64 Logo
        SendChar(pgm_read_byte(logo+i));
    
      displayOn();
      sendStrXY("Carlos Sancho",7,2);
      sendStrXY("v1.0", 0, 12);
      delay(5000);
      clear_display();
      sendStrXY("http://karman.homelinux.net",0,0);
      sendStrXY("Using TinyGPS by Mikal Hart",3,0);
      delay(5000);
      reset_display();
    }
    
    // Menu/mode button
    else if(buttonStateA == HIGH && buttonStateB == LOW) 
    {
      // Change mode
      if (mode == 0) 
        mode = 1;
      
      else if (mode == 1) 
        mode = 2;
        
      else if (mode == 2)
        mode = 3;
        
      else if (mode == 3)
        mode = 0;
      
      EEPROM_writeAnything(9, mode); // Save mode
      reset_display();
    } 
    
    // Other button
    else if (buttonStateB == HIGH && buttonStateA == LOW) 
    {
      reset_buttons();
      
      // Change cardinal <-> degrees
      if (mode == 0) 
      {
        course_degree = !course_degree;
        EEPROM_writeAnything(11, course_degree);
        reset_display();
      }
      
      // Memorize current location after 3 seconds pushing button
      else if (mode == 1) 
      {
        displayOff();
        clear_display();
        sendStrXY("Memorizing in: ", 0, 0);
        printBigNumber('3', 3 ,6);
        displayOn();
        boolean exit = 0;
        unsigned long start = millis();
        while (digitalRead(buttonB) == HIGH && !exit)
        {          
          if (millis() - start > 3000) 
          {
            clear_display();
            exit = true;
            sendStrXY("Coordinates memorized:", 0, 0);
            saveActualLoc(gps);
            delay(2000);
          } 
          
          else if (millis() - start > 2000)
            printBigNumber('1', 3 ,6);
            
          else if (millis() - start > 1000)
            printBigNumber('2', 3 ,6);
        }
        reset_display();
      }
      
      // Reset trip 
      else if (mode == 2)
      {
        displayOff();
        clear_display();
        sendStrXY("Clearing in: ", 0, 0);
        printBigNumber('3', 3 ,6);
        displayOn();
        boolean exit = 0;
        unsigned long start = millis();
        while (digitalRead(buttonB) == HIGH && !exit)
        {          
          if (millis() - start > 3000) 
          {
            clear_display();
            exit = true;
            unsigned long age;
            float flat, flon;
            gps.f_get_position(&flat, &flon, &age);
            sendStrXY("Trip reseted", 0, 0);
            tripDistance = 0;
            LAST_LAT = flat;
            LAST_LON = flon;
            EEPROM_writeAnything(15, tripDistance);
            delay(2000);
          } 
          
          else if (millis() - start > 2000)
            printBigNumber('1', 3 ,6);
            
          else if (millis() - start > 1000)
            printBigNumber('2', 3 ,6);
        }
        reset_display();
      }
      
      // Change clock hour mode, 12h <-> 24h in short push (< 3 secs)
      // In long push (> 3 sec) enters in time zone setting mode
      else if (mode == 3)
      {
        reset_buttons();
        boolean exit = 0;
        boolean mode_timezone = false;
        unsigned long start = millis();
        while (digitalRead(buttonB) == HIGH && !exit)
        {
          if (millis() - start > 3000) 
          {
            exit = true;
            mode_timezone = true;
          }
        }
        
        if (mode_timezone)
        {
          displayOff();
          clear_display();
          sendStrXY("Select TimeZone:", 0, 0);
          sendStrXY("Menu to set", 7, 2);
          displayOn();
          reset_buttons();
          bool print_TZ = true;
          while(buttonStateA != HIGH)
          {
            
            if (buttonStateB == HIGH) 
            {
              // this loop avoids false contacts of defective switches and sparks
              while (digitalRead(buttonB) != LOW)
                delay(10); 
              
              buttonStateB = LOW;
              TZ++;
              print_TZ = true;
            }
            
            if (TZ == 13)
              TZ = -11;
            
            // Avoid to print always same value
            if (print_TZ) {
              print_timezone(TZ);
              print_TZ = false;
            }
            
            delay(10); // to not fall into an endless loop. 
          }
          EEPROM_writeAnything(13, TZ);
        }
        else 
        {
          control_clock = !control_clock;
          EEPROM_writeAnything(12, control_clock);
        }
        reset_display();
      }
    }
    reset_buttons();
    doing_menu = false;    // Reset both vars on buttons exit
    interrupt = false;
  }
  
  
  // check if new data is avaiable
  if (feedgps())
     updateScreen(gps);  // and prints it    
     
  // update trip distance
  udpateTrip(gps);
}

// Change button state on interrupt
void interrupt_button (void)
{
  if (PCintPort::arduinoPin == buttonA)
    buttonStateA = HIGH;
  else if (PCintPort::arduinoPin == buttonB)
    buttonStateB = HIGH;
    
  interrupt = true;          // Stop printing on display, speeds up response.
}

// Resets button states
static void reset_buttons(void)
{
  buttonStateA = LOW;
  buttonStateB = LOW;
}

//======================//
// Resets display depending on the actual mode.
static void reset_display(void)
{
  displayOff();
  clear_display();
  if (mode == 0)
  {
    printKmh_unit();
  }
  else if (mode == 1) 
  {
    //nothing here by now
  } 
  else if (mode == 2) 
  {
    sendStrXY("Trip sum:", 0, 3);
  }
  else if (mode == 3)
  {
    sendStrXY("Atomic GPS Watch",0,0);
  }  
  updateScreen(gps);
  displayOn();
}

//======================//
// Updates screen depending on the actual mode.
static void updateScreen(TinyGPS &gps) 
{
  unsigned long age;
  float flat, flon;
  gps.f_get_position(&flat, &flon, &age);
  
  if (mode == 0)
  {
    print_date(gps);
    printAlt(gps.f_altitude(), 0, 0);
    printSpeed(gps.f_speed_kmph());
    printSats(gps.satellites(), 0, 10);
    feedgps();
    printCourse(gps); 
  }  
  else if (mode == 1)
  { 
    print_coord(flat, TinyGPS::GPS_INVALID_F_ANGLE, 0, 0);
    print_coord(flon, TinyGPS::GPS_INVALID_F_ANGLE, 0, 9);
    sendDistanceBetwen(gps);
    printCourse(gps);
    print_coord(SAVED_LAT, TinyGPS::GPS_INVALID_F_ANGLE, 7, 0);
    print_coord(SAVED_LON, TinyGPS::GPS_INVALID_F_ANGLE, 7, 9);
  }
  else if (mode == 2)
  {
    printTrip();
  }
  else if (mode == 3)
  {
    print_date(gps);
  }
}



//======================//
// Shows and saves actual coordinates
static void saveActualLoc(TinyGPS &gps)
{
  unsigned long age;
  float flat, flon;
 
  gps.f_get_position(&flat, &flon, &age);
  sendStrXY("Lat: ", 4, 0);
  sendStrXY("Lon: ", 5, 0);
  print_coord(flat, TinyGPS::GPS_INVALID_F_ANGLE, 4, 5);
  print_coord(flon, TinyGPS::GPS_INVALID_F_ANGLE, 5, 5);
  SAVED_LAT = flat;
  SAVED_LON = flon;
  EEPROM_writeAnything(1, SAVED_LAT);
  EEPROM_writeAnything(5, SAVED_LON);
}

//======================//
// Prints display trip update
static void printTrip () {
 /* char sz[32];
  sprintf(sz, "RAW: %d", tripDistance);
  sendStrXY(sz, 7, 0);*/
  print_distance(tripDistance);
}

//======================//
// Gets current location and if > 20, sums to trip global var.
static void udpateTrip (TinyGPS &gps) {
  unsigned long age;
  float flat, flon;
  int max_dist = 25;
 
  gps.f_get_position(&flat, &flon, &age);
  if (flat == TinyGPS::GPS_INVALID_F_ANGLE)
    return;
  else {
    
    int mySpeed = (int)gps.f_speed_kmph();
    
    if(mySpeed > 5) 
      max_dist = 20;
    if(mySpeed > 10) 
      max_dist = 15;
    if(mySpeed > 15) 
      max_dist = 5;
    
    if(fix_first) 
    {
      LAST_LAT = flat;
      LAST_LON = flon;
      fix_first = false;
    } 
    else 
    {
    
      // Distance in meters
      unsigned long int dist = (long int)TinyGPS::distance_between(flat, flon, LAST_LAT, LAST_LON);

      if (dist > max_dist)   
      {
        
        tripDistance += dist;
        
        LAST_LAT = flat;
        LAST_LON = flon;
        EEPROM_writeAnything(15, tripDistance);
      }
    }   
  }
}

//======================//
// Prints actual course or course to a point (distance mode) 
// in cardinal or dregree mode.
static void printCourse(TinyGPS &gps) 
{
  unsigned long age;
  float flat, flon;
  gps.f_get_position(&flat, &flon, &age);
  
  if (flat == TinyGPS::GPS_INVALID_F_ANGLE) 
    sendStrXY("C:N/A", 2, 10);
  else
  {
    char sz[32];
    if(course_degree)       // Print course in degrees mode
    {
      char sy[10];
      
      if (mode == 0)
        dtostrf(gps.f_course(),3,0,sy);
      else if (mode == 1)
        dtostrf(TinyGPS::course_to(flat, flon, SAVED_LAT, SAVED_LON),3,0,sy);
        
      sprintf(sz, "C:%s", sy);
      
      setXY(2, 15);
      for(int i=0;i<8;i++)     // print degree simbol
        SendChar(pgm_read_byte(myDregree+i));
    }    
    else                // Print course in cardinal mode
    {
      char tmp[3];
     
      if (mode == 0)
        sprintf(tmp, "%s", TinyGPS::cardinal(gps.f_course()));
      else if (mode == 1)
        sprintf(tmp, "%s", TinyGPS::cardinal(TinyGPS::course_to(flat, flon, SAVED_LAT, SAVED_LON)));
        
      int lon = strlen(tmp);
 
      sprintf(sz, "C:% 3s", tmp);
    }
      
    sendStrXY(sz, 2, 10);
  }
}


//======================//
// Prints distance between two points given by actual and saved coordinates.
// To do so, function gets the two mayor magnitudes and prints them.
static void sendDistanceBetwen(TinyGPS &gps) 
{
  unsigned long age;
  float flat, flon;
 
  gps.f_get_position(&flat, &flon, &age);
  if (flat == TinyGPS::GPS_INVALID_F_ANGLE)
  {
    sendDistance("000", " m");
    sendStrXY("m ", 5, 9);
    sendStrXY("000*", 5, 12);
  }
  else {
    // Distance in meters
    unsigned long int dist = (long int)TinyGPS::distance_between(flat, flon, SAVED_LAT, SAVED_LON);
    print_distance(dist);
 
  }
}

//======================//
// Prints distance.
static void print_distance (unsigned long int dist)
{
   char unit[10] = "m ";
   char sz[32];
   char next_unit[2];
   char tmp[32];
   unsigned long int little_ones;
   unsigned long int big_ones;
   
   if (dist >= 1000000000) 
    {
      little_ones = (dist % 1000000000) / 1000000;
      big_ones = (dist - (little_ones * 1000000)) / 1000000000;
      sprintf(next_unit, "%s", "M");
      sprintf(unit, "%s", "Gm");
    }
    else if (dist >= 1000000) 
    {
      little_ones = (dist % 1000000) / 1000;
      big_ones = (dist - (little_ones * 1000)) / 1000000;
      sprintf(next_unit, "%s", "K");
      sprintf(unit, "%s", "Mm");
    }
    else if (dist >= 1000) 
    {
      little_ones = dist % 1000;
      big_ones = ((dist - little_ones) / 1000);
      sprintf(next_unit, "%s", "m");
      sprintf(unit, "%s", "Km");
    }
    else
    {
        big_ones = dist;
        little_ones = 0;
        sprintf(next_unit, "%s", "*");
        sprintf(unit, "%s", "m ");
    }
      
    sprintf(sz, "%03d", big_ones);
      
    sprintf(tmp, "%03d", little_ones);
          
    sendDistance(sz, unit);
    sendStrXY(tmp, 5, 12);
    sendStrXY(next_unit, 5, 15);
}


//======================//
// Prints current sattelites being used by GPS module.
static void printSats(int sats, int X, int Y)
{
  if (sats == TinyGPS::GPS_INVALID_SATELLITES)
    sendStrXY("00 SAT", X, Y);
  else {
    char sz[7];
    (sats>9)?sprintf(sz, "%d SAT", sats):sprintf(sz, "0%d SAT", sats);
    sendStrXY(sz, X, Y);
  }
}


//======================//
// Prints altitude adjusting it to display representation.
static void printAlt(float altitud, int X, int Y)
{
  if (altitud == TinyGPS::GPS_INVALID_F_ALTITUDE)
    sendStrXY("00000 m", X, Y);
  else {
    char sz[32];
    int alt = (int)altitud;
    
    if (alt<0)
      sprintf(sz, "-%04d m", abs(alt));
    else
      sprintf(sz, "%05d m", alt);
      
    sendStrXY(sz, X, Y);
  }
}


//======================//
// Prints Speed and it's first decimal adjusting 0 in the left.
static void printSpeed(float val)
{
  if(val == TinyGPS::GPS_INVALID_F_SPEED)
  {
      sendSpeed("000");
      sendStrXY(".0",5,14);
  }
  else {
    char sx[5];
    char sy[5];
    char sz[5];
    int num = (int)val;
    float tmp = val - num;
    
    dtostrf(tmp,3,1,sy);
    sprintf(sx, ".%c", sy[2]);
    sprintf(sz, "%03d", num);
   
    sendSpeed(sz);
    sendStrXY(sx,5,14);
  }
}


//======================//
// Prints a floating coordinate yanking last two decimals for display
// fitting.
static void print_coord(float val, float invalid, int X, int Y)
{
  char sz[] = "*******";
  if (val == invalid)
  {
    sendStrXY(sz,X,Y);
  }
  else
  {
    dtostrf(val,6,4,sz);
    sendStrXY(sz,X,Y);
  }
}


//======================//
// As we don't have RTC this function prints date and time obtained by GPS.
// Function recongnices actual mode and prints date and time for each one.
static void print_date(TinyGPS &gps)
{
  int year;
  byte month, day, hourtmp, minute, second, hundredths;
  unsigned long age;
  char sz[17];
  char sz1[] = "**:**";
  char sz2[] = "**/**/****";
  int hour;
  
  gps.crack_datetime(&year, &month, &day, &hourtmp, &minute, &second, &hundredths, &age);
  
  hour = hourtmp;
  
  if (age == TinyGPS::GPS_INVALID_AGE) {
    if (mode == 0) {
      sprintf(sz, "%s %s", sz1, sz2);
      sendStrXY(sz,7,0);
    }
    else if (mode == 3) {
      sendStrXY("Syncing...",7,3);
    }
  }
  else
  {    
    char moment[3] = "PM";
    control_blink = !control_blink;
    hour+=TZ; // Time Zone
    
    if (hour >= 24)
    {
      ++day;
      hour -= 24;
    }
    else if (hour < 0)
    {
        --day;
        hour += 24;
    }

    if (control_clock && hour > 12) 
      hour -= 12;
    else
      moment[0] = 'A';
    
    if (control_blink)
      sprintf(sz1, "%02d:%02d", hour, minute);
    else
      sprintf(sz1, "%02d %02d", hour, minute);
        
    sprintf(sz2, "%02d/%02d/%02d", day, month, year);
    
    if (mode == 0) 
    {        
      sendStrXY(sz1, 7, 0);
      sendStrXY(sz2, 7, 6);    
    }
    else if (mode == 3)
    {
      printBigTime(sz1);
      sendStrXY(sz2, 7, 6);
      
      if(control_clock)
      {
        sendStrXY("(12h) ",7,0);
        sendCharXY(moment[0], 3, 15);
        sendCharXY(moment[1], 4, 15);
      }
      else
      {
        sendStrXY("(24h) ",7,0);
      }
    }
  }
}


//======================//
// Flushes the buffer in new software serial into the TinyGPS
// object. This function is ofently call to not loose data
// (almost every char is printed on display).
static bool feedgps()
{
  while (nss.available())
  {
 // char tmp = nss.read();
    if (gps.encode(nss.read()))
 // Serial.print(tmp);
 // if (gps.encode(tmp))
      return true;
  }
  return false;
}

//======================//
// Turns display on.
void displayOn(void)
{
    sendcommand(0xaf);        //display on
}

//======================//
// Turns display off.
void displayOff(void)
{
  sendcommand(0xae);		//display off
}

//======================//
// Clears the display by sendind 0 to all the screen map.
static void clear_display(void)
{
  unsigned char i,k;
  for(k=0;k<8;k++)
  {	
    setXY(k,0);    
    {
      for(i=0;i<128;i++)     //clear all COL
      {
        SendChar(0);         //clear all COL
        //delay(10);
      }
    }
  }
}


//======================//
// Prints 'km/h' in the screen in a big font. To avoid to create 
// an entirely new font from scratch, this justs prints a static
// image.
static void printKmh_unit(void) 
{
  int X = 3;
  int Y = 9;
  setXY(X,Y);
  int salto=0; 
  for(int i=0;i<40*3;i++)     // show 40 * 24 picture
  {
    SendChar(pgm_read_byte(kmh+i));
    if(salto == 39) {
      salto = 0;
      X++;
      setXY(X,Y);
    } else {
      salto++;
    }
  }  
}


//======================//
static void sendSpeed(char *string)
{

  int Y=6;
  int lon = strlen(string);
  if(lon == 3) {
    Y = 0;
  } else if (lon == 2) {
    Y = 3;
  } else if (lon == 1) {
    Y = 6;
  }
  
  int X = 2;
  while(*string)
  {
    printBigNumber(*string, X, Y);
    
    Y+=3;
    X=2;
    setXY(X,Y);
    *string++;
  }
}

//======================//
static void sendDistance(char *string, char *unit)
{
  int Y;
  int lon = strlen(string);
  if(lon == 3) {
    Y = 0;
  } else if (lon == 2) {
    Y = 3;
  } else if (lon == 1) {
    Y = 6;
  }
  
  int X = 2;
  while(*string)
  {
    printBigNumber(*string, X, Y);
    
    Y+=3;
    X=2;
    setXY(X,Y);
    *string++;
  }
  sendStrXY(unit, 5, 9);
}


//======================//
static void printBigTime(char *string)
{

  int Y;
  int lon = strlen(string);
  if(lon == 3) {
    Y = 0;
  } else if (lon == 2) {
    Y = 3;
  } else if (lon == 1) {
    Y = 6;
  }
  
  int X = 2;
  while(*string)
  {
    printBigNumber(*string, X, Y);
    
    Y+=3;
    X=2;
    setXY(X,Y);
    *string++;
  }
}

//======================//
// Prints timezone in timezone setting mode.
static void print_timezone (int timezone)
{
  char sz[10];
  int X = 2;
  int Y = 6;  
  sprintf(sz, "%d", abs(timezone));
  
  // print minus simbol
  if(timezone < 0) {
    int salto=0;
    int myX = X;
    int myY = Y-3;
    for(int i=0;i<96;i++)
    {
      SendChar(pgm_read_byte(minus+i));
     
      if(salto == 23) {
        salto = 0;
        myX++;
        setXY(myX,myY);
      } else {
        salto++;
      }
    }
  }
  else
  {
    printBigNumber(' ', X, Y-3);
  }
  
  if(strlen(sz) == 2) 
    printBigNumber(sz[1], X, Y+3);
  else
    printBigNumber(' ', X, Y+3);
     
  printBigNumber(sz[0], X, Y);
}

//======================//
// Prints a display big number (96 bytes) in coordinates X Y,
// being multiples of 8. This means we have 16 COLS (0-15) 
// and 8 ROWS (0-7).
static void printBigNumber(char string, int X, int Y)
{    
  setXY(X,Y);
  int salto=0;
  for(int i=0;i<96;i++)
  {
    if(string == ' ') {
      SendChar(0);
    } else 
      SendChar(pgm_read_byte(bigNumbers[string-0x30]+i));
   
    if(salto == 23) {
      salto = 0;
      X++;
      setXY(X,Y);
    } else {
      salto++;
    }
  feedgps();
  }
}

//======================//
// Actually this sends a byte, not a char to draw in the display. 
// Display's chars uses 8 byte font the small ones and 96 bytes
// for the big number font.
static void SendChar(unsigned char data) 
{
  if (interrupt && !doing_menu) return;   // Stop printing only if interrupt is call but not in button functions
  
  Wire.beginTransmission(OLED_address); // begin transmitting
  Wire.write(0x40);//data mode
  Wire.write(data);
  Wire.endTransmission();    // stop transmitting
}

//======================//
// Prints a display char (not just a byte) in coordinates X Y,
// being multiples of 8. This means we have 16 COLS (0-15) 
// and 8 ROWS (0-7).
static void sendCharXY(unsigned char data, int X, int Y)
{
  if (interrupt && !doing_menu) return; // Stop printing only if interrupt is call but not in button functions
  
  setXY(X, Y);
  Wire.beginTransmission(OLED_address); // begin transmitting
  Wire.write(0x40);//data mode
  
  for(int i=0;i<8;i++)
    Wire.write(pgm_read_byte(myFont[data-0x20]+i));
    
  Wire.endTransmission();    // stop transmitting
}

//======================//
// Used to send commands to the display.
static void sendcommand(unsigned char com)
{
  Wire.beginTransmission(OLED_address);     //begin transmitting
  Wire.write(0x80);                          //command mode
  Wire.write(com);
  Wire.endTransmission();                    // stop transmitting
}

//======================//
// Set the cursor position in a 16 COL * 8 ROW map.
static void setXY(unsigned char row,unsigned char col)
{
  sendcommand(0xb0+row);                //set page address
  sendcommand(0x00+(8*col&0x0f));       //set low col address
  sendcommand(0x10+((8*col>>4)&0x0f));  //set high col address
}


//======================//
// Prints a string regardless the cursor position.
static void sendStr(unsigned char *string)
{
  unsigned char i=0;
  while(*string)
  {
    for(i=0;i<8;i++)
    {
      SendChar(pgm_read_byte(myFont[*string-0x20]+i));
    }
    *string++;
    feedgps();    // empty serial buffer every char is printed
  }
}

//======================//
// Prints a string in coordinates X Y, being multiples of 8.
// This means we have 16 COLS (0-15) and 8 ROWS (0-7).
static void sendStrXY( char *string, int X, int Y)
{
  setXY(X,Y);
  unsigned char i=0;
  while(*string)
  {
    for(i=0;i<8;i++)
    {
      SendChar(pgm_read_byte(myFont[*string-0x20]+i));
    }
    *string++;
    feedgps();    // empty serial buffer every char is printed
  }
}

//======================//
// Inits oled and draws logo at startup
static void init_OLED(void)
{
  sendcommand(0xae);		//display off
  sendcommand(0xa6);            //Set Normal Display (default)

  clear_display();
  sendcommand(0x2e);            // stop scroll
  //----------------------------REVERSE comments----------------------------//
  //  sendcommand(0xa0);		//seg re-map 0->127(default)
  //  sendcommand(0xa1);		//seg re-map 127->0
  //  sendcommand(0xc8);
  //  delay(1000);
  //----------------------------REVERSE comments----------------------------//
  // sendcommand(0xa7);  //Set Inverse Display  
  // sendcommand(0xae);		//display off
  sendcommand(0x20);            //Set Memory Addressing Mode
  sendcommand(0x00);            //Set Memory Addressing Mode ab Horizontal addressing mode
  //  sendcommand(0x02);         // Set Memory Addressing Mode ab Page addressing mode(RESET)  
  
  setXY(0,0);

  for(int i=0;i<128*8;i++)     // show 128* 64 Logo
  {
    SendChar(pgm_read_byte(logo+i));
  }
  sendcommand(0xaf);		//display on
  
  sendStrXY("by KaR]V[aN",7,5);
  delay(3000); 
}
Контактная информация:
Реклама
Потрогал лапой паяльник
Сообщения: 312
Зарегистрирован: Вс июл 29, 2012 16:25:39

Сообщение mas123 »

Evgeny1 писал(а):дисплей SSD1306 имеет у себя в контроллере память и что-то там запоминает и после повторного включения питания девайс работать отказывается
Не нашел в даташите на SSD1306 ничего про наличие там энергонезависимой памяти. Так что не понимаю - как он может что-то "запомнить" и не запуститься при повторном включении питания.
Правильно ли формируется сигнал сброса на индикатор? Правильно ли формируется диаграмма i2c/spi?
Правильно ли выдаются инициализирующие команды?
Evgeny1 писал(а):у него контроллер SSD1306 и i2c там вроде как программный
У SSD1306 интерфейс может быть как i2c, так и SPI.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4106
Зарегистрирован: Пн авг 10, 2009 01:18:55
Откуда: Электросталь

Сообщение Evgeny1 »

Так что не понимаю - как он может что-то "запомнить" и не запуститься при повторном включении питания
еслиб я знал, то ткут бы не спрашивал))
Правильно ли формируется сигнал сброса на индикатор?
вообще он изначально в проекте этом не подключается никуда
но я пробовал дергать его RC цепочкой в момент запуска девайса - результата никакого не дает

Правильно ли формируется диаграмма i2c/spi?
Правильно ли выдаются инициализирующие команды?
эммм :oops: :oops:
У SSD1306 интерфейс может быть как i2c, так и SPI.
у него есть и тот и тот как хочешь так и подключаешь (перемычку только перекидываешь и все)
Контактная информация:
Потрогал лапой паяльник
Сообщения: 312
Зарегистрирован: Вс июл 29, 2012 16:25:39

Сообщение mas123 »

Evgeny1 писал(а):
Так что не понимаю - как он может что-то "запомнить" и не запуститься при повторном включении питания
еслиб я знал, то ткут бы не спрашивал))
Это был такой тонкий намёк, что не в запоминании чего-то там дело. :)))
Evgeny1 писал(а):
Правильно ли формируется сигнал сброса на индикатор?
вообще он изначально в проекте этом не подключается никуда
В этом мире ходит байка про то, как цифровой вход, висящий в воздухе, влёгкую ловит всякий "мусор" от всевозможных наводок.
Сказки, наверное? И потдяжка через резистор к плюсу или земле - это злостное расточительство резисторов! :shock:
Evgeny1 писал(а):но я пробовал дергать его RC цепочкой в момент запуска девайса - результата никакого не дает
Сурово, сурово. Дергаешь RC-задержкой?
А ты уверен, что к моменту начала и окончания импульса сброса контроллер ещё не начал работать с LCD? А то вдруг, AVR'ка уже настроила LCD на работу, а тут бац - подаем сигнал сброса. А потом удивляемся - чего экран не горит.

Или вот ещё веселей: успеваем подать импульс сброса до начала работы контроллера с экраном. А AVR ноги интерфейса связи с экраном ещё не настроила на выход - т.е. для LCD все входа висят в воздухе, и имеют возможность "нахватать" импульсов - вот теперь скажи, в каком состоянии находится экран? Сколько бит "мусора" он уже принял?

Сам контроллер должен формировать сброс для LCD!
Причем формировать так, чтобы в момент окончания сброса i2c/spi интерфейс был уже в проинициализированном состоянии: CS там в "1", выход клоков в нужном (неактивном) уровне.
Evgeny1 писал(а):
Правильно ли формируется диаграмма i2c/spi?
Правильно ли выдаются инициализирующие команды?
эммм :oops: :oops:
А что тут такого? Любой LCD после включения нужно запрограммировать на нужный режим работы.
В даташите описана стартовая последовательность команд.
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Аватара пользователя
Сообщения: 4106
Зарегистрирован: Пн авг 10, 2009 01:18:55
Откуда: Электросталь

Сообщение Evgeny1 »

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

Я в программировании не силен, но в этом gps проекте у чувака отлично работает и без сброса, и тестовая картинка которую друг сделал (скетч я прикладывал) тоже отлично работает, а вот тот никак не хочет стартовать после 10-15 минут без питания! Если например вырубить и подождать 2-3минуты, то запускается, а если дольше то уже нет((
Контактная информация:
Реклама
Друг Кота
Сообщения: 19495
Зарегистрирован: Чт фев 20, 2014 18:57:55

Сообщение Morroc »

Другого экранчика нет я так понимаю ? А то мало ли... может совсем китайский. Я для аналогичного oled дисплея на ssd1306 (только в нем полоса желтых пикселов сверху) с ардуиной на avr и на stm32 (maple) использовал готовую библиотеку Adafruit_SSD1306, проблем не было.
"Вся военная пропаганда, все крики, ложь и ненависть исходят от людей, которые на эту войну не пойдут !" / Джордж Оруэлл /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4106
Зарегистрирован: Пн авг 10, 2009 01:18:55
Откуда: Электросталь

Сообщение Evgeny1 »

Дисплеи есть 5 шт и со всеми одно и тоже
Вот та картинка тестовая которую друг сделал она через библиотеку работает да
А этот проект он вроде как написан напрямую без библиотеки дисплея
Контактная информация:
Друг Кота
Сообщения: 19495
Зарегистрирован: Чт фев 20, 2014 18:57:55

Сообщение Morroc »

Ну я как бы на это и намекал. Надо или сравнивать код работы с дисплеем с рабочей библиотекой или просто библиотеку вкорячить в этот проект вместо тех функций.
"Вся военная пропаганда, все крики, ложь и ненависть исходят от людей, которые на эту войну не пойдут !" / Джордж Оруэлл /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
Потрогал лапой паяльник
Сообщения: 312
Зарегистрирован: Вс июл 29, 2012 16:25:39

Сообщение mas123 »

Evgeny1 писал(а):Вот та картинка тестовая которую друг сделал она через библиотеку работает да
А этот проект он вроде как написан напрямую без библиотеки дисплея
Тогда остаётся простой путь - сравнить код работы с дисплеем "в библиотеке" и свой. И найти критическое отличи, скорее всего оно как раз в инициализации дисплея и будет.
В приведенном примере я как-то не увидел инициализации дисплея - только команды откл и вкл. Этого недостаточно для работы.
Друг Кота
Аватара пользователя
Сообщения: 4106
Зарегистрирован: Пн авг 10, 2009 01:18:55
Откуда: Электросталь

Сообщение Evgeny1 »

В приведенном примере я как-то не увидел инициализации дисплея - только команды откл и вкл. Этого недостаточно для работы.
однако же все работает

а вот то, что нужно заставить нормально работать
Спойлер

Код: Выделить всё

//======================//
//                                                          //
//    GPS Toy By KaR]V[aN, http://karman.homelinux.net      //
//    Thanks to the Arduino comunity for providing code,    //
//    libraries and platforms. Also many thanks to Nitz,    //
//    whose coding skills helped so much.                   //
//                                                          //
//======================//

/* 
 * This is a simple GPS Toy/'on board computer' that shows GPS
 * data in a tiny 128x64 OLED display (I2C driven, 0.96").
 * Because being I2C display the frame rate is very slow 
 * but saves pins for future use.
 */
 
#include <EEPROM.h>
#include "EEPROMAnything.h"
#include "mySoftwareSerial.h" 
#include <TinyGPS.h>
#include <Wire.h>
#include <avr/pgmspace.h>

// So, why use a custom software serial? This addresses a problem sharing 
// interrupts between pinchangeint and software serial, by disabling the 
// unsued ports on both of them. Meanwhile pinchangeint allows easy disabling,
// newsoftwareserial doesn't, so have to comment code. More info:
// http://code.google.com/p/arduino-pinchangeint/issues/detail?id=7

//---------------FONT + GRAPHIC-----------------------------//
#include "data.h"
//======================//

#define OLED_address  0x3c

// I'll attach interrupt to digital pins 4 and 5, both 
// on port D. Both ports B and C are to be disabled:
#define NO_PORTB_PINCHANGES // to indicate that port b will not be used for pin change interrupts
#define NO_PORTC_PINCHANGES // to indicate that port c will not be used for pin change interrupts
#include <PinChangeInt.h>

TinyGPS gps;
SoftwareSerial nss(9, 8);
static bool feedgps();
const int buttonA = 4;
const int buttonB = 5;
unsigned int buttonStateB = 0;      
unsigned int buttonStateA = 0;       
unsigned int mode=0;
bool course_degree = false;
bool control_blink = false;
bool control_clock = false;
bool interrupt = false;
bool doing_menu = false;
float SAVED_LAT = 0.0, SAVED_LON = 0.0, LAST_LAT = 0.0, LAST_LON = 0.0;
unsigned int TZ = 2;
unsigned long int tripDistance = 0;
static const byte settings_version = B00000001;
bool fix_first = 1;
float last_course = 0.0;


//---------------Saved Data Map-----------------------------//
// Bytes  Size  Purpose
// ····························································
// 0      1     Settings Version
// 1-4    4     Saved Latitude
// 5-8    4     Saved Longitude
// 9-10   2     Saved Mode
// 11     1     Saved Course preference (Degrees - Cardinal)
// 12     1     Saved Clock prefence (12h - 24h)
// 13-14  2     Saved Time Zone
// 15-18  4     Saved trip distance
//======================//


void setup()
{
  // Load previous Settings
  byte read_settings_version;
  EEPROM_readAnything(0, read_settings_version);
 
  if(settings_version == read_settings_version) // If version matchs, load vars from EEPROM
  {  
    EEPROM_readAnything(1, SAVED_LAT);
    EEPROM_readAnything(5, SAVED_LON);
    EEPROM_readAnything(9, mode);
    EEPROM_readAnything(11, course_degree);
    EEPROM_readAnything(12, control_clock);
    EEPROM_readAnything(13, TZ);
    EEPROM_readAnything(15, tripDistance);
  }
  else                                          // If not, initialize with defaults
  {
    EEPROM_writeAnything(0, settings_version);
    EEPROM_writeAnything(1, SAVED_LAT);
    EEPROM_writeAnything(5, SAVED_LON);
    EEPROM_writeAnything(9, mode);
    EEPROM_writeAnything(11, course_degree);
    EEPROM_writeAnything(12, control_clock);
    EEPROM_writeAnything(13, TZ);
    EEPROM_writeAnything(15, tripDistance);
  }
  
  // Buttons...
  pinMode(buttonA, INPUT);
  pinMode(buttonB, INPUT);    
  digitalWrite(buttonA, LOW);
  digitalWrite(buttonB, LOW);
  
  // Attach interrupts to both buttons on rising change
  PCintPort::attachInterrupt(buttonA, &interrupt_button, RISING); 
  PCintPort::attachInterrupt(buttonB, &interrupt_button, RISING); 
  
  // Initialize Software Serial, I2C and OLED Display
  nss.begin(4800);
  Wire.begin();
  init_OLED();

  reset_display();           // Clear logo and load saved mode
  nss.listen();
  //Serial.begin(115200);
}


//======================//
void loop()
{  
  // Read Button state
  if (buttonStateA == HIGH || buttonStateB == HIGH)
  {
    doing_menu = true;                            // we are in button fuctions, ignore interrupt bool
    unsigned long button_delay = millis();
    
    while (millis() - button_delay < 50) 
    {
      if (buttonStateA == LOW) 
        buttonStateA = digitalRead(buttonA);
      if (buttonStateB == LOW) 
        buttonStateB = digitalRead(buttonB);
    }
      
    // Both buttons pushed
    if (buttonStateB == HIGH && buttonStateA == HIGH)
    {
      displayOff();
      setXY(0,0);
  
      for(int i=0;i<128*8;i++)     // show 128* 64 Logo
        SendChar(pgm_read_byte(logo+i));
    
      displayOn();
      sendStrXY("Carlos Sancho",7,2);
      sendStrXY("v1.0", 0, 12);
      delay(5000);
      clear_display();
      sendStrXY("http://karman.homelinux.net",0,0);
      sendStrXY("Using TinyGPS by Mikal Hart",3,0);
      delay(5000);
      reset_display();
    }
    
    // Menu/mode button
    else if(buttonStateA == HIGH && buttonStateB == LOW) 
    {
      // Change mode
      if (mode == 0) 
        mode = 1;
      
      else if (mode == 1) 
        mode = 2;
        
      else if (mode == 2)
        mode = 3;
        
      else if (mode == 3)
        mode = 0;
      
      EEPROM_writeAnything(9, mode); // Save mode
      reset_display();
    } 
    
    // Other button
    else if (buttonStateB == HIGH && buttonStateA == LOW) 
    {
      reset_buttons();
      
      // Change cardinal <-> degrees
      if (mode == 0) 
      {
        course_degree = !course_degree;
        EEPROM_writeAnything(11, course_degree);
        reset_display();
      }
      
      // Memorize current location after 3 seconds pushing button
      else if (mode == 1) 
      {
        displayOff();
        clear_display();
        sendStrXY("Memorizing in: ", 0, 0);
        printBigNumber('3', 3 ,6);
        displayOn();
        boolean exit = 0;
        unsigned long start = millis();
        while (digitalRead(buttonB) == HIGH && !exit)
        {          
          if (millis() - start > 3000) 
          {
            clear_display();
            exit = true;
            sendStrXY("Coordinates memorized:", 0, 0);
            saveActualLoc(gps);
            delay(2000);
          } 
          
          else if (millis() - start > 2000)
            printBigNumber('1', 3 ,6);
            
          else if (millis() - start > 1000)
            printBigNumber('2', 3 ,6);
        }
        reset_display();
      }
      
      // Reset trip 
      else if (mode == 2)
      {
        displayOff();
        clear_display();
        sendStrXY("Clearing in: ", 0, 0);
        printBigNumber('3', 3 ,6);
        displayOn();
        boolean exit = 0;
        unsigned long start = millis();
        while (digitalRead(buttonB) == HIGH && !exit)
        {          
          if (millis() - start > 3000) 
          {
            clear_display();
            exit = true;
            unsigned long age;
            float flat, flon;
            gps.f_get_position(&flat, &flon, &age);
            sendStrXY("Trip reseted", 0, 0);
            tripDistance = 0;
            LAST_LAT = flat;
            LAST_LON = flon;
            EEPROM_writeAnything(15, tripDistance);
            delay(2000);
          } 
          
          else if (millis() - start > 2000)
            printBigNumber('1', 3 ,6);
            
          else if (millis() - start > 1000)
            printBigNumber('2', 3 ,6);
        }
        reset_display();
      }
      
      // Change clock hour mode, 12h <-> 24h in short push (< 3 secs)
      // In long push (> 3 sec) enters in time zone setting mode
      else if (mode == 3)
      {
        reset_buttons();
        boolean exit = 0;
        boolean mode_timezone = false;
        unsigned long start = millis();
        while (digitalRead(buttonB) == HIGH && !exit)
        {
          if (millis() - start > 3000) 
          {
            exit = true;
            mode_timezone = true;
          }
        }
        
        if (mode_timezone)
        {
          displayOff();
          clear_display();
          sendStrXY("Select TimeZone:", 0, 0);
          sendStrXY("Menu to set", 7, 2);
          displayOn();
          reset_buttons();
          bool print_TZ = true;
          while(buttonStateA != HIGH)
          {
            
            if (buttonStateB == HIGH) 
            {
              // this loop avoids false contacts of defective switches and sparks
              while (digitalRead(buttonB) != LOW)
                delay(10); 
              
              buttonStateB = LOW;
              TZ++;
              print_TZ = true;
            }
            
            if (TZ == 13)
              TZ = -11;
            
            // Avoid to print always same value
            if (print_TZ) {
              print_timezone(TZ);
              print_TZ = false;
            }
            
            delay(10); // to not fall into an endless loop. 
          }
          EEPROM_writeAnything(13, TZ);
        }
        else 
        {
          control_clock = !control_clock;
          EEPROM_writeAnything(12, control_clock);
        }
        reset_display();
      }
    }
    reset_buttons();
    doing_menu = false;    // Reset both vars on buttons exit
    interrupt = false;
  }
  
  
  // check if new data is avaiable
  if (feedgps())
     updateScreen(gps);  // and prints it    
     
  // update trip distance
  udpateTrip(gps);
}

// Change button state on interrupt
void interrupt_button (void)
{
  if (PCintPort::arduinoPin == buttonA)
    buttonStateA = HIGH;
  else if (PCintPort::arduinoPin == buttonB)
    buttonStateB = HIGH;
    
  interrupt = true;          // Stop printing on display, speeds up response.
}

// Resets button states
static void reset_buttons(void)
{
  buttonStateA = LOW;
  buttonStateB = LOW;
}

//======================//
// Resets display depending on the actual mode.
static void reset_display(void)
{
  displayOff();
  clear_display();
  if (mode == 0)
  {
    printKmh_unit();
  }
  else if (mode == 1) 
  {
    //nothing here by now
  } 
  else if (mode == 2) 
  {
    sendStrXY("Trip sum:", 0, 3);
  }
  else if (mode == 3)
  {
    sendStrXY("Atomic GPS Watch",0,0);
  }  
  updateScreen(gps);
  displayOn();
}

//======================//
// Updates screen depending on the actual mode.
static void updateScreen(TinyGPS &gps) 
{
  unsigned long age;
  float flat, flon;
  gps.f_get_position(&flat, &flon, &age);
  
  if (mode == 0)
  {
    print_date(gps);
    printAlt(gps.f_altitude(), 0, 0);
    printSpeed(gps.f_speed_kmph());
    printSats(gps.satellites(), 0, 10);
    feedgps();
    printCourse(gps); 
  }  
  else if (mode == 1)
  { 
    print_coord(flat, TinyGPS::GPS_INVALID_F_ANGLE, 0, 0);
    print_coord(flon, TinyGPS::GPS_INVALID_F_ANGLE, 0, 9);
    sendDistanceBetwen(gps);
    printCourse(gps);
    print_coord(SAVED_LAT, TinyGPS::GPS_INVALID_F_ANGLE, 7, 0);
    print_coord(SAVED_LON, TinyGPS::GPS_INVALID_F_ANGLE, 7, 9);
  }
  else if (mode == 2)
  {
    printTrip();
  }
  else if (mode == 3)
  {
    print_date(gps);
  }
}



//======================//
// Shows and saves actual coordinates
static void saveActualLoc(TinyGPS &gps)
{
  unsigned long age;
  float flat, flon;
 
  gps.f_get_position(&flat, &flon, &age);
  sendStrXY("Lat: ", 4, 0);
  sendStrXY("Lon: ", 5, 0);
  print_coord(flat, TinyGPS::GPS_INVALID_F_ANGLE, 4, 5);
  print_coord(flon, TinyGPS::GPS_INVALID_F_ANGLE, 5, 5);
  SAVED_LAT = flat;
  SAVED_LON = flon;
  EEPROM_writeAnything(1, SAVED_LAT);
  EEPROM_writeAnything(5, SAVED_LON);
}

//======================//
// Prints display trip update
static void printTrip () {
 /* char sz[32];
  sprintf(sz, "RAW: %d", tripDistance);
  sendStrXY(sz, 7, 0);*/
  print_distance(tripDistance);
}

//======================//
// Gets current location and if > 20, sums to trip global var.
static void udpateTrip (TinyGPS &gps) {
  unsigned long age;
  float flat, flon;
  int max_dist = 25;
 
  gps.f_get_position(&flat, &flon, &age);
  if (flat == TinyGPS::GPS_INVALID_F_ANGLE)
    return;
  else {
    
    int mySpeed = (int)gps.f_speed_kmph();
    
    if(mySpeed > 5) 
      max_dist = 20;
    if(mySpeed > 10) 
      max_dist = 15;
    if(mySpeed > 15) 
      max_dist = 5;
    
    if(fix_first) 
    {
      LAST_LAT = flat;
      LAST_LON = flon;
      fix_first = false;
    } 
    else 
    {
    
      // Distance in meters
      unsigned long int dist = (long int)TinyGPS::distance_between(flat, flon, LAST_LAT, LAST_LON);

      if (dist > max_dist)   
      {
        
        tripDistance += dist;
        
        LAST_LAT = flat;
        LAST_LON = flon;
        EEPROM_writeAnything(15, tripDistance);
      }
    }   
  }
}

//======================//
// Prints actual course or course to a point (distance mode) 
// in cardinal or dregree mode.
static void printCourse(TinyGPS &gps) 
{
  unsigned long age;
  float flat, flon;
  gps.f_get_position(&flat, &flon, &age);
  
  if (flat == TinyGPS::GPS_INVALID_F_ANGLE) 
    sendStrXY("C:N/A", 2, 10);
  else
  {
    char sz[32];
    if(course_degree)       // Print course in degrees mode
    {
      char sy[10];
      
      if (mode == 0)
        dtostrf(gps.f_course(),3,0,sy);
      else if (mode == 1)
        dtostrf(TinyGPS::course_to(flat, flon, SAVED_LAT, SAVED_LON),3,0,sy);
        
      sprintf(sz, "C:%s", sy);
      
      setXY(2, 15);
      for(int i=0;i<8;i++)     // print degree simbol
        SendChar(pgm_read_byte(myDregree+i));
    }    
    else                // Print course in cardinal mode
    {
      char tmp[3];
     
      if (mode == 0)
        sprintf(tmp, "%s", TinyGPS::cardinal(gps.f_course()));
      else if (mode == 1)
        sprintf(tmp, "%s", TinyGPS::cardinal(TinyGPS::course_to(flat, flon, SAVED_LAT, SAVED_LON)));
        
      int lon = strlen(tmp);
 
      sprintf(sz, "C:% 3s", tmp);
    }
      
    sendStrXY(sz, 2, 10);
  }
}


//======================//
// Prints distance between two points given by actual and saved coordinates.
// To do so, function gets the two mayor magnitudes and prints them.
static void sendDistanceBetwen(TinyGPS &gps) 
{
  unsigned long age;
  float flat, flon;
 
  gps.f_get_position(&flat, &flon, &age);
  if (flat == TinyGPS::GPS_INVALID_F_ANGLE)
  {
    sendDistance("000", " m");
    sendStrXY("m ", 5, 9);
    sendStrXY("000*", 5, 12);
  }
  else {
    // Distance in meters
    unsigned long int dist = (long int)TinyGPS::distance_between(flat, flon, SAVED_LAT, SAVED_LON);
    print_distance(dist);
 
  }
}

//======================//
// Prints distance.
static void print_distance (unsigned long int dist)
{
   char unit[10] = "m ";
   char sz[32];
   char next_unit[2];
   char tmp[32];
   unsigned long int little_ones;
   unsigned long int big_ones;
   
   if (dist >= 1000000000) 
    {
      little_ones = (dist % 1000000000) / 1000000;
      big_ones = (dist - (little_ones * 1000000)) / 1000000000;
      sprintf(next_unit, "%s", "M");
      sprintf(unit, "%s", "Gm");
    }
    else if (dist >= 1000000) 
    {
      little_ones = (dist % 1000000) / 1000;
      big_ones = (dist - (little_ones * 1000)) / 1000000;
      sprintf(next_unit, "%s", "K");
      sprintf(unit, "%s", "Mm");
    }
    else if (dist >= 1000) 
    {
      little_ones = dist % 1000;
      big_ones = ((dist - little_ones) / 1000);
      sprintf(next_unit, "%s", "m");
      sprintf(unit, "%s", "Km");
    }
    else
    {
        big_ones = dist;
        little_ones = 0;
        sprintf(next_unit, "%s", "*");
        sprintf(unit, "%s", "m ");
    }
      
    sprintf(sz, "%03d", big_ones);
      
    sprintf(tmp, "%03d", little_ones);
          
    sendDistance(sz, unit);
    sendStrXY(tmp, 5, 12);
    sendStrXY(next_unit, 5, 15);
}


//======================//
// Prints current sattelites being used by GPS module.
static void printSats(int sats, int X, int Y)
{
  if (sats == TinyGPS::GPS_INVALID_SATELLITES)
    sendStrXY("00 SAT", X, Y);
  else {
    char sz[7];
    (sats>9)?sprintf(sz, "%d SAT", sats):sprintf(sz, "0%d SAT", sats);
    sendStrXY(sz, X, Y);
  }
}


//======================//
// Prints altitude adjusting it to display representation.
static void printAlt(float altitud, int X, int Y)
{
  if (altitud == TinyGPS::GPS_INVALID_F_ALTITUDE)
    sendStrXY("00000 m", X, Y);
  else {
    char sz[32];
    int alt = (int)altitud;
    
    if (alt<0)
      sprintf(sz, "-%04d m", abs(alt));
    else
      sprintf(sz, "%05d m", alt);
      
    sendStrXY(sz, X, Y);
  }
}


//======================//
// Prints Speed and it's first decimal adjusting 0 in the left.
static void printSpeed(float val)
{
  if(val == TinyGPS::GPS_INVALID_F_SPEED)
  {
      sendSpeed("000");
      sendStrXY(".0",5,14);
  }
  else {
    char sx[5];
    char sy[5];
    char sz[5];
    int num = (int)val;
    float tmp = val - num;
    
    dtostrf(tmp,3,1,sy);
    sprintf(sx, ".%c", sy[2]);
    sprintf(sz, "%03d", num);
   
    sendSpeed(sz);
    sendStrXY(sx,5,14);
  }
}


//======================//
// Prints a floating coordinate yanking last two decimals for display
// fitting.
static void print_coord(float val, float invalid, int X, int Y)
{
  char sz[] = "*******";
  if (val == invalid)
  {
    sendStrXY(sz,X,Y);
  }
  else
  {
    dtostrf(val,6,4,sz);
    sendStrXY(sz,X,Y);
  }
}


//======================//
// As we don't have RTC this function prints date and time obtained by GPS.
// Function recongnices actual mode and prints date and time for each one.
static void print_date(TinyGPS &gps)
{
  int year;
  byte month, day, hourtmp, minute, second, hundredths;
  unsigned long age;
  char sz[17];
  char sz1[] = "**:**";
  char sz2[] = "**/**/****";
  int hour;
  
  gps.crack_datetime(&year, &month, &day, &hourtmp, &minute, &second, &hundredths, &age);
  
  hour = hourtmp;
  
  if (age == TinyGPS::GPS_INVALID_AGE) {
    if (mode == 0) {
      sprintf(sz, "%s %s", sz1, sz2);
      sendStrXY(sz,7,0);
    }
    else if (mode == 3) {
      sendStrXY("Syncing...",7,3);
    }
  }
  else
  {    
    char moment[3] = "PM";
    control_blink = !control_blink;
    hour+=TZ; // Time Zone
    
    if (hour >= 24)
    {
      ++day;
      hour -= 24;
    }
    else if (hour < 0)
    {
        --day;
        hour += 24;
    }

    if (control_clock && hour > 12) 
      hour -= 12;
    else
      moment[0] = 'A';
    
    if (control_blink)
      sprintf(sz1, "%02d:%02d", hour, minute);
    else
      sprintf(sz1, "%02d %02d", hour, minute);
        
    sprintf(sz2, "%02d/%02d/%02d", day, month, year);
    
    if (mode == 0) 
    {        
      sendStrXY(sz1, 7, 0);
      sendStrXY(sz2, 7, 6);    
    }
    else if (mode == 3)
    {
      printBigTime(sz1);
      sendStrXY(sz2, 7, 6);
      
      if(control_clock)
      {
        sendStrXY("(12h) ",7,0);
        sendCharXY(moment[0], 3, 15);
        sendCharXY(moment[1], 4, 15);
      }
      else
      {
        sendStrXY("(24h) ",7,0);
      }
    }
  }
}


//======================//
// Flushes the buffer in new software serial into the TinyGPS
// object. This function is ofently call to not loose data
// (almost every char is printed on display).
static bool feedgps()
{
  while (nss.available())
  {
 // char tmp = nss.read();
    if (gps.encode(nss.read()))
 // Serial.print(tmp);
 // if (gps.encode(tmp))
      return true;
  }
  return false;
}

//======================//
// Turns display on.
void displayOn(void)
{
    sendcommand(0xaf);        //display on
}

//======================//
// Turns display off.
void displayOff(void)
{
  sendcommand(0xae);		//display off
}

//======================//
// Clears the display by sendind 0 to all the screen map.
static void clear_display(void)
{
  unsigned char i,k;
  for(k=0;k<8;k++)
  {	
    setXY(k,0);    
    {
      for(i=0;i<128;i++)     //clear all COL
      {
        SendChar(0);         //clear all COL
        //delay(10);
      }
    }
  }
}


//======================//
// Prints 'km/h' in the screen in a big font. To avoid to create 
// an entirely new font from scratch, this justs prints a static
// image.
static void printKmh_unit(void) 
{
  int X = 3;
  int Y = 9;
  setXY(X,Y);
  int salto=0; 
  for(int i=0;i<40*3;i++)     // show 40 * 24 picture
  {
    SendChar(pgm_read_byte(kmh+i));
    if(salto == 39) {
      salto = 0;
      X++;
      setXY(X,Y);
    } else {
      salto++;
    }
  }  
}


//======================//
static void sendSpeed(char *string)
{

  int Y=6;
  int lon = strlen(string);
  if(lon == 3) {
    Y = 0;
  } else if (lon == 2) {
    Y = 3;
  } else if (lon == 1) {
    Y = 6;
  }
  
  int X = 2;
  while(*string)
  {
    printBigNumber(*string, X, Y);
    
    Y+=3;
    X=2;
    setXY(X,Y);
    *string++;
  }
}

//======================//
static void sendDistance(char *string, char *unit)
{
  int Y;
  int lon = strlen(string);
  if(lon == 3) {
    Y = 0;
  } else if (lon == 2) {
    Y = 3;
  } else if (lon == 1) {
    Y = 6;
  }
  
  int X = 2;
  while(*string)
  {
    printBigNumber(*string, X, Y);
    
    Y+=3;
    X=2;
    setXY(X,Y);
    *string++;
  }
  sendStrXY(unit, 5, 9);
}


//======================//
static void printBigTime(char *string)
{

  int Y;
  int lon = strlen(string);
  if(lon == 3) {
    Y = 0;
  } else if (lon == 2) {
    Y = 3;
  } else if (lon == 1) {
    Y = 6;
  }
  
  int X = 2;
  while(*string)
  {
    printBigNumber(*string, X, Y);
    
    Y+=3;
    X=2;
    setXY(X,Y);
    *string++;
  }
}

//======================//
// Prints timezone in timezone setting mode.
static void print_timezone (int timezone)
{
  char sz[10];
  int X = 2;
  int Y = 6;  
  sprintf(sz, "%d", abs(timezone));
  
  // print minus simbol
  if(timezone < 0) {
    int salto=0;
    int myX = X;
    int myY = Y-3;
    for(int i=0;i<96;i++)
    {
      SendChar(pgm_read_byte(minus+i));
     
      if(salto == 23) {
        salto = 0;
        myX++;
        setXY(myX,myY);
      } else {
        salto++;
      }
    }
  }
  else
  {
    printBigNumber(' ', X, Y-3);
  }
  
  if(strlen(sz) == 2) 
    printBigNumber(sz[1], X, Y+3);
  else
    printBigNumber(' ', X, Y+3);
     
  printBigNumber(sz[0], X, Y);
}

//======================//
// Prints a display big number (96 bytes) in coordinates X Y,
// being multiples of 8. This means we have 16 COLS (0-15) 
// and 8 ROWS (0-7).
static void printBigNumber(char string, int X, int Y)
{    
  setXY(X,Y);
  int salto=0;
  for(int i=0;i<96;i++)
  {
    if(string == ' ') {
      SendChar(0);
    } else 
      SendChar(pgm_read_byte(bigNumbers[string-0x30]+i));
   
    if(salto == 23) {
      salto = 0;
      X++;
      setXY(X,Y);
    } else {
      salto++;
    }
  feedgps();
  }
}

//======================//
// Actually this sends a byte, not a char to draw in the display. 
// Display's chars uses 8 byte font the small ones and 96 bytes
// for the big number font.
static void SendChar(unsigned char data) 
{
  if (interrupt && !doing_menu) return;   // Stop printing only if interrupt is call but not in button functions
  
  Wire.beginTransmission(OLED_address); // begin transmitting
  Wire.write(0x40);//data mode
  Wire.write(data);
  Wire.endTransmission();    // stop transmitting
}

//======================//
// Prints a display char (not just a byte) in coordinates X Y,
// being multiples of 8. This means we have 16 COLS (0-15) 
// and 8 ROWS (0-7).
static void sendCharXY(unsigned char data, int X, int Y)
{
  if (interrupt && !doing_menu) return; // Stop printing only if interrupt is call but not in button functions
  
  setXY(X, Y);
  Wire.beginTransmission(OLED_address); // begin transmitting
  Wire.write(0x40);//data mode
  
  for(int i=0;i<8;i++)
    Wire.write(pgm_read_byte(myFont[data-0x20]+i));
    
  Wire.endTransmission();    // stop transmitting
}

//======================//
// Used to send commands to the display.
static void sendcommand(unsigned char com)
{
  Wire.beginTransmission(OLED_address);     //begin transmitting
  Wire.write(0x80);                          //command mode
  Wire.write(com);
  Wire.endTransmission();                    // stop transmitting
}

//======================//
// Set the cursor position in a 16 COL * 8 ROW map.
static void setXY(unsigned char row,unsigned char col)
{
  sendcommand(0xb0+row);                //set page address
  sendcommand(0x00+(8*col&0x0f));       //set low col address
  sendcommand(0x10+((8*col>>4)&0x0f));  //set high col address
}


//======================//
// Prints a string regardless the cursor position.
static void sendStr(unsigned char *string)
{
  unsigned char i=0;
  while(*string)
  {
    for(i=0;i<8;i++)
    {
      SendChar(pgm_read_byte(myFont[*string-0x20]+i));
    }
    *string++;
    feedgps();    // empty serial buffer every char is printed
  }
}

//======================//
// Prints a string in coordinates X Y, being multiples of 8.
// This means we have 16 COLS (0-15) and 8 ROWS (0-7).
static void sendStrXY( char *string, int X, int Y)
{
  setXY(X,Y);
  unsigned char i=0;
  while(*string)
  {
    for(i=0;i<8;i++)
    {
      SendChar(pgm_read_byte(myFont[*string-0x20]+i));
    }
    *string++;
    feedgps();    // empty serial buffer every char is printed
  }
}

//======================//
// Inits oled and draws logo at startup
static void init_OLED(void)
{
  sendcommand(0xae);		//display off
  sendcommand(0xa6);            //Set Normal Display (default)

  clear_display();
  sendcommand(0x2e);            // stop scroll
  //----------------------------REVERSE comments----------------------------//
  //  sendcommand(0xa0);		//seg re-map 0->127(default)
  //  sendcommand(0xa1);		//seg re-map 127->0
  //  sendcommand(0xc8);
  //  delay(1000);
  //----------------------------REVERSE comments----------------------------//
  // sendcommand(0xa7);  //Set Inverse Display  
  // sendcommand(0xae);		//display off
  sendcommand(0x20);            //Set Memory Addressing Mode
  sendcommand(0x00);            //Set Memory Addressing Mode ab Horizontal addressing mode
  //  sendcommand(0x02);         // Set Memory Addressing Mode ab Page addressing mode(RESET)  
  
  setXY(0,0);

  for(int i=0;i<128*8;i++)     // show 128* 64 Logo
  {
    SendChar(pgm_read_byte(logo+i));
  }
  sendcommand(0xaf);		//display on
  
  sendStrXY("by KaR]V[aN",7,5);
  delay(3000); 
}
или просто библиотеку вкорячить в этот проект вместо тех функций.
еслиб я разбирался в программировании, то не спрашивал бы
Контактная информация:
Потрогал лапой паяльник
Сообщения: 312
Зарегистрирован: Вс июл 29, 2012 16:25:39

Сообщение mas123 »

Evgeny1 писал(а):а вот то, что нужно заставить нормально работать
Я про это "щастье" и говорил.
Откуда уверенность, что вот так нужно инициализировать экран?
Спойлер

Код: Выделить всё

// Inits oled and draws logo at startup
static void init_OLED(void)
{
  sendcommand(0xae);		//display off
  sendcommand(0xa6);            //Set Normal Display (default)

  clear_display();
  sendcommand(0x2e);            // stop scroll
  //----------------------------REVERSE comments----------------------------//
  //  sendcommand(0xa0);		//seg re-map 0->127(default)
  //  sendcommand(0xa1);		//seg re-map 127->0
  //  sendcommand(0xc8);
  //  delay(1000);
  //----------------------------REVERSE comments----------------------------//
  // sendcommand(0xa7);  //Set Inverse Display  
  // sendcommand(0xae);		//display off
  sendcommand(0x20);            //Set Memory Addressing Mode
  sendcommand(0x00);            //Set Memory Addressing Mode ab Horizontal addressing mode
  //  sendcommand(0x02);         // Set Memory Addressing Mode ab Page addressing mode(RESET)  
Когда даташит "SSD1306 App Note Rev 0.4" английским по белому описывает такую последовательность:

Код: Выделить всё

A8h, 3Fh      Set MUX Ratio                  
D3h, 00h      Set Display Offset            
40h             Set Display Start Line       
A0h/A1h      Set Segment re-map       
C0h/C8h     Set COM Output Scan Direction     
DAh, 02h     Set COM Pins hardware configuration     
81h, 7Fh      Set Contrast Control                  
A4h             Disable Entire Display On           
A6h             Set Normal Display                    
D5h, 80h     Set Osc Frequency                    
8Dh, 14h     Enable charge pump regulator   
AFh             Display On                               
Evgeny1 писал(а):еслиб я разбирался в программировании, то не спрашивал бы
Разбираться в программировании - это в первую очередь умение искать информацию и читать документацию.

Ладно, когда либа работает - можно не изучать. Но, когда периферия не работает , имхо самое время изучать первоисточники.
В полчаса гуглится и проверяется и более длинная стартовая последовательность, которая у меня идеально работает и по i2c, и по spi
Ессно, вызывается после настройки портов ввода/вывода и выдачи на LCD сигнала сброс. Но, ты можешь этого не делать - раз и так всё подтянуто и не нужно ничего городить.
Спойлер

Код: Выделить всё

    LCDCommand(LCD_CMD_DISPLAY_OFF);//+ display off
  
    LCDCommand(LCD_CMD_SET_COL_L);
    LCDCommand(LCD_CMD_SET_COL_H);
    LCDCommand(LCD_CMD_START_LINE);//+ Set Page Start Address for Page Addressing Mode,0-7

    LCDCommand_param(LCD_CMD_CONTRAST, 0x00); ///~~~0xCF);
  
    LCDCommand(LCD_CMD_SEGMENT_MAP_1);
    LCDCommand(LCD_CMD_SCAN_DIR_MINUS);
    LCDCommand(LCD_CMD_NORMAL_DISPLAY);
  
//--set multiplex ratio(1 to 64)  
    LCDCommand_param(LCD_CMD_MULTIPLEX_RATIO, 63);
//-set display offset    (not offset)
    LCDCommand_param(LCD_CMD_DISPLAY_OFFSET, 0x00);
  
//--set display clock divide ratio/oscillator frequency  
//   set divide ratio  
    LCDCommand_param(LCD_CMD_SET_CLOCK_DIVIDE, 0x80);//
  
    LCDCommand_param(LCD_CMD_SET_PRE_CHARGE_PERIOD, 0xF1);
  
    LCDCommand_param(LCD_CMD_SET_PIN_CONF, 0x12);//--  0x02???
  
    LCDCommand_param(LCD_CMD_SET_VCOMH, 0x10);  // 0.77 * VCC
  
// Set Memory Addressing Mode  
    LCDCommand_param(LCD_CMD_ADDR_MODE, 0x02);
  
    LCDCommand_param(LCD_CMD_SET_CHARGE_BUMP, 0x14); // Enable Charge Pump
  
    LCDCommand(LCD_CMD_ALL_OFF);
    LCDCommand(LCD_CMD_NORMAL_DISPLAY);
  
    LCDCommand(LCD_CMD_DISPLAY_ON);//+ --turn on oled panel 
    
    LcdClear();

Код: Выделить всё

// Set Lower Column Start Address for Page Addressing Mode (00h~0Fh)
#define LCD_CMD_SET_COL_L               0x00
// Set Higher Column Start Address for Page Addressing Mode (10h~1Fh)
#define LCD_CMD_SET_COL_H               0x10

// Set Memory Addressing Mode (20h)
#define LCD_CMD_ADDR_MODE               0x20
// след байт: 
//  0 - Horizontal Addressing Mode; 
//  1 - Vertical Addressing Mode; 
//  2 - Page Addressing Mode (RESET); 
//  3 - Invalid

// Set Column Address (21h)

// Set Page Address (22h)

// Set Display Start Line (40h~7Fh)
#define LCD_CMD_START_LINE              0x40

// Set Contrast Control for BANK0 (81h)
#define LCD_CMD_CONTRAST                0x81
// след байт: контрастность

// Charge Bump Setting
#define LCD_CMD_SET_CHARGE_BUMP         0x8D
// след байт: значение

// Set Segment Re-map (A0h/A1h)
// column address 0 is mapped to SEG0 (RESET)
#define LCD_CMD_SEGMENT_MAP_0           0xA0
// column address 127 is mapped to SEG0
#define LCD_CMD_SEGMENT_MAP_1           0xA1

// Entire Display ON (A4h/A5h)
#define LCD_CMD_ALL_OFF                 0xA4
#define LCD_CMD_ALL_ON                  0xA5

// Set Normal/Inverse Display (A6h/A7h)
#define LCD_CMD_NORMAL_DISPLAY          0xA6
#define LCD_CMD_INVERSE_DISPLAY         0xA7

// Set Multiplex Ratio (A8h)
#define LCD_CMD_MULTIPLEX_RATIO         0xA8
// след байт: значение

// Set Display ON/OFF (AEh/AFh)
#define LCD_CMD_DISPLAY_ON              0xAF
#define LCD_CMD_DISPLAY_OFF             0xAE

// Set Page Start Address for Page Addressing Mode (B0h~B7h)
#define LCD_CMD_SET_PAGE                0xB0

// Set COM Output Scan Direction (C0h/C8h)
// C0h, X[3]=0b: normal mode (RESET) Scan from COM0 to COM[N –1]
#define LCD_CMD_SCAN_DIR_PLUS           0xC0
// C8h, X[3]=1b: remapped mode. Scan from COM[N-1] to COM0
#define LCD_CMD_SCAN_DIR_MINUS          0xC8

// Set Display Offset (D3h)
#define LCD_CMD_DISPLAY_OFFSET          0xD3
// след байт: значение

// Set Display Clock Divide Ratio/ Oscillator Frequency (D5h)
#define LCD_CMD_SET_CLOCK_DIVIDE        0xD5
// след байт:   Display Clock Divide Ratio + Oscillator Frequency

// Set Pre-charge Period (D9h)
#define LCD_CMD_SET_PRE_CHARGE_PERIOD   0xD9
// след байт: значение

// Set COM Pins Hardware Configuration (DAh)
#define LCD_CMD_SET_PIN_CONF            0xDA
// след байт: значение

// Set VCOMH Deselect Level (DBh)
#define LCD_CMD_SET_VCOMH               0xDB
// след байт: значение
А крики в стиле "я же не программист и не разбираюсь в программировании" меня всегда веселят. :))
Если взялся делать - не стони, а учись и делай! Иначе - полож компилер обратно на полочку. :)))

Кстати, человек, у которого на форуме радиолюбителей 3815 сообщений и не умеет программировать? Это тоже радует! 8)
Друг Кота
Аватара пользователя
Сообщения: 4106
Зарегистрирован: Пн авг 10, 2009 01:18:55
Откуда: Электросталь

Сообщение Evgeny1 »

все решилось добавлением двух строчек
sendCommand(SSD1306_CHARGEPUMP);
sendCommand(0x14);
всем спасибо!
Контактная информация:
Ответить

Вернуться в «AVR»