Update ...
bin einen guten Schritt weiter gekommen ...
Das Antriebs-Modul ist weitgehend fertig, Das Modul wird wie alle anderen Module dann auf eine BUS-Platine gesteckt,
dadurch kann ich flexibel auch spätere Erweiterungen nachrüsten.

Meine Test-Umgebung:

Das Modul steuere ich derzeit über einen IO-Warrior (I2C) und dem Programm All-In-One,
zur Auswertung von Parametern nehme ich die RS232-Schnittstelle und einem einfachen eigenen PC-Programm.
Das Antriebs-Modul steuert die Motoren über Treiber-Module per PWM/DIR/Brake,
die Drehzahl und Drehrichtung der beiden Motore wird über die Tacho-Einheit ausgewertet.
Dank der Hilfe im Bascom-Forum, konnte ich recht schnell die TWI-Hardware-Lösung ohne LIB umsetzen ... siehe hier
Das Modul wird wie folgt über TWI(I2C) angesprochen
schreiben:
ADR|Mode|W1|W2|Wn
lesen:
ADR|Mode|R1|R2|Rn
Funktionen
Mode=0 ( schnelles bremsen ) ... funktioniert sicher
schreiben:
ADR|00 ... beide Motoren fahren schnell Ihre Drehzahl runter
lesen:
ADR|00|FF ... keine Daten außer Mode, Rest wir mit FF gefüllt
Mode=1 ( Speed ) ... funktioniert sicher
schreiben:
ADR|01|DR|V0|V1 ... beide Motoren werden beschleunigt bzw. abgebremst um auf die vorgegeben Drehzahl zu kommen und halten diese konstant.
lesen:
ADR|01|DR|V0|V1|P0|P1
DR = Drehrichtung 1= Motor_0 rückwärts / 2=Motor_1 rückwärts / 0= vorwärts beide / 3= rückwärts beide ... kann nur bei stehenden Motoren geändert werden
V0 = Drehzahl-Vorgabe Motor_0 0=Null / 150 = 7500 U/min ( Werte für die Faulhaber-Motoren)
V1 = Drehzahl-Vorgabe Motor_1 0=Null / 150 = 7500 U/min ( Werte für die Faulhaber-Motoren)
P0 = PWM-Wert Motor_0 ( nur lesen )
P1 = PWM-Wert Motor_1 ( nur lesen )
Mode=2 ( Strecke) .... noch nicht implementiert ... eine Wegstrecke wird mit Vmax gefahren ... auch Kurven oder drehen ist möglich.
schreiben:
ADR|02|DR|VM|S0|S0|S1|S1
lesen:
ADR|02|DR|VM|V0|V1|P0|P1
DR = Drehrichtung 1= Motor_0 rückwärts / 2=Motor_1 rückwärts / 0= vorwärts beide / 3= rückwärts beide
VM = Vmax
S0 = Strecke für Motor_0
S1 = Strecke für Motor_1
.....
zischen den Mode-1 und Mode-2 kann nicht direkt umgeschaltet werden nur über Mode-0 ... je nach Mode kann auch nur die dafür vorgegeben Werte gelesen werden.
ist das Modul am beschleunigen oder bremsen oder fährt die vorgegeben Wegstrecke wird die Leitung Ready auf LOW gelegt,
so muss der Master nicht immer über I2C pollen.
Wird die NOT-AUS-Leitung (BUS) auf LOW gelegt werden die Motoren über die Gatter sofort deaktiviert und das Modul fährt die Werte intern runter.
-----
derzeitiger Code:
Code:
' Projekt Mäh-Roboter
' R. Greinert
' (CC) 07 / 2016
'
' Antrieb_Steuerung Ver.008
'
'
' ------------ Bascom - Parameter ------------------------
$regfile = "m328pdef.dat"
$crystal = 16000000
$hwstack = 100
$swstack = 100
$framesize = 100
$baud = 19200
Print "Start_Main"
' ------------ Timer_0 Zeitvorgabe ------------------------------
Config Timer0 = Timer , Prescale = 256
On Ovf0 Timer0_ovf
Enable Timer0
' ------------ Output ------------------------------
Config Portb.0 = Output ' Ready-Leitung
Config Portb.3 = Output ' DIR Motor_0
Config Portb.4 = Output ' DIR Motor_1
Config Portb.5 = Output ' Herzschlag
Config Portd.4 = Output ' Break Motor_0
Config Portd.5 = Output ' Break Motor_1
Config Portd.7 = Output ' I2C-Data-Anzeige
Portb.0 = 0 ' NOT-Ready = LOW
Portb.3 = 0 ' DIR Motor_0 0=vorwärts 1=Rückwärts
Portb.4 = 0 ' DIR Motor_1 0=vorwärts 1=Rückwärts
Portd.4 = 0 ' Break Motor_0 low-aktiv
Portd.5 = 0 ' Break Motor_1 low-aktiv
Portd.7 = 1 ' I2C-LED aus
' ------------ Input ------------------------------
Config Pinc.2 = Input ' Motor_0 Decoder Q2
Config Pinc.3 = Input ' Motor_1 Decoder Q2
Config Pinc.0 = Input ' Abfrage NOT-AUS LOW-Aktiv
Config Pinc.1 = Input ' Abfrage RS232-Enabled
' ------------ PWM ----------------------
Config Portb.1 = Output ' PWM Motor_0
Config Portb.2 = Output ' PWM Motor_1
Portb.1 = 0
Portb.2 = 0
Config Timer1 = Pwm , Pwm = 8 , Compare_a_pwm = Clear_up , Compare_b_pwm = Clear_up , Prescale = 64
' ------------ RS232 - Input ------------------------
Config Serialin = Buffered , Size = 40
' ------------ I2C-Slave ------------------------
Dim Twi_status As Byte
Dim Twi_control As Byte
Dim Twi_dn As Byte
Twsr = 0
Twdr = 255
Twar = 180
Twcr = &B11000100
' ------------ DIM ------------------------
Dim Na As String * 30 ' RS232 Input-String
Dim Nax As String * 30 ' RS232 Input-UCASE-String
Dim Si As Byte ' RS232 Input Zeichen
Dim Z0 As Integer ' Zähler Motor_0
Dim Z1 As Integer ' Zähler Motor_1
Dim Z0x As Word ' Zähler cache Motor_0
Dim Z1x As Word ' Zähler cache Motor_1
Dim Tx As Byte ' Zähler ms
Dim Tmx As Byte ' Zähler sec
Dim P0 As Byte ' PWM_Motor_0 Stellwert
Dim P1 As Byte ' PWM_Motor_1 Stellwert
Dim Px As Byte ' Temp-Wert Stellwert_diff soll
Dim Pt As Word ' Temp-wert Stellwert_diff Ist
Dim Vx As Integer ' Temp-Wert Drehzahl_Diff
Dim V0 As Byte ' Vorgabe Drehzahl Motor_0
Dim V1 As Byte ' Vorgabe Drehzahl Motor_1
Dim R_0 As Byte ' Vorgabe Richtung Motor_0
Dim R_1 As Byte ' Vorgabe Richtung Motor_1
Dim Sx As Boolean ' Ready 1=fertig 0=atwork
Dim S0 As Long ' Streckenzähler Motor_0
Dim S1 As Long ' Streckenzähler Motor_1
Dim Xmode As Byte ' Funktion-Mode 0=Stop 1=Speed 2=Strecke
Dim Xt1 As Byte ' temp1
' ------ Split -------
Dim Sb As Byte ' Split_Zähler
Dim Sbx(5) As String * 10 ' Split_Array
' -------------- Declare Sub ----------------
' -------------- Interupt-Eingänge ----------------
Config Int0 = Falling ' Motor_0 Decoder Q1
Config Int1 = Falling ' Motor_1 Decoder Q1
Enable Int0
Enable Int1
On Int0 Int0_sub
On Int1 Int1_sub
Enable Interrupts
Print "Start_Hauptschleife"
Do
' --------------- Hauptschleife ------------------
If Ischarwaiting() <> 0 Then
Si = Inkey()
If Pinc.1 = 0 Then ' abfrage ob RS232 enabled
If Si <> 13 And Si <> 10 And Len(na) < 30 Then
Na = Na + Chr(si)
Else
Nax = Ucase(na)
Sb = Split(nax , Sbx(1) , "|")
Print Sb
If Nax = "STATUS" Then
Print "ACK|STATUS"
Print "Status|Z0x=" ; Z0x ; "|Z1x=" ; Z1x
Elseif Nax = "STOP" Then
Xmode = 0
Print "ACK|STOP"
Elseif Left(nax , 5) = "SPEED" Then
If Sb = 5 Then
Print "ACK|SPEED"
Xmode = 1
R_0 = Val(sbx(2) )
V0 = Val(sbx(3) )
R_1 = Val(sbx(4) )
V1 = Val(sbx(5) )
Else
Print "NAK|" ; Na
End If
Else
Print "NAK|" ; Na
End If
Na = ""
End If
End If
End If
' ----------------- TWI ------------------
Twi_control = Twcr And &H80 ' Bit7 von Controlregister
If Twi_control = &H80 Then
' TWI Transfer
Portd.7 = 0
Twi_status = Twsr
If Twi_status = &H80 Or Twi_status = &H88 Then
' -------- Daten von TWI erhalten
If Twi_dn = 0 Then
If Twdr = 1 Then
Xmode = 1
Elseif Twdr = 2 Then
Xmode = 2
Else
Xmode = 0
End If
Elseif Twi_dn = 1 Then
If Xmode = 1 Then
' Richtung
Xt1 = Twdr And 1
R_0 = Xt1
Xt1 = Twdr And 2
If Xt1 = 2 Then
R_1 = 1
Else
R_1 = 0
End If
Elseif Xmode = 2 Then
' ---- kommt noch
End If
Elseif Twi_dn = 2 Then
If Xmode = 1 Then
V0 = Twdr
Elseif Xmode = 2 Then
' ---- kommt noch
End If
Elseif Twi_dn = 3 Then
If Xmode = 1 Then
V1 = Twdr
Elseif Xmode = 2 Then
' ---- kommt noch
End If
Elseif Twi_dn = 4 Then
Elseif Twi_dn = 5 Then
End If
Incr Twi_dn
Elseif Twi_status = &HB0 Or Twi_status = &HB8 Then
' ------- Daten an TWI übergeben
If Xmode = 0 Then
If Twi_dn = 0 Then
Twdr = Xmode
Else
Twdr = 255
End If
Elseif Xmode = 1 Then
If Twi_dn = 0 Then
Twdr = Xmode
Elseif Twi_dn = 1 Then
Xt1 = 0
If R_0 = 1 Then Xt1 = 1
If R_1 = 1 Then Xt1 = Xt1 + 2
Twdr = Xt1
Elseif Twi_dn = 2 Then
Twdr = V0
Elseif Twi_dn = 3 Then
Twdr = V1
Elseif Twi_dn = 4 Then
Twdr = P0
Elseif Twi_dn = 5 Then
Twdr = P1
Else
Twdr = 0
End If
Elseif Xmode = 2 Then
If Twi_dn = 0 Then
Twdr = Xmode
Else
Twdr = 255
End If
Else
Twdr = 0
End If
Incr Twi_dn
Elseif Twi_status = &HA0 Or Twi_status = &HC0 Then
' TWI Transfer beendet
Portd.7 = 1
Twi_dn = 0
End If
Twcr = &B11000100
End If
Loop
Timer0_ovf:
' ---- Timer_0 ----- Interrupt alle 1 mS ----------------
Timer0 = 194 ' Resrwert = 61
Incr Tx
If Tx = 80 Then Portb.5 = 0 ' Herzschlag-LED (ein)
If Tx > 99 Then
' -------- Zeitbasis 100 mS ------------------
Sx = 1 ' Ready-Leitung =1
Tx = 0
Incr Tmx
Z0x = Z0
Z0 = 0
Z1x = Z1
Z1 = 0
If P0 = 0 And P1 = 0 Then
' ------ Richtung setzen wenn Motoren stehen
If R_0 = 0 Then Portb.3 = 0 Else Portb.3 = 1
If R_1 = 0 Then Portb.4 = 0 Else Portb.4 = 1
End If
If Xmode = 0 Then
' ------ Mode - Stop ----------
If P0 > 30 Then
P0 = P0 - 30
Sx = 0
Else
P0 = 0
End If
If P1 > 30 Then
P1 = P1 - 30
Sx = 0
Else
P1 = 0
End If
Elseif Xmode = 1 Then
' ------ Mode - Speed ----------
If V0 > Z0x And P0 < 255 And Pinc.0 = 1 Then
Px = 1
Vx = V0 - Z0x
If Vx > 6 Then
Px = 5
Sx = 0
End If
If Vx > 30 Then
Px = 20
End If
Pt = P0 + Px
If Pt > 255 Then
P0 = 255
Else
P0 = P0 + Px
End If
End If
If V1 > Z1x And P1 < 255 And Pinc.0 = 1 Then
Px = 1
Vx = V1 - Z1x
If Vx > 6 Then
Px = 5
Sx = 0 ' Ready-Leitung =0
End If
If Vx > 30 Then
Px = 20
End If
Pt = P1 + Px
If Pt > 255 Then
P1 = 255
Else
P1 = P1 + Px
End If
End If
If V0 < Z0x And P0 > 0 Or Pinc.0 = 0 Then
Px = 1
Vx = Z0x - V0
If Vx > 3 Then
Px = 6
Sx = 0
End If ' Ready-Leitung =0
If Vx > 35 Then
Px = 30
End If
If Px > P0 Then
P0 = 0
Else
P0 = P0 - Px
End If
End If
If V1 < Z1x And P1 > 0 Or Pinc.0 = 0 Then
Px = 1
Vx = Z1x - V1
If Vx > 3 Then
Px = 6
Sx = 0
End If ' Ready-Leitung =0
If Vx > 35 Then
Px = 30
End If
If Px > P1 Then
P1 = 0
Else
P1 = P1 - Px
End If
End If
Elseif Xmode = 2 Then
' ---- Mode-Strecke ------------------
End If
' ------ NOT - STOP ---- und Treiber auf null setzen ----
If V0 = 0 And Z0x = 0 And P0 > 0 Or Pinc.0 = 0 Then P0 = 0
If V1 = 0 And Z1x = 0 And P1 > 0 Or Pinc.0 = 0 Then P1 = 0
' ------ Treiber-Bremse -------
If P0 > 0 Then
Portd.4 = 1
Else
Portd.4 = 0
End If
If P1 > 0 Then
Portd.5 = 1
Else
Portd.5 = 0
End If
' ----- PWM-Wert setzen ---------
Compare1a = P0
Compare1b = P1
Portb.0 = Sx ' Ausgabe Ready-Leitung
End If
If Tmx > 9 Then
' ------------- Zeitbasis 1 Sec -------------------
Tmx = 0
If Pinc.1 = 0 Then ' abfrage ob RS232 enabled
Print "Status XM=" ; Xmode ; " Z0x=" ; Z0x ; " Z1x=" ; Z1x ; " P0=" ; P0 ; " P1=" ; P1 ; " S0=" ; S0 ; " S1=" ; S1 ; " NA=" ; Pinc.0
End If
Portb.5 = 1 ' Herzschlag-LED (aus)
End If
Return
Return
Int0_sub: ' Interrupt Motor_0 Decoder_Q1
Incr Z0
If Pinc.2 = 0 Then ' Abfrage Motor_0 Decoder_Q2 ( Drehrichtung )
Incr S0
Else
Decr S0
End If
Return
Return
Int1_sub: ' Interrupt Motor_1 Decoder_Q1
Incr Z1
If Pinc.3 = 0 Then ' Abfrage Motor_1 Decoder_Q2 ( Drehrichtung )
Incr S1
Else
Decr S1
End If
Return
Return
Lesezeichen