Showing posts with label clock. Show all posts
Showing posts with label clock. Show all posts

Saturday, 2 December 2023

ESP32-2432S024R "nixie" clock with micropython

Working on a (simulated) nixie tube clock on a "Cheap Yellow Display" in micropython. I used the nixie images from macsbug's M5Stack clock ( https://macsbug.wordpress.com/2019/06/16/m5stack-nixie-tube-clock/ ). Converted with the img2rgb565.py utility from rdagger's ILI9341 library  (https://github.com/rdagger/micropython-ili9341). The library had a RST pin input that the CYD did not need, so I just commented that out, is this the "right" way to fix it ? who knows ? it works. Update: added a "beats" internet time and date display in little round "nixie" tubes... 



The board has lots of built in stuff - SD card, battery charge circuit, 2W audio amp, an LDR and a RGB led

 

"""ILI9341 nixie clock"""
#from time import sleep
from ili9341 import Display, color565
from machine import Pin, SPI, Timer
from xglcd_font import XglcdFont
from beats import Beats

OldNews= XglcdFont('fonts/OldNewspaperTypes24x26.c',24,26)

spi = SPI(1, baudrate=2000000, sck=Pin(14), mosi=Pin(13))

display = Display(spi, dc=Pin(2), cs=Pin(15),width=320, height=240, rotation=270)
display.display_on()

from machine import RTC
rtc=RTC()


def nixieclock():
    """clock display"""
    days=('Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday')
    display.draw_text8x8(0, 0, 'Time is an illusion...', color565(30, 33, 0))
    display.draw_text(25, 145,(days[rtc.datetime()[3]]) ,OldNews,color565(255, 165, 0))
    x=0
    
    if (rtc.datetime()[4] < 10 ) :
        fn='/images/raw/nix10.raw'
        display.draw_image(fn, x, 10, 70, 134)
        x=x+69
        fn='/images/raw/nix'+str(rtc.datetime()[4])+'.raw'     
        display.draw_image(fn, x, 10, 70, 134)
    else:    
        fn='/images/raw/nix'+str(rtc.datetime()[4])[0]+'.raw'
        display.draw_image(fn, x, 10, 70, 134)
        x=x+69
        fn='/images/raw/nix'+str(rtc.datetime()[4])[1]+'.raw'
        display.draw_image(fn, x, 10, 70, 134)
        
    x=x+71
    display.draw_image('/images/raw/nixc.raw', x, 10, 40, 134)
    x=x+40
    
    if (rtc.datetime()[5] < 10 ) :
        fn='/images/raw/nix0.raw'
        display.draw_image(fn, x, 10, 70, 134)
        x=x+69
        fn='/images/raw/nix'+str(str(rtc.datetime()[5]))+'.raw'
        display.draw_image(fn, x, 10, 70, 134)
    else: 
        fn='/images/raw/nix'+str(rtc.datetime()[5])[0]+'.raw'
        display.draw_image(fn, x, 10, 70, 134)
        x=x+69
        fn='/images/raw/nix'+str(str(rtc.datetime()[5])[1])+'.raw'
        display.draw_image(fn, x, 10, 70, 134)

def ndate() :    
    (year,month,day,h,m,s,dow,doy)=rtc.datetime()
    fn='/50px/'+str("%02d"%day)[0] +'_50px.raw'
    x=5
    display.draw_image(fn,1, 190, 50, 48)
    fn='/50px/'+str("%02d"%day)[1] +'_50px.raw'
    x=x+48
    display.draw_image(fn, x, 190, 50, 48)
    x=x+60
 
    fn='/50px/'+str("%02d"%month)[0] +'_50px.raw'   
    display.draw_image(fn,x, 190, 50, 48)
    x=x+48
    fn='/50px/'+str("%02d"%month)[1] +'_50px.raw'
    display.draw_image(fn, x, 190, 50, 48)
    x=x+60 
    fn='/50px/'+str(year)[2] +'_50px.raw'   
    display.draw_image(fn,x, 190, 50, 48)
    x=x+48
    fn='/50px/'+str(year)[3] +'_50px.raw'
    display.draw_image(fn, x, 190, 50, 48)

def nixbeats():
    x=150;y=140
    fn='/50px/'+Beats()[1] +'_50px.raw'
    display.draw_image(fn,x, y, 50, 48)

    x+=48
    if (Beats()[2] != '.'):
        fn='/50px/'+Beats()[2] +'_50px.raw'
        display.draw_image(fn, x, y, 50, 48)

    x+=48
    if (Beats()[3] != '.'):
        fn='/50px/'+Beats()[3] +'_50px.raw'   
        display.draw_image(fn,x, y, 50, 48)
    


nixieclock()
ndate()
tim0 = Timer(0)
tim0.init(period=30000, mode=Timer.PERIODIC, callback=lambda t:nixieclock())

nixbeats()
tim1 = Timer(1)
#attempt to sychronise with beat change
while (Beats()[-2:] != "01" ):
    pass     
tim1.init(period=86400, mode=Timer.PERIODIC, callback=lambda t:nixbeats())
nixbeats()

Thursday, 26 May 2011

Arduino analog Clock

Continuing the clock theme, this one uses the marvelous TVOut library to do (admittedly grainy) analog clock .

//start "sketch"
#include <TVout.h>
#include "Wire.h"
//#include <pollserial.h>
#include <fontALL.h>

TVout TV;
//pollserial pserial;

#define DS1307_I2C_ADDRESS 0x68 // This is the I2C address
// Global Variables
long previousMillis = 0; // will store last time time was updated
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
long interval = 200;
int tvx,tvy,tvradius,x2,y2,x3,y3;

// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
return ( (val/10*16) + (val%10) );
}

// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
return ( (val/16*10) + (val%16) );
}

// Gets the date and time from the ds1307 and prints result
void getDateDs1307()
{
// Reset the register pointer
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0x00);
Wire.endTransmission();

Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

// A few of these need masks because certain bits are control bits
second = bcdToDec(Wire.receive() & 0x7f);
minute = bcdToDec(Wire.receive());
hour = bcdToDec(Wire.receive() & 0x3f); // Need to change this if 12 hour am/pm
dayOfWeek = bcdToDec(Wire.receive());
dayOfMonth = bcdToDec(Wire.receive());
month = bcdToDec(Wire.receive());
year = bcdToDec(Wire.receive());

}


void printTime()
{
TV.set_cursor(0,0);
TV.print( char( hour/10 + 0x30) );
TV.print( char( hour%10 + 0x30) );
TV.print(":");
TV.print( char(minute/10 + 0x30));
TV.print( char(minute%10 + 0x30));
TV.print(":");
TV.print(char (second/10+0x30));
TV.print(char (second%10+0x30));


TV.set_cursor(8,9);
TV.print(char(dayOfMonth/10+0x30));
TV.print(char(dayOfMonth%10+0x30));
TV.print("/");
TV.print(char(month/10+0x30));
TV.print(char(month%10+0x30));
TV.set_cursor(10,18);
TV.print("20");
TV.print(char(year/10+0x30));
TV.print(char(year%10+0x30));

TV.draw_circle(tvx,tvy,tvradius-5,BLACK,BLACK);

float angle = second*6 ;
angle=(angle/57.29577951) ; //Convert degrees to radians
x3=(tvx+(sin(angle)*(tvradius-6)));
y3=(tvy-(cos(angle)*(tvradius-6)));
TV.draw_line(tvx,tvy,x3,y3,WHITE);
angle = minute * 6 ;
angle=(angle/57.29577951) ; //Convert degrees to radians
x3=(tvx+(sin(angle)*(tvradius-11)));
y3=(tvy-(cos(angle)*(tvradius-11)));
TV.draw_line(tvx,tvy,x3,y3,WHITE);
angle = hour * 30 + int((minute / 12) * 6 ) ;
angle=(angle/57.29577951) ; //Convert degrees to radians
x3=(tvx+(sin(angle)*(tvradius-15)));
y3=(tvy-(cos(angle)*(tvradius-15)));
TV.draw_line(tvx,tvy,x3,y3,WHITE);
}


void setup() {
Wire.begin();
getDateDs1307() ;
//TV.begin(_NTSC,184,72);
//the circle didn't look very round with 184,72
TV.begin(_NTSC,150,71);
TV.select_font(font6x8);
TV.clear_screen();
//TV.println("TV Clock");
tvx= TV.hres()/2;
tvy=TV.vres()/2;
tvradius=TV.vres()/2 ;
//clock face
TV.draw_circle(tvx,tvy,tvradius,WHITE);
//hour ticks
for( int z=0; z < 360;z= z + 30 ){
//Begin at 0° and stop at 360°
float angle = z ;
angle=(angle/57.29577951) ; //Convert degrees to radians
x2=(tvx+(sin(angle)*tvradius));
y2=(tvy-(cos(angle)*tvradius));
x3=(tvx+(sin(angle)*(tvradius-5)));
y3=(tvy-(cos(angle)*(tvradius-5)));

TV.draw_line(x2,y2,x3,y3,WHITE);
}
//TV.set_hbi_hook(pserial.begin(57600));
}

void loop() {
// if (pserial.available()) {
// TV.print((char)pserial.read());
// }

// other processing here maybe

unsigned long currentMillis = millis();

if(currentMillis - previousMillis > interval) {
// save the last time you printed and updated

previousMillis = currentMillis;
TV.delay(1);
printTime();
//read RTC
getDateDs1307() ;
}


}

//end sketch
Once again just a clock, blocky but readable :

Arduino LCD Clock

Using the Wire library to read a DS1307 RTC chip (I used this one from Seeed Studio and bits of the example code ) and the LCD3wire library to implement, what is almost the "hello world" of arduino projects, a digital clock. The LCD3wire example uses a 4094 shift register, my parts box only had a 74HC595 so the connections are a little different:





















74HC595LCDArduinopower
14

25

36

414

513

612

711

8

gnd
9


10

+ve
11
4 (clk)
12
2 (strobe)
13

gnd
14
8 (data)
15


16

+ve

1
gnd

2
+ve

3
2.2K to gnd

//the "sketch"
// Example use of LCD3Wire and Wire library
// to read time from RTC and display on LCD

#include <LCD3Wire.h>
#include "Wire.h"
// Arduino pins
#define LCD_LINES 2 // number of lines in your display
#define DOUT_PIN 8 // Dout pin
#define CLK_PIN 4 // Clock pin
#define STR_PIN 2 // Strobe pin

#define DS1307_I2C_ADDRESS 0x68

long previousMillis = 0; // will store last time time was updated
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
long interval = 200;

//create object to control an LCD.
LCD3Wire lcd = LCD3Wire(LCD_LINES, DOUT_PIN, STR_PIN, CLK_PIN);
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
return ( (val/10*16) + (val%10) );
}

// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
return ( (val/16*10) + (val%16) );
}

// Gets the date and time from the ds1307 and prints result
void getDateDs1307()
{
// Reset the register pointer
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0x00);
Wire.endTransmission();

Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

// A few of these need masks because certain bits are control bits
second = bcdToDec(Wire.receive() & 0x7f);
minute = bcdToDec(Wire.receive());
hour = bcdToDec(Wire.receive() & 0x3f); // Need to change this if 12 hour am/pm
dayOfWeek = bcdToDec(Wire.receive());
dayOfMonth = bcdToDec(Wire.receive());
month = bcdToDec(Wire.receive());
year = bcdToDec(Wire.receive());

}

void printTime()
{
lcd.cursorTo(1, 4); //line=1, x=4.
lcd.print( char( hour/10 + 0x30) );
lcd.print( char( hour%10 + 0x30) );
lcd.print(':');
lcd.print( char(minute/10 + 0x30));
lcd.print( char(minute%10 + 0x30));
lcd.print(':');
lcd.print(char (second/10+0x30));
lcd.print(char (second%10+0x30));

lcd.cursorTo(2, 3); //line=2, x=3.
lcd.print(char(dayOfMonth/10+0x30));
lcd.print(char(dayOfMonth%10+0x30));
lcd.print('/');
lcd.print(char(month/10+0x30));
lcd.print(char(month%10+0x30));
lcd.printIn("/20");
lcd.print(char(year/10+0x30));
lcd.print(char(year%10+0x30));
}

void setup() {
Wire.begin();
getDateDs1307() ;
lcd.init();
lcd.clear();

}

void loop() {

unsigned long currentMillis = millis();

if(currentMillis - previousMillis > interval) {
// save the last time you printed and updated
previousMillis = currentMillis;
printTime();
//read RTC
getDateDs1307() ;
}
}
//end sketch

The result as expected (just a clock :-) ):