- LiTime Speicher und Akkus         
RSS-Feed anzeigen

Searcher

Steppender Linienfolger - SW serieller Transfer im Zwangslaufverfahren mit zwei Adern

Bewerten
Positive Nachricht. Serielle Übertragung über zwei Adern im Zwangslaufverfahren läuft. Zwar nur etwa halb so schnell als die Methode mit den drei Adern aber ich denke, daß man noch etwas an der Sende- und besonders an der Empfangsroutine optimieren kann.

Ein paar Oszi Screenshots.
1. Zeigt eine komplette 12 Bit Übertragung. Channel 2, der untere, liegt zu Beginn auf "0", da schon ein Bit vom Sender angelegt ist. Irgendwann hat der Empfänger das Bit wahrgenommen und quittiert das mit Channel 1 auf "0" ziehen. Ab da werden die restlichen Bits zügig übertragen. Übertragung des Pakets dauert etwa 58µs (ca. 200kB/s bei 8MHz systemtakt auf Sende- und Empfangsseite)

2. Zeigt Detail zu Beginn der Übertragung. Die ersten 4 Bit enthalten den Funktionscode für Liniensensordaten = dez 6 ( binär 0110 )

3. Zeigt drei 12 Bit Pakete. Nachdem ein Paket übertragen wurde sieht man, daß Channel 2 recht bald wieder auf "0" geht. Der Sender legt also schon wieder ein Bit zur Übertragung an. Der Mega88 ist aber noch nicht soweit und arbeitet noch irgendein anderes Zeug ab. Im Schnitt nimmt er alle 316µ (also ca 3200 Mal pro Sekunde) Daten vom Liniensensor zur Steuerung seiner Schrittmotore entgegen.

Bild hier  Bild hier  Bild hier  

Zuletzt noch zur Verwirrung und Kritik das komplette Programm des LS-Tiny mit Sendeprogramm. Das Empfangsprogramm sieht noch zu wüst aus und ist noch schlimmer kommentiert als das Sendeprogramm. Ich versuche englisch zu kommentieren, damit die Sprache bei mir nicht einrostet. Kritik und Fragen erwünscht.

Code:
'###############################################################################
'File: LS-Tiny45_05.bas
'
'Differential measurement of photodiodes for linefollowing
'Sending processed measurement data to ATMega88 main processor
'over 2 wires via a compelled signalling method
'
'IDE: BASCOM-AVR Demoversion 2.0.7.5
'
'Linesensor at ADC2 (PB4), ADC3 (PB3), Signal/data lines: PB0, PB1
'###############################################################################

$regfile = "attiny45.dat"
$framesize = 32
$swstack = 32
$hwstack = 36
$crystal = 8000000
$lib "mcsbyte.lbx"                                          'only byte operations

Dim Adc_low As Byte                                         'variables for adc result
Dim Command As Byte
Dim Command_old As Byte
Dim Address As Byte

Portb = Bits(pb0 , Pb1)                                     'PB0, PB1 are inputs. activate pullups (signal lines to main proc.)

Didr0 = Bits(adc2d , Adc3d)                                 '&B00011000                                          'ADC power save PB3,PB4
Admux = Bits(refs1 , Adlar , Mux2 , Mux1 , Mux0)            '1,1V internal reference, ADLAR=1 (left adjusted), PB4 PB3 gain 20
Adcsrb.7 = 1                                                'bipolar input mode
'try maybe 2,56V ref

'ADC enable, start first conversion, auto trigger, interrupt enable, prescale 64
Adcsra = Bits(aden , Adsc , Adate , Adie , Adps2 , Adps1)

On Adc Linedata_to_main_processor                           'conversion ready triggers ISR

Address = 6                                                 'identifier for linedata

Enable Interrupts                                           'allow general interrupts

Do                                                          'main loop
!nop                                                        'NOP for Simulator only
Loop

Linedata_to_main_processor:                                 'ISR ADC readout, process and transmit linedata
   Adc_low = Adch                                           'only 8 bit measurement data are used
   If Adc_low.7 = 1 Then                                    'if differential measurement value is negative then
         Adc_low = Not Adc_low                              'process 2th Complement to positive number
         Adc_low = Adc_low + 1                              'process 2th Complement to positive number
         Shift Adc_low , Right , 2                          'experimental processing of the line data
         Adc_low = 64 - Adc_low
      Else                                                  'Meßwert positiv - keine Umwandlung
         Shift Adc_low , Right , 2                          'experimental processing of the line data
         Adc_low = Adc_low + 63
   End If
   Command = Adc_low

'   If Command <> Command_old Then
'     Command_old = Command

'###############################################################################
'
'12 bits send routine via a compelled signalling method
'
'send last four bits (LSBs) of "address" and the 8 bits of the "command" byte to main processor
'send high bits first. Signal/data lines are at PB0 and PB1
'
'In idle state, PB0 and PB1 are inputs with activated internal pullup resistors,
'high impedance HIGH potential from and to main processor on both lines.
'
'To send a data bit as a HIGH bit, PB0 becomes an output and switches to LOW potential.
'Receive acknowledement from main processor is LOW potential expected at PB1
'Will be acknowledged by HIGH at PB0
'Main processor removes LOW, applies HIGH - Idle State on both lines reached.
'Ready to send another bit.
'
'To send a data bit as a LOW bit, PB1 becomes an output and switches to LOW potential.
'Acknowledement from main processor is LOW potential expected at PB0
'Will be acknowledged by HIGH at PB1
'Main processor removes LOW - Idle State on both lines reached.
'Ready to send another bit.
'
'###############################################################################

    $asm
      lds r16,{address}                                     'first byte to be send
      Swap R16                                              'send low nibble only, MSB first
      ldi r17,4                                             'r17 loop variable, number of bits of the byte to be send
      ldi r18,2                                             'r18 loop variable, number of bytes to be send

    Wait_for_line_free:
      sbis pinb,0                                           'check for HIGH at PB0 (ready to receive indication from mega88 if PB1 is HIGH as well)
     rjmp Wait_for_line_free
      sbis pinb,1                                           'check for HIGH at PB1 (ready to receive indication from mega88 if PB0 is HIGH as well)
     rjmp Wait_for_line_free
      SBrs r16,7                                            'skip next if bit to be send is high
     rjmp Send_low_bit

    Send_high_bit:                                          'switch PB0 to LOW, keep PB1 as input
      sbi ddrb,0                                            'PB0 as output
      Cbi portb,0                                           'PB0 to LOW
    Wait_ack_for_high_bit:
      sbic pinb,1                                           'wait ack. from Mega88 (a LOW at pinb.1)
     rjmp Wait_ack_for_high_bit
      Sbi portb,0                                           'reset PB0 to HIGH
      CbI ddrb,0                                            'reset PB0 as input
     rjmp Next_bit

    Send_low_bit:                                           'switch PB1 to LOW, keep PB0 as input
      sbi ddrb,1                                            'PB1 as output
      Cbi portb,1                                           'PB1 to LOW
    Wait_ack_for_low_bit:
      sbic pinb,0                                           'wait ack. from Mega88 (a LOW at pinb.0)
     rjmp Wait_ack_for_low_bit
      Sbi portb,1                                           'PB1 to HIGH
      CbI ddrb,1                                            'PB1 as INPUT

    Next_bit:
      lsl R16                                               'shift next data bit to send position (to pos 7 in R16)
      dec R17                                               'counter of transmitted bits
     brne Wait_for_line_free                                'branch if more bits to be send
      dec r18                                               'counter of transmitted bytes (or series of bits)
     Brne send_next_byte
      rjmp End_of_transmission                              'all data have been send

    Send_next_byte:
      lds r16,{command}                                     'fetch the next byte to be send
      ldi r17,8                                             '8 Bit (of the byte) to be send
     rjmp Wait_for_line_free

    End_of_transmission:
    $end Asm
'  End If
Return
Jetzt kann ich leider weitermachen und muß den CNY70 an den frei gewordenen Pin des LS-Tiny anschließen um die verlorene Linie zu bemerken (siehe auch letzten Blogeintrag)

Gruß
Searcher

"Steppender Linienfolger - SW serieller Transfer im Zwangslaufverfahren mit zwei Adern" bei Twitter speichern "Steppender Linienfolger - SW serieller Transfer im Zwangslaufverfahren mit zwei Adern" bei Facebook speichern "Steppender Linienfolger - SW serieller Transfer im Zwangslaufverfahren mit zwei Adern" bei Mister Wong speichern "Steppender Linienfolger - SW serieller Transfer im Zwangslaufverfahren mit zwei Adern" bei YiGG.de speichern "Steppender Linienfolger - SW serieller Transfer im Zwangslaufverfahren mit zwei Adern" bei Google speichern "Steppender Linienfolger - SW serieller Transfer im Zwangslaufverfahren mit zwei Adern" bei del.icio.us speichern "Steppender Linienfolger - SW serieller Transfer im Zwangslaufverfahren mit zwei Adern" bei Webnews speichern "Steppender Linienfolger - SW serieller Transfer im Zwangslaufverfahren mit zwei Adern" bei My Yahoo speichern

Aktualisiert: 27.10.2015 um 22:38 von Searcher

Stichworte: - Stichworte bearbeiten
Kategorien
Kategorielos

Kommentare

  1. Avatar von witkatz
    Eine interessante DÜ Technik und verspricht auch vom Ansatz her störungssicher zu sein. Die 4Bit Codierung könnte eigentlich entfallen, weil es sowieso nur Point-To-Ponint geht, oder?
  2. Avatar von Searcher
    Zitat Zitat von witkatz
    Eine interessante DÜ Technik und verspricht auch vom Ansatz her störungssicher zu sein.
    Die Technik wurde zB in der Telekommunikation eingesetzt. Find ich auch interessant und weiß noch nicht so recht was ich hier auf meinem Linienstepper davon halten soll.

    Denke auch das es störungssicher ist. Ich habe noch 1kΩ Widerstände in Reihe in den Verbindungsleitungen zwischen den µC falls mal durch Programmfehler zwei Ausgänge gegeneinander arbeiten. Die können noch entfallen und die relativ hochohmigen internen Pullup-Widerstände könnten noch durch externe unterstützt werden. Dadurch, daß jedes Bit quittiert wird, ist es vermutlich sehr schwer die Verbindung zu stören. Man könnte noch Zeiten einbauen, die ein Bit anstehen muß um als sicher erkannt zu gelten. Soviel will ich aber gar nicht und bis jetzt läuft es mit meiner wackeligen Stromversorgung im Linienstepper mit den stromfressenden Schrittmotoren prima. Weiß allerdings nicht, wieviele Bits verfälscht werden. Durch die pure Anzahl der Meßwerte gehen die möglicherweise unter und schlagen nicht sichtbar auf die Lenkung des Linienfolgers durch.

    Die 4Bit Codierung könnte eigentlich entfallen, weil es sowieso nur Point-To-Ponint geht, oder?
    Stimmt. Hab ich bisher noch nicht näher drüber nachgedacht. Wenn auf der Sende- und der Empfangsseite klar ist, wieviele Bits übertragen werden und welche Bedeutung die haben kann der "Funktionscode" wegfallen. zB nutze ich vom ADC nur ein 8 Bit Ergebniswert, der auch noch durch 2 shifts auf 6 Bit beschitten wird. Es würde reichen, nur diese 6 Bits, vielleicht 7 zu übertragen - müßte da in der Aufbereitung und im Fahrprogramm noch was anpassen, aber die 6 Bit würden reichen.

    Den Funktionscode habe ich ja noch von der Fernbedienung mitgeschleppt. Da werden ja über Infrarot mit RC5-Code mittlerweile fünf Funktionen übertragen: Motorstrom ein-/ausschalten, vorwärts/rückwärts, Lenken, Geschwindigkeit und Linienmodus ein/aus. Dort möchte ich nicht auf den Funktionscode verzichten.

    Mal sehen, ob es notwendig wird, die Paketlänge zu kürzen. Dadurch, daß Sende- oder Empfangsseite die Übertragung unterbrechen kann um dringendere Aufgaben zu erledigen, sehe ich das im Augenblick noch nicht.

    Grund für die Einführung eines solchen Protokolls bei mir war ja, daß vom Mega88 die Schrittmotore über ISRs gesteuert werden. Damit die ISRs einen gleichmäßigen Takt liefern können, sollten sie nicht durch anderes gestört werden. Bei BASCOM kam die Störung durch die RC5 Empfangsroutine, die ja jetzt auf den RC5-Tiny ausgelagert ist und die Datenübertragung von dort getrost durch die Stepper ISRn unterbrochen werden kann.
    Aktualisiert: 27.10.2015 um 22:42 von Searcher

LiTime Speicher und Akkus