# Συζήτηση για... > Ερωτήσεις Αρχάριων >  >  i2c Πρωτόκολλο, Απορίες, Προβληματισμοί

## acmilangr

Λοιπόν έχω το 24C64 eeprom τσιπάκι

(http://www.datasheetcatalog.org/data.../227040_DS.pdf)

διάβασα αρκετά για αυτό το eeprom και έμαθα κάποια πράγματα, 

Θέλω να το συνδέσω σειρακά με τον μικροελενκτή μου (arduino) και να μπορώ να γράφω και να διαβάζω κάποια bytes που θέλω

γνωρίζω πως μέσω I2C πρωτοκόλλου μπορώ με τα 2 pin του να γράψω και να διαβάσω τα δεδομένα που θέλω. 

Η διαδικασία γίνεται μέσω του SCL και SDA pin μέσω μίας σειράς εντολών.
το SDA ειναι αυτό που μεταφέρει τα bits ενώ το SCL ειναι το clock το οποίο θα πρέπει να γίνεται high και low κάθε φορά που το SDA στέλνει 1 bit

πχ για το 1ο βήμα start ο Microελενκτής θα πρέπει να στέλνει στο EEPROM τα bit κάπως έτσι 
DigitalWrite SDA,1
DigitalWrite SCL,1 
DigitalWrite SDA,0 
DigitalWrite SCL,0
(το γράφω έτσι απλά για να είναι πιο εύκολο στην ανάγνωση)
Αυτό το βήμα όπως και στο Stop δεν έχω καμία απορία. Ψάχνοντας στο Internet το κατάλαβα ειναι εύκολο όπως επίσης και να στέλνω τiς adresses και τα data bit.
*
Το πρόβλημα μου ειναι τα Acknowledge Bit (ACK). Εκεί λίγο μπερδεύομαι στο πως λειτουργεί. 

Επίσης πώς γίνεται να λάβω τα bit; ο microελενκτής μου στο setup void έχει επιλεχτει ώστε τα 2 pins να ειναι output,θα πρέπει όταν ειναι να διαβάζει τα δεδομένα να τα αλάξω σε input; Γίνεται αυτό;  Επίσης καπου είχα διαβάσει ότι πρίν διαβάσω τα bits που στέλνει ο slave θα πρέπει ο Microελενκτής να σταματήσει να στέλνει δεδομένα (λογικό ειναι το ξέρω αφου θα πρέπει να δέχεται εκείνη την στιγμή). Αλλα πως γίνεται τα pins να ειναι "νεκρά;" δηλαδή να μην στέλνουν ούτε 0 ούτε 1;**

σκέφτηκα να συνδέσω τα pins του eeprom παράλληλα σε 2 ακόμα pins του arduino όπου θα είναι Input αλλα αν τότε θα διαβάζουν εκτός τα bit του eeprom τα pin του output του arduino!!

βοηθήστε με σας παρακαλώ, Με απλά λόγια τύπου SDA,0  CSL,1 κάντε με να καταλάβω όλη την διαδικασία*

----------


## klik

Δεν μπορώ να σου πω για arduino συγκεκριμένα γιατί δεν το έχω δουλέψει.

Για τις απορίες σου:
α) ναι για να διαβάσεις μπορείς να κάνεις την ακίδα SDA input και να διαβάσεις είτε το ACK bit είτε τα δεδομένα που έρχονται απο το eeprom.
β) μια άλλη λύση είναι να έχεις δυο ακίδες για το SDA. Μια που να είναι είσοδος και μια έξοδος. 
Η ακίδα SDAout θα πρέπει να συνδεθεί με OpenCollector τύπο στη γραμμή SDA (ή πιο απλά με την κάθοδο μιας διόδου 1Ν4148 της οποίας η άνοδος θα είναι συνδεδεμένη στη γραμμή SDA).
Πριν διαβάσεις δεδομένα, θα κάνεις το SDAout 1(αν έχεις δίοδο 1Ν4148 ) ή 0 (αν έχεις συνδέσει bc547 σαν NOT), ωστε να αφήνει τη γραμμη SDA ελεύθερη για να μπορεί να στέλνει το eeprom και να διαβάζει η ακίδα σου SDAinput.

γ) το ACK είναι σήμα επιβεβαίωσης:
όταν ζητάς απο την eeprom να γράψει κάτι και της στέλνεις ένα byte αυτή θα στο επιβεβαιώσει στέλνοντας σου αυτό το bit (τιμή 0). Αν δεν έρθει 0, δεν πήρε το byte η eeprom.
οταν ζητάς απο την eeprom να σου στείλει byte, πρέπει εσύ να επιβεβαιώσεις ότι το πήρες για να σου στείλε το επόμενο. Προσοχή αν δεν θέλεις να πάρεις άλλο byte ΔΕΝ επιβεβαιώνεις και στέλνεις απ'ευθείας STOP

----------


## acmilangr

> Δεν μπορώ να σου πω για arduino συγκεκριμένα γιατί δεν το έχω δουλέψει.
> 
> Για τις απορίες σου:
> α) ναι για να διαβάσεις μπορείς να κάνεις την ακίδα SDA input και να διαβάσεις είτε το ACK bit είτε τα δεδομένα που έρχονται απο το eeprom.
> β) μια άλλη λύση είναι να έχεις δυο ακίδες για το SDA. Μια που να είναι είσοδος και μια έξοδος. 
> Η ακίδα SDAout θα πρέπει να συνδεθεί με OpenCollector τύπο στη γραμμή SDA (ή πιο απλά με την κάθοδο μιας διόδου 1Ν4148 της οποίας η άνοδος θα είναι συνδεδεμένη στη γραμμή SDA).
> Πριν διαβάσεις δεδομένα, θα κάνεις το SDAout 1(αν έχεις δίοδο 1Ν4148 ) ή 0 (αν έχεις συνδέσει bc547 σαν NOT), ωστε να αφήνει τη γραμμη SDA ελεύθερη για να μπορεί να στέλνει το eeprom και να διαβάζει η ακίδα σου SDAinput.
> 
> γ) το ACK είναι σήμα επιβεβαίωσης:
> ...



Ευχαριστώ για την απάντηση σου. 

εχω και άλλους προβληματισμούς:
*1) Device Select Code* 
Πρίν στείλω την adress θα πρέπει να στείλω με 0 και 1 σε ποια device θέλω; Μπορεί να ειναι οποιαδήποτε;

2) Πότε η eeprom μου στέλνει τα bits; ακριβώς μόλις απαντήσω; ποια στιγμή εγώ θα πρέπει να αλάξω την είσοδο;

αν θα μπορούσες με λειτουργικούς απλούς τρόπους να μου έδειχνες όλοκληρωμένο τον κώδικα με όλη την διαδικασία ώστε να διαβάσω μία μνήμη θα πήγαινα στο άγιο όρος και θα σου άναβα λαμπάδα!!

δεν θέλω τίποτα το ιδιαίτερο κατι σαν αυτό

step 1
SCL 1
CLK 0
--------

step 2
SCL 1
CLK 1
CLK 0

κτλ

----------


## klik

> ...αν θα μπορούσες με λειτουργικούς απλούς τρόπους να μου έδειχνες όλοκληρωμένο τον κώδικα με όλη την διαδικασία ώστε να διαβάσω μία μνήμη θα πήγαινα στο άγιο όρος και θα σου άναβα λαμπάδα!!...



έχω μέσο στο Αγιο Όρος, θα το ελέγξω! :Rolleyes: 




```
//o κώδικας είναι C απο 8051 compatible processor

//all commands after START leave BUS in SCL=0
//START waits BUS to be 1,1
//RepStart waits BUS to be SCL=0,SDA=?

#define I2C_delay()	_nop_()

#define Set_SCL_0	P3_3=0	//i2c communications
#define Set_SCL_1	P3_3=1	//i2c communications
#define Set_SDA_0	P3_4=0	//i2c communications
#define	Set_SDA_1	P3_4=1
#define	Is_SDA_1	P3_4

void init_i2c(void){ 
           Set_SDA_1; 
           Set_SCL_1; 
}

#define I2C_START		{ /*assume SDA==1*/ Set_SDA_0; I2C_delay(); Set_SCL_0; }

#define I2C_STOP		{ /*assume SCL==0*/ Set_SDA_0; Set_SCL_1; I2C_delay(); Set_SDA_1; }

#define I2C_RepSTART		{ /*assume SCL==0*/ Set_SDA_1; Set_SCL_1; I2C_delay(); I2C_START; }

void I2C_put_bit(bool a){//στείλε ένα bit
	if(a) 
		Set_SDA_1;
	else
		Set_SDA_0;
	Set_SCL_1;
	I2C_delay();
	Set_SCL_0;
}

byte _I2C_read_noack(void){
	//διαβασε 1 byte και μην στείλεις επιβεβαιωση
	byte k=0,i;
	for(i=8;i!=0;i--){
		k<<=1;
		{ //read a bit
			Set_SDA_1; Set_SCL_1; I2C_delay();
			if(Is_SDA_1)
				k |= 1;
			Set_SCL_0; }
		}
	}
	//I2C_put_bit(FALSE);//ack
	return k;
}

byte I2C_read_sendack(void){
	//διαβασε 1 byte και στείλε επιβεβαιωση
           byte b =_I2C_read_noack();
           I2C_put_bit(FALSE); 
           return b;
}

bool I2C_write_waitack(byte b){
	byte i;
	for(i=8;i!=0;i--){
		I2C_put_bit((b&0x80));
		b <<= 1;
	}
	//wait acknowledgment	
	{//διαβασε την επιβεβαιωση (0 σημαίνει ηρθε)
		Set_SDA_1; Set_SCL_1; I2C_delay();
		i = TRUE;
		if(Is_SDA_1)
			i = FALSE;	//not aknowledged
		Set_SCL_0; 
	}
	return i;//επέστρεψε TRUE αν έγινε επιβεβαιωση
}
```


Να και ένα παράδειγμα που διάβαζα και έγραφα τιμές απο ένα 24c02



```
void ReadStoredValues(void){
	//use i2c to read values from 24cxx
	I2C_START;
		I2C_write_waitack(0xa0);		//device address + write request
		I2C_write_waitack(EEpromStartAddr);	//word address to start read
	I2C_RepSTART;
		I2C_write_waitack(0xa1);		//device address + read request
		I2C_read_sendack(uVal.Val[fvac1].b.lo);
		I2C_read_sendack(uVal.Val[fvac1].b.hi);
		I2C_read_sendack(uVal.Val[fvac2].b.lo);
		I2C_read_sendack(uVal.Val[fvac2].b.hi);
		I2C_read_sendack(uVal.Val[fexp1].b.lo);
		I2C_read_sendack(uVal.Val[fexp1].b.hi);
		I2C_read_sendack(uVal.Val[fexp2].b.lo);
		I2C_read_noack  (uVal.Val[fexp2].b.hi);
	I2C_STOP;
}
	I2C_START;
		I2C_write_waitack(0xa0);		//device address + write request
		I2C_write_waitack(EEpromStartAddr);	//word address to start read
		I2C_write_waitack(uVal.Val[fvac1].b.lo);
		I2C_write_waitack(uVal.Val[fvac1].b.hi);
		I2C_write_waitack(uVal.Val[fvac2].b.lo);
		I2C_write_waitack(uVal.Val[fvac2].b.hi);
		I2C_write_waitack(uVal.Val[fexp1].b.lo);
		I2C_write_waitack(uVal.Val[fexp1].b.hi);
		I2C_write_waitack(uVal.Val[fexp2].b.lo);
		I2C_write_waitack(uVal.Val[fexp2].b.hi);
	I2C_STOP;
```


Έκανα μερικές τροποποιήσεις στο γράψιμο της απάντησης, βγάζοντας κάποιες inline συναρτήσεις με χρήση define για ευκολότερη ανάγνωση, οπότε ίσως να υπάρχουν μικρά συντακτικά λάθη στον κώδικα. Δεν υπάρχουν όμως λογικά λάθη, ο κώδικας περιγράφει ακριβώς τι πρέπει να γίνει.

----------


## klik

offtopic: Απο χιόνι πως πάτε; λέω να παω αύριο προς Σέλι.

----------


## acmilangr

gmt. Γιατί να ειμαι τόσο άσχετος με τις γλώσες;!!!

άκρη δεν βγάζω....
δεν γίνεται κάπως έτσι;;; μετά εγώ ξέρω να κάνω την μετάφραση....
step 1
SCL 1
CLK 0
--------

step 2
SCL 1
CLK 1
CLK 0

----------


## acmilangr

> offtopic: Απο χιόνι πως πάτε; λέω να παω αύριο προς Σέλι.



ϊσως και να έχει... αλλα δεν ειναι σίγουρο, στον βόρα σίγουρα

----------


## klik

> gmt. Γιατί να ειμαι τόσο άσχετος με τις γλώσες;!!!
> 
> άκρη δεν βγάζω....



ξεκίνα απο τα απλά



```
	I2C_START;	//κάνε start
	I2C_write_waitack(0xa0);//γράψε το byte 0xa0 (device address select+ write request) και διάβασε και την επιβεβαιωση απο την eeprom
	I2C_write_waitack(0);	//γράψε την διευθυνση που θέλω να κεκινησω το διάβασμα και διάβασε και την επιβεβαιωση απο την eeprom
	I2C_RepSTART;//γράψε το byte 0xa0 (device address select+ READ request)
	I2C_write_waitack(0xa1);		//device address + read request και διάβασε και την επιβεβαιωση απο την eeprom
	x = I2C_read_sendack();//διάβασε στη μεταβλητή x το περιεχόμενο της eeprom (θέση 0) και στείλε επιβεβαιωση (ack)
	y = I2C_read_sendack();//διάβασε στη μεταβλητή y το περιεχόμενο της eeprom (θέση 1) και στείλε επιβεβαιωση (ack)
	z = I2C_read_nodack();//διάβασε στη μεταβλητή y το περιεχόμενο της eeprom (θέση 2) και MHN στείλεις επιβεβαιωση (ack)
	I2C_STOP;
```

----------


## acmilangr

> ξεκίνα απο τα απλά
> 
> 
> 
> ```
>     I2C_START;    //κάνε start
>     I2C_write_waitack(0xa0);//γράψε το byte 0xa0 (device address select+ write request) και διάβασε και την επιβεβαιωση απο την eeprom
>     I2C_write_waitack(0);    //γράψε την διευθυνση που θέλω να κεκινησω το διάβασμα και διάβασε και την επιβεβαιωση απο την eeprom
>     I2C_RepSTART;//γράψε το byte 0xa0 (device address select+ READ request)
> ...



ωραια αλλα ο λόγος που θέλω να μου πεί κάποιος την διαδικασία βήμα βήμα ειναι για να μάθω ακριβώς πως λειτουργεί το i2c

Οπως και να έχει βέβαια με βοήθησε πολύ, Θα ψαχτώ να μεταφράσω

----------


## ALAMAN

Συγνώμη αν θα βγώ εκτός θέματος, αλλά τί είναι το πρωτόκολλο i2c?
Τον έχω συναντήσει πολλές φορές αυτόν τον όρο, όπως και τον όρο "διάδρομος i2c".  :Huh:

----------


## acmilangr

δεν βγάζω άκρη κλαψ!

----------


## chip

δύο πιν σου χρειάζονται μόνο.
όταν θέλεις είσοδο είναι είσοδος. 
όταν θέλεις έξοδο (να στείλει ο μικροελεγκτής) το SDA με λογικό 0 το κάνεις έξοδο με λογικό μηδέν.
όταν θέλεις έξοδο (να στείλει ο μικροελεγκτής) το SDA με λογικό 1 απλά το κάνεις είσοδο όποτε παίρνει λογικό 1 από την pull-up αντίσταση. (επίσης καλό είναι να βάλεις εξωτερική pull-up γιατί το μικροελεγκτή ίσως να είναι λίγο "αδύναμη" ιδιαίτερα αν κάνεις την επικοινωνία σε υψηλή ταχύτητα.
Μετά από κάθε 8 Bit ο δέκτης (η μνήμη κατά τη διάρκεια εγγραφής ο μικροελεγκτής κατά τη διάρκεια ανάγνωσης) στέλνει το ack που είναι '0'. Για το σκοπό αυτός που στέλνει μετά από κάθε 8bit πρέπει να απελευθερώσει το sda ώστε ο δέκτης να επιβεβαιώσει οτι είναι δέχεται ack (λογικό 0).

----------


## gsmaster

Ο μικροελεκτής σου είναι πάντα αυτός που κανονίζει τα πάντα στην επικοινωνία (MASTER). 
Όταν θέλεις να στείλεις, βάζεις ένα ένα τα bit στο SDA και ενώ αλλάζεις και το CLK σε κάθε bit. 
Όταν θέλεις να λάβεις, διαβάζεις απο το SDA και αλλάζεις το CLK για να λάβεις κάθε bit. 

Αυτό που ίσως δεν κατάλαβες είναι ότι το CLK δεν αλλάζει κατεύθυνση. Πάντα είναι έξοδος του μικροελεκτή και είσοδος στην eeprom. Το SDA αλλάζει ανάλογα αν θες να στείλεις ή να λάβεις. 

Τις περισσότερες φορές σε μια επικοινωνία, πρέπει να στείλεις πρώτα μια εντολή που να "λέει" στο τσιπάκι να σου στείλει δεδομένα, αυτό θα το δείς στο εκάστοτε datasheet. 

Πολύ καλή αναλυση του πρωτοκόλλου επικοινωνίας εχουν τα datasheet της MAXIM. Κάποτε είχα κάνει απο την αρχή σε assembly κώδικα για να διαβάζω θερμοκρασία απο το DS1620 χρησιμοποιόντας μόνο πληροφορίες απο το datasheet.  :Wink:

----------


## acmilangr

Λοιπόν θα σας πώ τι έχω κάνει μέχρι τώρα.
έχω συνδέσει το 24c64  (http://www.datasheetcatalog.org/data.../227040_DS.pdf) ως εξής:

Εχω συνδέσει τα PIN E0,E1,E2 (Chip Enable Address)  του Epprom στην γή "-". και τα SDA,SCL ώς εξής:




Έτσι όταν θέλω να στείλω τα δεδομένα τα στέλνω μέσω του SC_OUT ενώ όταν θέλω να διαβάσω τα δεδομένα τα διαβάζω μέσω του SCL_IN (αφού έχω δώσει high στο SC_OUT ώστε η δίοδος να μην δώσει κανένα "σήμα", σωστα :Wink: 

Τώρα πάμε στο arduino. Ακόμα και να μήν ξέρετε την γλώσα το γράφω τόσο απλά που πιστεύω όλοι θα το καταλάβετε

int SCL_OUT = 5;
 int SDA_INP = 6;
int SDA_OUT = 7;
//εδώ δήλωσα τα pin του arduino


 int TEST_LED = 8;
//εδώ δήλωσα το pin 8 το οποίο το έχω συνδεμένο με ενα LED. Ο λόγος ειναι ότι για να δοκιμάζω αν ανταποκρίνεται το eeprom, (δηλαδή το ack)




 void setup() 
{      
  pinMode(SCL_OUT, OUTPUT);
  pinMode(SDA_INP, INPUT);
  pinMode(SDA_OUT, OUTPUT);

  pinMode(TEST_LED, OUTPUT);
//εδώ δήλωσα ποια Pin θα ειναι output και ποια input
  }

void loop() {
i2c_start();                   //1.Στάδιο Εκίνησης
i2c_send_device_code(); //2.Στάδιο Αποστολής Κώδικα Συσκευής
i2c_write_bit();             //3.Στάδιο Αποστολής Bit Εγγραφής
i2c_acknowledge();        //4.Στάδιο Αναμονής Απάντησης
//εδώ ξεκινάνε οι εντολές του arduino. Το πρόγραμμα θέλει να γράψει στην eeprom δεδομένα, γνωρίζω πως τα στάδια δεν είναι μόνο αυτά, αλλα για λόγους ευκολίας σταμάτησα στο στάδιο αναμονής απάντησης που εκεί έχω το πρόβλημα.
  while(1) { }
//αυτή η εντολή ειναι απλά για να σταματήσει το loop
}



void i2c_start() { //Στάδιο Εκίνησης
  digitalWrite (SDA_OUT,1); 
  i2c_delay();
  digitalWrite (SCL_OUT,1); 
  i2c_delay();
  digitalWrite (SDA_OUT,0); 
  i2c_delay();
  digitalWrite (SCL_OUT,0);   
    }
  //πρώτο στάδιο, νομίζω δεν έχω λάθος. το i2c_delay είναι ανάμεσα σε όλες τις εντολές γιατί θα πρέπει να υπάρχει μια μικρή καθυστέριση

void i2c_send_device_code() {   //Στάδιο Αποστολής Κώδικα Συσκευής 
   digitalWrite (SDA_OUT,1);   
    i2c_delay();
    i2c_pulse();
   digitalWrite (SDA_OUT,0);    
    i2c_delay();
    i2c_pulse();
   digitalWrite (SDA_OUT,1);    
    i2c_delay();
    i2c_pulse();
   digitalWrite (SDA_OUT,0);    
    i2c_delay();
     i2c_pulse();
    digitalWrite (SDA_OUT,1);    
    i2c_delay();
    i2c_pulse();
    digitalWrite (SDA_OUT,1);    
    i2c_delay();
    i2c_pulse();
    digitalWrite (SDA_OUT,1);    
    i2c_delay();
    i2c_pulse();

//εδώ στέλνω τα bit 1010111, δεν είμαι σίγουρος αν έκανα σωστά αλλα απο όσο διαβασα στο datasheet τα 4 πρώτα θα πρέπει να ειναι 1010 και τα υπόλοιπα 3 να ειναι ανάλογα τα pin, και εφόσων εγώ τα έχω και τα 3 στην γή τα έδωσα 1.

το i2c_pulse επίσης ειναι το void για να στέλνει εναν παλμό μετά απο κάθε αποστολή δεδομένων.
}



 void i2c_write_bit() { //Στάδιο Αποστολής Bit Εγγραφής
 digitalWrite(SDA_OUT,0);

 i2c_delay();
 i2c_pulse();
//εδώ απλά στέλνω 0 για να του πώ ότι θα γράψω
}
 void i2c_acknowledge(){  //Στάδιο Αναμονής Απάντησης
Εδώ επίσης θέλω να ξέρω αν το έχω κάνει σωστά


   digitalWrite (SDA_OUT,1); //Δίνω 1 στην έξοδο ώστε να μπορεί το eeprom να στείλει σήμα το ACK (με την βοήθεια της διόδου)
  i2c_delay();
  digitalWrite (SCL_OUT,1);  //στέλνω εναν παλμό 1 στο SCL ώστε να διαβάσει το SDA_INP το acc του eeprom σωστά;

  temp = digitalRead(SDA_INP); //αποθηκεύω στην μεταβλητή temp τα δεδομένα που θα στείλει η epprom
    if (temp==0)
  {
  digitalWrite (TEST_LED,1); 
  }
  //και εδώ του λέω αν στείλει 0 να ανάψει το LED που το έχω στο PIN8
    i2c_delay();


  //digitalWrite (SCL_OUT,0); 
//εδώ ξαναρίχνω τον παλμό στο 0.
 i2c_delay();
 }


έχω πουθενά λάθος και δεν ανάβει το LED; αν μπορεί κάποιος να διαβάσει τον κώδικα και να μου πεί που έχω λάθος. Σας παρακαλώ

----------


## acmilangr

χμ... πρόσεξα ενα λάθος 

"εδώ στέλνω τα bit 1010111, δεν είμαι σίγουρος αν έκανα σωστά αλλα απο όσο διαβασα στο datasheet τα 4 πρώτα θα πρέπει να ειναι 1010 κ*αι τα υπόλοιπα 3 να ειναι ανάλογα τα pin, και εφόσων εγώ τα έχω και τα 3 στην γή τα έδωσα 1"*

εφόσων τα έχω στην γή τότε θα πρέπει να στείλω 1010*000. Σωστά;*

δεν ειμαι σπίτι μου όμως τώρα να το δοκιμάσω.

Αν μπορεί κάποιος ας διαβάσει τον κώδικα και να μου πεί που αλού έχω λάθη

EDIT: SUCCESSSSSSSS!!!!!!!!!!!!!!!

αυτό έφτεγε!!!!

τώρα μένει να συνεχίσω στα επόμενα βήματα!!!!

θα επανέλθω!

----------


## chip

Το ξαναλέω. Μόνο ένα πιν για το SDA.
Όταν θελεις να πάρεις δεδομένα κάνεις το πιν είσοδο.
όταν θες να στείλεις δεδομένα αν θές να στείλεις μηδέν στέλνεις μηδέν, αν θες να στείλεις ένα γυρνάς το πιν σε είδοδο (δεν την διαβάζεις απλά την κάνεις είσοδο) και έτσι το πιν αυτό πάει σε λογικό 1 λόγο της pull-up αντίστασης και είναι σα να έστειλες 1.

----------


## acmilangr

> Το ξαναλέω. Μόνο ένα πιν για το SDA.
> Όταν θελεις να πάρεις δεδομένα κάνεις το πιν είσοδο.
> όταν θες να στείλεις δεδομένα αν θές να στείλεις μηδέν στέλνεις μηδέν, αν θες να στείλεις ένα γυρνάς το πιν σε είδοδο (δεν την διαβάζεις απλά την κάνεις είσοδο) και έτσι το πιν αυτό πάει σε λογικό 1 λόγο της pull-up αντίστασης και είναι σα να έστειλες 1.



 Ναι φίλε μου το σκέφτηκα και ξέρω πως έχεις δίκιο, τώρα μένει να δώ αν μπορώ να αλάζω το pin μέσω του προγράματος όποτε θέλω καθώς έχει ξεχωριστό setup void οπου δηλώνουμε το κάθε Pin αν θα είναι είσοδος η έξοδος

----------

