Zisternen-Überwachung mit kapazitivem Füllstandssensor

dino03

Aktives Mitglied
27. Okt. 2008
6.760
20
38
Sprachen
  1. BascomAVR
  2. Assembler
Hallo zusammen,

wie angedroht :D hier das nächste Projekt ...
Es soll eine Zisternen-Überwachung (Füllstandsanzeige) werden die mit einem
kapazitiven Sensor arbeitet. Hört sich hochkompliziert an ist aber nur ein Stück
Kabel das im Wasser hängt (Ende isoliert).

Wie schon im anderen Thread erzählt basiert das ganze auf dem folgenden
Artikel aus der elektor 4/2009 Seiten 46-52 "Volle Kanne! Mit Pico- und Femto-
farad zum Füllstand" oder auf der Seite des WDR-Computer-Clubs ..
ComputerClub2 - Downloads
es müßte theoretisch dieses Projekt sein ...
Kapazitätsmessgerät (83 KB) zuletzt geändert am 28.05.08

Der Oszillator für die kapazitive Messung ist fertig gelötet aber noch nicht
getestet. Der Tiny2313 mit 8x2Chr LCD (Pollin C0802-04), 4 Tastern, I2C,
UART, 1Wire, .. läuft hardwaremäßig schon und das erste Lebenszeichen
auf dem LCD ("Test") ist auch schon durch.

Und weil es Spaß macht und gut für die Augen ist hab ich mich in SMD ausgetobt ...
P1050885.JPG P1050887.JPG
im rechten Bild ist vorne der Oszillator für die Messung zu sehen. Im Endeffekt
soll ein abgesetzter Meß-Satellit mit Tiny2313 in der Zisterne die Temperatur
(DS18S20) und den Füllstand (kapazitive Messung) aufnehmen und per UART
an die Anzeigestelle im Keller liefern. Der aktuelle Aufbau ist eigentlich erst
ein "Labor-Muster" zum rumtesten.

Gruß
Dino
 
Hi Dino,

nett wie immer, aber ...
Und weil es Spaß macht und gut für die Augen ist hab ich mich in SMD ausgetobt ...
...kannst Du nicht einmal richtige Platinen verwenden, wie alle anderen, normale Forum- User auch? Haste kein Bügeleisen, schenk' ich Dir eins zu Ostern...:aetsch:


Grüsse,

Michael
 
...kannst Du nicht einmal richtige Platinen verwenden, wie alle anderen, normale Forum- User auch? Haste kein Bügeleisen, schenk' ich Dir eins zu Ostern...:aetsch:
hab ich auch mal dran gedacht. Ich hab auch schon mit dem Gedanken an eine
Platinenfräse gespielt. ...
- Platinenfräse braucht Platz (ca. DIN-A3 Fläche), macht Krach und Staub
- Platinen ätzen geht auf rumgepansche raus.

Irgendwann werde ich wohl dann auf Bügeleisen/Laminiergerät wechseln.
Das wird aber wohl noch etwas dauern ...

Der Tiny2313 hat jetzt noch nen 20MHz Keramikresonator bekommen. Der ist
kleiner als nen Quarz im HC49-Gehäuse. Wird wohl fürs rumtestet reichen.

Gruß
Dino
 
Zum Ätzen:

Mit Tonertransfer und Wippätzgerät geht es eigentlich ohne grosses Gepansche. Bei den Küvettenätzgeräten hatte ich das Problem dass man massenhaft Ätzmittel verschwendet, weil man nicht gleich 10 Platinen in 1 Woche macht. Wenn das Ätzmittel länger als 1 Woche steht ist es aus eigener Erfahrung nicht mehr zu gebrauchen. Beim Wippätzgerät brauche ich pro Ätzgang (2-3 Platinen) gerade mal 80ml, folglich habe ich weniger Ätzmittelverschleiss. Mit Belichten habe ich am ANfang herumgespielt, bin aber davon weggekommen, da man immer wieder Abweichungen dank verschiedener Photopositivbeschichtungen und deren Alter hat. Mit einem Plotter auf eine Platine zu drucken ist auch eine ganz tolle Methode auch wenn es einen mordsmäßigen Krach macht.

Zum Projekt: Schönschön. Das habe ich mal bei unserer Regentonne versucht in dem ich den Widerstand zwischen 2 Metallplatten gemessen habe. Deine Methode sollte aber 10000000 mal genauer sein :) . Ich bin gespannt was du für Abweichungen haben wirst.

Mfg,
Flo
 
Wenn das Ätzmittel länger als 1 Woche steht ist es aus eigener Erfahrung nicht mehr zu gebrauchen.


Hallo Flo !

Öhm..... mein Ätzmittel ist teilweise schon monate in der Ätzanlage und es leistet immer noch gute Dienste.
Scheint so, als mache ich etwas falsch. ;)



Das habe ich mal bei unserer Regentonne versucht in dem ich den Widerstand zwischen 2 Metallplatten gemessen habe.

Nun ja.... Regenwasser und deren Widerstand bzw. Leitwert..... das ist so ein Thema für sich. ;)
Ich denke mal, dass du mit deinem Aufbau keine brauchbaren Werte ermitteln kannst.
Von Oxidation will ich jetzt gar nicht mal sprechen. :rolleyes:



Hi Dino!
Super Sache!
Kann ich dass dann auch für mein Aquarium benutzen?

Ich hatte schon mal begonnen, ähnliche Versuche mit einem 2x0,75mm² isolierten Kabelstück aufzubauen.......
Bin dann aber auf "Abwege" geraten. :rolleyes:

OK, für meine Aquarium kommt es auch nicht auf die genaue Literzahl an..... nur ob sich in einem bestimmten Bereich etwas verändert (Leckwahner).

Trotzdem werde ich das mal gespannt verfolgen.

Grüße,
Cassio
 
Hallo zusammen,

also Bascom ist der totale Flash-Zumüller :(
Mit ner DS18S20-Messung, nen bischen LCD und ein wenig UART sind 2kByte
Flash voll bis Oberkante Unterlippe. Wenn das so weitergeht dann nehme ich
wieder meine Assembler-Routinen für das LCD, 1Wire und UART und schreib
nur noch das allernötigste in Bascom. Boah ... Ich hab keinen Bock nen
Mega8 einzusetzen für so ein bischen Fusselzeugs ...

Debugging über LCD kann ich bei diesem Projekt vergessen. Alleine die ersten
Testroutinen mit LCD, nem Schleifenzähler und einer einzigen Ausgabe der
Zählervariable auf dem LCD (kein UART, kein 1Wire, nix weiter) hat den
Flash-Speicher zu knapp 40% gefüllt. Es kommt noch soweit das ich für
Kleckerzeugs nen Mega32 verwenden muß.

Kein Wunder das Thomas und Markus dauernd die dicken Klopfer (Mega1281,
Mega2561, ...) verwenden. Das ist bestimmt nicht nur wegen IO-Pins.

Über kurz oder lang werde ich mir stark abgespeckte Libraries für LCD, 1Wire,
UART schreiben. So geht das nicht weiter. Das macht keinen Spaß.

Wenn ich bedenke was man mit Assembler alles in die kleinen Dinger rein
bekommt und wenn ich dann sehe wie der Tiny2313 bei Bascom zugemüllt
wird, dann krieg ich die Kriese.

Ich werde die Routinen jetzt so weit wie möglich abspecken und hoffen das
der ganze Kram da reinpaßt (Frequenzmessung, DS18S20 Temperaturmessung,
UART-Senderoutine). Das würde in Assembler mindestens 4mal da reinpassen.

Gruß
Dino
 
Hi Dino,

...Testroutinen mit LCD, nem Schleifenzähler und einer einzigen Ausgabe der
Zählervariable auf dem LCD (kein UART, kein 1Wire, nix weiter) hat den
Flash-Speicher zu knapp 40% gefüllt. Es kommt noch soweit das ich für
Kleckerzeugs nen Mega32 verwenden muß.

cool it! Was glaubst Du, warum ich mit dem Tester nicht weiterkomme? Mistige 2K des 2313.

Was hast Du gegen die Mega8? Mehr Pins=Platz, ok - aber sonst? Nimm den, dann brauchst Du programmiertechnisch nicht solche Klimmzüge machen und hast mehr Zeit zum löten. :)


Grüsse,

Michael
 
Hi Dino!

Nun hör aber auf zu heulen..... ;)

Du kannst doch ASM!

Also, warum regst du dich so auf? :hmmmm:
Nimm du lieber deinen "Bitpopler" und alles wird gut..... :D

Grüße,
Cassio
 
Hallo,

tja ... den Tiny2313 hab ich genommen weil der im 1/20tel Zoll-Raster ist.
Also 1,27mm. Das geht wunderbar auf Lochrasterplatinen. Außerdem reichen
die Pins allemal. Der Mega8 im TQFP hat ein kleineres Rastermaß der Pins und
ich wollte mir die Augen nicht verderben :D :rolleyes:

Wird aber wohl irgendwie da reinpassen (hoffe ich mal) ;)

Gruß
Dino
 
Hallo,

mal wieder ne positive Nachricht (nach dem Gemotze über Bascom) :D
Der Meßoszillator läuft. Ohne was dran liegt er bei 306kHz. Das sagt mir
bis jetzt nur mein Frequenzzähler weil der Atmel noch nicht so will wie ich :rolleyes:
Wenn man die beiden Eingangspins mit dem Finger überbrückt dann geht
er bis auf ca 54kHz runter. Der Schwingkreis soll aber nachher von den
beiden Leitern des Kabels kapazitiv verstellt werden.

Gruß
Dino
 
Es ist vollbracht ...

Hallo,

ich hab das Proggi tatsächlich mit Bascom in den Tiny2313 gequetscht
bekommen :D

So siehts jetzt aus ..


CodeBox BASCOM

' ####################################################
' ##### Basisroutinen für das Tiny2313-EvalBoard #####
' ####################################################
' (c) 27.06.2010 by Dino
'
' Frequenzmessung und Temperaturmessung fuer
' Zisternenanzeige (Fuellstand und Innentemperatur)

' Prozessor ATtiny2313
$regfile = "ATtiny2313.DAT"
$crystal = 20000000

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


' ####################################
' ##### DEFINITION DER VARIABLEN #####
' ####################################
'
' Array fuer den 1Wire-Sensor
Dim Ds18s20(9) As Byte

' Variablen fuer DS18S20 Temperatur
Dim Ds_count As Byte '
Dim Deg_lo As Byte
Dim Deg_hi As Byte

' Variablen fuer Frequenzmessung
Dim Ticks As Word
Dim Cnt_lo As Byte
Dim Cnt_md As Byte
Dim Cnt_hi As Byte
Dim T1ovf As Byte


' ################################
' ##### DEFINITION DER PORTS #####
' ################################
'
' PD0 --<---- RxD | UART
' PD1 ---->-- TxD | TTL-Pegel
'
' PD2 --<---- INT0
' PD3 --<---- INT1
' PD4 --<---- T0 --- 1Wire
' PD5 --<---- T1 --- Mess-Oszillator
' ____________
' | |
' PB0 ---->--|D4 |
' PB1 ---->--|D5 LCD 4Bit |
' PB2 ---->--|D6 HD44780 |
' PB3 ---->--|D7 2x16Chr |
' | |
' PD6 ---->--|E / Sys-LED |
' PB4 ---->--|RS |
' |____________|
'
' PB5 ---->-- SDA - MOSI |
' PB6 --<---- --- - MISO | ISP-Port
' PB7 ---->-- SCL - SCK |
'
' PA0 -- XTAL1 | Systemquarz
' PA1 -- XTAL2 | 20,000MHz
' PA2 -- RESET
'
' ===== PortB =================================================================
' O=7= I=6= O=5= O=4= O=3= O=2= O=1= O=0= => 10111111 => DDRB
' SCL ?? SDA RS D7 D6 D5 D4 => 01000000 => PORTB (init)
' | | | | | | | |
'
Ddrb = &B1011_1111
Portb = &B0100_0000

' ===== PortD =================================================================
' I=7= O=6= I=5= I=4= I=3= I=2= O=1= I=0= => 01000010 => DDRD
' ---- E T1 T0 INT1 INT0 TxD RxD => 00111101 => PORTD (init)
' x | | | | | | |
'
Ddrd = &B0100_0010
Portd = &B0011_1101
'
' ===== UART (TTL) initialisieren =============================================
Config Com1 = 9600 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
' Config Serialin = Buffered , Size = 4
Open "com1:" For Binary As #1
' Clear Serialin


' ===== 1Wire-Bus DS18S20 Temperatursensor ====================================
Config 1wire = Portb.1
'

' ===== Lcd Initialisieren ====================================================
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portd.6 , Rs = Portb.4
Config Lcdbus = 4
Initlcd
Cursor Off
Cls

' ===== Timer Initialisieren ==================================================
Config Timer0 = Timer , Prescale = 256
On Ovf0 Tim0_isr

Config Timer1 = Counter , Edge = Falling , Prescale = 1
On Ovf1 Tim1_isr

Enable Timer0
Enable Timer1


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

Gosub Ds18s20_temp
Gosub Ds18s20_mess

Ticks = 0
Enable Interrupts
Waitms 1100


' Debug-Anzeige
Locate 1 , 1
Lcd Hex(cnt_hi) ; " " ; Hex(cnt_md) ; " " ; Hex(cnt_lo)
Locate 2 , 1
Lcd Hex(deg_hi) ; " " ; Hex(deg_lo)

' Uebertragung der Daten ueber UART (9k6 8n1)
Print #1 , Chr(cnt_hi) ; Chr(cnt_md) ; Chr(cnt_lo); Chr(deg_hi) ; Chr(deg_lo)


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

' ============================================
' ===== Sub fuer DS18S20 Messung starten =====
' ============================================
Ds18s20_mess:
1wreset ' 1Wire-Bus zuruecksetzen
1wwrite &HCC ' Alle 1Wire-Devices ansprechen
1wwrite &H44 ' Temperaturmessung starten
Return



' ================================================
' ===== Sub fuer DS18S20 Temperatur einlesen =====
' ================================================
Ds18s20_temp:
1wreset ' 1Wire-Bus zuruecksetzen
1wwrite &HCC ' Alle 1Wire-Devices ansprechen
1wwrite &HBE ' Scratchpad einlesen

For Ds_count = 1 To 9
Ds18s20(ds_count) = 1wread() ' Scratchpad in Array uebertragen
' Print #1 , Count ; " - " ; Ds18s20(count)
Next

If Ds18s20(9) = Crc8(ds18s20(1) , 8) Then ' Wenn CRC8 korrekt dann Berechnung starten
Deg_lo = Ds18s20(1) ' Temperatur LSB
Deg_hi = Ds18s20(2) ' Temperatur MSB
End If

Return



' ================================================
' ===== ISR fuer Timer0 Overflow =================
' ================================================
' Timer0 ist das Gate fuer die Frequenzmessung
Tim0_isr:
Timer0 = 178
Incr Ticks
If Ticks = 1 Then
Timer1 = 0
T1ovf = 0
End If
If Ticks = 1001 Then
Cnt_lo = Tcnt1l ' Frequenz LSB (Byte 1)
Cnt_md = Tcnt1h ' Frequenz (Byte 2)
Cnt_hi = T1ovf ' Frequenz MSB (Byte 3)
Disable Interrupts
End If
Return



' ================================================
' ===== ISR fuer Timer1 Overflow =================
' ================================================
' Timer1 ist der Zaehler fuer die Frequenzmessung
Tim1_isr:
Incr T1ovf ' 16Bit-Ueberlauf (Byte3) bearbeiten
Return



' ###############################################
' ##### Programm Ende ###########################
' ###############################################
' Close #1
End

73% vom 2kB-Flash werden verwendet (also ca 1,5kByte)
Vom Programm aus der Elektor 4/2009 das ich als Vorlage/Beispiel
verwendet habe ist nicht mehr wirklich viel übrig geblieben ;)
Dafür ist eine 1Wire-Temperaturmessung und die Frequenzmessung drin,
die Werte werden als Debug-Info auf dem LCD angezeigt und als rohe
Bytes auf dem UART übertragen ...
Zisterne_UART-TxD.png

und hier die Einstellung des Timer0 (8Bit) für die Gate-Zeit für die
Frequenzmessung. Also die Zähldauer für die Impulse am Timer1.
Zisterne_Timer0.png
Mit Prescaler=256 und Reload von 178 ergibt sich in etwa 1ms die dann
über die Variable Ticks auf 1sec erweitert wird. Die genaue Frequenz ist
aber nicht so wichtig. Man muß nachher sowieso den gemessenen Wert
auf die Füllhöhe der Zisterne umrechnen.

Nun kann es also weiter gehen. Bei der Auswerte-Einheit hab ich im Gehäuse
mehr Platz und kann da auch nen normalen Mega8 im DIP-Gehäuse nehmen.

Bei der entgültigen Meßeinheit fällt dann nachher das LCD wieder weg. Für
den Probezeitraum will ich es aber unbedingt haben.

Mit einem Funktionsgenerator hab ich den Tiny2313 bis auf 2,2MHz am T1-Pin
getestet. Läuft alles super. Er könnte evtl sogar noch höhere Frequenzen ab.

Gruß
Dino
 
Hi Dino,


...
ich hab das Proggi tatsächlich mit Bascom in den Tiny2313 gequetscht
bekommen :D ...
Super, das lässt ja hoffen, für meinen Tester. Zugegeben, am Programm habe ich noch nicht weitergebastelt..
So siehts jetzt aus ..


CodeBox BASCOM


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

Gosub Ds18s20_temp
Gosub Ds18s20_mess

Ticks = 0
Enable Interrupts
Waitms 1100
...
Loop
[highlight]


CodeBox BASCOM

Fein, diese Technik mit Unterprogrammen bevorzuge ich ebenfalls. Alles, was mindestens 2x gebraucht wird, geht in eine Sub. :)
Gehört das "Enable Interrupts" nicht an den Anfang, vor die Do...Loop Schleife?


CodeBox BASCOM

' ================================================
' ===== ISR fuer Timer0 Overflow =================
' ================================================
' Timer0 ist das Gate fuer die Frequenzmessung
Tim0_isr:
Timer0 = 178
Incr Ticks
If Ticks = 1 Then
Timer1 = 0
T1ovf = 0
End If
If Ticks = 1001 Then
Cnt_lo = Tcnt1l ' Frequenz LSB (Byte 1)
Cnt_md = Tcnt1h ' Frequenz (Byte 2)
Cnt_hi = T1ovf ' Frequenz MSB (Byte 3)
Disable Interrupts
End If
Return
[highlight]


CodeBox BASCOM

ICH verwende hier eigentlich immer Select...Case. Da soll Bascom schnelleren und effizienteren Code erzeugen. Messungen bezüglich Ramverbrauch und Speed habe ich bislang noch nicht durchgeführt.

Bei Gelegenheit muss ich mir den 2313 noch mal vorknöpfen...;)


Grüsse,

Michael
 
Hi Michael,

Fein, diese Technik mit Unterprogrammen bevorzuge ich ebenfalls. Alles, was mindestens 2x gebraucht wird, geht in eine Sub. :)
ich hab mir angewöhnt möglichst nur globale Variablen und Gosubs (also keine
Funktionen, ...) zu verwenden um das SRAM zu entlasten.

Gehört das "Enable Interrupts" nicht an den Anfang, vor die Do...Loop Schleife?
in diesem Fall nicht. Die Interrupts werden für die Frequenz-Messung
eingeschaltet und am Ende der Frequenzmessung (in einer ISR) wieder
ausgeschaltet.

ICH verwende hier eigentlich immer Select...Case. Da soll Bascom schnelleren und effizienteren Code erzeugen. Messungen bezüglich Ramverbrauch und Speed habe ich bislang noch nicht durchgeführt.
Select Case war in dem Fall schlecht einzusetzen.

Bei Gelegenheit muss ich mir den 2313 noch mal vorknöpfen...;)
vom Gehäuse (SOIC20) und den internen Komponenten (UART, ...) ist er
eigentlich nicht schlecht. Nur die 2k Flash sind recht eng wenn man Bascom
verwendet.

Gruß
Dino
 
"Dino stellt ein Programm ein, und alle meckern rum."

So soll es nicht aussehen, aber ich hätte auch noch ein paar Punkte ;)

Config Lcdbus = 4
Hält sich hartnäckig, weil irgendwo in der Hilfe verwendet. Ist hier aber falsch.

Wahrscheinlich zu Testzwecken liest du hier jedes Byte einzeln ein.
For Ds_count = 1 To 9
Ds18s20(ds_count) = 1wread() ' Scratchpad in Array uebertragen
' Print #1 , Count ; " - " ; Ds18s20(count)
Next
Dies braucht 30 Byte weniger
Ds18s20(ds_count) = 1wread(9)

Bei deiner Frequenz dauert jeder 1wire Befehl ~1ms. Das hier
Gosub Ds18s20_temp
Gosub Ds18s20_mess
sind dann etwa 10 ms. Während der Zeit werden mehrere Überläufe verschluckt. Da das 1wire Timing aber sehr zeitkritisch ist, kannst du dir auch nicht erlauben, dass der Interrupt dazwischenkommt.
Wenn ich einen Timer im 1ms Takt überlaufen lasse und gleichzeitig 1wire machen will, habe ich das so gemacht:

Jeder 1wire Befehl wird in eine Bedingung gesetzt:
If 1wire_flag=1 Then
1wire_flag=0
Disable Interrupts
1wreset
Enable Interrupts
End If
Tim0_isr:
...
1wire_flag=1
...
Return

Die Interruptbedingung tritt dann zwar immer noch auf, wenn global disabled ist. Aber nur ein mal. Die Interrupts werden dann sofort im Anschluss nachgeholt, es wird also keiner verschluckt.

Noch mehr Genauigkeit bzgl. der 1ms - die hier evtl. nicht gefragt ist - bekommst du indem du den Timer im CTC Modus laufen lässt. Dann wirken sich die 53 Takte Register retten auch nicht mehr aus. Wobei du als passionierter ASM Spezialist ohnehin die Nosave Option nutzen und die notwendigen Register selber pushen könntest.

Lässt du die LCD Befehle nachher ganz weg, sparst du damit 400 Byte, sodass weniger als 1K übrigbleibt.
Ich weiß leider nicht, wie man die 1wire Kiste in ASM umsetzt, aber ob da soviel weniger rauskommt?

HBA
 
Hallo,

"Dino stellt ein Programm ein, und alle meckern rum."
alle hacken auf mir rum ... keiner hat mich lieb ... schnüf :D

So soll es nicht aussehen, aber ich hätte auch noch ein paar Punkte ;)

Config Lcdbus = 4
Hält sich hartnäckig, weil irgendwo in der Hilfe verwendet. Ist hier aber falsch.
ist irgendwie aus irgendeinem Beispiel mal in meine Programme gewandert
und wurde danach (weil es funktioniert) nicht mehr hinterfragt.

Wahrscheinlich zu Testzwecken liest du hier jedes Byte einzeln ein.
For Ds_count = 1 To 9
Ds18s20(ds_count) = 1wread() ' Scratchpad in Array uebertragen
' Print #1 , Count ; " - " ; Ds18s20(count)
Next
irgendwo geklaut und recyclet ;)

Dies braucht 30 Byte weniger
Ds18s20(ds_count) = 1wread(9)
kann ich ja mal einbauen. Hab ich auch schon mal so gesehen aber wie oben
schon einmal ... es läuft und wurde dadurch nicht mehr hinterfragt.

Bei deiner Frequenz dauert jeder 1wire Befehl ~1ms. Das hier
Gosub Ds18s20_temp
Gosub Ds18s20_mess
sind dann etwa 10 ms. Während der Zeit werden mehrere Überläufe verschluckt. Da das 1wire Timing aber sehr zeitkritisch ist, kannst du dir auch nicht erlauben, dass der Interrupt dazwischenkommt.
Wenn ich einen Timer im 1ms Takt überlaufen lasse und gleichzeitig 1wire machen will, habe ich das so gemacht:

Jeder 1wire Befehl wird in eine Bedingung gesetzt:
If 1wire_flag=1 Then
1wire_flag=0
Disable Interrupts
1wreset
Enable Interrupts
End If
Tim0_isr:
...
1wire_flag=1
...
Return

Die Interruptbedingung tritt dann zwar immer noch auf, wenn global disabled ist. Aber nur ein mal. Die Interrupts werden dann sofort im Anschluss nachgeholt, es wird also keiner verschluckt.
wird bei mir sowieso nicht da die Frequenzmessung mit freigegebenen
Interrupts erst dann anfängt wenn die 1Wire-Messung bereits erledigt ist.

Noch mehr Genauigkeit bzgl. der 1ms - die hier evtl. nicht gefragt ist - bekommst du indem du den Timer im CTC Modus laufen lässt. Dann wirken sich die 53 Takte Register retten auch nicht mehr aus. Wobei du als passionierter ASM Spezialist ohnehin die Nosave Option nutzen und die notwendigen Register selber pushen könntest.

Lässt du die LCD Befehle nachher ganz weg, sparst du damit 400 Byte, sodass weniger als 1K übrigbleibt.
Ich weiß leider nicht, wie man die 1wire Kiste in ASM umsetzt, aber ob da soviel weniger rauskommt?
Ich bin im Moment echt mit dem Gedanken am spielen, einige Bibliotheken
direkt in Assembler selber umzusetzen. Dafür fehlt aber im Moment die Zeit
weil die Zisternenüberwachung Anfang Frühling ... wenn die Zisterne wegen
Reinigung geöffnet wird ... fertig sein sollte.
Die 1Wire-Algorithmen habe ich in Assembler hier liegen (selbst gemacht)
für Mega8/16/32 und Mega168. Die laufen und müßten nur mit Bascom
gekoppelt werden (Werteübergabe). Die sind echt kurz.

Erst einmal kam es mir hauptsächlich auf Funktion an. Egal wie. Der Teil
mit dem Aufräumen kommt später.

Gruß
Dino
 
Frequenzmessung und 1Wire laufen jetzt ...

Hallo,

also hier die neueste Version des Bascom-Geraffels :eek: :p :rolleyes:


CodeBox BASCOM

' ####################################################
' ##### Basisroutinen für das Tiny2313-EvalBoard #####
' ####################################################
' (c) 27.06.2010 by Dino
'
' Frequenzmessung und Temperaturmessung fuer
' Zisternenanzeige (Fuellstand und Innentemperatur)

' Prozessor ATtiny2313
$regfile = "ATtiny2313.DAT"
$crystal = 20000000

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


' ####################################
' ##### DEFINITION DER VARIABLEN #####
' ####################################
'
' Array fuer den 1Wire-Sensor
Dim Ds18s20(9) As Byte

' Variablen fuer DS18S20 Temperatur
Dim Ds_count As Byte '
Dim Deg_lo As Byte
Dim Deg_hi As Byte

' Variablen fuer Frequenzmessung
Dim Ticks As Word
Dim Cnt_lo As Byte
Dim Cnt_md As Byte
Dim Cnt_hi As Byte
Dim T1ovf As Byte


' ################################
' ##### DEFINITION DER PORTS #####
' ################################
'
' PD0 --<---- RxD | UART
' PD1 ---->-- TxD | TTL-Pegel
'
' PD2 --<---- INT0
' PD3 --<---- INT1
' PD4 --<---- T0 --- 1Wire
' PD5 --<---- T1 --- Mess-Oszillator
' ____________
' | |
' PB0 ---->--|D4 |
' PB1 ---->--|D5 LCD 4Bit |
' PB2 ---->--|D6 HD44780 |
' PB3 ---->--|D7 2x16Chr |
' | |
' PD6 ---->--|E / Sys-LED |
' PB4 ---->--|RS |
' |____________|
'
' PB5 ---->-- SDA - MOSI |
' PB6 --<---- --- - MISO | ISP-Port
' PB7 ---->-- SCL - SCK |
'
' PA0 -- XTAL1 | Systemquarz
' PA1 -- XTAL2 | 20,000MHz
' PA2 -- RESET
'
' ===== PortB =================================================================
' O=7= I=6= O=5= O=4= O=3= O=2= O=1= O=0= => 10111111 => DDRB
' SCL ?? SDA RS D7 D6 D5 D4 => 01000000 => PORTB (init)
' | | | | | | | |
'
Ddrb = &B1011_1111
Portb = &B0100_0000

' ===== PortD =================================================================
' I=7= O=6= I=5= I=4= I=3= I=2= O=1= I=0= => 01000010 => DDRD
' ---- E T1 T0 INT1 INT0 TxD RxD => 00111101 => PORTD (init)
' x | | | | | | |
'
Ddrd = &B0100_0010
Portd = &B0011_1101
'
' ===== UART (TTL) initialisieren =============================================
Config Com1 = 9600 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
' Config Serialin = Buffered , Size = 4
Open "com1:" For Binary As #1
' Clear Serialin


' ===== 1Wire-Bus DS18S20 Temperatursensor ====================================
Config 1wire = Portd.4
'

' ===== Lcd Initialisieren ====================================================
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portd.6 , Rs = Portb.4
Config Lcdbus = 4
Initlcd
Cursor Off
Cls

' ===== Timer Initialisieren ==================================================
Config Timer0 = Timer , Prescale = 256 ' Timer0 liefert die Messzeit (1sec)
On Ovf0 Tim0_isr

Config Timer1 = Counter , Edge = Falling , Prescale = 1 ' Timer1 zaehlt die Eingangstakte
On Ovf1 Tim1_isr

Enable Timer0
Enable Timer1


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

Gosub Ds18s20_temp ' 1Wire Temperatur abfragen
Gosub Ds18s20_mess ' 1Wire Messung starten - der chip arbeitet alleine weiter

Ticks = 0 ' Timer0-Ticks initialisieren
Enable Interrupts ' Interrupts für Frequenzmessung anschalten
Waitms 1100 ' Die Frequenzmessung sollte nach 1,1sec beendet sein.
' und damit die Interrupts auch wieder abgeschaltet (siehe ISR)

' Debug-Anzeige
Locate 1 , 1
Lcd Hex(cnt_hi) ; " " ; Hex(cnt_md) ; " " ; Hex(cnt_lo)
Locate 2 , 1
Lcd Hex(deg_hi) ; " " ; Hex(deg_lo)

' Uebertragung der Daten ueber UART (9k6 8n1) im Binaerformat mit crlf (0D 0A) als Endmarke
Print #1 , Chr(cnt_hi) ; Chr(cnt_md) ; Chr(cnt_lo) ; Chr(deg_hi) ; Chr(deg_lo)
' Print #1 , Cnt_hi ; " " ; Cnt_md ; " " ; Cnt_lo ; " " ; Deg_hi ; " " ; Deg_lo


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

' ============================================
' ===== Sub fuer DS18S20 Messung starten =====
' ============================================
Ds18s20_mess:
1wreset ' 1Wire-Bus zuruecksetzen
1wwrite &HCC ' Alle 1Wire-Devices ansprechen
1wwrite &H44 ' Temperaturmessung starten
Return



' ================================================
' ===== Sub fuer DS18S20 Temperatur einlesen =====
' ================================================
Ds18s20_temp:
1wreset ' 1Wire-Bus zuruecksetzen
1wwrite &HCC ' Alle 1Wire-Devices ansprechen
1wwrite &HBE ' Scratchpad einlesen

Ds18s20(1) = 1wread(9) ' diese Version spart etwas Flash (85% zu 87%)
' For Ds_count = 1 To 9
' Ds18s20(ds_count) = 1wread() ' Scratchpad in Array uebertragen
' Next

If Ds18s20(9) = Crc8(ds18s20(1) , 8) Then ' Wenn CRC8 korrekt dann Temperaturwerte sichern
Deg_lo = Ds18s20(1) ' Temperatur LSB
Deg_hi = Ds18s20(2) ' Temperatur MSB
End If

Return



' ================================================
' ===== ISR fuer Timer0 Overflow =================
' ================================================
' Timer0 ist das Gate fuer die Frequenzmessung
Tim0_isr:
Timer0 = 178 ' Initialisierung fuer 1ms Takt (Prescaler 256)
Incr Ticks ' 1ms-Ticks zaehlen
If Ticks = 1 Then ' beim ersten Tick ...
Timer1 = 0 ' Timer1 fuer Taktzaehlung initialisieren
T1ovf = 0 ' und Timer1-Ueberlaufszaehler auf 0
End If
If Ticks = 1001 Then ' 1sec Messzeit ist vorbei -> Werte sichern
Cnt_lo = Tcnt1l ' Frequenz LSB (Byte 1) - Timer1 LowByte
Cnt_md = Tcnt1h ' Frequenz (Byte 2) - Timer1 HighByte
Cnt_hi = T1ovf ' Frequenz MSB (Byte 3) - Timer1-Ueberlaufszaehler
Disable Interrupts
End If
Return



' ================================================
' ===== ISR fuer Timer1 Overflow =================
' ================================================
' Timer1 ist der Zaehler fuer die Frequenzmessung
Tim1_isr:
Incr T1ovf ' 16Bit-Ueberlauf (Byte3) bearbeiten
Return



' ###############################################
' ##### Programm Ende ###########################
' ###############################################
' Close #1
End

Wenn man bei der 1Wire-Config den richtigen Pin angibt dann klappts auch
mit dem DS18S20 :D Man sollte nicht so viel Copy-n-Paste machen :rolleyes:

Ich hab noch ein paar Kommentare eingebaut um es etwas verständlicher zu machen. Ich liege jetzt bei 71% Flash-Verbrauch. Ohne die LCD-Teile bin ich
bei 49%.

Gruß
Dino
 
Ich bin im Moment echt mit dem Gedanken am spielen, einige Bibliotheken
direkt in Assembler selber umzusetzen. Dafür fehlt aber im Moment die Zeit
weil die Zisternenüberwachung Anfang Frühling ... wenn die Zisterne wegen
Reinigung geöffnet wird ... fertig sein sollte.
Die 1Wire-Algorithmen habe ich in Assembler hier liegen (selbst gemacht)
für Mega8/16/32 und Mega168. Die laufen und müßten nur mit Bascom
gekoppelt werden (Werteübergabe). Die sind echt kurz.
Die Bascom Routinen sind natürlich so geschrieben, dass sie alle Fälle abdecken. Wenn du also nicht so universell verwendbare umsetzt, kannst du bestimmt noch das eine oder andere Byte sparen. Aber macht das wirklich Sinn, wenn du die Routinen selber für verschiedene Anwendungen nutzen willst? Und besonders, wenn du sie hier anderen zur Verfügung stellen willst?
Bei den 1wire Routinen sehe ich das größte Problem darin, dass Bascom beim ersten 1wire Befehl sofort alle Routinen mit kompiliert.
Schreib mal nur 1wreset in dein Programm, schon geht der Flash um 250Byte hoch. Jeder weitere 1wire Befehl wie 1wwrite oder 1wread erhöht den Flash praktisch nur noch um den Aufruf.
Noch schlimmer wird es, wenn du den ersten Befehl wie 1wverify dazu tust. 410 Byte mehr. Wenn man also am Speicherplatz sparen will, darf man solche Konstrukte gar nicht verwenden. Es geht ja auch mit den "normalen" 1wire Befehlen.
Bei LCD genau das gleiche Spiel. Ein simples CLS erhöht den Flash um 230 Byte, viele weitere Befehle nur um den Aufruf.
Daher sehe ich die größte Einsparmöglichkeit, wenn du Routinen nur dann mit reinkompilierst, wenn sie wirklich benötigt werden. Das kannst du bei eigenen Libs natürlich besser bestimmen.

HBA
 
Oh Mann, SMD auf 3-Punkt Raster. Du bist wirklich verrückt.
Allerdings sehen meine Platinen auf der Rückseite meist auch so aus, weil ich keine "richtigen" Platinen machen kann. Und machen lassen ist mir zu teuer.

HBA
 
Hi,

mal zwischendurch ne kurze Info ...
beim längeren Probelauf hat sich das Proggi gerne mal aufgehängt. Also hab
ich ein wenig mit den Speicherbereichen gespielt ...
' ####################################################
' ##### Basisroutinen für das Tiny2313-EvalBoard #####
' ####################################################
' (c) 27.06.2010 by Dino
'
' Frequenzmessung und Temperaturmessung fuer
' Zisternenanzeige (Fuellstand und Innentemperatur)

' Prozessor ATtiny2313
$regfile = "ATtiny2313.DAT"
$crystal = 20000000

$hwstack = 44
$swstack = 40
$framesize = 20
$noramclear
So läuft es im Moment seit mehreren Stunden.
Scheint im SRAM auch recht gedrängt zuzugehen ;)

Oh Mann, SMD auf 3-Punkt Raster. Du bist wirklich verrückt.
:D :rolleyes: tja ... irgendeine Macke hat jeder ;)

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)