X-Clock (IKEA OBEGRÄNSAD Hack)

Upcycle the IKEA Obergränsad LED Lamp to a connected WiFi Clock!

Image :User Boxi

In this article i describe how to convert a IKEA LED Lamp to a digital WIFI Wall Clock.

Video from german make: Magazine about our project.

All you need is the IKEA Obergränsad and a Wemos-D1.Mini-Pro. I will provide simple Sketches serving as base for your own development. But you also find a ready made precompiled Version with many options. Its up to you.

What is OBEGRÄNSAD ?

This is a LAMP, you can buy at your local IKEA shop in the lights corner. It is capable of displaying animated patterns.

In my opinion it is very annoying or boring after a few minutes. So i thought it would be a good idea to upcycle to something more useful.

Cost: OBEGRÄNSAD 100€, Wemos D1 Mini 5€.
I personally find Obegränsad relatively expensive. You may argue that you can buy RGB LED Panels for less. This is very true – but take into account that OBEGRÄNSAD comes completely usable in a case. Building a „Living room compatible“ enclosure is time consuming. If you are looking for a cheaper option: Please have a look at my y-clok, the comparable IKEA-Frekvens Hack.

Credits: The modification is based on sources i found for the frequenz multimedia elements. I simplified and adapted them for OBEGRÄNSAD and made it available for Arduino IDE.

OBEGRÄNSAD: These IKEA Elements have a display of 16×16 white LEDs. Basically the 16×16 pixels can be used for any kind of display. But the limitations of 16 by 16 LED and the non symetrical arrangement make it more difficult to find a useful application.

The X-Clock is 52×32 cm in size and has a good readability if used vertically.

As you can see a 16 Pixel wide Display will not be sufficient for a 24h – Clock.

So i arranged the 4 digits in two rows.

This is sufficient for a Clock Display.

To modify the OBEGRÄNSAD you have to open it, which is only possible by drilling the rivets heads off – this sounds complicated , but since these rivets are made of aluminium it is very easy.

TIPP: It is much easier to hang-up the clock with one Screw/Nail instead of two screws. So if you have the drill at hand, drill a hole in the back, center top of the Metal frame!

Then you have to remove the built in microcontroller, which is located at the bottom board near a position marked U1. I marked it with a red Arrow.

Option1: Use a hot air pistol.

Option2: You solder it off by placing a knife between board and chip gentle lift the chip while solder all pins one after another .

Position of the original Chip, which has to be removed, marked by red arrow.
TIP: Center hole for easy hang-up.
Visible at the bottom center of the Picture.

Once U1 is gone, you attach the wires as displayed. Attach the Microcontroller as displayed with dual adhesive tape: You have to use long cables for the Pushbutton! The pushbutton wires are marked black/red. Power lines white(5V-VCC) and grey(GND 0).

Close up with chip U1 removed and new connections made to the Wemos D1 mini pro. We recommend a Capaciator at the power line. (eG.: 1000uF/12V)

The connections are:

  • D8 CLA
  • D7 CLK
  • D6 DIN
  • D5 EN
  • D4 Button IN (Note: If held low(GND) during startup..prevents boot)
  • VCC to 5V ! (not 3V3)
  • 0 to GND

A MOST SIMPLE SKETCH

  1. Install Arduino IDE Support for ESP
  2. (add http://arduino.esp8266.com/stable/package_esp8266com_index.json insettings and choose board esp8266 WemosD1)
  3. copy the sketch below into the Arduino IDE,
  4. change your SSID and Password
  5. compile as Lolin(Wemos) D1 Mini .
  6. flash the device

Option WifiManager:

You may uncomment the WiFi Manager section for more comfort:

You need to install the WiFi Manager Lib by TZAPU: WiFi Manager Library

 // THIS FILE IS A DEMO FOR IKEA OBERGRANSÄD/Frequenz KIT
 // ANALOG NO WEB
 // AS INTERNET CLOCK

 // (C)2023 DR. ARMIN ZINK
 // parts borrowed from
 // By /u/frumperino
 // goodwires.org

// FOR FREQUENZ     H_FREKVENS
// FOR OBERGRÄNSAD  H_OBEGRANSAD

#define H_OBEGRANSAD
#include <Arduino.h>
#include <pgmspace.h>

#include <ESP8266WiFi.h>
#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager

 
// COLORS VALID FOR OBEGRÄNSAD ARICLE
#define P_EN D5  // ORANGE
#define P_DI D6  // YELLO
#define P_CLK D7 // BLUE
#define P_CLA D8 // LILA

#define P_KEY D4 // ROT
#define P_KEY_YELLOW D2 // YELLOW BUTTON


// SET YOUR TIMEZONE HERE
#define MY_NTP_SERVER "pool.ntp.org" // set the best fitting NTP server (pool) for your location
#define MY_TZ "CET-1CEST,M3.5.0/02,M10.5.0/03" // https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv

long     mil;
int      brightness=220;
uint8_t  sec;
uint8_t  minute;
uint8_t  hour;
time_t   now;                         // this is the epoch
tm       tm;

 // Waiting Time for Shift Cycke, can go downto 1
#define TT 5
static const uint8_t System6x7[] PROGMEM = {
  
    // Fixed width; char width table not used !!!!
    // FIRST 32 Characters omitted
    
    // font data
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (space)
  0x00, 0x00, 0x4f, 0x4f, 0x00, 0x00, 
  0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 
  0x00, 0x0a, 0x3f, 0x0a, 0x3f, 0x0a, 
  0x24, 0x2a, 0x7f, 0x2a, 0x7f, 0x12, 
  0x23, 0x33, 0x18, 0x0c, 0x66, 0x62, 
  0x3e, 0x3f, 0x6d, 0x6a, 0x30, 0x48, 
  0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 
  0x00, 0x1c, 0x3e, 0x63, 0x63, 0x00,
  0x00, 0x00, 0x63, 0x63, 0x3e, 0x1c, 
  0x2a, 0x1c, 0x7f, 0x7f, 0x1c, 0x2a, 
  0x08, 0x08, 0x3e, 0x3e, 0x08, 0x08, 
  0x00, 0x00, 0xc0, 0xe0, 0x60, 0x00, 
  0x00, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 
  0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 
  0x20, 0x30, 0x18, 0x0c, 0x06, 0x02, 
  0x3e, 0x7f, 0x63, 0x63, 0x7f, 0x3e, // 0
  0x00, 0x02, 0x7f, 0x7f, 0x00, 0x00, // 1
  0x62, 0x73, 0x7b, 0x6b, 0x6f, 0x66, // 2
  0x22, 0x63, 0x6b, 0x6b, 0x7f, 0x36, // 3
  0x0f, 0x0f, 0x08, 0x08, 0x7f, 0x7f, // 4
  0x2f, 0x6f, 0x6b, 0x6b, 0x7b, 0x3b, // 5
  0x3e, 0x7f, 0x6b, 0x6b, 0x7b, 0x3a, // 6
  0x03, 0x03, 0x7b, 0x7b, 0x0f, 0x07, // 7
  0x36, 0x7f, 0x6b, 0x6b, 0x7f, 0x36, // 8
  0x26, 0x6f, 0x6b, 0x6b, 0x7f, 0x3e, // 9
  0x00, 0x00, 0x36, 0x36, 0x00, 0x00,
  0x00, 0x00, 0x76, 0x36, 0x00, 0x00, 
  0x00, 0x18, 0x3c, 0x66, 0x42, 0x00, 
  0x00, 0x00, 0x36, 0x36, 0x36, 0x36,
  0x00, 0x00, 0x42, 0x66, 0x3c, 0x18, 
  0x00, 0x02, 0x5b, 0x5b, 0x0f, 0x06, 
  0x3c, 0x42, 0x4a, 0x56, 0x5c, 0x00, 
  0x7e, 0x7f, 0x0b, 0x0b, 0x7f, 0x7e, 
  0x7f, 0x7f, 0x6b, 0x6b, 0x7f, 0x36, 
  0x3e, 0x7f, 0x77, 0x63, 0x63, 0x22,
  0x7f, 0x7f, 0x63, 0x63, 0x7f, 0x3e, 
  0x7f, 0x7f, 0x6b, 0x6b, 0x63, 0x63, 
  0x7f, 0x7f, 0x0b, 0x0b, 0x03, 0x03, 
  0x3e, 0x7f, 0x63, 0x6b, 0x7b, 0x32, 
  0x7f, 0x7f, 0x08, 0x08, 0x7f, 0x7f, 
  0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 
  0x00, 0x23, 0x63, 0x63, 0x7f, 0x3f, 
  0x7f, 0x7f, 0x1c, 0x36, 0x63, 0x41, 
  0x7f, 0x7f, 0x60, 0x60, 0x60, 0x60, 
  0x7f, 0x7f, 0x03, 0x06, 0x03, 0x7f, 
  0x7f, 0x7f, 0x0e, 0x18, 0x7f, 0x7f, 
  0x3e, 0x7f, 0x63, 0x63, 0x7f, 0x3e, 
  0x7f, 0x7f, 0x0b, 0x0b, 0x0f, 0x06, 
  0x3e, 0x7f, 0x63, 0x73, 0x3f, 0x5e, 
  0x7f, 0x7f, 0x1b, 0x3b, 0x7f, 0x6e, 
  0x26, 0x6f, 0x6b, 0x6b, 0x7b, 0x32, 
  0x03, 0x03, 0x7f, 0x7f, 0x03, 0x03, 
  0x3f, 0x7f, 0x60, 0x60, 0x7f, 0x3f, 
  0x0f, 0x7f, 0x78, 0x40, 0x7f, 0x0f, 
  0x3f, 0x7f, 0x60, 0x78, 0x60, 0x3f, 
  0x63, 0x77, 0x1c, 0x1c, 0x77, 0x63, 
  0x07, 0x0f, 0x78, 0x78, 0x0f, 0x07, 
  0x63, 0x73, 0x7b, 0x6f, 0x67, 0x63, 
  0x7d, 0x7e, 0x0b, 0x0b, 0x7e, 0x7d, 
  0x3d, 0x7e, 0x66, 0x66, 0x7e, 0x3d, 
  0x3d, 0x7d, 0x60, 0x60, 0x7d, 0x3d, 
  0x00, 0x04, 0x02, 0x01, 0x02, 0x04, 
  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 
  0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 
  0x7e, 0x7f, 0x0b, 0x0b, 0x7f, 0x7e, 
  0x7f, 0x7f, 0x6b, 0x6b, 0x7f, 0x36, 
  0x3e, 0x7f, 0x77, 0x63, 0x63, 0x22, 
  0x7f, 0x7f, 0x63, 0x63, 0x7f, 0x3e, 
  0x7f, 0x7f, 0x6b, 0x6b, 0x63, 0x63, 
  0x7f, 0x7f, 0x0b, 0x0b, 0x03, 0x03, 
  0x3e, 0x7f, 0x63, 0x6b, 0x7b, 0x32, 
  0x7f, 0x7f, 0x08, 0x08, 0x7f, 0x7f, 
  0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 
  0x00, 0x23, 0x63, 0x63, 0x7f, 0x3f, 
  0x7f, 0x7f, 0x1c, 0x36, 0x63, 0x41, 
  0x7f, 0x7f, 0x60, 0x60, 0x60, 0x60, 
  0x7f, 0x7f, 0x03, 0x06, 0x03, 0x7f, 
  0x7f, 0x7f, 0x0e, 0x18, 0x7f, 0x7f, 
  0x3e, 0x7f, 0x63, 0x63, 0x7f, 0x3e, 
  0x7f, 0x7f, 0x0b, 0x0b, 0x0f, 0x06, 
  0x3e, 0x7f, 0x63, 0x73, 0x3f, 0x5e, 
  0x7f, 0x7f, 0x1b, 0x3b, 0x7f, 0x6e, 
  0x66, 0x6f, 0x6b, 0x6b, 0x7b, 0x32, 
  0x03, 0x03, 0x7f, 0x7f, 0x03, 0x03, 
  0x3f, 0x7f, 0x60, 0x60, 0x7f, 0x3f, 
  0x0f, 0x7f, 0x78, 0x40, 0x7f, 0x0f, 
  0x3f, 0x7f, 0x60, 0x78, 0x60, 0x3f, 
  0x63, 0x77, 0x1c, 0x1c, 0x77, 0x63, 
  0x07, 0x0f, 0x78, 0x78, 0x0f, 0x07, 
  0x63, 0x73, 0x7b, 0x6f, 0x67, 0x63, 
  0x7d, 0x7e, 0x0b, 0x0b, 0x7e, 0x7d, 
  0x3d, 0x7e, 0x66, 0x66, 0x7e, 0x3d, 
  0x3d, 0x7d, 0x60, 0x60, 0x7d, 0x3d, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    
};


// LUT For OBEGRÄNSAD
int lut[16][16] = {
        {23, 22, 21, 20, 19, 18, 17, 16, 7, 6, 5, 4, 3, 2, 1, 0},
        {24, 25, 26, 27, 28, 29, 30, 31, 8, 9, 10, 11, 12, 13, 14, 15},
        {39, 38, 37, 36, 35, 34, 33, 32, 55, 54, 53, 52, 51, 50, 49, 48},
        {40, 41, 42, 43, 44, 45, 46, 47, 56, 57, 58, 59, 60, 61, 62, 63},
        {87, 86, 85, 84, 83, 82, 81, 80, 71, 70, 69, 68, 67, 66, 65, 64},
        {88, 89, 90, 91, 92, 93, 94, 95, 72, 73, 74, 75, 76, 77, 78, 79},
        {103, 102, 101, 100, 99, 98, 97, 96, 119, 118, 117, 116, 115, 114, 113, 112},
        {104, 105, 106, 107, 108, 109, 110, 111, 120, 121, 122, 123, 124, 125, 126, 127},
        {151, 150, 149, 148, 147, 146, 145, 144, 135, 134, 133, 132, 131, 130, 129, 128},
        {152, 153, 154, 155, 156, 157, 158, 159, 136, 137, 138, 139, 140, 141, 142, 143},
        {167, 166, 165, 164, 163, 162, 161, 160, 183, 182, 181, 180, 179, 178, 177, 176},
        {168, 169, 170, 171, 172, 173, 174, 175, 184, 185, 186, 187, 188, 189, 190, 191},
        {215, 214, 213, 212, 211, 210, 209, 208, 199, 198, 197, 196, 195, 194, 193, 192},
        {216, 217, 218, 219, 220, 221, 222, 223, 200, 201, 202, 203, 204, 205, 206, 207},
        {231, 230, 229, 228, 227, 226, 225, 224, 247, 246, 245, 244, 243, 242, 241, 240},
        {232, 233, 234, 235, 236, 237, 238, 239, 248, 249, 250, 251, 252, 253, 254, 255}};
  
 unsigned short _pLatch;
 unsigned short _pClock;
 unsigned short _pData;
 uint8_t p_buf[16*16];


// -----------------------------------------------------------
void p_init(int p_latch, int p_clock, int p_data)
{

    _pLatch = p_latch;
    _pClock = p_clock;
    _pData  = p_data;
    pinMode(_pLatch, OUTPUT);
    pinMode(_pClock, OUTPUT);
    pinMode(_pData,  OUTPUT);
 }


// -----------------------------------------------------------

// Clear the Panel Buffer
void p_clear(){
    for (int i = 0; i < 256; i++)  {
        p_buf[i] = 0;
    }
}


// -----------------------------------------------------------
// SCAN DISPLAY, output Bytes to Serial
void p_scan(uint8_t cmask){

 
    analogWrite(P_EN,255);
    delayMicroseconds(TT); 
 
    uint8_t w=0;
    uint8_t w2=0;
     for (int i = 256; i>0 ; i--)  {            
          digitalWrite(_pData, cmask & p_buf[w++]);  
          digitalWrite(_pClock, HIGH);               
          digitalWrite(_pClock, LOW);                
          
  
        }  // update 2024/01/01 speedup
              digitalWrite(_pLatch, HIGH);           
              digitalWrite(_pLatch, LOW);  
       analogWrite(P_EN,brightness);  // re enable brightmess
       
}


 // -----------------------------------------------------------

void p_drawPixel(int8_t x, int8_t y, uint8_t color)
{ 
  if((x<16) && (y<16)) {
#ifdef H_OBEGRANSAD
     p_buf[lut[y][x]] = color;
#endif
#ifdef  H_FREKVENS
    if (x > 7) { y += 0x10; x &= 0x07; }
    p_buf[(y*8+x)] = color ;
#endif
  }
}

// -----------------------------------------------------------
void p_fillScreen(uint8_t col){
  for (uint8_t x=0;x < 16; x++)
     for (uint8_t y=0;y < 16; y++)
       p_drawPixel(x, y, col);
}

// -----------------------------------------------------------
void test_display() {

    for (int i = 0; i<2; i++) {          
        p_fillScreen(0xff);  p_scan(1);  analogWrite(P_EN,250); delay(300);
        p_fillScreen(0x00);  p_scan(1);  analogWrite(P_EN,250); delay(300);
        
    }
}


// -----------------------------------------------------------
void p_printChar(uint8_t xs, uint8_t ys, char ch) {
    uint8_t d;
 
    for (uint8_t x=0;x<6;x++) { 
   
        d = pgm_read_byte_near((ch-32)*6+  // Buchstabennummer (ASCII ) minus 32 da die ersten 32 Zeichen nicht im Font sind
                               x +         // jede Spalte
                               System6x7); // Adrress of Font
   
     if ((d&1)    ==  1)  p_drawPixel(x+xs, 0+ys, 0xFF);else p_drawPixel(x+xs, 0+ys, 0);
     if ((d&2)    ==  2)  p_drawPixel(x+xs, 1+ys, 0xFF);else p_drawPixel(x+xs, 1+ys, 0);
     if ((d&4)    ==  4)  p_drawPixel(x+xs, 2+ys, 0xFF);else p_drawPixel(x+xs, 2+ys, 0);
     if ((d&8)    ==  8)  p_drawPixel(x+xs, 3+ys, 0xFF);else p_drawPixel(x+xs, 3+ys, 0);
     if ((d&16 )  == 16)  p_drawPixel(x+xs, 4+ys, 0xFF);else p_drawPixel(x+xs, 4+ys, 0);
     if ((d&32 )  == 32)  p_drawPixel(x+xs, 5+ys, 0xFF);else p_drawPixel(x+xs, 5+ys, 0);
     if ((d&64 )  == 64)  p_drawPixel(x+xs, 6+ys, 0xFF);else p_drawPixel(x+xs, 6+ys, 0);
   
    }
 }  
 

// -----------------------------------------------------------
const char* getTimeString(void) {
  static char   acTimeString[32];
  time_t now = time(nullptr);
  ctime_r(&now, acTimeString);
  size_t    stLength;
  while (((stLength = strlen(acTimeString))) &&
         ('\n' == acTimeString[stLength - 1])) {
    acTimeString[stLength - 1] = 0; // Remove trailing line break...
  }
  return acTimeString;
}
 

// -----------------------------------------------------------
 void set_clock(void) {   
  configTime(MY_TZ, MY_NTP_SERVER); // --> Here is the IMPORTANT ONE LINER needed in your sketch!
  Serial.print("Waiting for NTP time sync: ");
  time_t now = time(nullptr);   // Secs since 01.01.1970 (when uninitialized starts with (8 * 3600 = 28800)
  while (now < 8 * 3600 * 2) {  // Wait for realistic value
  
    Serial.print(".");
    now = time(nullptr);
  }
  Serial.println("");
  Serial.printf("Current time: %s\n", getTimeString());
}



// -----------------------------------------------------------
void set_clock_from_tm() {
    time(&now);                       // read the current time
    localtime_r(&now, &tm);           // update the structure tm with the current time  

   // update time from struct
   minute = tm.tm_min;   
   hour   = tm.tm_hour;   
}



// -----------------------------------------------------------
void setup() {
  
  pinMode(P_KEY, INPUT_PULLUP);  // RED KEY
  pinMode(P_EN, OUTPUT);         // Pseudo Analog out for FM Brightess
  analogWrite(P_EN, brightness); // adjust brightness

  p_init(P_CLA, P_CLK, P_DI);    // init Display

  test_display();
  Serial.begin(74880);           // Native Baud Rate of ESP
   
  p_clear();
  p_printChar(2,0,'A');          // Print "AP" while waiting for WiFi Manager
  p_printChar(9,0,'P');
  p_scan(1);
  delay(1000);
  
  WiFiManager wm;
  wm.setMinimumSignalQuality(50);
  bool res;
#ifdef H_FREKVENS
  res = wm.autoConnect("Y-CLOCK");  
#endif
#ifdef H_OBEGRANSAD
  res = wm.autoConnect("X-CLOCK");  
#endif

/*
// enable fo use without wifi manager
// start network
  WiFi.mode(WIFI_STA);
  WiFi.begin(STASSID, STAPSK);
*/
   while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
   p_printChar(2,9,'O');
   p_printChar(9,9,'K');
   p_scan(1);
   delay(500);
   
   //if you get here you have connected to the WiFi   
   Serial.println("Wifi connected!");
   // Sync clock
   set_clock();
   set_clock_from_tm() ;
   print_time();
   
}


// -----------------------------------------------------------
void print_time() {
        p_clear();
        p_printChar(2,0,(hour / 10)   +48);
        p_printChar(9,0,(hour % 10)   +48);
        p_printChar(2,9,(minute / 10) +48);
        p_printChar(9,9,(minute % 10) +48);
        p_scan(1); // refreshes display
  
}
// -----------------------------------------------------------
/// MAIN LOOP

void loop() {

  // JEDE SEKUNDE
  if (millis()>mil+1000)
  {
    mil = millis();
    sec ++;
    
    // Jede Minute
    if (sec>60) {
        sec = 0;
        print_time(); 
        set_clock_from_tm() ;
        set_clock();
      }
      //Serial.printf("Current time: %s\n", getTimeString());
  }

  // TASTE gedrückt ? Helligkeit einstellen. Max = 0, Min = 254
  if (digitalRead(P_KEY) == 0) {
     if(brightness>205) brightness =104; // 105,155,205,255
      brightness+=25; 
     
      analogWrite(P_EN, brightness); 
      print_time(); 
      delay(500);
    
      Serial.print(brightness);
   }
  
 
}

PRE BUILT FIRMWARE

To flash the controller you can use our pre – built firmware. It is available at o-clock.eu.

Before flashing, make sure ESP is blank and fully erased !

It is most easy to flash it with a Chrome Browser, before soldering the Wemos-D1-Mini-Pro. There are two Versions available

X-Clock WiFi Manager (Key for Brightness), which is the compiled source from example above

X-Clock WEB (with Web Interface)

https://o-clock.eu/

Downloads:

To simply flash any binary to the Wemos-D1 you can use this tool, it is very handy : EspWebFlasher

Expansion LDR:

If you want to adjust the brightness of the Display in relation of the ambient light. The Sensor can be placed on. the side of the Frame.

Add this line of Code for LDR to be executed every minute in the main loop:

brightness = map(analogRead(A0), 1024, 0 ,200, 254);

(full Sketch below)

This is a picture of the advanced wiring. It features a brightness Sensor. Its a bit messed up. Important is the pink wire to the LDR, and the resistor with the grey wire to GND. The other pin of the LDR is connected to 3V3.

Brightness Sensor

The brightness Sensor (two wires in the bottom of the image: pinkish white and red) is connected to A0. A Pulldown 100k is attached to A0 and GND. The other wire of the LDR is RED, goes to 3.3V.

TROUBLESHOOTING

// THIS FILE IS A DEMO FOR IKEA OBERGRANSÄD/Frequenz KIT WITH LDR 
 // AS INTERNET CLOCK
 // 24.11.23 Improved by Malte
 // 1.11.23 increased accuracy by Martin
 // simplified by Pixelkoenig - (C)2023 DR. ARMIN ZINK
 // parts borrowed from
 // By /u/frumperino
 // goodwires.org

 // Waiting Time for Shift Cycle, can go downto 1 to speed up update of display.
#define TT 5

// FOR FREQUENZ     H_FREKVENS
// FOR OBERGRÄNSAD  H_OBEGRANSAD
#define H_OBEGRANSAD

#include <Arduino.h>
#include <pgmspace.h>
#include <ESP8266WiFi.h>
// #include <WiFiManager.h> // https://github.com/tzapu/WiFiManager
#define STASSID "SSID"
#define STAPSK  "PASS"
// COLORS VALID FOR OBEGRÄNSAD ARICLE
#define P_EN D5  // ORANGE
#define P_DI D6  // YELLO
#define P_CLK D7 // BLUE
#define P_CLA D8 // LILA

#define P_KEY D4 // ROT
#define P_KEY_YELLOW D2 // YELLOW BUTTON
#define P_LDR A0 // LDR SENSOR


// SET YOUR TIMEZONE HERE
#define MY_NTP_SERVER "pool.ntp.org" // set the best fitting NTP server (pool) for your location
#define MY_TZ "CET-1CEST,M3.5.0/02,M10.5.0/03" // https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv

long     mil;
int      brightness=220;
uint8_t  sec;
uint8_t  minute;
uint8_t  hour;
time_t   now;                         // this is the epoch
tm       tm;



static const uint8_t System6x7[] PROGMEM = {
  
    // Fixed width; char width table not used !!!!
    // FIRST 32 Characters omitted
    
    // font data
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (space)
  0x00, 0x00, 0x4f, 0x4f, 0x00, 0x00, // "!" etc..
  0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 
  0x00, 0x0a, 0x3f, 0x0a, 0x3f, 0x0a, 
  0x24, 0x2a, 0x7f, 0x2a, 0x7f, 0x12, 
  0x23, 0x33, 0x18, 0x0c, 0x66, 0x62, 
  0x3e, 0x3f, 0x6d, 0x6a, 0x30, 0x48, 
  0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 
  0x00, 0x1c, 0x3e, 0x63, 0x63, 0x00,
  0x00, 0x00, 0x63, 0x63, 0x3e, 0x1c, 
  0x2a, 0x1c, 0x7f, 0x7f, 0x1c, 0x2a, 
  0x08, 0x08, 0x3e, 0x3e, 0x08, 0x08, 
  0x00, 0x00, 0xc0, 0xe0, 0x60, 0x00, 
  0x00, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 
  0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 
  0x20, 0x30, 0x18, 0x0c, 0x06, 0x02, 
  0x3e, 0x7f, 0x63, 0x63, 0x7f, 0x3e, // 0
  0x00, 0x02, 0x7f, 0x7f, 0x00, 0x00, // 1
  0x62, 0x73, 0x7b, 0x6b, 0x6f, 0x66, // 2
  0x22, 0x63, 0x6b, 0x6b, 0x7f, 0x36, // 3
  0x0f, 0x0f, 0x08, 0x08, 0x7f, 0x7f, // 4
  0x2f, 0x6f, 0x6b, 0x6b, 0x7b, 0x3b, // 5
  0x3e, 0x7f, 0x6b, 0x6b, 0x7b, 0x3a, // 6
  0x03, 0x03, 0x7b, 0x7b, 0x0f, 0x07, // 7
  0x36, 0x7f, 0x6b, 0x6b, 0x7f, 0x36, // 8
  0x26, 0x6f, 0x6b, 0x6b, 0x7f, 0x3e, // 9
  0x00, 0x00, 0x36, 0x36, 0x00, 0x00,
  0x00, 0x00, 0x76, 0x36, 0x00, 0x00, 
  0x00, 0x18, 0x3c, 0x66, 0x42, 0x00, 
  0x00, 0x00, 0x36, 0x36, 0x36, 0x36,
  0x00, 0x00, 0x42, 0x66, 0x3c, 0x18, 
  0x00, 0x02, 0x5b, 0x5b, 0x0f, 0x06, 
  0x3c, 0x42, 0x4a, 0x56, 0x5c, 0x00, 
  0x7e, 0x7f, 0x0b, 0x0b, 0x7f, 0x7e, 
  0x7f, 0x7f, 0x6b, 0x6b, 0x7f, 0x36, 
  0x3e, 0x7f, 0x77, 0x63, 0x63, 0x22,
  0x7f, 0x7f, 0x63, 0x63, 0x7f, 0x3e, 
  0x7f, 0x7f, 0x6b, 0x6b, 0x63, 0x63, 
  0x7f, 0x7f, 0x0b, 0x0b, 0x03, 0x03, 
  0x3e, 0x7f, 0x63, 0x6b, 0x7b, 0x32, 
  0x7f, 0x7f, 0x08, 0x08, 0x7f, 0x7f, 
  0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 
  0x00, 0x23, 0x63, 0x63, 0x7f, 0x3f, 
  0x7f, 0x7f, 0x1c, 0x36, 0x63, 0x41, 
  0x7f, 0x7f, 0x60, 0x60, 0x60, 0x60, 
  0x7f, 0x7f, 0x03, 0x06, 0x03, 0x7f, 
  0x7f, 0x7f, 0x0e, 0x18, 0x7f, 0x7f, 
  0x3e, 0x7f, 0x63, 0x63, 0x7f, 0x3e, 
  0x7f, 0x7f, 0x0b, 0x0b, 0x0f, 0x06, 
  0x3e, 0x7f, 0x63, 0x73, 0x3f, 0x5e, 
  0x7f, 0x7f, 0x1b, 0x3b, 0x7f, 0x6e, 
  0x26, 0x6f, 0x6b, 0x6b, 0x7b, 0x32, 
  0x03, 0x03, 0x7f, 0x7f, 0x03, 0x03, 
  0x3f, 0x7f, 0x60, 0x60, 0x7f, 0x3f, 
  0x0f, 0x7f, 0x78, 0x40, 0x7f, 0x0f, 
  0x3f, 0x7f, 0x60, 0x78, 0x60, 0x3f, 
  0x63, 0x77, 0x1c, 0x1c, 0x77, 0x63, 
  0x07, 0x0f, 0x78, 0x78, 0x0f, 0x07, 
  0x63, 0x73, 0x7b, 0x6f, 0x67, 0x63, 
  0x7d, 0x7e, 0x0b, 0x0b, 0x7e, 0x7d, 
  0x3d, 0x7e, 0x66, 0x66, 0x7e, 0x3d, 
  0x3d, 0x7d, 0x60, 0x60, 0x7d, 0x3d, 
  0x00, 0x04, 0x02, 0x01, 0x02, 0x04, 
  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 
  0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 
  0x7e, 0x7f, 0x0b, 0x0b, 0x7f, 0x7e, 
  0x7f, 0x7f, 0x6b, 0x6b, 0x7f, 0x36, 
  0x3e, 0x7f, 0x77, 0x63, 0x63, 0x22, 
  0x7f, 0x7f, 0x63, 0x63, 0x7f, 0x3e, 
  0x7f, 0x7f, 0x6b, 0x6b, 0x63, 0x63, 
  0x7f, 0x7f, 0x0b, 0x0b, 0x03, 0x03, 
  0x3e, 0x7f, 0x63, 0x6b, 0x7b, 0x32, 
  0x7f, 0x7f, 0x08, 0x08, 0x7f, 0x7f, 
  0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 
  0x00, 0x23, 0x63, 0x63, 0x7f, 0x3f, 
  0x7f, 0x7f, 0x1c, 0x36, 0x63, 0x41, 
  0x7f, 0x7f, 0x60, 0x60, 0x60, 0x60, 
  0x7f, 0x7f, 0x03, 0x06, 0x03, 0x7f, 
  0x7f, 0x7f, 0x0e, 0x18, 0x7f, 0x7f, 
  0x3e, 0x7f, 0x63, 0x63, 0x7f, 0x3e, 
  0x7f, 0x7f, 0x0b, 0x0b, 0x0f, 0x06, 
  0x3e, 0x7f, 0x63, 0x73, 0x3f, 0x5e, 
  0x7f, 0x7f, 0x1b, 0x3b, 0x7f, 0x6e, 
  0x66, 0x6f, 0x6b, 0x6b, 0x7b, 0x32, 
  0x03, 0x03, 0x7f, 0x7f, 0x03, 0x03, 
  0x3f, 0x7f, 0x60, 0x60, 0x7f, 0x3f, 
  0x0f, 0x7f, 0x78, 0x40, 0x7f, 0x0f, 
  0x3f, 0x7f, 0x60, 0x78, 0x60, 0x3f, 
  0x63, 0x77, 0x1c, 0x1c, 0x77, 0x63, 
  0x07, 0x0f, 0x78, 0x78, 0x0f, 0x07, 
  0x63, 0x73, 0x7b, 0x6f, 0x67, 0x63, 
  0x7d, 0x7e, 0x0b, 0x0b, 0x7e, 0x7d, 
  0x3d, 0x7e, 0x66, 0x66, 0x7e, 0x3d, 
  0x3d, 0x7d, 0x60, 0x60, 0x7d, 0x3d, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    
};


// LUT For OBEGRÄNSAD
int lut[16][16] = {
        {23, 22, 21, 20, 19, 18, 17, 16, 7, 6, 5, 4, 3, 2, 1, 0},
        {24, 25, 26, 27, 28, 29, 30, 31, 8, 9, 10, 11, 12, 13, 14, 15},
        {39, 38, 37, 36, 35, 34, 33, 32, 55, 54, 53, 52, 51, 50, 49, 48},
        {40, 41, 42, 43, 44, 45, 46, 47, 56, 57, 58, 59, 60, 61, 62, 63},
        {87, 86, 85, 84, 83, 82, 81, 80, 71, 70, 69, 68, 67, 66, 65, 64},
        {88, 89, 90, 91, 92, 93, 94, 95, 72, 73, 74, 75, 76, 77, 78, 79},
        {103, 102, 101, 100, 99, 98, 97, 96, 119, 118, 117, 116, 115, 114, 113, 112},
        {104, 105, 106, 107, 108, 109, 110, 111, 120, 121, 122, 123, 124, 125, 126, 127},
        {151, 150, 149, 148, 147, 146, 145, 144, 135, 134, 133, 132, 131, 130, 129, 128},
        {152, 153, 154, 155, 156, 157, 158, 159, 136, 137, 138, 139, 140, 141, 142, 143},
        {167, 166, 165, 164, 163, 162, 161, 160, 183, 182, 181, 180, 179, 178, 177, 176},
        {168, 169, 170, 171, 172, 173, 174, 175, 184, 185, 186, 187, 188, 189, 190, 191},
        {215, 214, 213, 212, 211, 210, 209, 208, 199, 198, 197, 196, 195, 194, 193, 192},
        {216, 217, 218, 219, 220, 221, 222, 223, 200, 201, 202, 203, 204, 205, 206, 207},
        {231, 230, 229, 228, 227, 226, 225, 224, 247, 246, 245, 244, 243, 242, 241, 240},
        {232, 233, 234, 235, 236, 237, 238, 239, 248, 249, 250, 251, 252, 253, 254, 255}};
  
 unsigned short _pLatch;
 unsigned short _pClock;
 unsigned short _pData;
 uint8_t p_buf[16*16];


// -----------------------------------------------------------
void p_init(int p_latch, int p_clock, int p_data)
{

    _pLatch = p_latch;
    _pClock = p_clock;
    _pData  = p_data;
    pinMode(_pLatch, OUTPUT);
    pinMode(_pClock, OUTPUT);
    pinMode(_pData,  OUTPUT);
 }


// -----------------------------------------------------------

// Clear the Panel Buffer
void p_clear(){
    for (int i = 0; i < 256; i++)  {
        p_buf[i] = 0;
    }
}


// -----------------------------------------------------------
// SCAN DISPLAY, output Bytes to Serial
void p_scan(uint8_t cmask){

 
    analogWrite(P_EN,255);
    delayMicroseconds(TT); 
 
    uint8_t w=0;
    uint8_t w2=0;
     for (int i = 256; i>0 ; i--)  {            
          digitalWrite(_pData, cmask & p_buf[w++]);  
          digitalWrite(_pClock, HIGH);               
          digitalWrite(_pClock, LOW);                
          
   
        }  
// update 2024/01/01 speedup
       digitalWrite(_pLatch, HIGH);           
       digitalWrite(_pLatch, LOW);    
       analogWrite(P_EN,brightness);  // re enable brightmess
       
}


 // -----------------------------------------------------------

void p_drawPixel(int8_t x, int8_t y, uint8_t color)
{ 
  if((x<16) && (y<16)) {
#ifdef H_OBEGRANSAD
     p_buf[lut[y][x]] = color;
#endif
#ifdef  H_FREKVENS
    if (x > 7) { y += 0x10; x &= 0x07; }
    p_buf[(y*8+x)] = color ;
#endif
  }
}

// -----------------------------------------------------------
void p_fillScreen(uint8_t col){
  for (uint8_t x=0;x < 16; x++)
     for (uint8_t y=0;y < 16; y++)
       p_drawPixel(x, y, col);
}

// -----------------------------------------------------------
void test_display() {

    for (int i = 0; i<2; i++) {          
        p_fillScreen(0xff);  p_scan(1);  analogWrite(P_EN,250); delay(300);
        p_fillScreen(0x00);  p_scan(1);  analogWrite(P_EN,250); delay(300);
        
    }
}


// -----------------------------------------------------------
void p_printChar(uint8_t xs, uint8_t ys, char ch) {
    uint8_t d;
 
    for (uint8_t x=0;x<6;x++) { 
   
        d = pgm_read_byte_near((ch-32)*6+  // Buchstabennummer (ASCII ) minus 32 da die ersten 32 Zeichen nicht im Font sind
                               x +         // jede Spalte
                               System6x7); // Adrress of Font
   
     if ((d&1)    ==  1)  p_drawPixel(x+xs, 0+ys, 0xFF);else p_drawPixel(x+xs, 0+ys, 0);
     if ((d&2)    ==  2)  p_drawPixel(x+xs, 1+ys, 0xFF);else p_drawPixel(x+xs, 1+ys, 0);
     if ((d&4)    ==  4)  p_drawPixel(x+xs, 2+ys, 0xFF);else p_drawPixel(x+xs, 2+ys, 0);
     if ((d&8)    ==  8)  p_drawPixel(x+xs, 3+ys, 0xFF);else p_drawPixel(x+xs, 3+ys, 0);
     if ((d&16 )  == 16)  p_drawPixel(x+xs, 4+ys, 0xFF);else p_drawPixel(x+xs, 4+ys, 0);
     if ((d&32 )  == 32)  p_drawPixel(x+xs, 5+ys, 0xFF);else p_drawPixel(x+xs, 5+ys, 0);
     if ((d&64 )  == 64)  p_drawPixel(x+xs, 6+ys, 0xFF);else p_drawPixel(x+xs, 6+ys, 0);
   
    }
 }  
 

// -----------------------------------------------------------
const char* getTimeString(void) {
  static char   acTimeString[32];
  time_t now = time(nullptr);
  ctime_r(&now, acTimeString);
  size_t    stLength;
  while (((stLength = strlen(acTimeString))) &&
         ('\n' == acTimeString[stLength - 1])) {
    acTimeString[stLength - 1] = 0; // Remove trailing line break...
  }
  return acTimeString;
}
 

// -----------------------------------------------------------
 void set_clock(void) {   
  configTime(MY_TZ, MY_NTP_SERVER); // --> Here is the IMPORTANT ONE LINER needed in your sketch!
  Serial.print("Waiting for NTP time sync: ");
  time_t now = time(nullptr);   // Secs since 01.01.1970 (when uninitialized starts with (8 * 3600 = 28800)
  while (now < 8 * 3600 * 2) {  // Wait for realistic value
  
    Serial.print(".");
    now = time(nullptr);
  }
  Serial.println("");
  Serial.printf("Current time: %s\n", getTimeString());
}



// -----------------------------------------------------------
void set_clock_from_tm() {
    time(&now);                       // read the current time
    localtime_r(&now, &tm);           // update the structure tm with the current time  

   // update time from struct
   sec    = tm.tm_sec;
   minute = tm.tm_min;   
   hour   = tm.tm_hour;   
}



// -----------------------------------------------------------
void setup() {
  pinMode(P_LDR,INPUT);          // Light detector
  pinMode(P_KEY, INPUT_PULLUP);  // RED KEY
  pinMode(P_EN, OUTPUT);         // Pseudo Analog out for FM Brightess
  analogWrite(P_EN, brightness); // adjust brightness

  p_init(P_CLA, P_CLK, P_DI);    // init Display

  test_display();
  Serial.begin(74880);           // Native Baud Rate of ESP
   
  p_clear();
  p_printChar(2,0,'A');          // Print "AP" while waiting for WiFi Manager
  p_printChar(9,0,'P');
  p_scan(1);
  delay(1000);

  WiFi.mode(WIFI_STA);
  WiFi.begin(STASSID, STAPSK);

   while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
   p_printChar(2,9,'O');
   p_printChar(9,9,'K');
   p_scan(1);
   delay(500);
   
   //if you get here you have connected to the WiFi   
   Serial.println("Wifi connected!");
   // Sync clock
   set_clock();
   set_clock_from_tm() ;
   print_time();
   
}


// -----------------------------------------------------------
void print_time() {
        p_clear();
        p_printChar(2,0,(hour / 10)   +48);
        p_printChar(9,0,(hour % 10)   +48);
        p_printChar(2,9,(minute / 10) +48);
        p_printChar(9,9,(minute % 10) +48);
        p_scan(1); // refreshes display
  
}
// -----------------------------------------------------------
/// MAIN LOOP

void loop() {

  // JEDE SEKUNDE
  if (millis()>mil+1000)
  {
    mil = millis();
    sec ++;
    // Brightness should change every second
    brightness = map(analogRead(P_LDR), 1024, 7, 200, 254);
    analogWrite(P_EN, brightness);

    // Jede Minute
    if (sec>60) {
        sec = 0;
        set_clock_from_tm() ;
        print_time();
    }
    // Sync with NTP server only once a day
    // After 3 AM will catch summer/winter time
    if (hour == 03 & minute == 15 & sec == 00) {
        set_clock();
    }
  }
}

FLICKER:

If you experience Flicker while the Display is updated, try a different Power Supply ! Not all chargers are good power supplies. You need a good amount of milliamps to drive all LEDS…

NEW: Try the updated source which reduces the number of pixel updates. which prevent power glitches .

Startup/BOOT Problems:

Make sure ESP was erased before flash. Maybe you need to use the ESP Tools for full chip erase!

Unfortunately we proposed to use D4 is KEY pin. Pressed during Power Cycle, it prevents the CPU from booting. You may use another IO for the KEY!

FONT EDIT

You do not like the Font ? Want to edit Characters – No Problem! Download the bitmap below and make edits of your choice. Then convert to C-Code with the online Image2cpp converter.

Image2cpp converter

https://hurricanejoef.github.io/image2cpp/

Import the font below, Section 2: select: Invert image colors, Section 4: Select: Arduino Code , Horizontal 1 bit per Pixel.

Select „Invert“ in Section 1
Select Arduino Code and Horizontal 1 Bit per Pixel

This Code above is for the LDR variant. Attach the LDR to the Side of the case, so that it is catching surrounding light, but not the illumunation caused by the clock.

Do you like the project ?

https://www.buymeacoffee.com/pixelkoenig

Example Font

Download this font and edit as you like with MS Paint, then convert it with Image2cpp into C-Source and copy into your Sketch.

Hall of FAME:

X-Clock (IKEA OBEGRÄNSAD Hack)

114 Gedanken zu „X-Clock (IKEA OBEGRÄNSAD Hack)

  1. Interessantes Projekt. Danke für’s Teilen.
    Frage: Warum gibt es die erweiterte Version der Firmware (mit Wifi Manager, Web Frontend, Animationen (welche?), Timern (für was?), Auto Update und Brightness Control (wo genau wird da eigentlich der Helligkeits-Sensor montiert?)) nicht auch im Repository?

    1. Hallo Karl-Heinz,
      Zu dem Display fallen jedem Nutzer wahrscheinlich sehr verschiedene Anwendungen ein. Die hier hinterlegten
      Beispiele ermöglichen eine sofortige einfache Nutzung und Nachvollziehbarkeit. Auf Deine Nachfrage habe ich das Beispiel mit LDR noch zusätzlich unten in den Artikel gepackt.
      Ich bastle schon lange Zeit eigne Uhren und natürlich sind mir viele Features eingefallen. Das Ergebnis teile ich gern. Es soll ja auch als Inspiration für eigene Ideen dienen.
      Eine Veröffentlichung der Sourcen erdorfert Ornung des Codes und die Prüfung der Rechte. Zusätzlich gäbe es eine Menge Fragen zu Modifikationen. Das übersteigt meinen Hobbyanspruch. Die Alternative wäre nur das Entfernen des Binaries aus dem WebFlasher und das wäre ja schade. Also wünsche ich viel Spass beim ausprobieren, es kostet ja nix. Die fertigen Binaries werden übrigens regelmässig mit Updates versorgt.

      Der Pixelkönig

      1. Hallo Pixelkönig,
        danke für die erweiterte Version.
        Eine Sache noch: in den Sourcen ist zwar davon die Rede, dass der LDR an A0 angeschlossen wird, im Fritzing-Sketch ist er aber an D0 angeschlossen.
        Grüße!

  2. Danke für das Projekt 🙂
    Kann ich folgende Komponenten für die Erweiterung mit LDR verwenden: GL5537 und Metallschicht Widerstand 100k 0.4 W ?

    1. Hallo Mati,
      Ja das sollte gehen.
      Sie können später die Helligkeitsfunktion im Code an die Lichtverhältnisse und die Sensorwerte anpassen.
      Dazu die Messwerte für helles Licht und Dunkelheit bestimmen und anstatt der 1024 und 0 einsetzen. Viel Spass

  3. Hallo,

    ich habe versucht das Projekt nachzubauen, leider funktioniert es nicht ganz wie erwartet. Als cap habe ich leider gerade nur einen 16V 1000uF, aber es macht keinen unterschied ob mit oder ohne. Die Uhr geht an, verbindet sich und zeigt die Zeit an, dann geht sie innerhalb 30-60 Sek wieder aus. LDR ist ein GL5528 mit 100k Pulldown, wie beschrieben.
    Wie kann ich auf das Web-Interface kommen? Beim Start der Uhr wird mir zwar eine IP angezeigt, unter der kann ich aber leider nichts erreichen.
    Woran kann das liegen?

    1. Hallo Daniel,
      Das Verhalten der Uhr ist normal. Sie wird sich automatisch ausschalten da sie anscheinend noch keine Uhrzeit bekommen hat . Für die Uhr ist es dann Nachts und „Nachts“ schaltet sie sich aus.

      Bitte prüfe nocheinmal ob Du einen Access Point x-clock findest und dort die SSID und das Passwort korrekt eingegeben wurden.

      Findet die Uhr das Heimnetz, zeigt Sie „AP“ und dann „OK“ an. Unter der im folgenden angezeigten IP sollte man das Web Interface erreichen.

      Das klappt gut mit dem Chrome Browser. Der Firefox zeigt manchmal die Webseite nicht an.

      Als erstes kontrolliert man dann den Timeserver auf der Netzwerk Seite.
      Ggf verwendet man den dort angezeigten Beispiel Eintrag und kopiert diesen in das Eingabefeld. Mit dem Button „get Network Time“ forciert man das abholen der Uhrzeit.

      Dann sollte man zwischen 7:00 und 23:59 Uhr wieder die Uhrzeit angezeigt bekomnen. Andere Einschaltzeiten konfiguriert man über die „Timer“ Seite.

      Ich hoffe das hilft !

      1. Hallo, danke für die Antwort. Sie zeigt die aktuelle Uhrzeit an, aber geh dann wie gesagt aus. Chrome benutzte ich auch. Und wenn ich die ein paar mal die Taste kommt auch eine Art Lauftext, aber dann wieder nichts.
        Chrome benutze ich auch.

        Ich habe den Chip auf der IKEA Platte nicht komplett ausgelötet, sonder nur das VCC Beinchen angehoben. Und D4 (Button in) nehme ich von der linken Seite von C6. Das sollte aber doch trotzdem gehen? Zumindest solle lt. Multimeter alles korrekt verbunden sein…

  4. Hallo Daniel,
    Elektrisch ist anscheinend alles OK. Es handelt sich um Probleme bei den Einstellungen.
    Als Lauftext sollte zu sehen sein:
    „Y-Clock Version 0.9 “
    „AP“, „OK“ gefolgt von der IP Adresse..
    Kannst Du „AP“ und „OK“ und die IP Adresse erkennen ?
    Diese im Browser eintippen. Wie ist das Ergebnis ?

    Grüsse

    1. Hallo Daniel,
      vielleicht versehentlich das eigene Gastnetz erwischt ? Zum korrigieren müsste es reichen die Taste lange zu drücken, dann sollte der y-clock Accespoint auf dem Handy wieder erscheinen.
      (Alternativ Software neu installieren).
      Übrigens: sollte sofort automatisch ein Update auf Version 09 erfolgen. Also nochmal anschalten ..und ein wenig abwarten !
      Im Blog habe ich eine Anleitung für die Software hinterlegt. Das hilft vielleicht bei den Einstellungen. Übrigens ist die Software eigentlich für den D1-Mini-Pro gemacht. Es könnte sein das die automatischen updates aufgrund geringen Speichers vielleicht nicht funktionieren. Kann ich leider nicht prüfen. Die Prüfung erfolgt nach Anzeige der IP. Man sieht das die Uhr da neu startet, weil ggf das update nicht geklappt hat…

      UPDATE: Die Version auf dem Webinstaller entspricht jetzt der letzten aktuellen Version und das Handbuch ist direkt dort verlinkt.
      Grüsse

  5. Ja, war im Gastnetz -.-

    Also, die Uhr an sich funktioniert jetzt schon mal. Leider scheint das Update vom Zeitserver nicht richtig zu funktionieren, ist immer -1h. Software Version wird auch immer noch 0.1.00 angezeigt.
    Kann man den Timeserver irgendwie ändern?

    Ich kann die Uhr zwar manuell richtig stellen, nach einer Minute holt er sich aber wieder die falsche Zeit.
    Den Punkt „Web Update“ gibt es derzeit gar nicht, habe gerade nochmal die Software von der Webseite neu geflasht.

    Grüße

  6. Hallo Daniel,
    Im Netzwerk Tab bitte den Eintrag für den Zeitserver prüfen. Er steht bei der 09 Version links: Alles markieren und rechts ins Eingabefeld kopieren. Dann klappt es auch mit der Sommer/Winterzeit

    (Oder „load defaults“ verwenden)

  7. Coole Idee,Respekt..

    Sollte doch möglich sein einen 3Wege Schalter zwischen dem Original Mikroprozessor und dem D1-Mini-Pro zu wechseln oder?

    Natürlich mit der entsprechenden +- Verlötung…
    Oder spricht da was dagegen?

    1. Hallo Christian,
      Du bräuchstest am besten wohl einen 4 fach Schalter für die Datenleitungen. Ob es funktioniert nur die Stromleitungen umzuschaltet wäre ein Experiment wert.

      Ich glaub es ist einfacher die Effekte mit in den D1 Mini reinzuprogrammieren.
      Braucht nur „einen verregneten Nachmittag“ um die lahmen original Effekte einzubauen…

      Grüsse

  8. Hallo,
    mein Versuch, die Uhr nachzubauen, ist leider gescheitert. Woran es aktuell liegt ist mir nicht klar.
    Das Löten hat ohne Probleme funktioniert, das Aufspielen der SW (https://o-clock.eu/) hat beim ersten Mal auch noch geklappt, aber wenn ich die Uhr mit einer USB-Buchse verbinde, wird nicht das Geringste angezeigt.
    Wenn ich die SW erneut aufspielen möchte erhalte ich die Fehlermeldung „Failed to initialize. Try resetting your device or holding the BOOT button while clicking INSTALL.“. Welcher BOOT button?

    Wo kann ich ansetzen um noch zu einem guten Ende zu kommen und die aktuell Fehlerursache zu identifizieren und zu beheben?

    Würde mich sehr über Anregungen freuen …

    Ciao
    Andreas

    1. Hallo Andreas,

      UPDATE:
      Leider hat der Webflasher die Sripte verwechselt. Bitte probier es nochmal aus !

      Schade, manchmal zicken die ESPs und man bekommt es durch probieren doch noch irgendwann hin:

      . Der Knopf ist an der Seite, beim flashen gedrückt halten oder kurz vorher mal drücken und folgendes probieren..

      1. Probiere einfach erstmal irgendeine der anderen Softwaren auf o-clock.eu zu flashen.
      2. Probiere irgendein Demo-Programm mit der Arduino Ide aufzuspielen
      3. Alle Kabel ablöten und Schritt 1 und Schritt 2. nochmal probieren.

      Wenn das nix hilft war der ESP wohl defekt…:(

  9. Hallo, ich (noob) habe fertig 🙂
    Die Uhr funktioniert und zeigt die aktuelle Zeit an. Allerdings flackert die Anzeige. Ich habe vier unterschiedliche Netzteile ausprobiert. Leider ohne Erfolg.
    Den Taster habe ich ebenfalls angeschlossen. Drück und Halten dimmt das Display (zyklisch) langsam runter. Aber wenn ich den Taster loslasse wird wieder die volle Helligkeit verwendet.
    Einzige Erklärung für das Flackern, die ich habe: Zu dünne Kabel verwendet. Kann das sein?

    1. Hallo Heiko,

      Im fertigen Programm wird Anzeige jede Sekunde geändert. Meinst Du das als Flackern ?

      Hast Du selber übersetzt oder die fertige Software verwendet?

      Versuche mal mit der Arduino IDE selber zu übersetzen und im Code den Wert TT zu ändern.

      Im Arduino Sketch könnte man das ändern Anzeige seltenr aktualisieren..

      Grüsse

      1. Danke für die schnelle Antwort.
        Ich habe den Code in die Arduino-IDE kopiert, STASSID und STAPSK angepasst, kompiliert und hochgeladen. Die Variante über o-clock.eu hat leider bei mir auch nicht geklappt. Schade, denn ich hätte auch gerne die Zeitbegrenzung (von – bis) für die Anzeige. Aber vielleicht ist der Wunsch ja ein Anreiz, mich mit der Programmierung zu beschäftigen und Dinge auszuprobieren 😉
        Versuche jetzt mal die vorgeschlagene Änderung des TT-Werts.

          1. Hallo!
            Leider komme ich über den WEB-Installer nicht weiter. Im Fenster „Installing X-Clock Web“ hängt sich der Installer nach dreifachem blauen Blinken auf dem Board während „Preparing Installation“ auf. Sämtliche Kabel von der Lampe getrennt. Leider ohne Erfolg.
            Besteht nicht evtl. doch die Möglichkeit den Sketch-Code bzw. die Binärdatei zu posten, damit diese mittels Arduino IDE geflasht werden kann? Bei mir wäre es die Version „X-Clock WEB FOR OBEGRÄNSAD V0.1.09“
            Verzweifelte Grüße

          2. Hallo Heiko,

            UPDATE: Danke für den Kaffee !

            Bitte beachte, das ich nur den Wemos D1 Mini *** PRO *** am WebFlasher getestet habe.
            Der Speicher des D1 MINI ist kleiner.
            Deshalb kann es sein, das es bei Verwendung eines MINI der WebFlasher nicht funktioniert.
            ( Manchmal werden MINIS als MINI-PRO verkauft… )
            Ich habe die Version 1.00 und 1.09 auch für den MINI (ohne PRO) hinterlegt.
            Vielleicht hilft das herauszufinden wo das Problem liegt.
            Wenn es klappt, und mit dem PRO nicht, habt Ihr wohlmöglich den falschen ESP verwendet.

            folgende Lösungen :
            1. Eine beliebige andere Version der X- oder Y-Clock probieren. Und dann nochmal die X-Clock V1.0.9.
            2. Manuell flashen mit den esptools: Die jeweils aktuellen bin files liegen immer auf o-clock.eu/update/xclock.bin

            Grüsse

      2. Habe jetzt den Teil
        // PRINT THE TIME
        in den Abschnitt
        // every minute set the time
        verschoben.
        Jetzt wird nur alle 60 Sekunden aktualisiert.
        Damit bin ich dann MEGA-zufrieden, 🙂
        Tolles Projekt. Nochmals vielen Dank

    2. Hallo Heiko,
      Der Taster muss an GND und an den D4 angeschlossen werden.
      Man muss Ihn nur kurz drücken und dann loslassen. Jedesmal geht es eine Stufe dunkler. Nach vier Stufen kommmt wieder die maximale Helligeit..
      Zu dünne Kabel sollten kein Problem sein.
      Viele Grüse

  10. Hallo,
    ich habe den WEMOS über Arduino geflasht. Soweit kein Problem. Jetzt wollte ich die ESPHome Variante
    testen. Wo finde ich die pre-build Firmware? ESPHome habe ich installiert.

    Danke und Grüße
    Klaus

  11. So, bei mir hat es jetzt mit den ESPtools und dem direkten flashen der .xclock.bin geklappt. Auf diesem Wege noch einmal vielen herzlichen Dank für die schnellen Reaktionszeiten und die unverzügliche Problembehebung.
    Ein tolles Projekt. Wieder viel gelernt. Und Spass ist natürlich auch immer am Start, wenn der Lötkolben glüht.
    Am Ende habe ich mich nur gewundert, warum die Leute so einen digitalen IKEA-Bilderrahmen kaufen, (der einen mit den einfallslosen Animationen nur verrückt macht). Dank dem X-Clock-Projekt hat man jetzt ein wirklich nützliches Gadget. Bin total happy, werde jetzt die Rückseite verschließen und die Uhr aufhängen.
    Nochmals vielen herzlichen Dank.

  12. Hi, thanks for the LDR Version, I installed it successfully and made some changes: https://github.com/maltewirz/Obegraensad/blob/develop/Arduino-Sketch/obegraensad_d1_mini_V0.ino

    Most important change is „sec = tm.tm_sec;“, see diff here: https://github.com/maltewirz/Obegraensad/commit/71939c0afa746dc5cbc0febe09daeddb6cb72a9f#diff-e1817d7de02886d18232b9071bd7b6874f8519bcd7992a83398cbdd502a95b2cR318

    This caused a two minute delay, now the clock is right on the second.
    Lastly, i changed the sync with NTP server only once a day – I checked and this is sufficient 🙂

  13. Hi, ich nochmal….
    Warum orientierst Du Dich eigentlich nicht an der Software für eine Wordclock auf ESP8266-Basis, wie sie schon seit längerem existiert? Gute Beispiele siehe
    http://thorsten-wahl.ch/qlockwork/,
    http://www.harald-sattler.de/html/wordclock_v2.htm
    https://github.com/bracci/Qlockwork
    1) die Usability hat noch Potential: mit dem Smartphone ist (für mich) das Frontend so nicht wirklich gut bedienbar, weil die Darstellung sehr klein ist und ständig gezoomt werden muss. Die „save“-Tasten liegen so nah beieinander, dass es immer wieder zu Fehlbedienungen kommt. Hier würde ich an die Vorarbeiten der Wordclock-Veteranen verweisen. Das Tasmota-Frontend ist ähnlich aufgebaut. Wenn man also schon mal mit derartigen Frontends zu tun hatte, würde man sich auch sehr schnell in einer ähnlichen Bedienung des IKEA-Panels zurecht finden.
    2) Helligkeiteinstellung automatisch: der ESP kann sich doch selbst den Min- und den Max-Wert merken und danach seine Skala für die Brightness-Einstellung berechnen. Nach zwei bis drei Tagen funktioniert diese Regulierung sehr gut. Das hat den Vorteil, dass die Helligkeitseinstellung flexibel bleibt (z.B. durch die Jahreszeit bedingte Helligkeitsänderungen werden gut ausgeregelt) und keine Einstellung durch Anwender notwendig ist.
    3) Time-Zone: dafür gibt es eine Lib, die auch bei den Wordclock-Varianten zum Einsatz kommt. Die Einstellung per kryptischen Kürzeln ist keinem „normalen“ Anwender zumutbar.
    4) da die Wordclocks schon seit langem mit einem D1-mini (mit 4MB Flash) auskommen, müsste das doch hier für das IKEA-Panel auch als Quasi-Standard reichen. Das OTA-Feature ist DAS Argument für einen großen Flash-Speicher, darauf verzichte ich aber liebend gerne. Ich mag es einfach nicht, wenn ungefragt per OTA Updates eingespielt werden ( das entscheide und mache ich lieber selbst). Übrigens: bei reichelt.de und bei az-delivery.de gibt es D1-mini-Pro, die laut Artikeltext auch nur 4MB Flash (statt 16MB, wie das WEMOS-Original) haben. Damit ist das Chaos perfekt.

    Bitte bleib weiter dran.

    1. Hallo Karl-Heinz,
      Vielen Dank für Deinen ausführlichen Kommentar und die Links.
      Du bist offensichtlich Profi und hast eine grössere Übersicht über andere Projekte.

      Ich muss Dir in allen Punkten Recht geben.

      Ich könnte zu jedem Punkt eine lange Begründung abgeben. Letztlich hat iwahrscheinlich jeder Fortgeschrittene **sehr** genaue Vorstellungen davon wie das eigene Projekt aussehen soll.
      Das hatte auch mich bewegt, etwas eigenes zu machen und mich nicht an ein Projekt anzuhängen.

      Als fortgeschrittener maker sind die wenigen Zeilen Code, die notwendig sind um diese spezielle Hardware zu nutzen, fix in das eigene Framework eingebaut.
      Das finde ich persönlich an Beispielen aus dem Netz am besten.

      Meine eigene Web Version stelle ich gern zur Verfügung. Im schlechtesten Fall dient es als Beispiel wie man es besser machen kann…
      Letztendlich ist alles eine Frage der Zeit und es ist ja nur ein Hobby Projekt.

      Update: Ich hab auf Basis eines der von Dir empfohlenen WordClock Propjekte mal eine meiner WortUhren umgebaut und das Projekt eignet sich auch gut als Basis für die X-Clock. Vielen Dank fün den Tipp

      Viele liebe Grüsse und fleissiges Maken!

  14. Hi Pixelkönig,
    danke für die Anleitung. Der Umbau hat gut und schnell funktioniert.
    Ich habe die X-Clock WEB FOR OBEGRÄNSAD (MINI PRO) V0.1.09 Version installiert und die Uhrzeit wird angezeigt. Leider jetzt im Winter um 1 h verschoben.
    Muss ich für die Version mit Winterzeitumstellung die SW selber bauen oder habe ich die falsche Version geflasht?

    Grüße

    Alex

    1. Hallo Alex,
      Super das es geklappt hat – ein Foto wäre prima. Die Uhr hat ja ein WEB Interface.
      Beim Start zeigt Sie Ihre IP Adresse. Im Browser (Safari/Chrome) die IP eingeben und das Web Interface erscheint.
      Dort bitte auf der Seite „Netzwerk“ die Zeitkonfiguration eintragen:
      Für Deutschland:
      CET-1CEST,M3.5.0/02,M10.5.0/03

      1. Hi Pixelkönig,
        Es hat alles gut funktioniert. Ich konnte am Anfang nur nicht auf das Webinterface zugreifen aufgrund der Router Einstellungen.
        Ich habe aber leider noch eine Probleme mit der Stromversorgung.
        An dem USB Anschluss des Laptops läuft die Uhr super, an der Powerbank ganz gut aber es flackert ein Pixel.
        Netzteile funktioniert alle an sich nicht richtig egal wieviel Leistung die haben.
        Auf was kommst den genau an?
        Spannungs-, Stromstabilität ?
        Und wie genau kann ich hier ein Foto Posten?
        Grüße
        Alex

  15. Hallo, herzlichen Dank für diese Anleitung! Der Umbau des OBEGRÄNSAD hat funktioniert und nun verbindet sich der D1 Mini mit meinen Heim-WLAN und zeigt anschließend auch dauerhaft die korrekte Uhrzeit auf dem OBEGRÄNSAD an.

    Ich habe das obere Skript verwendet (ohne Helligkeitssensor, WifiManager entfernt). Die Helligkeit müsste nun über D4 (rotes Kabel) einstellbar sein. Aber leider kann ich D4 nicht anschließen, weil sonst der D1 Mini streikt: Die blaue Onboard-LED leuchtet direkt nach dem Einschalten dauerhaft und es tut sich nichts… Trenne ich die Verbindung zu D4 funktioniert die Schaltung prima – nur dann mit der Standard-Helligkeit. Das Bestätigen des Knopfs am Rahmen des OBEGRÄNSAD ändert nichts.

    Könnt ihr mir helfen zu verstehen, was das Dauerleuchten bedeutet?
    Weshalb tritt es auf?
    Herzlichen Dank vorab!
    – slowjoe

    1. Hallo SlowJoe,
      Der Taster muss an GND und an D4 angeschlossen werden. Dazu habe ich die Kabel des Tasters mit einem rot / schwarzen Kabel verlängert. Daher die Farben rot und schwarz.

      Hast Du das auch so gemacht ? Alternativ mal einen anderen Taster für D4 verwenden und an GND löten. In der Ausgabe (Serial Monitor) kann man auch sehen ob der Taster gedrückt wird. Man könnte auch einen anderen Eingang verwenden falls der D4 vielleicht defekt ist. Viel Erfolg.

      1. Ja, der Taster ist tatsächlich korrekt angeschlossen. Inzwischen klappt’s. Aber vielleicht läuft noch jemand in dieses Problem, also beschreibe ich mal hier das Symptom und wie ich zur Lösung gekommen bin.

        Wenn der Taster bereits zum Start des Boards an D4 angeschlossen war, leuchtete die Onboard-LED dauerhaft blau. Das Board schien einfach gar nichts zu machen. In der IDE (VS Code mit PlatformIO) habe ich am Serial Monitor folgendes gesehen:

        Fatal exception (0):
        epc1=0x40100003, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000
        Fatal exception (0):
        epc1=0x40100003, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000
        Fatal exception (0):
        … usw. …
        (endlose Wiederholung in schneller Folge)

        Wenn ich allerdings den Taster erst nach erfolgreichem Start an D4 angeschlossen habe, zeigte sich folgendes Bild (das wusste ich übrigens bei meinem ersten Post noch nicht):
        Die Uhrzeit wird auf der LED-Matrix korrekt angezeigt. Sobald ich D4 anschloss wechselte die Helligkeit (in vmtl. 0,5-Sekunden-Schritten) in einer Endlosschleife immer von hell nach dunkel. Der Serial Monitor zeigte folgendes:

        // Start ohne D4
        Reconnecting to COM3 ……… Connected!
        …..Wifi connected!
        Waiting for NTP time sync:
        Current time: Sat Dec 9 14:25:14 2023
        Waiting for NTP time sync:
        Current time: Sat Dec 9 14:26:14 2023
        // Anschluss D4
        129154179204229129154179204229129154179204229129154179204229129154179204229129154179

        (Die Zeilen, die mit // starten, waren im Serial Monitor nicht zu sehen. Ich habe sie hinzugefügt, um die parallelen Aktivitäten einzuordnen.)
        Die letzte Zeile müsste das Ergebnis des „Serial.print(brightness)“-Befehls am Ende des Skripts sein.

        Meine Vermutung war nun, dass der Taster evtl. klemmt und daher dauerhaft geschlossen ist.
        Da ich an den Taster ein männliches Dupont-Kabel angelötet habe, das ich in die am D1 Mini angelötete Steckleiste gesteckt hatte, konnte ich einfach das Kabel am D1 Mini lösen und mit einem weiteren m-m-Kabel eine Steckverbindung schaffen, die ich provisorisch als zusätzlichen Schalter nutzen konnte. Mit offener Verbindung habe ich dann den D1 Mini neu gestartet und nach Erscheinen der Uhrzeit kurzzeitig die Kontakte der beiden Kabel aneinander gehalten: Die Helligkeit änderte sich, blieb dann nach Trennung konstant.
        So weit so erwartet. Ein erneutes Verbinden der Kabel änderte aber danach gar nichts mehr… Anscheinend war der Taster nun nicht mehr geschlossen, obwohl ich ihn nicht bewegt habe. Diese Beobachtung kann ich mir nicht erklären…

        Auf jeden Fall funktioniert jetzt wirklich alles: Ich habe das am Taster angelötete Kabel wieder direkt mit dem D4 Port des D1 Mini verbunden und jetzt kann ich die Helligkeit mit dem Taster am Rahmen des OBEGRÄNSAD zuverlässig steuern.

        Die Grundlagen funktionieren nun. Wunderbar! 😉
        Vielen Dank an alle Beitragenden!

        1. Der Kunststoff bzw. die Mechanik des Tasters könnte durch die Hitze beim Löten was abgekommen haben. Vielleicht ist auch Flussmittel in den Taster gelaufen, how knows.
          Ja, den D4 als Input zu nehmen, an dem ein Taster angeschlossen ist, der dann den D4 nach Masse zieht, ist vielleicht etwas unglücklich. Da der D4 beim Booten eine Rolle spielt, könnte das zu unerklärlichen Effekten führen.
          Bei einem Umzug, bei dem der schwarze Monolith an einem heißen Sommertag in einem Sprinter von Frankfurt nach Berlin geschüttelt wird, wird dann wohl zum Ausfall führen und kein Mensch kann sich erinnern, dass das am Schalter liegen könnte…
          Ich würde empfehlen, den Taster auf den freien D2 zu legen.

  16. Hallo, ich bin’s mal wieder…
    Hab mir inzwischen einen Wemos D1 Mini Pro geholt, leider scheitert es jetzt schon beim Web-Installer.
    Es kommt immer die Fehlermeldung „Failed to initialize. Try resetting your device or holding the BOOT button while clicking INSTALL.“

    Hab beides versucht, geht leider nicht. Hab mein Modell von makershop.de, sollte aber doch kompatibel sein oder? Sieht zumindest auf dem Bild 1 zu 1 wie deiner aus. Gibt es eine andere Möglichkeit die Software z.B. manuell zu flashen?

  17. Nevermind, es hat lediglich ein Treiber gefehlt. Der war beim D1 mini nicht erforderlich… Ich teste nun mal, ob es mit dem PRO und 1.09er Firmware besser klappt 🙂

  18. Ein cooles Projekt.
    Leider schließt sich mir die Dimmung nicht.

    Bei versuchen, das Display zu dimmen, wird die Anzeige ungleichmäßig. Ein Panel bleibt hell weiß, die anderen sind abgedunkelt. Ich habe schon so ziemlich alle Werte zwischen 100 und 255 versucht, aber ich bekomme die Brightness nicht in den Griff.

    Bei sekündlicher Erneuerung tritt der Effekt nicht auch. Ich möchte aber eine Anzeige (Temperatur) für ein paar Sekunden ohne „Refresh“ stehen lassen.

    Ist das ein „elektrisches“ Problem? Ich habe keinen Kondensator verbaut und ein Wemos D1 mini (ohne Pro) am Start.

    1. Hallo!
      Cool das Du das Projekt erweiterst.
      Die Dimmung wird über den Analog Ausgang geregelt. Aber die ist digital. D.h. der „Analog“ Wert im EsP oder Arduino ist nur eine PWM, also ein sehr sehr schnelles an und aus. Das wird vor dem Nutzer versteckt in der Funktion Analog out.

      Manche Funktionen der Libs stören die Analog Ausgabe, zb die beliebten RGB WS2812 Leds.

      Es wär als erstmal zu prüfen ob die Temperatur Lib das Analog Signal stört.
      Dann würde ich die Helligkeit erstmal fest
      einstellen (p_Scan letzte Zeile) und schauen ob es besser wird.

      Aber dne Elko montieren ist bei Flackern die beste Idee!

      Liebe Grüsse

      1. Hallo, danke für die Rückmeldung und die Tipps. Einen Kondensator habe ich verbaut und ein anderes USB-Netzteil versucht (das von IKEA arbeitet erfreulich „spannungsstabil“).

        Die Anzeige wechselt zwischen Zeit, PM2,5 (Feinstaub) und Temperatur. Die beiden Messwerte werden aus einer Luftdaten.info Station über httpGet und Json „abgeholt“.

        Die zentrale Herausforderung bleibt PWM. An zwei „Delay“ Aufrufen scheint es nicht zu liegen. Ab einem bestimmten Punkt der Dimmung (>204) wird die Anzeige in den weiteren Schleifen (nach der Zeitanzeige) für die „Temperatur“ und „Feinstaub“ instabil, seltsamerweise nur das „untere“ Display, von den Vieren, auf welchem die ursprüngliche CPU liegt. Die Zeitanzeige bleibt „stabil.“

        Ich werde mal ein anderes „größeres Board“ versuchen, wohl ein D1 R2, mit Netzteil, mit analogWrite() experimentieren und versuchen, die „Störquelle“ zu finden. Möglicherweise auch ein Problem, das aus den WLAN Abfragen entspringt.

        Ich berichte. 🙂

        Beste Grüße!

  19. Hallo,

    hat jemand schon mal eine andere Zeitquelle als NTP versucht. Ich würde die Uhr gerne bei mir im Büro aufhängen und da ist es etwas schwierig mit der Einbindung von Gerät.
    Zuerst dachte ich an DCF 77 oder einem RTC Board.

    Danke für eure Hilfe

    Grüße

    1. Hallo!
      Bisher nicht.
      1. Tipp: Im Büro ein Gastnetz verwenden
      2. Zur RTC
      Ich würde so vorgehen:
      Uhrchip oder DCF anlöten und Arduino Beispiel dazu ausprobieren.

      Anschliessend die Uhrzeit auslesen und
      zur Kontrolle ausgeben. Dann den Code der x-clock dazukopieren..

      Frohe Weihnachten

      Viele Grüsse

      1. Hat wunderbar funktioniert!!
        Danke für den Denkanstoß

        Eine Frage habe ich noch, ich würde gerne die Weboberfläche nutzen um die Abschaltung an bestimmten Tagen und Uhrzeiten zu nutzen. Würdest du den Code der Version 1.0.9 bereitstellen?
        Ich nutze die Arduino IDE und würde gerne die RTC in diese Version einfügen

  20. Hallo
    Hat auf Anhieb funktioniert – sogar mit dem Webinstaller. Beeindruckend.
    Sobald ich etwas Zeit habe, versuche ich es zu erweitern. Ne Laufschrift wäre nicht schlecht.
    Frohe Weihnachten

  21. I am running the X-Clock WEB FOR OBEGRÄNSAD (MINI PRO) V0.1.09 software which I installed via https://o-clock.eu/. That was really easy to set-up on my Wemos D1 mini, awesome!

    But the actual time is 1 hour in advance of the time that the clock shows. When I change the time via the web interface the time is updated. But the moment that a minutes passed and the clock updates the hour is set back 1 hour again.

    If I then refresh the web interface the hour is indeed changed again. So it looks like new time is not actually stored. When I set the minute incorrect and then wait for a minute it is also set back to the actual time.

    This is all great but only if the time is shown for the correct time zone and with DST off for now in the winter. What can I do?

  22. Hallo Pixelking,
    Bei mir hat die Installation per Webinstaller ( X-Clock WEB FOR OBEGRÄNSAD (MINI PRO) V0.1.09) ebenfalls super einfach und komfortabel schnell funktioniert. Danach habe ich per Web-Frontend mein WLAN eingetragen und gespeichert. Der Wemos D1 mini Pro startet danach und ich kann ihn in meinem DHCP finden. Wenn ich mich nun aber per Browser darauf verbinden möchte (getestet mit Firefox und MS Edge), dann komme ich nicht drauf. „Die Webseite ist nicht erreichbar:“.
    Der serielle Monitor liefert folgendes:
    21:44:59.824 -> HTTP serv: new client
    21:44:59.824 -> http_main aaction:- disconnct
    21:44:59.963 -> HTTP serv: new client
    21:45:05.426 -> – empty http request
    Was kann das sein?

    Nebenbei muss ich einräumen, dass der Wemos D1 mini Pro noch nicht noch nicht in der OBEGRÄNSAD eingebaut ist. Ich teste „steril“ auf dem Schreibtisch per USB-Kabel am PC. Hat es etwas damit zutun?

  23. Hallo, ich erhalte beim Kompilieren folgende Fehlermeldung:
    Was mache ich falsch?

    Arduino: 1.8.19 (Mac OS X), Board: „LOLIN(WEMOS) D1 R2 & mini, 80 MHz, Flash, Disabled, 4M (no SPIFFS), v2 Lower Memory, Disabled, None, Only Sketch, 921600“

    /Users/b/Documents/Arduino/x-clock/x-clock.ino: In function ‚void set_clock()‘:
    x-clock:294:34: error: invalid conversion from ‚const char*‘ to ‚long int‘ [-fpermissive]
    configTime(MY_TZ, MY_NTP_SERVER); // –> Here is the IMPORTANT ONE LINER needed in your sketch!
    ^
    x-clock:294:34: error: invalid conversion from ‚const char*‘ to ‚int‘ [-fpermissive]
    x-clock:294:34: error: too few arguments to function ‚void configTime(long int, int, const char*, const char*, const char*)‘
    In file included from /Users/b/Documents/Arduino/x-clock/x-clock.ino:14:0:
    /Users/b/Library/Arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/Arduino.h:297:17: note: declared here
    extern „C“ void configTime(long timezone, int daylightOffset_sec,
    ^
    exit status 1
    invalid conversion from ‚const char*‘ to ‚long int‘ [-fpermissive]

    Dieser Bericht wäre detaillierter, wenn die Option
    „Ausführliche Ausgabe während der Kompilierung“
    in Datei -> Voreinstellungen aktiviert wäre.

  24. Hallo Pixelking,
    ich bin kompletter Neuling in Sachen wie ESP’s und Löten und habe mir alle benötigten Komponenten besorgt, um dieses coole Projekt umzusetzen. Dazu hätte ich 2 Fragen:
    1. Wie schließe ich den Strom am besten an? Braucht mein Wemos D1 mini pro über den Micro-USB Anschluss Strom und der IKEA Obergränsad zusätzlich mit dem bereits vorhandenen USB Kabel Strom? Oder reicht es aus, wenn ich nur den Obergränsad anschließe oder nur den Wemos?
    2. Wenn ich durch meine Unfähigkeit beim Löten die oberen Anschlüsse „VCC, CLA, CLK“ usw. kaputt gemacht habe, die Anschlüsse des untersten Panel nehmen kann oder funktioniert dies nicht? Müsste dafür der Code umgeschrieben werden?

    Da bin ich leider überfragt und würde mich sehr über eine Antwort freuen!

    Liebe Grüße,
    Boxi

    1. Hallo Boxi , schön das Du Dich an das Projekt rangetraut hast.
      Ganz ohne Lötkenntnisse kann man natürlich auch etwas kaputt machen.
      Gern beantworte ich Deine Fragen:

      1. Es ist kein zusätzlicher Strom notwendig. Du verbindest ja die Anschlüsse VCC/GND vom Panel mit dem Wemos. Dann benutzt Du das original USB Kabel mit einem leistungsfähigen Ladegerät.
      2. Die Anschlüsse werden von Panel zu Panel weitergereicht. Einige sind überall identisch, andere reichen die Information weiter – ähnlich Stille Post – da ist dann die Richtung wichtig.
      Bei den Anschlüssen VCC und CLK sowie CLA hast Du Glück..!! und kannst Sie von unten nehmen, Allerdings bei D-IN nicht !

      Viel Glück und vorsichtig löten !
      Liebe Grüsse

      1. Hallo,
        danke für deine Rückmeldung! Ich habe es geschafft und bin sehr zufrieden damit, danke!
        Eine Frage hätte ich dennoch: Mit welcher „Technik“ werden auf der X-Clock Website die einzelnen Einstellungen gesendet? http get/post? Wäre es in Zukunft denkbar dazu eine API-Schnittstelle zu entwickeln?

        Ein Foto habe ich auch geschickt..

        Liebe Grüße, Boxi!

    1. Hi Eric,
      Das ist noch ganz neu, aber ich habe die Anleitung im Blog jetzt mit verlinkt.
      Die Version 17 ist die neueste Anleitung. Noch ist der upload und konvertier Vorgang nicht sehr „geschmeidig“, aber es funktioniert.
      Viel Spass beim ausprobieren.

  25. Vielleicht hilft das auch anderen: Ich hatte eine Menge Probleme mit flackernden Pixeln, mit unterschiedlichsten Stromversorgungen. Die Lösung war dann schließlich, die U1 CPU komplett zu entfernen. Es scheint nicht immer auszureichen, bei der U1 CPU nur den POWER-Pin 1 abzulöten.

  26. Vielen Dank für dieses schöne Projekt. Ich habe es nachgebaut und bin sehr zufrieden! Auch die vielfältigen Konfigurationsmöglichkeiten sind sehr gut. Ich hätte ein kleines Feature-Request. Wenn die Uhr doch so schön Wochentag und Datum anzeigen kann, warum kann man das nicht so einstellen, dass es nach x Sekunden wechselt? Also 10 Sek. Uhrzeit, dann 5 Sek. Datum und Wochentag oder so. Das wäre doch noch eine schöne Erweiterung.

    Danke und viele Grüße!

  27. danke für das Projekt. Ich habe folgendes Problem: Firmware per Web 0.1.18 installiert.
    Uhr Startet, AP per Weboberfläche eingegeben, Uhr verbindet sich mit dem Netzwerk.
    Uhr holt sich dann aber keine Zeit aus den Netz. Drücken von „get net Time“ holt sie sich die richtige Zeit.
    habe schon einige Netzteil probiert…

    lg Uwe

  28. Moin,
    danke für das schöne Projekt. Ich habe es mit LDR gebaut.
    Leider habe ich das Problem, dass einem Teil der LEDs die Helligkeit immer konstant ist. Dieses ist bei auch bei deaktiviertem LDR so d.h. macht kein Unterschied.
    Hier ein Bild wie es aussieht:
    https://postimg.cc/QV1YVpJL

    Hast du eine Idee woran es liegen könnte?
    Viele Grüße aus dem Norden
    Sven

    1. Hallo Sven,
      Hast Du den U1 Chip ausgelötet oder nur das Power Beinchen angehoben ?
      Es ist wohl besser den Chip ganz auszulöten.. Den Vorschlag nur den Power Pin zu abzulöten habe ich bereits gelöscht – Leider kam es manchmal zu Problemen ..
      Grüsse

        1. Hi Sven, der Fehler trat bisher nur in dem Zusammenhang auf, das der alte Chip noch drin war.
          Kannst Du mal das einfacheste Programm mit fester Helligkeit drauf flashen. Dann weitersehen.

          Die Helligkeit wird ja „pseudo“ analog eingestellt. d.h. der EN (Enable) Ausgang wird dauernd an/aus geschaltet vom Arduino-Code „analog out“.
          Wenn da Störungen, Netzteil-Brummen, drauf ist, könnte das sowas auch auslösen.
          Hast Du einen Elko eingebaut ? Anderes Netzteil probiert ?

          Grüsse

          1. Hi,

            Elko ist eingebaut.
            Ich probiere, wie vorgeschlagen, die minimale Version aus und schaue was passiert. Danke für die schnellen Rückmeldungen.

            VG Sven

          2. Hi,

            kurze Rückmeldung. Ich habe die minimale Version ausprobiert und habe den gleichen Effekt.
            Ein anderes Netzteil habe ich auch ausprobiert, keine Abhilfe.
            Ich habe auch EN mal komplett getrennt, dann sind alle LEDs dunkel, aber die betreffenden 12 LEDs bleiben an. Ein- und Ausschalten entsprechend der Uhrzeit funktioniert aber d.h. es werden nur die LEDs eingeschaltet, die für die Zahl benötigt werden.
            Eigenartig, warum dieses 12 LEDs die Helligkeitsinformation nicht annehmen, sondern scheinbar nur an/aus verstehen.

            VG Sven

          3. Hallo Sven,
            Tut mir Leid, aber da habe ich keine Idee. Ich vermute mal es gibt einen Kurzschluss an den LEDS oder ein Problem mit dem Analog Out am ESP.

            Vielleicht kannst Du einen anderen ESP verwenden. Die Steuerung der Helligkeit geschieht allein über das PWM Signal am EN Eingang der LEDS- Die PWM ist unter Kontrolle des Arduino Codes und hat nichts mit dem Sketch zu tun. Das zeigt ja auch das Experiment das Du einen anderen Code verwendet hast und auch schon das Netzteil getauscht hast.
            Eine Möglichkeit wäre den einen einfache Sketch zu verwenden, und einen anderen Pin für das EN Signal zu nutzen. Vieleicht ist der ja defekt…

            Grüsse und hoffentlich klappt es

  29. Vielen Dank, dass Du uns diese Uhr zur Verfügung gestellt hast. Ich bin begeistert. Es hat alles auf Anhieb geklappt.
    Ich hjabe eine Frage, wird es in Zukunft eine Version geben, bei der sich Uhrzeit- und Datumsanzeige abwechseln?
    Das wäre toll.
    Nochmal vielen Dank
    Claus

      1. Es scheint ja die Version 1.09 zu geben. (minor erros detected).
        Nach dem Versuch die Firmware upzudaten, startet die Uhr neu.
        Beim Start zeigt sie UP NO – hat aber trotzdem noch die alte Version 1.08.
        Was mache ich falsch?
        Claus

  30. Hallo Pixelkönig,
    cooles Projekt. Ich habe mir die Lampe gebraucht gekauft, beim Test funktionierten alle Pixel.
    Dann habe ich den U1-Chip entfernt und den ESP eingebaut. Verbindung über das Web-Interface bekomme ich. Es wird auch die richtige Zeit ermittelt, aber leider absolut nichts angezeigt.
    Ich habe schon alle meine Netzteile ausprobiert. Reichen 2.5 Ampere nicht aus?
    Gibt es irgendwelche Messpunkte? Ich bin gerade ziemlich ratlos.

    VG
    Thorsten

    1. Hallo Thorsten,
      Schön das Du das Projekt ausprobiert hast. Checke erstmal ob alle 4 pins d5,d6,d7,d8 in der korrekten Reihenfolge angeschlossen und nicht untereinander kurzgeschlossen sind. Sie sind in derselben Reihenfolge an der Platine angelötet.
      Dann bitte prüfen ob beim auslöten des Chips keine Kurzschlüsse an den kleinen Kontakten übrig geblieben sind!
      Vielleicht sendest Du dazu da ein oder andere Photo an Pixelkoenig@web.de.
      Dann schaue ich mal da drauf.

      Viele Grüsse

      1. Hallo,
        ich habe jetzt einen neuen ESP verwendet und einen Kurzschluss am IC auf dem 3. Panel durch überflüssiges Lötzinn entfernt und nun funktioniert alles, wie gewünscht 🙂

        Vielen Dank trotzdem für die schnelle Rückmeldung.

        Viele Grüße
        Thorsten

  31. Hallo Thorsten,
    danke für deine Arbeit an dieser tollen Uhr/Multifunktionsdisplay.

    Bei mir hat alles super funktioniert und ich habe zugleich noch viel über die Ansteuerung so eines Displays gelernt.

    Hab gerade manuell auf 0.1.19 aktualisiert.
    Das Autoupdate beim Start hat bei mir leider nicht funktioniert.

    Grüße Flo

  32. Habe erfolgreich das Projekt nach gebaut. Bin sehr begeistert.

    1) Besteht die Möglichkeit, das MQTT noch um Login erweiter wird?
    ohne Login kann ich es nicht nutzen.
    2) Per MQTT eigene Meldungen oder Animation einspielen?
    3) eine Temp-Sensor z.B. 1Wire zu integrieren?

    Bin leider nicht so der Programmiere

  33. Hallo in die Runde hier, mein Obegränsad hat mitten im laufenden Betrieb den Geist aufgegeben. Alle Pixel gingen aus und bleiben dunkel. Der Wemos Mini Pro funktioniert einwandfrei. Der Austausch gegen einen anderen Wemos Mini Pro brachte keinen Unterschied. Wenn ich den Wemos oder den Obegränsad mit dem Strom verbinde, leuchten ein paar Pixel sehr kurz auf. Das wars dann aber schon wieder. Kennt das jemand? Kann ich den Obegränsad noch retten?

  34. Servus,
    wie viel Strom verbraucht denn die Lampe ungefähr, wenn die Uhr angezeigt wird auf voller Helligkeit?
    Habt ihr da Erfahrung?
    Gruß
    Vitus

  35. Hallo,

    vielen Dank für das Projekt, das wird nun die neue Familien-Uhr. Damit man gleich erkennt, dass hier ein Informatiker wohnt.

    Ein Hinweis noch: Beir mir gab es nur wirren Pixelmüll, in dem ab und zu mal Fragmente der Uhrzeit lesbar waren. Das hat sich erst geändert mit dem 1000 uF Kondensator zwischen GND und VCC. Der ist in der Make aber gar nicht erwähnt. Wäre also vielleicht gut, wenn man das Github-Projekt mit einem Hinweis darauf versieht.

    Weiterer Hinweis: Es funktioniert auch mit dem D1 mini 3.0 statt dem pro.

    Und noch eine Frage: Wie kann man die Helligkeit der einzelnen Pixel steuern? Im Werkszustand gab es eine Animation, wo die Pixel innerhalb eines Frames unterschiedliche Helligkeiten hatten.

    Beste Grüße, Michael

    1. Hallo Michael,
      Schön das Dir das Projekt Spass gemacht hat. Richtig, es funktioniert auch mit dem Mini, insbesondere wenn man die einfachen Sketche probiert , der Pro hat mehr Speicher wenn man die Web version verwendet und — ganz wichtig: – man kann Ihn besser ankleben, da die Rückseite flach ist.
      der Kondensator ist in der X-Clock erwähnt und war bei dieser bisher nie nötig. Aber das ist ja bei den Bastelprojekten immer so, das man keine Herstellerinfo hat und probieren muss… Die Helligkeit kann man nur per PWM regeln. Dazu muss man mit einigen KHz die Pixelmaps ausgeben und modulieren. Das habe ich mir gespart um das Projekt verständlich zu halten. Du kannst es einbauen indem Du mehrere Bitmaps speicherst, und diese innerhalb von Interrupts ausgibst. Hab ich mal probiert aber der Effekt war nur begrenzt interessant…Es ist quasi „künstlerisch“ kontraproduktiv zum Pixel look. Auch „bessere“ Buchstaben sind optisch kein „Vorteil“. Der Reiz der Schachtel liegt im Pixel Look… Viel Spass beim Programmieren !

      1. Danke für die Antwort! Noch eine Frage: Ist es normal, dass in dem Sketch der Unterschied zwischen maximaler und minimaler Helligkeit gering ist? Also im Sinne von: Man sieht es schon ein bisschen, aber minimal ist so etwa 80% von maximal?

        Gruß, Michael

        1. Für alle Mitleser und Selbstprobierer: Beim D1 mini sind die PWM-Ausgangspins 10-bittig. Das heißt, dass man Werte zwischen 0 und 1023 für die Helligkeit verwenden kann, nicht nur zwischen 0 und 255. Mit höheren Werten wird es dunkler. Das bezieht sich auf diese Zeile:

          analogWrite(P_EN, brightness);

  36. Hallo,
    Danke für das schöne Projekt! Ich habe nach dem FREKVENS Würfel noch eine andere Variante ausprobiert: 4 in Reihe geschaltete 8×8 RGB Matrizes, in Anordnung 16×16. Diese Teile sind gut und preiswert erhältlich. Der genial programmierte Empfangs- und Auswerteteil wird unverändert übernommen und mit Hilfe von Adafruit_GFX.h, Adafruit_Neomatrix.h und Adafruit_Neopixel.h geschieht mit wenigen Zeilen die Ausgabe der Uhrzeit. Zur Übernahme der schön geschnittenen Ziffern des Projektes muß man in der GFX Library das File glcdfont.c anpassen. Die Ziffern geraten dabei 1 Byte schmaler, sind aber noch angenehm zu lesen. Wer es mag, kann jetzt ein zusätzliches Spielfeld zur farblichen Darstellung eröffnen. Ich probiere derzeit für jede Ziffer die zufällige Wahl zwischen weiß, rot und grün bei jedem Anzeigewechsel.

    Grüsse
    Folker_F

  37. Hey, danke für das tolle Projekt!
    Funktioniert der Web Uploader noch? Bei mir bleibt er bei „Preparing installation“ Stundenlang hängen, ESP wird sehr warm und sonst passiert nichts. ESPHome Installation über Web klappt ganz gut. D.h. an sich geht mein ESP (Ich habe mir extra die Pro Version mit 16MB gekauft)
    Meinen D1 Mini will der WEB Installer mit „Klick mal BOOT Taste“ auch nicht.
    Wäre evtl. möglich die bin Dateien zum Download anzubieten? Dann kann man die über ESPFlasher einspielen. Wobei Sketch an sich wäre mir am liebsten… aber gut, Argumente verstehe ich schon…

  38. Hallo
    als erstes einmal: Super cooles Projekt!
    gleich meine erste Frage: gibt es die V 1.25 auch für die x-clock? Das Online Update geht nur bis 1.22.

    Eine Idee für MQTT hätte ich auch noch: in der Mitte könnten die beiden unbenutzen Pixelzeilen als zwei Bargraphs 0-100% genutzt werden.
    somit könnte man zeitgleich mit der Uhrzeit Infos einblenden…..

    thx
    Werner

    1. Hallo Werner,
      ja, wird es geben.

      die Änderungen sind nicht gravierend:
      Es betrifft im wesentlichen kleine Änderungen am Zeichensatz oder MqTT und wird sicher bald nachezogen.

      Ich haben mal mit den mittleren Punkten gespielt, im Rahmen der ersten Tests. Das fand ich persönlich nicht vorteilhaft.

      Wenn Ihr da spezielle Umsetzungen im Bereich MqTT machen möchtet, würde ich empfehlen einfach das Mqtt Example zu verwenden und zu experimentieren. Mit dem WifiManager und der Uhrzeit ist es doch ein prima Startpunkt für eigene Ideen. Ich werde wohl nicht alle Vorschläge einbauen, denn dann wird das Projekt zu gross.. Im wesentlichen soll es ja eine Uhr sein…

      Liebe Grüsse

  39. Hallo,

    erstmal vielen Dank für die tollen Projekte X und Y-Clock. Bin über die Make drauf aufmerksam
    geworden und baue nun beide nach.

    Ich hab mir nun das .bin-File der 0.1.22 besorgt und geflasht (via Spacehuhn).

    Funktioniert auch seitens des OBEGRÄNSAD.

    Nur wenn ich über die IP das Web-Interface aufrufen will, wird die Verbindung sofort abgebrochen.
    Ich habe nun auf Verdacht mal einen anderen Browser probiert (Edge), da es ähnliche Probleme auch
    mit dem flashen gibt, und siehe da – ich konnte es aufrufen – aber nur einmal. Ein erneuter Versuch
    scheiterte – bei Firefox bricht die Verbindung sofort ab, ich sehe das Interface noch kurz…
    Weist Du, woran das liegt?

    Grüße,

  40. Hallo,
    finde die Implementierung vom MQTT echt super, und hätte noch ein kleinen Vorschlag.
    Wäre es möglich einen Präfix und Suffix für die MQTT Anzeige zu Implementieren, sowie eine Fixe Zeit, zudem die MQTT Informationen abgerufen werden.

    Leider habe ich vom programmieren keine Ahnung, finde das Projekt aber Super !!!

    Grüße Xaver

    1. Hallo Xaver, danke das Die das Peojekt gefällt. Aktuell werden die Daten angezeigt wenn Sie als geändert beim MQTT broker liegen.
      Der Punkt MQTT wird jetzt sehr umfangreich und die Wünsche sehr unterschiedlich. Das Display ist ja auch klein – im Sinne der Auflösung. Das macht Erweiterungen schwierig. Ich versuche es.. Grüsse

  41. Vielen Dank für die Mühen, Arbeit und das zur Verfügung stellen.
    Würde behaupten, dass ich in allen Disziplinen die bei diesem Projekt nötig sind, eher ein Laie bin.
    Im ersten Lötanlauf wahrscheinlich zu dünne Kabel genommen und es funktionierte leider nicht. Im zweiten Anlauf (mit etwas dickeren Kabeln) hat alles wunderbar geklappt.

    Hier das Ergebnis:
    https://postimg.cc/k290Bn6c

  42. Hallo,
    hätte da noch eine Frage, was mir aufgefallen ist, dass die Uhr innerhalb von wenigen Tagen relative falsch geht.
    Wird die Uhr in gewissen abständen wieder neu aus dem Internet gestellt?
    Derzeit behelfe ich mit regelmäßigen re-starts.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Nach oben scrollen