PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Error:256 Line (XYZ) Single expected ?!?



M_I_B
30.10.2013, 21:23
Hallo Liebe Leutz,

ich beiße mir gerade an einer Fehlermeldung die Zähne aus... Hier mal die relevanten Teile, damit wir über's Gleiche reden:


...
Config Adc = Single , Prescaler = Auto , Reference = Internal_1.1
...
DIM Strom as Long
...
Const Imax = 1000
Const Umax = Imax * 0.00047
...
Strom = Getadc(5)
Strom = Strom * 0.001075
If Strom > Umax Then
...
...

Der Fehler taucht in der letzten Zeile auf, ich komme nur leider ums Verrecken nicht drauf, wo da der Knackpunkt ist :mad:
Umax wäre ja hier 0,47. Mal angenommen, ich lese aus dem ADC 800 aus, das Ganze mal 0,001075 ergibt 0,86 für die Variable "Strom", womit die Bedingung erfüllt wäre... Ich sehe da nirgendwo ein Problem, BASCOM aber offensichtlich *meggerschimpf*

Wäre nett, wenn mir da mal wer auf die Sprünge helfen könnte, bevor ich mir noch die letzten Haare vom Kopf raufe ^^

HeXPloreR
30.10.2013, 21:35
Es ist manches mal so das Bascom die betreffende Zeile zwar rot markiert, der Fehler aber nicht zwangsläufig in dieser liegen muss.
Von daher ist es manchmal nicht so gut einfach den Code stückchenweise hier abzugeben, nur weil man meint da müsste es mit bei sein.

Ich denke mal der Fehler liegt in Deiner Dimensionierung von "Strom as Long" , darin möchtest Du jetzt einen sehr kleinen Wert speichern. Dieser Wert ist aber nach der multiplikation mit 0,001075 nicht mehr im Wertebereich eines LONG. Du könntest eine zweite Variable anlegen, die "Strom * 0,001075" aufnimmt, diese müsste dann mindestens ein SINGLE (SINGLE EXPECTED) oder DOUBLE sein. http://halvar.at/elektronik/kleiner_bascom_avr_kurs/variablen/

for_ro
30.10.2013, 21:45
Ich denke schon, dass der Fehler in der unterstrichenen Zeile liegt.
Bascom mag keinen Vergleich zwischen einer Long und einer Single, auch nicht gegen eine Single Konstante.
Wenn du umax nur so benutzen möchtest, kannst du dir nur den ganzzahligen Anteil nehmen
Const umax = int(imax * 0.00047)
was allerdings erst bei imax Werten über 2000 wirklich Sinn macht. Ansonsten muss Strom auch eine Single werden.

Edit: Nach dieser Zeile
Strom = Strom * 0.001075
wird Strom immer den Wert 0 haben.
Ich würde bei der Berechnung einfach mit den ADC Werten arbeiten und umax lieber mit 1023 multiplizieren. An der Stelle interessiert dich die absolute Spannung doch noch gar nicht. Erst wenn du sie anzeigen oder sonst wie ausgeben willst, würde ich umrechnen.

HeXPloreR
31.10.2013, 11:52
Und da haben wir schon das erste Problem: Woher wissen wir was mit dem Wert gemacht werden soll und was nicht? Er gab uns nur Codeauszüge.
Zufällig war die Dimensionierung von Strom jetzt mit dabei.

Vorallem mag Bascom es nicht wenn man eine Fliesskommazahl in einen Datentyp speichern möchte der nur Ganzzahlen aufnehmen kann.

Probier es mal aus Strom as Single zu machen, eine zweite Variable benötigst Du, wie ich oben ja anders schrieb, wohl nicht.

M_I_B
31.10.2013, 16:30
... jo ... erstmal Dank für Eure Hinweise. Ich habe es jetzt "irgendwie" gelöst bekommen, schaut aber ganz schön gruselig aus ^^
Sinn der Sache:
Über einen Shunt von 0,47Ohm gegen Masse wird die Stromaufnahme eines Motors gemessen. Der Spannungsabfall wird via 3k3 an den Pin und mit 100n Pin gegen Masse gegen all zu schnelle Spitzen geblockt.
Als Konstante gebe ich den Maximalwert in mA vor.
Abgefragt wird via Timer0 etwa alle 100ms in der dazu gehörenden ISR. Wenn der Strom (resp. die Spannung an Pin5) den vorgegebenen Wert übersteigt, wird eine BitVar (Iover) gesetzt und der EN des Motorcontrollers abgeschaltet. So lange das Bit gesetzt ist, wird eine ByteVar bei jedem Aufruf der ISR um eins hochgezählt und bei 100 das Flag wieder gelöscht.

Eigentlich wäre es schöner, wenn man irgendwie dafür sorgen könnte, das bei Erreichen/Überschreiten eines Vorgabewertes der DAC selbst einen IRQ auslöst ohne das man aktiv in Intervallen den DAC abfragen muß. Aber dazu habe ich in BASCOM keine Möglichkeit finden können.

Ok, wie gesagt tut es nun (VarTypen angepasst), aber natürlich hätte ich nichts dagegen, wenn von Euch noch ein paar andere Lösungen kommen, damit ich vielleicht eine andere Denkweise bei solchen Sachen erlernen kann...


DlzG
Micha

for_ro
31.10.2013, 18:25
Vorallem mag Bascom es nicht wenn man eine Fliesskommazahl in einen Datentyp speichern möchte der nur Ganzzahlen aufnehmen kann.
Doch HeXPloreR, genau dieses "Casten" mag Bascom, nur nicht Ganzzahl und Fließkomma vergleichen.

HeXPloreR
31.10.2013, 19:43
ja for_ro, Du hast recht. Bascom macht automatisch einen cast aus 0,00215 wird 0. Man merkt hier sehr gut jetzt ist wieder der Programmierer gefragt darauf zu achten das wenn er 0,XXX Werte mit einem Ganzzahlentyp weiter verarbeitet das möglicherweise etwas abgeschnitten wird und nicht nur, wie in diesem Fall zwei verschieden Datentypen der Vergleich nicht klappt, sondern das der Vergleich auch nicht korrekt sein könnte nach einem solchen cast, wenn es auch um die Dezimalstellen geht.

Peter(TOO)
31.10.2013, 20:45
Hallo Micha,


Ok, wie gesagt tut es nun (VarTypen angepasst), aber natürlich hätte ich nichts dagegen, wenn von Euch noch ein paar andere Lösungen kommen, damit ich vielleicht eine andere Denkweise bei solchen Sachen erlernen kann...


Prozessoren ohne FPU müssen Fliesskommaberechnung über eine Bibliothek erledigen. Diese braucht einiges an Platz im ROM und ist etwa 100x langsamer als eine FPU.

Es macht also in vielen Fällen Sinn, Fliesskommaoperationen zu vermeiden.

Es kann also Sinn machen, wenn du alles in mV und mA rechnest, dann kommst du mit Integern durch.

Und anstatt
x *0.47
zu rechnen, was eben nur mit Fliesskomma geht, kann man auch
(x * 100) / 47
rechnen, was mit Integern geht (Allerdings muss man aufpassen, dass (x *100) in jedem Fall noch in den gewählten Integer passt. Obwohl du eine Multiplikation und eine Division machen musst, ist das oft als Integerrechnung schneller als eine einzelne Fliesskomma-Multiplikation.

Bei der Ausgabe muss man dann den Dezimalpunkt an der richtigen Stelle einsetzen, aber das geht rein über Textmanipulation.

Ich kann mich nicht erinnern, dass ich in den letzten 30 Jahren auf einem Microcontroller einmal Fliesskommaoperationen gebraucht habe. Selbst bei der Linearisierung eines NTC lässt sich so umformen, dass man mit Integern zurecht kommt. Im professionellen Bereich bedeuten mehr ROM und mehr Rechenleistung immer auch höhere Kosten, welche man dann mit den Stückzahlen multiplizieren muss.
Wie schon gesagt, ich habe da dann auch mal mit 1/40tel Grad gerechnet (wegen den Rundungsfehlern, gefordert waren nur 1/10 Grad).

MfG Peter(TOO)

for_ro
01.11.2013, 09:49
Eigentlich wäre es schöner, wenn man irgendwie dafür sorgen könnte, das bei Erreichen/Überschreiten eines Vorgabewertes der DAC selbst einen IRQ auslöst ohne das man aktiv in Intervallen den DAC abfragen muß. Aber dazu habe ich in BASCOM keine Möglichkeit finden können.

Hallo Micha,
du meinst sicherlich den ADC, nicht den DAC. Das geht in Bascom schon.
Schau dir mal den Analog Comparator an, den du in Bascom über Config ACI konfigurieren kannst.