Nachtrag:
Ich habe die Räder gegen ASURO-Räder ausgetauscht, der Grip ist deutlich besser.
Druckbare Version
Nachtrag:
Ich habe die Räder gegen ASURO-Räder ausgetauscht, der Grip ist deutlich besser.
Hallo m.a.r.v.i.n,Zitat:
Zitat von m.a.r.v.i.n
den ATmega644 hatte ich gleich mit dem NIBObee mitbestellt, weil ich dachte, daß es nicht übel wäre, für 5€ 4x soviel Speicher zu haben wie das Original.
Heute wollte ich nun auf den 644 umsteigen und hab es so gemacht, wie oben beschrieben: Deine Dateien in den /src - Zweig kopiert, die libs wie beschrieben neu gebaut, die Projekte auf den 644 angepasst genau wie den Aufruf von avrdude. Damit lassen sich die Programme auch übersetzen und auf den NIBObee laden.
So weit - so gut. Dann gehen die Problem aber los: Die Programme laufen wesentlich laaaaaaaangsamer, als mit dem ATmega 16 - handgestoppt so um den Faktor 20. Die Liniensensoren funktionieren, lcd-Anzeige klappt, aber die linken Fühler funktionieren nicht mehr - die rechten Fühler dagegen schon. Alles wie gesagt wesentlich langsamer.
Wenn ich den ATmega16 wieder einbaue und die entsprechenden Einstellung wiederherstelle, dann klappt alles normal.
Hast Du eine Idee, was da falsch laufen könnte? Habe ich etwas vergessen? Ist der 644 defekt? Bin etwas ratlos...
Hallo pinsel,
Prima - danke! Habe mir mal die SRF-Sensoren angesehen. Ich überlege, ob ich gleich den SRF10 nehme - den gibt es gleich mit passendem Montage-Winkel. Kleiner ist er auch noch und läßt sich wegen i2c-Ansteuerung leicht programmieren - der NIBObee hat ja alles, was man dafür braucht ;-) Spricht außer dem Preis etwas gegen dieses Teil?Zitat:
Zitat von pinsel120866
Könnte man sich Deinen Quellcode mal ansehen?Zitat:
4. Testprogramm ist angehängt.
Hi Tuxi,
natürlich kannst du das SFH10 nehmen.
Mein Testprogrammcode sieht so aus:
Code:'Verwendeter Compiler Bascom V 1.11.9.3
'
'Aufgabe:
'Entfernung wird gemessen und in Zentimetern über
'RS232 ausgegeben
'Autor: Pinsel120866
'###################################################
$regfile = "m16def.dat"
$crystal = 15000000
$baud = 9600
$hwstack = 32
$framesize = 32
$swstack = 32
Dim Zeitmessung As Word
Dim Entfernung As Word
Wait 1
Print "**** SRF05 mit NIBOBee *****"
Print "Entfernung in cm anzeigen"
Print " "
Config Pinc.2 = Output
Do
Portc.2 = 0
Pulseout Portc , 2 , 40
Pulsein Zeitmessung , Pinc , 2 , 1
Zeitmessung = Zeitmessung * 10
Entfernung = Zeitmessung / 58
Print "Entfernung: " ; Entfernung ; " cm"
Wait 1
Loop
Hallo Tuxi-Halle,Zitat:
Zitat von Tuxi-Halle
der Prozessor ist sicher nicht defekt. Die Fuse Bits stimmen nur nicht. Ein fabrikfrischer Prozessor läuft mit internem Takt mit 1MHz.
Hier sind 2 Screenshots zur Verwendung des myAVR Progtool mit der NIBObee.
1. Zeigt die Einstellung der Programmer Hardware. Unter Sonstiges usbasp und als Schnittstelle usb auswählen.
http://www.flickr.com/photos/hmblgrmpf/4224673867/
2. Zeigt die Fuses Einstellungen des Original NIBObee Controller. In die Fuse & Lock-Bits Einstellung gelangt man unter Brennen, bearbeiten.
http://www.flickr.com/photos/hmblgrmpf/4224673787/
Hallo pinsel,
danke für die schnelle Antwort!
Schon bestellt ;-) Leider ist das Ding samt Befestigungswinkel teurer als der ganze NIBObee :-( Aber was solls...Zitat:
Zitat von pinsel120866
Bascom kenne ich zwar nicht, aber man versteht auch so, was gemacht wird ;-)Zitat:
Mein Testprogrammcode sieht so aus:
'Verwendeter Compiler Bascom V 1.11.9.3
...
Ich meinte aber eher die Ansteuerung des Servos, weil ich das noch nie gemacht habe. Die eigentliche Messerei muß ich mit dem SFH10 sowieso anders machen. Den Conrad-Servo hab ich mir angeschaut - wirklich schön klein und preiswert das Ding! Braucht man dafür extra Treiberschaltkreise oder wie geht das? Kannst Du dafür mal ein Code-Schnipsel posten?
Danke!
Wiewas? So einfach ist das? Und funktioniert wunderbar. *dankedankedanke*Zitat:
Hier sind 2 Screenshots zur Verwendung des myAVR Progtool mit der NIBObee.
Hallo m.a.r.v.i.n,
Danke! Daran wird es wohl liegen.Zitat:
Die Fuse Bits stimmen nur nicht. Ein fabrikfrischer Prozessor läuft mit internem Takt mit 1MHz.
Ich hab mal die fuses des ATmega16 ausgelesen:
Bild hier
Und dann die des ATmega644:
Bild hier
Wenn ich Dich recht verstanden habe, dann muß ich wohl die Werte des 16ers aus dem NIBObee in den 644er schreiben, also "hfuse=D1" und "lfuse=EF". Was ist aber mit den "efuse", die es offenbar beim 16er gar nicht gibt? Einfach so lassen ("FF")? Habe leider nix wirklich Erhellendes "ergoogeln" können :-(
Hallo m.a.r.v.i.n,
habs einfach mal so gemacht (efuse="FF", hfuse="D1", lfuse="EF") - funktioniert :-)
Nochmals vielen Dank!
btw.:kennst Du ein vernünftiges Tutorial zum Thema "fuses"?
Hi tuxi,
ich gebe dir mal den gesamten C-Code meines Greifer-Asuros:
Den Ablauf siehst du unter http://www.youtube.com/watch?v=wQY2dqMZH3Y
Du kannst dir sicher die Servoschnipsel rauspflücken.Code:/************************************************************************
Test Programm fuer den ASURO IR-Adapter mit 2 Sende-LEDs
Der ASURO ermittelt ueber den nach vorne gerichteten
Infrarot Empfänger und Sender über die Reflektion des
Lichtes an einem Objekt ungefaehr dessen Abstand.
Es wird je nach Abstand der Rechten SendeLED die Status-LED in
verschiedenen Farben eingeschaltet. Wir der Abstand kleiner als 17 cm
werden die Motoren mit verschiedenen Geschwindigkeiten eingeschaltet.
Zur Compilierung dieses Programmes wird asuro.c und asuro.h aus
der ASURO Lib 2.6.1 benötigt. Die ASURO Lib ist auf sourceforge
zu finden.
************************************************************************
Hardware: ASURO Roboter
prozessor: ATMEGA32
clock: 16MHz Crystal
****************************************************************************
date authors version comment
====== ====================== ======= ==============================
Jan.08 (ch) robo.fr V1.0 First implemetation
Apr.08 (kk) pinsel V1.1 Erweiterung auf 2 SendeLEDs
Versions:
V1.0
- first version
V2.0
- Auf 2 SendeLEDs erweitert
***************************************************************************/
/***************************************************************************
*
* (c) 2007 robo.fr , christoph(at)roboterclub-freiburg.de
*
***************************************************************************
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation version 2 of the License, *
* If you extend the program please maintain the list of authors. *
* If you want to use this software for commercial purposes and you *
* don't want to make it open source, please contact the authors for *
* licensing. *
***************************************************************************/
#include "asuro.h"
#include <stdlib.h>
unsigned char i, servo_stellzeit;
/*************************************************************************
uint8_t objekt_sichtbar(uint8_t abstand)
Ist ein Objekt in der Entfernung kleiner oder gleich
dem Eingangsparameter "abstand" erkennbar?
objekt_sichtbar(7) liefert TRUE zurück, falls überhaupt
ein Object detektierbar.
abstand:
0: 5cm
1: 7cm
2: 13cm
3: 15cm
4: 16cm
5: 17cm
6: 18cm
7: 22cm
( Testobjekt: Joghurtecher, Umgebungsbeleuchtung: Zimmer )
return: TRUE falls Objekt gefunden
FALSE wenn nicht
Zeitbedarf: 5ms
author: robo.fr, christoph ( ät ) roboterclub-freiburg.de
date: 2008
*************************************************************************/
uint8_t objekt_sichtbar_rechts(uint8_t distance_r)
{
uint16_t j,z;
PORTB |= (1 << PB6); // PB6 auf HIGH (LED ausschalten)
DDRD |= (1 << DDD1); // Port D1 als Ausgang
PORTD &= ~(1 << PD1); // PD1 auf LOW
OCR2 = 254-distance_r; // wenn OCR2=0xFE dann Objekt sehr nahe
z=0;
for(j=0;j<30;j++) // loop time: 5ms
{
if (PIND & (1 << PD0))z++;
Sleep(6); // 6*Sleep(6)=1ms
}
if (z>=29) return FALSE; // Objekt nicht gefunden
else return TRUE;
}
uint8_t objekt_sichtbar_links(uint8_t distance_l)
{
uint16_t i,y;
PORTD |= (1 << PD1); // PD1 auf HIGH (LED ausschalten)
DDRB |= (1 << DDB6); // Port B6 als Ausgang
PORTB &= ~(1 << PB6); // PB6 auf LOW
OCR2 = 254-distance_l; // wenn OCR2=0xFE dann Objekt sehr nahe
y=0;
for(i=0;i<30;i++) // loop time: 5ms
{
if (PIND & (1 << PD0))y++;
Sleep(6); // 6*Sleep(6)=1ms
}
if (y>=29) return FALSE; // Objekt nicht gefunden
else return TRUE;
}
/*************************************************************************
uint8_t abstand()
Abstandsermittelung über IR-Sendiode / IR-Empfänger.
0:kleinster Abstand
7:größter Abstand
255: kein Objekt
Zeitbedarf: 5ms*9=45ms
author: robo.fr, christoph ( ät ) roboterclub-freiburg.de
date: 2008
*************************************************************************/
uint8_t abstand_rechts()
{
uint8_t k,n;
k=255;
for(n=0;n<4;n++)
{
if (!objekt_sichtbar_rechts(n)) k=n; // solange kein Objekt, Distanz erhoehen
}
return k;
}
uint8_t abstand_links()
{
uint8_t l,m;
l=255;
for(m=0;m<4;m++)
{
if (!objekt_sichtbar_links(m)) l=m; // solange kein Objekt, Distanz erhoehen
}
return l;
}
//************************************************************************
void RaceStart(void) // blink until any switch is pressed,
{ // then wait until switch is released
uint8_t t1, t2;
unsigned int col=OFF;
while (1) // blinking StatusLED until any switch is pressed
{
t1 = PollSwitch();
t2 = PollSwitch();
if (t1==t2)
{
if (t1)
{
break;
}
else
{
col ^= GREEN;
StatusLED(col);
}
}
Msleep(50);
}
StatusLED(OFF); // turn off StatusLED and ...
BackLED(ON,ON); // ... turn on both BackLED's
while (1) // wait until switch is released
{
t1 = PollSwitch();
t2 = PollSwitch();
if (t1==t2)
{
if (!t1)
{
break;
}
}
Msleep(50);
}
BackLED(OFF,OFF); // turn off BackLED's indication start of race
}
//************************************************************************
void servo(unsigned char winkel)
{
unsigned int count=0;
do
{
count++;
if(winkel)
{
PORTB |= (1 << PB0);
Sleep(winkel);
}
PORTB &= ~(1 << PB0);
Sleep(255-winkel);
}
while (count<servo_stellzeit);
}
/*************************************************************************
Hauptprogramm
*************************************************************************/
int main(void)
{
uint8_t n,m;
float volt;
int proz;
unsigned int sensors[2];
DDRB |= (1 << PB0);
Init();
initLcd();
volt=2.56/1024*Batterie()*22/10;
proz=(int)(((volt)/5)*100); //so ungefähr
// Output some strings to the LCD
writeStringToLCD("*ASURO bereit*");
writeStringToLCD("Batterie: ");
writeIntegerToLCD(proz);
writeStringToLCD("%");
RaceStart();
FrontLED(OFF);
while(1)
{
n=abstand_rechts();
m=abstand_links();
if ((n!=255) || (m!=255))
{
if ((n<0) && (m<0))
{
MotorDir(RWD,RWD);
MotorSpeed(155,165);
}
else if (m>n)
{
StatusLED(RED);
BackLED(ON,ON);
servo_stellzeit=12; //Servogeschw. einstellen
MotorSpeed(10,10); //kurze Pause
Msleep(1);
MotorSpeed(BREAK,BREAK);
Msleep(500);
MotorSpeed(10,10); //kurze Pause
Msleep(1);
MotorDir(FWD,FWD); //Kleines Stück vor
MotorSpeed(110,100);
Msleep(1100);
MotorSpeed(BREAK,BREAK);
clearLCD();
writeStringToLCD("Close Gripper");
for (i=15; i<85; i+=2) servo(i); //Greifer zumachen
MotorSpeed(10,10); //Kurze Pause
Msleep(1);
MotorDir(RWD,RWD); //Kleines Stück zurück
MotorSpeed(120,120);
Msleep(500);
MotorSpeed(BREAK,BREAK);
clearLCD();
writeStringToLCD("Turn left");
MotorSpeed(135,0); //Vierteldrehung nach links
Msleep(1000);
MotorSpeed(BREAK,BREAK);
clearLCD();
writeStringToLCD("Open Gripper");
for (i=75; i>17; i-=2) servo(i); //Greifer aufmachen
MotorSpeed(10,10); //Kurze Pause
Msleep(1);
MotorDir(RWD,RWD); //Kleines Stück zurück
MotorSpeed(120,120);
Msleep(500);
MotorSpeed(BREAK,BREAK);
clearLCD();
writeStringToLCD("Turn right");
MotorSpeed(0,135); //Vierteldrehung nach rechts
Msleep(1000);
MotorSpeed(BREAK,BREAK);
MotorSpeed(10,10); //Kurze Pause
Msleep(1);
clearLCD();
writeStringToLCD("That's it!");
MotorSpeed(0,155);
BackLED(ON,OFF);
clearLCD();
IRData(sensors);
writeStringToLCD("**NACH LINKS**");
writeIntegerToLCD(sensors[0]);
writeStringToLCD("*Wert*");
writeIntegerToLCD(sensors[1]);
}
else if (n>m)
{
StatusLED(RED);
BackLED(ON,ON);
servo_stellzeit=12; //Servogeschw. einstellen
MotorSpeed(10,10); //kurze Pause
Msleep(1);
MotorSpeed(BREAK,BREAK);
Msleep(500);
MotorSpeed(10,10); //kurze Pause
Msleep(1);
MotorDir(FWD,FWD); //Kleines Stück vor
MotorSpeed(95,120);
Msleep(1100);
MotorSpeed(BREAK,BREAK);
clearLCD();
writeStringToLCD("Close Gripper");
for (i=15; i<85; i+=2) servo(i); //Greifer zumachen
MotorSpeed(10,10); //Kurze Pause
Msleep(1);
MotorDir(RWD,RWD); //Kleines Stück zurück
MotorSpeed(120,120);
Msleep(500);
MotorSpeed(BREAK,BREAK);
clearLCD();
writeStringToLCD("Turn right");
MotorSpeed(0,135); //Vierteldrehung nach links
Msleep(1000);
MotorSpeed(BREAK,BREAK);
clearLCD();
writeStringToLCD("Open Gripper");
for (i=75; i>17; i-=2) servo(i); //Greifer aufmachen
MotorSpeed(10,10); //Kurze Pause
Msleep(1);
MotorDir(RWD,RWD); //Kleines Stück zurück
MotorSpeed(120,120);
Msleep(500);
MotorSpeed(BREAK,BREAK);
clearLCD();
writeStringToLCD("Turn left");
MotorSpeed(135,0); //Vierteldrehung nach rechts
Msleep(1000);
MotorSpeed(BREAK,BREAK);
MotorSpeed(10,10); //Kurze Pause
Msleep(1);
clearLCD();
writeStringToLCD("That's it!");
MotorSpeed(155,0);
BackLED(OFF,ON);
clearLCD();
IRData(sensors);
writeStringToLCD("**NACH RECHTS**");
writeIntegerToLCD(sensors[0]);
writeStringToLCD("*Wert*");
writeIntegerToLCD(sensors[1]);
}
else
{
StatusLED(GREEN);
BackLED(ON,ON);
MotorDir(FWD,FWD);
MotorSpeed(155,165);
clearLCD();
IRData(sensors);
writeStringToLCD("***GERADEAUS***");
writeIntegerToLCD(sensors[0]);
writeStringToLCD("*Wert*");
writeIntegerToLCD(sensors[1]);
}
}
}
}
Hallo Tuxi-Halle,Zitat:
Zitat von Tuxi-Halle
Ein Tutorial gibt es im RN-Wissen.
Ich habe es bei meiner NIBObee auch genauso gemacht. Die Fuses vom mega16 eingelesen und auf den mega644 übertragen.
Hallo,
nachdem die IR-Abstandsmessung gut funktioniert, will ich die PINs der 4 Schalter verwenden. Ich habe vor die Schalter abzulöten und die Leitungen der IR-Erweiterung dort anzubringen.
Ich habe nur bis jetzt nicht herausgefunden an welcher der 4 Lötpunkte pro Schalter ich die Leitung anlöten kann.
Kann mir bitte jemand weiterhelfen?
Hallo
Die Widerstände der Taster R46 bis R49 befinden sich direkt neben X1 bzw. X4. Da die Seiten der Widerstände, die an den X-Steckern liegen, auch die Anschlüsse zum Kontroller sind, habe ich einfach je zwei 2er-Stiftleisten an die Widerstände angelötet. Beim Löten hatte ich die neuen Stifte mit einem Sockel an X1/X4 angesteckt, so habe ich das Rastermass eingehalten und kann die zusätzlichen Pins jeweils zusammen mit X1/X4 verwenden.
Das habe ich so bei meinem parallelen LCD angewendet, die Taster am LCD hängen dabei neben den D4-D7 am LCD auch parallel zu den orginalen Fühlertasten:
Bild hier Bild hier
Aus: https://www.roboternetz.de/phpBB2/vi...=477739#477739
und https://www.roboternetz.de/phpBB2/ze...=476664#476664
Die Tastenfunktion meiner LCD-Lib unterscheidet nicht zwischen den neuen LCD-Tasten und den orginalen Sens-Tastern:
Meine bee hat nun AAs als Stromversorgung, weil die AAAs mit dem LCD zu schnell zusammenbrechen (unter 4,6V wird meine bee vom Programmer nicht mehr erkannt!). Die Ladefunktion hatte ich eh nie genutzt, deshalb habe ich die drei Jumper durch Brücken ersetzt. Leider fehlen ein paar Millimeter Platz zwischen den Radkästen:Code:uint8_t lcd_getkeys(void)
{
uint8_t keys=0;
el;
DDRC &= ~0b11110010; // LCD-Pins auf Eingang mit PullUp
PORTC |= 0b11110010;
delay(1);
if(PINC & (1<<PC1)) keys |= 16;
if(PINC & (1<<PC4)) keys |= 8;
if(PINC & (1<<PC5)) keys |= 4;
if(PINC & (1<<PC6)) keys |= 2;
if(PINC & (1<<PC7)) keys |= 1;
PORTC &= ~0b11110010; // nanu ???
DDRC |= 0b11110010; // LCD-Pins auf Ausgang und low
return(~keys & 0b11111);
}
Bild hier
Gruß
mic
Edit: http://www.roboter.cc/index.php?opti...Itemid=20#1062
Hallo
Nun habe ich mich endlich auf die Odometry gestürzt und diese auch gleich etwas gepimpt. Mechanische Änderung sind je 4 zusätzliche Löcher in den Codescheibenritzeln, softwaremäßig habe ich odometry.c der Lib ersetzt.
Durch die zusätzlichen Löcher sind die Abstände der Löcher in den Coderitzeln gleichmäßiger, deshalb werden die Odometryzähler nun bei erkanntem Pinchange des entsprechenden Eingangs erhöht. Das ergibt mit 16 Zählimpulsen pro Coderadumdrehung eine deutliche Verbesserung gegenüber den vier Impulsen der orginalen Odometry. Die Impulse werden nur aufsteigend und drehrichtungsunabhängig gezählt. Gleichzeitig wird die Differenz der Seiten seit dem letzen Zählerreset gebildet. Die neuen Funktionen dafür sind:
int odometry_reset(void); // Zähler zurücksetzen
int odometry_get_left(void); // linken Zähler auslesen
int odometry_get_right(void); // rechten Zähler auslesen
int odometry_get_difference(void); // Zählerdifferenz auslesen, positiv bedeutet links>rechts
Desweiteren habe ich eine (in der Library nicht verwendete) Overflow-ISR am Timer1 eingeklinkt. Diese wird mit 15MHz/1022= ca. 15kHz aufgerufen und bildet die Basis für einfache Zeit- und Geschwindigkeitsfunktionen:
void Sleep(uint8_t); // Pause in 1/15000 Sekunden
void Msleep(uint16_t); // Pause in 1/1000 Sekunden
void delay(uint16_t); // ohne delay.h, verwendet Msleep()
uint32_t gettime(void); // Millisekunden seit dem Systemstart (als 32bit-Wert)
int speed_get_left(void); // 1000 minus Anzahl der Overflow-Ticks zwischen zwei positiven Flanken links
int speed_get_right(void); // dito rechts
Maxwerte für die Geschwindigkeitsmessung mit Startwert 1000 sind bei meiner Bee ca. 900 (also 100 Ticks zwischen den Löchern), bei orginalen Coderitzeln muss man die Werte selbst ermitteln. Mein aktueller Arbeitscode dazu:
Soweit, so gut, das funktioniert alles zufriedenstellend. Aber wie kann ich nun die Geschwindigkeiten der Motoren regeln? Alle meine Anläufe die diversen Reglergrößen anzupassen scheiterten bisher kläglich. Selbst einen popeligen P-Regler kann ich nicht umsetzen, weil ich nicht weiß, wie ich die Abtastzeit und die Stellgröße (möglichst ohne float) an meine bee anpassen kann. Hier finde ich den Einstieg nicht, vielleicht kann mir das mal jemand erklären.Code:// nibobee Odometry- und Motorfunktionen 24.1.01 mic
// Modifizierte Odometry mit 8 Löchern in den Ritzeln und Pinchange-Interrupt
// ergibt 16 Flanken pro Umdrehung des Coderitzels.
// Zusätzlich zur Library ist für den Timer1 eine Overflow-ISR eingeklingt die
// mit ca. 15kHz die Zeitbasis für Sleep(), Msleep() und gettime() liefert.
// Außerdem misst diese ISR die Anzahl der Timer1-Overflows zwischen zwei positiven
// Flanken der Odometrysensoren als umgekehrtes Mass für die Geschwindigkeit.
#include <nibobee/iodefs.h>
#include <nibobee/led.h>
#include <nibobee/motpwm.h>
// Variblen
volatile uint8_t count15kHz;
volatile uint32_t count_ms; // 32bit-Zähler!
volatile uint16_t odometry_left=0, odometry_right=0;
volatile int16_t odometry_difference=0;
volatile uint16_t speed_left=0, speed_right=0, speed_left_tmp=1000, speed_right_tmp=1000;
int16_t motor_pwm_left, motor_pwm_right;
uint32_t stopwatch1, stopwatch2;
// Funktionen
void Sleep(uint8_t pause); // ca. 1/15000 Pause blockierend
void Msleep(uint16_t pause); // ca. 1/1000 Pause blockierend
inline void delay(uint16_t pause) { Msleep(pause); }
uint32_t gettime(void); // Millisekunden seit Systemstart als 32bit-Wert
void odometry_reset(void); // Odometryzähler zurücksetzen
int odometry_get_left(void); // Odometryzähler auslesen
int odometry_get_right(void);
int odometry_get_difference(void); // Zählerunterschied seit dem letzten odo_reset
int speed_get_left(void); // Geschwindigkeit auslesen
int speed_get_right(void);
#include "lcd_lib.c" // Hier muss man die eigene LCD-Lib einbinden
int main(void)
{
led_init();
motpwm_init();
TIMSK |= (1 << TOIE1); // Die Overflow-ISR misst die Geschwindigkeit der Antriebe
enable_interrupts();
lcd_init();
lcd_writeString(" Nibobee mit LCD");
led_set(0,1);
Msleep(2000); // wait4programmer
lcd_writeStringAt(0,3,"Bitte Taste druecken");
while(!lcd_getkeys()) {PORTB ^= (1<<PB0); Msleep(100);}
led_set(0,0);
// Odometry: enable int0 and int1 on pinchange
MCUCR = (1<<ISC10) | (1<<ISC00); // Interrupt bei Pinchange
GICR |= (1<<INT1) | (1<<INT0); // Int0 und Int1 freigeben
lcd_cls();
lcd_writeString(" Odometrywerte");
lcd_writeStringAt(0,2,"Sp/PWM Li:");
lcd_writeStringAt(0,3,"Sp/PWM Re:");
motor_pwm_left=motor_pwm_right=300;
stopwatch1=stopwatch2=gettime();
while(1)
{
odometry_reset();
while((odometry_get_left()+odometry_get_right()) < 998) // Sollposition 1000
{
motpwm_setLeft(motor_pwm_left); motpwm_setRight(motor_pwm_right);
if((odometry_get_left()+odometry_get_right()) < 900) // Verzögerungspunkt
{
if(gettime() > stopwatch1)
{
stopwatch1=gettime()+20; // alle 20 Millisekunden ausführen
if(odometry_difference > 0)
{
motor_pwm_left--;
motor_pwm_right++;
}
else
{
motor_pwm_left++;
motor_pwm_right--;
}
}
}
else
{
motor_pwm_left=motor_pwm_right=200; // Einfahrgeschwindigkeit
}
if(gettime() > stopwatch2)
{
stopwatch2=gettime()+300;
lcd_writeIntegerAt(11,2,speed_get_left(), 10);
lcd_writeString("/");
lcd_writeInteger(motor_pwm_left, 10);
lcd_writeString(" ");
lcd_writeIntegerAt(11,3,speed_get_right(), 10);
lcd_writeString("/");
lcd_writeInteger(motor_pwm_right, 10);
lcd_writeString(" ");
}
}
motpwm_stop();
Msleep(200);
lcd_writeStringAt(0,1,"L ");
lcd_writeInteger(odometry_get_left(), 10);
lcd_writeString(" R ");
lcd_writeInteger(odometry_get_right(), 10);
lcd_writeString(" S ");
lcd_writeInteger(odometry_get_difference(), 10);
lcd_writeString(" ");
motor_pwm_left=motor_pwm_right=300;
while(!lcd_getkeys()) {PORTB ^= (1<<PB0); Msleep(100);}
}
return(0);
}
ISR(INT0_vect)
{
// static uint8_t flag=0; // nur jedes zweite Loch zählen für orginale bee
odometry_left++;
odometry_difference++;
if(PIND & (1<<PD2)) // if(flag++)
{
speed_left=(speed_left+speed_left_tmp)/2; // unterschiedliche Lochabstände ausgleichen
speed_left_tmp=1000;
// flag=0;
}
PORTB ^= (1<<PB0); // Kontrolle mit LED0
}
ISR(INT1_vect)
{
//static uint8_t flag=0;
odometry_right++;
odometry_difference--;
if(PIND & (1<<PD3)) // if(flag++)
{
speed_right=(speed_right+speed_right_tmp)/2;
speed_right_tmp=1000;
// flag=0;
}
PORTB ^= (1<<PB3); // Kontrolle mit LED3
}
ISR(TIMER1_OVF_vect)
{
static uint8_t count_ms_temp=15;
if(speed_left_tmp) speed_left_tmp--;
if(speed_right_tmp) speed_right_tmp--;
//PORTB ^= (1<<PB2); // Kontrolle mit LED2
if(count15kHz) count15kHz--;
if(!count_ms_temp--) {count_ms++; count_ms_temp=15;}
}
void Sleep(uint8_t pause) // ca. 1/15000 Pause blockierend
{
count15kHz=pause;
while(count15kHz);
}
void Msleep(uint16_t pause) // ca. 1/1000 Pause blockierend
{
while(pause--) Sleep(15);
}
uint32_t gettime(void) // Millisekunden seit Systemstart als 32bit-Wert
{
uint32_t temp32;
cli();
temp32=count_ms;
sei();
return(temp32);
}
void odometry_reset(void)
{
cli();
odometry_left=odometry_right=odometry_difference=0;
sei();
}
int odometry_get_left(void)
{
uint16_t temp16;
cli();
temp16=odometry_left;
sei();
return(temp16);
}
int odometry_get_right(void)
{
uint16_t temp16;
cli();
temp16=odometry_right;
sei();
return(temp16);
}
int odometry_get_difference(void)
{
uint16_t temp16;
cli();
temp16=odometry_difference;
sei();
return(temp16);
}
int speed_get_left(void)
{
uint16_t temp16;
cli();
temp16=speed_left;
sei();
return(temp16);
}
int speed_get_right(void)
{
uint16_t temp16;
cli();
temp16=speed_right;
sei();
return(temp16);
}
Gruß
mic
Hallo
ich bin mal so dreist und hole diesen thread aus der Versenkung.
Ich hab mit meinem Bienchen mittlerweile auch schon allerhand unsinn angestellt und möchte ihn jetzt auch Hardware seitig umbauen.
Gut gefiel mir die idee die taster durch ir dioden zu ersetzen, aber mir ist nicht so ganz klar wie ich das machen muss.
drum die frage ob mir das mal einer erklären kann?
danch würd ich gerne ein kleinen arm auf meine bienchen bauen, dafür bräuchte ich drei so mini servos kann ich die überhaupt alle ansteuern?
und geht des einigermassen lkeicht? ich hab mich bisher nur mit den standard funktionen beschäftigt
was haltet ihr von diesen Servos?
mfg Sebastian
Hallo
Das wurde hier mal vorgeschlagen, aber nie umgesetzt:
https://www.roboternetz.de/phpBB2/ze...=476661#476661
Daraus ist dann eine IR-Abstandmessung für die bee geworden die wir hier zusammengebastelt haben:
https://www.roboternetz.de/phpBB2/ze...ag.php?t=52115
Mehrere Servos anzuschliesen und anzusteuern ist kein Problem mit der bee. Als Basis könntest du diese Servo-ISR verwenden:
https://www.roboternetz.de/phpBB2/ze...=474468#474468
Für mehrere Servos sind die AAAs der Biene zu schwach. Mit AAs könnte sie den geplanten Arm auch besser ausbalancieren:
Bild hier
Gruß
mic
vielen dank ich lese es mir gleich mal durch
den thread mit der abstandsmessung hab ich bei meiner suche gar nicht gefunden, muss ich wohl noch weng üben;-)
bei den servos ist irgendwie der link verschwunden bzw wurde durch den link ins rn wissen ersetzt hier nochmal
was meint ihr dazu
http://cgi.ebay.de/ws/eBayISAPI.dll?...=STRK:MEWAX:IT
Hallo,
ich möchte auch ein LCD über I²C betreiben. Nur leider klappts nicht so richtig und ich finde den Fehler einfach nicht. Die BGX1 Lib is eingefügt und dann hab ich den Code einfach kopiert. Trotzdem kommt diese Fehlermeldung.
Code:../lcdi2c.c: In function 'lcd_writePCF8574':
../lcdi2c.c:174: error: 'i2c_size' undeclared (first use in this function)
../lcdi2c.c:174: error: (Each undeclared identifier is reported only once
../lcdi2c.c:174: error: for each function it appears in.)
../lcdi2c.c: In function 'lcd_pushNibble':
../lcdi2c.c:186: error: 'i2c_size' undeclared (first use in this function)
make: *** [lcdi2c.o] Error 1
Build failed with 4 errors and 0 warnings...
Dann hab ich "i2c_size" einfach mal auskommentiert um zu schauen ob noch mehrere Fehler kommen. Dann kam folgendes
Wäre dankbar für einen Tipp....Code:D:\programme\nibobee\lib\libnibobee_bgx1.a(i2cmaster.o): In function `i2c_init':
i2cmaster.c:(.text.i2c_init+0x16): undefined reference to `nibobee_initialization'
i2cmaster.c:(.text.i2c_init+0x1c): undefined reference to `nibobee_initialization'
make: *** [Elsy_NiBoBee.elf] Error 1
Build failed with 2 errors and 0 warnings...
Danke im Voraus
Die BGX1 Bibliothek (libnibobee_bgx1.a) muss noch dazugelikt werden!
Linker-Option: -l nibobee_bgx1
Nach etwa einer 1 stündigen suche bin ich noch immer nicht weiter. Wie linke ich die denn dazu?
Und wieso hab ich mit den anderen Libs keine Probleme?
Ich nehme an Du verwendest AVRStudio? Hast Du schon mal das Tutorial zum NIBObee durchgearbeitet?
Ja ich verwende das AVRStudio.
Ich hab auch das Tutorial durchgearbeitet. Hat auch alles funktioniert.
Nur das mit der BGX1 Lib funktioniert nicht. Hab auch schon ein neues Projekt erstellt aber es bleibt das gleiche Problem. Es wird wohl nchit viel sein...
Auf Seite 16 steht ja, dass man die Reihenfolge beachten soll. Hab das so wie im Tutorial gemacht und am Schluss die BGX1 hinzugefügt. Also wirds daran ja nicht liegen
Hallo,
ich habe mal ins Makefile geschaut und da steht folgendes:
Also müsste die BGX1 gelinkt sein oder?!?Code:## Libraries
LIBS = -lnibobee_base -lnibobee_line -lnibobee_utils -lnibobee_bgx1
Meiner Meinung liegts doch eher an der i2cmaster.h. Dort ist die Variable "i2c_size" deklariert und diese Headerdatei ist auch eingebunden. Trotzdem kennt er diese Variabel nicht.....
Hallo,
das LCD funktioniert mittlerweile einwandfrei. Weiss auch nicht genau, wo der Fehler mit der Lib lag...
Habe nun ein anderes Problem. Ich bentutze ein LCD mit dem HD44780. Schreiben und so weiter auf das Display funktioniert auch. Nur die Funktion lcd_setCursor(0,1); funktioniert nicht. Wenn ich sie aufrufe und danach was schreiben möchte erscheint nichts auf dem Display.
Hallo Roboternetz,
dieser Beitrag soll den alten ersetzen, da dieser u.a. nicht wirklich gut formuliert war. 8-[
Ich würde gerne mit meiner NIBObee die Helligkeit von einem Gegenstand ermitteln, der vor meiner Biene steht.
Es gibt ein Video bei youtube, welches einen ASURO zeigt, der genau das macht und sich abhängig von der Helligkeit bewegt: "Müll sortierender ASURO".
Leider wird das Verfahren nicht genauer erläutert, aber ich dachte, dass es über Infrarot geht (so wie z.B. bei den Liniensensoren), weswegen ich im Folgenden 3 Alternativen aufführen möchte und um eure Beurteilung dieser bitte.
1) Liniensensoren nachbauen
Auf die Liniensensoren habe ich bereits oben schon verwiesen, allerdings möchte ich dies nun spezifizieren. Da die Liniensensoren ebenfalls die Helligkeit des Untergrunds messen, dachte ich, dass man ggf. mit einem ähnlichen oder gleichen Aufbau die Helligkeit eines Objektes messen könnte.
Konkret war meine Überlegung: eine IR-LED sowie einen IR-Transistor zu verwenden und zur Messung dann die Spannung am Ausgang des Transistors zu messen (geht das?).
2) Sharp Entfernungssensor GP2D120
Daneben bin ich mehrfach auf die Sensorreihe von Sharp gestoßen, mit denen man ja eig. Entfernungen bestimmen kann. Könnte ich mit einem von diesen auch die Helligkeit ermitteln? Rabenauge hat an dieser Stelle bereits etwas über die Verwendung von einem Sharp-Sensor an der NIBObee geschrieben.
3) Verwendung eines IR-Empfängers
Außerdem hab ich an einigen Stellen gesehen, dass ein IR-Empfänger verwendet wurde, Beispiel: von Pinsel120866. In dem Link wird ein IR-Empfänger + 2 IR-LEDs zur Abstandmessung verwendet.
Da ich neben dem Programmiertutorial zur NIBObee noch nicht viel Erfahrung gesammelt habe, denke ich, dass die 3. Möglichkeit rausfällt, da diese am schwierigsten zu programmieren ist.
Bei Möglichkeit 1 bin ich mir allerdings nicht sicher, ob eine IR-LED und ein IR-Transistor reicht - könnt ihr dazu genaueres sagen? (das stellt eig. mein Hauptanliegen dar)
Möglichkeit 2 möchte ich erstmal unkommentiert lassen.
Liebe Grüße und ein frohes neues Jahr
Max.
Edit 1:
Möglichkeit 2 fällt raus:
Damit bleiben noch Möglichkeit 1 und 3 offen, wobei ich 1 bevorzuge. Bei Möglichkeit 1 bin ich mir aber nicht sicher, wie diese umsetzen muss:Zitat:
Farbunabhängig ermittelt die Auswertelektronik die Entfernung und gibt sie über Analogsignal aus.
Reicht es, wenn ich die IR-LED & den Vorwiderstand an + und - eines Ports anschließe und die Kathode des IR-Transistor an das analoge Signal eines Ports (wo muss ich die Anode anschließen), damit ich diesen über analog_getValue() abfragen kann?
@aurikeL:
Das reicht fast, Du benötigst 2 Widerstände. Einen als Vorwiderstand für die IR-LED (180 Ohm) und einen als Strom/Spannungswandler für den Fototransistor (2,2 kOhm).
Im Schaltplan zur NIBObee auf Seite 1 ist die Schaltung für die Liniensensoren abgebildet (gestrichelter Kasten).
Passende IR-LEDs und Fototransitoren findest Du hier: http://www.nibo-roboter.de/wiki/NIBObee/Ersatzteile
Die Schaltung kannst Du an X1 (2 analoge Eingänge) oder X2 bzw. X3 (jeweils 1 analoger Eingang) anschliessen.
Die IR-LED kannst Du auch schaltbar an einem Port-Ausgang betreiben, sie benötigt keinen extra Treiber.
Mit dem Ziel, dass die Biene Farben (minimal 2) erkennen kann - sind die beiden oberen Beiträge entstanden. Daneben war ich mehrmals im #roboternetz.de IRC-Chat, in dem ich auf Schumi gestoßen, der mich eine große Hilfe war. Einen besonderen Dank an ihn - an die anderen, die mir geholfen haben, aber auch! =D>
Das Resultat ist nun folgendes (leider in schlechter Qualität):
http://www.youtube.com/watch?v=Y2hlnTpRI9s
Der Aufbau ist folgender:
Ein grüner Gegenstand wird z.T. falsch erkannt, allerdings verwende ich auch grüne Legosteine - die sind etwas dunkel.Code:LED1: [AVR]--[R]--[+LED-]--[VCC]
LED2: [AVR]--[R]--[+LED-]--[VCC]
LED3: [AVR]--[R]--[+LED-]--[VCC]
Sensor: [+5V]--[LDR]--+--[R]--[VCC]
[AVR]-----------|
Ein Link zum Aufbau: http://img718.imageshack.us/img718/5...0108193606.jpg
Edit: ein Grund für die oben genannten Ungenauigkeiten sind, dass z.T. Licht direkt von der LED auf den Fotowiderstand fällt - deswegen auch die Papiere, allerdings sind diese nicht wirklich gut. Ich muss morgen mal meinen Schrumpfschlauch suchen, aber den muss ich irgendwie verlegt haben (gestern hab ich ihn nicht gefunden).
Edit2: Anbei noch mein Code (ich bin für Verbesserungen offen - ob der "Dummyreadout" so notwendig ist, sei an dieser Stelle dahingestellt):
Die 0,5 Sek Wartezeit sind wahrs. viel zu hoch dimensioniert, allerdings stört mich die Wartezeit momentan nicht, weshalb ich bisher keinen Grund sehe, diese zu reduzieren.Code:#define StatusLEDs_on PORTB |= (1 << PB1) | (1 << PB2);
#define StatusLEDs_off PORTB &= ~((1 << PB1) | (1 << PB2));
#include <nibobee/iodefs.h>
#include <nibobee/led.h>
#include <nibobee/delay.h>
#include <nibobee/analog.h>
#include <nibobee/sens.h>
#include <avr/io.h>
// Aufbau:
// Farbe1: [PA0]--[R]--[+LED-]--[GND]
// Farbe2: [PA1]--[R]--[+LED-]--[GND]
// Farbe3: [PA2]--[R]--[+LED-]--[GND]
// Sensor: [+5V]--[LDR]--+--[R]--[GND]
// Sensor: [PA3]---------|
uint16_t getLightValue() {
int Value = 0;
int8_t i;
// Auslesen
for (i = 0; i < 11; i++) {
Value = Value + analog_getValue(ANALOG_EXT3);
delay(50);
} // for
return(Value / i);
} // getValue()
int main()
{
uint16_t grValue, blValue, reValue;
int8_t i;
led_init(); // LED initialisieren
analog_init(); // Analoge Eingaenge initialisieren
sens_init(); // Fuehler initialisieren
enable_interrupts(); // Interrupts aktivieren
DDRA |= 0b00000111; // PINs als Ausgaenge schalten
DDRB |= 0b00000110; // PINs als Ausgaenge schalten
// Dummyreadout
for (i = 0; i < 11; i++) {
grValue = analog_getValue(ANALOG_EXT3);
delay(50);
}
while (1 == 1) {
StatusLEDs_on;
while ((sens_getLeft() != 0) | (sens_getRight() != 0)) {
StatusLEDs_off;
// Farbmessungen
// 1. gruen
PORTA = 0b00000001; // LED anschalten
delay(500); // 0,5 Sek. warten
grValue = getLightValue(); // Wert des Sensors abfragen
// 2. rot
PORTA = 0b00000010; // LED anschalten
delay(500); // 0,5 Sek. warten
reValue = getLightValue() - 25; // Wert des Sensors abfragen
// 3. blau
PORTA = 0b00000100; // LED anschalten
delay(500); // 0,5 Sek. warten
blValue = getLightValue() - 75; // Wert des Sensors abfragen
// Auswertung
if ((grValue > reValue) & (grValue > blValue)) {
// gruener Gegenstand
PORTA = 0b00000001; // gruene LED an
} else if ((reValue > grValue) & (reValue > blValue)) {
// roter Gegenstand
PORTA = 0b00000010; // rote LED an
} else if ((blValue > grValue) & (blValue > reValue)) {
// blauer Gegenstand
PORTA = 0b00000100; // blaue LED an
} else {
// keine Erkennung
PORTA = 0b00000111; // alle LEDs an
} // if
} // while - Fuehler
} // while - Endlosschleife
return 0;
}