LED posūkių tarpinis progamos variantas

Tobulinant  LED posūkių programą pamaniau būtų neblogai išsisaugoti tarpinį variantą. Tarpiniu variantu vadinu todėl, jog dabar programoje prikūriau įvairių funkcijų LED šviesos diodų uždegimui (dar mąstau apie kelias papildomas), o pačių posūkių valdymo funkcijos kaip dar ir neparašiau, na bet jau su turimomis funkcijomis tai nebus padaryti sunku. O kol kas pati programa:


Programos kodas:
/*
* WS2812B.c
*
* Created: 2017.09.30 17:25:58
* Author : Saulius Stasys
*/

// laiko intervalų nustatymai
#define F_CPU 8000000

#define LED 10 //LED skaičius

#define T0 0.35// laiko intervalas 1
#define T1 0.9//laiko0 intervalas 2

#define slide 30 // laiko intervalas šliaužimui

//išeinantys signalai
#define OUTPORT PORTB //LED valdymo portas
#define OUTDR DDRB

#define OUTDDR PB3 //Kairės pusės LED valdymo kontaktas
#define OUTDDR1 PB4 //Dešinės pusės LED valdymo kontaktas

//Įeinantys signalai
#define INDDR DDRB //Valdymo registras
#define INPIN PINB

#define INLIDDR DDB0 //Ilgų kontaktas
#define INLDDR DDB1 //Kairio posūkio kontaktas
#define INRDDR DDB2 //Dešinio posūkio

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

//signalų generavimo funkcija
void rgb(uint8_t r,uint8_t z, uint8_t m, uint8_t as )
{
//zalia spalva
//8bit
uint8_t ch;
for (uint8_t h=0;h<3;h++) { if(h==0) ch=z; if(h==1) ch=r; if(h==2) ch=m; //8bit if (ch-128>0)
{
ch-=128;
OUTPORT=1<<as;
_delay_us(T1);
OUTPORT=0<<as;
_delay_us(T0);
}
else
{
OUTPORT=1<<as;
_delay_us(T0);
OUTPORT=0<<as;
_delay_us(T1);
}

//7bit
if((ch-64<128)&&(ch>63))
{
ch-=64;
OUTPORT=1<<as;
_delay_us(T1);
OUTPORT=0<<as;
_delay_us(T0);
}
else
{
OUTPORT=1<<as;
_delay_us(T0);
OUTPORT=0<<as;
_delay_us(T1);
}

//6bit
if((ch-32<64)&&(ch>31))
{
ch-=32;
OUTPORT=1<<as;
_delay_us(T1);
OUTPORT=0<<as;
_delay_us(T0);
}
else
{
OUTPORT=1<<as;
_delay_us(T0);
OUTPORT=0<<as;
_delay_us(T1);
}

//5bit
if((ch-16<32)&&(ch>15))
{
ch-=16;
OUTPORT=1<<as;
_delay_us(T1);
OUTPORT=0<<as;
_delay_us(T0);
}
else
{
OUTPORT=1<<as;
_delay_us(T0);
OUTPORT=0<<as;
_delay_us(T1);
}

//4bit
if((ch-8<16)&&(ch>7))
{
ch-=8;
OUTPORT=1<<as;
_delay_us(T1);
OUTPORT=0<<as;
_delay_us(T0);
}
else
{
OUTPORT=1<<as;
_delay_us(T0);
OUTPORT=0<<as;
_delay_us(T1);
}

//3bit
if((ch-4<8)&&(ch>3))
{
ch-=4;
OUTPORT=1<<as;
_delay_us(T1);
OUTPORT=0<<as;
_delay_us(T0);
}
else
{
OUTPORT=1<<as;
_delay_us(T0);
OUTPORT=0<<as;
_delay_us(T1);
}

//2bit
if((ch-2<4)&&(ch>1))
{
ch-=2;
OUTPORT=1<<as;
_delay_us(T1);
OUTPORT=0<<as;
_delay_us(T0);
}
else
{
OUTPORT=1<<as;
_delay_us(T0);
OUTPORT=0<<as;
_delay_us(T1);
}

//1bit
if(ch==1)
{
ch-=1;
OUTPORT=1<<as;
_delay_us(T1);
OUTPORT=0<<as;
_delay_us(T0);
}
else
{
OUTPORT=1<<as;
_delay_us(T0);
OUTPORT=0<<as;
_delay_us(T1);
}
}

}

void fixrgb(uint8_t r,uint8_t z, uint8_t m, uint8_t sk, uint8_t as)
{
for (uint8_t i=0;i<sk;i++)rgb(r,z,m,as);
_delay_us(200);
}

void fromto(uint8_t r,uint8_t z, uint8_t m, uint8_t sk, uint8_t sk2, uint8_t as)
{
for (uint8_t i=0;i<sk;i++)rgb(0,0,0,as);
for (uint8_t i=sk;i<sk2;i++)rgb(r,z,m,as);
_delay_us(50);
}

void snake(uint8_t r,uint8_t z, uint8_t m, uint8_t sk, uint8_t as)
{
for (uint8_t i=0;i<sk;i++)
{
for (uint8_t o=0;o<i;o++)rgb(r,z,m,as); _delay_ms(slide); } } void revsnake(uint8_t r,uint8_t z, uint8_t m, uint8_t r1,uint8_t z1, uint8_t m1, uint8_t sk, uint8_t as) { for (uint8_t i=sk;i>0;i–)
{
for (uint8_t o=0;o<i;o++)rgb(r,z,m,as);
for (uint8_t o=0;o<sk-i;o++)rgb(r1,z1,m1,as);
_delay_ms(slide);
}
}

 

void slidebar(uint8_t r,uint8_t z, uint8_t m, uint8_t r1,uint8_t z1, uint8_t m1, uint8_t sk2, uint8_t sk, uint8_t as)
{
for (uint8_t i=0;i<sk;i++)
{
if (i<sk2)for (uint8_t o=0;o<i;o++)rgb(r,z,m,as);
else
{
for (uint8_t o=0;o<i-sk2;o++)rgb(r1,z1,m1,as);
for (uint8_t o=i-sk2;o<i;o++)rgb(r,z,m,as);
}
_delay_ms(slide);
}
for (uint8_t i=sk-sk2;i<sk;i++)
{
for (uint8_t o=0;o<i;o++)rgb(r1,z1,m1,as);
_delay_ms(slide);
}

}

int main(void)
{
_delay_ms(200);
if(INDDR==OUTDR)INDDR=0<<INLIDDR|0<<INLDDR|0<<INRDDR|1<<OUTDDR|1<<OUTDDR1;
else
{
INDDR=0<<INLIDDR|0<<INLDDR|0<<INRDDR;
OUTDR=1<<OUTDDR|1<<OUTDDR1;
}

uint8_t a=0,b=0,c=0,k=0,p=0,kr=0;

p=eeprom_read_byte(0);

while (1)
{

/*
fromto(1,0,0,40,50,OUTDDR);
//_delay_ms(100);
fromto(0,1,0,0,40,OUTDDR);
//_delay_ms(100);*/
/*
fromto(1,0,0,0,3,OUTDDR);
_delay_ms(100);*/

//fromto(0,1,0,0,60,OUTDDR);
//slidebar(0,0,1,1,0,0,50,60,OUTDDR);

snake(25,9,0,10,OUTDDR);
revsnake(25,9,0,25,14,6,10,OUTDDR);

}

}


LED posūkių schemos ir PCB projektavimas

Taigi,  kol esu užsidegęs šiuo projektu jis sparčiai stumiasi į priekį. Šiandien (2017-10-04), pasibraižiau numanomą schemą LED valdymui.

Šioje schemoje pagrindinis komponentas yra Attiny25 QFN korpuse (4x4mm) – šio mikrovaldiklio litavimas bus dar vienas iššūkis. Attiny 25 valdymo signalus gaus iš ilgųjų šviesų, abiejų pusių posūkių. Kadangi valdymo signalai galimai gali tūrėti trukdžių, o taip pat jų įtampa yra kur kas aukštesnė negu 5V, be to dar ir kinta nuo 12 iki 14.5V (grubiai tariant), todėl šie signalai bus perduodami be tiesioginio ryšio mikrovaldikliui panaudojant PC817 optoporas. Taip pat, kadangi mikrovaldiklis bus prilituotas prie PCB jam papildomai schemoje suprojektavau ir programavimo jungtį.

Schema bus maitinama per rėlę, kurią valdys gabaritinės šviesos.  Įtampą lygins LM338 5A įtampos stabilizatorius su keliais kondensatoriais prišais ir už jo. Kadangi schema dar tik teorinė ir neišbandyta realiomis sąlygomis, ateityje ji gali kiek keistis.

Jungtys kairėje iš viršaus į apačia: maitinimo, gabaritų, ir bendra ilgųjų su posūkiais.

Jungtis per vidurį skirta mikrovaldiklio programavimui.

Jungtys dešinėje: LED juostų valdymo jungtys.

Taip pat 3D ir PCB vaizdai:

Numanomi PCB matmenys 50x45mm

 

Automobilio posūkiai

Kažkada kilo įdėja pagaminti LED posūkius, kurie ne mirksėtų, o bėgtų eilute. Tuomet parašiau šiokią tokią programą ir viską pamiršau. Na ir visai neseniai prisiminiau visą šį reikalą ir pamaniau, jog būtų neblogai jį pabaigti. Pačioje pradžioje mąsčiau jog LED valdiklio širdis bus ATTINY2313 mikrovaldiklis, tačiau kiek patobulinęs programą pastebėjau, jog viskam pakaks Attiny25, žinoma, jei ateityje dar tobulinsiu šio mikrovaldiklio nepakaks dėl išvadų trūkumo.Siekis yra pagaminti LED posūkius valdomus per bluetooth sąsają. Na o kol kas senas pirmosios programos rezultatas (deje programos kodo nebėra, jis jau perdarytas 100 kartų :D)

Na, o kadangi šiame video pats rašiau subtitrus, tai klaidų gali pasitaikyti (Man su kalbomis niekad nesisekė).
Kur baigiau, tiesa po šiokio tokio patobulinimo net jau pagaminau pcb ir jai dėžutę. Taip pat naujieji posūkiai buvo ištobulinti ant automobilio- pastebėtos klaidos, bugai ir visokie kitokie error. Kitaip tariant po Alfa testavimo nusiųstas tolimiasniam tobulinimui ir galbūt sulaukęs Beta testavimo veiks nepriekaištingai.
Kol kas čia „Alfa“ programa (tobulintina, be bluetooth sąsajos) Led posūkiai turi 2 rėžimus perjungiamus ilgosiomis šviesomis- smulkiau programos komentaruose.


Programa
/*
* WS2812B.c
*
* Created: 2017.09.30 17:25:58
* Author : Saulius Stasys
*/

// laiko intervalų nustatymai
#define F_CPU 8000000

#define LED 60 //LED skaičius

#define T0 0.35// laiko intervalas 1
#define T1 0.9//laiko0 intervalas 2
#define slide 5 // laiko intervalas šliaužimui

//išeinantys signalai
#define OUTPORT PORTB //LED valdymo portas
#define OUTDR DDRB

#define OUTDDR PB3 //Kairės pusės LED valdymo kontaktas
#define OUTDDR1 PB4 //Dešinės pusės LED valdymo kontaktas

//Įeinantys signalai
#define INDDR DDRB //Valdymo registras
#define INPIN PINB

#define INLIDDR DDB0 //Ilgų kontaktas
#define INLDDR DDB1 //Kairio posūkio kontaktas
#define INRDDR DDB2 //Dešinio posūkio

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

//signalų generavimo funkcija
void grb(uint8_t z,uint8_t r, uint8_t m,uint8_t as )
{
//zalia spalva
//8bit
uint8_t ch;

for (uint8_t h=0;h<3;h++) { if(h==0) ch=z; if(h==1) ch=r; if(h==2) ch=m; //8bit if (ch-128>=0)
{
ch-=128;
OUTPORT=1<<as;
_delay_us(T1);
OUTPORT=0<<as;
_delay_us(T0);
}
else
{
OUTPORT=1<<as;
_delay_us(T0);
OUTPORT=0<<as;
_delay_us(T1);
}

//7bit
if((ch-64<128)&&(ch>63))
{
ch-=64;
OUTPORT=1<<as;
_delay_us(T1);
OUTPORT=0<<as;
_delay_us(T0);
}
else
{
OUTPORT=1<<as;
_delay_us(T0);
OUTPORT=0<<as;
_delay_us(T1);
}

//6bit
if((ch-32<64)&&(ch>31))
{
ch-=32;
OUTPORT=1<<as;
_delay_us(T1);
OUTPORT=0<<as;
_delay_us(T0);
}
else
{
OUTPORT=1<<as;
_delay_us(T0);
OUTPORT=0<<as;
_delay_us(T1);
}

//5bit
if((ch-16<32)&&(ch>15))
{
ch-=16;
OUTPORT=1<<as;
_delay_us(T1);
OUTPORT=0<<as;
_delay_us(T0);
}
else
{
OUTPORT=1<<as;
_delay_us(T0);
OUTPORT=0<<as;
_delay_us(T1);
}

//4bit
if((ch-8<16)&&(ch>7))
{
ch-=8;
OUTPORT=1<<as;
_delay_us(T1);
OUTPORT=0<<as;
_delay_us(T0);
}
else
{
OUTPORT=1<<as;
_delay_us(T0);
OUTPORT=0<<as;
_delay_us(T1);
}

//3bit
if((ch-4<8)&&(ch>3))
{
ch-=4;
OUTPORT=1<<as;
_delay_us(T1);
OUTPORT=0<<as;
_delay_us(T0);
}
else
{
OUTPORT=1<<as;
_delay_us(T0);
OUTPORT=0<<as;
_delay_us(T1);
}

//2bit
if((ch-2<4)&&(ch>1))
{
ch-=2;
OUTPORT=1<<as;
_delay_us(T1);
OUTPORT=0<<as;
_delay_us(T0);
}
else
{
OUTPORT=1<<as;
_delay_us(T0);
OUTPORT=0<<as;
_delay_us(T1);
}

//1bit
if(ch==1)
{
ch-=1;
OUTPORT=1<<as;
_delay_us(T1);
OUTPORT=0<<as;
_delay_us(T0);
}
else
{
OUTPORT=1<<as;
_delay_us(T0);
OUTPORT=0<<as;
_delay_us(T1);
}
}

}

int main(void)
{
if(INDDR==OUTDR)INDDR=0<<INLIDDR|0<<INLDDR|0<<INRDDR|1<<OUTDDR|1<<OUTDDR1;
else
{
INDDR=0<<INLIDDR|0<<INLDDR|0<<INRDDR;
OUTDR=1<<OUTDDR|1<<OUTDDR1;
}

uint8_t a=0,b=0,c=0,k=0,p=0,kr=0;

p=eeprom_read_byte(0);

while (1)
{

////////////////////////////////////////////////////LED posūkių įjungimas ir išjungimas//////////////////////////////////
_delay_ms(30);
if(INPIN&(1<<INLIDDR))// ilgų šviesų tikrinimas
{
k++;
if(k<255) //sumirksėtri per 7.65s (30ms*255)
{
if(c==0)a++; //tikriname ar buvo jungiklis išjungtas
}
else k=254;
c=1;
}
else c=0; // ilgų šviesų jungiklio išjungimas

if (a==3) // reikšmės tikrinimas eeprom atmintyje
{
if(p==0)eeprom_write_byte(0,1); // keičiam reikšmes
else eeprom_write_byte(0,0);
}

/////////////////////////////////////////////////////////REGITRINIS variantas- kuomet LED posūkiai išjungti (paprastas gabaritas)///////////////////////
if(p==0) // išjungta (regitrinis variantas)
{
/////////////////////////////////////////////////////////////PABAIGTI SU LED define!/////////////////////////////////////////

for(uint8_t o=0;o<45;o++)grb(0,0,0,OUTDDR);
for(uint8_t o=45;o<60;o++)grb(147,255,63,OUTDDR);
for(uint8_t o=0;o<45;o++)grb(0,0,0,OUTDDR1);
for(uint8_t o=45;o<60;o++)grb(147,255,63,OUTDDR1);

}

/////////////////////////////////////////////////////////LED posūkiai su gabaritu
else // įjungta (viskas veika)
{

/////////////////////////////////mirksejimas//////////////////////////////////neveikia prigesimas mirksint vienai lempai
if(INPIN&(1<<INLDDR))
{
if(INPIN&(1<<INRDDR))kr=3;
else kr=1;
}

else
{
if(INPIN&(1<<INRDDR))kr=2;
else kr=0;
}

if(INPIN&(1<<INLDDR)||INPIN&(1<<INRDDR))
{
b=0;
for (uint8_t i=0;i<LED;i++)
{
if(kr==1)for(uint8_t o=0;o<i;o++) grb(90,255,0,OUTDDR);
if(kr==2)for(uint8_t o=0;o<i;o++) grb(90,255,0,OUTDDR1);
if(kr==3||kr==0)
{
for(uint8_t o=0;o<i;o++) grb(90,255,0,OUTDDR);
for(uint8_t o=0;o<i;o++) grb(90,255,0,OUTDDR1);
}
_delay_ms(slide); //tarpams vinguriavimo greičiui
}
}

// kai posūkis užgęsta
else
{
b++;
if(b==5) //patikrinam kiek laiko užgesęs posūkis
{
// jei 5 ciklus paryškinam gabaritus
b=b-1;

for(uint8_t o=0;o<LED-1;o++)grb(197,255,143,OUTDDR);
for(uint8_t o=0;o<LED-1;o++)grb(197,255,143,OUTDDR1);
_delay_ms(slide);

}
// jei užgęses posūkis laikome prigesintus gabaritus
else
{
for (uint8_t i=0;i<LED;i++)
{
//

if(kr==1)for(uint8_t o=0;o<i;o++) grb(49,63,35,OUTDDR);
if(kr==2)for(uint8_t o=0;o<i;o++) grb(49,63,35,OUTDDR1);
if(kr==3||kr==0)
{
for(uint8_t o=0;o<i;o++) grb(49,63,35,OUTDDR);
for(uint8_t o=0;o<i;o++) grb(49,63,35,OUTDDR1);
}
_delay_ms(slide);
}
}
}

}

}

}