Excel formula that you can convert: https://exceljet.net/formula/get-nth-day-of-week-in-month
↧
BASCOM-AVR : Calculating date from # of occurance of Sunday in a month? : REPLY
↧
Share your working BASCOM-AVR code here : Sun position and Heliostat offset. : NEWTOPIC
Here is a nice little program for calculating the suns position and also heliostat position.
I translated it from a QBasic program that can be found here.
https://www.instructables.com/community/heliostat-and-sun-tracker-basic-program/
Thanks to David Williams for original QBasic code.
[code:1:50692aec6e]'Thanks to David Williams for sharing the QBasic version of this program.
'The original QBasic code can be found here:
'https://www.instructables.com/community/heliostat-and-sun-tracker-basic-program/
' SunAlign.BAS (Version for QBasic and similar dialects)
' Calculates position of sun in sky, as azimuth (compass bearing
' measured clockwise from True North) and angle of elevation, as
' seen from any place on earth, on any date and any time.
' Also calculates alignment of a heliostat mirror.
' David Williams
' Initially dated 2007 Jul 07
' This version 2008 Jan 13
' All angles in radians except in i/o routines DegIn and DegOut
'Translated to BASCOM by:
'Dave Carr
'July 14, 2019
$regfile = "m328pdef.dat"
$crystal = 8000000
$baud = 38400
$hwstack = 100
$swstack = 100
$framesize = 100
DECLARE SUB C2P(byref X as single, byref Y as single, byref Z as single, byref AZ as single, byref EL as single)
DECLARE SUB P2C(byval AZ as single, byval EL as single, byref X as single ,byref Y as single ,byref Z as single)
DECLARE FUNCTION Ang(byval X as single ,byval Y as single)as single
DECLARE SUB DegIn(byval P as string,byref X as single)
DECLARE SUB DegOut(byval P as string,byref X as single)
CONST c_PY = 3.1415926536 ' "PI" not assignable in some BASICs
CONST c_DR = 180 / c_PY ' degree / radian factor
const c_W = 2 * c_PY / 365 ' earth's mean orbital angular speed in radians/day
const c_WR = c_PY / 12' earth's speed of rotation relative to sun (radians/hour)
const c_C = -23.45 / c_DR ' reverse angle of earth's axial tilt in radians
const c_ST = SIN(c_C) ' sine of reverse tilt
const c_CT = COS(c_C) ' cosine of reverse tilt
const c_E2 = 2 * .0167 ' twice earth's orbital eccentricity
const c_SN = 10 * c_W ' 10 days from December solstice to New Year (Jan 1)
const c_SP = 12 * c_W ' 12 days from December solstice to perihelion
dim s_C as single
dim st_S as string * 1
dim s_Lt as single
dim s_LG as single
dim i_TZN as integer
dim b_HR, b_MIN as byte
dim b_Mth, b_Day as byte
dim s_CL as single
dim w_D as word
dim s_A, s_B, s_L, s_DC, s_LD, s_SL as single
dim s_tAZ, s_tEL, s_tX, s_tY, s_tZ, s_mAZ, s_mEL as single
dim s_sX, s_sY, s_sZ, s_sAZ, s_sEL as single
dim s_temp1, s_temp2, s_temp3 as single
CLS
Menu:
PRINT "1. Calculate sun's position"
PRINT "2. Calculate mirror orientation"
PRINT "3. Calculate both"
PRINT "4. Quit program"
PRINT
PRINT "Which? (1 - 4)";
DO
st_S = INKEY()
LOOP UNTIL st_S >= "1" AND st_S <= "4"
PRINT st_S
IF st_S ="4" THEN END
' Note: For brevity, no error checks on user inputs
PRINT
PRINT "Use negative numbers for directions opposite to those shown."
PRINT
DegIn "Observer's latitude (degrees North)", s_LT
DegIn "Observer's longitude (degrees East)", s_LG
INPUT "Time Zone (+/- hours from GMT/UT)", i_TZN
INPUT "Hours (24-hr format)", b_HR
input "Minutes ", b_MIN
INPUT "Month ", b_Mth
input "Day of month ", b_Day
PRINT
's_CL = c_PY / 2 - s_LT ' co-latitude
s_CL = c_PY / 2
s_CL = s_CL - s_LT
'print "co-lat ";s_CL
'w_D = INT(30.6 * ((b_Mth + 9) MOD 12) + 58.5 + b_Day) MOD 365
' day of year (D = 0 on Jan 1)
s_C = b_Mth + 9
s_C = s_C mod 12
s_C = 30.6 * s_C
s_C = s_C + 58.5
s_C = s_C + b_Day
s_C = int(s_C)
w_D = s_C mod 365
'print "Day of year = ";w_D
's_A = c_W * w_D + c_SN ' orbit angle since solstice at mean speed
s_A = c_W * w_D
s_A = s_A + c_SN
'print "Orbit angle ";s_A
's_B = s_A + c_E2 * SIN(s_A - c_SP) ' angle with correction for eccentricity
s_C = s_A - c_SP
s_B = sin(s_C)
s_B = s_B * c_E2
s_B = s_B + s_A
'print "Eccentricity ";s_B
's_C = (s_A - ATN(TAN(s_B) / c_CT)) / c_PY
s_C = tan(s_B)
s_C = s_C/c_CT
s_C = atn(s_C)
s_C = s_A - s_C
s_C = s_C/c_PY
's_SL = c_PY * (s_C - INT(s_C + .5))' solar longitude relative to mean position
s_SL = s_C + .5
s_SL = int(s_SL)
s_SL = s_C - s_SL
s_SL = c_PY * s_SL
'print "solar longitude ";s_SL
's_C = c_ST * COS(s_B)
s_C = cos(s_B)
s_C = c_ST * s_C
's_DC = ATN(s_C / SQR(1 - s_C * s_C)) ' solar declination (latitude)
' arcsine of C. ASN not directly available in QBasic
s_DC = s_C * s_C
s_DC = 1 - s_DC
s_DC = sqr(s_DC)
s_DC = s_C / s_DC
s_DC = atn(s_DC)
'print "solar declination ";s_DC
's_LD = (b_HR - i_TZN + b_MIN / 60) * c_WR + s_SL + s_LG ' longitude difference
s_LD = b_MIN / 60
s_C = b_HR - i_TZN
s_LD = s_C + s_LD
s_LD = s_LD * c_WR
s_LD = s_LD + s_SL
s_LD = s_LD + s_LG
'print "longitude difference ";s_LD
CALL P2C(s_LD, s_DC, s_sX, s_sY, s_sZ) ' polar axis (perpend'r to azimuth plane)
CALL C2P(s_sY, s_sZ, s_sX, s_sAZ, s_sEL) ' horizontal axis
s_temp1=s_sAZ - s_CL
CALL P2C(s_temp1, s_sEL, s_sY, s_sZ, s_sX) ' rotate by co-latitude
IF s_sZ < 0 THEN
'BEEP
PRINT "Sun Below Horizon"
PRINT
GOTO NewCalc
END IF
IF st_S <> "2" THEN ' calculate and display sun's position
CALL C2P(s_sX, s_sY, s_sZ, s_sAZ, s_sEL) ' vertical axis
DegOut "Sun's azimuth: ", s_sAZ
DegOut "Sun's elevation: ", s_sEL
PRINT
END IF
IF st_S > "1" THEN ' calculate and display mirror orientation
PRINT "For target direction of light reflected from mirror:"
DegIn "Azimuth of target direction (degrees)", s_tAZ
DegIn "Elevation of target direction (degrees)", s_tEL
PRINT
CALL P2C(s_tAZ, s_tEL, s_tX, s_tY, s_tZ) ' target vector X,Y,Z
s_temp1=s_sX + s_tX
s_temp2=s_sY + s_tY
s_temp3=s_sZ + s_tZ
CALL C2P(s_temp1,s_temp2 ,s_temp3 , s_mAZ, s_mEL)
' angle bisection by vector addition
PRINT "Mirror aim direction (perpendicular to surface):"
DegOut "Azimuth: ", s_mAZ
DegOut "Elevation: ", s_mEL
PRINT
END IF
NewCalc:
PRINT
PRINT "New Calculation"
PRINT
GOTO Menu
FUNCTION Ang (byval X as single,byval Y as single)
' calculates angle from positive X axis to vector to (X,Y)
'SELECT CASE SGN(X)
'CASE 1: Ang = ATN(Y / X)
'CASE -1: Ang = ATN(Y / X) + PY
'CASE ELSE: Ang = SGN(Y) * PY / 2
'END SELECT
local s as single
s = sgn(x)
SELECT CASE s
CASE 1
s=y/x
Ang = ATN(s)
CASE -1
s=y/x
s=atn(s)
Ang = s+c_PY
CASE ELSE
s=sgn(y)
s=s*c_PY
Ang = s/2
END SELECT
END FUNCTION
SUB C2P (byref X as single,byref Y as single,byref Z as single,byref AZ as single,byref EL as single)
' Cartesian to Polar. Convert from X,Y,Z to AZ,EL
local A as single
local s as single
local s2 as single
'EL = Ang(SQR(X * X + Y * Y), Z)
s=x*x
s2=y*y
s=s+s2
s=sqr(s)
el=ang(s,z)
'A = Ang(Y, X)
A = Ang(Y, X)
'IF A < c_PY THEN AZ = A + c_PY ELSE AZ = A - c_PY
IF A < c_PY THEN
AZ = A + c_PY
ELSE
AZ = A - c_PY
end if
END SUB
SUB DegIn (byval P as string,byref X as single)
' Input angle in degrees and convert to radians
local N as single
PRINT P;
INPUT N
X = N / c_DR
END SUB
SUB DegOut (byval P as string,byref X as single)
' converts radians to degrees, rounds to nearest 0.1, and prints
local st as string * 20
local s as single
local i as integer
'S$ = LTRIM$(STR$(INT(10 * ABS(X * c_DR) + .5)))
s=X*c_DR
s=abs(s)
s=s*10
s=s + .5
i=int(s)
st=str(i)
st=ltrim(st)
IF St = "3600" THEN St = "0"
IF LEN(St) = 1 THEN St = "0" + St
'IF X < 0 THEN IF VAL(St) THEN St = "-" + St
IF X < 0 THEN
s=val(st)
IF s>0 THEN St = "-" + St
end if
'PRINT P; LEFT(St, LEN(St) - 1); "."; RIGHT$(St, 1); " degrees"
i=len(st)-1
print P;left(st,i);".";right(st,1);" degrees"
END SUB
SUB P2C (byval AZ as single,byval EL as single,byref X as single,byref Y as single,byref Z as single)
' Polar to Cartesian. Convert from AZ,EL to X,Y,Z
local s as single
Z = SIN(EL)
s_C = COS(EL)
s_C=s_C*-1
X = s_C * SIN(AZ)
Y = s_C * COS(AZ)
END SUB[/code:1:50692aec6e]
↧
↧
BASCOM-AVR : Strange behavior ADC7 ATMega328P : NEWTOPIC
When testing the AD channels on a NANO board ATMega328p I am receiving strange values from the AD channel #7 at pin 22 just between the 5V pin and the AD #6. Trying with a potentiometer I receive values ranging from about 18 up to 940 and not from 0 to 1023 as expected extreme sides. It seems also noisy.
All other channels works fine with the same code.
'===================================
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Dim W As Word
Dim Z As String * 10
Do
W = Getadc(7) 'select the ADC channel on getadc(#)
Z = Str(w)
Z = Format(z , "0000")
Z = "AD7=" + Z
Print Z
Loop
'===================================
There are any special configuration to have this channel working properly ?
[b:f90d752281][color=red:f90d752281](BASCOM-AVR version : 2.0.8.1 )[/b:f90d752281][/color:f90d752281]
↧
BASCOM-AVR : absolute value of difference : REPLY
Wie wäre es damit:
[code:1:245504ab9c]
Dim a as Byte
Dim b as Byte
Dim c as Byte
a = 5
b = 3
Do
!LDS r24,{a}
!LDS r25,{b}
[b] !SUB r24,r25
!SBIC SREG,2
!NEG r24
[/b]
!STS {c},r24
print c
Incr b
Loop
[/code:1:245504ab9c]
[/code]
↧
BASCOM-AVR : SPI reading from different address : NEWTOPIC
Hi,
I have this simple example of writing (to &H34) & reading (from &H74) from SPI addresses:
[code:1:3b2a876a04] Spi_array(1) = &H34
Spi_array(2) = 0
Reset Cs
Spiout Spi_array(1) , 2
Set Cs
Spi_array(1) = &H74
Spi_array(2) = 0
Reset Cs
Spiin Spi_array_rx_status(1) , 2
Set Cs[/code:1:3b2a876a04]
It happens that SPIOUT remembers the address where data was sent (Spi_array(1) = &H34) and with SPIIN command it reads data from this address and not from the address that I need to read (Spi_array(1) = &H74).
How to do that?
Best regards
Jure
[b:3b2a876a04][color=red:3b2a876a04](BASCOM-AVR version : 2.0.8.1 )[/b:3b2a876a04][/color:3b2a876a04]
↧
↧
BASCOM-AVR : SPI reading from different address : REPLY
best to use spimove
↧
Share your working BASCOM-AVR code here : Sun position and Heliostat offset. : REPLY
hi Dave
Thanks for sharing.
I wonder if the accuracy would not be better when using double instead of single?
↧
BASCOM-AVR : Strange behavior ADC7 ATMega328P : REPLY
there is no special config.
just make sure you connect to the right pin. and also, check if the input you offer is not too high for the AD converter.
keep wires very short and possible add a small cap to ground on the input pin.
notice that the DIP version of the chip does not have these channels.
↧
Share your working BASCOM-AVR code here : Sun position and Heliostat offset. : REPLY
Hello Mark
[quote:23f4797ab8]I wonder if the accuracy would not be better when using double instead of single?[/quote:23f4797ab8]
I don't think so. After I first got the code working I ran it in the simulator and compared the output to online calculators. The output was off by a few tenths of a degree so I did a quick search and replace of all singles to doubles and the output was still off by about the same amount. I think David Williams took some shortcuts to keep the code small at the cost of accuracy. But for pointing a solar panel at the sun or reflecting sun light to a shaded part of my garden a few tenths a degree is fine.
I'm working to optimize the code to take advantage on some of bascoms built in features like fusing and asin. I'll share that at a latter date.
↧
↧
BASCOM-AVR : absolute value of difference : REPLY
@ Micha:
Testing the negative flag of SREG ( !SBIC SREG,2 ) will not work with unsigned byte vars, as it represents the high-bit of the result (=sign of signed number). So it will be set if you calculate [b:7c9a434c65]240 - 1 = 239[/b:7c9a434c65], because [b:7c9a434c65]239[/b:7c9a434c65] represents [b:7c9a434c65]-17[/b:7c9a434c65] in 2's complement.
Using [i:7c9a434c65]!sbic sreg,0[/i:7c9a434c65] instead of [i:7c9a434c65]!brcc[/i:7c9a434c65] does not make a difference in terms of speed on a mega device. On a Xmega it is even slower.
@ MWS:
For this specific situation your code will work, but it is - in general - not a good idea to use SREG in that way in basic code. The compiler adds several assembler commands between the actual subtraction and the [i:7c9a434c65]if-then[/i:7c9a434c65] directive. You can't be sure that this commands doesn't affect SREG. Obviously this variant will not work:
[code:1:7c9a434c65]C(I) = A - B
If SREG.0 = 1 Then C(I) = 256 - C(I)[/code:1:7c9a434c65]
as the compiler will generate code for calculating the memory address of [i:7c9a434c65]C(I)[/i:7c9a434c65], which kills the carry status of the previous subtraction.
I know that you are aware of that, but other people with less knowledge about assembler will also read the forum thread.
↧
BASCOM-AVR : absolute value of difference : REPLY
OK, this code works:
[code:1:6ae1224e2e] Dim a as Byte
Dim b as Byte
Dim c as Byte
a = 230
b = 3
Do
!LDS r24,{a}
!LDS r25,{b}
!SUB r24,r25 ' Subtraction
!SBIC SREG,0 ' Carry-Flag
!NEG r24
!STS {c},r24
print c
Incr b
Loop
[/code:1:6ae1224e2e]
↧
Share your working BASCOM-AVR code here : Sun position and Heliostat offset. : REPLY
Hi Dave
I really like your program, my hobby being astronomical clock building, this kind of calculation is always interesting.
To make it usable by everyone, I suggest you to use an SD card and AVR-DOS for storing latitude and longitude coordinates.
As Mark suggests : the use of double give you more accuracy, a little error+ a little error give you a big one.
JP :wink:
↧
Share your working BASCOM-AVR code here : Sun position and Heliostat offset. : REPLY
Ok, for a solar panel it is fine :-)
Wish my roof was better pointed towards the Sun.
↧
↧
BASCOM-AVR : Calculating date from # of occurance of Sunday in a month? : REPLY
[quote:682f3fbe9d="Evert :-)"]Excel formula that you can convert: https://exceljet.net/formula/get-nth-day-of-week-in-month[/quote:682f3fbe9d]
That appears to backwards from what I need I believe
The only input I have to work with is knowing the occurrence of a day within a particular month.
For example, let's say I want to find the date (for the current year) of the 4th occurrence of Tuesday in July. Looking at a calendar, I can see that to be 07/23/19.
Fine, how to calculate the date in Bascom?
Sorry, I have a nasty habit of not making myself clear. Hopefully I succeeded this time....
↧
BASCOM-AVR : Calculating date from # of occurance of Sunday in a month? : REPLY
[quote:f88955ad98="KenHorse"]I have a nasty habit of not making myself clear.[/quote:f88955ad98]
Thou shalt not extend the habit by not reading nor understanding answers given to you.
↧
BASCOM-AVR : Calculating date from # of occurance of Sunday in a month? : REPLY
[quote:fd22431770="MWS"][quote:fd22431770="KenHorse"]I have a nasty habit of not making myself clear.[/quote:fd22431770]
Thou shalt not extend the habit by not reading nor understanding answers given to you.[/quote:fd22431770]
I was willing to pay a reasonable price for the code but I guess not.......
↧
Share your working BASCOM-AVR code here : Sun position and Heliostat offset. : REPLY
JP
Thanks for your suggestions.
Have you posted any pics of your astronomical clocks? I'd like to see them.
D.
↧
↧
BASCOM-AVR : Calculating date from # of occurance of Sunday in a month? : REPLY
[quote:7e7d284a2e="KenHorse"]I was willing to pay a reasonable price for the code but I guess not.......[/quote:7e7d284a2e]
I'm sorry, I'm not here for getting paid, I post for fun.
You can try to convert the Excel thing, which in contrary to your belief actually does what you want, i.e. it does what you describe.
Your input is month, year and DOW, the desired output is an exact date, the Excel sheet shows it in row 'Result'.
The Excel formula works similar to my suggestion in determining the DOW for the first day of month and then uses this result to calculate the exact date, which is easy.
For example, you know the year, 2019, you know the month, say August, 08, you know the first of month, wich is of course 01.
This gives 08.01.2019, Bascom's DayOfWeek() will return 4, as it's a Thursday.
If you look for the n't Friday of same month, while you know the first day is a Thursday, naturally and also easy to calculate, the first Friday must be the second of August.
Assumed you look for the 4th Friday of same month, you add 3 * 7 = 21 days to the 2nd, which returns the 23rd.
Finally you need do do range checking for not using void combinations.
↧
EASY TCP/IP : I think, Config TCP is not confortable with W5500 : REPLY
Hi andrej,
what exactly is your problem?
↧
Share your working BASCOM-AVR code here : Sun position and Heliostat offset. : REPLY
Hi Dave,
see [url]https://www.mcselec.com/index2.php?option=com_forum&Itemid=59&page=viewtopic&t=13096&highlight=astronomical[/url]
astro-IV will soon arrive with a simpler method to enter latitude, longitude and birthdays, without or with an Excel sheet
JP
:wink:
↧