26

Re: Часы на адресной ленте WS2812 (Разработка)

Пин подлючения

#define L_BIT    PORTB &= ~(1<<PB0)
#define H_BIT    PORTB |=  (1<<PB0)

Раделительные точи

  if(((PIND >> PD2) & 1) == 0){data_led(42, BRIG, BRIG, BRIG);data_led(43, BRIG, BRIG, BRIG);data_led(44, BRIG, BRIG, BRIG);data_led(45, BRIG, BRIG, BRIG);}
    else{data_led(42, 0, 0, 0);data_led(43, 0, 0, 0);data_led(44, 0, 0, 0);data_led(45, 0, 0, 0);}

27

Re: Часы на адресной ленте WS2812 (Разработка)

При компиляции выдаёт ошибку.

avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x34
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x34
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x34
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x34
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x34
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x34
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x34
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x34
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x34
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x34
Problem uploading to board.  See https://support.arduino.cc/hc/en-us/sections/360003198300 for suggestions.

28

Re: Часы на адресной ленте WS2812 (Разработка)

Это ошибка загрузчика

29

Re: Часы на адресной ленте WS2812 (Разработка)

Я уже понял. Свежая ардуинка с новым загрузчиком. Но скетч всё равно не выводит хотелки, хотя грузится без ошибок

30

Re: Часы на адресной ленте WS2812 (Разработка)

liman324 пишет:

Пин подлючения

#define L_BIT    PORTB &= ~(1<<PB0)
#define H_BIT    PORTB |=  (1<<PB0)

Раделительные точи

  if(((PIND >> PD2) & 1) == 0){data_led(42, BRIG, BRIG, BRIG);data_led(43, BRIG, BRIG, BRIG);data_led(44, BRIG, BRIG, BRIG);data_led(45, BRIG, BRIG, BRIG);}
    else{data_led(42, 0, 0, 0);data_led(43, 0, 0, 0);data_led(44, 0, 0, 0);data_led(45, 0, 0, 0);}

С подключением разобрался. Теперь никак не раскурю "лишние" разделительные точки. У меня одинарные торчат. Получается - второй массив циферок весь переписывать надо...

31

Re: Часы на адресной ленте WS2812 (Разработка)

да

32

Re: Часы на адресной ленте WS2812 (Разработка)

Буду мозговать

33 (2023-01-30 01:28:17 отредактировано www.aleksandrov74)

Re: Часы на адресной ленте WS2812 (Разработка)

Здравствуйте ! Собрал с  градусником все четко работает! Спасибо за скетч.Единственно не меняется цвет цифер когда градусник показывает и нет возможности его поменять. А так в целом не плохо все.
http://forum.rcl-radio.ru/uploads/images/2023/01/24f92e8584ac8607cb03b8185e3b80b7.jpg
http://forum.rcl-radio.ru/uploads/images/2023/01/052815622567068cb88a285162fa3abf.jpg

34

Re: Часы на адресной ленте WS2812 (Разработка)

Здравствуйте. собрал часы по схеме. тест 0-9999 работает. как только загружаю прошивку(финальный скетч) часов без датчика температуры ничего не происходит. светодиоды не горят. что может быть подскажите.

35

Re: Часы на адресной ленте WS2812 (Разработка)

Проверьте I2C сканером адрес ds3231

36

Re: Часы на адресной ленте WS2812 (Разработка)

поменял ds3231. всё заработало. спасибо.

37 (2023-03-22 22:55:41 отредактировано kirilchuk.a)

Re: Часы на адресной ленте WS2812 (Разработка)

В скетчах часов без датчика в строке  case 9: ws(21,1);ws(24,1);ws(27,1);ws(30,1);ws(33,0);ws(37,1);ws(39,1);break; следует ;ws(37,1); заменить на ;ws(36,1); А как бы использовать  показания температуры от самих часов ? Зачем отдельный датчик? Можно отнять от показаний температуры 2-3 ( сколько надо), чтобы учесть нагрев самого кристалла. Это если не нужна уличная температура.

38

Re: Часы на адресной ленте WS2812 (Разработка)

А как бы использовать  показания температуры от самих часов ?

temper = (i2c_read_1bit(ADDR_DS3231,0x11)*100 + ((i2c_read_1bit(ADDR_DS3231,0x12) & 0b11000000) >> 6)*25) ;

надо заменить  i = hour*100+min; на  isecчтобы посмотреть что выведет, скорее всего будет 2700 (27,00 гр)

И вывести запятую.

data_led(45, BRIG, BRIG, BRIG);

задать условие вывода температуры по времени

if(sec>50){i=temper;www=1;}
else{i = hour*100+min;www=0;}


Условие вывода запятой при показе температуры
if(www==0){
    if(((PIND >> PD2) & 1) == 0){data_led(42, BRIG, BRIG, BRIG);data_led(43, BRIG, BRIG, BRIG);data_led(44, BRIG, BRIG, BRIG);data_led(45, BRIG, BRIG, BRIG);}
    else{data_led(42, 0, 0, 0);data_led(43, 0, 0, 0);data_led(44, 0, 0, 0);data_led(45, 0, 0, 0);}
}
else{
    data_led(42, 0, 0, 0);data_led(43, 0, 0, 0);data_led(44, 0, 0, 0);data_led(45, BRIG, BRIG, BRIG);}
}

39

Re: Часы на адресной ленте WS2812 (Разработка)

Спасибо! Буду пробовать.

40

Re: Часы на адресной ленте WS2812 (Разработка)

Туповатый я для самостоятельного программирования. Так и не сообразил что куда вставлять, ни один мой фокус компилятор не пропустил.:)Можно и с Далласом собрать, а где-то ещё видел,что цвета периодически меняются.Хотел фото своих часов вставить, что-то не пошло.

41

Re: Часы на адресной ленте WS2812 (Разработка)

Опубликуйте скетч который вы используете.

42

Re: Часы на адресной ленте WS2812 (Разработка)

// Atmega328, Atmega8 16MHz

#include <avr/io.h>
#include <util/delay.h>
#define ADDR_DS3231    0b1101000
#define CPU_F   16000000 // Clock Speed
#define SCL_F   100000 // // I2C Speed
#define L_BIT    PORTB &= ~(1<<PB0)
#define H_BIT    PORTB |=  (1<<PB0)   
#define LED_MAX 88

  byte rr[LED_MAX],gg[LED_MAX],bb[LED_MAX],r,g,b;
  int i,up,down,brig=1,hh,mm;
  byte sec,min,hour,datat,mont,year,day;
  byte r_led=0,g_led=1,b_led=0;
  byte mode;
  bool sett,w,w1;
  unsigned long times,times0;

int main(void){
    cli();
  TWBR = (((CPU_F)/(SCL_F)-16 )/2) ;
  TWSR = 0;
  DDRD &= ~(1<<PD2);// INPUT SQW DS3231
  DDRB |= (1<<PB0); // INPUT WS2812B (D8 - ARDUINO)
  DDRD &= ~(1<<PD3);// INPUT BUTTON MODE
  DDRD &= ~(1<<PD4);// INPUT BUTTON UP
  DDRD &= ~(1<<PD5);// INPUT BUTTON DOWN
  DDRD &= ~(1<<PD6);// INPUT BUTTON SET
  PORTD |= (1<<PD3);PORTD |= (1<<PD4);PORTD |= (1<<PD5);PORTD |= (1<<PD6);
  DDRB |= (1<<PB0); // INPUT WS2812B (D8 - ARDUINO)
  DDRD &= ~(1<<PD2);// BUTTON (D2 - ARDUINO)
  PORTD |=(1<<PD2); // INPUT_PULLUP
  /// TIMER 0 = 1ms
  ADCSRA = 0b10000100;
  TCCR0A = 0;TCCR0B = 0;TCNT0 = 0;
  OCR0A = 249;
  TCCR0A |= (1 << WGM01);
  TCCR0B |= (1 << CS01) | (1 << CS00);
  TIMSK0 |= (1 << OCIE0A);
  sei();
  _delay_ms(100);
  i2c_write(ADDR_DS3231,0x0E,0b00000000);
  //set_time(23,3,3,22,9,14,0);// год 00-99, ДН 1-7 (1=ВС), месяц 1-12, дата 1-31, час 0-23, минуты 0-59, секунды 0-59
  if(EEPROM_read(100)!=0){for(int i1=0;i1<101;i1++){EEPROM_write(i1,1);}}// очистка памяти при первом включении
  mode = EEPROM_read(0);brig = EEPROM_read(1);

while(1){
/////// BUTTON ///////////////////////////////////////////////
  if(((PIND >> PD3) & 1) == 0){mode++;if(mode>7){mode=0;}_delay_ms(300);w=1;times0=times;}
  switch(mode){
    case 0: r_led=1,g_led=1,b_led=1; break;
    case 1: r_led=1,g_led=0,b_led=0; break;
    case 2: r_led=0,g_led=1,b_led=0; break;
    case 3: r_led=0,g_led=0,b_led=1; break;
    case 4: r_led=1,g_led=1,b_led=0; break;
    case 5: r_led=1,g_led=0,b_led=1; break;
    case 6: r_led=0,g_led=1,b_led=1; break;
    case 7: r_led=0,g_led=0,b_led=0; break;
    }
   if(((PIND >> PD4) & 1) == 0 && sett==0){brig++;if(brig>255){brig=255;}_delay_ms(1);w=1;times0=times;}
   if(((PIND >> PD5) & 1) == 0 && sett==0){brig--;if(brig<1){brig=1;}_delay_ms(1);w=1;times0=times;}
   if(((PIND >> PD6) & 1) == 0 && sett==0){sett=1;_delay_ms(300);}
   if(((PIND >> PD6) & 1) == 0 && sett==1){sett=0;_delay_ms(300);}   

/////// READ TIME //////////////////////////////////////////// 
   sec =  (i2c_read_1bit(ADDR_DS3231,0) & 0x0F) + (((i2c_read_1bit(ADDR_DS3231,0) & 0x70) >> 4) * 10);
   min =  (i2c_read_1bit(ADDR_DS3231,1) & 0x0F) + (((i2c_read_1bit(ADDR_DS3231,1) & 0x70) >> 4) * 10);
   hour = ((i2c_read_1bit(ADDR_DS3231,2) & 0x0F) + ((i2c_read_1bit(ADDR_DS3231,2) & 0x70) >> 4) * 10);
   i = hour*100+min;

//////////// SET TIME //////////////////////////////////////////////////////////////////////
if(sett==1){
  hh=hour;
  mm=min;
  if(((PIND >> PD4) & 1) == 0){hh++;if(hh>23){hh=0;}_delay_ms(100);w1=1;}
  if(((PIND >> PD5) & 1) == 0){mm++;if(mm>59){mm=1;}_delay_ms(100);w1=1;}
  if(w1==1){w1=0;set_time(21,1,12,26,hh,mm,0);}
  i = hh*100+mm;
  }
////////// RGB ////////////////////////////////////////////////
  switch(i/1000){   
    case 0: ws(0,0);ws(3,0);ws(6,0);ws(9,0);ws(12,0);ws(15,0);ws(18,0);break;
    case 1: ws(0,0);ws(3,0);ws(6,1);ws(9,0);ws(12,0);ws(15,0);ws(18,1);break;
    case 2: ws(0,0);ws(3,1);ws(6,1);ws(9,1);ws(12,1);ws(15,1);ws(18,0);break;
    case 3: ws(0,0);ws(3,1);ws(6,1);ws(9,1);ws(12,0);ws(15,1);ws(18,1);break;
    case 4: ws(0,1);ws(3,0);ws(6,1);ws(9,1);ws(12,0);ws(15,0);ws(18,1);break;
    case 5: ws(0,1);ws(3,1);ws(6,0);ws(9,1);ws(12,0);ws(15,1);ws(18,1);break;
    case 6: ws(0,1);ws(3,1);ws(6,0);ws(9,1);ws(12,1);ws(15,1);ws(18,1);break;
    case 7: ws(0,0);ws(3,1);ws(6,1);ws(9,0);ws(12,0);ws(15,0);ws(18,1);break;
    case 8: ws(0,1);ws(3,1);ws(6,1);ws(9,1);ws(12,1);ws(15,1);ws(18,1);break;
    case 9: ws(0,1);ws(3,1);ws(6,1);ws(9,1);ws(12,0);ws(15,1);ws(18,1);break;
    }
  switch(i/100%10){   
    case 0: ws(21,1);ws(24,1);ws(27,1);ws(30,0);ws(33,1);ws(36,1);ws(39,1);break;
    case 1: ws(21,0);ws(24,0);ws(27,1);ws(30,0);ws(33,0);ws(36,0);ws(39,1);break;
    case 2: ws(21,0);ws(24,1);ws(27,1);ws(30,1);ws(33,1);ws(36,1);ws(39,0);break;
    case 3: ws(21,0);ws(24,1);ws(27,1);ws(30,1);ws(33,0);ws(36,1);ws(39,1);break;
    case 4: ws(21,1);ws(24,0);ws(27,1);ws(30,1);ws(33,0);ws(36,0);ws(39,1);break;
    case 5: ws(21,1);ws(24,1);ws(27,0);ws(30,1);ws(33,0);ws(36,1);ws(39,1);break;
    case 6: ws(21,1);ws(24,1);ws(27,0);ws(30,1);ws(33,1);ws(36,1);ws(39,1);break;
    case 7: ws(21,0);ws(24,1);ws(27,1);ws(30,0);ws(33,0);ws(36,0);ws(39,1);break;
    case 8: ws(21,1);ws(24,1);ws(27,1);ws(30,1);ws(33,1);ws(36,1);ws(39,1);break;
    case 9: ws(21,1);ws(24,1);ws(27,1);ws(30,1);ws(33,0);ws(36,1);ws(39,1);break;
    }

    if(((PIND >> PD2) & 1) == 0 && sett==0){data_led(42, r_led*brig, g_led*brig, b_led*brig);data_led(43, r_led*brig, g_led*brig, b_led*brig);
    data_led(44, r_led*brig, g_led*brig, b_led*brig);data_led(45, r_led*brig, g_led*brig, b_led*brig);}
    else{data_led(42, 0, 0, 0);data_led(43, 0, 0, 0);data_led(44, 0, 0, 0);data_led(45, 0, 0, 0);}

    if(sett==1){data_led(42, 0, brig, 0);data_led(43, brig, 0, 0);data_led(44, 0, brig, 0);data_led(45, brig, 0, 0);}

  switch(i/10%10){   
    case 0: ws(46,1);ws(49,1);ws(52,1);ws(55,0);ws(58,1);ws(61,1);ws(64,1);break;
    case 1: ws(46,0);ws(49,0);ws(52,1);ws(55,0);ws(58,0);ws(61,0);ws(64,1);break;
    case 2: ws(46,0);ws(49,1);ws(52,1);ws(55,1);ws(58,1);ws(61,1);ws(64,0);break;
    case 3: ws(46,0);ws(49,1);ws(52,1);ws(55,1);ws(58,0);ws(61,1);ws(64,1);break;
    case 4: ws(46,1);ws(49,0);ws(52,1);ws(55,1);ws(58,0);ws(61,0);ws(64,1);break;
    case 5: ws(46,1);ws(49,1);ws(52,0);ws(55,1);ws(58,0);ws(61,1);ws(64,1);break;
    case 6: ws(46,1);ws(49,1);ws(52,0);ws(55,1);ws(58,1);ws(61,1);ws(64,1);break;
    case 7: ws(46,0);ws(49,1);ws(52,1);ws(55,0);ws(58,0);ws(61,0);ws(64,1);break;
    case 8: ws(46,1);ws(49,1);ws(52,1);ws(55,1);ws(58,1);ws(61,1);ws(64,1);break;
    case 9: ws(46,1);ws(49,1);ws(52,1);ws(55,1);ws(58,0);ws(61,1);ws(64,1);break;
    } 
  switch(i%10){   
    case 0: ws(67,1);ws(70,1);ws(73,1);ws(76,0);ws(79,1);ws(82,1);ws(85,1);break;
    case 1: ws(67,0);ws(70,0);ws(73,1);ws(76,0);ws(79,0);ws(82,0);ws(85,1);break;
    case 2: ws(67,0);ws(70,1);ws(73,1);ws(76,1);ws(79,1);ws(82,1);ws(85,0);break;
    case 3: ws(67,0);ws(70,1);ws(73,1);ws(76,1);ws(79,0);ws(82,1);ws(85,1);break;
    case 4: ws(67,1);ws(70,0);ws(73,1);ws(76,1);ws(79,0);ws(82,0);ws(85,1);break;
    case 5: ws(67,1);ws(70,1);ws(73,0);ws(76,1);ws(79,0);ws(82,1);ws(85,1);break;
    case 6: ws(67,1);ws(70,1);ws(73,0);ws(76,1);ws(79,1);ws(82,1);ws(85,1);break;
    case 7: ws(67,0);ws(70,1);ws(73,1);ws(76,0);ws(79,0);ws(82,0);ws(85,1);break;
    case 8: ws(67,1);ws(70,1);ws(73,1);ws(76,1);ws(79,1);ws(82,1);ws(85,1);break;
    case 9: ws(67,1);ws(70,1);ws(73,1);ws(76,1);ws(79,0);ws(82,1);ws(85,1);break;
    }       
    led_rgb();res();
    _delay_ms(100);

////// EEPROM ///////////////////
if(times-times0>10000&&w==1){EEPROM_write(0,mode);EEPROM_write(1,brig);w=0;} 
}} // end loop

void ws(int ind, bool datt){
  if(datt==1){data_led(ind, r_led*brig, g_led*brig, b_led*brig);data_led(ind+1, r_led*brig, g_led*brig, b_led*brig);data_led(ind+2, r_led*brig, g_led*brig, b_led*brig);}
  if(datt==0){data_led(ind, 0, 0, 0);data_led(ind+1, 0, 0, 0);data_led(ind+2, 0, 0, 0);}}

void bit_0(){H_BIT;asm("nop");asm("nop");   L_BIT;asm("nop");asm("nop");asm("nop");   asm("nop");}
void bit_1(){H_BIT;asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");   L_BIT;}
void bit_w(bool x){if(x) bit_1(); else bit_0();}
void res(){_delay_us(100);}
void data_led(int num, byte rrr, byte ggg, byte bbb){bb[num]=bbb;rr[num]=rrr;gg[num]=ggg;}
void led_rgb(){
  for(int num_i=0;num_i<LED_MAX;num_i++){
  cli();
bit_w((bb[num_i] & 0x80)>>7);
bit_w((bb[num_i] & 0x40)>>6);
bit_w((bb[num_i] & 0x20)>>5);
bit_w((bb[num_i] & 0x10)>>4);
bit_w((bb[num_i] & 0x08)>>3);
bit_w((bb[num_i] & 0x04)>>2);
bit_w((bb[num_i] & 0x02)>>1);
bit_w((bb[num_i] & 0x01)>>0);

bit_w((rr[num_i] & 0x80)>>7);
bit_w((rr[num_i] & 0x40)>>6);
bit_w((rr[num_i] & 0x20)>>5);
bit_w((rr[num_i] & 0x10)>>4);
bit_w((rr[num_i] & 0x08)>>3);
bit_w((rr[num_i] & 0x04)>>2);
bit_w((rr[num_i] & 0x02)>>1);
bit_w((rr[num_i] & 0x01)>>0);

bit_w((gg[num_i] & 0x80)>>7);
bit_w((gg[num_i] & 0x40)>>6);
bit_w((gg[num_i] & 0x20)>>5);
bit_w((gg[num_i] & 0x10)>>4);
bit_w((gg[num_i] & 0x08)>>3);
bit_w((gg[num_i] & 0x04)>>2);
bit_w((gg[num_i] & 0x02)>>1);
bit_w((gg[num_i] & 0x01)>>0);
   sei();
}}

void set_time(byte years, byte days, byte monts, byte datas, byte hours ,byte minute, byte second){
    if(second < 255){i2c_write(ADDR_DS3231,0x00,(second/10<<4)+second%10);}
    if(minute < 255){i2c_write(ADDR_DS3231,0x01,(minute/10<<4)+minute%10);}
    if(hours < 255){i2c_write(ADDR_DS3231,0x02,(hours/10<<4)+hours%10);}
    if(days < 255){i2c_write(ADDR_DS3231,0x03,days);}
    if(datas < 255){i2c_write(ADDR_DS3231,0x04,(datas/10<<4)+datas%10);}
    if(monts < 255){i2c_write(ADDR_DS3231,0x05,(monts/10<<4)+monts%10);}
    if(years < 255){i2c_write(ADDR_DS3231,0x06,(years/10<<4)+years%10);}
  }   


int i2c_read_1bit(byte i2c_addr, byte i2c_reg){
   TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);  // START
  while (!(TWCR & (1<<TWINT)));
   TWDR = i2c_addr << 1;
   TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));
   TWDR = i2c_reg;
   TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));

   TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);  // START
  while (!(TWCR & (1<<TWINT)));
   TWDR = (i2c_addr << 1) | 1;
   TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));

   TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
  while(~TWCR&(1<<TWINT));
    byte i2c_data = TWDR;
  TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));

   TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); // СТОП
  return i2c_data;
  }

void i2c_write(byte i2c_addr, byte i2c_reg, byte i2c_dat){
   TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);  // START
  while (!(TWCR & (1<<TWINT)));
   TWDR = i2c_addr << 1;
   TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));
   TWDR = i2c_reg;
   TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));
   TWDR = i2c_dat;
   TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));
   TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); // СТОП
  }

ISR(TIMER0_COMPA_vect) {times++;}// millis = 1 ms     

unsigned char EEPROM_read(unsigned int uiAddress){
  while(EECR & (1<<EEPE));  // проверка готовности EEPROM
    EEARH = ((uiAddress & 0xF0) << 2); // регистр адреса H
    EEARL = uiAddress & 0x0F; // регистр адреса L
    EECR |= (1<<EERE);// чтение EEPROM
    return EEDR; // вывод значения
}

void EEPROM_write(unsigned int uiAddress, unsigned char ucData){
  while(EECR & (1<<EEPE)); // проверка готовности EEPROM
    EEARH = ((uiAddress & 0xF0) << 2); // регистр адреса H
    EEARL = uiAddress & 0x0F; // регистр адреса L
    EEDR = ucData; // регистр данных
    EECR |= (1<<EEMPE);// Разрешение записи в EEPROM
    EECR |= (1<<EEPE); // Запись в EEPROM
}

43 (2023-03-23 16:41:04 отредактировано kirilchuk.a)

Re: Часы на адресной ленте WS2812 (Разработка)

03:15:41.    Когда же Вы отдыхаете?! smile

Вот такая хотелка:   Формат вывода температуры - ХХ*С. Данные - с модуля часов, вывод раз в минуту с 40 по 50 секунду,
                           далее с 50  до 30 секунды следующей минуты время, с 31 по 39 - дата в формате ДД:ММ

44

Re: Часы на адресной ленте WS2812 (Разработка)

#include <avr/io.h>
#include <util/delay.h>
#define ADDR_DS3231    0b1101000
#define CPU_F   16000000 // Clock Speed
#define SCL_F   100000 // // I2C Speed
#define L_BIT    PORTB &= ~(1<<PB0)
#define H_BIT    PORTB |=  (1<<PB0)   
#define LED_MAX 88

  byte rr[LED_MAX],gg[LED_MAX],bb[LED_MAX],r,g,b;
  int i,up,down,brig=1,hh,mm,mn,dd,temper;
  byte sec,min,hour,datat,mont,year,day;
  byte r_led=0,g_led=1,b_led=0;
  byte mode;
  bool w,w1;
  unsigned long times,times0,times1,times2;
  byte ind[4],www,sett;

int main(void){
    cli();
  TWBR = (((CPU_F)/(SCL_F)-16 )/2) ;
  TWSR = 0;
  DDRD &= ~(1<<PD2);// INPUT SQW DS3231
  DDRB |= (1<<PB0); // INPUT WS2812B (D8 - ARDUINO)
  DDRD &= ~(1<<PD3);// INPUT BUTTON MODE
  DDRD &= ~(1<<PD4);// INPUT BUTTON UP
  DDRD &= ~(1<<PD5);// INPUT BUTTON DOWN
  DDRD &= ~(1<<PD6);// INPUT BUTTON SET
  PORTD |= (1<<PD3);PORTD |= (1<<PD4);PORTD |= (1<<PD5);PORTD |= (1<<PD6);
  DDRB |= (1<<PB0); // INPUT WS2812B (D8 - ARDUINO)
  DDRD &= ~(1<<PD2);// BUTTON (D2 - ARDUINO)
  PORTD |=(1<<PD2); // INPUT_PULLUP
  /// TIMER 0 = 1ms
  ADCSRA = 0b10000100;
  TCCR0A = 0;TCCR0B = 0;TCNT0 = 0;
  OCR0A = 249;
  TCCR0A |= (1 << WGM01);
  TCCR0B |= (1 << CS01) | (1 << CS00);
  TIMSK0 |= (1 << OCIE0A);
  sei();
  _delay_ms(100);
  i2c_write(ADDR_DS3231,0x0E,0b00000000);
  //set_time(23,3,3,22,9,14,0);// год 00-99, ДН 1-7 (1=ВС), месяц 1-12, дата 1-31, час 0-23, минуты 0-59, секунды 0-59
  if(EEPROM_read(100)!=0){for(int i1=0;i1<101;i1++){EEPROM_write(i1,1);}}// очистка памяти при первом включении
  mode = EEPROM_read(0);brig = EEPROM_read(1);

while(1){
/////// BUTTON ///////////////////////////////////////////////
  if(((PIND >> PD3) & 1) == 0){mode++;if(mode>7){mode=0;}_delay_ms(300);w=1;times0=times;}
  switch(mode){
    case 0: r_led=1,g_led=1,b_led=1; break;
    case 1: r_led=1,g_led=0,b_led=0; break;
    case 2: r_led=0,g_led=1,b_led=0; break;
    case 3: r_led=0,g_led=0,b_led=1; break;
    case 4: r_led=1,g_led=1,b_led=0; break;
    case 5: r_led=1,g_led=0,b_led=1; break;
    case 6: r_led=0,g_led=1,b_led=1; break;
    case 7: r_led=0,g_led=0,b_led=0; break;
    }
   if(((PIND >> PD4) & 1) == 0 && sett==0){brig++;if(brig>255){brig=255;}_delay_ms(1);w=1;times0=times;}
   if(((PIND >> PD5) & 1) == 0 && sett==0){brig--;if(brig<1){brig=1;}_delay_ms(1);w=1;times0=times;}
   if(((PIND >> PD6) & 1) == 0){sett++;if(sett>2){sett=0;}_delay_ms(300);}  

/////// READ TIME + TEMPER //////////////////////////////////////////// 
   sec =  (i2c_read_1bit(ADDR_DS3231,0) & 0x0F) + (((i2c_read_1bit(ADDR_DS3231,0) & 0x70) >> 4) * 10);
   min =  (i2c_read_1bit(ADDR_DS3231,1) & 0x0F) + (((i2c_read_1bit(ADDR_DS3231,1) & 0x70) >> 4) * 10);
   hour = ((i2c_read_1bit(ADDR_DS3231,2) & 0x0F) + ((i2c_read_1bit(ADDR_DS3231,2) & 0x70) >> 4) * 10);

   datat = ((i2c_read_1bit(ADDR_DS3231,4) & 0x0F) + ((i2c_read_1bit(ADDR_DS3231,4) & 0x70) >> 4) * 10);
   mont = ((i2c_read_1bit(ADDR_DS3231,5) & 0x0F) + ((i2c_read_1bit(ADDR_DS3231,5) & 0x70) >> 4) * 10);
   
   if(times-times1>5000){times1=times;
   temper = (i2c_read_1bit(ADDR_DS3231,0x11)*100 + ((i2c_read_1bit(ADDR_DS3231,0x12) & 0b11000000) >> 6)*25) ;}

   if(sec>=40 && sec<=50){i = temper;www=1;}
   else if(sec>=31 && sec<=39){i = datat*100+mont;www=2;}
   else{i = hour*100+min;www=3;}
   

//////////// SET TIME //////////////////////////////////////////////////////////////////////
if(sett==1){
  mn=mont;
  dd=datat;
  hh=hour;
  mm=min;
  if(((PIND >> PD4) & 1) == 0){hh++;if(hh>23){hh=0;}_delay_ms(100);w1=1;}
  if(((PIND >> PD5) & 1) == 0){mm++;if(mm>59){mm=1;}_delay_ms(100);w1=1;}
  if(w1==1){w1=0;set_time(22,1,mn,dd,hh,mm,0);}
  i = hh*100+mm;
  }
if(sett==2){
  mn=mont;
  dd=datat;
  hh=hour;
  mm=min;
  if(((PIND >> PD4) & 1) == 0){dd++;if(dd>31){dd=1;}_delay_ms(100);w1=1;}
  if(((PIND >> PD5) & 1) == 0){mn++;if(mn>12){mn=1;}_delay_ms(100);w1=1;}
  if(w1==1){w1=0;set_time(22,1,mn,dd,hh,mm,0);}
  i = dd*100+mn;
  }  

  
  ind[0]=i/1000%10;
  ind[1]=i/100%10;
  ind[2]=i/10%10;
  ind[3]=i/1%10;

  if(www==1){ind[2]=10;ind[3]=11;}
  
////////// RGB ////////////////////////////////////////////////
  switch(ind[0]){   
    case 0: ws(0,0);ws(3,0);ws(6,0);ws(9,0);ws(12,0);ws(15,0);ws(18,0);break;
    case 1: ws(0,0);ws(3,0);ws(6,1);ws(9,0);ws(12,0);ws(15,0);ws(18,1);break;
    case 2: ws(0,0);ws(3,1);ws(6,1);ws(9,1);ws(12,1);ws(15,1);ws(18,0);break;
    case 3: ws(0,0);ws(3,1);ws(6,1);ws(9,1);ws(12,0);ws(15,1);ws(18,1);break;
    case 4: ws(0,1);ws(3,0);ws(6,1);ws(9,1);ws(12,0);ws(15,0);ws(18,1);break;
    case 5: ws(0,1);ws(3,1);ws(6,0);ws(9,1);ws(12,0);ws(15,1);ws(18,1);break;
    case 6: ws(0,1);ws(3,1);ws(6,0);ws(9,1);ws(12,1);ws(15,1);ws(18,1);break;
    case 7: ws(0,0);ws(3,1);ws(6,1);ws(9,0);ws(12,0);ws(15,0);ws(18,1);break;
    case 8: ws(0,1);ws(3,1);ws(6,1);ws(9,1);ws(12,1);ws(15,1);ws(18,1);break;
    case 9: ws(0,1);ws(3,1);ws(6,1);ws(9,1);ws(12,0);ws(15,1);ws(18,1);break;
    }
  switch(ind[1]){   
    case 0: ws(21,1);ws(24,1);ws(27,1);ws(30,0);ws(33,1);ws(36,1);ws(39,1);break;
    case 1: ws(21,0);ws(24,0);ws(27,1);ws(30,0);ws(33,0);ws(36,0);ws(39,1);break;
    case 2: ws(21,0);ws(24,1);ws(27,1);ws(30,1);ws(33,1);ws(36,1);ws(39,0);break;
    case 3: ws(21,0);ws(24,1);ws(27,1);ws(30,1);ws(33,0);ws(36,1);ws(39,1);break;
    case 4: ws(21,1);ws(24,0);ws(27,1);ws(30,1);ws(33,0);ws(36,0);ws(39,1);break;
    case 5: ws(21,1);ws(24,1);ws(27,0);ws(30,1);ws(33,0);ws(36,1);ws(39,1);break;
    case 6: ws(21,1);ws(24,1);ws(27,0);ws(30,1);ws(33,1);ws(36,1);ws(39,1);break;
    case 7: ws(21,0);ws(24,1);ws(27,1);ws(30,0);ws(33,0);ws(36,0);ws(39,1);break;
    case 8: ws(21,1);ws(24,1);ws(27,1);ws(30,1);ws(33,1);ws(36,1);ws(39,1);break;
    case 9: ws(21,1);ws(24,1);ws(27,1);ws(30,1);ws(33,0);ws(36,1);ws(39,1);break;
    }

    if(sett==0){
    if(www==1){data_led(42, 0, 0, 0);data_led(43, 0, 0, 0);data_led(44, 0, 0, 0);data_led(45, 0, 0, 0);}
    if(www==2){data_led(42, r_led*brig, g_led*brig, b_led*brig);data_led(43, r_led*brig, g_led*brig, b_led*brig);
    data_led(44, r_led*brig, g_led*brig, b_led*brig);data_led(45, r_led*brig, g_led*brig, b_led*brig);}

    if(www==3){
    if(((PIND >> PD2) & 1) == 0 && sett==0){data_led(42, r_led*brig, g_led*brig, b_led*brig);data_led(43, r_led*brig, g_led*brig, b_led*brig);
    data_led(44, r_led*brig, g_led*brig, b_led*brig);data_led(45, r_led*brig, g_led*brig, b_led*brig);}
    else{data_led(42, 0, 0, 0);data_led(43, 0, 0, 0);data_led(44, 0, 0, 0);data_led(45, 0, 0, 0);}}
    }

    if(sett==1){data_led(42, 0, brig, 0);data_led(43, brig, 0, 0);data_led(44, 0, brig, 0);data_led(45, brig, 0, 0);}
    if(sett==2){data_led(42, brig, 0, 0);data_led(43, 0, 0, brig);data_led(44, brig, 0, 0);data_led(45, 0, 0, brig);}

  switch(ind[2]){   
    case 0: ws(46,1);ws(49,1);ws(52,1);ws(55,0);ws(58,1);ws(61,1);ws(64,1);break;
    case 1: ws(46,0);ws(49,0);ws(52,1);ws(55,0);ws(58,0);ws(61,0);ws(64,1);break;
    case 2: ws(46,0);ws(49,1);ws(52,1);ws(55,1);ws(58,1);ws(61,1);ws(64,0);break;
    case 3: ws(46,0);ws(49,1);ws(52,1);ws(55,1);ws(58,0);ws(61,1);ws(64,1);break;
    case 4: ws(46,1);ws(49,0);ws(52,1);ws(55,1);ws(58,0);ws(61,0);ws(64,1);break;
    case 5: ws(46,1);ws(49,1);ws(52,0);ws(55,1);ws(58,0);ws(61,1);ws(64,1);break;
    case 6: ws(46,1);ws(49,1);ws(52,0);ws(55,1);ws(58,1);ws(61,1);ws(64,1);break;
    case 7: ws(46,0);ws(49,1);ws(52,1);ws(55,0);ws(58,0);ws(61,0);ws(64,1);break;
    case 8: ws(46,1);ws(49,1);ws(52,1);ws(55,1);ws(58,1);ws(61,1);ws(64,1);break;
    case 9: ws(46,1);ws(49,1);ws(52,1);ws(55,1);ws(58,0);ws(61,1);ws(64,1);break;
    case 10: ws(46,0);ws(49,0);ws(52,0);ws(55,0);ws(58,0);ws(61,0);ws(64,0);break;// пусто
    } 
  switch(ind[3]){   
    case 0: ws(67,1);ws(70,1);ws(73,1);ws(76,0);ws(79,1);ws(82,1);ws(85,1);break;
    case 1: ws(67,0);ws(70,0);ws(73,1);ws(76,0);ws(79,0);ws(82,0);ws(85,1);break;
    case 2: ws(67,0);ws(70,1);ws(73,1);ws(76,1);ws(79,1);ws(82,1);ws(85,0);break;
    case 3: ws(67,0);ws(70,1);ws(73,1);ws(76,1);ws(79,0);ws(82,1);ws(85,1);break;
    case 4: ws(67,1);ws(70,0);ws(73,1);ws(76,1);ws(79,0);ws(82,0);ws(85,1);break;
    case 5: ws(67,1);ws(70,1);ws(73,0);ws(76,1);ws(79,0);ws(82,1);ws(85,1);break;
    case 6: ws(67,1);ws(70,1);ws(73,0);ws(76,1);ws(79,1);ws(82,1);ws(85,1);break;
    case 7: ws(67,0);ws(70,1);ws(73,1);ws(76,0);ws(79,0);ws(82,0);ws(85,1);break;
    case 8: ws(67,1);ws(70,1);ws(73,1);ws(76,1);ws(79,1);ws(82,1);ws(85,1);break;
    case 9: ws(67,1);ws(70,1);ws(73,1);ws(76,1);ws(79,0);ws(82,1);ws(85,1);break;
    case 11: ws(67,1);ws(70,1);ws(73,0);ws(76,0);ws(79,1);ws(82,1);ws(85,0);break;// C
    }       
    led_rgb();res();
    _delay_ms(100);

////// EEPROM ///////////////////
if(times-times0>10000&&w==1){EEPROM_write(0,mode);EEPROM_write(1,brig);w=0;} 
}} // end loop

void ws(int ind, bool datt){
  if(datt==1){data_led(ind, r_led*brig, g_led*brig, b_led*brig);data_led(ind+1, r_led*brig, g_led*brig, b_led*brig);data_led(ind+2, r_led*brig, g_led*brig, b_led*brig);}
  if(datt==0){data_led(ind, 0, 0, 0);data_led(ind+1, 0, 0, 0);data_led(ind+2, 0, 0, 0);}}

void bit_0(){H_BIT;asm("nop");asm("nop");   L_BIT;asm("nop");asm("nop");asm("nop");   asm("nop");}
void bit_1(){H_BIT;asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");   L_BIT;}
void bit_w(bool x){if(x) bit_1(); else bit_0();}
void res(){_delay_us(100);}
void data_led(int num, byte rrr, byte ggg, byte bbb){bb[num]=bbb;rr[num]=rrr;gg[num]=ggg;}
void led_rgb(){
  for(int num_i=0;num_i<LED_MAX;num_i++){
  cli();
bit_w((bb[num_i] & 0x80)>>7);
bit_w((bb[num_i] & 0x40)>>6);
bit_w((bb[num_i] & 0x20)>>5);
bit_w((bb[num_i] & 0x10)>>4);
bit_w((bb[num_i] & 0x08)>>3);
bit_w((bb[num_i] & 0x04)>>2);
bit_w((bb[num_i] & 0x02)>>1);
bit_w((bb[num_i] & 0x01)>>0);

bit_w((rr[num_i] & 0x80)>>7);
bit_w((rr[num_i] & 0x40)>>6);
bit_w((rr[num_i] & 0x20)>>5);
bit_w((rr[num_i] & 0x10)>>4);
bit_w((rr[num_i] & 0x08)>>3);
bit_w((rr[num_i] & 0x04)>>2);
bit_w((rr[num_i] & 0x02)>>1);
bit_w((rr[num_i] & 0x01)>>0);

bit_w((gg[num_i] & 0x80)>>7);
bit_w((gg[num_i] & 0x40)>>6);
bit_w((gg[num_i] & 0x20)>>5);
bit_w((gg[num_i] & 0x10)>>4);
bit_w((gg[num_i] & 0x08)>>3);
bit_w((gg[num_i] & 0x04)>>2);
bit_w((gg[num_i] & 0x02)>>1);
bit_w((gg[num_i] & 0x01)>>0);
   sei();
}}

void set_time(byte years, byte days, byte monts, byte datas, byte hours ,byte minute, byte second){
    if(second < 255){i2c_write(ADDR_DS3231,0x00,(second/10<<4)+second%10);}
    if(minute < 255){i2c_write(ADDR_DS3231,0x01,(minute/10<<4)+minute%10);}
    if(hours < 255){i2c_write(ADDR_DS3231,0x02,(hours/10<<4)+hours%10);}
    if(days < 255){i2c_write(ADDR_DS3231,0x03,days);}
    if(datas < 255){i2c_write(ADDR_DS3231,0x04,(datas/10<<4)+datas%10);}
    if(monts < 255){i2c_write(ADDR_DS3231,0x05,(monts/10<<4)+monts%10);}
    if(years < 255){i2c_write(ADDR_DS3231,0x06,(years/10<<4)+years%10);}
  }   


int i2c_read_1bit(byte i2c_addr, byte i2c_reg){
   TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);  // START
  while (!(TWCR & (1<<TWINT)));
   TWDR = i2c_addr << 1;
   TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));
   TWDR = i2c_reg;
   TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));

   TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);  // START
  while (!(TWCR & (1<<TWINT)));
   TWDR = (i2c_addr << 1) | 1;
   TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));

   TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
  while(~TWCR&(1<<TWINT));
    byte i2c_data = TWDR;
  TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));

   TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); // СТОП
  return i2c_data;
  }

void i2c_write(byte i2c_addr, byte i2c_reg, byte i2c_dat){
   TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);  // START
  while (!(TWCR & (1<<TWINT)));
   TWDR = i2c_addr << 1;
   TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));
   TWDR = i2c_reg;
   TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));
   TWDR = i2c_dat;
   TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));
   TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); // СТОП
  }

ISR(TIMER0_COMPA_vect) {times++;}// millis = 1 ms     

unsigned char EEPROM_read(unsigned int uiAddress){
  while(EECR & (1<<EEPE));  // проверка готовности EEPROM
    EEARH = ((uiAddress & 0xF0) << 2); // регистр адреса H
    EEARL = uiAddress & 0x0F; // регистр адреса L
    EECR |= (1<<EERE);// чтение EEPROM
    return EEDR; // вывод значения
}

void EEPROM_write(unsigned int uiAddress, unsigned char ucData){
  while(EECR & (1<<EEPE)); // проверка готовности EEPROM
    EEARH = ((uiAddress & 0xF0) << 2); // регистр адреса H
    EEARL = uiAddress & 0x0F; // регистр адреса L
    EEDR = ucData; // регистр данных
    EECR |= (1<<EEMPE);// Разрешение записи в EEPROM
    EECR |= (1<<EEPE); // Запись в EEPROM
}

45 (2023-03-24 00:50:02 отредактировано kirilchuk.a)

Re: Часы на адресной ленте WS2812 (Разработка)

Спасибо!!! Работает как часы! smile Дорисовал знак градуса и опытным путем подкорректировал на 5 градусов температуру. Ну ещё изменил под себя время индикации t и data. Всё! Я доволен, спасибо ещё раз.

46

Re: Часы на адресной ленте WS2812 (Разработка)

Здравствуйте! Можно такие режимы замутить чтоб сегменты разными цветами горели?http://forum.rcl-radio.ru/uploads/images/2024/02/29d1dfa8b2ef117ce4daa4369de83c17.jpg http://forum.rcl-radio.ru/uploads/images/2024/02/3a8bb22fb69516b142c8b1c239bc311b.jpg
https://www.ozon.ru/product/oribi-naste … 392333422/ там видео есть как они работают