Help ILI9163 modified clock

Hello, i want to make buttons to alter hours and minutes(set). I used debounce, but i click and i still get not by one hour, but random..

Rele means relay(to create ticking)
VAlanda = hour
Minute = minute
For my easier finding i made in my language(lithuanian)

So can you help me with the hour setting? :slight_smile: Thanks.

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <TFT_ILI9163C.h>

// Color definitions
#define	BLACK   0x0000
#define	BLUE    0x001F
#define	RED     0xF800
#define	GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0  
#define WHITE   0xFFFF

#define __CS 10
#define __DC 9
#define __RST 12
/*
Teensy 3.x can use: 2,6,9,10,15,20,21,22,23
Arduino's 8 bit: any
DUE: check arduino site
If you do not use reset, tie it to +3V3
*/
int valandos = 8;
int minutes = 7;
int rele = 6;
int minuteState = 0;
int valandaState = 0;

int lastButtonState = LOW;
int lastButtonState2 = LOW;

long debounceDelay = 1000;
long lastDebounceTime = 0;
long debounceDelay2 = 1000;
long lastDebounceTime2 = 0;





TFT_ILI9163C tft = TFT_ILI9163C(__CS, __DC, __RST);

uint16_t ccenterx,ccentery;//center x,y of the clock
const uint16_t cradius = 63;//radius of the clock
const float scosConst = 0.0174532925;
float sx = 0, sy = 1, mx = 1, my = 0, hx = -1, hy = 0;
float sdeg=0, mdeg=0, hdeg=0;
uint16_t osx,osy,omx,omy,ohx,ohy;
uint16_t x0 = 0, x1 = 0, yy0 = 0, yy1 = 0;
uint32_t targetTime = 0;// for next 1 second timeout
uint8_t hh,mm,ss;  //containers for current time


void drawClockFace(){
//  tft.fillCircle(ccenterx, ccentery, cradius, YELLOW);
 // tft.fillCircle(ccenterx, ccentery, cradius-4, BLACK);
  // Draw 12 lines
  for(int i = 0; i<360; i+= 30) {
    sx = cos((i-90)*scosConst);
    sy = sin((i-90)*scosConst);
    x0 = sx*(cradius-4)+ccenterx;
    yy0 = sy*(cradius-4)+ccentery;
    x1 = sx*(cradius-11)+ccenterx;
    yy1 = sy*(cradius-11)+ccentery;
    tft.drawLine(x0, yy0, x1, yy1, YELLOW);
  }
}

static uint8_t conv2d(const char* p) {
  uint8_t v = 0;
  if ('0' <= *p && *p <= '9') v = *p - '0';
  return 10 * v + *++p - '0';
}

void setup(void) {
  tft.begin();

  tft.setTextColor(WHITE, BLACK);
  ccenterx = tft.width()/2;
  ccentery = tft.height()/2;
  osx = ccenterx;
  osy = ccentery;
  omx = ccenterx;
  omy = ccentery;
  ohx = ccenterx;
  ohy = ccentery;
  drawClockFace();// Draw clock face
  //get current time from compiler
  hh = conv2d(__TIME__);
  mm = conv2d(__TIME__+3);
  ss = conv2d(__TIME__+6);
  pinMode(rele, OUTPUT); 
  pinMode(valandos, INPUT_PULLUP); 
  pinMode(minutes, INPUT_PULLUP); 
  targetTime = millis() + 1000; 
}

void drawClockHands(uint8_t h,uint8_t m,uint8_t s){
  // Pre-compute hand degrees, x & y coords for a fast screen update
  sdeg = s * 6;                  // 0-59 -> 0-354
  mdeg = m * 6 + sdeg * 0.01666667;  // 0-59 -> 0-360 - includes seconds
  hdeg = h * 30 + mdeg * 0.0833333;  // 0-11 -> 0-360 - includes minutes and seconds
  hx = cos((hdeg-90)*scosConst);    
  hy = sin((hdeg-90)*scosConst);
  mx = cos((mdeg-90)*scosConst);    
  my = sin((mdeg-90)*scosConst);
  sx = cos((sdeg-90)*scosConst);    
  sy = sin((sdeg-90)*scosConst);

  // Erase just old hand positions
  tft.drawLine(ohx, ohy, ccenterx+1, ccentery+1, BLACK);  
  tft.drawLine(omx, omy, ccenterx+1, ccentery+1, BLACK);  
  tft.drawLine(osx, osy, ccenterx+1, ccentery+1, BLACK);
  // Draw new hand positions  
  tft.drawLine(hx*(cradius-28)+ccenterx+1, hy*(cradius-28)+ccentery+1, ccenterx+1, ccentery+1, YELLOW);
  tft.drawLine(mx*(cradius-17)+ccenterx+1, my*(cradius-17)+ccentery+1, ccenterx+1, ccentery+1, YELLOW);
  tft.drawLine(sx*(cradius-14)+ccenterx+1, sy*(cradius-14)+ccentery+1, ccenterx+1, ccentery+1, YELLOW);
  tft.fillCircle(ccenterx+1, ccentery+1, 3, YELLOW);

  // Update old x&y coords
  osx = sx*(cradius-14)+ccenterx+1;
  osy = sy*(cradius-14)+ccentery+1;
  omx = mx*(cradius-17)+ccenterx+1;
  omy = my*(cradius-17)+ccentery+1;
  ohx = hx*(cradius-28)+ccenterx+1;
  ohy = hy*(cradius-28)+ccentery+1;
}


void loop() {
  valandaState = digitalRead(valandos);
  minuteState = digitalRead(minutes);

  
  // read the state of the switch into a local variable:
  int reading = digitalRead(minutes);
  int reading2 = digitalRead(valandos);

  // check to see if you just pressed the button 
  // (i.e. the input went from LOW to HIGH),  and you've waited 
  // long enough since the last press to ignore any noise:  

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  } 
  if (reading2 != lastButtonState2) {
    // reset the debouncing timer
    lastDebounceTime2 = millis();
  } 

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer
    // than the debounce delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != valandaState) {
      valandaState = reading;

      // only toggle the LED if the new button state is HIGH
      if (valandaState == LOW) {
        hh++;
      }
    }
  }
  
    if ((millis() - lastDebounceTime2) > debounceDelay2) {
    // whatever the reading is at, it's been there for longer
    // than the debounce delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading2 != minuteState) {
      minuteState = reading2;

      // only toggle the LED if the new button state is HIGH
      if (minuteState == LOW) {
        mm++;
      }
    }
  }
  lastButtonState2 = reading2;
  lastButtonState = reading;




  if (targetTime < millis()) {
    targetTime = millis()+1000;
    ss++;
    rele = !rele;
    if (ss == 60) {
      ss = 0;
      mm++;
      if(mm > 59) {
        mm = 0;
        hh++;
        if (hh > 23) hh = 0;
      }
    }
    drawClockHands(hh,mm,ss);

  }

}

Your clock sketch is some fun.

I tried it, and sure enough the "button debouncing" is diabolical.

I am taking my dog out for a walk. I will try some "conventional" button handling when I come back.

David.

Ok, I used a different style. i.e. a count rather than a specific # of milliseconds.

#define DEBOUNCE   1000
int debounceCount;    //a good press needs to be stable for DEBOUNCE counts.
int debounceCount2;
    ...
    // read the state of the switch into a local variable:
    int reading = digitalRead(minutes);
    int reading2 = digitalRead(valandos);

    if (reading2 == lastButtonState2) {
        if (reading2 == LOW && debounceCount2 < DEBOUNCE) debounceCount2++;
    } else {
        if (reading2 == HIGH && debounceCount2 >= DEBOUNCE)
            if (++hh > 23) hh = 0;
        debounceCount2 = 0;
    }
    if (reading == lastButtonState) {
        if (reading == LOW && debounceCount < DEBOUNCE) debounceCount++;
    } else {
        if (reading == HIGH && debounceCount >= DEBOUNCE)
            if (++mm > 59) mm = 0;
        debounceCount = 0;
    }
    lastButtonState2 = reading2;
    lastButtonState = reading;

This simple code just "counts" the loops instead of using millis().

Normally, you would use a CTC timer for a clock. On the x'th tick, you read pins. On the y'th tick you update time and display it.

I like the way that your sketch uses the COMPILE-TIMESTAMP to start you off with the correct time on the clock.

David.

Thank you very much! :slight_smile: