1

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

http://forum.rcl-radio.ru/uploads/images/2022/01/a804a933e336ce6f0bb974179671bac6.png

http://forum.rcl-radio.ru/uploads/images/2022/01/486beeaccdfafc1069672ec1040a8c34.png

http://forum.rcl-radio.ru/uploads/images/2022/01/b65a5af32a603b3a99b0e8477a47a722.png

http://forum.rcl-radio.ru/uploads/images/2022/01/05a3dcbe08d47fbe55c037f502c2483b.png

http://forum.rcl-radio.ru/uploads/images/2022/01/11cc9c56829d7e43679f554ab03fa151.jpg

2

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

Тест распайки

http://forum.rcl-radio.ru/uploads/images/2022/01/3cb8287f4284688ce1db0e8c5f93bd5a.jpg

http://forum.rcl-radio.ru/uploads/images/2022/01/d66fbf08e96a23daebf90c2d414537e8.png
http://forum.rcl-radio.ru/uploads/images/2022/01/1f1e971019e54808ef2df28103d696ca.png
http://forum.rcl-radio.ru/uploads/images/2022/01/e54ba5dde706c023febb7cf211384e8e.png
http://forum.rcl-radio.ru/uploads/images/2022/01/6274226bbeb0249e2237912b85e9450d.png 


// Atmega328, Atmega8 16MHz

#include <avr/io.h>
#include <util/delay.h>

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

#define BRIG 2  // яркость 2...255
 
  byte rr[LED_MAX],gg[LED_MAX],bb[LED_MAX],r,g,b;
  int i;

  



int main(void){
  DDRB |= (1<<PB0); // INPUT WS2812B (D8 - ARDUINO)
 while(1){

////////// RGB ////////////////////////////////////////////////
 
  switch(i){   
    case 0: ws(0,1);ws(3,1);ws(6,1);ws(9,0);ws(12,1);ws(15,1);ws(18,1);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;
    } 
    i++;
  if(i>9){i=0;}
    led_rgb();res();
    _delay_ms(1000);

   for(int i1=0;i1<LED_MAX;i1++){data_led(i1,  1,1,1);}led_rgb();res();
   _delay_ms(1000);
 
}} // end loop

 void ws(int ind, bool datt){
  if(datt==1){data_led(ind, BRIG, BRIG, BRIG);data_led(ind+1, BRIG, BRIG, BRIG);data_led(ind+2, BRIG, BRIG, 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(); 
}}

3

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

Тест 2
Счет от 0 до 9999

http://forum.rcl-radio.ru/uploads/images/2022/01/252d836e8ee3c745c7d724eead855b81.png


// Atmega328, Atmega8 16MHz

#include <avr/io.h>
#include <util/delay.h>

#define L_BIT    PORTB &= ~(1<<PB0)
#define H_BIT    PORTB |=  (1<<PB0)    
#define LED_MAX 88
#define BRIG 1  // яркость 2...255
 
  byte rr[LED_MAX],gg[LED_MAX],bb[LED_MAX],r,g,b;
  int i;

  



int main(void){
  DDRB |= (1<<PB0); // INPUT WS2812B (D8 - ARDUINO)
 while(1){

////////// RGB ////////////////////////////////////////////////
 
  switch(i/1000){   
    case 0: ws(0,1);ws(3,1);ws(6,1);ws(9,0);ws(12,1);ws(15,1);ws(18,1);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(37,1);ws(39,1);break;
    } 
    data_led(42, BRIG, BRIG, BRIG);data_led(43, BRIG, BRIG, BRIG);
    data_led(44, BRIG, BRIG, BRIG);data_led(45, BRIG, BRIG, BRIG);
  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;
    }        
    i++;
  if(i>9999){i=0;}
    led_rgb();res();
    _delay_ms(1000);

 
}} // end loop

 void ws(int ind, bool datt){
  if(datt==1){data_led(ind, BRIG, BRIG, BRIG);data_led(ind+1, BRIG, BRIG, BRIG);data_led(ind+2, BRIG, BRIG, 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(); 
}}

4

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

Запуск часов DS3231

http://forum.rcl-radio.ru/uploads/images/2022/01/68d71fed8acdf0c117b28c4fcbf99e06.png

http://forum.rcl-radio.ru/uploads/images/2022/01/3ca09040da5977c1317f61eb49f649ae.png

// 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
#define BRIG 1  // яркость 2...255
 
  byte rr[LED_MAX],gg[LED_MAX],bb[LED_MAX],r,g,b;
  int i;
  byte sec,min,hour,datat,mont,year,day;

int main(void){
  TWBR = (((CPU_F)/(SCL_F)-16 )/2) ;
  TWSR = 0;
  DDRD &= ~(1<<PD2);// INPUT SQW DS3231
  DDRB |= (1<<PB0); // INPUT WS2812B (D8 - ARDUINO)
  _delay_ms(100);
  i2c_write(ADDR_DS3231,0x0E,0b00000000);
  //set_time(21,1,12,26,12,12,0);// год 00-99, ДН 1-7 (1=ВС), месяц 1-12, дата 1-31, час 0-23, минуты 0-59, секунды 0-59

while(1){
   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);
 //  day =  (i2c_read_1bit(ADDR_DS3231,3) & 0x0F);
 //  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);
 //  year = ((i2c_read_1bit(ADDR_DS3231,6) & 0x0F) + ((i2c_read_1bit(ADDR_DS3231,6) & 0x70) >> 4) * 10);
 // temper = (i2c_read_1bit(ADDR_DS3231,0x11)*100 + ((i2c_read_1bit(ADDR_DS3231,0x12) & 0b11000000) >> 6)*25) ;

  i = hour*100+min;
////////// RGB ////////////////////////////////////////////////
  switch(i/1000){   
    case 0: ws(0,1);ws(3,1);ws(6,1);ws(9,0);ws(12,1);ws(15,1);ws(18,1);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(37,1);ws(39,1);break;
    } 
    
    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);}

  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;
    }        
    i++;
  if(i>9999){i=0;}
    led_rgb();res();
    _delay_ms(100);

 
}} // end loop

 void ws(int ind, bool datt){
  if(datt==1){data_led(ind, BRIG, BRIG, BRIG);data_led(ind+1, BRIG, BRIG, BRIG);data_led(ind+2, BRIG, BRIG, 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); // СТОП
  }    

5

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

http://forum.rcl-radio.ru/uploads/images/2022/01/22533a85ea553445dea198b8396188a6.jpg

6

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

Схема часов

http://forum.rcl-radio.ru/uploads/images/2022/01/8bb9bb819029dc3c058a58c721381ec1.png

Финальный скетч

// 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(21,1,12,26,12,12,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,1);ws(3,1);ws(6,1);ws(9,0);ws(12,1);ws(15,1);ws(18,1);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(37,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
} 

7 (2022-01-02 18:20:02 отредактировано Djonny 2022)

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

Термометр бы ещё добавить и убрать нолик в десятках часов

8

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

Термометр бы ещё добавить и убрать нолик в десятках часов

для того чтобы убрать ноль нужно заменить строку:
  case 0: ws(0,1);ws(3,1);ws(6,1);ws(9,0);ws(12,1);ws(15,1);ws(18,1);break;
на
  case 0: ws(0,0);ws(3,0);ws(6,0);ws(9,0);ws(12,0);ws(15,0);ws(18,0);break;

По термометру, если будет собирать часы то добавлю такую функцию.

9

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

Я желающий собрать)))

10

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

Термометр будете использовать который встроен в DS3231?

11

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

У меня цифры распечаны на 3д принтере,туда хочу ленту запихать

12

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

Ds18B20

13

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

Показания датчика выводить с десятыми долями?

14

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

Целыми цифрами,без запятой.Не нужна такая прям точность.Датчик на улице будет

15

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

Формат вывода:
**27
t*27
27°C

* - пустое место

Сколько раз минуту выводить, сколько секунд показывать температуру, на какой секунде начать показывать температуру?

16

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

Добавлен датчик температуры DS18B20 (протестирован на отрицательную температуру)

Температура показывается с 20 до 25 секунду и с 40 по 45 секунду

http://forum.rcl-radio.ru/uploads/images/2022/01/5a6c7173034bb7bb67327e79a878a893.png

http://forum.rcl-radio.ru/uploads/images/2022/01/c32a8c6f40fc298b4a1a8823d3b30f9e.png

// 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,t_iz;
  unsigned long times,times0;
  int temper;
  byte a0,a1,a2,a3;

int main(void){
    Serial.begin(9600);
    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(21,1,12,26,12,12,0);// год 00-99, ДН 1-7 (1=ВС), месяц 1-12, дата 1-31, час 0-23, минуты 0-59, секунды 0-59
  mode = EEPROM_read(0);brig = EEPROM_read(1);
  if(EEPROM_read(100)!=0){for(int i1=0;i1<101;i1++){EEPROM_write(i1,1);}}// очистка памяти при первом включении 
  temper = read_temp();

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

   a0 = hour/10;
   a1 = hour%10;
   a2 = min/10;
   a3 = min%10;
   
   if(sett==0 && (sec>=20&&sec<=25 || sec>=40&&sec<=45)){t_iz=1;temper = read_temp();
   a0 = 10;
   if(temper<0){temper=temper*-1;a1=11;}else{a1 = 10;}
   a2 = temper/10;
   a3 = temper%10;
   r_led=1;g_led=1;b_led=1;
   }else{t_iz=0;}
   
//////////// 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);}
   a0 = hh/10;
   a1 = hh%10;
   a2 = mm/10;
   a3 = mm%10;
  }
////////// RGB ////////////////////////////////////////////////
  switch(a0){   
    case 0: ws(0,1);ws(3,1);ws(6,1);ws(9,0);ws(12,1);ws(15,1);ws(18,1);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;
   case 10: ws(0,0);ws(3,0);ws(6,0);ws(9,0);ws(12,0);ws(15,0);ws(18,0);break;// пусто
    } 
  switch(a1){   
    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;
   case 10: ws(21,0);ws(24,0);ws(27,0);ws(30,0);ws(33,0);ws(36,0);ws(39,0);break;// пусто
   case 11: ws(21,0);ws(24,0);ws(27,0);ws(30,1);ws(33,0);ws(36,0);ws(39,0);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);}
    if(t_iz==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);}
     
  switch(a2){   
    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(a3){   
    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
} 

uint8_t therm_reset(){
    uint8_t i;
    PORTD &= ~(1 << PD7);
    DDRD |= (1 << PD7);
    _delay_us(480);  
    DDRD &= ~(1 << PD7);
    _delay_us(60);
    i=((PIND >> PD7) & 1);
    _delay_us(420);
    return i;
}
// write bit
void therm_write_bit(uint8_t bit){
    PORTD &= ~(1 << PD7);
    DDRD |= (1 << PD7);
    _delay_us(1);
    if(bit) DDRD &= ~(1 << PD7);
    _delay_us(60);
    DDRD &= ~(1 << PD7);
}
// read bit
uint8_t therm_read_bit(void){
    uint8_t bit=0;
    PORTD &= ~(1 << PD7);
    DDRD |= (1 << PD7);
    _delay_us(1);
    DDRD &= ~(1 << PD7);
    _delay_us(14);
    if(PIND & (1 << PD7)) bit=1;
    _delay_us(45);
    return bit;
}
 
// read byte
uint8_t therm_read_byte(void){
    uint8_t i=8, n=0;
    while(i--){n>>=1;n|=(therm_read_bit()<<7);}
    return n;
}
 
// write byte
void therm_write_byte(uint8_t byte){
    uint8_t i=8;
    while(i--){therm_write_bit(byte&1);byte >>= 1;
    }
}
// read temp
int read_temp(){
    uint8_t temperature[2];
    int temper;
    therm_reset();
    therm_write_byte(0xCC);
    therm_write_byte(0x44);
    while(!therm_read_bit());
    therm_reset();
    therm_write_byte(0xCC);
    therm_write_byte(0xBE);
    temperature[0]=therm_read_byte();
    temperature[1]=therm_read_byte();
    therm_reset();
    temper = (temperature[1] << 8 | temperature[0])/16;
    return temper;
}  

17

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

Будем тестить,спасибо)))

18

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

http://forum.rcl-radio.ru/uploads/images/2022/01/0c9fa8cb5cdc466292046a1600e29274.png

Добавлен знак t при выводе температуры

// Atmega328, Atmega8 16MHz

#include <avr/io.h>
#include <util/delay.h>
#define ADDR_DS3231    0b1101000
#define CPU_F   16000000 // Clock Speed 
#define SCL_F   50000 // // 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,t_iz;
  unsigned long times,times0;
  int temper;
  byte a0,a1,a2,a3;

int main(void){
    Serial.begin(9600);
    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(21,1,12,26,12,12,0);// год 00-99, ДН 1-7 (1=ВС), месяц 1-12, дата 1-31, час 0-23, минуты 0-59, секунды 0-59
  mode = EEPROM_read(0);brig = EEPROM_read(1);
  if(EEPROM_read(100)!=0){for(int i1=0;i1<101;i1++){EEPROM_write(i1,1);}}// очистка памяти при первом включении 
  temper = read_temp();

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

   a0 = hour/10;
   a1 = hour%10;
   a2 = min/10;
   a3 = min%10;
   
   if(sett==0 && (sec>=20&&sec<=25 || sec>=40&&sec<=45)){t_iz=1;temper = read_temp();
   a0 = 12;
   if(temper<0){temper=temper*-1;a1=11;}else{a1 = 10;}
   a2 = temper/10;
   a3 = temper%10;
   r_led=1;g_led=1;b_led=1;
   }else{t_iz=0;}
   
//////////// 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);}
   a0 = hh/10;
   a1 = hh%10;
   a2 = mm/10;
   a3 = mm%10;
  }
////////// RGB ////////////////////////////////////////////////
  switch(a0){   
    case 0: ws(0,1);ws(3,1);ws(6,1);ws(9,0);ws(12,1);ws(15,1);ws(18,1);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;
   case 10: ws(0,0);ws(3,0);ws(6,0);ws(9,0);ws(12,0);ws(15,0);ws(18,0);break;// пусто
   case 12: ws(0,1);ws(3,0);ws(6,0);ws(9,1);ws(12,1);ws(15,1);ws(18,0);break;// t
    } 
  switch(a1){   
    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;
   case 10: ws(21,0);ws(24,0);ws(27,0);ws(30,0);ws(33,0);ws(36,0);ws(39,0);break;// пусто
   case 11: ws(21,0);ws(24,0);ws(27,0);ws(30,1);ws(33,0);ws(36,0);ws(39,0);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);}
    if(t_iz==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);}
     
  switch(a2){   
    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(a3){   
    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
} 

uint8_t therm_reset(){
    uint8_t i;
    PORTD &= ~(1 << PD7);
    DDRD |= (1 << PD7);
    _delay_us(480);  
    DDRD &= ~(1 << PD7);
    _delay_us(60);
    i=((PIND >> PD7) & 1);
    _delay_us(420);
    return i;
}
// write bit
void therm_write_bit(uint8_t bit){
    PORTD &= ~(1 << PD7);
    DDRD |= (1 << PD7);
    _delay_us(1);
    if(bit) DDRD &= ~(1 << PD7);
    _delay_us(60);
    DDRD &= ~(1 << PD7);
}
// read bit
uint8_t therm_read_bit(void){
    uint8_t bit=0;
    PORTD &= ~(1 << PD7);
    DDRD |= (1 << PD7);
    _delay_us(1);
    DDRD &= ~(1 << PD7);
    _delay_us(14);
    if(PIND & (1 << PD7)) bit=1;
    _delay_us(45);
    return bit;
}
 
// read byte
uint8_t therm_read_byte(void){
    uint8_t i=8, n=0;
    while(i--){n>>=1;n|=(therm_read_bit()<<7);}
    return n;
}
 
// write byte
void therm_write_byte(uint8_t byte){
    uint8_t i=8;
    while(i--){therm_write_bit(byte&1);byte >>= 1;
    }
}
// read temp
int read_temp(){
    uint8_t temperature[2];
    int temper;
    therm_reset();
    therm_write_byte(0xCC);
    therm_write_byte(0x44);
    while(!therm_read_bit());
    therm_reset();
    therm_write_byte(0xCC);
    therm_write_byte(0xBE);
    temperature[0]=therm_read_byte();
    temperature[1]=therm_read_byte();
    therm_reset();
    temper = (temperature[1] << 8 | temperature[0])/16;
    return temper;
}  

19

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

Привет! Видео часов с температурой можно посмотреть?

20

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

Я уже все разобрал.

21

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

Печалька, что уже всё разобрано. Недавно начал знакомиться с адресной лентой.
Хотелки:
1. Что подправить в итоговом скетче, если в разделительных точках по одному светодиоду?
2. Формат вывода температуры - ХХ*С. Данные - с модуля часов, вывод раз в минуту с 40 по 50 секунду
3. Формат вывода: с 50 до 00, далее - с 00 до 30 секунды время, с 31 по 39 - дата в формате ДД:ММ

22

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

У Вас уже все собрано?

23

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

liman324 пишет:

У Вас уже все собрано?

Пока только шаблон цыферок. Вчера только курьер привёз.
https://disk.yandex.ru/i/jwyh__bkLYmpzg

24

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

Как будет все готово, оставьте сообщение. Я внесу правки в код, а Вы протестируете.

25

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

Наконец-то я закончил паять сие чудо (то отпуск, то руки не доходят).
В моей версии пока нет кнопок и всех прочих наворотов (собрано по схеме http://forum.rcl-radio.ru/viewtopic.php?pid=4988#p4988). В скетче не нашёл пин подключения sad И в разделительных точках по одному светодиоду