Erinevus lehekülje "LPT RGB LED BALL" redaktsioonide vahel

Allikas: Kuutõrvaja
(LPT)
(Esimene)
45. rida: 45. rida:
 
== Esimene ==
 
== Esimene ==
  
Järgmine koodijupp on kirjutatud c++ keeles.
+
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.
  
 
<source lang="c">
 
<source lang="c">
77. rida: 77. rida:
 
</source>
 
</source>
  
// REV 1.0
+
== Teine ==
 +
 
 +
Pisut täiustatud koodijupp. Klahve loetakse ühekaupa, numbri teisendamiseks eraldi funktsioon-
 +
 
 +
<source lang="c">
 
#include <stdio.h>
 
#include <stdio.h>
 
#include <stdlib.h>
 
#include <stdlib.h>
86. rida: 90. rida:
 
#include <termios.h>
 
#include <termios.h>
 
#include <unistd.h>
 
#include <unistd.h>
#include <time.h>
+
#include <math.h>
 +
#include <ctime>
 +
#include <string>
 +
#include <sstream>
  
 
#define BASEPORT 0x378 /* lp1 */
 
#define BASEPORT 0x378 /* lp1 */
+
using namespace std;
int getkey( ) {
+
 
   struct termios oldt,
+
// tavalise klahvi küsimise asendus, et reageeritaks ka ühe klahvivajutuse peale
  newt;
+
int getkey() {
 +
   struct termios oldt, newt;
 
   int ch;
 
   int ch;
 
 
   tcgetattr( STDIN_FILENO, &oldt );
 
   tcgetattr( STDIN_FILENO, &oldt );
 
 
   newt = oldt;
 
   newt = oldt;
 
   newt.c_lflag &= ~( ICANON | ECHO );
 
   newt.c_lflag &= ~( ICANON | ECHO );
108. rida: 114. rida:
  
 
   char c;
 
   char c;
   int n, tem, int1 = 95;
+
   int tem;
 
+
   int runner = 1; // tsükkel käib, kuni runner on 1
   int runner = 1;
+
  int mins = 100, maxs = 1000; // samud intervalli muutmiseks
  
   printf("Väljumiseks vajuta ESC.\n");
+
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");
  
   //set permissions to access port
+
   // määrame ligipääsu LPT pordile
 
   if (ioperm(BASEPORT, 3, 1)) { perror("ioperm"); exit(1); }
 
   if (ioperm(BASEPORT, 3, 1)) { perror("ioperm"); exit(1); }
  
120. rida: 130. rida:
 
   fcntl (0, F_SETFL, (tem | O_NDELAY));
 
   fcntl (0, F_SETFL, (tem | O_NDELAY));
  
   //main loop where actual blinking is done
+
   //main loop
 
   while (runner == 1) {
 
   while (runner == 1) {
  
     //if some key is pressed, break out from loop
+
     // küsime klahvivajutust
    //n = read(0, &c, 1);
+
    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
  
    c = getkey();
+
      /* 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
  
    //if ( c > 0 ) { printf( "\nKey: %d", c ); }
+
      // OFF vähendamine
        
+
      if ( c == 118 ) if ( engine2[2]-mins < 0 ) engine2[2] = 0; else engine2[2]-=mins; // klahv v
    if ( c == 113 ) {
+
       if ( c == 86 ) if ( engine2[2]-maxs < 0 ) engine2[2] = 0; else engine2[2]-=maxs; // klahv V     
      printf( "\n Väljun...\n\n" );
 
      runner = 0;
 
 
     }
 
     }
   
 
    if ( c == 97 ) {
 
      if ( int1 < 100 ) int1++;
 
      printf( "\nInt1: %d ", int1 );
 
    }
 
   
 
    if ( c == 122 ) {
 
  
       if ( int1>1 ) int1--;
+
    // kui Engine #1 või Engine #2 tahab muuta olekut
      printf( "\nInt1: %d ", int1 );
+
    if ( engine1[3] < clock() ) {
    }
+
 
   
+
      // kui Engine #1
    //printf( "." );
+
       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]);
 +
 
  
    usleep( 1000 );
+
      // saadame LPT'le konverteeritud binaar -> dec arvu
 +
      outb( engine1[0], BASEPORT );
  
    //write 'on' bit on all data pins and wait 1/4 second
+
      // kuvame ekraanile statistika
    outb(255, BASEPORT);
+
      printf( "Engine [%3s], %6ld :: %2d\n",  
    //usleep(250000)
+
              engine1[0] == 1 ? "on" : "off", engine1[3] - clock(),
    //sleep(1);
+
              engine1[0] );
 +
  }
  
     //write 'off' bit on all data pins and wait 1/4 second
+
     usleep( 10 ); // maga 1000 mikrosekundit e. 1 millisekund
    outb(0, BASEPORT);
 
    //usleep(250000);  
 
    //sleep(1);
 
 
   }
 
   }
 
+
 
 
   fcntl(0, F_SETFL, tem);
 
   fcntl(0, F_SETFL, tem);
 +
 +
  // lülitame andmesignaalid välja, hoolimata viimasest seisust
 
   outb(0, BASEPORT);
 
   outb(0, BASEPORT);
  
   //take away permissions to access port
+
   // loobume LTP kasutamise õigustest
 
   if (ioperm(BASEPORT, 3, 0)) {
 
   if (ioperm(BASEPORT, 3, 0)) {
     perror("ioperm"); exit(1);  
+
     perror("ioperm"); exit(1);
 
   }
 
   }
 
+
 
 
   exit(0);
 
   exit(0);
 
}
 
}
 +
</source>
  
 
= Youtube =
 
= Youtube =

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:

LPTTransistorLED.png

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 ports.gif

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)