PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : fertiges Projekt vorstellen: RC Modellbauschalter mit ATMega 88



stfan1409
10.05.2012, 19:39
Hallo,
ich habe eine RC Auto mit einer 3 Kanal Fernbedinung. 2 Kanäle sind für Gas/Bremse sowie Lenkung belegt. Der 3te Kanal ist frei und soll meine Beleuchtung steuern.

In meinem Projekt habe ich die RC-EmpfängerKanäle ausgewertet (Pulsein) und damit die Autobeleuchtung angesteuert. Es ist kein Eingriff in die FB nötig.
Kanal 3: Steuerknüppel OBEN ist die eine Funktion (tast&rast) und Knüppel UNTEN die andere(tast&rast).
Außerdem sind die Bremsleuchten beim fahren gedimmt(PWM) und im Stand auf volle Helligkeit. Beim start des µC wird die Nullstellung der Knüppel gespeichert.
Alle Einstellungen sind im EEProm(M88) gespeichert und können über RS232 geändert werden.

Video unter: http://youtu.be/Zc1vbOMbclw
Weitere Info´s im Programmcode.



'-------------------------------------------------------------------------------
' Modellbauschalter -05/2012- 2Kanal mit ATMega 88
' Programmiert für Savage Flux
'-------------------------------------------------------------------------------
'Anmerkungen:
' - INPUT wartet bis eine Eingabe empfangen wurde - das Programm steht solange!!!
' - INPUT wartet auf den Befehl "CR" am Ende - sonst wird die Eingabe nicht erkannt


'Beschreibung:

'2 RC Empfängerkanäle werden abgefragt

'Beim einschalten muss die FB in Nullstellung sein, da diese Position beim einschalten als Neutral gespeichert wird.

'Kanal 2: ist Gas/Bremse und schaltet das Bremslicht
'Knüppel in Mittelstellung = LED´s volle Helligkeit
'Knüppel vor/zurück = LED´s gedimmt über Hardware PWM

'Kanal 3: war noch frei und schaltet nun Abblendlicht bzw. Fernlicht
'über PWM als Tast- und Rastfunktion bei Knüppel UNTEN
'Knüppel OBEN hat auch Tast- und Rastfunktion und schaltet 2 LED´s
'die wie bei einem Polizeiauto an der Fron in der Mitte als Doppelblitz
'blitzen(2xlinks...2xrechts...2xlinks...).


'Das Hi-Signal vom Empfänger wird mit "Pulsein" ermittelt!
'Knüppelstellung Mitte hat ca. 159 Zeiteinheiten bei einem 20 MHz Quarz!

'An den Ausgängen für die LED´s sind Transistoren (BD677) die nach Masse schalten.

'Nicht angeschlossene Kanäle müssen auf einen angeschlossenen Kanal gebrückt
'werden - wenn kein Signal kommt wartet das Programm, bis ein ERROR nach ca.650ms kommt!

'LED´s:
'Abblendlicht - PWM - Compare1A
'Bremslicht - PWM - Compare1B
'Fernlicht_Links ohne PWM
'Fernlicht_Rechts ohne PWM

'Menü über RS232:
'Programm HTerm: 19200 Baud; Neue Zeile bei CR+LF; Zeichen senden als "ASC" und mit Enter CR+LF abschließen!!!
'man hat nur knapp 3 sekunden um mit "1" in das Menü zu gelangen - also vielleicht die 1 schon vorher drücken und dann bei Start nur noch Enter drücken

'EEPROM:
'einige Werte werden aus dem EEProm ausgelesen - wenn das EEProm leer ist funktioniert es nicht ;-)
'siehe bei Programmstart: Start-Werte setzen / aus EEPROM übernehmen


'-------------------------------------------------------------------------------
'Konfiguration µC:
$regfile = "m88def.dat" 'Deklarationen
$crystal = 20000000 'interner Quarz 8MHz
$baud = 19200 'Baudrate der UART: 9600 Baud

'-------------------------------------------------------------------------------
'Ein- Ausgänge:
Ddrb = &B11111111 '1 Ausgang, 0 Eingang = alles Ausgänge
Ddrc = &B0000000 '1 Ausgang, 0 Eingang = alles Eingänge
Ddrd = &B11111111 '1 Ausgang, 0 Eingang = alles Ausgänge


'-------------------------------------------------------------------------------
'Konfiguration Timer:
'Timer0 = 8 Bit

Config Timer0 = Pwm , Compare A Pwm = Clear Up , Compare B Pwm = Clear Up , Prescale = 64
On Timer0 Isr_von_timer0
Enable Timer0

'------------------------------------------------------------------------------
'Variablen auswertung FB
Dim Pulsbreite2 As Word 'Knüppelstellung Knüppel Kanal 2 '
Dim K2null As Word 'Nullstellung Kanal 2
Dim K2null2 As Word 'hilfsNullstellung Kanal 2
Dim K2hys As Byte 'Hyterese
Dim K2hys_eeprom As Eram Byte


Dim Pulsbreite3 As Word
Dim K3null As Word 'Nullstellung Kanal 3
Dim K3null2 As Word 'hilfsNullstellung Kanal 3
Dim K3hys As Byte 'Hyterese
Dim K3hys_eeprom As Eram Byte
Dim K3oz As Word 'Zähler für Kanal 3 wenn OBEN betätigt / Auswertung lange drücken
Dim K3uz As Word 'Zähler für Kanal 3 wenn UNTEN betätigt / Auswertung lange drücken
Dim K3o_rast As Bit 'Rastfunktion OBEN
Dim K3u_rast As Bit 'Rastfunktion UNTEN
Dim K3sperre As Bit '1 = gesperrt

'PWM
Dim Bremse As Byte 'Bremslicht
Dim Bremsedimm As Byte 'dimm wert für Bremslicht
Dim Bremsedimm_eeprom As Eram Byte 'dimm wert für Bremslicht aus EEPROM
Dim Ab_licht As Byte 'Abblendlicht
Dim Ab_lichtdimm As Byte 'dimm wert für Abblendlicht
Dim Ab_lichtdimm_eeprom As Eram Byte 'dimm wert für Abblendlicht aus EEPROM

Dim Blitzlicht As Bit 'Fernlicht links / rechts
Dim Fl As Bit 'Impuls für Blitz
Dim Fl_zaehler As Byte
Dim Fl_auswahl As Byte 'auswahl der Lampe links / rechts / aus
Dim Warten As Byte 'Wartezeit / dauer für Tastendrück lang
Dim Warten_eeprom As Eram Byte 'Wartezeit / dauer für Tastendrück lang aus EEPROM

Dim Rs232 As Byte 'für seriellen Input
Dim Rs232_z As Word 'Zähler Wartezeit für serielle Eingabe
Dim Udr_in As Word 'um UDR auszulesen, zu löschen
Dim Info As Byte '1=Ausgabe von Info´s
Dim Info_eeprom As Eram Byte
Dim Info_m As Byte 'merker damit Info nicht in jeder Do...Loop ausgegeben wird
Dim Info_z As Byte 'welches Infomenue angezeigt werden soll
Dim Info_z_eeprom As Eram Byte 'welches Infomenue angezeigt werden soll
Dim Startmerker As Bit 'wird einmal beim Start ausgeführt
Dim Cpu As Byte 'Auslastung verteilen
'------------------------------------------------------------------------------
'ALIAS
Fl_l Alias Portd.7 'Fernlicht LINKS
Fl_r Alias Portb.0 'Fernlicht RECHTS

'-------------------------------------------------------------------------------

Waitms 250 'Störungen vom einschalten abwarten z.b. Prellen...

Enable Interrupts 'interrupts einschalten

'------------------------------------------------------------------------------
' Start-Werte setzen / aus EEPROM übernehmen

Info = Info_eeprom 'Info´s ausgeben 1=JA
Info_z = Info_z_eeprom 'welche Infos ausgeben


Bremsedimm = Bremsedimm_eeprom 'Wert für gedimmtes Licht Bremse aus EEPROM laden
Ab_lichtdimm = Ab_lichtdimm_eeprom 'Wert für gedimmtes Licht Abblendlicht aus EEPROM laden

Bremse = 255 'Bremslicht 100% einschalten
Ab_licht = Ab_lichtdimm 'Abblendlicht auf gedimmten Wert einstellen

Fl_l = 0 'Fernlicht links aus
Fl_r = 0 'Fernlicht rechts aus

Warten = Warten_eeprom 'Wartezeit aus EEPROM laden

K2hys = K2hys_eeprom 'Hysterese für aktuellen Nullwert K2
K3hys = K3hys_eeprom 'Hysterese für aktuellen Nullwert K3

Pulsein K2null , Pinc , 5 , 1 'aktuelle Nullstellung erfassen
K2null2 = K2null - K2hys 'mit Hysterese umrechnen
K2null = K2null + K2hys 'mit Hysterese umrechnen

Pulsein K3null , Pinc , 4 , 1 'Nullstellung erfassen
'K3null = 159 'fester Wert da Schalter nicht zwingend in Mittelstellung...
K3null2 = K3null - K3hys 'mit Hysterese umrechnen
K3null = K3null + K3hys 'mit Hysterese umrechnen


Print " "
Print "Modelbauschalter V2 Version: "
Print Version(1)
Print "Baudrate: 19200"
Print "_____________________________"
Print " "


Rs232_z = 100 'Wartezeit auf Menüeingabe
Do

Decr Rs232_z 'Variable zum Do...Loop verlassen runterzählen
Print Rs232_z ; " - Druecke die (1) fuer das Menue: " 'Variable anzeigen

Rs232 = Inkey() 'Warten auf eingabe
If Rs232 = 49 Then 'wenn Eingabe = 1 (ASC = 49)
Print "Menü wird gestartet"
Print ""
Udr_in = Udr 'Puffer auslesen b.z.w. leeren
Goto Menue 'und ins Menü springen
End If

Loop Until Rs232_z = 0


Anfang:
Print ""
Print ""
Print "================================================== ================="
Print "Anfang - Programm laueft - das Menue wurde beendet"

'-------------------------------------------------------------------------------
' HAUPTPROGRAMM
'-------------------------------------------------------------------------------
Enable Interrupts
'================================================= ================================================== ==================================
'================================================= ================================================== ==================================
'================================================= ================================================== ==================================
'================================================= ================================================== ==================================
'================================================= ================================================== ==================================
Do 'Do Loop Schleife

Ocr0a = Bremse 'Übergabe der Werte in die PWM Ausgabe
Ocr0b = Ab_licht



'FB auswerten:
'_________________________________________________ ______________________________
'Kanal 2 auswerten (Gas/Bremse):
'_________________________________________________ ______________________________

Pulsein Pulsbreite2 , Pinc , 5 , 1 'Pulsbreite auslesen (1=High Impuls)
'Knüppel Gas / Bremslicht
If Pulsbreite2 < K2null And Pulsbreite2 > K2null2 Then 'wenn Knüppel in Mittelstellung dann
Bremse = 255 'volle helligkeit
Else 'sonst
Bremse = Bremsedimm 'gedimmt
End If




'_________________________________________________ ______________________________
'Kanal 3 auswerten (Abblendlicht/Fernlicht):
'_________________________________________________ ______________________________

Pulsein Pulsbreite3 , Pinc , 4 , 1 'Pulsbreite auslesen (1=High Impuls)
'Knüppel UNTEN
If Pulsbreite3 > K3null Then 'wenn Knüppel unten dann
Incr K3uz 'Variable hochzählen
End If

'Knüppel MITTE
If Pulsbreite3 < K3null And Pulsbreite3 > K3null2 Then 'wenn Knüppel in Mittelstellung dann
K3oz = 0 'falls der Zählerstand zum schalten nicht erreicht wird, wird hier auf 0 gesetzt
K3uz = 0 'falls der Zählerstand zum schalten nicht erreicht wird, wird hier auf 0 gesetzt
K3sperre = 0 'Sperre frei (für Rastfunktion)
End If

'Knüppel OBEN
If Pulsbreite3 < K3null2 Then 'wenn Knüppel oben dann
Incr K3oz 'Variable hochzählen
End If


'_________________________________________________ ______________________________
'Blitzlicht:
If K3oz = 0 And K3o_rast = 0 Then 'wenn Knüppel in Mittelposition und rasten aus dann
Blitzlicht = 0 'Blitzlicht ausschalten
Fl_auswahl = 0 'Zähler für Fehrnlicht auf 0
Fl_l = 0 'Fernlicht links aus
Fl_r = 0 'Fernlicht rechts aus
End If

'Blitzlicht_tast:
If K3oz > 0 Then 'wenn Knüppel oben dann
Blitzlicht = 1 'Blitzlicht einschalten
If K3o_rast = 1 And K3sperre = 0 Then K3o_rast = 0 'wenn rasten aktiv und Sperre nicht aktiv dann rasten aus
End If
'Blitzlicht_rast:
If K3oz > Warten Then 'wenn Knüppel oben lange genug gehalten wurde dann
K3sperre = 1 'K3 sperren
K3o_rast = 1 'Rastfunktion aktiv
K3oz = 0 'Zähler zurücksetzen
End If

If Blitzlicht = 1 Then Gosub Blitzlicht_routine



'_________________________________________________ ______________________________
'Fernlicht dimmen:
If K3uz = 0 And K3u_rast = 0 Then 'wenn Knüppel in Mittelposition und rasten aus dann
Ab_licht = Ab_lichtdimm 'gedimmte Helligkeit
End If

'Fernlicht volle Helligkeit_tast:
If K3uz > 0 Then 'wenn Knüppel unten dann
Ab_licht = 255 'volle Helligkeit
If K3u_rast = 1 And K3sperre = 0 Then K3u_rast = 0 'wenn rasten aktiv und Sperre nicht aktiv dann rasten aus
End If
'Fernlicht volle Helligkeit_rast:
If K3uz > Warten Then 'wenn Knüppel unten lange genug gehalten wurde dann
K3sperre = 1 'K3 sperren
K3u_rast = 1 'Rastfunktion aktiv
K3uz = 0 'Zähler zurücksetzen
End If



'_________________________________________________ ______________________________
If Info = 1 And Fl = 1 And Info_m = 0 Then 'wenn info aktiv über Menüauswahl und Fl aktiv über Timer0Zähler und infoMerker aus dann

Select Case Info_z 'Auswahl, welche Info angezeigt werden soll


Case 1 : Gosub Info1
Case 2 : Gosub Info2
Case 3 : Gosub Info3
Case 4 : Gosub Info4
'Case 5 : Gosub Info5
'Case 6 : Gosub Info6
'Case 7 : Gosub Info7

'Case Else : Goto Menue_1
End Select

Info_m = 4 'Merker setzen, damit nicht zu oft ausgegeben wird
Else
Decr Info_m 'Merker runterzählen
End If


'Zähler auswerten
If Fl_zaehler > 40 Then 'wird in Timer0 hochgezählt (eigendlich Hardware-PWM-Timer) wenn > 40 dann
Fl_zaehler = 0 'zurücksetzen
Toggle Fl 'Taktgeber - wird für Blitzlicht UND Printbefehle benötigt!!!
'Doppelblitz:
If Fl_auswahl < 12 Then 'es werden 12 Schritte für den Doppelblitz benötigt
Incr Fl_auswahl 'Fernlicht Auswahl hochzählen
Else 'sonst
Fl_auswahl = 1 'zurücksetzen
Fl = 1 'auf 1 setzen damit syncron
End If
End If

Loop


'================================================= ================================================== ==================================
'================================================= ================================================== ==================================
'================================================= ================================================== ==================================
'================================================= ================================================== ==================================
'================================================= ================================================== ==================================
'_________________
Isr_von_timer0: 'ISR von Timer0
Incr Fl_zaehler

Return


'___________________
Blitzlicht_routine:

If Fl = 1 And Fl_auswahl < 4 Then '0-4 ist für Fernlicht links - siehe Tabelle ganz unten
Fl_l = 1 'Fernlicht links AN
Else 'sonst
Fl_l = 0 'Fernlicht links AUS
End If


If Fl = 1 And Fl_auswahl > 6 And Fl_auswahl < 10 Then '6-10 ist für Fernlicht rechts - siehe Tabelle ganz unten
Fl_r = 1 'Fernlicht rechts AN
Else 'sonst
Fl_r = 0 'Fernlicht rechts AUS
End If


Return



Info1:
Print "Gas / K2: " ; Pulsbreite2
Print "Bremse: " ; Bremse
Print "K2null: " ; K2null
Print "K2null2: " ; K2null2
Print "K2Hys: " ; K2hys
Print "-------------------------------"
Print ""
Return

Info2:
Print "Kanal 3: " ; Pulsbreite3
Print "K3null: " ; K3null
Print "K3null2: " ; K3null2
Print "K3Hys: " ; K3hys
Print "K3uz: " ; K3uz
Print "Warten: " ; Warten
Print "K3u_rast: " ; K3u_rast
Print "-------------------------------"
Print ""
Return

Info3:
Print "Kanal 3: " ; Pulsbreite3
Print "K3null: " ; K3null
Print "K3null2: " ; K3null2
Print "K3Hys: " ; K3hys
Print "K3oz: " ; K3oz ; " (muss > warten = Blitzlicht AN) "
Print "Warten: " ; Warten
Print "K3sperre: " ; K3sperre ; " (muss = 0)"
Print "Blitzlicht: " ; Blitzlicht
Print "-------------------------------"
Print ""
Return

Info4:
Print "Gas / K2: " ; Pulsbreite2
Print "K2null: " ; K2null
Print "K2null2: " ; K2null2
Print "K2Hys: " ; K2hys
Print ""
Print "Kanal 3: " ; Pulsbreite3
Print "K3null: " ; K3null
Print "K3null2: " ; K3null2
Print "K3Hys: " ; K3hys

Print "-------------------------------"
Print ""
Return


'_________________
Menue:
Disable Interrupts
Print ""
Print ""
Print ""
Print "************************************************** *****************"
Print "************************************************** *****************"
Print "***** - - - MENUE - - - *****"
Print "************************************************** *****************"
Print " - - - ACHTUNG: BITTE CR-LF 10/13 AKTIVIREN!!! - - - "
Print "************************************************** *****************"
Print "************************************************** *****************"
Print ""
Print "aktuelle Werte:"
Print K2null ; " = K2null - erfasste Nullstellung"
Print K3null ; " = K3null - erfasste Nullstellung"
Print " "
Print Bremsedimm ; " = Bremsedimm - Wert fuer gedimmtes Bremslicht(Empf.10)"
Print Ab_lichtdimm ; " = Ab_lichtdimm - Wert fuer gedimmtes Abblendlicht(Empf.10)"
Print Warten ; " = Warten - Wartezeit fuer Rastfunktion(Empfehlung.25)"
Print " " ; K2hys ; " = Hysterese Kanal 2(Empfehlung.5)"
Print " " ; K3hys ; " = Hysterese Kanal 3(Empfehlung.10)"
Print " "
Print " "
Print "zum aendern (2) druecken... "
Print "zum beenden (0) druecken... "

Do
Udr_in = Udr
Input Rs232 Noecho
Select Case Rs232

Case 2 : Goto Menue_1
Print ""
Print "Auswahl >2< aendern"
Case 0 : Goto Anfang

Case Else : Goto Menue_1
End Select
Loop Until Rs232 = 0
Goto Anfang


Menue_1:
Print ""
Print "================================================== ================="
Print "Welcher Wert soll geaendert werden?"
Print " "
Print "(1) " ; Bremsedimm ; " = Bremsedimm - Wert fuer gedimmtes Bremslicht(Empf.10)"
Print "(2) " ; Ab_lichtdimm ; " = Ab_lichtdimm - Wert fuer gedimmtes Abblendlicht(Empf.10)"
Print "(3) " ; Warten ; " = Warten - Wartezeit fuer Rastfunktion(Empfehlung.25)"
Print "(4) " ; K2hys ; " = Hysterese Kanal 2(Empfehlung.5)"
Print "(5) " ; K3hys ; " = Hysterese Kanal 3(Empfehlung.10)"
Print "(7) " ; Info ; " = InfoAusgabe ein-/ ausschalten"
Print "(8) " ; Info_z ; " = Info_z (Auswahl der InfoAusgabe von aktuellen Werten)"
Print "(0) -- > beenden"

Udr_in = Udr
Input Rs232 Noecho

Select Case Rs232


Case 1 : Goto Wert1
Case 2 : Goto Wert2
Case 3 : Goto Wert3
Case 4 : Goto Hys2
Case 5 : Goto Hys3
Case 7 : Goto Info_aus
Case 8 : Goto Info_zz
Case 0 : Goto Anfang

Case Else : Goto Menue_1
End Select
Return


Wert1:
Print ""
Print "Auswahl >1<"
Print ""
Print "================================================== ================="
Print Bremsedimm ; " = Bremsedimm - Wert fuer gedimmtes Bremslicht"
Print "bitte neuen Wert eingeben"
Udr_in = Udr
Input Bremsedimm Noecho
Print "neuer Wert: " ; Bremsedimm
Bremsedimm_eeprom = Bremsedimm
Print " "
Goto Menue_1
Return

Wert2:
Print ""
Print "Auswahl >2<"
Print ""
Print "================================================== ================="
Print Ab_lichtdimm ; " = Ab_lichtdimm - Wert fuer gedimmtes Abblendlicht"
Print "bitte neuen Wert eingeben"
Udr_in = Udr
Input Ab_lichtdimm Noecho
Print "neuer Wert: " ; Ab_lichtdimm
Ab_lichtdimm_eeprom = Ab_lichtdimm
Print " "
Goto Menue_1
Return

Wert3:
Print ""
Print "Auswahl >3<"
Print ""
Print "================================================== ================="
Print Warten ; " = Warten - Wartezeit fuer Rastfunktion"
Print "bitte neuen Wert eingeben"
Udr_in = Udr
Input Warten Noecho
Print "neuer Wert: " ; Warten
Warten_eeprom = Warten
Print " "
Goto Menue_1
Return

Hys2:
Print ""
Print "Auswahl >4<"
Print ""
Print "================================================== ================="
Print K2hys ; " = Hysterese Kanal 2"
Print "bitte neuen Wert eingeben"
Udr_in = Udr
Input K2hys Noecho
Print "neuer Wert: " ; K2hys
K2hys_eeprom = K2hys
Print " "
Goto Menue_1
Return

Hys3:
Print ""
Print "Auswahl >5<"
Print ""
Print "================================================== ================="
Print K3hys ; " = Hysterese Kanal 3"
Print "bitte neuen Wert eingeben"
Udr_in = Udr
Input K3hys Noecho
Print "neuer Wert: " ; K3hys
K3hys_eeprom = K3hys
Print " "
Goto Menue_1
Return

Info_aus:
Print ""
Print "Auswahl >7<"
Print ""
Print "================================================== ================="
Print Info ; " = InfoAusgabe ein-/ausschlten - 1=ein"
Print "bitte neuen Wert eingeben"
Udr_in = Udr
Input Info Noecho
Print "neuer Wert: " ; Info
Info_eeprom = Info
Print " "
Goto Menue_1
Return

Info_zz:
Print ""
Print "Auswahl >8<"
Print ""
Print "================================================== ================="
Print "Info_z = " ; Info_z
Print "(1) = Gas / Bremslicht"
Print "(2) = K3 Fernlicht"
Print "(3) = K3 Doppelblitz Front"
Print "(4) = K2 & K3 aktuelle Werte"
Print "(5) ="
Print "bitte neuen Wert eingeben"
Udr_in = Udr
Input Info_z Noecho
Info_z_eeprom = Info_z
Print "neuer Wert: " ; Info_z
Print " "
Goto Menue_1
Return






End


'================================================= ==============================
'Doppelblitz ansteuerung Fernlicht
'================================================= ==============================

'FL FL_AUSW links rechts
'1 1 1 0
'0 2 0 0
'1 3 1 0
'0 4 0 0
'1 5 0 0
'0 6 0 0
'1 7 0 1
'0 8 0 0
'1 9 0 1
'0 10 0 0
'1 11 0 0
'0 12 0 0



'================================================= ==============================
'Pinbelegung µC
'================================================= ==============================

'MEGA88:

'Pin = Funktion
' 1 = Reset 10k Widerstand auf +5V
'2&3 = Rs232
' 9 = Quarz 20 MHz mit 33p Kondensator gegen Masse
' 10 = Quarz 20 MHz mit 33p Kondensator gegen Masse
' 11 = PWM Abblendlicht
' 12 = PWM Bremslicht
' 13 = Fernlicht links
' 14 = Fernlicht rechts
' 27 = RC Empfänger Kanal 2(Gas)
' 28 = RC Empfänger Kanal 3(war noch frei)