PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Mehrere Programme gleichzeitig laufen lassen geht nicht.



mesli-andres
04.06.2005, 10:10
Hallo
Ich mache für die Schule ein Projekt, ich baue einen Überwachungsroboter. dazu verwende ich den ATMega32 und programmiere mit Bascom. O:)

Wie kann man ein Sub Programm und eine Funtion gleichzeitig ausführen?
Also im Klaren der Roboter muss zwei LEDs abwechselnd blinken lassen
und dabei noch einen Analog-Port überwachen? (noch besser 3 Analog-Porte)
Wenn das Sub-programm für die LEDs läuft kann ich nicht gleichzeitig
einen Analog-Port (oder die Taster) überwachen. ](*,)
Danke schon im Voraus

Marco78
04.06.2005, 10:25
Multitaskfähig ist ein AVR nicht.
Ist das blinken von irgendwas abhänig? Sonst kannst du dafür einfach ein Timer programmieren.
Wenn die blinken nicht im ms-Takt erfolgen muss, sollte dein Problem zu lösen sein.
Bei 16MHz arbeitet der Prozessor fast 16.000.000 Schritte in der Sekunde ab. Analogwerte auslesen benötigt etwa 7 Schritte. Dazu kommen dann noch die Schritte um die Werte auszuwerten. Das Wechselblinken wird auch nicht mehr als 100 Schritte beanspruchen.

Probier erstmal deine Anwendung zu programmieren und schau dann ob noch alles schnell genug läuft.

Wie gesagt, für's blinken könntest du ein Timer programmieren.

recycle
04.06.2005, 11:02
Wie kann man ein Sub Programm und eine Funtion gleichzeitig ausführen?


Dein PC kann auch nicht mehrere Aufgaben gleichzeitig ausführen. Der arbeitet auch alle Programmbefehle nacheinander ab, da sorgt nur das Betriebssystem dafür, dass ständig zwischen den einzelnen Tasks gewechselt wird und es wie echtes Multitasking aussieht.

Dein AVR ist so schnell, dass du mit blossem Auge ganz sicher nicht feststellen wirst, wenn die LEDs nacheinander geschaltet und zwischendurch noch ein paar Sensoren abgefragt werden.

Dass du im deinem Programm selber dafür sorgen musst, dass die einzelnen Aufgaben schnell genug nacheinander ausgeführt werden, mag etwas lästig erscheinen, ist aber eigentlich meist sogar einfacher.

Bei Mutitasking und Multithreading ist es oft ganz schön kompliziert die einzelnen Threads und Tasks zu synchronisieren.
Wenn ein Thread schon auf das Messergebnis reagieren würde, bevor der andere Thread überhaupt gemessen hat, wäre das ja auch nicht so toll.

Arexx-Henk
04.06.2005, 11:05
Hallo,

Dass blinken konnte mann am einfachsten mit einem Zeit verzogerungs Schleife (in 'C' for(i=0;i<Wert;i++) realisieren aber dann wird alle processorzeit vom verzogerung function (unnotig) benutzt.

Am besten man benuzt so wie schon gesagt ein Timer der z.B jeden Zehntel Sekunde (0.1 Sek.) ein Interrupt generiert. Nuzte ein 10-zahler variabelen um die Leds jeden einzelne Sekunde 1-mahl blinken zu lassen und nutze die Interrupt (10 mahl pro Sekunde) um die Ports jedesmahl einmal zu uberprufen.

Damit ist 99% der Prozessorzeit noch frei fur andere Sachen.

So eine idee, :cheesy:

gruss

Henk

mesli-andres
05.06.2005, 17:26
Hallo
Danke für die vielen Ideen zum Blinken, dass funtioniert jetzt jetzt muss ich noch 3 Ports überwachen, zuerst ein Port alleine das geht und später sollte er zwei ports überwachen um einer Linie nach zufahren.
Ich weiss nicht wie ich zwei Ports miteinander überwachen soll oder gibt es noch eine andere Lösung?
Danke schon im Voraus

Marco78
05.06.2005, 19:15
Analogports?
B=GETADC(1)
C=GETADC(2)

Beides nacheinander abfragen.

Bei digitalen Ports das gleiche.

Ich glaube du traust deinem AVR zu wenig zu ;)
Bedenke, das er bei 16MHz etwa 16.000.000 Befehle pro Sekunde ausführt. (Ein PIC nur etwa 8.000.000 bei 16MHZ :D (et gibt aber auch µC die 4 Takte pro Befehl benötigen.))
Falls deine Angst ist, das nicht die besagten Ports gleichzeitig angefragt werden können, kann ich dich beruhigen. Das geht tatsächlich nicht. Aber wie hier auch schon gesagt, kann ein PC das auch nicht!
Das Abfragen von 2 digitalen Ports nacheinander benötigt 2 Taktzyklen. Bei 16MHz und damit 16 Millionen Takte pro Sekunde kannst du dir ja ausrechenen, wie viele µs es dauert, bis dein AVR weiss, ob die abgefragten Ports High oder Low sind.

PicNick
06.06.2005, 07:49
..Ich glaube du traust deinem AVR zu wenig zu ;)


Noch'n Vergleich: Hat es Dich schon jemals gestört, daß Dein Fernseher in Wirklichkeit immer nur einen einzigen verwuzelten Punkt am Schirm darstellen kann und erst in deinen Hirn überhaupt ein Bild entsteht ?

mesli-andres
08.06.2005, 18:23
Hallo
Ich habe die Analogports wie vorgeschlagen abgefragt.
Oder habe ich trotzdem ein Fehler gemacht ? :-s
Ich wäre froh wenn mir jemand sagen könte was ich falsch gemacht habe.
Danke schon im Voraus
Hier ist noch mein Programmcode

Do

Taste = Bewegungsmelder()
If Taste <> 0 Then

Select Case Taste

Case 1
Pwm1a = 0 'Linker Motor aus
Waitms 1000
Pwm1a = 1023
Print "Rechts weisse Linie erkannt"

Case 2
Pwm1b = 0
Waitms 1000
Pwm1b = 1023
Print "Links weisse Linie erkannt"

Case 3
Waitms 2000
Porta.4 = 1
Waitms 800
Porta.4 = 0
Waitms 1000
Porta.4 = 1
Waitms 500
Porta.4 = 0
Waitms 4000
Porta.4 = 1
Waitms 500
Porta.4 = 0
Waitms 4000
Porta.4 = 1
Waitms 500
Porta.4 = 0

Print "Person gesichtet und fotografiert"
Waitms 5000
Call Linieverfolgung
End Select
End If

Waitms 100
Loop

End




Function Bewegungsmelder()
Local B As Word
Local C As Word
Local We As Word
Bewegungsmelder = 0
'Diese Unterfunktion überwacht den Raum und folgt Der Linie
Start Adc
B = Getadc(0)
C = Getadc(1)
We = Getadc(2)
If We < 1010 Then
Select Case We
Case 380 To 470
Bewegungsmelder = 3

Case 535 To 720
Bewegungsmelder = 3
End If
End Select

If B < 1010 Then
Select Case B
Case 612 To 820
Bewegungsmelder = 1
End If
End Select

If C < 1010 Then
Select Case C
Case 612 To 820
Bewegungsmelder = 2
End If
End Select

End Function

Marco78
09.06.2005, 21:01
Ich wäre froh wenn mir jemand sagen könte was ich falsch gemacht habe.

Was geht denn nicht?
Reagiert das Programm überhaupt nicht?
Die Schaltung an den Analogports ist auch richtig?

mesli-andres
09.06.2005, 21:36
Der Roboter überwacht den Raum und wenn es eine Person erkennt
(input von Bewegungsmelder) löst es die Digicam aus und dann macht der Roboter drei Fotos. Bis hier hin geht alles.
Dann sollte er der Linie nachfahren(um zu lenken schaltet er den linken/rechten Motor kurz aus)
Bis jetzt hat er ab und zu den linken/rechten Motor ausgeschalten aber nicht wenn es sollte. Weiss nicht was es sein kann

Was für eine Schaltung muss ich den haben?

danke schon im voraus

mesli-andres
10.06.2005, 16:09
Hallo
Hat schon jemand ein Lienverfolgungs prog geschrieben.
Wäre froh wenn jemang so ein Prog mal posten kann.
Würde mich schon viel weiter bringen.
Danke schon im voraus

Marco78
11.06.2005, 12:44
Wie hast du denn die Sensoren angeschlossen? Das da oben ist ja sicherlich nicht das ganze Programm. Hast du den ADC auch richtig eingestellt? Die jeweiligen Ports als Ein- und Ausgang eingestellt?

Marvin
11.06.2005, 15:50
Hi mesli-andres,
ich denke Du hast da nen ganz trivialen bug in der Funktion Bewegungsmelder. Bei allen 3 Abfragen sind "End If" und "End Select" vertauscht.

If We < 1010 Then
Select Case We
Case 380 To 470
Bewegungsmelder = 3

Case 535 To 720
Bewegungsmelder = 3
End If
End Select

If B < 1010 Then
Select Case B
Case 612 To 820
Bewegungsmelder = 1
End If
End Select

If C < 1010 Then
Select Case C
Case 612 To 820
Bewegungsmelder = 2
End If
End Select

Verschachtelte Ifs, Selects, Schleifen usw müssen immer von innen nach aussen geschlossen werden.

Edit:
Hab grad noch mal Dein Progie angesehen und verstehe "Call Lienienverfolgung" unter "Case 3" nicht.
Dann dachte ich noch, Du solltest bei "Case 3 " vielleicht zuerst die Motoren abzuschalten, damit das Teil nicht fast 20 Sekunden lang einfach geradeaus weiterfährt.

Grüße
Marvin

Marco78
11.06.2005, 15:57
If C < 1010 Then
Select Case C
Case 612 To 820
Bewegungsmelder = 2
End If
End Select

Ich hab das mal anders dargestellt. Es mag sein, das ich mich täusche, aber denke eher das du If und Select vertauschst hast. Select ist innen und If ist aussen.

Marvin
11.06.2005, 16:42
Hmm, bei genauer Betrachtung ist das If mitsamt dem End If eigentlich völlig überflüssig.
Wenn C >= 1010 ist, dann trifft der "Case 612 to 820" nicht zu und "Bewegungsmelder" wird nicht gesetzt.

Grüße
Marvin

recycle
11.06.2005, 17:14
@mesli-andres
hast du bei deinem ATMega die serielle Schnitstelle so beschaltet (max232), dass du Daten an den PC ausgeben kannst?

Dann würde ich bei Schleifen, Abfragen usw. Print Befehle zum Debuggen einfügen.
Damit findet man Fehler wie Marco78 und Marvin gefunden haben meist schneller, als wenn man über dem Quelltext brütet.

mesli-andres
11.06.2005, 19:16
Hallo
Danke mal für die vielen tips. O:)
Mit Case 3 steuere ich eine Digicam die dann Fotos macht.
Später habe ich dann das Prog mit Print Befehlen ausgestattet aber das brachte mich nicht weiter.

Marco78
11.06.2005, 19:51
Kannst du nicht mal den Schaltplan und das komplette Propgramm veröffentlichen?

Es stellt sich immer noch die Frage, ob der ADC überhaupt richtig eingestellt ist und ob die Spannung mit einem Spannungsteiler ermittelt wird...

mesli-andres
11.06.2005, 20:38
Hallo
Hier ist das gesamte Prog.


'################################################# ##
'Überwachungsroboter.bas
'Überwachungsroboter
'Projekt von Andres
'################################################# ######


Declare Function Bewegungsmelder() As Byte
Declare Sub Linieverfolgung()



$regfile = "m32def.dat"
$framesize = 32
$swstack = 32
$hwstack = 32


Dim I As Integer
Dim N As Integer
Dim Ton As Integer

$crystal = 16000000 'Quarzfrequenz
$baud = 9600

Config Adc = Single , Prescaler = Auto 'Für Tastenabfrage und Spannungsmessung

Config Pina.7 = Input 'Für Tastenabfrage
Porta.7 = 1 'Pullup Widerstand ein

Config Pina.5 = Input
Config Pina.6 = Input
Config Pina.2 = Input
Config Pina.3 = Input
Config Porta.4 = Output


Dim Taste As Byte
Dim Volt As Single
' Für Linieverfolgung
'Ports für linken Motor
Config Pinc.6 = Output 'Linker Motor Kanal 1
Config Pinc.7 = Output 'Linker Motor Kanal 2
Config Pind.4 = Output 'Linker Motor PWM
'Ports für rechten Motor
Config Pinb.0 = Output 'Rechter Motor Kanal 1
Config Pinb.1 = Output 'Rechter Motor Kanal 2
Config Pind.5 = Output 'Rechter Motor PWM
Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down
Pwm1a = 0
Pwm1b = 0
Tccr1b = Tccr1b Or &H02 'Prescaler = 8





I = 0
Waitms 5000
Sound Portd.7 , 400 , 450 'BEEP
Sound Portd.7 , 400 , 250 'BEEP
Sound Portd.7 , 400 , 450
Print
Print "**** RN-CONTROL 1.4 *****"
Print "Das neue Experimentier- und Roboterboard"
Print "Weitere passende Zusatzboards bei www.robotikhardware.de"
Print "Projekt Ueberwachungsroboter von Andres"
Print
Do






Do

Taste = Bewegungsmelder()
If Taste <> 0 Then

Select Case Taste

Case 1
Pwm1a = 0 'Linker Motor aus
Waitms 1000
Pwm1a = 1023
Print "Rechts weisse Linie erkannt"

Case 2
Pwm1b = 0
Waitms 1000
Pwm1b = 1023
Print "Links weisse Linie erkannt"

Case 3
Waitms 2000
Porta.4 = 1
Waitms 800
Porta.4 = 0
Waitms 1000
Porta.4 = 1
Waitms 500
Porta.4 = 0
Waitms 4000
Porta.4 = 1
Waitms 500
Porta.4 = 0
Waitms 4000
Porta.4 = 1
Waitms 500
Porta.4 = 0
Print "Person gesichtet und fotografiert"
Waitms 5000
Call Linieverfolgung
End Select
End If

Waitms 100
Loop

End




Function Bewegungsmelder()
Local B As Word
Local C As Word
Local We As Word
Bewegungsmelder = 0
'Diese Unterfunktion überwacht den Raum und folgt Der Linie
Start Adc
B = Getadc(5)
C = Getadc(6)
We = Getadc(2)
If We < 1010 Then
Select Case We
Case 380 To 470
Bewegungsmelder = 3

Case 535 To 720
Bewegungsmelder = 3
End Select
End If
If B < 1010 Then
Select Case B
Case 412 To 820
Bewegungsmelder = 1
Case Else
' Print "Wert anpassen!ADC Wert B=" ; B
End Select
End If


If C < 1010 Then
Select Case C
Case 412 To 820
Bewegungsmelder = 2
Print "Wert anpassen!ADC Wert C=" ; C
End Select
End If


End Function



Sub Linieverfolgung()

Waitms 1000


'Linker Motor ein
Portc.6 = 1 'bestimmt Richtung
Portc.7 = 0 'bestimmt Richtung
Portd.4 = 1 'Linker Motor EIN

'Rechter Motor ein
Portb.0 = 1 'bestimmt Richtung rechter Motor
Portb.1 = 0 'bestimmt Richtung rechter Motor
Portd.5 = 1 'rechter Motor EIN


I = 0
Do
Pwm1a = I
Pwm1b = I
Waitms 10
I = I + 5
Loop Until I > 1023
'
Waitms 100

Do
Pwm1a = 1023
Pwm1b = 1023
End

End Sub



Loop
Loop


Und hier der Schaltplan zum ansteuern der CN70's

Marco78
11.06.2005, 21:07
Und da sehe ich schon den ersten Fehler. Der ADC-Port ist hochohmig. Bedeutet es fließt kein Strom und es kann keine Spannung abfallen. Die Spannungsmessung muss als Spannungsteiler erfolgen. Du brauchst also noch ein Widerstand vom Analogport zu Masse.

Ein CNY70 ist ein Optokoppler, oder? Lässt der sich so 'fein' ansprechen, das man verschiedene Spannungen bekommt?

mesli-andres
11.06.2005, 21:18
Ja der CNY70 ist ein Optokoppler.
Muss der Schaltplan so aussehen?

Marco78
11.06.2005, 21:23
Vom Prinzip her ist der Schaltplan so schon richtiger. Die 10k müssen in der Praxis evtl angepasst werden. Der Widerstand muss zum einen den Strom begrenzen und zum anderen klein genug sein, das noch genug zu messende Spannung anfallen kann.

Kann eine Optokoppler nicht nur '1' und '0' sondern auch gut messbare analoge Werte liefern?

mesli-andres
11.06.2005, 21:26
Ja der Optokoppler liefert verschiedene spannungen zwischen 2,8V bis 3,7V

Marco78
11.06.2005, 21:29
Ok, dann solltest du erstmal nur die Werte bestimmen, die der Optokoppler liefert. Ihn einfach mit dem Spannungsteilerwiderstand anschliessen und die Werte über RS232 ermitteln, die er bei hell und dunkel liefert. Damit kannst du auch den besten Widerstand ermitteln.
Wenn du die min. und max. Werte hast kannst du sie im Programm ja nochmal ändern und schauen was dann passiert. Dann sollte es schonmal etwas besser laufen.