İki Arduino arasında 16 bit veri gönderimi

Başlatan cirak05, 23 Aralık 2018, 13:39:57

interrupter

Aynen ustam dediğiniz gibi yapıyorum zaten tek while nin içinden cikabilsem kodumun tamamı en son gyzdigim zaten kesme işlemini test ediyorum ama kesmeye giremedim

interrupter

#31
#include <avr/io.h>
#include <SPI.h>
#include <DMD2.h>
#include <fonts/Arial_Black_16.h>
#define USART_BAUDRATE 9600
 


byte a=31,b=29,c=27,d=25,e=23,f=21,g=19;

SoftDMD dmd(2,1);  // DMD controls the entire display
DMD_TextBox box(dmd, 0, 1);  // "box" provides a text box to automatically write to/scroll the display

void setup() {
 
  UBRR0L = USART_BAUDRATE & 0xff;
  UBRR0H = USART_BAUDRATE >> 8;
  UCSR0C |= (1 << UCSZ00) | (1 << USBS0); // Use 8-bit character sizes
  UCSR0B |= (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);  // Turn on the transmission, reception, and Receive interrupt     
  interrupts();
 Serial.begin(9600);
 dmd.setBrightness(25);
 dmd.selectFont(Arial_Black_16);
 dmd.begin();
 pinMode(a, OUTPUT);
digitalWrite(a,LOW);

}

void loop()
{
digitalWrite(a,HIGH);
delay(30);
digitalWrite(a,LOW);
 }




ISR(USART0_RXC)
{
  box.clear();
box.print("veriii");
  UDR0 = 1;
  delay(100);              // wait for a second
}




mg ustam kodun tamamı böyle su anda tek amacım kesme oluşup oluşmadığını test etmeye çalışıyorum ama oluşturamadım daha 

z

Global bir int enable disable durumu yokmu bu islemcide?
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

interrupter

z hocam sorduğnuz soruya cevabım olacak kapasitede bilgim olsa... öğrenmeye çalışıyorum

mg1980

Bu kod sanırım, bir kaç yerden toparlanmış ve karışık bir hal almış gibi.. mesela "a" başlangıçta byte değişken olarak atanmış ve 31 değeri verilmiş.. sonra setup, da pin yapılandırması gibi çıkış yapılıp LOW, HIGH yapılıyor.. loop içinde blink yaptırılıyor, orada da bir delay eksik, yani pin yapılandırması olsa devamlı yanar.. belki de ben yanlış değerlendiriyorum, arduino mantığına pek uygun gibi gelmedi bana... fazla uzman olmadığımı söyledim.. kendi işlerimi görecek kadar.. hocalarımız daha iyi değerlendirebilir..

interrupter

mg ustam kod toplama değil seri port kesmesi toplama çünkü bilmiyorum mantığını anlamadım örnek bulamadım.

a değişkeni tanımladım ve içeriğini 31 yaptım çünkü benim arduino mega karttımın 31 numaralı pini benim slave 1 kartımın bilgi gönder pinine denk geliyor.

a değişkenine 31 yazdım

a yı çıkış olarak atadım yani 31 numaralı pini

loop ta da
 a pinini high low yapıyorum.
çünkü her bu pindeki her palste slave seri veri gönderiyor.
ve seri porttan verii gelmeye başladığı anda master kesmeye girmesi lağzım ama seri kesmeyi yapamadım
seri porttan verii geliyor ama kesmeye sokamıyorum

muhendisbey

Alıntı yapılan: interrupter - 05 Ocak 2022, 17:41:41uma bakmayın kesmenin yalanı gerçeği mi olur. foruma göre çok acemiyim.

Yalan, gerçek mevzusu değil. Arduino'nun seri iletişim kütüphanesinde kesme yoktur. Kesmeye benzer mantıkta çalışan kodlar türetilmiştir, ancak bu da her koşulda kesme gibi kullanabilmenizi sağlamaz. serialEvent'in while içerisinde çalışmaması gibi...

O nedenle bazen AVR kodları ile müdahale ederiz. Örneğin; çok küçük gecikme oluştururken, pinleri hızlı toggle ederken; farklı, özel frekanslarda PWM oluştururken...
Zulmü alkışlayamam, zalimi asla sevemem; Gelenin keyfi için geçmişe kalkıp sövemem.

interrupter

Anladım sayın muhendisbey. Yani Arduinoda (atmega 328p) için konuşuyorum seri port donanımsal kesme yok adamlar yazılımsal serialevent yapmışlar bu da bu şekilde çalışıyor. Örneğin o kadar serial kesme için doküman aradım ama yok bulamadim hep harici kesme (dijital pinlerle) yada dahili kesmeler var. Sorunuma tekrar gelecek olursam kesmeye çok kafayı takmışım farklı yöntemle kesmesiz hallettim. Ama bu kesme meselesini kafaya taktım. Sizler nasıl yapıyorsunuz

muhendisbey

Eğer bir arduino projesi ise çoğunlukla kesmeye ihtiyaç olmadan çözmeye çalışırım. Bir veri geliyorsa o veriyi kısa sürede işleyip, ya da gelen veri çoksa buffer'a alıp işlerim. Ancak bu da her zaman çözüm olmaz.

Echo yapmıyorsun ki bu sıkıntının kaynağı burada yatıyor. Echo yaparsan veri gönderildiğinde bu veriyi değişkene kaydedip geri gönderirsin ve verinin alındığından emin olursun. Geri gelmemişse veri, tekrar gönderirsin. Handshake denir bu işleme.

Proje büyükse, bu işi arduino ile değil, tiva ya da STM ile gerçekleştiririm. Vector table'ını ayarlar, kesmelerini ayarlar, ring buffer oluşturarak yaparım.

Arduino ile ilerleyeceksen:
14. yorum:
https://www.avrfreaks.net/forum/atmega328p-serial-communication-interrupt
ya da
https://stackoverflow.com/questions/53104440/how-to-implement-interrupt-for-serial-usart-communication-for-atmega328p-arduino

datasheet'i detaylı okumak gerekli.
Zulmü alkışlayamam, zalimi asla sevemem; Gelenin keyfi için geçmişe kalkıp sövemem.

Kabil ATICI

Atmega 328p seri port(uart) ilgili örnekleri (datasheet) veri kağıtlarında asm ve c kod olarak bulunmaktadır.

Arduino kodu olarak da çalışmaktadır.
ambar7

mg1980

#40
@interrupter  ve değerli arkadaşlar,

İşinize yarar mı bilmiyorum ama Arduino'da olmayan USART-donanımsal kesme ile ilgili bir çalışma yaptım.Benzeri var mı bilmiyorum, bir yerden alıntı değil ve fiilen denedim, çalışıyor. Kodları ile ilave yapılacak basit bir devre fotoğrafını aşağıya koyuyorum. Bilindiği gibi Arduino Uno-Nano'da External Kesme denen bir olay var. Buna ait pinler 2 ve 3 no.lu pinler. 2 no.lu harici kesme pinini bir transistör ile PULLUP yaparak INT0 (pin2)  pinine bağladım.Rx (0 pini) 'ni de 27k direnç ile transistör beyz'ine verdim.Kendi seri portu üzerinden PC'den veri gönderip aldım gayet güzel çalışıyor.Şimdilik problem görünmüyor.İki Arduino arasında denendiğinde problem gören olursa birlikte çözüm ararız.
const int LED=8;
const int LEDX=13;

volatile double deneme;
volatile double gelen;





void setup() 
{
  Serial.begin(9600);
  pinMode(LED,OUTPUT);
  pinMode(LEDX,OUTPUT);
  pinMode(2,INPUT);
  digitalWrite(LED,LOW);
  digitalWrite(LEDX,LOW);
  
  attachInterrupt(0,kesme,FALLING); //RISING=Yükselen kenar,FALLING..düşen 

}

void loop() 
{

  digitalWrite(LEDX,HIGH);
  delay(500);
  digitalWrite(LEDX,LOW);
  delay(500);
  digitalWrite(LED,LOW);
}

void kesme()   // Kesme fonksiyonu
{
  cli();           // Fonksiyon boyunca tekrar kesme oluşmaması için....KESME'yi KAPAT..
  if(Serial.available()>0)  // Seri porta veri geldiyse
  {
    gelen=Serial.read();
    digitalWrite(LED,HIGH);
    
    Serial.println(gelen);
    deneme=65535;
    Serial.println(deneme);
    
  }
  sei();          // KESME'yi AÇ..
  
}


interrupter

Mg1980 başa cikamazsam bende böyle düşünüyordum ama mantigimi değiştirerek hallettim. Bazı denemeler yapıyorum kod üzerinde ve burada da paylasacagim

interrupter


#include <avr/io.h>
#include <SPI.h>
#include <DMD2.h>
#include <fonts/Arial_Black_16.h>
#define USART_BAUDRATE 9600
unsigned int sayac=0, toplam=0, sys=0,slva=0,slvb=0,slvc=0,slvd=0,slve=0,slvf=0,slvg=0;

byte level=1,a=29,b=27,c=25,d=23,e=21,f=19,g=17,bosalt=0;
byte low=0,high=0;
bool aa=0,bb=0,cc=0,dd=0,ee=0,ff=0,gg=0,interrupt=0;
bool stringComplete = false;
SoftDMD dmd(2,1);  // DMD controls the entire display
DMD_TextBox box(dmd, 0, 1);  // "box" provides a text box to automatically write to/scroll the display





void setup() {
 
 
 Serial.begin(9600);
 dmd.setBrightness(100);
 dmd.selectFont(Arial_Black_16);
 dmd.begin();
 pinMode(a, OUTPUT);
 pinMode(b, OUTPUT);
 pinMode(c, OUTPUT);
 pinMode(d, OUTPUT);
 pinMode(e, OUTPUT);
 pinMode(f, OUTPUT);
 pinMode(g, OUTPUT);

 
 digitalWrite(a,LOW);
 digitalWrite(b,LOW);
 digitalWrite(c,LOW);
 digitalWrite(d,LOW);
 digitalWrite(e,LOW);
 digitalWrite(f,LOW);
 digitalWrite(g,LOW);


}

void loop()
{

  if(aa==1)
  {
    slva=0;
    aa=0;
    DMD_TextBox box(dmd, 45, 0);
    box.print("A");
 digitalWrite(a,LOW);
 digitalWrite(b,LOW);
 digitalWrite(c,LOW);
 digitalWrite(d,LOW);
 digitalWrite(e,LOW);
 digitalWrite(f,LOW);
 digitalWrite(g,LOW);
 delay(500);
  }

    if(bb==1)
  {
    slvb=0;
    bb=0;
    DMD_TextBox box(dmd, 45, 0);
    box.print("B");
 digitalWrite(a,LOW);
 digitalWrite(b,LOW);
 digitalWrite(c,LOW);
 digitalWrite(d,LOW);
 digitalWrite(e,LOW);
 digitalWrite(f,LOW);
 digitalWrite(g,LOW);
 delay(500);
  }

      if(cc==1)
  {
    slvc=0;
    cc=0;
    DMD_TextBox box(dmd, 45, 0);
    box.print("C");
 digitalWrite(a,LOW);
 digitalWrite(b,LOW);
 digitalWrite(c,LOW);
 digitalWrite(d,LOW);
 digitalWrite(e,LOW);
 digitalWrite(f,LOW);
 digitalWrite(g,LOW);
 delay(500);
  }

        if(dd==1)
  {
    slvd=0;
    dd=0;
    DMD_TextBox box(dmd, 45, 0);
    box.print("D");
 digitalWrite(a,LOW);
 digitalWrite(b,LOW);
 digitalWrite(c,LOW);
 digitalWrite(d,LOW);
 digitalWrite(e,LOW);
 digitalWrite(f,LOW);
 digitalWrite(g,LOW);
 delay(500);
  }

        if(ee==1)
  {
    slve=0;
    ee=0;
    DMD_TextBox box(dmd, 45, 0);
    box.print("E");
 digitalWrite(a,LOW);
 digitalWrite(b,LOW);
 digitalWrite(c,LOW);
 digitalWrite(d,LOW);
 digitalWrite(e,LOW);
 digitalWrite(f,LOW);
 digitalWrite(g,LOW);
 delay(500);
  }

        if(ff==1)
  {
    slvf=0;
    ff=0;
    DMD_TextBox box(dmd, 45, 0);
    box.print("F");
 digitalWrite(a,LOW);
 digitalWrite(b,LOW);
 digitalWrite(c,LOW);
 digitalWrite(d,LOW);
 digitalWrite(e,LOW);
 digitalWrite(f,LOW);
 digitalWrite(g,LOW);
 delay(500);
  }

        if(gg==1)
  {
    slvg=0;
    gg=0;
    DMD_TextBox box(dmd, 45, 0);
    box.print("G");
 digitalWrite(a,LOW);
 digitalWrite(b,LOW);
 digitalWrite(c,LOW);
 digitalWrite(d,LOW);
 digitalWrite(e,LOW);
 digitalWrite(f,LOW);
 digitalWrite(g,LOW);
 delay(500);
  }
  toplam=slva+slvb+slvc+slvd+slve+slvf+slvg;

box.clear();
box.print(toplam);

if (Serial.available() > 0)
{
bosalt=Serial.read();
}
else
{

if(level==1)
{
aa=1;
slva=0;
digitalWrite(a,HIGH);



}

if(level==2)
{
bb=1;
slvb=0;
digitalWrite(b,HIGH);


}

if(level==3)
{
cc=1;
slvc=0;
digitalWrite(c,HIGH);


}

if(level==4)
{
dd=1;
slvd=0;
digitalWrite(d,HIGH);


}

if(level==5)
{
ee=1;
slve=0;
digitalWrite(e,HIGH);
digitalWrite(e,HIGH);


}

if(level==6)
{
ff=1;
slvf=0;
digitalWrite(f,HIGH);


}

if(level==7)
{
gg=1;
slvg=0;
digitalWrite(g,HIGH);


}
delay(1000);
level++;
if(level>=8) level=1;

    }
}

void serialEvent() {
 digitalWrite(a,LOW);
 digitalWrite(b,LOW);
 digitalWrite(c,LOW);
 digitalWrite(d,LOW);
 digitalWrite(e,LOW);
 digitalWrite(f,LOW);
 digitalWrite(g,LOW);

byte sonuc=0;
high=0;
low=0;
sayac =0;
if (Serial.available() > 0)
{
low= Serial.read();
high= Serial.read();
sonuc=Serial.read();

sayac=high;
sayac=sayac<<8;
sayac |=low;
high=0;
low=0;

if(sonuc==67)
{
  sonuc=0;
 
  if(aa==1){
  aa=0;
 slva=sayac;
 sayac=0;


}
  if(bb==1){
  bb=0;
 slvb=sayac;
 sayac=0;

}

  if(cc==1){
  cc=0;
 slvc=sayac;
 sayac=0;

}

  if(dd==1){
  dd=0;
 slvd=sayac;
 sayac=0;

}

  if(ee==1){
  ee=0;
 slve=sayac;
 sayac=0;

}

  if(ff==1){
  ff=0;
 slvf=sayac;
 sayac=0;

}

  if(gg==1){
  gg=0;
 slvg=sayac;
 sayac=0;

}

}
}
}

mg1980

İyi günler arkadaşlar,
Arduino Uno ile desimal 5 basamak yukarıda sunulan ilave devre ile external kesme yoluyla veri alımı denenen gönderici ve alıcı kodları aşağıdadır. Bazı arkadaşların işine yarayabilir.
GÖNDERME KODLARI:
//USART GÖNDERME ARDUİNO UNO..
//BU PROGRAM ARDUİNO UNO İLE USART HABERLEŞME GÖNDERME ÜNİTESİDİR.Çalışmada kullanılan bazı fazlalıklar silinmemiştir.LED vs.

const int BUTON1=4;
const int BUTON2=5;
const int BUTON3=3;
const int BUTON4=6;

const int LED=8;
const int LEDY=9;
const int LEDZ=10;
const int LEDX=13;

volatile unsigned long gonder;     //32 bit işaretsiz
volatile unsigned long  gelen;







void setup() 
{
  Serial.begin(9600);
  pinMode(BUTON1,INPUT_PULLUP);
  pinMode(BUTON2,INPUT_PULLUP);
  pinMode(BUTON3,INPUT_PULLUP);
  pinMode(BUTON4,INPUT_PULLUP);
  
  pinMode(2,INPUT);
  pinMode(LEDY,OUTPUT);
  pinMode(LEDZ,OUTPUT);
  
  pinMode(LED,OUTPUT);
  pinMode(LEDX,OUTPUT);
  
  digitalWrite(LED,LOW);
  digitalWrite(LEDX,LOW);
  digitalWrite(LEDY,LOW);
  digitalWrite(LEDZ,LOW);
  
 
 
}

void loop() 
{
    if(digitalRead(BUTON1)==LOW){    
    gonder=12;    
    delay(2000); // Buton paraziti için fazlaca yazılmıştır.
    Serial.print(gonder); //Serialwrite komutu göndermede çalışmıyor,karışık işaretler oluşuyor.!!!!!
    
  }

    if(digitalRead(BUTON2)==LOW){
    gonder=123;   
    delay(2000);
    Serial.print(gonder);
    
  }
  
  if(digitalRead(BUTON3)==LOW){
    gonder=1234;   
    delay(2000);
    Serial.print(gonder);
  }
  if(digitalRead(BUTON4)==LOW){
    gonder=12345;   
    delay(2000);
    Serial.print(gonder);
  }
  
  
  
  digitalWrite(LEDX,HIGH); //blink için
 
  for(int i=0;i<50;i++){
    delay(1);
  }
  digitalWrite(LEDX,LOW);
 
  for(int i=0;i<50;i++){
    delay(1);
  }
  
}
ALMA KODLARI:
//USART KESME..ALICI...ARDUİNO UNO...
// BU PROGRAM ALICI ARDUİNO TARAFIDIR.İŞLEM SONUCU PC'DE SERİAL MONİTÖRDE GÖRÜLEBİLİR.BUTON,LED GİBİ FAZLALIKLAR SİLİNMEMİŞTİR.
// YAPILAN TRANSİSTÖLÜ DEVRE SAYESİNDE EXTERNAL İNTERRUPT İLE desimal 5 basamak veri alınmıştır.Daha fazlası denenmemiştir.
const int BUTON1=4;
const int BUTON2=5;
const int LED=8;
const int LEDY=9;
const int LEDZ=10;
const int LEDX=13;

volatile unsigned long gonder;     //32 bit işaretsiz
volatile unsigned long  gelen;
volatile unsigned long  silme;
boolean t;







void setup() 
{
  Serial.begin(9600);
  pinMode(BUTON1,INPUT_PULLUP);
  pinMode(BUTON2,INPUT_PULLUP);
  pinMode(2,INPUT);
  pinMode(LEDY,OUTPUT);
  pinMode(LEDZ,OUTPUT);
  
  pinMode(LED,OUTPUT);
  pinMode(LEDX,OUTPUT);
  
  digitalWrite(LED,LOW);
  digitalWrite(LEDX,LOW);
  digitalWrite(LEDY,LOW);
  digitalWrite(LEDZ,LOW);
  
  attachInterrupt(0,kesme,CHANGE);     //RISING=Yükselen kenar,FALLING..düşen 
   
}

void loop() 
{
 
    if(t==1){
      
    
      while(Serial.available()>0){
        gelen=Serial.read();
      
       Serial.write(gelen);
       t=0;
       gelen=0;
      }
       delayMicroseconds(1);
    attachInterrupt(0,kesme,CHANGE);
   
    } 
  
  
  
  digitalWrite(LEDX,HIGH); //blink için
  for(int i=0;i<500;i++){
    delay(1);
  }
  digitalWrite(LEDX,LOW);
 
  for(int i=0;i<500;i++){
    delay(1);
  }
   
}



void kesme()   // Kesme fonksiyonu
{
             
 detachInterrupt(0);// Fonksiyon boyunca tekrar kesme oluşmaması için....KESME'yi KAPAT..
  
 t=1;
}