PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : SRF02 I2C C-Quellcode (RN-Control)



Meyk
04.07.2011, 21:59
Guten Abend.

Ich bastel derzeit an der Kollisionserkennung meines Roboters (Basis:RN-Control) und habe mir dafür einen SRF02 bestellt. Das Ganze hängt bereits an dem I2C Bus. Wenn ich das Netzteil anschließe und das Board mit Strom versorge, dann leuchtet die rote LED am SRF02 kurz auf.

Mein Problem:
Ich suche nun seit mehreren Tagen nach einem vernünftigen Quellcode in der Programmiersprache C, an dem ich mich orientieren kann. Der Hersteller liefert leider nur Bascom und hier im Forum gibt es zwar viele Beispiele, jedoch sind die dann immer gleich so komplex, dass ich kaum was verstehe und es selbst kaum testen kann. Ich habe natürlich schon vieles ausprobiert, es tut sich jedoch leider nichts. Nicht einmal die Lampe vom SRF02 leuchtet noch einmal auf. Sie leuchtet nicht einmal mit einem klick auf den "Resetknopf" auf dem Board auf. Erst wenn ich die Stromversorgung wegnehme und wieder anschließe gibts ein kurzes aufleuchten.
Ich habe gelesen, dass es vielleicht an den Pull-up Widerständen liegen kann, aber die sind bei einem RN-Control doch schon integriert.

Hat jemand ein Beispiel, an dem sich Anfänger wie ich, die in C programmieren, orientieren können?
Das wär echt super!

lG Tobi

Meyk
06.07.2011, 10:54
Soo.. nach langer Recherche bin ich gerade auf folgendes gestoßen:

http://www.rn-wissen.de/index.php/SRF08_mit_avr-gcc
(http://www.rn-wissen.de/index.php/SRF08_mit_avr-gcc)

Dort ist ein Beispiel in C, wie man einen SRF08 ansteuert. Ob das auch bei mir funktioniert, werde ich in den nächsten Tagen feststellen.

mfg Tobi

miicchhii
21.07.2011, 20:56
hast du es schon geschafft?
ich möchte mir auch einen srf02 zulegen,
bin aber noch unsicher ob analoge auswertung nicht vielleicht einfacher wäre,
da ich keine Ahnung von I2C habe
und ebenfalls keine passenden Beispiele in C finde


mfg michi

Meyk
21.07.2011, 21:02
HI, ich habe zwar den I2C Bus ansteuern können, habe aber immer noch einige Probleme mit der Ansteuerung der SRF02.

programm hab ich hier her:
http://www.rn-wissen.de/index.php/SRF08_mit_avr-gcc

w (http://www.rn-wissen.de/index.php/SRF08_mit_avr-gcc)erde in Kürze den Bus ausmessen, vielleicht liegt es an den Pullup-Widerständen... :(


mfg tobi

miicchhii
21.07.2011, 21:15
die internen Pull-Ups sind zu hoch, falls du die verwendest,
du musst unbedingt 2k2 extern anschließen.

edit: du musst auch die Adresse ändern (#define SRF08_adress 0xE0), die müsste im Datenblatt stehen.


mfg michi

Meyk
22.07.2011, 07:25
ja die verwende ich.. Sind zu hoch? shit.. okay dann ist das die erste Sache dich ich machen werde.
vielen dank!

Meyk
23.07.2011, 09:08
edit: du musst auch die Adresse ändern (#define SRF08_adress 0xE0), die müsste im Datenblatt stehen.

Im Datenblatt steht folgendes:
"Die Standard-Hausnummer vom SRF02 ist Hex 0xE0"

dann muss ich ja alles so lassen, wie es ist, richtig?

Ich werde jetzt gleich die Pullups einlöten

miicchhii
23.07.2011, 11:40
Ja, ich denke so müsste es dann eh passen,
ich weiß auch nur was ich lese,
so ein teil leg ich mir demnächst auch zu,
was für sensoren verwendest du sonst noch auf deinem bot?

PS: schon eingelötet bzw getestet?

Mfg michi

Meyk
23.07.2011, 12:58
hi.. ich habe soeben 2x 10k zwischen 5V und SDA sowie SCL eingelötet. ohne Erfolg :(
Habe 10k genommen, weil ich kein 2,2 da hatte und es auch in einem anderen Thread gelesen hatte.
Es kann doch nicht daran liegen oder?

Ich habe bisher folgendes gemacht:
1. Einen anderen SRF02 ausprobiert.
2. Pullup wiederstände eingelötet
3. viele Änderungen im Code

Ich benutze bisher nur diesen einen SRF02 Sensor.

Folgenden Code:

Hauptprogramm:



//#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include "rncontrol.h"
#include "SRF08.h"








/*### Variablen ###*/
//char wort[5]; //Zahlen (Integer und Float) müssen vor der Ausgabe per RS232 in ASCII-Zeichen konvertiert werden, für die ein Speicher benötigt wird.
//const float referenzspannung = 0.0048828125; //Referenzwert zur Multiplikation mit den Werten der Analogports (0...1023), um auf die Voltzahl zu kommen (0...5). Ergibt sich aus 5/1024.
//uint16_t analog; //Variable für jeweils an einem Analogport gemessenen Wert, um nicht für eine Ausgabe mehrere Messungen durchführen zu müssen.




/*### Hauptschleife ###*/
int main(void)
{
//Pins bzw. Ports als Ein-/Ausgänge konfigurieren
//DDRA |= 0x00; //00000000 -> alle Analogports als Eingänge
//DDRB |= 0x03; //00000011 -> PORTB.0 und PORTB.1 sind Kanäle des rechten Motors
//DDRC |= 0xFF; //11111111 -> PORTC.6 und PORTC.7 sind Kanäle des linken Motors, Rest sind LEDs für Lauflicht
//DDRD |= 0xB0; //10110000 -> PORTD.4 ist PWM-Kanal des linken Motors, PORTD.5 des rechten

//Initialisierungen
//setportcon(0); setportcon(1); setportcon(2); setportcon(3); setportcon(4); setportcon(5); //LEDs ausschalten
setportdoff(7); //Speaker aus
//init_timer1(); //Initialisierung Timer für PWM
init_USART(); //USART konfigurieren
//SFIOR &= ~(1<<PUD); // Pull-UP enable (nicht unbedingt nötig, aber zur Klarheit!)
//PORTA |= (1<<PA7); // internen Pull-Up an PA7 aktivieren




//timer1 für 10ms-Interrupt starten
TIMSK |=(1<<OCIE1A); //ctc interrupt
TCCR1B |=(1<<CS12) | (1<<CS10); //Prescaler 1024
TCCR1B |=(1<<WGM12); //Clear Timer on Compare Match Modus
OCR1A = 0x009C; //Compare auf 10ms bei 8MHz setzen


sendUSART("---------------------------------------------Start 1\r\n");


sei();
start_SRF08_automessung(); //Messung beginnen
uint16_t messwert;
while(1)
{
messwert=get_SRF08_distance();
sendUSART("Messerwert empfangen!\n");
}


}




ISR(TIMER1_COMPA_vect) //wird alle 10ms aufgerufen
{
sendUSART("Timer Startet\n");
SRF08_task();
}





twimaster.c

unsigned char i2c_start(unsigned char address){
uint8_t twst;


// send START condition
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
sendUSART("Hier wird noch ausgeführt!\n");
// wait until transmission completed
while(!(TWCR & (1<<TWINT)));
sendUSART("Hier leider nicht mehr!\n");
// check value of TWI Status Register. Mask prescaler bits.
twst = TW_STATUS & 0xF8;
if ( (twst != TW_START) && (twst != TW_REP_START)) return 1;


// send device address
TWDR = address;
TWCR = (1<<TWINT) | (1<<TWEN);


// wail until transmission completed and ACK/NACK has been received
while(!(TWCR & (1<<TWINT)));


// check value of TWI Status Register. Mask prescaler bits.
twst = TW_STATUS & 0xF8;
if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ){
return 1;
}
return 0;


}/* i2c_start */




Folgende Ausgabe über RS232:

---------------------------------------------Start 1Timer Startet
Hier wird noch ausgeführt!


Wenn ich das Programm starte, initialisiert er den Timer, welcher DIREKT den SRF08_task(); Befehl startet ohne dass vorher i2c initialisiert wurde. So steht es in dem Programm bei RN-Wissen.
Wenn ich das veränder, also die Initialisierung des I2C der Initialisierung des Timers vorziehe, funktionierts aber auch nicht.

Grob gesagt, bleibt er an folgender Stelle im twimaster.c hängen:

// wait until transmission completed
while(!(TWCR & (1<<TWINT)));


Vielen Dank für eure Hilfe!

Meyk
23.07.2011, 13:00
Achja: und folgende Frequenzen:




/* define CPU frequency in Mhz here if not defined in Makefile */
#ifndef F_CPU
#define F_CPU 8000000UL
#endif


/* I2C clock in Hz */
#define SCL_CLOCK 100000L

Meyk
30.07.2011, 09:25
Weiß denn keiner mir zu helfen? :(

miicchhii
30.07.2011, 17:37
hi.. ich habe soeben 2x 10k zwischen 5V und SDA sowie SCL eingelötet. ohne Erfolg :(
Habe 10k genommen, weil ich kein 2,2 da hatte und es auch in einem anderen Thread gelesen hatte.
Es kann doch nicht daran liegen oder?


nimm doch 4 parallel, damit du wenigstens auf 2k5 runterkommst.

Meyk
30.07.2011, 17:51
also wenn du meinst, dass es daran liegen könnte, dann besorg ich mir einfach nächste Woche ein paar neue Widerstände.
Was sagst du denn zu den Frequenzen?

lg

miicchhii
30.07.2011, 18:03
ich kenn mich da nicht aus, war nur ein vorschlag.

was ich so gesehen hab passen 100kHz
edit: probiers doch trotzdem mal mit 50kHz

mfg miicchhii

miicchhii
10.08.2011, 11:02
Ich hab meinen gestern bekommen, bei mir hats nach ein bisschen versuchen und verzweifeln funktioniert.

hier der Code:
Main.c:


#include <avr/io.h>
#include <avr/interrupt.h>
#include "srf08.h"
#include "srf08.c"
#include "twimaster.c"
int main(void)
{

//timer1 für 10ms-Interrupt starten
TIMSK |=(1<<OCIE1A); //ctc interrupt
TCCR1B |=(1<<CS12) | (1<<CS10); //Prescaler 1024
TCCR1B |=(1<<WGM12); //Clear Timer on Compare Match Modus
OCR1A = 0x009C; //Compare auf 10ms bei 8MHz setzen

sei();
start_SRF08_automessung(); //Messung beginnen

uint16_t messwert;
uint8_t ausgabe[20];
while(1)
{
messwert=get_SRF08_distance();

/*
Messwert verarbeiten...
*/
}
}


ISR(TIMER1_COMPA_vect) //wird alle 10ms aufgerufen
{
SRF08_task();
}




den code hab ich ausm Rn-Wissen,
die libraries und C-depencies auch direkt kopiert.


mfg michi

edit: ja, meine includes sind vl nicht so toll, aber es funktioniert, bei mir heißt das schon was ;-)

Genghis
13.09.2011, 18:06
Hallo,

bin jetzt vllh nen Monat zu spät dran, aber ich hab auch sowas vor. Was hast du jetzt genau geändert? Konnte nur den Unterschied erkennen, dass du ne Zeile mit "uint8_t ausgabe[20];" geadded hast.

Greetz
Genghis