Ynt: PCF8574 Binary Converter nasıl yaparım?

Başlatan veliusta, 09 Mayıs 2014, 04:19:16

veliusta

#include <Wire.h>

const int LED1 = 2;
const int LED2 = 3;
const int LED3 = 4;
const int LED4 = 5;
const int LED5 = 6;
const int LED6 = 7;
const int LED7 = 8;
const int LED8 = 9;

byte iInput=0;

void setup()
{
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);
pinMode(LED4, OUTPUT);
pinMode(LED5, OUTPUT);
pinMode(LED6, OUTPUT);
pinMode(LED7, OUTPUT);
pinMode(LED8, OUTPUT);
Wire.begin();
}
     
    void loop()
    {
      Wire.requestFrom(32,1);// Begin transmission to PCF8574 with the buttons
      if(Wire.available())   // If bytes are available to be recieved
      {
        iInput = Wire.read();// Read a byte
      }
     
      if(iInput<255)         //If the value less than 255
      {
        if (iInput==254) // P0
        { 
          digitalWrite(LED1, HIGH);
          digitalWrite(LED2, LOW);
          digitalWrite(LED3, LOW);
          digitalWrite(LED4, LOW);
          digitalWrite(LED5, LOW);
          digitalWrite(LED6, LOW);
          digitalWrite(LED7, LOW);
          digitalWrite(LED8, LOW);
        }; 
        if (iInput==253) // P1
        { 
          digitalWrite(LED2, HIGH); 
        }; 
        if (iInput==251) // P2
        { 
          digitalWrite(LED3, HIGH); 
        }; 
        if (iInput==247) // P3
        { 
          digitalWrite(LED4, HIGH); 
        }; 
      }
    }


Arkadaşlar bu siteden bakarak yukarıdaki kodları yaptım; http://elger.org/wiki/projects/i2c_pcf8574_8bit_port_expander
Bu kadarını yapabildim.

Yapmak istediğim: Hangi butonlara basılırsa o Ledler yansın.

255 adet olasılık girmeden nasıl olacak?

mesaj birleştirme:: 09 Mayıs 2014, 18:23:28

İsiste Devreyi Çizdim;

polleme

Arduino'da maalesef 8 bitlik bit byte değerini bir porta aynen yazmak mümkün değil, Arduino'da 8 bitlik port yok zaten. IO portlarına tek tek ulaşılarak istenilen yapılıyor. PIC'e göre benim canımı sıkan en önemli eksiklik bu.

Şunu yapabilirsiniz: LED çıkışlarına da bir PCF8574 koyun, tuşlara bağladığınız PCF8574'ten okuduğunuz değeri aynen LED'lere bağlı PCF8574'e yazın. Böylece byte olarak ne okursanız onu yazdığınızda basılı tuşlara karşı gelen LED'ler yanacaktır. 

Kabil ATICI

#2
Atmel işlemcilerde Led'lerin parlak yanması için LED bağlantısın +5V'da olacak şekilde bağla. Sadece burada LED yanması(ışık vermesi) için lojik 0'a çekmen gerekir. Bu uyarıya göre programı oluşturuyorum

pragramı denemedim geri kalanını kendin tamamla
byte  deger=0;


          digitalWrite(LED1, HIGH);
          digitalWrite(LED2, HIGH);
          digitalWrite(LED3, HIGH);
          digitalWrite(LED4, HIGH);
          digitalWrite(LED5, HIGH);
          digitalWrite(LED6, HIGH);
          digitalWrite(LED7, HIGH);
          digitalWrite(LED8, HIGH);

deger=input & 0x01;
if(deger==0x01)
 { digitalWrite(LED1, LOW);}

deger=input & 0x02;
if(deger==0x02)
{  digitalWrite(LED2, LOW);}

deger=input & 0x04;
if(deger==0x04)
 { digitalWrite(LED3, LOW);}

deger=input & 0x08;
if(deger==0x08)
 { digitalWrite(LED4, LOW);}

deger=input & 0x10;
if(deger==0x10)
 { digitalWrite(LED5, LOW);}

deger=input & 0x20;
if(deger==0x20)
 { digitalWrite(LED6, LOW);}

deger=input & 0x40;
if(deger==0x40)
 { digitalWrite(LED7, LOW);}

deger=input & 0x80;
if(deger==0x80)
 { digitalWrite(LED8, LOW);}
ambar7

veliusta

#3
 @ambar7 simülasyonda sorun yok.
Teşekkürler.

mesaj birleştirme:: 09 Mayıs 2014, 23:07:31

@polleme

Dediğiniz yanlış. Bu işlem C# VB Basic gibi programlarda yapıldığını gördüm. Sadece matematik bilmek gerekiyor.

polleme

Alıntı yapılan: veliusta - 09 Mayıs 2014, 09:06:01
@ambar7 simülasyonda sorun yok.
Teşekkürler.

mesaj birleştirme:: 09 Mayıs 2014, 23:07:31

@polleme

Dediğiniz yanlış. Bu işlem C# VB Basic gibi programlarda yapıldığını gördüm. Sadece matematik bilmek gerekiyor.

C#, C ve Basic ile defalarca yaptım, hatta Assembler ile 50 sayfa kod içeren projem de var. Matematik sorunum yok ama bunun Arduino'da sorun olduğunu söyledim. Çünkü Arduino'da örneğin PIC'teki gibi 8 bitlik A, B, C gibi kapılar yok. Bir byte değerini doğrudan 8 bite yazamıyorsunuz. Sorun bu. Daha once incelemedi iseniz Arduino ve PIC'teki bir LCD uygulamaları arasındaki kod farklılıklarına bakın, ne demek istediğimi anlayacaksınız.

veliusta

@polleme evet hocam, Doğru.
Dediğinizi yanlış anlamışım.

Arduino da bunları yazılım ile yapmamız gerekiyor.

polleme

İşte iki adet PCF8574 veya bir adet MCP23017 ile dediğinizi yapabilirsiniz. Bir adet MCP23017 kullanırsanız bunun 8 bitine tuşarı, diğer 8 bitine LED'leri bağlarsınız, bir 8'den okuduğunuz veriyi diğer 8'e yazınca dediğiniz olur. Tek çipte ve Arduino'da sadece iki pin kullanarak işinizi yaparsınız.


veliusta

#7
Alıntı yapılan: polleme - 09 Mayıs 2014, 09:34:51
İşte iki adet PCF8574 veya bir adet MCP23017 ile dediğinizi yapabilirsiniz. Bir adet MCP23017 kullanırsanız bunun 8 bitine tuşarı, diğer 8 bitine LED'leri bağlarsınız, bir 8'den okuduğunuz veriyi diğer 8'e yazınca dediğiniz olur. Tek çipte ve Arduino'da sadece iki pin kullanarak işinizi yaparsınız.

Polleme hocam, dediğizi zaten yapmıştım ben. Amaç Öğrenmek. Birde böyle yapmayı deniyorum.

mesaj birleştirme:: 09 Mayıs 2014, 10:01:54

@ambar7 Hocam Teşekkürler Yaptım :D

#include <Wire.h>

const int LED1 = 2;
const int LED2 = 3;
const int LED3 = 4;
const int LED4 = 5;
const int LED5 = 6;
const int LED6 = 7;
const int LED7 = 8;
const int LED8 = 9;

byte iInput=0;
byte  a=0;
byte  b=0;
byte  c=0;
byte  d=0;
byte  e=0;
byte  f=0;
byte  g=0;
byte  h=0;
byte  x=0;

void setup()
{
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);
pinMode(LED4, OUTPUT);
pinMode(LED5, OUTPUT);
pinMode(LED6, OUTPUT);
pinMode(LED7, OUTPUT);
pinMode(LED8, OUTPUT);
Wire.begin();
}
     
    void loop()
    {
      Wire.requestFrom(32,1);// Begin transmission to PCF8574 with the buttons
      if(Wire.available())   // If bytes are available to be recieved
      {
        iInput = Wire.read();// Read a byte
      }
      
a=iInput & 0x01;
if(a==0x01)
{ 
 digitalWrite(LED1, LOW);
}
  else
{
 digitalWrite(LED1, HIGH);
}

b=iInput & 0x02;
if(b==0x02)
{ 
 digitalWrite(LED2, LOW);
}
  else
{
 digitalWrite(LED2, HIGH);
}

c=iInput & 0x04;
if(c==0x04)
{ 
 digitalWrite(LED3, LOW);
}
  else
{
 digitalWrite(LED3, HIGH);
}

d=iInput & 0x08;
if(d==0x08)
{ 
 digitalWrite(LED4, LOW);
}
  else
{
 digitalWrite(LED4, HIGH);
}

e=iInput & 0x10;
if(e==0x10)
{ 
 digitalWrite(LED5, LOW);
}
  else
{
 digitalWrite(LED5, HIGH);
}

f=iInput & 0x20;
if(f==0x20)
{ 
 digitalWrite(LED6, LOW);
}
  else
{
 digitalWrite(LED6, HIGH);
}

g=iInput & 0x40;
if(g==0x40)
{ 
 digitalWrite(LED7, LOW);
}
  else
{
 digitalWrite(LED7, HIGH);
}

h=iInput & 0x80;  //Binary:10000000 Decimal:128 Hexadecimal:80
if(h==0x80)
{ 
 digitalWrite(LED8, LOW);
}
  else
{
 digitalWrite(LED8, HIGH);
}
  }


Yaptım Çalışıyor ama Anlamadım. Biraz ne olduğunu anlatırmısın? 0xFF 'ten 0x80 seçiyoruz.. bir tek burasını anladım.
Kafama göre yaptım. Mutlaka eksiğim ve yanlışım vardır. Daha iyi nasıl yaparız?

Kabil ATICI

@polleme
Arduino'nun işlemcisi olarak Atmega328 ve diğer işlemci tiplerinde o sözünü ettiğiniz portlar var.

Arduino'nun üreticisi programlama açısından kendilerine göre bir yol izlemişler. Bu oyunun kurallarını koyan onlar.

İllede bir karşılaştırma yapacaksanız, hiç değilse Atmega ile PIC'i karşılaştırın.
ambar7

polleme

#9
Alıntı yapılan: ambar7 - 09 Mayıs 2014, 10:05:01
@polleme
Arduino'nun işlemcisi olarak Atmega328 ve diğer işlemci tiplerinde o sözünü ettiğiniz portlar var.

Arduino'nun üreticisi programlama açısından kendilerine göre bir yol izlemişler. Bu oyunun kurallarını koyan onlar.

İllede bir karşılaştırma yapacaksanız, hiç değilse Atmega ile PIC'i karşılaştırın.

Birebir katılıyorum. Sorun zaten Arduino için yaratılan kod sisteminde. Eğer Atmega328'i Arduino değil de MCU olarak kullanırsanız sorun kalmıyor.



mesaj birleştirme:: 09 Mayıs 2014, 10:09:19

Alıntı yapılan: veliusta - 09 Mayıs 2014, 09:49:07
Polleme hocam, dediğizi zaten yapmıştım ben. Amaç Öğrenmek. Birde böyle yapmayı deniyorum.

mesaj birleştirme:: 10 Mayıs 2014, 00:01:54


Yaptım Çalışıyor ama Anlamadım. Biraz ne olduğunu anlatırmısın? 0xFF 'ten 0x80 seçiyoruz.. bir tek burasını anladım.
Kafama göre yaptım. Mutlaka eksiğim ve yanlışım vardır. Daha iyi nasıl yaparız?

Bu koddaki her if satırı 8 bitin birini kontrol ediyor ve hangisi lojik 1 ise ona karşı gelen biti lojik 1 yapıyor. 0xFF demeden kastı ben de anlayamadım.

veliusta

0xFF hexadesimal sayısı örneği verdim. Hex sayıdan xx sayısını seçiyoruz.
Tamam Şuan Herşeyi anladım.

Herkese Teşekkürler. :)

Kabil ATICI

#11
@veliusta
Olayda bir şey yok; amaç veriyi bit olarak ayırıp incelemek.

Şimdi oradaki incelediğin tüm o değerleri binary olarak bakarsan
giriş baytının incelemesinde
0b00000001 ->0x01
0b00000010 ->0x02
0b00000100 ->0x04
0b00001000 ->0x08
0b00010000 ->0x10
...
şeklinde  gittiğini görürsün.
ilk önce istenilen bit VE işlemi ile izole ediliyor. Geri kalan bitler 0 oluyor. Karşılaştırma işleminde de bu bitin 1 olup olmadığı bakılıyor. Tabii bu işlem bayt bazında yapılıyor...

Else komutu ile uğraşmamak için
ben ilk başta tüm çıkışları sıfırlandı
sonraki değerlendirmede bu çıkışlar gerekli bitlerler tekrar 1 haline getirildi.
Normade işlemcinin çalışmasında bir kesilme olmadıkça bu çıkıştaki kesintiler (sıfırlanma hali) görülmez.
ambar7

veliusta

#12
#include <Wire.h>

const int LED1 = 2;
const int LED2 = 3;
const int LED3 = 4;
const int LED4 = 5;
const int LED5 = 6;
const int LED6 = 7;
const int LED7 = 8;
const int LED8 = 9;

byte iInput=0;
byte deger;

void setup()
{
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);
pinMode(LED4, OUTPUT);
pinMode(LED5, OUTPUT);
pinMode(LED6, OUTPUT);
pinMode(LED7, OUTPUT);
pinMode(LED8, OUTPUT);
Wire.begin();
}
    void loop()
    {
      Wire.requestFrom(32,1);// Begin transmission to PCF8574 with the buttons
      if(Wire.available())   // If bytes are available to be recieved
      {
        iInput = Wire.read();// Read a byte
      }
      
 if(iInput<=255)         //If the value less than 255
      {
      
deger=iInput & 0x01;
if(deger==0x01)
{ 
 digitalWrite(LED1, LOW);
}
  else
{
 digitalWrite(LED1, HIGH);
}

deger=iInput & 0x02;
if(deger==0x02)
{ 
 digitalWrite(LED2, LOW);
}
  else
{
 digitalWrite(LED2, HIGH);
}

deger=iInput & 0x04;
if(deger==0x04)
{ 
 digitalWrite(LED3, LOW);
}
  else
{
 digitalWrite(LED3, HIGH);
}

deger=iInput & 0x08;
if(deger==0x08)
{ 
 digitalWrite(LED4, LOW);
}
  else
{
 digitalWrite(LED4, HIGH);
}

deger=iInput & 0x10;
if(deger==0x10)
{ 
 digitalWrite(LED5, LOW);
}
  else
{
 digitalWrite(LED5, HIGH);
}

deger=iInput & 0x20;
if(deger==0x20)
{ 
 digitalWrite(LED6, LOW);
}
  else
{
 digitalWrite(LED6, HIGH);
}

deger=iInput & 0x40;
if(deger==0x40)
{ 
 digitalWrite(LED7, LOW);
}
  else
{
 digitalWrite(LED7, HIGH);
}

deger=iInput & 0x80;  //Binary:10000000 Decimal:128 Hexadecimal:80
if(deger==0x80)
{ 
 digitalWrite(LED8, LOW);
}
  else
{
 digitalWrite(LED8, HIGH);
}
}
}


Bitmiş Çalışan Kodlar. Mutlaka birinin ihtiyacı olur.

mesaj birleştirme:: 09 Mayıs 2014, 10:34:32

Yeni birşey yapmak istedim yapamadım.

Terminalden sadece birkez göndermesini istiyorum. Nasıl yaparım?
Sürekli gönderiyor. 1.2.3 Kapalı diye..

#include <Wire.h>

const int LED1 = 2;
const int LED2 = 3;
const int LED3 = 4;
const int LED4 = 5;
const int LED5 = 6;
const int LED6 = 7;
const int LED7 = 8;
const int LED8 = 9;

byte iInput=0;
byte deger;

void setup()
{
Serial.begin(9600);
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);
pinMode(LED4, OUTPUT);
pinMode(LED5, OUTPUT);
pinMode(LED6, OUTPUT);
pinMode(LED7, OUTPUT);
pinMode(LED8, OUTPUT);
Serial.println(" iyi Eglenceler / Veli USTA ");
Wire.begin();
}
    void loop()
    {
      Wire.requestFrom(32,1);// Begin transmission to PCF8574 with the buttons
      if(Wire.available())   // If bytes are available to be recieved
      {
        iInput = Wire.read();// Read a byte
      }
      
 if(iInput<=255)         //If the value less than 255
      {
      
deger=iInput & 0x01;
if(deger==0x01)
{ 
 digitalWrite(LED1, LOW);
 Serial.println("1.LED KAPATILDI");
}
  else
{
 digitalWrite(LED1, HIGH);
 Serial.println("1.LED ACILDI");
}

deger=iInput & 0x02;
if(deger==0x02)
{ 
 digitalWrite(LED2, LOW);
 Serial.println("2.LED KAPATILDI"); 
}
  else
{
 digitalWrite(LED2, HIGH);
 Serial.println("2.LED ACILDI"); 
}

deger=iInput & 0x04;
if(deger==0x04)
{ 
 digitalWrite(LED3, LOW);
 Serial.println("3.LED KAPATILDI");
}
  else
{
 digitalWrite(LED3, HIGH);
 Serial.println("3.LED ACILDI"); 
}

deger=iInput & 0x08;
if(deger==0x08)
{ 
 digitalWrite(LED4, LOW);
 Serial.println("4.LED KAPATILDI");
}
  else
{
 digitalWrite(LED4, HIGH);
 Serial.println("4.LED ACILDI"); 
}

deger=iInput & 0x10;
if(deger==0x10)
{ 
 digitalWrite(LED5, LOW);
 Serial.println("5.LED KAPATILDI");
}
  else
{
 digitalWrite(LED5, HIGH);
 Serial.println("5.LED ACILDI"); 
}

deger=iInput & 0x20;
if(deger==0x20)
{ 
 digitalWrite(LED6, LOW);
 Serial.println("6.LED KAPATILDI");
}
  else
{
 digitalWrite(LED6, HIGH);
 Serial.println("6.LED ACILDI"); 
}

deger=iInput & 0x40;
if(deger==0x40)
{ 
 digitalWrite(LED7, LOW);
 Serial.println("7.LED KAPATILDI");
}
  else
{
 digitalWrite(LED7, HIGH);
 Serial.println("7.LED ACILDI"); 
}

deger=iInput & 0x80;  //Binary:10000000 Decimal:128 Hexadecimal:80
if(deger==0x80)
{ 
 digitalWrite(LED8, LOW);
 Serial.println("8.LED KAPATILDI"); 
}
  else
{
 digitalWrite(LED8, HIGH);
 Serial.println("8.LED ACILDI"); 
}
}
}

Kabil ATICI

#13
Her bir led için değişken atıyorsun,
byte  degLed1=0;


deger=iInput & 0x01;
if((deger==0x01) && (deger !=degLed1))  //karşılaştırma
{
digitalWrite(LED1, LOW);
Serial.println("1.LED KAPATILDI");
deger =degLed1;
}
  else
{
digitalWrite(LED1, HIGH);
Serial.println("1.LED ACILDI");
deger =degLed1;
}
ambar7

veliusta

#14
Eskisinden farkı yok;
olmadı.

#include <Wire.h>

const int LED1 = 2;
const int LED2 = 3;
const int LED3 = 4;
const int LED4 = 5;
const int LED5 = 6;
const int LED6 = 7;
const int LED7 = 8;
const int LED8 = 9;

byte iInput=0;
byte deger;
byte degLed1=0;
byte degLed2=0;
byte degLed3=0;
byte degLed4=0;
byte degLed5=0;
byte degLed6=0;
byte degLed7=0;
byte degLed8=0;

void setup()
{
Serial.begin(9600);
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);
pinMode(LED4, OUTPUT);
pinMode(LED5, OUTPUT);
pinMode(LED6, OUTPUT);
pinMode(LED7, OUTPUT);
pinMode(LED8, OUTPUT);
Serial.println(" iyi Eglenceler / Veli USTA ");
Wire.begin();
}
    void loop()
    {
      Wire.requestFrom(32,1);
      if(Wire.available())   
      {
        iInput = Wire.read();
      }
      
 if(iInput<=255)      
      {
      
deger=iInput & 0x01;
if((deger==0x01) && (deger !=degLed1)) 
{ 
 digitalWrite(LED1, LOW);
 Serial.println("1.LED KAPATILDI");
 deger =degLed1;
}
  else
{
 digitalWrite(LED1, HIGH);
 Serial.println("1.LED ACILDI");
 deger =degLed1;
}

deger=iInput & 0x02;
if((deger==0x02) && (deger !=degLed2)) 
{ 
 digitalWrite(LED2, LOW);
 Serial.println("2.LED KAPATILDI"); 
 deger =degLed2;
}
  else
{
 digitalWrite(LED2, HIGH);
 Serial.println("2.LED ACILDI");
 deger =degLed2;
}

deger=iInput & 0x04;
if((deger==0x04) && (deger !=degLed3)) 
{ 
 digitalWrite(LED3, LOW);
 Serial.println("3.LED KAPATILDI");
 deger =degLed3;
}
  else
{
 digitalWrite(LED3, HIGH);
 Serial.println("3.LED ACILDI"); 
 deger =degLed3;
}

deger=iInput & 0x08;
if((deger==0x08) && (deger !=degLed4)) 
{ 
 digitalWrite(LED4, LOW);
 Serial.println("4.LED KAPATILDI");
 deger =degLed4;
}
  else
{
 digitalWrite(LED4, HIGH);
 Serial.println("4.LED ACILDI"); 
 deger =degLed4;
}

deger=iInput & 0x10;
if((deger==0x10) && (deger !=degLed5)) 
{ 
 digitalWrite(LED5, LOW);
 Serial.println("5.LED KAPATILDI");
 deger =degLed5;
}
  else
{
 digitalWrite(LED5, HIGH);
 Serial.println("5.LED ACILDI"); 
 deger =degLed5;
}

deger=iInput & 0x20;
if((deger==0x20) && (deger !=degLed6)) 
{ 
 digitalWrite(LED6, LOW);
 Serial.println("6.LED KAPATILDI");
 deger =degLed6;
}
  else
{
 digitalWrite(LED6, HIGH);
 Serial.println("6.LED ACILDI"); 
 deger =degLed6;
}

deger=iInput & 0x40;
if((deger==0x40) && (deger !=degLed7)) 
{ 
 digitalWrite(LED7, LOW);
 Serial.println("7.LED KAPATILDI");
 deger =degLed7;
}
  else
{
 digitalWrite(LED7, HIGH);
 Serial.println("7.LED ACILDI"); 
 deger =degLed7;
}

deger=iInput & 0x80;  //Binary:10000000 Decimal:128 Hexadecimal:80
if((deger==0x80) && (deger !=degLed8)) 
{ 
 digitalWrite(LED8, LOW);
 Serial.println("8.LED KAPATILDI");
 deger =degLed8;
}
  else
{
 digitalWrite(LED8, HIGH);
 Serial.println("8.LED ACILDI");
 deger =degLed8;
}
}
}


mesaj birleştirme:: 10 Mayıs 2014, 02:05:14

iç içe if te denedim. for döngüsüde yaptım olmuyor.

mesaj birleştirme:: 09 Mayıs 2014, 12:09:24

Tek çaresi  if(iInput<=255) bu kodun üstüne

if(iInput herhangi bir değişiklik yapıldığında)

böyle olursa olur.