[Urun]: Wireless Sim Dongle (Sümer Abi sağolsun... )

[Urun]: Wireless Sim Dongle (Sümer Abi sağolsun... )

Bugün iki uzun sorti uçtuk telsiz trainer sistemi ile. Tek kelime ile harika oldu! :D
 
[Urun]: Wireless Sim Dongle (Sümer Abi sağolsun... )

Sümer Yamaner' Alıntı:
Bugün iki uzun sorti uçtuk telsiz trainer sistemi ile. Tek kelime ile harika oldu! :D
Abi yeni bakabildim konuya. Gerçi beklediğimiz bir sonuçtu ama problemsiz sistemin çalıştığını teyid etmek harika olmuş gerçekten :halay:
 
[Urun]: Wireless Sim Dongle (Sümer Abi sağolsun... )

Sümer Yamaner' Alıntı:
Mustafa, birinci kanalı D00'a bağlayacak şekilde D00 - D07 arasını kullanan sekiz kanallı kod aşağıda...

Kod:
/*
   Herhangi bir alıcıdan çıkan servo sinyallerini
   birleştirip senkron darbeli bir PPM pulse train
   oluşturan program

   Kanal girişleri sıralı olarak D00 - D07'ye bağlanacak
   Çıkış D12'den ama istenirse ilk satırdaki #define
   komutu ile değiştirilebilir
*/

#define ppmout 12
#define maxchan 8

int ppm[maxchan + 1];
int current_channel = 0;
int tmp;
unsigned long tmr2H;


void setup()
{
  pinMode(ppmout, OUTPUT);
  digitalWrite(ppmout, HIGH);
  for (int n = 0; n < maxchan; n++)
  {
    pinMode(n, INPUT_PULLUP);
    ppm[n] = 1500;
  }
  ppm[maxchan] = 6000;
  TCCR1A = 0;
  TCCR1B = 10; // CTC Mode ve Prescaler 8
  TIMSK1 = 0;
  TCNT1 = 0;
  OCR1A = 12000; // İlk sync pulse 6 mS
  TIMSK1 = 2; // Start interrupts for PPM generation

  TCCR2A = 0;
  TCCR2B = 2; // Prescaler 8
  TIMSK2 = 0; // Timer2 interruptları beklemede
}

void loop()
{
  for (int n = 0; n < maxchan; n = n + 2)
  {
    tmp = pulse(n);
    if (tmp > 800 && tmp < 2200) ppm[n] = tmp;
  }
  for (int n = 1; n < maxchan; n = n + 2)
  {
    tmp = pulse(n);
    if (tmp > 800 && tmp < 2200) ppm[n] = tmp;
  }
}

ISR(TIMER1_COMPA_vect)
{
  if (digitalRead(ppmout) == HIGH)
  {
    digitalWrite(ppmout, LOW);
    OCR1A = 600;
  }
  else
  {
    digitalWrite(ppmout, HIGH);
    if (current_channel < maxchan)
    {
      OCR1A = 2 * ppm[current_channel] - 600;
      current_channel++;
    }
    else
    {
      current_channel = 0;
      OCR1A = 2 * ppm[maxchan];
    }
  }
}


ISR(TIMER2_OVF_vect)
{
  tmr2H++;
}


int pulse(int x)
{
  byte pin;
  byte cmp;
  unsigned long t;
  cmp |= 1 << x;
  pin = PIND & cmp;
  TCNT2 = 0;
  tmr2H = 0;
  TIMSK2 = 1; // Start Timer2 Overflow Interrupt
  while (!pin)
  {
    pin = PIND & cmp;
    if(tmr2H > 200) return 0;
  }
  TCNT2 = 0;
  tmr2H = 0;
  while (pin)
  {
    pin = PIND & cmp;
    if(tmr2H > 200) return 0;
  }
  TIMSK2 = 0; // Stop Timer2 Overflow Interrupt
  t = (256 * tmr2H + TCNT2) / 2;
  return t;
}
Sümer abi merhaba dün akşam yaptığım testte bu kod çalışmadı ama 6 kanal için olan eski kod çalıştı aradaki farkı araştırdığımda ilk satırlardaki for döngüsünde maxchann dan sonra +2 yok ve buna benzer -2 ve +2 lerden oluşan kodlar eksik bu akşam bunları tamamlayıp deneme yapacağım ama rica etsem bir göz atabilirmisin.
 
[Urun]: Wireless Sim Dongle (Sümer Abi sağolsun... )

Aslında eski dediğin kodla bu kodun çok ciddi farkları var. Temel mantık tamamen farklı. İlki çalıştıysa onunla devam et istersen. Onu sekiz kanala mı çıkarmak istiyordun? Ona bakayım ben.
 
[Urun]: Wireless Sim Dongle (Sümer Abi sağolsun... )

Sümer Yamaner' Alıntı:
Aslında eski dediğin kodla bu kodun çok ciddi farkları var. Temel mantık tamamen farklı. İlki çalıştıysa onunla devam et istersen. Onu sekiz kanala mı çıkarmak istiyordun? Ona bakayım ben.
evet eskiyle kendime bir yol üretmeye çalışıyorum bakalım olacak gibi yeter aslında bana 6 kanal :D
 
[Urun]: Wireless Sim Dongle (Sümer Abi sağolsun... )

Bunak Sümer kodları iyice karıştırmış olabilir. Şu çalışan kod hangisiydi sende?
 
[Urun]: Wireless Sim Dongle (Sümer Abi sağolsun... )

Kod:
/*
   Herhangi bir alıcıdan çıkan servo sinyallerini
   birleştirip senkron darbeli bir PPM pulse train
   oluşturan program

   Kanal girişleri sıralı olarak D02 - D07'ye bağlanacak
   Çıkış D12'den ama istenirse ilk satırdaki #define
   komutu ile değiştirilebilir
*/

#define ppmout 12
#define maxchan 6

int ppm[maxchan + 1];
int current_channel = 0;
int tmp;
unsigned long tmr2H;


void setup()
{
  pinMode(ppmout, OUTPUT);
  digitalWrite(ppmout, HIGH);
  for (int n = 2; n < (maxchan + 2); n++)
  {
    pinMode(n, INPUT_PULLUP);
    ppm[n - 2] = 1500;
  }
  ppm[maxchan] = 6000;
  TCCR1A = 0;
  TCCR1B = 10; // CTC Mode ve Prescaler 8
  TIMSK1 = 0;
  TCNT1 = 0;
  OCR1A = 12000; // İlk sync pulse 6 mS
  TIMSK1 = 2; // Start interrupts for PPM generation

  TCCR2A = 0;
  TCCR2B = 2; // Prescaler 8
  TIMSK2 = 0; // Timer2 interruptları beklemede
}

void loop()
{
  for (int n = 0; n < maxchan; n = n + 2)
  {
    tmp = pulse(n + 2);
    if (tmp > 800 && tmp < 2200) ppm[n] = tmp;
  }
  for (int n = 1; n < maxchan; n = n + 2)
  {
    tmp = pulse(n + 2);
    if (tmp > 800 && tmp < 2200) ppm[n] = tmp;
  }
}

ISR(TIMER1_COMPA_vect)
{
  if (digitalRead(ppmout) == HIGH)
  {
    digitalWrite(ppmout, LOW);
    OCR1A = 600;
  }
  else
  {
    digitalWrite(ppmout, HIGH);
    if (current_channel < maxchan)
    {
      OCR1A = 2 * ppm[current_channel] - 600;
      current_channel++;
    }
    else
    {
      current_channel = 0;
      OCR1A = 2 * ppm[maxchan];
    }
  }
}


ISR(TIMER2_OVF_vect)
{
  tmr2H++;
}


int pulse(int x)
{
  byte pin;
  byte cmp;
  unsigned long t;
  cmp |= 1 << x;
  pin = PIND & cmp;
  TCNT2 = 0;
  tmr2H = 0;
  TIMSK2 = 1; // Start Timer2 Overflow Interrupt
  while (!pin)
  {
    pin = PIND & cmp;
    if(tmr2H > 200) return 0;
  }
  TCNT2 = 0;
  tmr2H = 0;
  while (pin)
  {
    pin = PIND & cmp;
    if(tmr2H > 200) return 0;
  }
  TIMSK2 = 0; // Stop Timer2 Overflow Interrupt
  t = (256 * tmr2H + TCNT2) / 2;
  return t;
}
 
[Urun]: Wireless Sim Dongle (Sümer Abi sağolsun... )

Bugüne kadarki denemelerimde iki farklı yol izledim. Bunlardan birisi gelen sinyali sürekli okuyuo tek tek kanal değerlerini belirlemek ve zamanlama şaşmasın diye PPM sinyalini interruptlar ile oluşturmaktı. Halen sahada kullandığım kod (ki yukarıdaki kod oluyor) budur. Bunu sekiz kanala çıkarma girişimim anladığımkadarıyla başarısız oldu. Onunla ayrıca ilgileneceğim.
Ama yine test edip kullanılabilir bulduğum başka bir yaklaşım var. O da hiç giriş sinyallerinin darbe süreleri ile ilgilenmeden ve interruptlara bulaşmadan yapılıyor. Birinci kanaldan başlanarak darbe başlangıcı bekleniyor. Birinci kanala darbe geldiğinde çıkışa 300 mikrosaniyelik LOW darbesi veriliyor. Bundan sonra her bir kanal sıra ile okunarak LOW olması bekleniyor. LOW olduğunda 300 mikrosaniye beklenip sonra 300 mikrosaniyelik LOW pulse üretiliyor. Tek tek her kanalın LOW olması beklenerek döngü tamamlanıyor. Çok basit bir kod aslında. Daha fazla ayrıntıyı ancak çizerek anlatabilirim. (EK: Çizdim, şekil aşağıda).
Bu kodun önemli bir dezavantajı var ama. Eğer kodu sekiz kanal olarak yapar ama yedi kanal bağlarsak abur cubur sinyaller oluşturuyor. Bu ise kabul edilemez bir durum. Bunu çözmenin ise iki yolu var. Birisi daha en başta tüm kanalları tarayıp kanal sayısını belirlemek. Bunu henüz denemedim. Ben ikinci çözümü ürettim. Eğer sırası gelen kanalın HIGH darbesi vermediği anlaşılırsa PPM sinyali bitirilip tekrar başa dönülüyor.
Kodu aşağıya kopyalıyorum. Şu an test imkanım yok. Kucağımda bir kedi, klavyemin üstünde başka bir kedi varken bol kablolu işleri yapamıyorum. :D Ama Mustafa kardeşim deneyip sonucu yazarsa sevinirim.

Kod:
// 8 kanala kadar PWM sinyalini PPM sinyaline dönüştürücü

#define cikis 12
#define pulselen 300

int channels = 8;
unsigned long tmr;
boolean flag;

void setup()
{
  pinMode(cikis, OUTPUT);
  digitalWrite(cikis, HIGH);
}


void loop()
{
  digitalWrite(cikis, HIGH);
  while (digitalRead(0) == LOW);
  pulse();
  flag = false;
  for (int n = 0; n < channels; n++)
  {
    tmr = micros();
    while (digitalRead(n) == HIGH);
    if ((micros() - tmr) < 100)
    {
      flag = true;
      n = channels + 1;
    }
    delayMicroseconds(pulselen);
    if (!flag) pulse();
  }
}

void pulse()
{
  digitalWrite(cikis, LOW);
  delayMicroseconds(pulselen);
  digitalWrite(cikis, HIGH);
}

Kod istenildiği gibi çalışırsa belki delayMicroseconds() komutları daha şık hale getirilebilir.

[attachimg=1]
 

Ekli dosyalar

  • pic0001.JPG
    pic0001.JPG
    38.8 KB · Görülme: 28
[Urun]: Wireless Sim Dongle (Sümer Abi sağolsun... )

Sümer Yamaner' Alıntı:
Bunak Sümer kodları iyice karıştırmış olabilir. Şu çalışan kod hangisiydi sende?

Abi kod üst te biraz beklettim heralde.
Bende nihayi ürüne dalmışım kodla belki iki giriş daha ekleyebilecegim benim sim projem.

Bu RESMİ görmek için izniniz yok. Giriş yap veya üye ol
 
[Urun]: Wireless Sim Dongle (Sümer Abi sağolsun... )

yok abi oldugu gibi attım kodu ve 2-9 arasına giriş 12 nolu pinede çıkış bağladım ama olmadı çalışmayan 8 kanalda az olsa titreme oluyordu ama bunda oda yok çıkamıyor anladığım kadarıyla
 
[Urun]: Wireless Sim Dongle (Sümer Abi sağolsun... )

Mustafa Çoban.' Alıntı:
yok abi oldugu gibi attım kodu ve 2-9 arasına giriş 12 nolu pinede çıkış bağladım ama olmadı çalışmayan 8 kanalda az olsa titreme oluyordu ama bunda oda yok çıkamıyor anladığım kadarıyla

2-9 arasında değil 0-7 arasına giriş yapman gerekiyordu.
 
[Urun]: Wireless Sim Dongle (Sümer Abi sağolsun... )

abi yanılmıyorum umarım resimde cizdiğim yerdekiler 0 ve 1 oraya giriş bağladığımda rx ve tx yanıyor ve işlem yapmıyor.


Bu RESMİ görmek için izniniz yok. Giriş yap veya üye ol
 
[Urun]: Wireless Sim Dongle (Sümer Abi sağolsun... )

Kod yüklerken o iki pini kullandığı için kod yükleme esnasında alıcının bağlı olmaması gerekiyor. Kod yüklendikten sonra normal kullanılabilir bildiğim kadarıyla.

Bu arada kodun çok daha farklı bir yorumla yeniden yazılmış halini de paylaşıyorum:

Kod:
// 8 kanala kadar PWM sinyalini PPM sinyaline dönüştürücü
// 1.kanal D00, ... 8.kanal D07

#define cikis 12
#define pulselen 300

void setup()
{
  pinMode(cikis, OUTPUT);
  digitalWrite(cikis, HIGH);
  PCICR = 4; //D00 - 07 arasındaki PCINT16-23
  PCMSK2 = 255; // 0-7 arası tüm girişler
  TCCR1B = 2; // Prescaler 8
  TIMSK1 = 0; // No Tİmer1 interrupts
}

ISR(PCINT2_vect)
{
  if((PIND & 1) == 1)
  {
    digitalWrite(cikis, LOW);
    dly(pulselen);
    digitalWrite(cikis, HIGH);
  }
  else
  {
    dly(pulselen);
    digitalWrite(cikis, LOW);
    dly(pulselen);
    digitalWrite(cikis, HIGH);
  }
}

void loop()
{
}

void dly(int x)
{
  TCNT1 = 0;
  while(TCNT1 < (2 * x));
}
 
[Urun]: Wireless Sim Dongle (Sümer Abi sağolsun... )



Burada ( ) da şöyle diyor:

Serial
Used for communication between the Arduino board and a computer or other devices. All Arduino boards have at least one serial port (also known as a UART or USART): Serial. It communicates on digital pins 0 (RX) and 1 (TX) as well as with the computer via USB. Thus, if you use these functions, you cannot also use pins 0 and 1 for digital input or output.
 
[Urun]: Wireless Sim Dongle (Sümer Abi sağolsun... )

yeni kodu da denedim aynı durum söz konusu zaten şöyle oluyor alıcıdan 0 ve 1 çıkarmadan program atamıyorsun hata veriyor bende onları ayırıyorum kodu atıyorum sonra takıyorum ve yeni kodda da aynen rx ve tx ışığı sürekli yanıyor.