Erinevus lehekülje "LPT RGB LED BALL" redaktsioonide vahel
(→Esimene) |
P (→Teine) |
||
115. rida: | 115. rida: | ||
char c; | char c; | ||
int tem; | int tem; | ||
− | int | + | int runner = 1; // tsükkel käib, kuni runner on 1 |
int mins = 100, maxs = 1000; // samud intervalli muutmiseks | int mins = 100, maxs = 1000; // samud intervalli muutmiseks | ||
Redaktsioon: 13. oktoober 2011, kell 17:21
Sissejuhatus
Ülesanne on luua RGB valgusdioodidega kera, mis kahel (või kolmel) teljel pööreldes ägedaid mustreid looks. Originaalne idee koos täiendava infoga on Viidete all.
Skeem
Originaalse kera juhtimiseks oli modifitseeritud jalgratta tuli, mille sagedus oli muudetav. Minul tekkis aga idee, kasutada LPT porti mootorite ja LED'ide juhtimiseks.
LED'ide juhtimise skeem on jägmine:
NPN Transistor juhib voolu vaid siis, kui base on pinge all. LPT pordil jääb puudu ampritest, mistõttu suuremaid voolutarbijaid sinna ühendada ei tohi (oht LPT sootuks maha põletada). Küll aga saab soetada vastavaid transistoreid, mis mistahes voolu edasi annavad.
PSU (Power Supply Unit) seadmena kasutan tavalist arvuti AT (vanemat tüüpi) toiteplokki.
Takisti piirab voolu tugevust. Suuremate voolude korral (näiteks 5V või 12V) tuleks kindlasti takisti vahele panna.
LPT
LPT pordil on 8 andme- (D) ja 8 maanduse (G) pesa.
LPT pordile saadetakse signaale kümnendsüsteemi arvuna, kuigi arvestus käib binaarsüsteemis.
Näiteks:
dec bin 0 0 1 1 2 10 3 11 4 100 5 101 6 110 7 111
Kümnendarv 1 lülitaks sisse pesa D0, arv 5 aga D0 ja D2.
Parem ülevaade teisendustest asub siin.
Programm
Esimene
Järgmine koodijupp on kirjutatud c++ keeles. Ülesandeks on teatud andmesignaale sisse/välja lülitada. Samuti on võimalik ka intervalle (töötamise-, väljalülitamise aega) muuta.
#include <iostream>
#include <sys/io.h>
#define base 0x378
using namespace std;
void runFan(int powerLevel)
{
ioperm(base,1,1); // määrame õigused LPT kasutamiseks
// kordame, kuni tsükkel katkestatakse ( ctrl + c )
while(1)
{
outb(0,base); // lülitame LPT andmekanalid välja
usleep(10000-powerLevel*100); // ootame :: 10000 - % arv * 100
outb(255,base); // lülitame LPT andmekanalid sisse
usleep(powerLevel*100); // ootame :: % arv * 100
}
}
int main()
{
int powerLevel = 0; // tekitame muutuja
cout << "Power level %: "; // kuvame kasutajale stringi
cin >> powerLevel; // küsime kasutajalt väärtust
runFan(powerLevel); // käivitame kordustsükli, vastavalt sisestatud väärtusele
}
Teine
Pisut täiustatud koodijupp. Klahve loetakse ühekaupa, numbri teisendamiseks eraldi funktsioon-
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/io.h>
#include <sys/types.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <math.h>
#include <ctime>
#include <string>
#include <sstream>
#define BASEPORT 0x378 /* lp1 */
using namespace std;
// tavalise klahvi küsimise asendus, et reageeritaks ka ühe klahvivajutuse peale
int getkey() {
struct termios oldt, newt;
int ch;
tcgetattr( STDIN_FILENO, &oldt );
newt = oldt;
newt.c_lflag &= ~( ICANON | ECHO );
tcsetattr( STDIN_FILENO, TCSANOW, &newt );
ch = getchar();
tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
return ch;
}
int main() {
char c;
int tem;
int runner = 1; // tsükkel käib, kuni runner on 1
int mins = 100, maxs = 1000; // samud intervalli muutmiseks
int engine1[4] = { 0, 250000, 250000, 0 }; // state, delay_on, delay_off, wait_for
int engine2[4] = { 0, 2500, 2500, 0 };
// info väljumise kohta
printf("\nVäljumiseks vajuta q.\n");
// määrame ligipääsu LPT pordile
if (ioperm(BASEPORT, 3, 1)) { perror("ioperm"); exit(1); }
tem = fcntl(0, F_GETFL, 0);
fcntl (0, F_SETFL, (tem | O_NDELAY));
//main loop
while (runner == 1) {
// küsime klahvivajutust
c = getkey();
if ( c > 0 ) {
printf( "\nKey: %d", c );
// kui klahv oli q, lõpetame tsükli
if ( c == 113 ) { printf( "\nVäljun...\n\n" ); runner = 0; }
/* Engine #1 */
// ON suurendamine
if ( c == 97 ) engine1[1]+=mins; // klahv a
if ( c == 65 ) engine1[1]+=maxs; // klahv A
// ON vähendamine
if ( c == 122 ) if ( engine1[1]-mins < 0 ) engine1[1] = 0; else engine1[1]-=mins; // klahv x
if ( c == 90 ) if ( engine1[1]-maxs < 0 ) engine1[1] = 0; else engine1[1]-=maxs; // klahv X
// OFF suurendamine
if ( c == 115 ) engine1[2]+=mins; // klahv s
if ( c == 83 ) engine1[2]+=maxs; // klahv S
// OFF vähendamine
if ( c == 120 ) if ( engine1[2]-mins < 0 ) engine1[2] = 0; else engine1[2]-=mins; // klahv z
if ( c == 88 ) if ( engine1[2]-maxs < 0 ) engine1[2] = 0; else engine1[2]-=maxs; // klahv Z
/* Engine #2 */
// ON suurendamine
if ( c == 100 ) engine2[1]+=mins; // klahv d
if ( c == 68 ) engine2[1]+=maxs; // klahv D
// ON vähendamine
if ( c == 99 ) if ( (engine2[1]-mins) < 0 ) engine2[1] = 0; else engine2[1]-=mins; // klahv c
if ( c == 67 ) if ( (engine2[1]-maxs) < 0 ) engine2[1] = 0; else engine2[1]-=maxs; // klahv C
// OFF suurendamine
if ( c == 102 ) engine2[2]+=mins; // klahv f
if ( c == 70 ) engine2[2]+=maxs; // klahv F
// OFF vähendamine
if ( c == 118 ) if ( engine2[2]-mins < 0 ) engine2[2] = 0; else engine2[2]-=mins; // klahv v
if ( c == 86 ) if ( engine2[2]-maxs < 0 ) engine2[2] = 0; else engine2[2]-=maxs; // klahv V
}
// kui Engine #1 või Engine #2 tahab muuta olekut
if ( engine1[3] < clock() ) {
// kui Engine #1
if ( engine1[3] < clock() )
if ( engine1[0] == 0 && engine1[1] > 0 ) {
engine1[0] = 1; engine1[3] = clock() + engine1[1];
}
else if ( engine1[2] > 0 ) {
engine1[0] = 0; engine1[3] = clock() + engine1[2];
}
else
engine1[3] = clock() + (engine1[1] > engine1[2] ? engine1[1] : engine1[2]);
// saadame LPT'le konverteeritud binaar -> dec arvu
outb( engine1[0], BASEPORT );
// kuvame ekraanile statistika
printf( "Engine [%3s], %6ld :: %2d\n",
engine1[0] == 1 ? "on" : "off", engine1[3] - clock(),
engine1[0] );
}
usleep( 10 ); // maga 1000 mikrosekundit e. 1 millisekund
}
fcntl(0, F_SETFL, tem);
// lülitame andmesignaalid välja, hoolimata viimasest seisust
outb(0, BASEPORT);
// loobume LTP kasutamise õigustest
if (ioperm(BASEPORT, 3, 0)) {
perror("ioperm"); exit(1);
}
exit(0);
}
Youtube
http://www.youtube.com/embed/sO2-tqoyGik
http://www.youtube.com/embed/SEvToQ9jMXs
Viited
http://hackedgadgets.com/2010/04/20/spinning-rgb-led-ball/ <- originaalse kera pilidid ja kirjeldused #1
http://laserpointerforums.com/f57/led-orb-2-0-a-50012.html <- originaalse kera pilidid ja kirjeldused #2
http://www.codeproject.com/KB/cs/csppleds.aspx <- seletus LPT pordist ning selle toimimisest
http://www.instructables.com/id/A-Simple-Introduction-to-Transistors-and-PWM-Puls/ <- transistorid ja PWM (Pulse-Width Modulation)