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,0);}}// очистка памяти при первом включении
  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/ там видео есть как они работают

47

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

kirilchuk.a пишет:

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

Или я тупой, или платы у меня такие.
Все работает хорошо, но есть одно но..
При выключении питания, и последующем вкл. яркость на минимуме.
Если нажать кнопку сброса яркость так же падает до минимальной.
Как подправить скетч что бы при прошивке яркость была на максимуме.???
Или это невозможно?

Говорила мама учись, а то будешь дебилом коробочки клеить.

48

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

brig = EEPROM_read(1);

заменить на

brig = 255;

49

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

liman324 пишет:

brig = EEPROM_read(1);

заменить на

brig = 255;

Спасибо огромное.
Теперь все ОК.

Говорила мама учись, а то будешь дебилом коробочки клеить.

50

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

День добрый.
Большое спасибо за разработку.
Часы собрал (7 сегментов x  4 LED) x 4 цифры + 2 LED на точки = 114 диодов, WS2813).
Внес поправки на  4 диода в сегменте. Все работает.

Но есть вопрос.
В программировании, мягко говоря, слаб.

Как я понял, вот этот фрагмент

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;
    }

переключает цвета при нажатии соответствующей кнопки.
Вопрос: что означают значения 1 и 0 для  r_red, g_led b b_led ?

Экспериментально я выяснил, что при включении питания диоды загораются с цветом, соответствующим сase 1.

Какими должны быть значения r_red, g_led b b_led, чтобы исходным был зеленый цвет? красный цвет? синий цвет?