function

General questions about Firewing...

function

Postby AndrewB » Sat Oct 29, 2016 10:01 am

I have a number of routines that are incrementing and decrememnting various variables using buttons.
I have tried function as shown below but it does not work.
The sub does.

What do I need to modiy on the function to get this working.

Thanks

dim INTmin as byte = 3
Dim tempVal as Byte = 0


decrease(INTmin)
decrease2



function decrease(tempval2 as byte) as Ushort
If tempval2 >= 1 then
tempval2 = tempval2 - 1
else
tempval2 = 0
end if
delayms(100)
return tempval2
end function



sub decrease2()
tempval = INTmin
If tempval >= 1 then
tempval = tempval - 1
else
tempval = 0
end if
delayms(100)
INTmin = tempval

end sub
AndrewB
 
Posts: 94
Joined: Thu Jan 02, 2014 3:38 pm

Re: function

Postby Jerry Messina » Sat Oct 29, 2016 12:02 pm

Are you expecting the function to modify the INTmin parameter?

What's the purpose of a function and its return value vs a sub?
Do you think you should do something with the return value?

I think you need to read up a bit on variable scoping, lifetime, and the different methods of parameter passing (byval, byref)
Jerry Messina
 
Posts: 280
Joined: Thu Feb 14, 2013 10:16 am

Re: function

Postby AndrewB » Sat Oct 29, 2016 12:06 pm

Hi Jerry , I'm not wanting to be a programmer just doing this for fun.

If its a problem helping me no problem.

Thanks for your help.
AndrewB
 
Posts: 94
Joined: Thu Jan 02, 2014 3:38 pm

Re: function

Postby AndrewB » Sat Oct 29, 2016 12:32 pm

Ok I just add byref.....
AndrewB
 
Posts: 94
Joined: Thu Jan 02, 2014 3:38 pm

Re: function

Postby Jerry Messina » Sat Oct 29, 2016 1:59 pm

i don't mind helping at all. It just seems that maybe you're used to a simpler form of BASIC where everything is global and subroutines don't have parameters. If that's the case then a structured language like Firewing is going to take a bit of getting used to, that's all.

Instead of 'byref' you'd be better off using a function more along the lines of how they're supposed to work, and that's by assigning the return value. 'ByRef' is best used for special cases when you understand a little better how variables are passed.
Code: Select all
dim INTmin as byte = 3

function decrease(val as byte) as byte
   If val > 0 then
      val = val - 1
   end if
   delayms(100)
   return val
end function

INTmin = decrease(INTmin)
Jerry Messina
 
Posts: 280
Joined: Thu Feb 14, 2013 10:16 am

Re: function

Postby AndrewB » Sat Oct 29, 2016 4:02 pm

I did not add dual "As Byte".

Thanks I will change that later.

It's only a quick programme for me to get a couple of intervalometer shots of something being built.
They are only working at certain times of the day and only on work days.

This is just to save space on the SD card and allow me to leave it and not have to get up in the morning. :)

I have attached what I've done so far. which is working to an extent.

There are no checks on interval/exposure differnces or starttime and stoptime. It only starts and stops on hours as there is still a problem with that .
Also the exposure is outside of the interval due to the sub you gave me .
This should be inside and deducted from the interval.

If you have the time to point my errors that fine by me or modify please do.

Thanks for you time and help.

Code: Select all
' enable this line if using a 3 line LCD
#option LCD_DOGM = DOGM_163

' file imports...
imports LCDDogm                      ' import DOGM LCD library
imports DS1307                       ' import RTC module
Imports OW                           ' one wire, used for search
Imports DS18B20                      ' temperature sensor module 
                            ' secure digital (SD) module   
                  ' import the module

' program variables...
private DS18B20_Available As Boolean = False ' DS18B20 is available flag
private Time As RtcTime                      ' time variable
private Date As RtcDate                      ' date variable
dim Weekday as boolean = true
dim interval as ulong          // time to repeat, in seconds
dim exposure as uinteger      // time output is active, in msecs (65535 msecs = 65.535 secs)
Dim INTmin As byte = 3
Dim INTsec as byte = 0
Dim Startmin As Byte = 0
Dim Starthour As Byte = 8
Dim Stopmin As Byte = 0
Dim Stophour As Byte = 17
Dim Focus As Boolean = False
Dim TempVal as Byte = 0
Dim Posit as byte = 0
Dim EXPpoint as byte = 4
'Dim displayEXP as byte = 4
public dim running as boolean = false
dim frames as short = 0
dim shutter as PORTB.8
dim EXParray(13) as short = {8000,4000,2000,1000,510,250,125,66,33,16,8,4,2}

' the event is triggered each time the OW module is asked to
' perform a search - in this example, we are going to be looking
' for an DS18B20 device, which has a family ID of 0x28 (owDS18B20)...
Sub OnDeviceFound(command As Byte, family As Byte, ByRef romID() As Byte, ByRef abort As Boolean) Handles OW.OnSearch
   If command = owSearchROM And family = DS18B20.Family Then
      DS18B20_Available = True   ' mark as available
      DS18B20.ROMID = romID     ' set the unique ROM id...
      abort = True              ' no more searching required   
   End If
End Sub

' this code executes when firewing first starts up...
sub OnStartup() handles PIC.OnStartup
end sub

' main program entry point...
sub Main() 
   exposure = 1000
   ' clear LCD and set backlight       
   Dogm.Clear 
   Dogm.SetBacklight(160) 
   
   ' set the real time clock, you should only have
   ' to do this once if backup battery is installed...
   'SetRTC()   
     
   ' loop forever...
   while true   
   interval = (INTmin*60) + INTsec
      delayms(100)
      ' read time and date...
      Time = DS1307.ReadTime()
      Date = DS1307.ReadDate() 
     
      ' display time and date to LCD... 
      if posit <= 7 then 
      'if Weekday = true then
      'Dogm.WriteAt(1,1,Str(Time.Hour, 2),":",Str(Time.Minute,2),":",Str(Time.Second,2)," MTWTF  ")
      'else
      'Dogm.WriteAt(1,1,Str(Time.Hour, 2),":",Str(Time.Minute,2),":",Str(Time.Second,2)," MTWTFSS")
      'End if
      'Dogm.WriteAt(2,1,Str(Date.Day,2),":",Str(Date.Month,2),":",Str(Date.Year,2))
      Dogm.WriteAt(1,1,Str(Time.Hour, 2),":",Str(Time.Minute,2),":",Str(Time.Second,2)," ",GetDay(Date.DayOfWeek),"    ")
      Dogm.WriteAt(2,1,"IN:",Str(INTmin,2),":",Str(INTsec,2)," E:",GetEXP(EXPpoint))'Str(EXParray(EXPpoint))," ")' str(displayEXP),"  ")
      'Dogm.WriteAt(2,1,"IN=",Str(INTmin,2),":",Str(INTsec,2)," E=",Str(EXParray(EXPpoint  -1 ))," ")
      Dogm.WriteAt(3,1," T>",Str(Starthour,2),":",Str(Startmin,2)," T<",Str(Stophour,2),":",Str(Stopmin,2))
      else
      if running = true then
      Dogm.WriteAt(1,1,Str(Time.Hour, 2),":",Str(Time.Minute,2),":",Str(Time.Second,2)," SET    ")
       Dogm.SetBacklight(0)
       if date.DayOfWeek >=1 and date.DayOfWeek <=5   then
        if time.hour >= Starthour and time.hour < Stophour then 'time.minute > Startmin then
         'if time.minute >= Startmin and time.minute < Stopmin then
          Dogm.SetBacklight(0)
          Dogm.WriteAt(1,1,Str(Time.Hour, 2),":",Str(Time.Minute,2),":",Str(Time.Second,2)," RUNNING ") 
          Waitinterval(interval)
          if running = true then
          Dogm.SetBacklight(255)
          LoW(shutter)
          delayms(EXParray(EXPpoint - 1))
          high(shutter)   
          frames = frames + 1
          Dogm.SetBacklight(0)
          end if
        'end if
        end if
       end if
      Else
        Dogm.WriteAt(1,1,Str(Time.Hour, 2),":",Str(Time.Minute,2),":",Str(Time.Second,2)," STOPPED ")
        Dogm.SetBacklight(255)
      end if
      Dogm.WriteAt(2,1,"FRAMES:",Str(frames,4)," ",GetDay(Date.DayOfWeek)," ") 
      Dogm.WriteAt(3,1," T>",Str(Starthour,2),":",Str(Startmin,2)," T<",Str(Stophour,2),":",Str(Stopmin,2))
      end if
      Displaycursor               
      ' key control...
      dim Key as byte = Keypress
      select Key
       
         case 1 :
          if running = false and posit = 8 then 
          running = true
          else
          running = false
          end if
               
         ' key down
         case 2 :
          if posit = 0 then decrease(INTmin)'one1'decrease(INTmin)
          if posit = 1 then decrease(INTsec)
          if posit = 2 then increaseEXP
          if posit = 3 then decrease(Starthour)
          if posit = 4 then decrease(Startmin)
          if posit = 5 then decrease(Stophour)
          if posit = 6 then decrease(Stopmin)
          if posit = 7 then weekplus1
         
         ' key up
         case 4 :
          if posit = 0 then increasemin(INTmin)
          if posit = 1 then increasemin(INTsec)
          if posit = 2 then decreaseEXP
          if posit = 3 then increasehour(Starthour)
          if posit = 4 then increasemin(Startmin)
          if posit = 5 then increasehour(Stophour)
          if posit = 6 then increasemin(Stopmin)
          if posit = 7 then weekplus2
         
         ' key right...
         case 3 :   
          if running = false then
            If posit <= 7 then posit = posit + 1 else posit = 8
            delayms(100)
          end if
         ' key left...
         case 5 : 
         if running = false then   
             If posit >= 1 then posit = posit - 1 else posit = 0 
            delayms(100) 
         end if
      end select                   
     
         
         ' write to SD card... 
         
     
   end while
end sub

sub Waitinterval(secs as ulong)
   dim msecs as uInteger   
   dim i as ulong
   'dim button as byte = Keypress
   dim Button as PORTB.1
   while (secs > 0) 
      msecs = 1000                 // wait 1 sec (1000msec)... 
      Time = DS1307.ReadTime()
      Date = DS1307.ReadDate()   
      Dogm.WriteAt(1,1,Str(Time.Hour, 2),":",Str(Time.Minute,2),":",Str(Time.Second,2)," RUNNING ")
      while (msecs > 0)
         delayms(1) 
         if (button = 0) then    // leave if button pressed (PORTB.1 to GND)
         Dogm.WriteAt(1,1,Str(Time.Hour, 2),":",Str(Time.Minute,2),":",Str(Time.Second,2)," STOPPED ")
         running = false
         msecs = 0
         secs = 0
         exit sub
         end if
         msecs = msecs - 1
      end while 
      secs = secs - 1
   end while
end sub


sub Displaycursor()
if posit = 0 then
 Dogm.SetCursor(2,5)
 Dogm.WriteCommand(cmdBlinkOn)
end if
if posit = 1 then
 Dogm.SetCursor(2,8)
 Dogm.WriteCommand(cmdBlinkOn)
end if
if posit = 2 then
 Dogm.SetCursor(2,13)
 Dogm.WriteCommand(cmdBlinkOn)
end if
if posit = 3 then
 Dogm.SetCursor(3,5)
 Dogm.WriteCommand(cmdBlinkOn)
end if
if posit = 4 then
 Dogm.SetCursor(3,8)
 Dogm.WriteCommand(cmdBlinkOn)
end if
if posit = 5 then
 Dogm.SetCursor(3,13)
 Dogm.WriteCommand(cmdBlinkOn)
end if
if posit = 6 then
 Dogm.SetCursor(3,16)
 Dogm.WriteCommand(cmdBlinkOn)
end if
if posit = 7 then
 Dogm.SetCursor(1,11)
 Dogm.WriteCommand(cmdBlinkOn)
end if
if posit = 8 then
 Dogm.SetCursor(1,11)
 Dogm.WriteCommand(cmdBlinkOn)
end if
end sub

function decrease(byref tempval2 as byte) as Ushort
            If tempval2 >= 1 then
             tempval2 = tempval2 - 1
            else
             tempval2 = 0
            end if   
            return tempval2
            delayms(100)   
   end function

function increasemin(byref tempval2 as byte) as Ushort
            If tempval2 <= 59 then
             tempval2 = tempval2 + 1
            else
             tempval2 = 0
            end if   
            return tempval2
            delayms(100)   
   end function 
   
   function increasehour(byref tempval2 as byte) as Ushort
            If tempval2 <= 22 then
             tempval2 = tempval2 + 1
            else
             tempval2 = 00
            end if   
            return tempval2
            delayms(100)   
   end function


sub decreaseEXP()
            If EXPpoint >= 2 then
             EXPpoint = EXPpoint - 1
            else
             EXPpoint = 1
            end if
            delayms(100)                                     
end sub


sub increaseEXP()
             If  EXPpoint <= 12 then
              EXPpoint= EXPpoint + 1
             else
              EXPpoint = 13
             end if
            delayms(100) 
end sub

 
 sub Weekplus1()
  if Weekday = true then Weekday = false
end sub

sub Weekplus2()
 if Weekday = false then Weekday = true
end sub

Function GetEXP(index As Byte) As String
   if (index < 1) or (index > 13) then return "XXXX"
   Const EXP1(13) As String = {"8 Sec","4 Sec","2 Sec","1 Sec", "1/2  ","1/4  ", "1/8  ", "1/15 ", "1/30 ", "1/60 ","1/125","1/250","1/500"}
   return EXP1(index - 1)
End Function


' return the day of the week as a string value...
Function GetDay(index As Byte) As String
   if (index < 1) or (index > 7) then return "XXX"
   Const days(7) As String = {"MON", "TUE","WED", "THU", "FRI", "SAT", "SUN"}
   return days(index - 1)
End Function

' return month as a string value...
Function GetMonth(index As Byte) As String
   if (index < 1) or (index > 12) then return "XXX"
   Const months(12) As String = {"JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"}
   return months(index - 1)
End Function         
       
' set RTC...
Sub SetRTC()

   ' set the time...
   With Time, Time.Mode
      .Hour = 10
      .Minute = 12
      .Second = 00
      .Is12Hour = false
      .PM = false
   End With
   DS1307.WriteTime(Time)
                   
   ' set the date... 
   With Date
      .Day = 28
      .DayOfWeek = 5
      .Month = 10
      .Year = 16
   End With
   DS1307.WriteDate(Date)   
   
End Sub

' get keypress...
function Keypress() as byte
   dim voltage as ushort = Adc.Read(A0)
   Keypress = 0
   select voltage
      case 0     : Keypress = 1  ' select
      case < 200 : Keypress = 2  ' down
      case < 400 : Keypress = 3  ' right
      case < 600 : Keypress = 4  ' up
      case < 800 : Keypress = 5  ' left
   end select
end function


AndrewB
 
Posts: 94
Joined: Thu Jan 02, 2014 3:38 pm

Re: function

Postby Jerry Messina » Sun Oct 30, 2016 2:30 pm

Here's a few tips...

Since you're not really using the functions 'decrease', 'increasemin', and 'increasehour' as functions
I'd change them to 'subs' so that it's a little clearer how you're using them...
Code: Select all
    sub decrease(byref val as byte)
        if (val > 0) then
            val = val - 1
        endif
        delayms(100)   
    end sub

    // increase minutes... wrap 59 -> 0
    sub increasemin(byref val as byte)
        if (val < 59) then
            val = val + 1
        else
            val = 0
        end if
        delayms(100)   
    end sub
       
    // increase hours... wrap 23 -> 0
    sub increasehour(byref val as byte)
        if (val < 23) then
            val = val + 1
        else
            val = 0
        end if
        delayms(100)   
    end sub


Now, for the start and stop times... it can be tricky working in hours, minutes (and seconds).
Here's what the code currently looks like...
Code: Select all
    Dim Starthour As Byte = 8
    Dim Stophour As Byte = 17

    Dim Startmin As Byte = 0
    Dim Stopmin As Byte = 0

    if (time.hour >= Starthour) and (time.hour < Stophour) then
      if (time.minute >= Startmin) and (time.minute < Stopmin) then
          Dogm.WriteAt(1,1,Str(Time.Hour, 2),":",Str(Time.Minute,2),":",Str(Time.Second,2)," RUNNING ")
          <other code for running interval>
      end if
    end if


If you look at the 'minutes' comparison, since 'startmin' and 'stopmin' are zero the first part of that test is always true,
while the second part is always false.

When working with time I usually find it easier to convert hours:min:secs to a single value and work in minutes or seconds,
depending on what you're comparing...
Code: Select all
   
    Dim Starthour As Byte = 8
    Dim Stophour As Byte = 17

    Dim Startmin As Byte = 0
    Dim Stopmin As Byte = 0

    Dim CurrentTime, StartTime, StopTime as uInteger    // times in minutes

    // read time from the rtc
    Time = DS1307.ReadTime()

    // convert hours:minutes to minutes
    CurrentTime = (time.hour * 60) + time.minute
    StartTime = (Starthour * 60) + Startmin
    StopTime = (Stophour * 60) + Stopmin
   
    if (CurrentTime >= StartTime) and (CurrentTime < StopTime) then
      Dogm.WriteAt(1,1,Str(Time.Hour, 2),":",Str(Time.Minute,2),":",Str(Time.Second,2)," RUNNING ")
      <other code for running interval>
    end if


For example, you could change the 'Waitinterval' routine to use the RTC seconds time instead of using delay calls...
Code: Select all
    sub Waitinterval(waitsecs as uLong)
        dim Button as PORTB.1
        dim CurTime as uLong    // current time, in seconds
        dim ExitTime as uLong   // exit time, in seconds
        dim seconds as byte
       
        // read current time from rtc, convert to seconds and compute exit time
        Time = DS1307.ReadTime()
        CurTime = (Time.Hour * 60 * 60) + (Time.Minute * 60) + Time.Second
        ExitTime = CurTime + waitsecs
       
        // wait until its time to exit
        while (CurTime < ExitTime)
          Dogm.WriteAt(1,1,Str(Time.Hour, 2),":",Str(Time.Minute,2),":",Str(Time.Second,2)," RUNNING ")
          // wait for rtc seconds to change (easier on the LCD display)
          seconds = Time.seconds
          while (seconds = Time.seconds)
            if (button = 0) then    // leave if button pressed (PORTB.1 to GND)
              Dogm.WriteAt(1,1,Str(Time.Hour, 2),":",Str(Time.Minute,2),":",Str(Time.Second,2)," STOPPED ")
              running = false
              exit sub
            end if
            Time = DS1307.ReadTime()
          end while
          // update current time
          CurTime = (Time.Hour * 60 * 60) + (Time.Minute * 60) + Time.Second
        end while
    end sub


If you do the same sort of thing with the exposure and interval times then it makes it easier to adjust them
and you can more easily account for the exposure by subtracting it from the interval.
Jerry Messina
 
Posts: 280
Joined: Thu Feb 14, 2013 10:16 am

Re: function

Postby AndrewB » Sun Oct 30, 2016 2:58 pm

Thanks Jerry. I will have a look at these.

I had worked out that I needed to combine hours,min and secs.
Think I posted that the Day as Value thread.

As I'm using global values I think that the Starttime,Stoptime,interval and exposure should be worked out when entered.
so that I can check for

exposure is bigger than interval
interval and exposure are bigger than starttime+stoptime

etc.

Thanks again
AndrewB
 
Posts: 94
Joined: Thu Jan 02, 2014 3:38 pm


Return to Questions

Who is online

Users browsing this forum: No registered users and 1 guest

cron

x