- Katılım
- 17 Eyl 2013
- Mesajlar
- 9,108
- Tepkime puanı
- 23,779
- Yaş
- 62
- Konum
- İstanbul
- Web sitesi
- www.sumeryamaner.com
- İlgi Alanı
- Uçak
Yahu kulaklarım o kadar çok çınladı ki ancak yeni kendime gelebildim. Sümer abi,
hani hazır yazılmış kodu kütüphane haline getireceğimden değil ama gene de kodunu görebilsek ne güzel olurdu diyorum ... Ne bileyim, koda yorum olarak eklenmiş "şuraya deadband ekledim", "şurada titreşimi kaldırdım", "burada interruptlara şöyle yaptım" gibi satırlarda olsa, hani olmazda, kodu hızlı bir şekilde kütüphane haline getireceklere kolaylık olurdu ...
Bu arada eline sağlık Sümer abi ...
Hemen geliyor. En son modelimizin (7 segment LED göstergeli) kodu: (Yorumlar yetersiz olabilir)
Kod:
/*
Atmega 328 @ 16MHz external
Çıkış PD0
Buton PB0
Rotary Encoder A PB2 PCINT2
Rotary Encoder B PD5 PCINT21
mode0 Center
mode1 Kaba adımlı Coarse
mode2 Normal (hassas adımlı) Fine
mode3 Sweep
Shift registerli 4 haneli 7 segment display kullanılıyor
SCLK PC3
RCLK PC4
DIO PC5
Power On sırasında butona basılı ise 760 - 1520 seçimi yapılıyor
*/
#define buttonpin 8
#define rotaryA 10
#define rotaryB 5
#define pwmpin 0
#define SCLK 17
#define RCLK 18
#define DIO 19
volatile unsigned int pwm = 1520;
volatile unsigned int dolgu;
unsigned int prevpwm = 1520;
unsigned int oldpwm = 1520;
boolean button;
byte mode;
byte stp = 5;
boolean dir = 1;
volatile boolean pwmon;
volatile boolean slow = 1; // 1: 1520 uS, 0: 760 uS
volatile boolean rA;
volatile boolean rB;
volatile byte pointer;
byte bitmap[10]; // 7 segment digit datasını tutuyor
byte buf[4]; // Devir değerini alfanümerik olarak tutuyor
volatile byte prtbuf[4]; // Devir değerinin digit datasına çevrilmiş halini tutuyor
byte rowbyte;
byte sweeppointer;
byte sweeppointercounter;
byte sweepfactor;
boolean working;
ISR(TIMER1_COMPA_vect)
{
digitalWrite(pwmpin, LOW);
if (pwmon)
{
pwmon = 0;
TCNT1 = 0;
OCR1A = dolgu * (slow + 1);
}
else
{
pwmon = 1;
digitalWrite(pwmpin, HIGH);
TCNT1 = 0;
OCR1A = pwm * (slow + 1);
}
}
ISR(TIMER2_OVF_vect)
{
sei(); // İşte meşhur titreşim önleyici satır! Interrupt içinde interrupt açılıyor.
TCNT2 = 17;
LED_OUT(prtbuf[pointer]);
switch (pointer)
{
case 0:
LED_OUT(8);
break;
case 1:
LED_OUT(4);
break;
case 2:
LED_OUT(2);
break;
case 3:
LED_OUT(1);
break;
}
digitalWrite(RCLK, LOW);
digitalWrite(RCLK, HIGH);
pointer++;
if (pointer > 3) pointer = 0;
}
ISR(PCINT0_vect)
{
rA = digitalRead(rotaryA);
rB = digitalRead(rotaryB);
if (rA)
{
if ((mode == 1) || (mode == 2)) // coarse / fine
{
if (rA == rB)
{
if (mode == 2) pwm--;
if (mode == 1) pwm = pwm - 8;
}
else
{
if (mode == 2) pwm++;
if (mode == 1) pwm = pwm + 8;
}
}
if (mode == 3) // sweep
{
if (rA == rB)
{
stp--;
if (stp < 1) stp = 1;
}
else
{
stp++;
if (stp > 20) stp = 20;
}
}
}
}
void setup()
{
pinMode(buttonpin, INPUT_PULLUP);
pinMode(rotaryA, INPUT_PULLUP);
pinMode(rotaryB, INPUT_PULLUP);
pinMode(pwmpin, OUTPUT);
pinMode(RCLK, OUTPUT);
pinMode(SCLK, OUTPUT);
pinMode(DIO, OUTPUT);
bitmap[0] = B11000000;
bitmap[1] = B11111001;
bitmap[2] = B10100100;
bitmap[3] = B10110000;
bitmap[4] = B10011001;
bitmap[5] = B10010010;
bitmap[6] = B10000010;
bitmap[7] = B11111000;
bitmap[8] = B10000000;
bitmap[9] = B10010000;
oldpwm = pwm;
cli();
TCCR1A = 0;
TCCR1B = B00000010; // Timer1 prescaler 8
TCCR1C = 0;
TCCR2A = 0;
TCCR2B = B00000100; // Timer2 prescaler 256
TIMSK1 = 2; // OCR1A interrupt enabled
TIMSK2 = 1; // Timer2 overflow interrupt enabled
PCICR = 1; // PCINT0 Enabled
PCMSK0 = B00000100; // PCI2 enabled (PB2, Arduino 10)
sei();
if (!digitalRead(buttonpin))
{
delay(10);
if (!digitalRead(buttonpin)) changespeed();
while (!digitalRead(buttonpin));
}
}
void loop()
{
working = 1;
if (pwm < 800) pwm = 800;
if (pwm > 2200) pwm = 2200;
button = digitalRead(buttonpin);
if (!button)
{
delay(10);
button = digitalRead(buttonpin);
if (!button) changemode();
}
if (mode == 3)
{
printout(stp);
}
else
{
if(slow)
{
printout(pwm);
}
else
{
printout(pwm / 2);
}
}
switch (mode)
{
case 0:
midoutput();
break;
case 1:
normaloutput();
break;
case 2:
normaloutput();
break;
case 3:
sweep();
break;
}
}
void normaloutput()
{
dolgu = 20000 - pwm;
}
void midoutput()
{
pwm = 1520;
dolgu = 18480;
}
void sweep()
{
if (dir)
{
pwm = prevpwm + stp;
if (pwm > 2200)
{
pwm = 2200;
dir = 0;
}
}
else
{
pwm = prevpwm - stp;
if (pwm < 800)
{
pwm = 800;
dir = 1;
}
}
prevpwm = pwm;
dolgu = 20000 - pwm;
delay(10);
}
void changemode()
{
mode++;
if (mode > 3) mode = 0;
if (mode == 3) oldpwm = pwm;
if (mode == 1) pwm = oldpwm;
delay(10);
while (!digitalRead(buttonpin));
}
void changespeed()
{
while (!digitalRead(buttonpin)); // Buton bırakılana kadar bekliyoruz
delay(10); // Debounce
while (!digitalRead(buttonpin)); // Buton bırakılana kadar bekliyoruz
while (digitalRead(buttonpin))
{
if (slow)
{
printout(1520);
}
else
{
printout(760);
}
if (digitalRead(rotaryB))
{
delay(10);
if (digitalRead(rotaryB))
{
slow = !slow;
while (digitalRead(rotaryB))
{
if (!digitalRead(buttonpin))
{
slow = !slow;
return;
}
}
}
}
}
}
void printout(unsigned int x)
{
buf[0] = x / 1000;
buf[1] = (x - 1000 * buf[0]) / 100;
buf[2] = (x - 1000 * buf[0] - 100 * buf[1]) / 10;
buf[3] = x % 10;
if (buf[0] == 0)
{
buf[0] = 255;
if (buf[1] == 0)
{
buf[1] = 255;
if (buf[2] == 0) buf[2] = 255;
}
}
for (int n = 0; n < 4; n++)
{
if (buf[n] < 10)
{
prtbuf[n] = bitmap[buf[n]];
}
else
{
prtbuf[n] = 255;
}
}
dp_OFF();
if (working)
{
if (mode < 3)
{
dp_SET(mode);
}
else // Sweep modunda Decimal Point hareketli
{
sweeppointercounter++;
sweepfactor = map(stp, 1, 20, 75, 30); // Decimal Point hareket hızını belirliyor
if (sweeppointercounter > sweepfactor)
{
sweeppointercounter = 0;
sweeppointer++;
if (sweeppointer > 3) sweeppointer = 0;
}
dp_SET(sweeppointer);
}
}
}
void LED_OUT(unsigned char X)
{
unsigned char i;
for (i = 8; i >= 1; i--)
{
if (X & 0x80)
{
digitalWrite(DIO, HIGH);
}
else
{
digitalWrite(DIO, LOW);
}
X <<= 1;
digitalWrite(SCLK, LOW);
digitalWrite(SCLK, HIGH);
}
}
void dp_OFF()
{
for (int m = 0; m < 4; m++)
prtbuf[m] |= B10000000; // All Decimal Points OFF
}
void dp_SET(byte z)
{
prtbuf[z] &= B01111111; // Selected Decimal Point ON
}