Wie alles begann - oder - 4Kanal-PWM mit AT90S2313 für einen Magierstab

die farbigen LEDs ...

. .-----------weiss-----------
P1100147_w.JPG

. . .-----------rot----------- . . . . . . -----------gelb-----------
P1100142_r.JPG . P1100146_y.JPG

. . .-----------grün----------- . . . -----------magenta-----------
P1100143_g.JPG . P1100145_v.JPG
 
. . .-----------blau----------- . . . . . . -----------cyan-----------
P1100144_b.JPG . P1100148_c.JPG
Ja ... Cyan sieht beinahe wie blau aus. Das muß noch mit Farbmischtabelle angepaßt werden. :rolleyes: Die Weiß-Mischung muß dadurch auch verbessert werden.

Nun zum "Frust" ... hier sind nur die weißen LEDs der Gondeln an.
P1100152.JPG
Die eine ist allerdings nur am glimmen :p :( Irgendwie liegt es am Wandler. Mist! Das wird ein schönes Gebastel :hmpf: :vollkommenauf: Ich hab in dem Foto zum Test ne andere angelötet. Genauso "glimmig". An der Gesamthelligkeit fehlen also etwa 4 Watt der einen LED. Dabei habe ich vorher extra alle Wandler durchgetestet ob sie sauber funktionieren. Da gab es keinerlei Probleme und nun das.

Und zum Schluß einmal alles an ...
P1100153.JPG
Die weißen strahlen genau so nach unten wie ich mir das gewünscht habe. Man hat also eine Taschenlampe die einem den Weg erhellt. Der alte Stab hat da nur nach oben abgestrahlt und kaum Licht nach unten reflektiert. Das ist auf jeden Fall schon einmal eine Verbesserung. Mit der Farbmischung und den Strahlengängen/Lichtverteilung in den Kristallen bin ich auch sehr zufrieden.

EDIT: Mir ist noch was zur Glimm-LED eingefallen. Eventuell ist da der eine MOSFET ja im halb durchgeschalteten Zustand. Dann fährt er da die Leistung des Wandlers runter. Da ja sowieso ein paar MOSFETs scheinbar das zeitliche gesegnet haben, hoffe ich mal das ich den Bock mit einem MOSFET-Tausch raustreiben kann. In der letzten Lieferung waren auch SOT23er mit 100V drin (IRML 0100). Hoffentlich sind die etwas standfester. Zusätzlich hab ich noch 18V Schutzdioden mitbestellt (1,5KE 18CA). Die sichern dann noch die Versorgungsspannung gegen Spannungsspitzen und anderen Schmutz. Die SOT23 5,1V Z-Diode werde ich auch sicherheitshalber gegen eine normale kleine 0,5W Glasversion tauschen (ZF 5,1).

EDIT2: Transistor rausgelötet (hat mir keine Ruhe gelassen). Dann sollte es gehen. Tja ... MIST ... geht nicht. Also irgendwas am Wandler. :banghead: :vollkommenauf: Das heist also den ganzen Wandlerbereich zerlegen. :hmpf: :fie: Zum Glück sind die Wandler steckbar. Ich wollte die ursprünglich einlöten :boring:

Gruß
Dino
 
Vergleich - Alt zu Neu

Hallo,

mal ein Vergleich vom alten und neuen Magierstab. Beide Bilder wurden bei Tageslicht heute Mittag gemacht.

Hier einmal mit Hauptstrahlrichtung des alten Magierstabs (nach oben raus) ...
P1100162.JPG
Ein deutlicher Unterschied. In Wirklichkeit noch mehr wie auf dem Foto zu sehen.

Und einmal die Richtung, auf die es mir ankam ... zur Seite und unten ...
P1100163.JPG
Ein absolut deutlicher Unterschied in der Helligkeit. :cool:
Wobei immer noch eine LED fehlt :p

Gruß
Dino
 
ahhh okey du machst das 2 stöckig ?! *g*

jetzt bin ich verwirrt, geht dir durch den oberen Aufbau nicht zuviel von deinen Bergkristallen Optisch"verloren"?
 
Ein absolut deutlicher Unterschied in der Helligkeit. :cool:
Wobei immer noch eine LED fehlt :p


Hallo Dino!

Sieht wirklich super aus! :flowers:

Pass aber auf, dass dir das Licht nicht ein Loch in den Fußboden brennt, so hell wie das jetzt schon ist. :D


Ist aber wirklich klasse geworden!
Weiter so.

Grüße,
Cassio
 
Hi bluelight,

ahhh okey du machst das 2 stöckig ?! *g*

jetzt bin ich verwirrt, geht dir durch den oberen Aufbau nicht zuviel von deinen Bergkristallen Optisch"verloren"?

Also von unten strahlen die 7 LEDs in den Bergkristallhaufen. Oben über diesem Haufen "schweben" die drei LED-Gondeln mit jeweils einem Bergkristall und einer weißen LED. Von unten her kommen also die Farben und von oben her reines Weiß.

Der Kopf des großen Bergkristalls ist ein wenig verborgen. Geht aber noch. Mit den 3 weißen noch weiter nach oben würde alles zu sehr in die Länge ziehen. Weiter nach unten ist auch schlecht. Es hat sich so ergeben :rolleyes:

Beim alten Stab hat mir immer mißfallen das ich eigentlich nur Licht nach oben raus hatte. Drum herum war es so ... naja. Wenn man also viel Licht haben wollte mußte man den Stab waagerecht halten und zielen. Dabei kam man natürlich öfter mit Leuten ins Gehege weil der Stab ja auch so seine 170cm lang ist. Ab und zu gabs dann auch mal Gemotze von denen, vergleichbar mit der Situation am Bahnhof auf der Treppe wenn jemand mit zusammengeklapptem Regenschirm vor einem läuft und man beinahe vom Schirm "erstochen" wird. :p Also recht suboptimal. Der neue wird wohl noch etwas länger. Ich tippe mal auf 180cm.

Darum ist die neue Version auf eine breite Abstrahlung zur Seite und nach unten ausgerichtet. Die weißen LEDs strahlen den Boden um einen herum aus und auch etwas zur Seite. Die farbigen LEDs strahlen zwar nach oben, die Spitzen der Kristalle spiegeln das Licht durch ihre Form aber sehr stark zur Seite weg. Vergleichbar mit einem halbdurchlässigen Spiegel im 45°-Winkel.

Das ganze Ding wiegt im Moment etwa 620 Gramm. Dazu kommen jetzt noch 10 Mignonzellen, der Messingkörper für das obere Segment und eine Platine mit dem Mikrocontroller. Ich rechne mal mit nem guten Kilo für den Kopf vom Stab. Da der Stab an sich auch recht massig ist sollte es eine halbwegs vernünftige Gewichtsverteilung mit Schwerpunkt unter dem oberen Drittel geben. Also vom Schwerpunkt etwa 2/3 Länge nach unten und 1/3 nach oben. Damit läßt er sich trotz Gewicht gut führen.

Zuerst muß ich aber mal diesen einen Wandler-Kanal auf die Reihe bekommen. Das nervt ungemein. Man testet extra jedes Einzelteil bevor man es zusammenbaut und dann klappt es trotzdem nicht. :p Ich hab von den Wandlerplatinen jetzt noch den ersten Prototypen mit durchgebrutzeltem LM3404 und einen funktionsfähigen rumfliegen. Man gut das ich etwas mehr gebaut habe. Mit Glück muß ich nur die Wandlerplatine tauschen. Ist aber trotzdem schon ein ziemliches Gefummel. Aber der Wandler liegt ganz außen im Pack. Also noch halbwegs gut erreichbar.

Es ist doch gut wenn man modular und servicefreundlich baut :cool: und zusätzlich noch ein wenig zuviel anfertigt :sarcastic:

Gruß
Dino
 
Wo willst Du da eigentlich noch den voice-recognition-IC + Beschaltung unterbringen? :p
(obwohl man da irgendwie im Netz kaum was moderneres als 10 Jahre findet... kann doch gar nicht sein...)

[rezitier]Flim Flam Flunkel - Licht ins Dunkel[/rezitier]
*wusch*
 
Hallo zusammen,

und schon ist wieder soviel Zeit ins Land gegangen. :p :(

Dafür hab ich jetzt das defekte Wandlermoduil getauscht und alles läuft.
Es geht voran ;)

Jetzt hab ich neben dem Prototypen also noch ein weiteres Modul was repariert werden muß. Ich werd mir wohl noch so 2-3 Reservemodule bauen. Sicher ist sicher. Aber das kommt später.

EDIT: Parallel wird ein wenig an der Controllerplatine gebaut.

Gruß
Dino
 
Hallo,

nun ist auch die Softwareseite angefangen ...
Code:
' #############################################################################
' ##### Magierstab v2 mit Mega32 ##############################################
' #############################################################################
' (c) 27.06.2010 by Dino
' BASCOM 2.0.7.5
'
'

' Prozessor ATmega32
$regfile = "m32def.dat"
' 16MHz Quarztakt (Baudraten-Quarz)
$crystal = 16000000

$hwstack = 32
$swstack = 32
$framesize = 32

' ATMEL AVR ATmega32
' 32kByte Flash (16kx16)
' 1kByte EEPROM
' 32 Register + 2kByte RAM
'
'                                            ATmega32
'                                 +-------------------------------+
'               PWM rt1 ----------| 1 PB0(XCK/T0)     (ADC0)PA0 40|---------- PWM bl1
'               PWM rt2 ----------| 2 PB1(T1)         (ADC1)PA1 39|---------- PWM bl2
'               PWM gn1 ----------| 3 PB2(INT2/AIN0)  (ADC2)PA2 38|---------- PWM bl3
'               PWM gn2 ----------| 4 PB3(OC0/AIN1)   (ADC3)PA3 37|---------- PWM ws1
'                Enable ----------| 5 PB4(SS)         (ADC4)PA4 36|---------- PWM ws2
'        Taster1 --- (ISP) MOSI --| 6 PB5(MOSI)       (ADC5)PA5 35|---------- PWM ws3
'        Taster2 --- (ISP) MISO --| 7 PB6(MISO)       (ADC6)PA6 34|
'        Taster3 ---- (ISP) SCK --| 8 PB7(SCK)        (ADC7)PA7 33|---------- Akkuspannung
'   Reset-Taster -- (ISP) RESET --| 9 RESET                AREF 32|--(*)
'                          +Vcc --|10 VCC                   GND 31|-- GND
'                           GND --|11 GND                  AVCC 30|-- +Vcc (gesiebt)
'                          XTAL --|12 XTAL2          (TOSC2)PC7 29|
'                          XTAL --|13 XTAL1          (TOSC1)PC6 28|
'              MAX232 ||----------|14 PD0(RXD)         (TDI)PC5 27|
'              Debug  ||----------|15 PD1(TXD)         (TDO)PC4 26|
'           INT0-Taster ----------|16 PD2(INT0)        (TMS)PC3 25|
'           INT1-Taster ----------|17 PD3(INT1)        (TCK)PC2 24|
'                                 |18 PD4(OC1B)        (SDA)PC1 23|----------|| 2x LM75 (Akku + Treiber/LEDs)
'                                 |19 PD5(OC1A)        (SCL)PC0 22|----------|| PCF8574 für LCD Servicedisplay
'                                 |20 PD6(ICP1)        (OC2)PD7 21|
'                                 +-------------------------------+
'        (*) 100nF nach GND






' #############################################################################
' ##### DEFINITION DER VARIABLEN ##############################################
' #############################################################################
'
Dim R As Byte
R = 0
Dim G As Byte
G = 0
Dim B As Byte
B = 0
Dim W As Byte
W = 0


' #############################################################################
' ##### DEFINITION DER PORTS ##################################################
' #############################################################################
'
' =============================================================================
' ===== PortA (digital) =======================================================
' =============================================================================
' PA0 ---->-- blau1
' PA1 ---->-- blau2
' PA2 ---->-- blau3
' PA3 ---->-- weiss1
' PA4 ---->-- weiss2
' PA5 ---->-- weiss3
' PA6 ---->--
' PA7 ---->-- VBat-ADC
'
' A=7= I=6= I=5= O=4= O=3= O=2= O=1= O=0=  => 11110111 => DDRB
' VBat ---- ws3  ws2  ws1  bl3  bl2  bl1   => 00001000 => PORTB (init)
'   |    |    |    |    |    |    |    |
'
Ddra = &B0011_1111
Porta = &B0000_0000



' =============================================================================
' ===== PortB =================================================================
' =============================================================================
' PB0 ---->-- rot1
' PB1 ---->-- rot2
' PB2 ---->-- gruen1
' PB3 ---->-- gruen2
' PB4 ---->-- PWM-Enable
' PB5 ---->-- Taster1 (MOSI)
' PB6 ---->-- Taster2 (MISO)
' PB7 ---->-- Taster3 (SCK)
'
' I=7= I=6= I=5= O=4= O=3= O=2= O=1= O=0=  => 11110111 => DDRB
' SCK  MISO MOSI PWME gn2  gn1  rt2  rt1   => 00001000 => PORTB (init)
'   |    |    |    |    |    |    |    |
'
Ddrb = &B0001_1111
Portb = &B1110_0000



' =============================================================================
' ===== PortC (digital) =======================================================
' =============================================================================
' PC0 ---->-- SCL
' PC1 --<->-- SDA
' PC2 ---->--
' PC3 ---->--
' PC4 ---->--
' PC5 ---->--
' PC6 ---->--
' PC7 ---->--
'
' I=7= I=6= I=5= I=4= I=3= I=2= I=1= I=0=  => 11110111 => DDRB
' ---- ---- ---- ---- ---- ---- SDA  SCL   => 00001000 => PORTB (init)
'   |    |    |    |    |    |    |    |
'
Ddrc = &B0000_0000
Portc = &B1111_1111



' =============================================================================
' ===== PortD =================================================================
' =============================================================================
' PD0 --<---- RxD | UART1
' PD1 ---->-- TxD | TTL-Pegel
' PD2 --<---- INT0
' PD3 --<---- INT1
' PD4 --<----
' PD5 --<----
' PD6 --<----
' PD7 --<----
'
' I=7= I=6= I=5= I=4= O=3= I=2= O=1= I=0=  => 00001001 => DDRD
'  T4   T3   T2   T1  TxD1 RxD1 TxD  RxD   => 11110110 => PORTD (init)
'   |    |    |    |    |    |    |    |
'
Ddrd = &B0000_0010
Portd = &B1111_1111



' =============================================================================
' ===== I2C/TWI initialisieren ================================================
' =============================================================================
$lib "i2c_twi.lbx"                                          ' Bibliothek fuer Hardware-TWI einbinden
Config Scl = Portc.0
Config Sda = Portc.1
I2cinit
Config Twi = 300000                                         ' Taktfrequenz 300 kBit/s
' TWI gleich einschalten, das macht BASCOM ansonsten erst beim I2CStart
'Twcr = &B00000100                                           ' nur TWEN setzen
' Optionale Einstellungen für TWI Kommunikation die nicht zwingend erforderliche sind
' Twsr = 0                                                 ' Status und Prescaler Register
' Twbr = 152                                               ' Bit Rate Register, 72 = 100kHz   152 = 50kHz(0 bis 255)
' Config I2cdelay = 40
I2cstart
I2cstop



' =============================================================================
' ===== UART1 (TTL) initialisieren ============================================
' =============================================================================
Config Com1 = 9600 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Config Serialin = Buffered , Size = 8
Open "com1:" For Binary As #1



Waitms 100
  $asm
  sbi portb,0
  $end Asm

Waitms 100
  $asm
  Cbi portb,0
  Sbi portb,1
  $end Asm

Waitms 100
  $asm
  Cbi portb,1
  Sbi portb,2
  $end Asm

Waitms 100
  $asm
  Cbi portb,2
  Sbi portb,3
  $end Asm

Waitms 100
  $asm
  Cbi portb,3
  Sbi portA,0
  $end Asm

Waitms 100
  $asm
  Cbi portA,0
  Sbi portA,1
  $end Asm

Waitms 100
  $asm
  Cbi portA,1
  Sbi portA,2
  $end Asm

Waitms 100
  $asm
  Cbi portA,2
  Sbi portA,3
  $end Asm

Waitms 100
  $asm
  Cbi portA,3
  Sbi portA,4
  $end Asm

Waitms 100
  $asm
  Cbi portA,4
  Sbi portA,5
  $end Asm

Waitms 100
  $asm
  Cbi portA,5
  $end Asm







Dim Loopcount As Word
Loopcount = 0

' #############################################################################
' ##### Hauptschleife Start ###################################################
' #############################################################################
Do

If Pinc.4 = 0 Then
  R = 1
  ' ROT
  $asm
  sbi portb,0
  sbi portb,1
  $end Asm
Else
  R = 0
  ' Nicht ROT
  $asm
  Cbi portb,0
  Cbi portb,1
  $end Asm
End If

If Pinc.5 = 0 Then
  G = 1
  ' GRUEN
  $asm
  sbi portb,2
  sbi portb,3
  $end Asm
Else
  G = 0
  ' Nicht GRUEN
  $asm
  Cbi portb,2
  Cbi portb,3
  $end Asm
End If

If Pinc.6 = 0 Then
  B = 1
  ' BLAU
  $asm
  sbi portA,0
  sbi portA,1
  Sbi portA,2
  $end Asm
Else
  B = 0
  ' Nicht BLAU
  $asm
  Cbi portA,0
  Cbi portA,1
  Cbi portA,2
  $end Asm
End If

W = R + G
W = W + B
If W = 3 Then
  ' WEISS
  $asm
  sbi portA,3
  sbi portA,4
  Sbi portA,5
  $end Asm
Else
  ' Nicht WEISS
  $asm
  Cbi portA,3
  Cbi portA,4
  Cbi portA,5
  $end Asm
End If


Incr Loopcount

Loop
' #############################################################################
' ##### Hauptschleife Ende ####################################################
' #############################################################################


' #############################################################################
Close #1

End

Aufgebaut ist alles auf Dirk seinem Nano-Board mit drangesetzten farbigen LEDs. Läuft echt gut. Man hat Bascom und parallel den Development-Manager von Dirk laufen. Wenn man dann compiliert merkt der Manager das sich die Hex-Datei geändert hat und fragt ob er neu laden soll. Ist ne schöne Sache wenn man irgendwo anders ein wenig basteln möchte ohne zuviel Gedöns mitschleppen zu müssen. Einfach das Board mit nem Netzteil und nem Netbook und schon kann es losgehen. Ich werd mir für das Board wohl noch so ein paar Utilities bauen.

Gruß
Dino
 
Hallo,

nach ein paar Problemen mit dem Timer0 geht es jetzt ganz gut voran. Das Kapitel mit dem Timerproblem wird in einem anderen Thread (Timer0 im Mode2 (CTC) will in Bascom nicht so wie ich ...) abgehandelt.

Im Moment laufen die drei PWM-Kanäle für weiß bereits im 3-Phasen-Betrieb (um etwa 120° versetzt).
SoftPWM-3Ph-ws.png
Damit wird später die Stromversorgung gleichmäßiger belastet und die Elkos müssen nicht so extreme Stromspitzen ausgleichen.

EDIT: Nun gibt es auch drei blaue Kanäle die noch einmal um 60° gegen die Phasenlagen der weißen Kanäle gedreht sind ...
SoftPWM-3Ph-bl-ws.png

EDIT2: Nun sind alle 10 Kanäle über die 360° in der Phasenlage verteilt. Die ISR benötigt im Moment in Bascom etwa 17,5µs Zeit. Gute 60µs habe ich zwischen den ISRs an Luft. Für heute soll es reichen. Die einzelne Ansteuerung der Kanäle mache ich dann beim nächsten mal.

Gruß
Dino
 
Hallo,

hier mal der aktuelle Stand des Quelcodes. Er ist teilweise noch mit einigen Testroutinen durchsetzt und noch nicht vollständig durchdacht.
Code:
' #############################################################################
' ##### Magierstab v2 mit Mega32 ##############################################
' #############################################################################
' (c) 27.06.2010 by Dino
' BASCOM 2.0.7.5
'
'

' Prozessor ATmega32
$regfile = "m32def.dat"
' 16MHz Quarztakt (Baudraten-Quarz)
$crystal = 16000000

$hwstack = 64
$swstack = 64
$framesize = 64

' ATMEL AVR ATmega32
' 32kByte Flash (16kx16)
' 1kByte EEPROM
' 32 Register + 2kByte RAM
'
'                                            ATmega32
'                                 +-------------------------------+
'               PWM rt1 ----------| 1 PB0(XCK/T0)     (ADC0)PA0 40|---------- PWM bl1
'               PWM rt2 ----------| 2 PB1(T1)         (ADC1)PA1 39|---------- PWM bl2
'               PWM gn1 ----------| 3 PB2(INT2/AIN0)  (ADC2)PA2 38|---------- PWM bl3
'               PWM gn2 ----------| 4 PB3(OC0/AIN1)   (ADC3)PA3 37|---------- PWM ws1
' Tast0 / LCD D4 -<---------------| 5 PB4(SS)         (ADC4)PA4 36|---------- PWM ws2
' Tast1 / LCD D5 -<- (ISP) MOSI --| 6 PB5(MOSI)       (ADC5)PA5 35|---------- PWM ws3
' Tast2 / LCD D6 -<- (ISP) MISO --| 7 PB6(MISO)       (ADC6)PA6 34|---------- Enable
' Tast3 / LCD D7 -<-- (ISP) SCK --| 8 PB7(SCK)        (ADC7)PA7 33|---------- Akkuspannung
'   Reset-Taster -- (ISP) RESET --| 9 RESET                AREF 32|--(*)
'                          +Vcc --|10 VCC                   GND 31|-- GND
'                           GND --|11 GND                  AVCC 30|-- +Vcc (gesiebt)
'                          XTAL --|12 XTAL2          (TOSC2)PC7 29|
'                          XTAL --|13 XTAL1          (TOSC1)PC6 28|
' TastC MAX232 ||----------->-----|14 PD0(RXD)         (TDI)PC5 27|
'       Debug  ||-----------<-----|15 PD1(TXD)         (TDO)PC4 26|
'    INT0-Taster ----------->-----|16 PD2(INT0)        (TMS)PC3 25|
'                                 |17 PD3(INT1)        (TCK)PC2 24|
'         LCD CD -----------<-----|18 PD4(OC1B)        (SDA)PC1 23|----------|| 2x LM75 Temperatursensor
'         LCD E  -----------<-----|19 PD5(OC1A)        (SCL)PC0 22|----------|| (Akku + Treiber/LEDs)
'                                 |20 PD6(ICP1)        (OC2)PD7 21|
'                                 +-------------------------------+
'        (*) 100nF nach GND


' ----- FUSES -----
'
' * SUT1 und SUT0 (Zustand=11): Start-up Time 65ms nach Reset,
'   Einstellung für Quarzoszillator und langsam ansteigende
'   Betriebsspannung (Tabelle 5 des Datenblattes)
' * CKSEL3-CKSEL0 (Zustand=1111): Quarzoszillator im Bereich 3-8MHz
'   (Tabelle 4 des Datenblattes)
' * CKOPT (Zustand=1): schneller Quarzoszillator (Tabelle 4 des Datenblattes)
' * BODEN (Zustand=0): Brown-out einschalten
' * BODLEVEL (Zustand=1): Brown-out Schwelle auf 2,7V setzen
'
'  Unter Beachtung der invertierten Logik der Fuse-Bits sollte man
'  also die Fuses so setzen wie im folgenden Bild:
'
' ( )7 ( )6 [ ]BootLock12 [ ]BootLock11 [ ]BootLock02 [ ]BootLock01 [ ]Lock2 [ ]Lock1
'
' [ ]OCDEN [ ]JTAGEN (X)SPIEN [ ]CKOPT  [ ]EESAVE [X]BOOTSZ1 [X]BOOTSZ0 [ ]BOOTRST
'
' [ ]BODLEVEL [X]BODEN [ ]SUT1 [ ]SUT0 [ ]CKSEL3 [ ]CKSEL2 [ ]CKSEL1 [ ]CKSEL0
'  ______________________
' |                      |
' | [X] Bit=0  [ ] Bit=1 | ( ) -> Nicht anwaehlbar  [ ] -> Anwaehlbar
' | progr.     unprogr.  |
' |______________________|





' #############################################################################
' ##### DEFINITION DER VARIABLEN ##############################################
' #############################################################################
'
' Byte-Variablen fuer Assembler !!!ACHTUNG!!! Als erstes definieren !!!
' Mit der String-Variable wird der lineare Speicher zur Verfuegung gestellt der dann
' ueber die Overlays einzeln als Transfer zwischen Bascom und Assembler verwendet wird.
'
Dim Asm_vars As String * 31 At $60                          ' Definition ab SRAM-Start
'
Dim Pwm_ramp As Byte At $60 Overlay                         '01 PWM-Rampenzaehler
Dim Ramp_tmp As Byte At $61 Overlay                         '02 PWM-Rampenzaehler Arbeitswert
'
Dim Pwm_rt1 As Byte At $62 Overlay                          '03 Dimmwert Kanal Rot1
Dim Pwm_rt2 As Byte At $63 Overlay                          '04 Dimmwert Kanal Rot2
Dim Pwm_gn1 As Byte At $64 Overlay                          '05 Dimmwert Kanal Gruen1
Dim Pwm_gn2 As Byte At $65 Overlay                          '06 Dimmwert Kanal Gruen2
Dim Pwm_bl1 As Byte At $66 Overlay                          '07 Dimmwert Kanal Blau1
Dim Pwm_bl2 As Byte At $67 Overlay                          '08 Dimmwert Kanal Blau2
Dim Pwm_bl3 As Byte At $68 Overlay                          '09 Dimmwert Kanal Blau3
Dim Pwm_ws1 As Byte At $69 Overlay                          '10 Dimmwert Kanal Weiss1
Dim Pwm_ws2 As Byte At $6a Overlay                          '11 Dimmwert Kanal Weiss2
Dim Pwm_ws3 As Byte At $6b Overlay                          '12 Dimmwert Kanal Weiss3
'
Dim Max_rt As Byte At $6c Overlay                           '13 Maximalwert Kanal Rot
Dim Max_gn As Byte At $6d Overlay                           '14 Maximalwert Kanal Gruen
Dim Max_bl As Byte At $6e Overlay                           '15 Maximalwert Kanal Blau
Dim Max_ws As Byte At $6f Overlay                           '16 Maximalwert Kanal Weiss

Dim Xxxxxx As Byte At $70 Overlay                           '17 Maximalwert Kanal Weiss
'Dim xxxxxx As Byte At $71 Overlay                           '18 Maximalwert Kanal Weiss
'Dim xxxxxx As Byte At $72 Overlay                           '19 Maximalwert Kanal Weiss
'Dim xxxxxx As Byte At $73 Overlay                           '20 Maximalwert Kanal Weiss
'Dim xxxxxx As Byte At $74 Overlay                           '21 Maximalwert Kanal Weiss
'Dim xxxxxx As Byte At $75 Overlay                           '22 Maximalwert Kanal Weiss
'Dim xxxxxx As Byte At $76 Overlay                           '23 Maximalwert Kanal Weiss
'Dim xxxxxx As Byte At $77 Overlay                           '24 Maximalwert Kanal Weiss
'Dim xxxxxx As Byte At $78 Overlay                           '25 Maximalwert Kanal Weiss
'Dim xxxxxx As Byte At $79 Overlay                           '26 Maximalwert Kanal Weiss
'Dim xxxxxx As Byte At $7a Overlay                           '27 Maximalwert Kanal Weiss
'Dim xxxxxx As Byte At $7b Overlay                           '28 Maximalwert Kanal Weiss
'Dim xxxxxx As Byte At $7c Overlay                           '29 Maximalwert Kanal Weiss
'Dim xxxxxx As Byte At $7d Overlay                           '30 Maximalwert Kanal Weiss
'Dim xxxxxx As Byte At $7e Overlay                           '31 Maximalwert Kanal Weiss

Dim R As Byte
R = 0
Dim G As Byte
G = 0
Dim B As Byte
B = 0
Dim W As Byte
W = 0


Dim Pwm_r As Byte
Pwm_r = 0
Dim Pwm_g As Byte
Pwm_g = 0
Dim Pwm_b As Byte
Pwm_b = 0
Dim Pwm_w As Byte
Pwm_w = 0


' #############################################################################
' ##### DEFINITION DER PORTS ##################################################
' #############################################################################
'
' =============================================================================
' ===== PortA (digital) =======================================================
' =============================================================================
' PA0 ---->-- blau1
' PA1 ---->-- blau2
' PA2 ---->-- blau3
' PA3 ---->-- weiss1
' PA4 ---->-- weiss2
' PA5 ---->-- weiss3
' PA6 ---->-- /PWM-Enable
' PA7 ---->-- VBat-ADC
'
' A=7= O=6= O=5= O=4= O=3= O=2= O=1= O=0=  => 01111111 => DDRB
' VBat PWME ws3  ws2  ws1  bl3  bl2  bl1   => 00000000 => PORTB (init)
'   |    |    |    |    |    |    |    |
'
Ddra = &B0111_1111
Porta = &B0100_0000



' =============================================================================
' ===== PortB =================================================================
' =============================================================================
' PB0 ---->-- rot1
' PB1 ---->-- rot2
' PB2 ---->-- gruen1
' PB3 ---->-- gruen2
' PB4 ---->-- (SS) ---- LCD D4
' PB5 ---->-- (MOSI) -- LCD D5
' PB6 ---->-- (MISO) -- LCD D6
' PB7 ---->-- (SCK) --- LCD D7
'
' I=7= I=6= I=5= O=4= O=3= O=2= O=1= O=0=  => 11110111 => DDRB
' SCK  MISO MOSI PWME gn2  gn1  rt2  rt1   => 00001000 => PORTB (init)
'   |    |    |    |    |    |    |    |
'
Ddrb = &B0001_1111
Portb = &B1110_0000



' =============================================================================
' ===== PortC (digital) =======================================================
' =============================================================================
' PC0 ---->-- SCL
' PC1 --<->-- SDA
' PC2 ---->--
' PC3 ---->--
' PC4 ---->--
' PC5 ---->--
' PC6 ---->--
' PC7 ---->-- Index ISR
'
' I=7= I=6= I=5= I=4= I=3= I=2= I=1= I=0=  => 11110111 => DDRB
' ---- ---- ---- ---- ---- ---- SDA  SCL   => 00001000 => PORTB (init)
'   |    |    |    |    |    |    |    |
'
Ddrc = &B0000_0000
Portc = &B1111_1111



' =============================================================================
' ===== PortD =================================================================
' =============================================================================
' PD0 --<---- RxD | UART1
' PD1 ---->-- TxD | TTL-Pegel
' PD2 --<---- INT0 --- Taster
' PD3 --<---- INT1
' PD4 ---->-- LCD CD
' PD5 ---->-- LCD E
' PD6 --<----
' PD7 ---->-- Index ISR
'
' O=7= I=6= O=5= O=4= I=3= I=2= O=1= I=0=  => 00001001 => DDRD
' ---- ---- LCDE LCDC INT1 INT0 TxD  RxD   => 11110110 => PORTD (init)
'   |    |    |    |    |    |    |    |
'
Ddrd = &B1011_0010
Portd = &B0100_1111



' =============================================================================
' ===== TIMER0 Initialisieren =================================================
' =============================================================================
' Timer0 liefert die Basiszeit (20us)
' Er läuft im Modus 2 (CTC) mit Vorteiler /8 und ohne angeschlossenem OC0-Pin
Config Timer0 = Ctc , Prescale = 8 , Clear Timer = 1 , Compare = Disconnect
On Compare0 Tim0_isr                                        ' Interrupt-Vektor einstellen
Enable Compare0                                             ' Compare0-Interrupt aktivieren
'
'===== Timer/Counter Control Register =====
'Bit --7-- --6-- --5-- --4-- --3-- --2-- --1-- --0-- TCCR0
'    FOC0  WGM00 COM01 COM00 WGM01 CS02  CS01  CS00
'      W    R/W   R/W   R/W   R/W   R/W   R/W   R/W
'           ---   ---------   ---   ---------------
'              \        ||   /                 |||
'                \      00 Normal Port Oper.   000 No Clock (Stopped)
'                  \      /                    001 Clk no Prescaling
'               WGM00\  /WGM01                 010 Clk/8
'                     ||                       011 Clk/64
'                   0 00 Normal                100 Clk/256
'                   1 10 PWM, Phase Correct    101 Clk/1024
'                   2 01 CTC                   110 Ext T0, Clock on falling edge.
'                   3 11 Fast PWM              111 Ext T0, Clock on rising edge.
'
' In Clear Timer on Compare or CTC mode (WGM01:0 = 2), the OCR0 Register is used to
' manipulate the counter resolution. In CTC mode the counter is cleared to zero when
' the counter value (TCNT0) matches the OCR0. The OCR0 defines the top value for the
' counter, hence also its resolution.
' An interrupt can be generated each time the counter value reaches the TOP value by
' using the OCF0 Flag.
'
' Mode2, Prescaler /8, NormalPortOperation
'         FWCC WSSS
'Tccr0 = &B0000_1010


'===== Timer/Counter Register =====
'Bit -7- -6- -5- -4- -3- -2- -1- -0- TCNT0
'    -----------TCNT0[7:0]----------
'    R/W R/W R/W R/W R/W R/W R/W R/W


'===== Output Compare Register =====
'Bit -7- -6- -5- -4- -3- -2- -1- -0- OCR0
'    -----------OCR0[7:0]-----------
'    R/W R/W R/W R/W R/W R/W R/W R/W
Ocr0 = 155                                                  ' Compare-Wert einstellen

'===== Timer/Counter Interrupt Mask Register =====
'Bit --7-- --6-- --5--- --4--- --3--- --2-- --1-- --0-- TIMSK
'    OCIE2 TOIE2 TICIE1 OCIE1A OCIE1B TOIE1 OCIE0 TOIE0
'     R/W   R/W   R/W    R/W    R/W    R/W   R/W   R/W
'
'OCIEx: Timer/Counter Output Compare Match Interrupt Enable
'TOIEx: Timer/Counter Overflow Interrupt Enable
'Enable Compare0
'Timsk = &B0000_0010

'===== Timer/Counter Interrupt Flag Register =====
'Bit --7-- --6-- --5-- --4-- --3-- --2-- --1-- --0-- TIFR
'    OCF2  TOV2  ICF1  OCF1A OCF1B TOV1  OCF0  TOV0
'     R/W   R/W   R/W   R/W   R/W   R/W   R/W   R/W

' 200Hz PWM * 8Bit = 51,2kHz | 100Hz      | 50Hz <=== das reicht und entlastet
' 1 / 51,2kHz = 19,5us       | 39us       | 78us      den Prozessor
' Compare                    |            |
' Prescaler   Compare        | Presc Comp | Presc Comp
'      8      39             |   8    77  |   8   155
'     64       4             |  64     9  |  64    19







Enable Interrupts                                           ' Interrupts global aktivieren

Dim Loopcount As Word
Loopcount = 0

' #############################################################################
' ##### Hauptschleife Start ###################################################
' #############################################################################
Do



If Loopcount > 3000 Then
  ' ### Index Dimm ###      Anschalten fuer LA8
'  $asm
'  sbi portb,2
'  sbi portb,3
'  $end Asm
  ' #################

  If Pinc.7 = 0 Then                                        ' Taste gedrueckt
    If Pwm_ws1 < 255 Then                                   ' wenn Ende nicht erreich dann hochdimmen
      Incr Pwm_ws1
    End If
  Else                                                      ' Taste nicht gedrueckt
    If Pwm_ws1 > 0 Then                                     ' wenn Null nicht erreich dann runterdimmen
      Decr Pwm_ws1
    End If
  End If

  Pwm_rt1 = Pwm_ws1
  Pwm_rt2 = Pwm_ws1
  Pwm_gn1 = Pwm_ws1
  Pwm_gn2 = Pwm_ws1
  Pwm_ws2 = Pwm_ws1
  Pwm_ws3 = Pwm_ws1
  Pwm_bl1 = Pwm_ws1
  Pwm_bl2 = Pwm_ws1
  Pwm_bl3 = Pwm_ws1

  Loopcount = 0
  ' ### Ende Dimm ###      Ausschalten fuer LA8
'  $asm
'  Cbi portb,2
'  Cbi portb,3
'  $end Asm
  ' #################
End If


Incr Loopcount

Loop
' #############################################################################
' ##### Hauptschleife Ende ####################################################
' #############################################################################







' ================================================
' ===== ISR fuer Timer0 Overflow =================
' ================================================
' Timer0 ist der Impulsgeber fuer den PWM-Rampenzaehler
Tim0_isr:
  ' ### Index ISR ###    Anschalten fuer LA8
  $asm
  sbi portD,7
  $end Asm
  ' #################

  Incr Pwm_ramp                                             ' Ueberlauf vom 8Bit-Timer bearbeiten

' Startpunkt der PWM-Rampen relativ zum Masterzähler
'
' ========== PWM-Phasendiagramm ===============================
'                   1     1     2     2     3     3 -H|
'       4     9     3     8     2     7     1     6 -Z|- 360°Kreis
' 0     5     0     5     0     5     0     5     0 -E|
' |.:.:.|.:.:.|.:.:.|.:.:.|.:.:.|.:.:.|.:.:.|.:.:.|
' R1                      R2                      R1 - 180° +0
'             G1                      G2             - 180° +90
'   B1              B2              B3               - 120° +15
'           W1              W2              W3       - 120° +75
' |.:.:.|.:.:.|.:.:.|.:.:.|.:.:.|.:.:.|.:.:.|.:.:.|
'                        1  1       1 1     2     2 -H|
'   1       5 6     8    2  3       8 9     2     5 -Z|- 1Byte
' 0 1       3 4     5    8  9       1 2     4     6 -E|
'
' R1   1° =   0,71111111
' B1  15° =  10,6666 (11=15,5°)
' W1  75° =  53,3333 (53=74,5°)
' G1  90° =  64
'    120° =  85,3333 (85=119,5°)
' B2 135° =  95,9999 (96=135°)
' R2 180° = 128
' W2 195° = 138,6666 (139=195,5°)
' B3 255° = 181,3333 (181=254,5°)
' G2 270° = 192
' W3 315° = 223,9999 (224=315°)

  Ramp_tmp = Pwm_ramp                                       ' Rot-Start um 0deg verschieben
' ========== ROT 1 ==========
  If Pwm_rt1 < 1 Then Goto Dim_rt1_aus                      ' Bei PWM=0 Ausgang abschalten
  If Pwm_rt1 < Ramp_tmp Then Goto Dim_rt1_aus               ' Bei PWM kleiner Rampe also Ausgang abschalten
  ' PWM-Wert ist gleich oder groesser Rampe also Ausgang anschalten
  ' WEISS
  $asm
  sbi portb,0
  $end Asm
  Goto Dim_rt1_end                                          ' zum Ende um den Ausgang anzulassen
Dim_rt1_aus:                                                ' Ab hier den Ausgang abschalten
  ' Nicht WEISS
  $asm
  Cbi portb,0
  $end Asm
Dim_rt1_end:

Ramp_tmp = Ramp_tmp + 128                                   ' Eine Phase weiter (+180deg)
' ========== ROT 2 ==========
  If Pwm_rt2 < 1 Then Goto Dim_rt2_aus                      ' Bei PWM=0 Ausgang abschalten
  If Pwm_rt2 < Ramp_tmp Then Goto Dim_rt2_aus               ' Bei PWM kleiner Rampe also Ausgang abschalten
  ' PWM-Wert ist gleich oder groesser Rampe also Ausgang anschalten
  ' WEISS
  $asm
  sbi portb,1
  $end Asm
  Goto Dim_rt2_end                                          ' zum Ende um den Ausgang anzulassen
Dim_rt2_aus:                                                ' Ab hier den Ausgang abschalten
  ' Nicht WEISS
  $asm
  Cbi portb,1
  $end Asm
Dim_rt2_end:



Ramp_tmp = Pwm_ramp + 64                                    ' Gruen-Start um 90deg verschieben
' ========== GRUEN 1 ==========
  If Pwm_gn1 < 1 Then Goto Dim_gn1_aus                      ' Bei PWM=0 Ausgang abschalten
  If Pwm_gn1 < Ramp_tmp Then Goto Dim_gn1_aus               ' Bei PWM kleiner Rampe also Ausgang abschalten
  ' PWM-Wert ist gleich oder groesser Rampe also Ausgang anschalten
  ' WEISS
  $asm
  sbi portb,2
  $end Asm
  Goto Dim_gn1_end                                          ' zum Ende um den Ausgang anzulassen
Dim_gn1_aus:                                                ' Ab hier den Ausgang abschalten
  ' Nicht WEISS
  $asm
  Cbi portb,2
  $end Asm
Dim_gn1_end:

Ramp_tmp = Ramp_tmp + 128                                   ' Eine Phase weiter (+180deg)
' ========== GRUEN 2 ==========
  If Pwm_gn2 < 1 Then Goto Dim_gn2_aus                      ' Bei PWM=0 Ausgang abschalten
  If Pwm_gn2 < Ramp_tmp Then Goto Dim_gn2_aus               ' Bei PWM kleiner Rampe also Ausgang abschalten
  ' PWM-Wert ist gleich oder groesser Rampe also Ausgang anschalten
  ' WEISS
  $asm
  sbi portb,3
  $end Asm
  Goto Dim_gn2_end                                          ' zum Ende um den Ausgang anzulassen
Dim_gn2_aus:                                                ' Ab hier den Ausgang abschalten
  ' Nicht WEISS
  $asm
  Cbi portb,3
  $end Asm
Dim_gn2_end:



Ramp_tmp = Pwm_ramp + 11                                    ' Blau-Start um 15deg verschieben
' ========== BLAU 1 ==========
  If Pwm_bl1 < 1 Then Goto Dim_bl1_aus                      ' Bei PWM=0 Ausgang abschalten
  If Pwm_bl1 < Ramp_tmp Then Goto Dim_bl1_aus               ' Bei PWM kleiner Rampe also Ausgang abschalten
  ' PWM-Wert ist gleich oder groesser Rampe also Ausgang anschalten
  ' WEISS
  $asm
  sbi portA,0
  $end Asm
  Goto Dim_bl1_end                                          ' zum Ende um den Ausgang anzulassen
Dim_bl1_aus:                                                ' Ab hier den Ausgang abschalten
  ' Nicht WEISS
  $asm
  Cbi portA,0
  $end Asm
Dim_bl1_end:

Ramp_tmp = Ramp_tmp + 85                                    ' Eine Phase weiter
' ========== BLAU 2 ==========
  If Pwm_bl2 < 1 Then Goto Dim_bl2_aus                      ' Bei PWM=0 Ausgang abschalten
  If Pwm_bl2 < Ramp_tmp Then Goto Dim_bl2_aus               ' Bei PWM kleiner Rampe also Ausgang abschalten
  ' PWM-Wert ist gleich oder groesser Rampe also Ausgang anschalten
  ' WEISS
  $asm
  sbi portA,1
  $end Asm
  Goto Dim_bl2_end                                          ' zum Ende um den Ausgang anzulassen
Dim_bl2_aus:                                                ' Ab hier den Ausgang abschalten
  ' Nicht WEISS
  $asm
  Cbi portA,1
  $end Asm
Dim_bl2_end:

Ramp_tmp = Ramp_tmp + 85                                    ' Eine Phase weiter
' ========== BLAU 3 ==========
  If Pwm_bl3 < 1 Then Goto Dim_bl3_aus                      ' Bei PWM=0 Ausgang abschalten
  If Pwm_bl3 < Ramp_tmp Then Goto Dim_bl3_aus               ' Bei PWM kleiner Rampe also Ausgang abschalten
  ' PWM-Wert ist gleich oder groesser Rampe also Ausgang anschalten
  ' WEISS
  $asm
  Sbi portA,2
  $end Asm
  Goto Dim_bl3_end                                          ' zum Ende um den Ausgang anzulassen
Dim_bl3_aus:                                                ' Ab hier den Ausgang abschalten
  ' Nicht WEISS
  $asm
  Cbi portA,2
  $end Asm
Dim_bl3_end:



Ramp_tmp = Pwm_ramp + 53                                    ' Weiss-Start um 75deg verschieben
' ========== WEISS 1 ==========
  If Pwm_ws1 < 1 Then Goto Dim_ws1_aus                      ' Bei PWM=0 Ausgang abschalten
  If Pwm_ws1 < Ramp_tmp Then Goto Dim_ws1_aus               ' Bei PWM kleiner Rampe also Ausgang abschalten
  ' PWM-Wert ist gleich oder groesser Rampe also Ausgang anschalten
  ' WEISS
  $asm
  sbi portA,3
  $end Asm
  Goto Dim_ws1_end                                          ' zum Ende um den Ausgang anzulassen
Dim_ws1_aus:                                                ' Ab hier den Ausgang abschalten
  ' Nicht WEISS
  $asm
  Cbi portA,3
  $end Asm
Dim_ws1_end:

Ramp_tmp = Ramp_tmp + 85                                    ' Eine Phase weiter
' ========== WEISS 2 ==========
  If Pwm_ws2 < 1 Then Goto Dim_ws2_aus                      ' Bei PWM=0 Ausgang abschalten
  If Pwm_ws2 < Ramp_tmp Then Goto Dim_ws2_aus               ' Bei PWM kleiner Rampe also Ausgang abschalten
  ' PWM-Wert ist gleich oder groesser Rampe also Ausgang anschalten
  ' WEISS
  $asm
  sbi portA,4
  $end Asm
  Goto Dim_ws2_end                                          ' zum Ende um den Ausgang anzulassen
Dim_ws2_aus:                                                ' Ab hier den Ausgang abschalten
  ' Nicht WEISS
  $asm
  Cbi portA,4
  $end Asm
Dim_ws2_end:

Ramp_tmp = Ramp_tmp + 85                                    ' Eine Phase weiter
' ========== WEISS 3 ==========
  If Pwm_ws3 < 1 Then Goto Dim_ws3_aus                      ' Bei PWM=0 Ausgang abschalten
  If Pwm_ws3 < Ramp_tmp Then Goto Dim_ws3_aus               ' Bei PWM kleiner Rampe also Ausgang abschalten
  ' PWM-Wert ist gleich oder groesser Rampe also Ausgang anschalten
  ' WEISS
  $asm
  Sbi portA,5
  $end Asm
  Goto Dim_ws3_end                                          ' zum Ende um den Ausgang anzulassen
Dim_ws3_aus:                                                ' Ab hier den Ausgang abschalten
  ' Nicht WEISS
  $asm
  Cbi portA,5
  $end Asm
Dim_ws3_end:




  ' ### Ende ISR ###     Ausschalten fuer LA8
  $asm
  Cbi portD,7
  $end Asm
  ' #################
Return


' #############################################################################

End

Im Moment bin ich mir noch nicht ganz schlüssig wie ich die Serviceeinheit nachher anschließe. Entweder das LCD mit I2C anbinden oder im 4Bit-Betrieb. :confused: Na mal sehen. Für Debugging soll auch eine RS232 dran kommen. Es ist zur Zeit alles im Fluß ...

Aber wenn das Basissystem steht, bin ich schon einen großen Schritt weiter. Timer1 wird wohl noch als Zeitquelle für die DimmUp/DimmDown-Zeiten (Taste drücken/loslassen) verwendet werden.

EDIT: Mal zwei Fotos vom Testaufbau ...
P1100475.JPG . P1100492.JPG
links im "mitgenommenen Zustand" und rechts zuhause mit angeschlossenem LA8 für die Darstellung der PWM-Signale. Den 40er Sockel werd ich noch mit nem Textool-Nullkraft ausstatten.

Gruß
Dino
 
Plaung der Entwicklung

Hallo,

mal ein kleiner "Fahrplan" wo es hingehen soll ...

Die ISR mit dem 10Kanal Soft-PWM soll im Endeffekt komplett in Assembler realisiert werden um eine möglichst kurze Ausführungszeit zu haben. Als Schnittstelle zwischen dem Assemblerbereich und dem Bascombereich wird die 32Byte große Stringvariable verwendet. Die Stringvariable wurde nur benutzt um den Platz im SRAM zu reservieren. Aktiv verwendet werden die Overlay-Variablen. Die Stringvariable MUSS als allererste deklariert werden damit sie ganz am Anfang des SRAM liegt und nichts dazwischenkommen kann. Bascom würde sie sonst eventuell trotzdem verschieben und dann passen die verwendeten Speicherstellen nicht mehr. Der ganze PWM-Bereich soll auf höchste Effizienz getrimmt werden um dem Rest möglichst wenig Prozessorzeit zu klauen.

In der ersten Version werde ich lediglich einen Basisbetrieb wie beim alten Magierstab umsetzten. Also mit 3 Tasten rot, grün und blau dimmen und beim Druck auf alle Tasten die weißen LEDs hinzunehmen. Die Farbmischtabelle soll auch wenn möglich bereits in dieser Basisversion mit drin sein. Diese Mischtabelle wird im EEPROM abgelegt und über den Progger erzeugt. Später soll diese Mischtabelle über ein Bedienteil auch ohne Progger verändert werden können.

Über die vierte Taste am Stab wird eine Art Modusumschaltung umgesetzt. Also wie die Steuerung arbeiten soll. Zum Beispiel so wie der alte Stab oder als Beleuchtung mit heller/dunkler dimmen (aber alles weiß) oder als Flammennachbildung oder sowas. Es sollen maximal 8 Modi möglich sein (0-7).

Über I2C wird eine Temperaturmessung des LED-Clusters und evtl auch des Akkus vorgenommen um notfalls eine Leistungsreduzierung oder Notabschaltung vorzunehmen wenn es zu heiß wird (immerhin 40W!). Ich werde I2C mit LM75 verwenden weil I2C in Hardware ablaufen kann. 1Wire wäre zwar einfacher, läuft aber komplett in Software ab und die PWM würde mit mit hoher Wahrscheinlichkeit darum das 1Wire-Timing zerdeppern. Eventuell wird auch das LCD des Bedienteils (steckbar, abnehmbar) über I2C angesteuert. Weiß ich aber noch nicht genau.

Über UART (auch Hardware) wird eine Diagnoseschnittstelle für Debug-Daten gemacht. Der Anschluß wird sich mit dem MAX232 auch im abnehmbaren Bedienteil befinden und wohl über RJ45 mit Cisco-Belegung erstellt. Eventuell werden zusätzliche Tasten im Bedienteil über einen dort befindlichen kleinen Atmel über den UART als Befehle zum Stab senden.

Die Spannung des Akkupacks wird über ADC7 gemessen und ausgewertet und auch über Debug-UART ausgegeben sowie auf dem LCD angezeigt.

Das größte Problem habe ich im Moment mit der Entwicklung des Bedienteils. Da es aber eher optional ist habe ich dort keine zeitlichen Probleme. Ich bin mir im Moment nicht so ganz im klaren wie ich das LCD ansteuern soll. Ich habe als Verbindung ein 16poliges Kabel mit Schirm. 10 Pole sind signalführend. Der Schirm führt GND. Drei Adern (je 0,05qmm) liefern VBat und drei weitere Vcc/+5V. Ich setze das Kabel ein weil es recht dünn und flexibel ist (nur 5-6mm Durchmesser). Es ist ja bereits in einem Beitrag abgebildet. Über dieses Kabel wird auch die ISP-Schnittstelle herausgeführt. Diese Pins sind gesetzt und nicht zu umgehen. Also MISO, MOSI, SCK, Reset.

Wenn ich jetzt das LCD im 4Bit-Modus anschließe dann benötige ich für den Datenbus auch noch SS damit ich PortB4..7 für LCD D4..7 verwenden kann. Zusätzlich benötige ich noch C/D und EX für das LCD. Damit sind also 7 Adern weg. Bleiben also 3 übrig. Zwei Adern benötige ich noch für den UART. Also bleibt mir eine Ader übrig die ich auf INT0 legen möchte um notfalls mitten im Programm mit dem Bedienteil eingreifen zu können. Dadurch ist die Bedienmöglichkeit durch die wenigen Tasten jedoch arg begrenzt. Außer man setzt einen Atmel mit Tasten im Bedienteil an den UART und sendet von dort Befehle.

Ein weiterer Weg wäre der Anschluß des LCDs über I2C. Damit würde ich SS nicht benötigen. Aber ich bräuchte dann SDA/SCL. Das macht dann zusammen mit dem UART also 8 Adern. Bleiben also zwei Adern für Tasten übrig. Davon ist eine Taste wieder INT0. Eine ist also "normal". Außerdem muß dafür der I2C-Bus über das 1,5m-Kabel geführt werden. Auch nicht so doll. Vor allem weil das Kabel keine wirkliche Paarverseilung besitzt die mir die signalführenden Adern abschirmen würde.

Im Moment geht es wohl eher in Richtung des ersten Modells vom Bedienteil da die 4Bit-Ansteuerung des LCDs wesentlich weniger anfällig im Timing ist. Es kann dort problemlos auch mal die PWM-ISR zwischenhageln. Die Signale sind eher statischer Natur und haben lediglich Minimalzeiten aber nach meiner Info keine Maximalzeiten im Timing. Die Ausgabe könnte sich also lediglich verlangsamen aber nicht durcheinander geraten.

Soviel erstmal zum Fahrplan der Entwicklung.

Gruß
Dino
 
...Die Stringvariable MUSS als allererste deklariert werden damit sie ganz am Anfang des SRAM liegt und nichts dazwischenkommen kann. Bascom würde sie sonst eventuell trotzdem verschieben und dann passen die verwendeten Speicherstellen nicht mehr...
DIM name AS typ AT adresse ist Dir sicherlich bereits ein Begriff?
Bascom VERSUCHT dann, das dorthin zu schreiben - kontrollieren kannst Du das im report file. Mußt Du natürlich auch als erstes anlegen.

Edit: gerade den Post darüber gefunden... hast Du ja bereits...:eek:
 
Aktueller Quellcode-Stand

und hier noch der aktuelle Stand.

Die Dimmung der einzelnen Farben ist in einer sehr einfachen Version "mal eben schnell" umgesetzt.
Code:
' #############################################################################
' ##### Magierstab v2 mit Mega32 ##############################################
' #############################################################################
' (c) 27.06.2010 by Dino
' BASCOM 2.0.7.5
'
'

' Prozessor ATmega32
$regfile = "m32def.dat"
' 16MHz Quarztakt (Baudraten-Quarz)
$crystal = 16000000

$hwstack = 64
$swstack = 64
$framesize = 64

' ATMEL AVR ATmega32
' 32kByte Flash (16kx16)
' 1kByte EEPROM
' 32 Register + 2kByte RAM
'
'                                            ATmega32
'                                 +-------------------------------+
'               PWM rt1 ----------| 1 PB0(XCK/T0)     (ADC0)PA0 40|---------- PWM bl1
'               PWM rt2 ----------| 2 PB1(T1)         (ADC1)PA1 39|---------- PWM bl2
'               PWM gn1 ----------| 3 PB2(INT2/AIN0)  (ADC2)PA2 38|---------- PWM bl3
'               PWM gn2 ----------| 4 PB3(OC0/AIN1)   (ADC3)PA3 37|---------- PWM ws1
' Tast0 / LCD D4 -<---------------| 5 PB4(SS)         (ADC4)PA4 36|---------- PWM ws2
' Tast1 / LCD D5 -<- (ISP) MOSI --| 6 PB5(MOSI)       (ADC5)PA5 35|---------- PWM ws3
' Tast2 / LCD D6 -<- (ISP) MISO --| 7 PB6(MISO)       (ADC6)PA6 34|
' Tast3 / LCD D7 -<-- (ISP) SCK --| 8 PB7(SCK)        (ADC7)PA7 33|---------- Akkuspannung
'   Reset-Taster -- (ISP) RESET --| 9 RESET                AREF 32|--(*)
'                          +Vcc --|10 VCC                   GND 31|-- GND
'                           GND --|11 GND                  AVCC 30|-- +Vcc (gesiebt)
'                          XTAL --|12 XTAL2          (TOSC2)PC7 29|
'                          XTAL --|13 XTAL1          (TOSC1)PC6 28|
' TastC MAX232 ||----------->-----|14 PD0(RXD)         (TDI)PC5 27|
'       Debug  ||-----------<-----|15 PD1(TXD)         (TDO)PC4 26|
'    INT0-Taster ----------->-----|16 PD2(INT0)        (TMS)PC3 25|
'                                 |17 PD3(INT1)        (TCK)PC2 24|---------- /PWM-Enable
'         LCD CD -----------<-----|18 PD4(OC1B)        (SDA)PC1 23|----------|| 2x LM75 Temperatursensor
'         LCD EX -----------<-----|19 PD5(OC1A)        (SCL)PC0 22|----------|| (Akku + Treiber/LEDs)
'                                 |20 PD6(ICP1)        (OC2)PD7 21|---- ISR-Index fuer LA8
'                                 +-------------------------------+
'        (*) 100nF nach GND
'
'
' ===== Kabel 1,27mm Raster =====              ===== Kabel 2,54mm Raster =====
'  1 sw --- ISP1 (MISO) -- LCD D6 (7)          1 |sw -- ISP6 (GND) -- Schirm -- GND
'  2 bn --- ISP3 (SCK) --- LCD D7 (8)          2 |sw
'  3 rt --- ISP4 (MOSI) -- LCD D5 (6)          3 ge --- ISP2 (VTG) ------------ Vcc/+5V
'  4 rs --- ISP5 (RES) --- Reset (9) Tast      4 |or
'  5 ge ------------------ LCD D4 (5)          5 |or -------------------------- VBat
'  6 gn ------------------ LCD CD (18)
'  7 bl ------------------ LCD EX (19)
'  8 vi ------------------ INT0 (16) Tast
'  9 gr ------------------ RxD (14)
' 10 ws ------------------ TxD (15)
'
' ----- FUSES -----
'
' * SUT1 und SUT0 (Zustand=11): Start-up Time 65ms nach Reset,
'   Einstellung für Quarzoszillator und langsam ansteigende
'   Betriebsspannung (Tabelle 5 des Datenblattes)
' * CKSEL3-CKSEL0 (Zustand=1111): Quarzoszillator im Bereich 3-8MHz
'   (Tabelle 4 des Datenblattes)
' * CKOPT (Zustand=1): schneller Quarzoszillator (Tabelle 4 des Datenblattes)
' * BODEN (Zustand=0): Brown-out einschalten
' * BODLEVEL (Zustand=1): Brown-out Schwelle auf 2,7V setzen
'
'  Unter Beachtung der invertierten Logik der Fuse-Bits sollte man
'  also die Fuses so setzen wie im folgenden Bild:
'
' ( )7 ( )6 [ ]BootLock12 [ ]BootLock11 [ ]BootLock02 [ ]BootLock01 [ ]Lock2 [ ]Lock1
'
' [ ]OCDEN [ ]JTAGEN (X)SPIEN [ ]CKOPT  [ ]EESAVE [X]BOOTSZ1 [X]BOOTSZ0 [ ]BOOTRST
'
' [ ]BODLEVEL [X]BODEN [ ]SUT1 [ ]SUT0 [ ]CKSEL3 [ ]CKSEL2 [ ]CKSEL1 [ ]CKSEL0
'  ______________________
' |                      |
' | [X] Bit=0  [ ] Bit=1 | ( ) -> Nicht anwaehlbar  [ ] -> Anwaehlbar
' | progr.     unprogr.  |
' |______________________|





' #############################################################################
' ##### DEFINITION DER VARIABLEN ##############################################
' #############################################################################
'
' Byte-Variablen fuer Assembler !!!ACHTUNG!!! Als erstes definieren !!!
' Mit der String-Variable wird der lineare Speicher zur Verfuegung gestellt der dann
' ueber die Overlays einzeln als Transfer zwischen Bascom und Assembler verwendet wird.
'
Dim Asm_vars As String * 31 At $60                          ' Definition ab SRAM-Start
'
Dim Pwm_ramp As Byte At $60 Overlay                         '01 PWM-Rampenzaehler
Dim Ramp_tmp As Byte At $61 Overlay                         '02 PWM-Rampenzaehler Arbeitswert
'
Dim Pwm_rt1 As Byte At $62 Overlay                          '03 Dimmwert Kanal Rot1
Dim Pwm_rt2 As Byte At $63 Overlay                          '04 Dimmwert Kanal Rot2
Dim Pwm_gn1 As Byte At $64 Overlay                          '05 Dimmwert Kanal Gruen1
Dim Pwm_gn2 As Byte At $65 Overlay                          '06 Dimmwert Kanal Gruen2
Dim Pwm_bl1 As Byte At $66 Overlay                          '07 Dimmwert Kanal Blau1
Dim Pwm_bl2 As Byte At $67 Overlay                          '08 Dimmwert Kanal Blau2
Dim Pwm_bl3 As Byte At $68 Overlay                          '09 Dimmwert Kanal Blau3
Dim Pwm_ws1 As Byte At $69 Overlay                          '10 Dimmwert Kanal Weiss1
Dim Pwm_ws2 As Byte At $6a Overlay                          '11 Dimmwert Kanal Weiss2
Dim Pwm_ws3 As Byte At $6b Overlay                          '12 Dimmwert Kanal Weiss3
'
Dim Max_rt As Byte At $6c Overlay                           '13 Maximalwert Kanal Rot
Dim Max_gn As Byte At $6d Overlay                           '14 Maximalwert Kanal Gruen
Dim Max_bl As Byte At $6e Overlay                           '15 Maximalwert Kanal Blau
Dim Max_ws As Byte At $6f Overlay                           '16 Maximalwert Kanal Weiss

'Dim Xxxxxx As Byte At $70 Overlay                           '17 Maximalwert Kanal Weiss
'Dim xxxxxx As Byte At $71 Overlay                           '18 Maximalwert Kanal Weiss
'Dim xxxxxx As Byte At $72 Overlay                           '19 Maximalwert Kanal Weiss
'Dim xxxxxx As Byte At $73 Overlay                           '20 Maximalwert Kanal Weiss
'Dim xxxxxx As Byte At $74 Overlay                           '21 Maximalwert Kanal Weiss
'Dim xxxxxx As Byte At $75 Overlay                           '22 Maximalwert Kanal Weiss
'Dim xxxxxx As Byte At $76 Overlay                           '23 Maximalwert Kanal Weiss
'Dim xxxxxx As Byte At $77 Overlay                           '24 Maximalwert Kanal Weiss
'Dim xxxxxx As Byte At $78 Overlay                           '25 Maximalwert Kanal Weiss
'Dim xxxxxx As Byte At $79 Overlay                           '26 Maximalwert Kanal Weiss
'Dim xxxxxx As Byte At $7a Overlay                           '27 Maximalwert Kanal Weiss
'Dim xxxxxx As Byte At $7b Overlay                           '28 Maximalwert Kanal Weiss
'Dim xxxxxx As Byte At $7c Overlay                           '29 Maximalwert Kanal Weiss
'Dim xxxxxx As Byte At $7d Overlay                           '30 Maximalwert Kanal Weiss
'Dim xxxxxx As Byte At $7e Overlay                           '31 Maximalwert Kanal Weiss

'Dim R As Byte
'R = 0
'Dim G As Byte
'G = 0
'Dim B As Byte
'B = 0
'Dim W As Byte
'W = 0


'Dim Pwm_r As Byte
'Pwm_r = 0
'Dim Pwm_g As Byte
'Pwm_g = 0
'Dim Pwm_b As Byte
'Pwm_b = 0
'Dim Pwm_w As Byte
'Pwm_w = 0


' #############################################################################
' ##### DEFINITION DER PORTS ##################################################
' #############################################################################
'
' =============================================================================
' ===== PortA (digital) =======================================================
' =============================================================================
' PA0 ---->-- blau1
' PA1 ---->-- blau2
' PA2 ---->-- blau3
' PA3 ---->-- weiss1
' PA4 ---->-- weiss2
' PA5 ---->-- weiss3
' PA6 -------
' PA7 ------- VBat-ADC
'
' A=7= A=6= O=5= O=4= O=3= O=2= O=1= O=0=  => 01111111 => DDRB
' VBat ---- ws3  ws2  ws1  bl3  bl2  bl1   => 00000000 => PORTB (init)
'   |    |    |    |    |    |    |    |
'
Ddra = &B0011_1111
Porta = &B0100_0000



' =============================================================================
' ===== PortB =================================================================
' =============================================================================
' PB0 ---->-- rot1
' PB1 ---->-- rot2
' PB2 ---->-- gruen1
' PB3 ---->-- gruen2
' PB4 ---->-- (SS) ---- LCD D4
' PB5 ---->-- (MOSI) -- LCD D5
' PB6 ---->-- (MISO) -- LCD D6
' PB7 ---->-- (SCK) --- LCD D7
'
' O=7= O=6= O=5= O=4= O=3= O=2= O=1= O=0=  => 11110111 => DDRB
' SCK  MISO MOSI  SS  gn2  gn1  rt2  rt1   => 00001000 => PORTB (init)
'   |    |    |    |    |    |    |    |
'
Ddrb = &B1111_1111
Portb = &B1110_0000



' =============================================================================
' ===== PortC (digital) =======================================================
' =============================================================================
' PC0 ---->-- SCL
' PC1 --<->-- SDA
' PC2 ---->-- /PWM-Enable
' PC3 ---->--
' PC4 ---->--
' PC5 ---->--
' PC6 ---->--
' PC7 ---->--
'
' I=7= I=6= I=5= I=4= I=3= O=2= I=1= I=0=  => 11110111 => DDRB
' ---- ---- ---- ---- ---- PWME SDA  SCL   => 00001000 => PORTB (init)
'   |    |    |    |    |    |    |    |
'
Ddrc = &B0000_0100
Portc = &B1111_1111



' =============================================================================
' ===== PortD =================================================================
' =============================================================================
' PD0 --<---- RxD | UART1
' PD1 ---->-- TxD | TTL-Pegel
' PD2 --<---- INT0 --- Taster
' PD3 --<---- INT1
' PD4 ---->-- LCD CD
' PD5 ---->-- LCD EX
' PD6 --<----
' PD7 ---->-- Index ISR
'
' O=7= I=6= O=5= O=4= I=3= I=2= O=1= I=0=  => 00001001 => DDRD
' ISRx ---- LCDE LCDC INT1 INT0 TxD  RxD   => 11110110 => PORTD (init)
'   |    |    |    |    |    |    |    |
'
Ddrd = &B1011_0010
Portd = &B0100_1111



' =============================================================================
' ===== I2C/TWI initialisieren ================================================
' =============================================================================
$lib "i2c_twi.lbx"                                          ' Bibliothek fuer Hardware-TWI einbinden
Config Scl = Portc.0
Config Sda = Portc.1
I2cinit
Config Twi = 300000                                         ' Taktfrequenz 300 kBit/s
' TWI gleich einschalten, das macht BASCOM ansonsten erst beim I2CStart
'Twcr = &B00000100                                           ' nur TWEN setzen
' Optionale Einstellungen für TWI Kommunikation die nicht zwingend erforderliche sind
' Twsr = 0                                                 ' Status und Prescaler Register
' Twbr = 152                                               ' Bit Rate Register, 72 = 100kHz   152 = 50kHz(0 bis 255)
' Config I2cdelay = 40
I2cstart
I2cstop



' =============================================================================
' ===== UART1 (TTL) initialisieren ============================================
' =============================================================================
Config Com1 = 9600 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Config Serialin = Buffered , Size = 8
Open "com1:" For Binary As #1



' =============================================================================
' ===== LCD initialisieren ====================================================
' =============================================================================
Config Lcd = 16 * 4
Config Lcdpin = Pin , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7 , E = Portd.5 , Rs = Portd.4
' Config Lcdbus = 4
Initlcd
Cursor Off
Cls



' =============================================================================
' ===== TIMER0 Initialisieren =================================================
' =============================================================================
' Timer0 liefert die Basiszeit (20us)
' Er läuft im Modus 2 (CTC) mit Vorteiler /8 und ohne angeschlossenem OC0-Pin
Config Timer0 = Ctc , Prescale = 8 , Clear Timer = 1 , Compare = Disconnect
On Compare0 Tim0_isr                                        ' Interrupt-Vektor einstellen
Enable Compare0                                             ' Compare0-Interrupt aktivieren
'
'===== Timer/Counter Control Register =====
'Bit --7-- --6-- --5-- --4-- --3-- --2-- --1-- --0-- TCCR0
'    FOC0  WGM00 COM01 COM00 WGM01 CS02  CS01  CS00
'      W    R/W   R/W   R/W   R/W   R/W   R/W   R/W
'           ---   ---------   ---   ---------------
'              \        ||   /                 |||
'                \      00 Normal Port Oper.   000 No Clock (Stopped)
'                  \      /                    001 Clk no Prescaling
'               WGM00\  /WGM01                 010 Clk/8
'                     ||                       011 Clk/64
'                   0 00 Normal                100 Clk/256
'                   1 10 PWM, Phase Correct    101 Clk/1024
'                   2 01 CTC                   110 Ext T0, Clock on falling edge.
'                   3 11 Fast PWM              111 Ext T0, Clock on rising edge.
'
' In Clear Timer on Compare or CTC mode (WGM01:0 = 2), the OCR0 Register is used to
' manipulate the counter resolution. In CTC mode the counter is cleared to zero when
' the counter value (TCNT0) matches the OCR0. The OCR0 defines the top value for the
' counter, hence also its resolution.
' An interrupt can be generated each time the counter value reaches the TOP value by
' using the OCF0 Flag.
'
' Mode2, Prescaler /8, NormalPortOperation
'         FWCC WSSS
'Tccr0 = &B0000_1010


'===== Timer/Counter Register =====
'Bit -7- -6- -5- -4- -3- -2- -1- -0- TCNT0
'    -----------TCNT0[7:0]----------
'    R/W R/W R/W R/W R/W R/W R/W R/W


'===== Output Compare Register =====
'Bit -7- -6- -5- -4- -3- -2- -1- -0- OCR0
'    -----------OCR0[7:0]-----------
'    R/W R/W R/W R/W R/W R/W R/W R/W
Ocr0 = 155                                                  ' Compare-Wert einstellen

'===== Timer/Counter Interrupt Mask Register =====
'Bit --7-- --6-- --5--- --4--- --3--- --2-- --1-- --0-- TIMSK
'    OCIE2 TOIE2 TICIE1 OCIE1A OCIE1B TOIE1 OCIE0 TOIE0
'     R/W   R/W   R/W    R/W    R/W    R/W   R/W   R/W
'
'OCIEx: Timer/Counter Output Compare Match Interrupt Enable
'TOIEx: Timer/Counter Overflow Interrupt Enable
'Enable Compare0
'Timsk = &B0000_0010

'===== Timer/Counter Interrupt Flag Register =====
'Bit --7-- --6-- --5-- --4-- --3-- --2-- --1-- --0-- TIFR
'    OCF2  TOV2  ICF1  OCF1A OCF1B TOV1  OCF0  TOV0
'     R/W   R/W   R/W   R/W   R/W   R/W   R/W   R/W

' 200Hz PWM * 8Bit = 51,2kHz | 100Hz      | 50Hz <=== das reicht und entlastet
' 1 / 51,2kHz = 19,5us       | 39us       | 78us      den Prozessor
' Compare                    |            |
' Prescaler   Compare        | Presc Comp | Presc Comp
'      8      39             |   8    77  |   8   155
'     64       4             |  64     9  |  64    19







Enable Interrupts                                           ' Interrupts global aktivieren

Dim Loopcount As Word
Loopcount = 0

' #############################################################################
' ##### Hauptschleife Start ###################################################
' #############################################################################
Do



If Loopcount > 3000 Then
  ' ### Index Dimm ###      Anschalten fuer LA8
'  $asm
'  sbi portb,2
'  sbi portb,3
'  $end Asm
  ' #################

  If Pinc.4 = 0 Then                                        ' Taste gedrueckt
    If Pwm_rt1 < 255 Then                                   ' wenn Ende nicht erreich dann hochdimmen
      Incr Pwm_rt1
    End If
  Else                                                      ' Taste nicht gedrueckt
    If Pwm_rt1 > 0 Then                                     ' wenn Null nicht erreich dann runterdimmen
      Decr Pwm_rt1
    End If
  End If
  Pwm_rt2 = Pwm_rt1

  If Pinc.5 = 0 Then                                        ' Taste gedrueckt
    If Pwm_gn1 < 255 Then                                   ' wenn Ende nicht erreich dann hochdimmen
      Incr Pwm_gn1
    End If
  Else                                                      ' Taste nicht gedrueckt
    If Pwm_gn1 > 0 Then                                     ' wenn Null nicht erreich dann runterdimmen
      Decr Pwm_gn1
    End If
  End If
  Pwm_gn2 = Pwm_gn1

  If Pinc.6 = 0 Then                                        ' Taste gedrueckt
    If Pwm_bl1 < 255 Then                                   ' wenn Ende nicht erreich dann hochdimmen
      Incr Pwm_bl1
    End If
  Else                                                      ' Taste nicht gedrueckt
    If Pwm_bl1 > 0 Then                                     ' wenn Null nicht erreich dann runterdimmen
      Decr Pwm_bl1
    End If
  End If
  Pwm_bl2 = Pwm_bl1
  Pwm_bl3 = Pwm_bl1

  If Pinc.7 = 0 Then                                        ' Taste gedrueckt
    If Pwm_ws1 < 255 Then                                   ' wenn Ende nicht erreich dann hochdimmen
      Incr Pwm_ws1
    End If
  Else                                                      ' Taste nicht gedrueckt
    If Pwm_ws1 > 0 Then                                     ' wenn Null nicht erreich dann runterdimmen
      Decr Pwm_ws1
    End If
  End If

'  Pwm_rt1 = Pwm_ws1
'  Pwm_gn1 = Pwm_ws1
'  Pwm_bl1 = Pwm_ws1
  Pwm_ws2 = Pwm_ws1
  Pwm_ws3 = Pwm_ws1

  Loopcount = 0
  ' ### Ende Dimm ###      Ausschalten fuer LA8
'  $asm
'  Cbi portb,2
'  Cbi portb,3
'  $end Asm
  ' #################
End If


Incr Loopcount

Loop
' #############################################################################
' ##### Hauptschleife Ende ####################################################
' #############################################################################


' Hier die Timer0-ISR für SoftPWM einfuegen !!!


' #############################################################################

End
Nicht wundern wenn im Quellcode noch irgendwas stark gestrickt aussieht. Er entwickelt sich stetig weiter und es können auch Bereich mit falschen Bemerkungen existieren.

Gruß
Dino
 
Da der Text die maximalen 25000 Zeichen überschritten hat, gibts die ISR aus dem Quelltext hier einzeln ...
Code:
' ================================================
' ===== ISR fuer Timer0 Overflow =================
' ================================================
' Timer0 ist der Impulsgeber fuer den PWM-Rampenzaehler
' Compare-Match vom 8Bit-Timer bearbeiten
' Diese Routine wird noch von Bascom in Assembler umgesetzt.
Tim0_isr:
  ' ### Index ISR ###    Anschalten fuer LA8
  $asm
  sbi portD,7
  $end Asm
  ' #################
  Incr Pwm_ramp                                             ' PWM-Rampenzaehler um eins erhoehen

' Startpunkt der PWM-Rampen relativ zum Masterzähler
'
' ========== PWM-Phasendiagramm ===============================
'                   1     1     2     2     3     3 -H|
'       4     9     3     8     2     7     1     6 -Z|- 360°Kreis
' 0     5     0     5     0     5     0     5     0 -E|
' |.:.:.|.:.:.|.:.:.|.:.:.|.:.:.|.:.:.|.:.:.|.:.:.|
' R1                      R2                      R1 - 180° +0
'             G1                      G2             - 180° +90
'   B1              B2              B3               - 120° +15
'           W1              W2              W3       - 120° +75
' |.:.:.|.:.:.|.:.:.|.:.:.|.:.:.|.:.:.|.:.:.|.:.:.|
'                        1  1       1 1     2     2 -H|
'   1       5 6     8    2  3       8 9     2     5 -Z|- 1Byte
' 0 1       3 4     5    8  9       1 2     4     6 -E|
'
' R1   1° =   0,71111111
' B1  15° =  10,6666 (11=15,5°)
' W1  75° =  53,3333 (53=74,5°)
' G1  90° =  64
'    120° =  85,3333 (85=119,5°)
' B2 135° =  95,9999 (96=135°)
' R2 180° = 128
' W2 195° = 138,6666 (139=195,5°)
' B3 255° = 181,3333 (181=254,5°)
' G2 270° = 192
' W3 315° = 223,9999 (224=315°)


  Ramp_tmp = Pwm_ramp                                       ' Rot-Start um 0deg verschieben
' ========== ROT 1 ==========
  If Pwm_rt1 < 1 Then Goto Dim_rt1_aus                      ' Bei PWM=0 Ausgang abschalten
  If Pwm_rt1 < Ramp_tmp Then Goto Dim_rt1_aus               ' Bei PWM kleiner Rampe also Ausgang abschalten
  ' PWM-Wert ist gleich oder groesser Rampe also Ausgang anschalten
  ' WEISS
  $asm
  sbi portb,0
  $end Asm
  Goto Dim_rt1_end                                          ' zum Ende um den Ausgang anzulassen
Dim_rt1_aus:                                                ' Ab hier den Ausgang abschalten
  ' Nicht WEISS
  $asm
  Cbi portb,0
  $end Asm
Dim_rt1_end:

Ramp_tmp = Ramp_tmp + 128                                   ' Eine Phase weiter (+180deg)
' ========== ROT 2 ==========
  If Pwm_rt2 < 1 Then Goto Dim_rt2_aus                      ' Bei PWM=0 Ausgang abschalten
  If Pwm_rt2 < Ramp_tmp Then Goto Dim_rt2_aus               ' Bei PWM kleiner Rampe also Ausgang abschalten
  ' PWM-Wert ist gleich oder groesser Rampe also Ausgang anschalten
  ' WEISS
  $asm
  sbi portb,1
  $end Asm
  Goto Dim_rt2_end                                          ' zum Ende um den Ausgang anzulassen
Dim_rt2_aus:                                                ' Ab hier den Ausgang abschalten
  ' Nicht WEISS
  $asm
  Cbi portb,1
  $end Asm
Dim_rt2_end:



Ramp_tmp = Pwm_ramp + 64                                    ' Gruen-Start um 90deg verschieben
' ========== GRUEN 1 ==========
  If Pwm_gn1 < 1 Then Goto Dim_gn1_aus                      ' Bei PWM=0 Ausgang abschalten
  If Pwm_gn1 < Ramp_tmp Then Goto Dim_gn1_aus               ' Bei PWM kleiner Rampe also Ausgang abschalten
  ' PWM-Wert ist gleich oder groesser Rampe also Ausgang anschalten
  ' WEISS
  $asm
  sbi portb,2
  $end Asm
  Goto Dim_gn1_end                                          ' zum Ende um den Ausgang anzulassen
Dim_gn1_aus:                                                ' Ab hier den Ausgang abschalten
  ' Nicht WEISS
  $asm
  Cbi portb,2
  $end Asm
Dim_gn1_end:

Ramp_tmp = Ramp_tmp + 128                                   ' Eine Phase weiter (+180deg)
' ========== GRUEN 2 ==========
  If Pwm_gn2 < 1 Then Goto Dim_gn2_aus                      ' Bei PWM=0 Ausgang abschalten
  If Pwm_gn2 < Ramp_tmp Then Goto Dim_gn2_aus               ' Bei PWM kleiner Rampe also Ausgang abschalten
  ' PWM-Wert ist gleich oder groesser Rampe also Ausgang anschalten
  ' WEISS
  $asm
  sbi portb,3
  $end Asm
  Goto Dim_gn2_end                                          ' zum Ende um den Ausgang anzulassen
Dim_gn2_aus:                                                ' Ab hier den Ausgang abschalten
  ' Nicht WEISS
  $asm
  Cbi portb,3
  $end Asm
Dim_gn2_end:



Ramp_tmp = Pwm_ramp + 11                                    ' Blau-Start um 15deg verschieben
' ========== BLAU 1 ==========
  If Pwm_bl1 < 1 Then Goto Dim_bl1_aus                      ' Bei PWM=0 Ausgang abschalten
  If Pwm_bl1 < Ramp_tmp Then Goto Dim_bl1_aus               ' Bei PWM kleiner Rampe also Ausgang abschalten
  ' PWM-Wert ist gleich oder groesser Rampe also Ausgang anschalten
  ' WEISS
  $asm
  sbi portA,0
  $end Asm
  Goto Dim_bl1_end                                          ' zum Ende um den Ausgang anzulassen
Dim_bl1_aus:                                                ' Ab hier den Ausgang abschalten
  ' Nicht WEISS
  $asm
  Cbi portA,0
  $end Asm
Dim_bl1_end:

Ramp_tmp = Ramp_tmp + 85                                    ' Eine Phase weiter
' ========== BLAU 2 ==========
  If Pwm_bl2 < 1 Then Goto Dim_bl2_aus                      ' Bei PWM=0 Ausgang abschalten
  If Pwm_bl2 < Ramp_tmp Then Goto Dim_bl2_aus               ' Bei PWM kleiner Rampe also Ausgang abschalten
  ' PWM-Wert ist gleich oder groesser Rampe also Ausgang anschalten
  ' WEISS
  $asm
  sbi portA,1
  $end Asm
  Goto Dim_bl2_end                                          ' zum Ende um den Ausgang anzulassen
Dim_bl2_aus:                                                ' Ab hier den Ausgang abschalten
  ' Nicht WEISS
  $asm
  Cbi portA,1
  $end Asm
Dim_bl2_end:

Ramp_tmp = Ramp_tmp + 85                                    ' Eine Phase weiter
' ========== BLAU 3 ==========
  If Pwm_bl3 < 1 Then Goto Dim_bl3_aus                      ' Bei PWM=0 Ausgang abschalten
  If Pwm_bl3 < Ramp_tmp Then Goto Dim_bl3_aus               ' Bei PWM kleiner Rampe also Ausgang abschalten
  ' PWM-Wert ist gleich oder groesser Rampe also Ausgang anschalten
  ' WEISS
  $asm
  Sbi portA,2
  $end Asm
  Goto Dim_bl3_end                                          ' zum Ende um den Ausgang anzulassen
Dim_bl3_aus:                                                ' Ab hier den Ausgang abschalten
  ' Nicht WEISS
  $asm
  Cbi portA,2
  $end Asm
Dim_bl3_end:



Ramp_tmp = Pwm_ramp + 53                                    ' Weiss-Start um 75deg verschieben
' ========== WEISS 1 ==========
  If Pwm_ws1 < 1 Then Goto Dim_ws1_aus                      ' Bei PWM=0 Ausgang abschalten
  If Pwm_ws1 < Ramp_tmp Then Goto Dim_ws1_aus               ' Bei PWM kleiner Rampe also Ausgang abschalten
  ' PWM-Wert ist gleich oder groesser Rampe also Ausgang anschalten
  ' WEISS
  $asm
  sbi portA,3
  $end Asm
  Goto Dim_ws1_end                                          ' zum Ende um den Ausgang anzulassen
Dim_ws1_aus:                                                ' Ab hier den Ausgang abschalten
  ' Nicht WEISS
  $asm
  Cbi portA,3
  $end Asm
Dim_ws1_end:

Ramp_tmp = Ramp_tmp + 85                                    ' Eine Phase weiter
' ========== WEISS 2 ==========
  If Pwm_ws2 < 1 Then Goto Dim_ws2_aus                      ' Bei PWM=0 Ausgang abschalten
  If Pwm_ws2 < Ramp_tmp Then Goto Dim_ws2_aus               ' Bei PWM kleiner Rampe also Ausgang abschalten
  ' PWM-Wert ist gleich oder groesser Rampe also Ausgang anschalten
  ' WEISS
  $asm
  sbi portA,4
  $end Asm
  Goto Dim_ws2_end                                          ' zum Ende um den Ausgang anzulassen
Dim_ws2_aus:                                                ' Ab hier den Ausgang abschalten
  ' Nicht WEISS
  $asm
  Cbi portA,4
  $end Asm
Dim_ws2_end:

Ramp_tmp = Ramp_tmp + 85                                    ' Eine Phase weiter
' ========== WEISS 3 ==========
  If Pwm_ws3 < 1 Then Goto Dim_ws3_aus                      ' Bei PWM=0 Ausgang abschalten
  If Pwm_ws3 < Ramp_tmp Then Goto Dim_ws3_aus               ' Bei PWM kleiner Rampe also Ausgang abschalten
  ' PWM-Wert ist gleich oder groesser Rampe also Ausgang anschalten
  ' WEISS
  $asm
  Sbi portA,5
  $end Asm
  Goto Dim_ws3_end                                          ' zum Ende um den Ausgang anzulassen
Dim_ws3_aus:                                                ' Ab hier den Ausgang abschalten
  ' Nicht WEISS
  $asm
  Cbi portA,5
  $end Asm
Dim_ws3_end:



  ' ### Ende ISR ###     Ausschalten fuer LA8
  $asm
  Cbi portD,7
  $end Asm
  ' #################
Return
Wer es also lauffähig haben möchte muß es wieder zusammenfügen.

Gruß
Dino
 
Wer falsch mißt sucht einen Fehler der nicht da ist ...

Hallo,

dieses Eigentor möchte ich euch gerne mal als Anschauungsobjekt zeigen ...

Ich hab nun den Timer1 auch im Compare-Interrupt als Zeitbasis für die Dimmgeschwindigkeit eingestellt und eingebunden. Zur Kontrolle habe ich wieder einen Pin (wie in der anderen ISR) während der ISR auf High gesetzt und mit dem Logic8 die Zeit kontrolliert. Dabei kam aber was raus was mir garnicht paßte (6 - ISR-Timer1) ...
PWM_2MS-sec.png
Wie man sieht ist die Ausführung der ISR sehr unregelmäßig. So kann es auf jeden Fall nicht bleiben.


Hier sieht man mal die Laufzeit der ISR mit 500ns (Messwert Width rechts oben) ...
PWM_2MS-sec_500ns.png
Die Angabe +/-100% Meßfehler hätte mich stutzig machen sollen. Aber wenn man schon etwas müde ist dann sieht man nicht mehr so genau hin. Ich hab also einen Fehler im Programm gesucht :p

Des Rätsels Lösung ist die Samplerate des Logikanalysators. Einfach mal auf 4MHz (4MSample/s) hochgedreht ...
PWM_4MS-sec.png
und schon läuft der Interrupt vom Timer1 wunderbar gleichmäßig. Das ist aber auch nur ganz knapp die richtige Samplerate. EEigentlich müßte sie noch höher sein um sauber zu messen.

Ich hab dann mal auf 16MHz hochgedreht und den Impuls der ISR genauer unter die Lupe genommen ...
PWM_24MS-sec_312ns.png
mit 312,5ns und +/-20% Meßfehler ist das eigentlich für eine Messung noch viel zu langsam. Man kann sich nun aber schon einiges zusammenreimen. Wenn der Impuls etwa 300ns lang ist sollte er auf jeden Fall von mindestens einem Sample getroffen werden. Daher müssen die Samples weniger wie diese 300ns auseinanderliegen. Mit etwas Reserve nehme ich einfach mal 270ns. Das würde dann bei ...
1 / 0,27µs = 3,7MHz
... der Fall sein. Also mit 4 MHz Samplerate würde man diese Pulse sicher erkennen. Von Messen sollte man dann aber noch nicht reden. Man sieht lediglich das Impulse vorhanden sind.;)

Zur Abschreckung habe ich nochmal eine Messung mit 1MHz Samplerate gemacht ...
PWM_1MS-sec.png
Die Lücken beim Input6 ISR-Timer1 sagen wohl alles. Es klaffen riesige Lücken in denen die Messzeitpunkte an den Impulsen vorbeischießen und keinen erwischen.

Ergebnis: Bei Messungen erstmal die Samplerate hoch genug drehen und mit einem größeren Datenvolumen arbeiten (mehr Samples). Reinzoomen kann man immer. Wenn aber was nicht erfaßt wurde, dann kann man es auch nicht messen oder sehen.

Und nun mach ich erstmal Augenschonung ... :stoned::sleep:

Gruß
Dino
 
Beiträge zum Logic-Analysator verschoben.

Hallo,

wer es sucht. Ich hab die Beiträge zum Saleae Logic8/Logic16 verschoben weil es nicht so ganz in diesen Thread reingepaßt hat ;)
Man findet sie jetzt hier ... Saleae Logic8/Logic16 - Fragen, Tips, ....
Der Bereich "Programme und Tools - Entwicklungsunterstützende Programme und Tools (Windows, Linux, Mac)" hat nach meiner Meinung am besten gepaßt.

Gruß
Dino
 
Heute mal Metallarbeiten ...

Hallo zusammen,

heute mußte mal Feile und Säge ran. Das Gehäuse muß weiterkommen. Also hab ich mich mal ein wenig in Metallbearbeitung versucht ;)

Zuerst mußte ich ein wenig zeichnen um die entsprechenden Maße für das Blech zu bekommen. Der Blechkegel soll den Tubus für die Elektronik um weitere 20mm verlängern und unten mit einem 30°-Winkel zusammenlaufen und im Durchmesser des Stabes enden. Leider ist der Stab etwas oval. Stört zwar, ist aber kein Abbruchkriterium.
P1100692.JPG
unten auf dem Foto sieht man ein Probestück aus Pappe. Sicher ist sicher.

Das Probestück habe ich dann mal mit dem Tubus und dem Rest zusammengelegt um ein Gefühl für die Proportionen und Maße zu bekommen.
P1100698.JPG
Sieht aber alles soweit gut aus. Das Teil sollte passen.

Nun habe ich den Papp-Kameraden also in 0,5mm Messingblech gefertigt. Unter Einsatz von links- und rechtsschneidenden Blechscheren, Blechknabber und ner Zange zum "wieder glatt machen" :p
P1100705.JPG
Das Ergebnis sieht aber soweit gut aus. Es mußte noch etwas mit der Feile nachgearbeitet werden und wurde dann gebogen.

Um die beiden Teile zu verbinden wollte ich eigentlich einen Messingstreifen mit 2mm Dicke nehmen der jedes Teil mit 10mm überlappt. Das wäre dann 20mm Breite. Hatte ich aber nicht. Also hab ich einen 20mm breiten Streifen von 0,2mm-Blech genommen und den in der Mitte mit einem 10x2mm Streifen verstärkt. Bei dem Gewicht muß man schon mit einigen Kräften rechnen und ich möchte nicht das mir nachher alles zusammenknickt.
P1100706.JPG
Also hier dann die "Bauchbinde" in zusammengelötetem Zustand. Das überschüssige Zinn wurde dann noch weggefeilt.

So sah es dann in zusammengestecktem Zustand aus. Das Innenteil ist wegen den Schrauben nicht ganz eingeschoben. Der Konus ist nur grob vorgebogen und muß noch weiter bearbeitet werden.
P1100707.JPG
Bei den Schrauben kommt am Tubus noch ein 15x2mm Streifen Messing hin in dem die Schrauben als Senkkopf verschwinden. Zwischen den beiden Messingstreifen kommt dann Leder der das alles optisch auflockert. Sonst sieht das doch recht klobig aus. Der untere Konus wird auch mit Leder umspannt. Aus dem Konis kommen dann auch noch die Messingrohre mit den Kabeln für die Tasten, Lade-/Servicebuchse, Modusanzeige und diverses. Im Konus wird auch noch irgendwie ein Schalter untergebracht um sicherheitshalber alles vom Akku zu trennen und auch Strom zu sparen.

So langsam erkennt man wie es mal aussehen soll :cool:

Über die Bohrungen im Stab muß ich mir auch noch ein paar Gedanken machen. Mit dem dreieckigen Akkupack wird die Bohrung im Holz doch etwas groß und das Holz wird zu instabil. Ich werde also den Akkupack umdesignen und 3 Akkus in Reihe und davon 2 nebeneinander legen. Damit benötige ich dann eine Langloch-Bohrung von etwa 20x33mm und etwa 160mm Tiefe. Die Bohrung wird innen mit Glasfaserlaminat verstärkt um eine höhere Stabilität des Holzes zu erzeugen. Schließlich sitzen oben nachher nach aktueller Messung etwa 1150g drauf.

Gruß
Dino
 
Innenwiderstand - Schalter für 4A

Hallo,

heute hab ich mal scherzhalber den Mikroschalter (Marquardt 5A/125VDC) durchgemessen. Er hat 0,22 Ohm. Hmmm ... :p Das verbrät mir bei 4A etwa 0,8V und damit 3,2W der guten Akkuenergie. Außerdem wird das wohl etwas wärmer. Da muß ich mir noch was ausdenken. Entweder 2 parallel schalten oder mal sehen :confused:

Gruß
Dino
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)