Hallo,

Ik ben een eigen sensor aan het ontwikkelen voor een Lego NXT robot.
Aangezien de NXT sensors kan uitlezen via I²C, zou ik daarvan gebruik willen maken. Ik kan er alleen niet achterkomen hoe je een AVR (ATMega164p) kan gebruiken als I²C slave. Ik zou acht waarden moeten kunnen uitlezen tussen 0 en 255.

Ik heb al een tijdje zitten googlen, maar ik vind geen goede voorbeelden om een AVR als slave te gebruiken i.p.v. master. Ik heb wel ergens gelezen dat het mogelijk moet zijn om een AVR als I²C EEPROM te
laten gedragen, maar ik weet niet hoe.

P.s. Ik gebruik AVR Studio 5.

Mvg,
Knutselman

Dag knutselman, 1e klas HvA project?

Leuke ambitieuze keuze. In dit topic heb ik een stuk werkende code gepost:

http://www.circuitsonline.net/forum/view/97669/1/i2c+C+vwg3jb

AVR als EEPROM laten gedragen kan heel goed, maar is niet heel zinvol...

Ik heb daar 2e stukjes code neergezet en een daarvan is voor het sturen op een atmega. Daar heb je niet veel aan maar het is wel handig om te zien hoe het werkt.

je stuurt eerst je adressbyte, en vervolgens een databyte.

je adressbyte is 0x50+I2C_WRITE, en je databyte is 0x01.

dit bepaal je straks dus met je NXT brick.

mijn code voor de ontvangstkant start een interrupt op het moment dat iets binnen komt.

hier kom je dus altijd! zowel bij adresbyte als bij databyte. bij switch (TW_STATUS) wordt gekeken naar wat de inhoud is. In mijn geval moeten de eerste 7 bits overeen komen met een vooraf ingesteld slaveadress.

if((TWDR&0xFE) == SLAVE_ADRESS)
buffer_access=VALID;

als die overeen komen dan zeg ik dat mijn buffer open mag, de daarop volgende data zal dus kennelijk geldig zijn.

je kunt hier bijvoorbeeld ook even een led laten knipperen of de waarde via een poort naar buiten gooien, om te kijken of het werkt.

efin, als het adres geldig is dan mag de volgende byte bepalen of er wat moet gebeuren

if (buffer_access == VALID){
received_data = TWDR;
set_data(received_data);
}

received data is de databyte die je hebt ontvangen. set data is een functie die een led stuurd of whatever.

ik hoop dat het duidelijk is en anders vraag je het maar.

1e klas HvA project?

Nee, toch niet. (Ik ben trouwens nog maar 15 jaar oud...)

Leuke ambitieuze keuze.

Dankje, de bedoeling ervan is een (geavanceerde) lijnvolger te maken met 8 sensoren (vandaar de 8 waardes).

Ik heb vroeger al gewerkt met de PCF8574 port expander, dus ik wist ongeveer al hoe I²C in elkaar zit bij de master (NXT). Toch bedankt voor de duidelijke uitleg. Ik neem nu een kijkje naar dat ene topic, en laat nog iets weten als ik vorderingen maak.

Edit1: Ik heb ondertussen al een LED kunnen aan- en uitzetten via I²C volgens dit programma:

#include <avr/io.h>
#include <util/twi.h>
#include <util/delay.h>

int main(void){
DDRB = 0xff;
DDRC = 0x00;
PORTC = 0xff;
 
int data = 0;
 
TWAR = 2;   //het adres van de slave (adres is 1, maar bit0 hoort niet bij het adres
TWCR = (1<<TWEA)|(1<<TWEN); // enable de twi
 
while(1){
 
if(TWCR & (1<< TWINT)){   //als je een interrupt krijgt
	if(TWSR & 0x60){   // en die komt neer op een ontvangen adres
		TWCR |= (1<<TWINT);  // clear de interrupt voor de rest van de boodschap
	}
 
	if(TWSR & 0x80){  //als je data hebt ontvangen
		data = TWDR;  // zet die in data
		TWCR |= (1<<TWINT); // clear de interrupt
	}
}
 
PORTB = data;  //uitvoer van data
 
}
}

Ik heb nu nog twee problemen:
- Ik weet nog niet hoe ik data moet 'terugsturen' vanaf de slave
- De slave werkt op elk adres boven 0x01 (dus write)

Mvg,
Knutselman

[Bericht gewijzigd door Knutselman op (48%)]

Application note AVR311 geeft alles wat je nodig hebt om een AVR als i2c te gebruiken. Vanwege licentierechten oid wordt i2c door Atmel TWI genoemd.

weet ik zo niet.

je zal iig een 3e databyte moeten toevoegen. je moet hierbij de byte die je wilt versturen in een register zetten van je atmega nadat je een ack hebt gegeven op je vorige data byte. je brick regelt de clock, dus dat wordt vanzelf bij de atmega naar buiten geschoven.

zoals je in je java programma op de brick bytes kunt versturen, zal er ongetwijfeld ook wel een method in de library zitten om bytes te kunnen ontvangen. Dit zal je gewoon even moeten uitpluizen.