firescorpion
14.12.2012, 23:15
Hallo liebe Community,
ich bin neu hier und habe ein extrem dringendes Problem mit der SnakeVision von Asuro. Leider sind meine Programmier- geschweige denn Microcontrollerkenntnisse sehr beschränkt :(
Folgendes Problem: Wenn die ganz normalen Taster von Asuro in der Schleife des SnakeVision Programmes abgefragt werden, um Asuro dazu zu bringen, dass er nach Kollision mit Wänden etwas anderes tut, dann funktioniert plötzlich der linke Wärmesensor nicht mehr richtig.
Das Programm für die Verfolgung der Wärmequellen beruht auf dem Algorithmus aus dem Buch "Mehr Spaß mit Asuro Band2". Funktioniert soweit auch ziemlich gut. Sogar das Löschen von Teelichtern mit einem eingebauten Ventilator hat schon geklappt. Nur, wenn PollSwitch() ins Spiel kommt, geht halt der linke Sensor kaum noch :( Er erkennt bei Raumtemperatur meinen Finder dann nur noch auf wenige Millimeter Entfernung, während der rechte Sensor den Finger noch bei über 10cm Abstand erkennt (was der linke ja normalerweise auch tut)...
Habe dazu auch nirgends was passendes gefunden im Internet, deshalb seid ihr meine letzte Rettung. Kann es sein, dass da irgendwas gleichzeitig an einem Prozessorpin hängt oder dergleichen? Oder übersehe ich etwas bei der Programmierung? Habe leider echt nich das nötige KnowHow, um das selbst herauszufinden.
Hier mal der Code (ist jetzt erstmal einfach nur der Standard SnakeVision Code aus dem Buch, bloß mit Abbruch durch PollSwitch():
#include "asuro.h"
//Schwellen für die intensitätsabhängige Geschwindigkeit
#define THRESH1 20
#define THRESH2 80
#define THRESH3 200
//Funktion, um Tasterwert abzufragen
char switchwert(void){
char taste=0;
unsigned char t1,t2,t3;
t1=PollSwitch();
t2=PollSwitch();
t3=PollSwitch();
if((t1 == t2)&& (t2==t3))
{taste=t1;}
return taste;
}
//testet beim Fahren auf die Abbruchbedingungen
int abbruchtest(void){
int abbruch=0;
char tasten=switchwert();
if(tasten>0){
abbruch=1;
StatusLED(YELLOW);
}
return abbruch;
}
void ThermalData(unsigned int *data){
/* ThermalData() funktioniert genausi, wie LineData(), nur, dass dabei
die interne Spannungsreferenz als AD-Wandlerdifferenz verwendet wird.*/
//Prozessorinterne Referenz verwenden
//Multiplexer auf linken Sensor schalten
ADMUX = (1 << REFS0) | (1 << REFS1) | IR_LEFT;
//Wandlung starten
ADCSRA |= (1 << ADSC);
//Warten bis Wandlung beendet ist
while (!(ADCSRA & (1 << ADIF)));
//ADCIF zurücksetzen
ADCSRA |= (1 << ADIF);
//ADC-Wert auslesen
data[0] = ADCL + (ADCH << 8);
// Multiplexer auf rechten Sensor schalten
ADMUX = (1 << REFS0) | (1 << REFS1) | IR_RIGHT;
// Wandlung starten
ADCSRA |= (1 << ADSC);
// Warten, bis Wandlung beendet
while (!(ADCSRA & (1 << ADIF)));
// ADCIF zurücksetzen
ADCSRA |= (1 << ADIF);
// ADC-Wert auslesen
data[1] = ADCL + (ADCH << 8);
}
int main(void)
{
// Speicher für die Messwerte bereitstellen
unsigned int tdata[2],offset[2];
unsigned int speed;
signed int diff,sum;
Init();
//Port D, Pin 6 (die ehemalige FrontLED), auf Eingang schalten und den Pullup aktivieren.
DDRD&=~(1<<6);
PORTD|=(1<<6);
// Motoren immer auf vorwärts
MotorDir(FWD,FWD);
//Offset mit 0 initialisieren
offset[0]=0;
offset[1]=0;
int abbr=0;
while(abbr==0)
{
//Messwerte einlesen
ThermalData(tdata);
//Wenn Knopf gedrückt, den aktuellen Wert als Offset speichern
if ((PIND&(1<<6))==0){
offset[0]=tdata[0];
offset[1]=tdata[1];
}
//Offset abziehen, aber nur, wenn der Messwert groß genug ist, sonst gibt's nen Überlauf
if(tdata[0]>offset[0]) tdata[0]-=offset[0];
else tdata[0]=0;
if(tdata[1]>offset[1]) tdata[1]-=offset[1];
else tdata[1]=0;
/* Die Summe der Werte wird für die
Berechnung derGeschwindigkeit genutzt*/
sum=tdata[0]+tdata[1];
// Signal stark genug?
if (sum>THRESH1) {
StatusLED(GREEN);
speed=140;
// Ziemlich stark?
if (sum>THRESH2) {
StatusLED(YELLOW);
speed=200;
}
// Sehr stark?
if (sum>THRESH3) {
StatusLED(RED);
speed=255;
}
// Richtung bestimmen
diff=((signed)tdata[0]-(signed)tdata[1])*32/sum;
if (diff>4) {
// Links deutlich wärmer? Nach links fahren!
MotorSpeed(0,speed);
}
else if (diff<-4) {
// Rechts deutlich wärmer? Nach rechts fahren!
MotorSpeed(speed, 0);
}
else {
// Sonst geradeaus!
MotorSpeed(speed, speed);
}
}
else {
// Keine Wärmequelle in Sicht? Stehen bleiben!
StatusLED(OFF);
MotorSpeed(0,0);
}
abbr=abbruchtest();
}
MotorSpeed(0,0);
return 0;
}
Ich hoffe, dass mir jemand helfen kann, bin schon total verzweifelt :(
Danke schonmal an alle!
VG
ich bin neu hier und habe ein extrem dringendes Problem mit der SnakeVision von Asuro. Leider sind meine Programmier- geschweige denn Microcontrollerkenntnisse sehr beschränkt :(
Folgendes Problem: Wenn die ganz normalen Taster von Asuro in der Schleife des SnakeVision Programmes abgefragt werden, um Asuro dazu zu bringen, dass er nach Kollision mit Wänden etwas anderes tut, dann funktioniert plötzlich der linke Wärmesensor nicht mehr richtig.
Das Programm für die Verfolgung der Wärmequellen beruht auf dem Algorithmus aus dem Buch "Mehr Spaß mit Asuro Band2". Funktioniert soweit auch ziemlich gut. Sogar das Löschen von Teelichtern mit einem eingebauten Ventilator hat schon geklappt. Nur, wenn PollSwitch() ins Spiel kommt, geht halt der linke Sensor kaum noch :( Er erkennt bei Raumtemperatur meinen Finder dann nur noch auf wenige Millimeter Entfernung, während der rechte Sensor den Finger noch bei über 10cm Abstand erkennt (was der linke ja normalerweise auch tut)...
Habe dazu auch nirgends was passendes gefunden im Internet, deshalb seid ihr meine letzte Rettung. Kann es sein, dass da irgendwas gleichzeitig an einem Prozessorpin hängt oder dergleichen? Oder übersehe ich etwas bei der Programmierung? Habe leider echt nich das nötige KnowHow, um das selbst herauszufinden.
Hier mal der Code (ist jetzt erstmal einfach nur der Standard SnakeVision Code aus dem Buch, bloß mit Abbruch durch PollSwitch():
#include "asuro.h"
//Schwellen für die intensitätsabhängige Geschwindigkeit
#define THRESH1 20
#define THRESH2 80
#define THRESH3 200
//Funktion, um Tasterwert abzufragen
char switchwert(void){
char taste=0;
unsigned char t1,t2,t3;
t1=PollSwitch();
t2=PollSwitch();
t3=PollSwitch();
if((t1 == t2)&& (t2==t3))
{taste=t1;}
return taste;
}
//testet beim Fahren auf die Abbruchbedingungen
int abbruchtest(void){
int abbruch=0;
char tasten=switchwert();
if(tasten>0){
abbruch=1;
StatusLED(YELLOW);
}
return abbruch;
}
void ThermalData(unsigned int *data){
/* ThermalData() funktioniert genausi, wie LineData(), nur, dass dabei
die interne Spannungsreferenz als AD-Wandlerdifferenz verwendet wird.*/
//Prozessorinterne Referenz verwenden
//Multiplexer auf linken Sensor schalten
ADMUX = (1 << REFS0) | (1 << REFS1) | IR_LEFT;
//Wandlung starten
ADCSRA |= (1 << ADSC);
//Warten bis Wandlung beendet ist
while (!(ADCSRA & (1 << ADIF)));
//ADCIF zurücksetzen
ADCSRA |= (1 << ADIF);
//ADC-Wert auslesen
data[0] = ADCL + (ADCH << 8);
// Multiplexer auf rechten Sensor schalten
ADMUX = (1 << REFS0) | (1 << REFS1) | IR_RIGHT;
// Wandlung starten
ADCSRA |= (1 << ADSC);
// Warten, bis Wandlung beendet
while (!(ADCSRA & (1 << ADIF)));
// ADCIF zurücksetzen
ADCSRA |= (1 << ADIF);
// ADC-Wert auslesen
data[1] = ADCL + (ADCH << 8);
}
int main(void)
{
// Speicher für die Messwerte bereitstellen
unsigned int tdata[2],offset[2];
unsigned int speed;
signed int diff,sum;
Init();
//Port D, Pin 6 (die ehemalige FrontLED), auf Eingang schalten und den Pullup aktivieren.
DDRD&=~(1<<6);
PORTD|=(1<<6);
// Motoren immer auf vorwärts
MotorDir(FWD,FWD);
//Offset mit 0 initialisieren
offset[0]=0;
offset[1]=0;
int abbr=0;
while(abbr==0)
{
//Messwerte einlesen
ThermalData(tdata);
//Wenn Knopf gedrückt, den aktuellen Wert als Offset speichern
if ((PIND&(1<<6))==0){
offset[0]=tdata[0];
offset[1]=tdata[1];
}
//Offset abziehen, aber nur, wenn der Messwert groß genug ist, sonst gibt's nen Überlauf
if(tdata[0]>offset[0]) tdata[0]-=offset[0];
else tdata[0]=0;
if(tdata[1]>offset[1]) tdata[1]-=offset[1];
else tdata[1]=0;
/* Die Summe der Werte wird für die
Berechnung derGeschwindigkeit genutzt*/
sum=tdata[0]+tdata[1];
// Signal stark genug?
if (sum>THRESH1) {
StatusLED(GREEN);
speed=140;
// Ziemlich stark?
if (sum>THRESH2) {
StatusLED(YELLOW);
speed=200;
}
// Sehr stark?
if (sum>THRESH3) {
StatusLED(RED);
speed=255;
}
// Richtung bestimmen
diff=((signed)tdata[0]-(signed)tdata[1])*32/sum;
if (diff>4) {
// Links deutlich wärmer? Nach links fahren!
MotorSpeed(0,speed);
}
else if (diff<-4) {
// Rechts deutlich wärmer? Nach rechts fahren!
MotorSpeed(speed, 0);
}
else {
// Sonst geradeaus!
MotorSpeed(speed, speed);
}
}
else {
// Keine Wärmequelle in Sicht? Stehen bleiben!
StatusLED(OFF);
MotorSpeed(0,0);
}
abbr=abbruchtest();
}
MotorSpeed(0,0);
return 0;
}
Ich hoffe, dass mir jemand helfen kann, bin schon total verzweifelt :(
Danke schonmal an alle!
VG