View previous topic :: View next topic |
Author |
Message |
olhexy
Joined: 03 Apr 2011 Posts: 192 Location: Tilburg, Netherlands
|
Posted: Fri Feb 19, 2016 1:33 pm Post subject: Make Log table Problem. Promotion FP to Word? Config Base? |
|
|
This program calculates 1024 (0 to 1023) elements array for Adc voltage readings to be represented on a log scale.
There is a tricky part for Log(0) that it is infintely negative.
But as I use Dword and Word Log(0) is promoted to =0. That is what I want.
During calculation it works. First results (for 0, 1, 2, 3, 4) are shown for 5 seconds.
But when I want to use the calculated values (see last 6 lines at End) the first element shows value 7090.
Well Log(0)= not 7090! It is the value for my Log(1023)=7090.
Why, why , WHY???????
I checked if it could be misunderstanding of Config Base =0, but compiler does not accept element 1024 and does accept 0, so that seems OK.
The promotion of the negative Log(0) to =0 is done but brobably not fully accepted, because later the result gets an other value: =7090.
(I am using STK200+M1284+CharLCD+Serial)
Code: | $hwstack = 180
$swstack = 180
$framesize = 180
$crystal = 17100000 'Std 4Mhz ext.clock, but with internal OSCCAL=255=~17,1Mhz
$baud = 9600
Config Printbin = Extended
Config Clockdiv = 1 'in stead of default CLKDIV=8
Osccal = 255 'is max:~17.1Mhz. Factory default &H58 (decimal 8Cool~8MHz
Config Base = 0 'Non standard! But adviced for new projects.
Rem STK200geel conflict MOSI/SCK... met LCD op PortB;
'By specifying Wr the library lcd4busy_anypin (based on LUCIANO) will be used
Config Lcdpin = Pin , Db4 = Portc.4 , Db5 = Portc.5 , Db6 = Portc.6 , Db7 = Portc.7 , E = Portc.2 , Rs = Portc.0 , Wr = Portc.1
'Config Portc.1 = Output : Portc.1 = 0 'Wr to GND if not used
Config Lcd = 16x2 'Bascom does Initlcd to 4bit interface, but no Cls
Config Portc.3 = Output 'C.3 is for Lcdled initially =0
Lcdled Alias Portc.3 'at start led=OFF (transistor base=0)
Cls : Lcdled = 1 : Wait 2 : Lcd "LogTableProblem" : Wait 2 : Cls 'Lcdled =1 =ON
Generate_logarithmic_table:
Dim Adc_hl As Word 'Voltage reading ADC is in registers ADCH and ADCL
Dim Adc_log(1024) As Word 'Table Elements 0..1023 for Logarithm of Voltage
Dim Dwd As Dword '***For in between step in conversion Fpvalue
Dim Fpvalue As Double 'General high accuracy Floating Point Value (8bytes)
Dim Scaler As Double
'To make sure 1 digit difference in adc reading results in exact 1 digit difference log(adc) at full scale.
'Use differentating formula: d_ln(adc)/d_adc = 1/adc = 1/1024 = Scaler
Scaler = 1024 '1024*ln(1024)= 7097.727; rounded 7098
'1023*ln(1023)= 7089,896; rounded 7090
Fpvalue = Log(1023) 'Calculate adjusted scaler so that rounded=exact 7090 for ln(1023)
Scaler = 7090 / Fpvalue
Calc:
Lcd "Scaler" : Lowerline : Lcd Scaler : Wait 1 : Cls
For Adc_hl = 0 To 1023 Step 1 '0 is special case. Log(0)=negative infinity), but will be shown as =0.
Cls
Fpvalue = Adc_hl
Fpvalue = Log(fpvalue)
Fpvalue = Scaler * Fpvalue
Fpvalue = Round(fpvalue) 'Fpvalue's significant part fits now in 2 bytes.
'Lcd Fpvalue 'At end loop display upperline shows: 8.191E3
'***Conversion of Fpvalue is 2 step proces: 8bytes > 4bytes > 2 bytes:
Dwd = Fpvalue '1. Convert significant part of Fpvalue(8byte) to Dword(4byte)
Rem : Dwd Can Not Be Negative. Dwd = 0 if Adc_hl < 1 Causes Log(adc_hl) < 0
Adc_log = Dwd '2. Convert Dwd, a Dword(4byte), to Word(2byte)
Adc_log(adc_hl) = Adc_log
Lcd Adc_hl ; " Adc_log=" ; Adc_log 'At end loop display upperline shows: "1023 Adc_log=709"0 (last chr not visible)
Lowerline : Lcd "A(Adc_hl)=" ; Adc_log(adc_hl) 'At end loop display lowerline shows: "A(Adc_hl)=7090"_
'First 2 array elements will be =0 !!! Log(0)= negative, but as Word promoted to =0, and Log(1)=0
If Adc_hl < 5 Then '5 sec watch time for first 5 results
Wait 5
Else
Waitms 50
End If
Next Adc_hl
Wait 10
'The calculations are done. But The first element !=0 but 7090. It was calculated and shown as =0
Adc_hl = 0 'Max 1023; 1024: index out of range
Cls : Lcd "Adc_hl=" ; Adc_hl : Wait 10
Cls : Lcd "Adc_log(0)=" ; Adc_log(0) 'Adc_log(0)=7090....?
Lowerline : Lcd "A(Adc_hl)=" ; Adc_log(adc_hl)
End |
(BASCOM-AVR version : 2.0.7.9 , Latest : 2.0.7.8 ) |
|
Back to top |
|
|
Plons
Joined: 24 May 2005 Posts: 435 Location: Hilversum - The Netherlands
|
Posted: Fri Feb 19, 2016 4:40 pm Post subject: |
|
|
Page 38 of the datasheet:
Quote: | Note that this oscillator is used to time EEPROM and Flash write accesses, and these write
times will be affected accordingly. If the EEPROM or Flash are written, do not calibrate to more
than 8.8 MHz. Otherwise, the EEPROM or Flash write may fail. |
Log(0) is tricky, as you mention. Instead of allowing calculation of this, with possible wrong results, I'd rather use something like:
Code: | B = 0
...
if B = 0 then
A = - 3.4 x 10^38 (or - 1.7 x 10^308 for Doubles)
else
A = log(B)
end if |
Now, the problem you're facing with the array, element 0, I am puzzled as well. No solution for that, sorry. I suggest you send a report to Support. _________________ Bascom AVR ver 2.0.8.6
Dragon-lair: http://www.aplomb.nl/TechStuff/Dragon/Dragon.html
"leef met vlag en wimpel, maar hou het simpel" |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Fri Feb 19, 2016 8:06 pm Post subject: |
|
|
Plons wrote: | I suggest you send a report to Support. |
If support would need to correct every user-nonsense, they'd have to move to an open space office.
olhexy wrote: | Why, why , WHY??????? |
Because:
Code: | Adc_log = Dwd
Adc_log(adc_hl) = Adc_log |
|
|
Back to top |
|
|
Plons
Joined: 24 May 2005 Posts: 435 Location: Hilversum - The Netherlands
|
Posted: Fri Feb 19, 2016 8:32 pm Post subject: |
|
|
My goodness.
If every member would reply the way you do, MWS, it would be a nasty space here. Despite your sharp eye. _________________ Bascom AVR ver 2.0.8.6
Dragon-lair: http://www.aplomb.nl/TechStuff/Dragon/Dragon.html
"leef met vlag en wimpel, maar hou het simpel" |
|
Back to top |
|
|
olhexy
Joined: 03 Apr 2011 Posts: 192 Location: Tilburg, Netherlands
|
Posted: Fri Feb 19, 2016 8:52 pm Post subject: |
|
|
MWS wrote: |
olhexy wrote: | Why, why , WHY??????? |
Because:
Code: | Adc_log = Dwd
Adc_log(adc_hl) = Adc_log |
|
I do not understand what you mean. I mean Adc_log could also be called 'Adclog' or something. I think it is not defined or to be interpeted as an element of the array Adc_log(). Do you mean that I think this wrongly?
The conversion of Double to Dword and Word is discussed here: http://www.mcselec.com/index2.php?option=com_forum&Itemid=59&page=viewtopic&t=13195&highlight=
And that works. I have run many varieties that show that correctly on Lcd.
The problem is that the element (0) is =0 before 'Wait 10' section
and thereafter that same element (0) is =7090
Last edited by olhexy on Fri Feb 19, 2016 9:16 pm; edited 1 time in total |
|
Back to top |
|
|
laborratte
Joined: 27 Jul 2005 Posts: 299 Location: Berlin
|
Posted: Fri Feb 19, 2016 9:11 pm Post subject: |
|
|
mmmh, before MWS is banging his head too much against the desk I will give you a hint:
Code: | Adc_log = Dwd
Adc_log(adc_hl) = Adc_log
|
is the same as
Code: | Adc_log(0) = Dwd
Adc_log(adc_hl) = Adc_log(0)
|
The interesting part is, that the first code will not compiled in Version 2.0.7.6. There must be changes because of multidim arrays... |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Fri Feb 19, 2016 9:13 pm Post subject: |
|
|
Plons wrote: | My goodness.
If every member would reply the way you do, MWS, it would be a nasty space here. Despite your sharp eye. |
Don't mind, I get no feeling of coziness from your replies either. LOL
I can reassure you, in this case it was not my sharp eye, it was Bascom's simulator, which I've used on a bit cleaned up code and by checking the memory window the culprit was soon found.
This humbug using the same variable also as a temporary and non-indexed actually escaped me at first.
But - I did something, I did a simulation, and so you could have done too.
Instead you've suggested to write to support, which likely has better to do than checking buggy user code.
Was that clever? No.
Did you give this not so clever advice in a friendly manner? Sure you did.
Well, my posts do not always burst out of pure kindness, but I do my job. ;D
You don't have to like my attitude however, and I couldn't care less whether you like it. |
|
Back to top |
|
|
olhexy
Joined: 03 Apr 2011 Posts: 192 Location: Tilburg, Netherlands
|
Posted: Fri Feb 19, 2016 9:23 pm Post subject: |
|
|
laborratte wrote: | mmmh, before MWS is banging his head too much against the desk I will give you a hint:
Code: | Adc_log = Dwd
Adc_log(adc_hl) = Adc_log
|
is the same as
Code: | Adc_log(0) = Dwd
Adc_log(adc_hl) = Adc_log(0)
|
The interesting part is, that the first code will not compiled in Version 2.0.7.6. There must be changes because of multidim arrays... |
Thanks for you explanation. Apparently I did think wrongly that Adc_log is not an element of the array Adc_log().
In stead of Code: | Adc_log = Dwd '2. Convert Dwd, a Dword(4byte), to Word(2byte)
Adc_log(adc_hl) = Adc_log | I think I could leave out Adc_log and do it directly: Code: | Adc_log(adc_hl) = Dwd '2. Convert Dwd, a Dword(4byte), to Word(2byte)
|
Last edited by olhexy on Fri Feb 19, 2016 9:41 pm; edited 1 time in total |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Fri Feb 19, 2016 9:41 pm Post subject: |
|
|
olhexy wrote: | Apparently I did think wrongly that Adc_log is not an element of the array Adc_log(). |
If you've assumed it not to be an array element, you had to assume it a discrete and independent variable.
If it would have been discrete, where did you dimension it?
As for an undimensioned variable, the compiler would rise an error. |
|
Back to top |
|
|
olhexy
Joined: 03 Apr 2011 Posts: 192 Location: Tilburg, Netherlands
|
Posted: Fri Feb 19, 2016 9:45 pm Post subject: |
|
|
[quote="MWS"] olhexy wrote: |
If it would have been discrete, where did ou dimension it?
|
You are correct about that. I already noticed that I did not dim Adc_log as a stand alone.
If I had seen that before I wrote this topic I could have concluded that it would be interpreted as an array element of Adc_log(), because the compiler did not warn.
Thank you (and all others) for your help!
Last edited by olhexy on Fri Feb 19, 2016 9:59 pm; edited 1 time in total |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Fri Feb 19, 2016 9:55 pm Post subject: |
|
|
olhexy wrote: | .. because the compiler did not warn. |
Yes, this is now something, where support is the right addressee, imho the compiler should rise an error, if an indexed variable is used without index. |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|