PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Frage zur Funktionsweise eines Anti Collision System (mit Infrarot)



emty
05.06.2012, 15:34
Hallo, ich hab eine Verständnis Frage zu dem ACS des RP6.

Das ACS besteht aus einem IR Empfänger und 2 IR LEDs.22489

Woran erkennt jetzt der IR Empfänger von welcher IR LED der Strahl reflektiert wird?
Liegt es an der Frequenz oder an etwas anderem?

Schon mal Danke für Antworten.

PICture
05.06.2012, 16:13
Hallo!


Woran erkennt jetzt der IR Empfänger von welcher IR LED der Strahl reflektiert wird?

Am einfachsten wäre, falls möglich, die IR LED's abwechselnd einschalten. ;)

radbruch
05.06.2012, 16:42
Hallo

Ein Blick in den Schaltplan (Seite 2) der Base offenbart es:

https://www.roboternetz.de/community/attachment.php?attachmentid=22490&stc=1&d=1338910720

Die ACS-LEDs können getrennt angesteuert werden:

/**
* Disables the ACS task.
* ACS and IRCOMM Transmissions/Receptions will not work anymore.
*/
void disableACS(void)
{
acs_state = ACS_STATE_IDLE;
TIMSK &= ~(1 << OCIE2);
IRCOMM_OFF();
PORTB |= ACS_L;
PORTC |= ACS_R;
obstacle_right = false;
obstacle_left = false;
}

/**
* Enables the ACS task.
*/
void enableACS(void)
{
TIMSK &= ~(1 << OCIE2);
IRCOMM_OFF();
PORTB |= ACS_L;
PORTC |= ACS_R;
obstacle_right = false;
obstacle_left = false;
acs_state = ACS_STATE_IRCOMM_DELAY;
}

/**
* Turn ACS Power off.
*
* Example:
*
* setACSPwrOff();
*
*/
void setACSPwrOff(void)
{
DDRD &= ~ACS_PWR;
PORTD &= ~ACS_PWR;
DDRB &= ~ACS_PWRH;
PORTB &= ~ACS_PWRH;
PORTB &= ~ACS_L;
PORTC &= ~ACS_R;
}

/**
* Set ACS Power low.
*
* Example:
*
* setACSPwrLow();
*
*/
void setACSPwrLow(void)
{
DDRD |= ACS_PWR;
PORTD |= ACS_PWR;
DDRB &= ~ACS_PWRH;
PORTB &= ~ACS_PWRH;
}

/**
* Set ACS Power medium.
*
* Example:
*
* setACSPwrMed();
*
*/
void setACSPwrMed(void)
{
DDRD &= ~ACS_PWR;
PORTD &= ~ACS_PWR;
DDRB |= ACS_PWRH;
PORTB |= ACS_PWRH;
}

/**
* Set ACS Power high.
*
* Example:
*
* setACSPwrHigh();
*
*/
void setACSPwrHigh(void)
{
DDRD |= ACS_PWR;
PORTD |= ACS_PWR;
DDRB |= ACS_PWRH;
PORTB |= ACS_PWRH;
}
(Aus RP6RobotBaseLib.c)

Mit ACS_PWR und ACS_PWRH kann man R8 und R9 in unterschiedlichen Kombinationen ansteuern und so den Strom durch die ACS-LEDs und die Leuchtstärke beeinflußen.

Gruß

mic


[Edit]

Ach ja, ganz vergessen, die Kathoden liegen an ACS_L/ACS_R. Die Leds leuchten, wenn sie auf low liegen und über R8/9 ein high ausgegeben wird:
https://www.roboternetz.de/community/attachment.php?attachmentid=22492&stc=1&d=1338911618

[Noch ein Edit]
Bei der Suche nach dem Urheber der 36kHz-Trägerfrequenz für das ACS habe ich die getrennte Ansteuerung der ACS-LEDs gefunden:


// -------------------------------

/**
* Timer 2 Compare ISR
* ACS & IRCOMM
*
* WARNING: DO NOT CHANGE THIS!
* NEVER try to control the IRCOMM by your own routines if you do not
* know what you are doing!
*
*/
ISR (TIMER2_COMP_vect)
{
static uint8_t ircomm_pulse;
if(acs_state < 2) { // If ACS is not active, perform IRCOMM transmissions
if(ircomm_pulse) { // Do we have IR pulses to send?
if(ircomm_pulse < 60) { // Bi-Phase encoding...
if(ircomm_data & 0x4000) // check current bit
PORTD ^= (1<<PIND7); // Toggle IRCOMM port
else
PORTD &= ~(1<<PIND7); // deactivate IRCOMM port
}
else if(ircomm_data & 0x4000) // The same as above, but the other way round:
PORTD &= ~(1<<PIND7); // deactivate IRCOMM port
else
PORTD ^= (1<<PIND7); // Toggle IRCOMM port
ircomm_pulse--;
}
else if(ircomm_send) { // Do we still have data?
PORTD &= ~(1<<PIND7);
ircomm_data <<= 1; // Next Bit!
ircomm_pulse = 120;
ircomm_send--;
}
else
PORTD &= ~(1<<PIND7); // no more pulses - IR LEDs off!
}
else if(acs_pulse) { // Send ACS IR pulses?
if(sysStatACS.channel == ACS_CHANNEL_LEFT) // which channel?
PORTB ^= ACS_L;
else
PORTC ^= ACS_R;
acs_pulse--;
}
else { // no more pulses - IR LEDs off!
PORTB |= ACS_L;
PORTC |= ACS_R;
}
}
(Ebenfalls aus RP6RobotBaseLib.c)

RP6fahrer
20.07.2013, 19:49
Hey Leute,
ich weiß, das dieses Thema schon vor Jahren abgeschlossen wurde, aber ich habe zu meinem Problem keinen anderen Thread gefunden. Da ich momentan Montagemäßig unterwegs bin und dort immer mal Freizeit hab, hab ich gedacht, ich kümmer mich mal wieder um meinen RP6. Ich habe ihm eine Bumperplatine hinten angebaut mit zwei Bumpern, deren Anschluss und Auswertung genau wie die der vorderen Bumper erfolgt. Sie heißen nur Bumper_backleft und Bumper_backright. Ich habe die auch I2C tauglich gemacht und alles funktioniert wunderbar. Jetzt habe ich mir gedacht, ich baue das ACS auch nochmal für hinten nach. Da ich noch nen ATmega 16 übrig hab, hab ich mir gedacht, den nehme ich für das ACS nach hinten. Ich habe dann die Schaltung auf ein Steckboard 1:1 nachgebaut, wie ich sie in der Anleitung des Roboters gefunden hab. Die gleichen Teile, IR-LEDs usw, außer den IR Empfänger. Das ist bei mir ein TSOP31236. Der ist aber gleich wie der von Arexx verwendete (Datenblattvergleich). Den Programmcode nur für ACS, Timer2 steuerung INT2 hab ich alles von der RP6 Library übernommen. Compilieren ging einwandfrei und das laden via ISP in den Controller ging auch. Aber das Programm macht nichts. Es will einfach nicht funktionieren.
Das ist mein ganzes Programm:

#include "ATmega16.h"

/************************************************** ************/
void acsStateChanged(void)
{
if(obstacle_left)
PORTB ^= IOB0;
}
/************************************************** *************/
int main(void) //Hier beginnt das Hauptprogramm
{
initATmega();
PORTB |= IOB0 | IOB4 | IOB5; //Hier hängen StatusLEDs dran
delay_ms(200);
PORTB &= IOB0 & IOB5;
ACS_setStateChangedHandler(acsStateChanged);
enableACS();
setACSPwrHigh();

while (1)
{

task_ACS();
}
return 0;
}

Das einzige was passiert Die LEDs gehen an, nach 200ms geht nur LED an IOB5 aus. Mehr macht er nicht. Wie gesagt, der Programmcode ist komplett aus der RP6 Library übernommen.

Hier mal ein Auszug für initATmega():

void initATmega(void)
{
portInit(); // Setup port directions and initial values.
// THIS IS THE MOST IMPORTANT STEP!

//Initialisierung ADC

ADCSRA = (0<<ADEN) | (0<<ADIE) | (1<<ADPS2) | (1<<ADPS1)| (1<<ADIF);
ADMUX |= (1<<REFS0); //Interne Referenzspannung nehmen
//SFIOR = 0;

GICR = (1 << INT2);
MCUCSR = (0 << ISC2);

// Initialize Timer 0 - 100µs cycle for Delays/Stopwatches, etc.:
TCCR0 = (0 << WGM00) | (1 << WGM01)
| (0 << COM00) | (0 << COM01)
| (0 << CS02) | (1 << CS01) | (0 << CS00);
OCR0 = 99;

// Initialize Timer2 - ACS:
TCCR2 = (1 << WGM21) | (0 << COM20) | (1 << CS20);
OCR2 = 0x6E; // 0x6E = 72kHz @8MHz

// Initialize Timer Interrupts:
TIMSK = (1 << OCIE0);// | (1 << OCIE2); //Der Timer Interrupt wird initialisiert

// Initialize ACS:
sysStatACS.channel = ACS_CHANNEL_RIGHT;
acs_state = ACS_STATE_IRCOMM_DELAY;

sei(); // Enable Global Interrupts


} Das ist eigentlich genauso aufgebaut wie initRobotBase();

Ich hoffe ihr könnt mir helfen. Ich habe mir gedacht, wenn ich das 1:1 nachbaue, dann müsste es Fehlerfrei funktionieren. Könnt ihr mir nen Tipp geben, wie ich herausfinden kann, ob die LEDs mit 36KHz blinken. Wo wird denn die 36KHz Frequenz überhaupt eingestellt? Mit OCR2 = 0x6E ?
Wenn ich statt der IR-LEDs eine superhelle LED ranhänge, die leuchtet nicht. Möglicherweise ist das schon der Grund. Ich hoffe ihr könnt mir nen guten Tip geben.
VIelen Dank schonmal für eure Hilfe
MfG
RP6fahrer

PS:
Achja, mit Digitalkamera schauen hab ich auch versucht, aber man sieht weder beim RP6 noch hier die leuchtenden LEDs..

Dirk
20.07.2013, 20:19
Da wird man sicher den RP6-Code nicht unverändert übernehmen können.
Du hast ja einen ATmega 16 und nicht den 32. Da dürfte bei der Initialisierung nicht alles identisch sein. Ich habe das jetzt aber nicht nachgeschaut.

RP6fahrer
21.07.2013, 13:29
Hi,
danke erstmal für deinen ersten Gedanken... Also, ein Problem hat sich schon gelöst. Ich hatte nen Zahlendreher drin und hab das falsche Programm geladen. Deswegen ging das mit den 36 KHz der IR-LEDs nicht. Gut Problem behoben. Ich habe die LED an IOB5 so programmiert, dass sie ihren Zustand jedes mal wechselt, sobald ein Interrupt an INT2 (ACS) eingeht. Diese blinkt jetzt im Dauerfeuer. ziehe ich beide IR-LEDs raus, dann hört das blinken auf. Das Problem ist nur, dass ich die Signal (obstacle_left und obstacle_right) nicht auswerten kann.Ich werde aber auf jeden Fall nochmal das Datenblatt zur Initialisierung des Timer2 und INT2 wälzen. Ich hoffe, ich finde was.

Ich freue mich über weitere Tipps und gedanken

Schönen Sonntag noch

PS: Könnt ihr mir nen Denkansatz geben für ein eigenes ACS Programm. Die RC5 Code Auswertung brauche ich ja nicht. Mir reicht es, wenn der Controller Links, rechts, mitte auswerten kann.

Ich hab aus dem RP6 code jetzt alles rausgenommen, was mit IRCOMM und RC5 zu tun hat.
Das Problem, was ich jetzt aber nach wie vor hab, ich kann obstacle_left und obstacle_right nicht auswerten. Meine Status-Leds hab ich soweit programmiert, dass mir eine anzeigt, wie der Interrupt Eingang arbeitet. Diese leuchtet etwa mit halber Helligkeit, was ja bedeutet, dass dort ein wechselndes Signal anliegt. Ziehe ich nun eine IR-LED ab, dann blinkt sie ganz schnell. Ziehe ich beide IR-LEDs ab, dann hört das blinken auf. Das heißt ja dann scheinbar, dass der TSOP ein Signal von den Dioden bekommt. Und scheinbar bekommt er es ja auch immer wechselseitig. Aber ich kann mir nicht erklären, warum das obstacle nicht funktioniert. Kann es wirklich daran liegen, dass ich einen Atmega 16 statt Atmega 32 verwende. Ich habe im Datenblatt zum Timer2 und INT2 nachgeschaut und das ist soweit identisch. Ich hoffe wirklich, dass ihr noch nen guten Tipp für mich habt.

RP6fahrer
30.07.2013, 15:15
Hallo,
ich habe weiterhin viel versucht, sogar nen ATmega32 eingebaut, aber irgendwie klappt das mit dem ACS nicht. Was wäre eine günstige Alternative.
Mich würde auch interessieren ob man unbedingt das mit 36kHz modulierte Signal braucht oder könnte man auch die IR-LEDs auf Dauerlicht setzen und dann mit IR-Phototransistoren eine Reflexion detektieren? Oder hat das nicht soviel Reichweite?
Es tut mir leid, das ich so einfache Fragen stelle, aber ich hab das Problem, dass ich derzeit keinen IR-Phototransistor habe und das somit nicht testen kann und bevor ich dann sinnlos Geld ausgebe...

VIelen Dank für eure Hilfe :D

oberallgeier
30.07.2013, 15:41
... ob man ... 36kHz modulierte Signal braucht oder könnte man auch die IR-LEDs auf Dauerlicht setzen ...Der Vorteil der Kombination 36kHz-modulierte-irLED und dazu passendes Empfängermodul/-IC à la SFH5110 ist einmal die Anpassung an das Umgebungslicht und zum andern die Sicherheit gegen Fremdlicht wie Leuchtstofflampen, Gewitterblitze etc. Anm: die 36 kHz sind auf das Empfängermodul abgestimmt, es gibt Systeme mit anderen Modulationsfrequenzen: 38 kHz oder 40 ..., das funktioniert ebenso.

Deshalb wurde dieses System auf der Grundlage des asuro vor Jahren von waste (klick) (https://www.roboternetz.de/community/threads/9973-Asuro-Umbau-der-IR-Schnittstelle-zur-Hinderniserkennung) aus der Taufe gehoben. Damit hatte ich ausführlich weiter experimentiert (klick) (https://www.roboternetz.de/community/threads/33984-Abstandsmessung-ähnlich-wie-IR-Schnittstelle-des-asuro) weil mich diese Technik beeindruckte. Dabei hatte ich diese Messung etwas weiter ausgebaut, um sowohl Hindernisse als auch Abgründe zu detektieren (wieder ...) (https://www.roboternetz.de/community/threads/33984-Abstandsmessung-ähnlich-wie-IR-Schnittstelle-des-asuro?p=334010&viewfull=1#post334010). Das läuft prächtig. Ich hatte das in verschieden meiner Roboter eingebaut, zum Beispiel Dottie (https://www.roboternetz.de/community/threads/36121-Autonom-in-kleinen-Dosen-R2_D03-Nachfolger-R3D01?p=358306&viewfull=1#post358306) - die laufende Coladose - oder in WALL R, (https://www.roboternetz.de/community/threads/40453-WALL-R-läuft-(autonomes-Fahrzeug)) wo das gleiche System auch eine gestufte Reaktion auf verschiedene Abstände ermöglichte.

Dieses System läuft aber weder in wastes Urform noch in meiner Variante über ADC. Sowohl Beschreibungen als auch Code ist in den verlinkten Threads mehrfach enthalten. Vielleicht ist diese Lösung etwas für Dich? Jedenfalls viel Erfolg (und GEduld) mit Deinem Projekt.

RP6fahrer
31.07.2013, 17:00
Hallo Oberallgeier,

Danke für deine Anwort. Ich hab leider zur Zeit wenig Zeit im Internet, deswegen konnte ich noch nicht alle Links verfolgen. Aber ich habe weiterhin experimentiert. Bei dem TSOP 31236 ist es doch so, dass sobald ein 36kHz Signal einwirkt, dass sich der Ausgang auf Low zieht, richtig? Jetzt hab ich nen Programm geschrieben, wo die IR-LEDs dauernd mit 36kHz blinken (mit Multimeter nachgemessen: 36,1 kHz). Ich habe dann den IR-Empfänger neben dir IR-LED gebaut und mit dem Messgerät die Spannung auf Ausgang vom TSOP gemessen (ca 5V). Jetzt habe ich in verschiedenen Entfernung meine Hand davor gehalten, aber der Ausgang bleibt unverändert. Dann habe ich einen kleinen Spiegel genommen und ca. 1cm vor dem Empfänger schaltet er den Ausgang auf Low. Warum habe ich keine Reichweite?
Dann hab ich ein weiteres Programm geschrieben wo, die LEDs nur 200ms lang blinken und 800 ms aus sind. Mit einmal habe ich schon mehr Reichweite (etwa 10 cm). Ist das so normal?

Danke, Geduld ist hier wirklich gefragt. Ich finde es so schade, dass der RP6 code nicht einfach funktioniert. Naja, da ich momentan auf Montage bin, kann ich leider nicht überprüfen, ob die LEDs bei dem RP6 code blinken. Zuhause habe ich ein Oszi, da kann ich das detailiert ausmessen.

Ich werde aber deine Links noch weiter durcharbeiten.
Vielen Dank für deine Hilfe und ich freue mich über weitere ;D
MfG
RP6fahrer

Dirk
31.07.2013, 17:32
Hi RP6fahrer,

Ich finde es so schade, dass der RP6 code nicht einfach funktioniert.
Das war -denke ich- klar, weil beim RP6 ins ACS auch noch IRCOMM verschachtelt ist. Das war nicht 1:1 übertragbar.

Andererseits:
Man kann es gut schaffen, ein ACS hinten technisch genauso umzusetzen wie vorn und das auch mit dem µC des RP6 auszuwerten. Ein eigener µC dafür ist fast schon Overkill.
Die Auswertung kann so aussehen:
Du schreibst eine Funktion, die die LEDs mit 36 kHz blinken läßt. Zusätzlich kannst du die beiden LEDs einzeln ein-/ausschalten und mit 2 Portpins auch die Intensität (durch die Vorwiderstände) verändern.
Ob ein 36 kHz IR-Signal empfangen wurde, wertest du mit dem TSOP aus.

Das alles ist für dich sicher nicht neu. Aber: Das Programm dafür dürfte auch relativ einfach umzusetzen sein. Möglicherweise müßte man dazu aber die BaseLib modifizieren.

Wenn du all das nicht machen willst, könnte man hinten auch 2 SHARP-IR-Distanzsensoren und 2 Bumper dranbauen, wie fabqu das beim MultiIO Projekt gemacht hat: Klick! (http://www.rn-wissen.de/index.php/RP6_Multi_IO_Projekt#Bumper-Board)

RP6fahrer
09.08.2013, 11:01
Hey Dirk,
nach langer Zeit hab ich mal wieder Zeit dafür gehabt. Danke für deine Hilfe und Links. Bumper habe ich schon hinten dran ;) Die funktionierten auch auf Anhieb.
Die Sharp Sensoren hab ich auch schon in Erwägung gezogen, aber da ich dafür noch kein Geld ausgeben möchte und das andere Zeug da habe, hat mich der Ehrgeiz weitergepackt und ich habe wieder mehr versucht. Ich hab jetzt nochmal ein Komplett eigenes Programm geschrieben. Dabei habe ich beide IR-LEDs dauerhaft mit 36KHz blinken lassen. Am TSOP hab ich erstmal nur das Oszi hängen. Dort sieht ma ja schön, wann er ein Signal empfängt. Ergebnis ist: ich habe überhaupt keine Reichweite. Nur wenn ich die IR-LED direkt vor den TSOP halte, dann schaltet er seinen Ausgang auf Low. Das nützt mir nix, darum habe ich das Programm etwas verändert, nämlich, dass jetzt jede LED nacheinander für 20ms blinkt(mit 36KHz), und zwischen den beiden eine Pause von 500ms. Das heißt, 500ms vergehen LED1 blinkt für 20ms, 500ms warten, LED2 blinkt für 20ms und das wieder von vorn. Mit einmal hab ich eine gewaltige Reichweite. Ich muss die LEDs komplett zuhalten mit der Hand (Papier bringt nichts). Sonst empfängt der TSOP alle 500ms ein Signal. Es freut mich das das Programm ja scheinbar geht, aber warum hab ich mit einmal so eine gewaltige Reichweite. Die IR-LEDs haben einen Vorwiderstand von 1,5KOhm. Wenn ich sogar, wie beim RP6, zum 1,5K noch 2,2K parallel schalte, und mit meiner Hand den direkte Sichtkontakt der LEDs mit dem Tsop abdecke, dann erkennt dieser sogar die Reflektion der ca 1,5m entfernten Wand.


Ein eigener µC dafür ist fast schon Overkill.
Zwei Dinge: 1. Warum?
2. würde ich gerne noch mehr Sensoren später anbauen, darum dachte ich mir, dass ich für die einen eigenen Controller verwende. Aber gut, das hatte ich ja vorher noch nicht erwähnt.

Gut, ich werde erstmal noch ein bisschen weiter experiementieren. Vielen Danki nochmal für alle Infos und Hilfen.

MfG
RP6fahrer

Klebwax
09.08.2013, 11:25
Mit einmal hab ich eine gewaltige Reichweite ...

Da hilft ein Blick in das Datenblatt des TSOPs:


The data signal should be close to the band-pass center frequency (e.g. 38 kHz) and fulfill the conditions in the table below.

In dieser Tabelle kommt ein Dauersignal mit 38kHz nicht vor, sondern:

26195

Signale, die wesentlich anders als in dieser Beschreibung sind, werden als Störungen unterdrückt.

MfG Klebwax