Sonar krage för blinda hundar (3 / 5 steg)
Steg 3: programvara
Det första steget till att få programmet att fungera är att öppna ett nytt textdokument och klistra in följande:
< p > #ifndef _I2CMASTER_H < br > #define _I2CMASTER_H 1
/*************************************************************************
* Benämning: C inkluderingsfil för I2C ledar-gränssnittet
* (i2cmaster. S eller twimaster.c)
* Författare: Peter Fleury
< pfleury < en href = "http://jump.to/fleury" >< en href = "http://jump.to/fleury" > http://jump.to/fleury
< /a >
< /a >
* Fil: $Id: i2cmaster.h,v 1.10 2005/03/06 22:39:57 Peter Exp $
* Programvara: AVR-GCC 3.4.3 / avr-libc 1.2.3
* Mål: alla AVR enheter
* Användning: se Doxygen manual
**************************************************************************/</pfleury DOXYGEN
/**
pfleury_ic2master I2C Master bibliotek
#include < i2cmaster.h >
I2C (TWI) Master mjukvarubibliotek < /i2cmaster.h >< /p >< p > grundläggande rutiner för att kommunicera med I2C slav enheter. Denna enda hanterare
genomförandet är begränsad till en buss master på I2C bussen. < /P >< p > detta I2c bibliotek är implementerad som en kompakt assembler programvara genomförandet av I2C-protokollet
som körs på någon AVR (i2cmaster. S) och som en TWI hårdvara gränssnitt för alla AVR med inbyggd TWI maskinvara (twimaster.c).
Eftersom API för dessa två implementationer är exakt samma, ett program kan kopplas antingen mot den
programvara I2C genomförande eller maskinvaran I2C genomförandet. < /p >< p > Använd 4.7 k pull-up resistor på SDA och SCL PIN-koden.
Anpassa SCL och SDA hamnen och pin definitioner och så småningom dröjsmål rutin i modulen
i2cmaster. S till ditt mål när du använder programvara I2C genomförandet!
Justera CPU klocka frekvens F_CPU i twimaster.c eller i Makfile när du använder den TWI hårdvara implementering. < /p >< p >
Modul i2cmaster. S är baserat på Atmel ansökan Obs AVR300, korrigerat och anpassas
GNU assembler och AVR-GCC C samtal gränssnitt.
Ersatt det felaktiga kvartalet periodens förseningar Funna i AVR300 med
halva perioden förseningar.
Peter Fleury pfleury < en href = "http://jump.to/fleury" >< en href = "http://jump.to/fleury < / a" > http://jump.to/fleury
< /A >>< /p >< p > API-användning exempel
Följande kod visar typisk användning av detta bibliotek, se exempel test_i2cmaster.c < /p >< p > #include < i2cmaster.h >< /i2cmaster.h >< /p >< p > #define Dev24C02 0xA2 / / enhetens adress för EEPROM 24C 02, se datablad < /p >< p > int main(void)
{
unsigned char ret; < /p >< p > i2c_init(); initiera I2C biblioteket < /p >< p > / / skriva 0x75 till EEPROM adress 5 (Byte skriva)
i2c_start_wait(Dev24C02+I2C_WRITE); Ange enhetens adress och skriva läge
i2c_write(0x05); Skriv adress = 5
i2c_write(0x75); Skriv värdet 0x75 till EEPROM
i2c_stop(); ställa in stop conditon = release buss < /p >< p > / / Läs tidigare skrivit värde tillbaka från EEPROM adress 5
i2c_start_wait(Dev24C02+I2C_WRITE); Ange enhetens adress och skriva läge < /p >< p > i2c_write(0x05); Skriv adress = 5
i2c_rep_start(Dev24C02+I2C_READ); Ställ in enhetens adress och läsa sätt < /p >< p > ret = i2c_readNak(); läsa en byte från EEPROM
i2c_stop(); < /p >< p > for(;;);
}
#endif / * DOXYGEN * < /p >< p > ** (__GNUC__ * 100 + __GNUC_MINOR__) < 304
#error "detta bibliotek kräver AVR-GCC 3.4 eller senare, uppdatera till nyare AVR-GCC kompilator!"
#endif < /p >< p > #include < avr io.h= "" >< / avr >< /p >< p > / ** definierar data riktning (behandlingen från I2C enhet) i i2c_start(),i2c_rep_start() * /
#define I2C_READ 1 < /p >< p > / ** definierar data riktning (skriver till I2C enhet) i i2c_start(),i2c_rep_start() * /
#define I2C_WRITE 0 < /p >< p > / **
initiera I2C master interace. Behöver bara anropas en gång
void
ingen
*/
extern void i2c_init(void); < /p >< p > / **
Avslutar överföringen av uppgifter och släpper I2C bussen
void
ingen
*/
extern void i2c_stop(void); < /p >< p > / **
Utfärdar ett tillstånd som start och skickar adressen och överföring riktning
addr adress och överföring riktningen av I2C-enhet
0 enhet tillgänglig
Det gick inte att komma åt enheten 1
*/
extern unsigned char i2c_start (unsigned char addr); < /p >< p > / **
Utfärdar ett tillstånd som upprepade start och skickar adressen och överföring riktning < /p >< p > addr adress och överföring riktningen av I2C-enhet
0 enhet tillgänglig
Det gick inte att komma åt enheten 1
*/
extern unsigned char i2c_rep_start (unsigned char addr); < /p >< p > / **
Utfärdar ett tillstånd som start och skickar adressen och överföring riktning
Om enheten är upptagen, använda ack polling vänta tills enheten redo
addr adress och överföring riktningen av I2C-enhet
ingen
*/
extern void i2c_start_wait (unsigned char addr); < /p >< p >
/**
Skicka en byte till I2C enhet
databyte som skall överföras
0 Skriv framgångsrika
1 skrivning misslyckades
*/
extern unsigned char i2c_write (unsigned char data); < /p >< p > / **
läsa en byte från I2C-enheten, begär mer data från enheten
byte läsa från I2C enhet
*/
extern unsigned char i2c_readAck(void); < /p >< p > / **
läsa en byte från I2C-enheten, följs Läs av ett stoppvillkor
byte läsa från I2C enhet
*/
extern unsigned char i2c_readNak(void); < /p >< p > / **
läsa en byte från I2C-enheten
Genomföras som ett makro, som appeller antingen i2c_readAck eller i2c_readNak
Ack 1 skicka ack, begär mer data från enheten < br >
0 skicka nak, Läs följs av ett stoppvillkor
byte läsa från I2C enhet
*/
extern unsigned char i2c_read (unsigned char ack);
#define i2c_read(ack) (ack)? i2c_readAck(): i2c_readNak(); < /p >< p > / **
#endif < /p >
Spara filen som i2cmaster.h
Nästa öppen upp den Arduino programvaran och skapa ett nytt program med följande kod:
#include < i2cmaster.h >
byte clockPin = 12;
byte buf [9]; //Buffer att lagra den mottagna valeus
byte addr = 0x02, //address 0x02 i ett 8-bitars sammanhang - 0x01 i 7-bitars sammanhang
byte avstånd; < /p >< p > void setup()
{
i2c_init (); //I2C frekvens = 11494,253 Hz
Serial.BEGIN(9600);
printUltrasonicCommand (0x00); //Read Version
printUltrasonicCommand (0x08); //Read produkt-ID
printUltrasonicCommand (0x10); //Read sensortyp
printUltrasonicCommand (0x14); //Read måttenheter
pinMode(13,OUTPUT);
}
< /p >< p > void loop()
{
printUltrasonicCommand (0x42); //Read mätning Byte 0
avståndet = readDistance();
IF(Distance == 0xFF)
Serial.println ("fel läsavstånd");
annat
Serial.println (avstånd, DEC);
IF(Distance<30) {
Tone(13,4000);
Delay(200);
noTone(13);
}
}
byte readDistance()
{
fördröjning (100); //There måste vara en fördröjning mellan kommandon
byte cmd = 0x42; //Read mätning Byte 0
pinMode (clockPin, ingång), //Needed för att skriva att arbeta
digitalWrite (clockPin, hög);
IF(i2c_start(addr+I2C_WRITE)) //Check om det finns ett fel
{
Serial.println ("fel i2c_start");
i2c_stop();
returnera 0xFF;
}
IF(i2c_write(CMD)) //Check om det finns ett fel
{
Serial.println ("fel i2c_write");
i2c_stop();
returnera 0xFF;
}
i2c_stop();
delayMicroseconds (60), //Needed för att ta emot arbete
pinMode (clockPin, produktionen);
digitalWrite (clockPin, låg);
delayMicroseconds(34);
pinMode (clockPin, ingång);
digitalWrite (clockPin, hög);
delayMicroseconds(60);
IF(i2c_rep_start(addr+I2C_READ)) //Check om det finns ett fel
{
Serial.println ("fel i2c_rep_start");
i2c_stop();
returnera 0xFF;
}
för (int jag = 0; jag < 8; i ++)
BUF [i] = i2c_readAck();
BUF [8] = i2c_readNak();
i2c_stop();
returnera buf [0];
}
void printUltrasonicCommand(byte cmd)
{
fördröjning (100); //There måste vara en fördröjning mellan kommandon
pinMode (clockPin, ingång), //Needed för att skriva att arbeta
digitalWrite (clockPin, hög);
IF(i2c_start(addr+I2C_WRITE)) //Check om det finns ett fel
{
Serial.println ("fel i2c_start");
i2c_stop();
hemkomst.
}
IF(i2c_write(CMD)) //Check om det finns ett fel
{
Serial.println ("fel i2c_write");
i2c_stop();
hemkomst.
}
i2c_stop();
delayMicroseconds (60), //Needed för att ta emot arbete
pinMode (clockPin, produktionen);
digitalWrite (clockPin, låg);
delayMicroseconds(34);
pinMode (clockPin, ingång);
digitalWrite (clockPin, hög);
delayMicroseconds(60); < /p >< p > if(i2c_rep_start(addr+I2C_READ)) //Check om det finns ett fel
{
Serial.println ("fel i2c_rep_start");
i2c_stop();
hemkomst.
}
för (int jag = 0; jag < 8; i ++)
BUF [i] = i2c_readAck();
BUF [8] = i2c_readNak();
i2c_stop();
om (cmd == 0x00 || cmd == 0x08 || cmd == 0x10 || cmd == 0x14)
{
för (int jag = 0; jag < 9; i ++)
{
om (buf [i]! = 0xFF & & buf [i]! = 0x00)
Serial.Print(BUF[i]);
annat
bryta;
}
}
annat
Serial.Print (buf [0], DEC); < /P >< p > Serial.println("");
}
/*
"Ledningar på NXT jack kontakt.
"Tråd färger kan variera. Stift 1 är alltid slutet närmaste spärren.
' 1 vit + 9V
"2 black GND
"3 röda GND
"4 grön + 5V
"5 gula SCL - även ansluta clockpin för att ge en extra låga impuls
"6 blå SDA
"Använd inte i2c pullup motstånd - redan finns inom sensor.
* / < /p >
Kontrollera och kompilera koden på din Arduino. Om du får en fel göra säker som den i2cmaster.h filen är tillgänglig av Arduino koden.
Du kan justera avståndet från vilken den pipa kommer att ske genom att sänka eller höja värdet i if(distance<30) skick.