PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Per A/D Konverter Spannung anzeigen lassen.



Murus
18.09.2005, 12:47
Hallo zusammen.
Ich habe einen Mega8 und als Spannungsreferenz nehme ich AVCC (5V)

Ich schaffe es, den Wert des ADCs von einem ADC-Port auf einem LCD darstellen zu lassen, z.B. 1024 oder 485 etc.
Diese Werte möchte ich nun in eine Spannung umrechnen. Doch ich habe ein Problem... Wie stelle ich Nachkommastellen dar??

Ich habs bis jetzt so gemacht:
1024 geteilt durch den Wert des Konverters (hier jetzt mal 512) macht 2.
Dann teile ich 5 durch 2, macht 2.5.

Diese 2.5V möchte ich auf dem LCD haben... Nur: Er kriegt nur ganze Zahlen hin...
Wie muss ich das lösen?

Herzliche Grüsse
Mario

Murus
18.09.2005, 14:13
Hmm, ich kriegs hin, dass er mir mV ausgibt... Bei ADC von 512 schreibt er 2500mV....
Wie krieg ich das jetzt als Volt hin?
Kann man diese Zahl mit einem Befehl zerlegen?

Greets
Mario

patti16
18.09.2005, 14:17
hi

genau da bin ich auch dran.

In welcher Sprache schreibst du deine Programme und kannste das vielleicht mal online stellen, möchte das mal vergleichen.



gruß
patrick

Murus
18.09.2005, 14:27
Ich écris in Bascom.

Hier mal le code:

$regfile= "m8def.dat"
$crystal=1000000

DDRC.1=0 ' Ich verwende den AD Port 1. Also: Eingang.

Config Adc=Single, Prescaler=Auto, Reference=Avcc ' Adc einstellen

Config Lcd=20*2
Config Lcdpin=pin, E= Portb etc. etc. ' LCD einstellen

Start adc ' Adc anwerfen
Dim W as Long

Do
cls ' Display leeren
W= Getadc(1) ' den Wert vom Port 1 holen
Locate 2,1
lcd W 'Zur Kontrolle mal diesen Wert aufm LCD zeigen.

W=5000*W
W=W/1024

locate 1, 1
Lcd W

Loop
End

So krieg ich 2500 aufm LCD... Jetzt bräuchte man noch ein Komma dazwischen und es wäre perfekt. Wie macht man das?


Greets Mario

Marco78
18.09.2005, 14:29
In welcher Sprache schreibst du deine Programme

AVR Basic-Programmierung mit Bascom
Vielleicht in Pascal?

Ich habe euch mit der Suche mal ein paar Links herrausgesucht.
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=3639&highlight=komma
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=12058&highlight=komma
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=7846&highlight=komma
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=7744&highlight=komma
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=6789&highlight=komma
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=5338&highlight=komma
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=5836&highlight=komma

Marco78
18.09.2005, 14:34
W=5000*W

Lcd W

So krieg ich 2500 aufm LCD...
W ist als Word eingestellt. Word geht nur bis 1024. Somit sind die 2500 nur ein Anzeigefehler!
Wenn 1000 auf's Display geschrieben wird, und danach 250, steht auf dem LCD 2500, weil die letzte 0 von 1000 ja nicht gelöscht wurde. Es wurde nur die 100 von der 1000 mit 250 überschrieben.
Bevor ein neuer Wert geschrieben wird, sollte die Anzeige an der Stelle gelöscht werden. Oder der Wert so formatieren, das er immer die gleichen Stellen belegt. lso so das 250 als 0250 angezeigt wird.

5000*W in einem Word erzeugt nur einen Überlauf und damit ein falsches Ergebnis.

Murus
18.09.2005, 14:37
Ja, hab ich schon korrigiert, es muss ein Long sein...

Wie kann ich das LCD an einer bestimmten stelle löschen??
locate y, x
cls??

Damit man mit Kommas rechnen kann, muss man als single oder double deklarieren... Bis wohin gehen diese Dinger? (Wieviel Bit bringen sie?)
Kann man das nicht eleganter über die Ausgabe lösen, so, dass z.B. die zweite Stelle ein Komma hat oder so?
Nur: wie zerlegt man die Zahlen??

Marco78
18.09.2005, 14:40
Ja, hab ich schon korrigiert, es muss ein Long sein...
Und jetzt klappt es mit dem Komma???


Wie kann ich das LCD an einer bestimmten stelle löschen??
locate y, x
cls??
Nein, CLS löscht das ganze Display.
Locate y,x
LCD " "
So wäre es einfacher. Zumindest wenn der Rest auf dem LCD stehen bleiben soll.

Murus
18.09.2005, 14:48
Ne, das mit dem Komma klappt doch auch net, wenn es ein Long ist....
Man müsst eben single nehmen.
Ich möchte es aber irgendwie mit einer Ausgaberoutine machen..

Marco78
18.09.2005, 14:48
Ganz zufällig habe ich noch einen anderen Beitrag gefunden, wo das gleiche Problem behandelt wird.
http://www.mikrocontroller.net/forum/read-1-235038.html#235072

PicNick
18.09.2005, 14:52
Eine single reicht von
1.5 x 10^–45 bis 3.4 x 10^38
Das sollte reichen.
Darstellen kann man das mit fusing

dim einstring as String * 12
dim einsingle as single
einsingle = deine-Zahl
einstring = fusing(einsingle, "#.##") ' für zwei dezimalstellen
lcd einstring

(type "Help" for help)

Marco78
18.09.2005, 16:23
Autor: Mario Mauerer - Email gelöscht
Datum: 18.09.2005 15:48

--------------------------------------------------------------------------------

Ok, das mit dem Modulo hat geklappt!!!
A=2500 mod 1000
für den Rest.

Nur: Sobald die Zahl vor dem Komma zweistellig wird, verschiebt er das
Komma nicht... Man sieht nur die erste Stelle der Zahl... Kann man das
durch Kommaverschieben lösen, oder soll man mehr Platz einräumen?

Herzlichen Gruss
Mario
Die Lösung steht hier doch schon!
Zwei Stellen vor den Komma kannst du sowieso nur haben, wenn du am Eingang einen Spannungsteiler hast. Die maximale Spannung die du messen kannst ist 5V.
Von daher hat PickNick dir schon den richtigen Code gegeben. Du kannst Fusing ja auf ##.## erweitern.
Schon alleine weil der Code damit kleiner und schneller wird als mit er aufwendigen MOD-Funktion!

patti16
18.09.2005, 16:57
hallo

verstehe nicht genau was ihr meint, könntet ihr mir bitte mal ein gutes beispiel geben mit dem komma??


gruß
patrick

Marco78
18.09.2005, 17:02
Ich habe euch mit der Suche mal ein paar Links herrausgesucht.
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=3639&highlight=komma
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=12058&highlight=komma
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=7846&highlight=komma
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=7744&highlight=komma
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=6789&highlight=komma
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=5338&highlight=komma
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=5836&highlight=komma
Da sind viele Beispiele.

Aber bitte:
Du musst Single nehmen. Alles andere kennt kein Komma.
Der ADC liefert 1024 Schritte bis 5V
Das per Dreisatz umrechnen und am besten so formartieren wie PickNick es schon beschrieben hat.

Wie sieht denn dein Code aus? Anhand deines Codes könnte man dich verbessern.

patti16
18.09.2005, 17:07
ok

hier der code:


' ------------- Hier die üblichen RN-Control Anweisungen --------------
$regfile = "m8def.dat"
$hwstack = 32
$framesize = 16
$crystal = 16000000 'Quarzfrequenz
$baud = 9600

' ------------- Ende der üblichen RN-Control Anweisungen --------------




Config Portc = &B11111111
Config Portb = &B11111111
Config Adc = Single , Prescaler = Auto , Reference = Avcc ' Adc einstellen
Config Scl = Portc.5 'Ports fuer IIC-Bus
Config Sda = Portc.4
Const Rnkeylcd_slaveid_write = &H40 'I2C SlaveAdresse
Const Rnkeylcd_slaveid_read = &H41

Dim Stemp As String * 100
Dim Taste As Word
Dim A As Word
Dim B As Word
Dim C As Word
Dim W As Long

Declare Sub Rnlcd_cursor(byval Spalte As Byte , Byval Zeile As Byte)
Declare Sub Rnlcd_clr()
Declare Sub Rnlcd(byval Text As String)
Declare Sub Rnlcd_cr()
Declare Function Rnlcd_getscan() As Word
Declare Sub Rnlcd_scanmodus(byval Ein As Byte) 'Tastenscanmodus ein und ausschalten

'Hauptprogramm


I2cinit 'Warte bis LCD bereit

Rnlcd_clr 'Scanmodus ein

Rnlcd_cursor 4 , 1
Rnlcd "Willkommen"
Rnlcd_scanmodus 1

Start Adc


Do

Rnlcd_clr
Rnlcd_cursor 1 , 1
Rnlcd "Spg1:"

W = Getadc(3)


W = 5000 * W
W = W / 10246
Rnlcd_cursor 10 , 1
Stemp = "" + Str(w)
Rnlcd Stemp
Rnlcd_cr


If W < 32 Then
Rnlcd_cursor 10 , 1
Rnlcd "zu niedrig"
End If

Waitms 60
Loop

End


'--------------------------------------------------------------
'Einige spezielle I2C.Befehle für RN-KeyLCD als Funktion definiert:

Sub Rnlcd_cursor(byval Spalte As Byte , Byval Zeile As Byte) 'Cursor setzen
Local Befehle As String * 4
Befehle = Chr(27) + Chr(79) + Chr(spalte) + Chr(zeile)
I2csend Rnkeylcd_slaveid_write , Befehle , 4
End Sub

Sub Rnlcd_clr() 'LCD löschen
Local Befehle As String * 2
Befehle = Chr(12)
I2csend Rnkeylcd_slaveid_write , Befehle , 1
End Sub

Sub Rnlcd_cr() 'LCD Zeilenvorschub
Local Befehle As String * 2
Befehle = Chr(13) + Chr(10)
I2csend Rnkeylcd_slaveid_write , Befehle , 2
End Sub

Sub Rnlcd(byval Text As String) 'Eine Art Print Befehl zum Ausgeben von Text
Local Le As Word
Le = Len(text)
I2csend Rnkeylcd_slaveid_write , Text , Le
End Sub

Function Rnlcd_getscan() As Word 'Scancode als Word abfragen
Local Lscan As Byte
Local Hscan As Byte


I2cstart
I2cwbyte Rnkeylcd_slaveid_read
I2crbyte Lscan , Ack
I2crbyte Hscan , Nack
I2cstop

If Hscan.7 = 1 Then 'AScii Modus
Rnlcd_getscan = Lscan
Else
Rnlcd_getscan = Hscan * 256
Rnlcd_getscan = Rnlcd_getscan + Lscan
End If
End Function

Sub Rnlcd_scanmodus(byval Ein As Byte) 'Tastenscanmodus ein und ausschalten
Local Befehle As String * 3
Befehle = Chr(27) + Chr(119) + Chr(ein)
I2csend Rnkeylcd_slaveid_write , Befehle , 3
End Sub


erstmal so denn ich habe eigentlich drei batterie blöcke.

gruß
patrick

patti16
18.09.2005, 18:01
hallo

hier habe ich noch mal was probiert.

hier der code:



' ------------- Hier die üblichen RN-Control Anweisungen --------------
$regfile = "m8def.dat"
$hwstack = 32
$framesize = 16
$crystal = 16000000 'Quarzfrequenz
$baud = 9600

' ------------- Ende der üblichen RN-Control Anweisungen --------------




Config Portc = &B11111111
Config Portb = &B11111111
Config Adc = Single , Prescaler = Auto , Reference = Avcc ' Adc einstellen
Config Scl = Portc.5 'Ports fuer IIC-Bus
Config Sda = Portc.4
Const Rnkeylcd_slaveid_write = &H40 'I2C SlaveAdresse
Const Rnkeylcd_slaveid_read = &H41

Dim Stemp As String * 100
Dim Taste As Word
Dim A As Long
Dim B As Long
Dim C As Long
Dim S As Single

Declare Sub Rnlcd_cursor(byval Spalte As Byte , Byval Zeile As Byte)
Declare Sub Rnlcd_clr()
Declare Sub Rnlcd(byval Text As String)
Declare Sub Rnlcd_cr()
Declare Function Rnlcd_getscan() As Word
Declare Sub Rnlcd_scanmodus(byval Ein As Byte) 'Tastenscanmodus ein und ausschalten

'Hauptprogramm


I2cinit 'Warte bis LCD bereit

Rnlcd_clr 'Scanmodus ein

Rnlcd_cursor 4 , 1
Rnlcd "Willkommen"
Rnlcd_scanmodus 1

Start Adc


Do

Rnlcd_clr
Rnlcd_cursor 1 , 1
Rnlcd "Spg1:"

A = Getadc(1)


Print Fusing(s , "#.##")
A = 5000 * A
A = A / 1024
Rnlcd_cursor 10 , 1
Stemp = "" + Str(a)
Rnlcd Stemp
Rnlcd_cr




Waitms 60
Loop

End


'--------------------------------------------------------------
'Einige spezielle I2C.Befehle für RN-KeyLCD als Funktion definiert:

Sub Rnlcd_cursor(byval Spalte As Byte , Byval Zeile As Byte) 'Cursor setzen
Local Befehle As String * 4
Befehle = Chr(27) + Chr(79) + Chr(spalte) + Chr(zeile)
I2csend Rnkeylcd_slaveid_write , Befehle , 4
End Sub

Sub Rnlcd_clr() 'LCD löschen
Local Befehle As String * 2
Befehle = Chr(12)
I2csend Rnkeylcd_slaveid_write , Befehle , 1
End Sub

Sub Rnlcd_cr() 'LCD Zeilenvorschub
Local Befehle As String * 2
Befehle = Chr(13) + Chr(10)
I2csend Rnkeylcd_slaveid_write , Befehle , 2
End Sub

Sub Rnlcd(byval Text As String) 'Eine Art Print Befehl zum Ausgeben von Text
Local Le As Word
Le = Len(text)
I2csend Rnkeylcd_slaveid_write , Text , Le
End Sub

Function Rnlcd_getscan() As Word 'Scancode als Word abfragen
Local Lscan As Byte
Local Hscan As Byte


I2cstart
I2cwbyte Rnkeylcd_slaveid_read
I2crbyte Lscan , Ack
I2crbyte Hscan , Nack
I2cstop

If Hscan.7 = 1 Then 'AScii Modus
Rnlcd_getscan = Lscan
Else
Rnlcd_getscan = Hscan * 256
Rnlcd_getscan = Rnlcd_getscan + Lscan
End If
End Function

Sub Rnlcd_scanmodus(byval Ein As Byte) 'Tastenscanmodus ein und ausschalten
Local Befehle As String * 3
Befehle = Chr(27) + Chr(119) + Chr(ein)
I2csend Rnkeylcd_slaveid_write , Befehle , 3
End Sub


könnte das jemand mal bitte probieren müsste mir mal die bascom vollversion kaufen.

danke.

gruß
patrick

Murus
18.09.2005, 18:17
Also das Fusing funktioniert bei mir hinten und vorne nicht... Er rechnet irgendwie trotzem nicht mit Nachkommastellen, aber die Anzeige funktioniert...
Komisch, ich gucks dann später nochmals an.

Zudem bräuchte er 22%Speicher. Der Modulo braucht 14%....

Gruss
Mario

patti16
18.09.2005, 18:29
haste noch mal das von picknick probiert??

Marco78
18.09.2005, 18:30
@patti16,
und was geht nicht?
Zunächst ein Tipp: Je größer der Variablentyp, desto mehr Programmspeicher wird gebraucht. Also immer nur den Typ nehmen, der max. nötig ist.
Du willst Spannungen bis 5V mit dem ADC messen.
Der ADC liefert Werte von 0V bis 5V in 1024 Schritten.
Also erstmal 5V geteilt durch 1024 rechnen. Ergibt: 0,00488. Das wieder mal 1024 ergibt 4,99712. Ich denke den Fehler kann man verzeihen.
Jeder Wert des ADC steht also für rund 5mV.
Wenn du mit A den Wert des ADC einliesst und ihn mit 0,00488 multiplizierst, hast du die gemessene Spannung in Volt.
Du kannst das ganze auch in mV ausrechnen lassen und dann durch 100 teilen um auf Volt zu kommen.
Aber im Prinzip ist das nicht weiter als Dreisatz.

Dim A as Word
Dim B as Single
Dim C as Single
B=0,00488
start adc
a=getadc(3)
C=A*B 'die gemessene Spannung in Volt

Config Adc = Single , Prescaler = Auto , Reference = Avcc
Ich würd den ADC anders einstellen:
Config Adc = Free, Prescaler = Auto
Mit Free kannst du etwas schneller messen. Und das Programm macht das ja dauerhaft. Die Reference musst du nicht angeben, wenn es Avcc ist.

patti16
18.09.2005, 18:38
hallo

also das mit der messung klappt auf jeden fall aber das problem ist nun das ich das nicht mir komma in volt angzeigt bekomme

patti16
18.09.2005, 18:44
hi marco

also das was du oben geschrieben hast klappt bei mir leider so nicht nur mit dem code wie ich den oben habe klappt aber halt nur ohne das fusing.

gruß
patrick

patti16
18.09.2005, 18:57
hallo,

jetzt klappt es aber die zahl ist jetzt voll lang.

danke für die hilfe

gruß
patrick

Murus
18.09.2005, 19:18
Ich kriegs hinten und vorne nich gebacken.. Versuche ich es mit Fusing, spinnt das LCd... zeigt einfach nix..
Aber egal! Der Modulo-Code braucht 14%, der Fusing-Code 21%...

Aber vielen Dank für die Hilfe!!!

Gruss
Mario

patti16
18.09.2005, 22:16
ich gebe dir morgen mal meinen code

gruß
patrick

patti16
19.09.2005, 19:01
hier der versprochene code.





' ------------- Hier die üblichen RN-Control Anweisungen --------------
$regfile = "m8def.dat"
$hwstack = 32
$framesize = 16
$crystal = 16000000 'Quarzfrequenz
$baud = 9600

' ------------- Ende der üblichen RN-Control Anweisungen --------------




Config Portc = &B11111111
Config Portb = &B11111111
Config Adc = Single , Prescaler = Auto , Reference = Avcc ' Adc einstellen
Config Scl = Portc.5 'Ports fuer IIC-Bus
Config Sda = Portc.4
Const Rnkeylcd_slaveid_write = &H40 'I2C SlaveAdresse
Const Rnkeylcd_slaveid_read = &H41

Dim Stemp As String * 100
Dim Taste As Word
Dim A As Word
Dim K As Word
Dim L As Word
Dim B As Single
Dim C As Single
Dim E As Single


Declare Sub Rnlcd_cursor(byval Spalte As Byte , Byval Zeile As Byte)
Declare Sub Rnlcd_clr()
Declare Sub Rnlcd(byval Text As String)
Declare Sub Rnlcd_cr()
Declare Function Rnlcd_getscan() As Word
Declare Sub Rnlcd_scanmodus(byval Ein As Byte) 'Tastenscanmodus ein und ausschalten

'Hauptprogramm


I2cinit 'Warte bis LCD bereit

Rnlcd_clr 'Scanmodus ein

Start Adc


Do

Rnlcd_clr
Rnlcd_cursor 1 , 1
Rnlcd "Spg1:"




A = Getadc(1)
B = A * 0.00488
Rnlcd_cursor 1 , 7 'die gemessene Spannung in Volt
Stemp = "" + Str(b)
Rnlcd Stemp
Rnlcd_cr


Waitms 60
Loop

End


'--------------------------------------------------------------
'Einige spezielle I2C.Befehle für RN-KeyLCD als Funktion definiert:

Sub Rnlcd_cursor(byval Spalte As Byte , Byval Zeile As Byte) 'Cursor setzen
Local Befehle As String * 4
Befehle = Chr(27) + Chr(79) + Chr(spalte) + Chr(zeile)
I2csend Rnkeylcd_slaveid_write , Befehle , 4
End Sub

Sub Rnlcd_clr() 'LCD löschen
Local Befehle As String * 2
Befehle = Chr(12)
I2csend Rnkeylcd_slaveid_write , Befehle , 1
End Sub

Sub Rnlcd_cr() 'LCD Zeilenvorschub
Local Befehle As String * 2
Befehle = Chr(13) + Chr(10)
I2csend Rnkeylcd_slaveid_write , Befehle , 2
End Sub

Sub Rnlcd(byval Text As String) 'Eine Art Print Befehl zum Ausgeben von Text
Local Le As Word
Le = Len(text)
I2csend Rnkeylcd_slaveid_write , Text , Le
End Sub

Function Rnlcd_getscan() As Word 'Scancode als Word abfragen
Local Lscan As Byte
Local Hscan As Byte


I2cstart
I2cwbyte Rnkeylcd_slaveid_read
I2crbyte Lscan , Ack
I2crbyte Hscan , Nack
I2cstop

If Hscan.7 = 1 Then 'AScii Modus
Rnlcd_getscan = Lscan
Else
Rnlcd_getscan = Hscan * 256
Rnlcd_getscan = Rnlcd_getscan + Lscan
End If
End Function

Sub Rnlcd_scanmodus(byval Ein As Byte) 'Tastenscanmodus ein und ausschalten
Local Befehle As String * 3
Befehle = Chr(27) + Chr(119) + Chr(ein)
I2csend Rnkeylcd_slaveid_write , Befehle , 3
End Sub


hoffe das du was damit anfangen kannst.

gruß
patrick

Murus
19.09.2005, 19:21
Ok, werds dann mal angucken, vielen Dank!!!
Am LCD hats nen Wackel.. muss den mal suchen und beheben...

Herzliche Grüsse
Mario