Shop Learn
P2 FlexProp Basic ADC & Comm drivers - Page 2 — Parallax Forums

P2 FlexProp Basic ADC & Comm drivers

2

Comments

  • ersmithersmith Posts: 4,750

    I suspect that you have to make the rpi.start() call on the same COG that's doing the rpi.send() calls. Pin setup is a per-COG operation: you can't set up the pins on the main cog (cog 0) and then use them in a different COG.

  • RsadeikaRsadeika Posts: 3,516

    I just tried your suggestion, it did not help. It did not get to the main do...loop, something is preventing it to get to the main do...loop. When I eliminate the dht.start() in the main do...loop, then it gets to my debug item. If it is the dht.start(), I have no idea as to how I would get around that. These are my guesses.


    Ray

  • ersmithersmith Posts: 4,750

    Try giving a bigger stack to the rpi_comm task (increase the size of com_stack to, say, 128). Stack overflow is a pretty common cause of memory corruption and strange run-time behavior.

  • RsadeikaRsadeika Posts: 3,516

    I made the stack 256, now it seems to be behaving a little bit better. Looking at the dhtxx code, I think it is supposed to be providing float numbers, but when I changed tempf% to tempoff#, it is still providing integers, although I am using rpi.dec(). It kooks like the jm_fullduplexserial.spin2 does not deal with float numbers, is there some way to get around that.


    As for the stack, is there a better way of determining what the stack should be. I know we now have uddles of memory, but there must be a better way of determining what that number should be.


    Ray

  • ersmithersmith Posts: 4,750

    I doubt that dhtxx is producing floating point numbers, that's not something Spin really handles. You'll have to read Jon's documentation but most likely it's returning some kind of fixed point. Look at the comments for the various functions: for example, read_tempc() says it returns the current temperature in 0.1C units, so a return value of 242 would correspond to a temperature of 24.2 degrees C.


    At present there's no way to automatically determine the required stack size. The problem is not solvable in general (it's equivalent to the halting problem I believe) but for many simple cases it could be solved. But it's not easy.

  • JonnyMacJonnyMac Posts: 7,419

    [quote]It looks like the jm_fullduplexserial.spin2 does not deal with float numbers, is there some way to get around that.[/quote]

    It looks like you're saying things about my code without bothering to study it. Again. How many times are we going to go through this?


    As Evan pointed out -- which he could, because he actually read the code -- the tempc() method returns the temperature in 0.1 degree units. In my serial output routines, you could use a formatted string or the dpdec() method.

  • RsadeikaRsadeika Posts: 3,516

    I decided to try out SendRecvDevice() function.

    [code]

    dim rpi as class using "spin/SmartSerial.spin"

    rpi.start(4,6,0,115200)

    open SendRecvDevice(@rpi.tx,@rpi.rx) as #2

    [/code]

    Not sure if I am using this correctly, but it compiled without errors and it seems to work.

    [code]

    sub rpi_comm()

    do

    temp1()

    print #2, tempf%;" Degrees F"

    pausems 2000

    loop

    end sub

    [/code]

    This seems to work also. I was surprised that sub rpi_comm() is designated as a cpu, and the print #2 still worked. Just for the heck of it, I tried something like:

    print using "##.# Degrees F" #2;tempf% , compiler did not like this at all.


    How do you use this correctly: SendRecvDevice(sendf, recvf, closef). Since this is used with SmartSerial.spin, will this function get some added functionality. At the moment, not sure what could be added.

    Ray

  • ersmithersmith Posts: 4,750

    The "#2" has to come immediately after the "print", so it would look like:

    print #2 using "##.# Degrees F"; x#

    Not sure what your question about SendRecvDevice() means. It appears you used it correctly; you left off the close function which is supposed to be called when "close #n" happens, but that's OK, it defaults to a dummy (do-nothing) function.

  • RsadeikaRsadeika Posts: 3,516

    The using it correctly, I was referring to the closef part. Previously, when working with the P1, for the closef, I used something like @rpi.stop. Now I get a compiler complaint about 'stop'. So, I am not sure what should go in there.


    Another problem just came up when using the dht access code in my temp1 sub. When my cpu rpi_comm sub starts up it is using the temp1() every 2 seconds. When I try to use it my UI do...loop, that is the temp1() which has the dht code, it is crashing the value in both instances. I did try putting the dht access code in its own cpu, but it seems that even if I have a variable that has been initialized as shared, the rpi_comm sub was not able to get a value. I thought that when you declared a variable as shared it becomes global and therefore it would be available in the different cpu designations.

    Ray

  • RsadeikaRsadeika Posts: 3,516
    edited 2021-02-06 13:12

    The program below sorta works as expected. Having trouble with the printout of the tempf% and humid% values.


    For instance for the temperature, I am getting readouts like: 65 and 655 at times. Similar thing happens with the humidity values: 55 and 551 at times. These readouts will wreak havoc on my database, when the data gets transferred there. I am not sure how this can be fixed, using FlexBasic. I tried the 'print using', but that only works correctly when you are working with real float values.


    I also noticed it gets a little tricky when you assign the stack values, at one point I had dim com_stack(32) and var b = cpu(rpi_comm(),@com_stack(256)), this worked fine, or at least I did not notice any adverse affects.


    I kind of like using open SendRecvDevice(@rpi.tx,@rpi.rx) as #2, not sure how flexible this will turn out to be.


    Ray

    ```

    ' solsta1.bas


    ' January 27, 2021

    '

    '

    dim adc_ez as class using "jm_analog_in.spin2"

    dim dht as class using "jm_dhtxx.spin2"

    dim rpi as class using "spin/SmartSerial.spin"

    ' Comm

    rpi.start(4,6,0,115200)

    open SendRecvDevice(@rpi.tx,@rpi.rx) as #2



    '' Variables

    dim inBuff as string

    dim shared tempf%,humid%



    '' Stack

    dim blink_stack(8)

    dim com_stack(256)


    '' Main

    print "Type help for system menu."

    'COGs (cpu)

    var a = cpu(blink(57,80_000_000),@blink_stack(1))

    var b = cpu(rpi_comm(),@com_stack(128))

    ' UI

    do

    print "> ";

    input inBuff

    if inBuff = "quit" then

    exit

    else if inBuff = "help" then

    menu()

    else if inBuff = "tempf" then

    print tempf%;" Degrees F"

    else if inBuff = "humid" then

    print humid%;" Percent"

    else

    print "Invalid Command!"

    end if

    loop


    print "Program Ended!"

    print "0"

    _reboot

    end


    '' Subroutines

    '' Subroutine for the CPU(COG)

    sub rpi_comm()

    do


    print #2 using "%%.%% Degrees F";tempf%

    print #2, humid%;" Percent"

    pausems 2000

    loop

    end sub

    ''''''''''''''''''''


    sub blink(pin, freq)

    direction(pin) = output

    do

    output(pin) = not output(pin)

    waitcnt(getcnt() + freq)

    ' This is the dhtxx access code.

    'Temperature

    dht.start(30,22,1)

    tempf% = dht.read_tempf()

    pausems 250

    tempf% = (tempf%/10)

    ' Humidity

    humid% = dht.read_humidity()

    pausems 250

    humid% = (humid%/10)

    'pausems 2000

    loop

    end sub

    ''''''''''''''''''''


    sub menu()

    print "     Menu"

    print "quit - End the program."

    print "tempf - Temperature in F degrees."

    print "humid - Humidity in percentage."

    end sub

    ''''''''''''''''''''

    ```

  • dgatelydgately Posts: 1,423
    edited 2021-01-30 15:46

    How to place code in your postings (the new forum software does not use [code], [/code] anymore)... This video hopefully shows how to import code into your posts:

    1. Type 3 backticks (`) & type RETURN/ENTER
    2. Paste your code in the new highlighted space
    3. Type another RETURN/ENTER to create a new line
    4. Click the formatting icon to the left of the text & select the paragraph icon (backwards "P" icon) to end the code block
    ' solsta1.bas
    
    ' January 27, 2021
    
    dim adc_ez as class using "jm_analog_in.spin2"
    


  • ersmithersmith Posts: 4,750

    @Rsadeika : You're reading the temperature and humidity in one COG (the blink subroutine) but printing them in another. Why are you doing that? It does explain why what you're printing is inconsistent: the blink routine writes to those variables several times with different values (first with the original one from the object, then with the value divided by 10) so the printing COG sometimes sees the full value and sometimes the /10 value. If you do want to use a different cog for reading and printing, make sure the reading COG only writes to the variables once (e.g. by first reading into a temporary value, dividing that by 10, and then writing the temp value into the final variable).

    If you want to format the final value as a float, don't do an integer division by 10, convert to float and divide by 10.0.

  • RsadeikaRsadeika Posts: 3,516

    The program below, I decided to try out the mount "home/pi/database", _vfs_open_host command. The program compiles, but not mounting, I think.


    I have my P2 hooked up to a Raspberry Pi 4, the FlexProp GUI is working very well, but, for what ever reason it is not mounting a filesystem. In the UI I have testfile command which is supposed to open up test.csv file, the program just locks with that command. Not sure what is going wrong.


    Ray



    '  solsta1.bas
    
    
    '  January 27, 2021
    '
    '
    dim adc_ez as class using "jm_analog_in.spin2"
    dim dht as class using "jm_dhtxx.spin2"
    dim rpi as class using "spin/SmartSerial.spin"
    ' Comm
    rpi.start(4,6,0,115200)
    open SendRecvDevice(@rpi.tx,@rpi.rx) as #2
    
    
    '' Filesystem
    mount "/home/pi/database/", _vfs_open_host()
    
    
    '' Variables
    dim inBuff as string
    dim shared tempf#,humid#,tempf1%,humid1%
    
    
    
    
    '' Stack
    dim blink_stack(8)
    dim com_stack(256)
    
    
    '' Main
    print "Type help for system menu."
    'COGs (cpu)
    var a = cpu(blink(57,80_000_000),@blink_stack(1))
    var b = cpu(rpi_comm(),@com_stack(128))
    ' UI
    do
    	print "> ";
    	input inBuff
    	if inBuff = "quit" then
    		exit
    	else if inBuff = "help" then
    		menu()
    	else if inBuff = "tempf" then
    		print using "##.## Degrees F";tempf#
    	else if inBuff = "humid" then
    		print using "##.## Percent";humid#
    	else if inBuff = "testfile" then
    		open "/home/pi/databse/test.csv" for append as #3
    		print #3, "How about this!"
    		close #3
    	else
    		print "Invalid Command!"
    	end if
    loop
    
    
    print "Program Ended!"
    print "0"
    _reboot
    end
    
    
    '' Subroutines
    '' Subroutine for the CPU(COG)
    sub rpi_comm()
    	do
    
    
    		'print #2 using "%%.%% Degrees F";tempf%
    		print #2, tempf#
    		'print #2, humid%;" Percent"
    		print #2, humid#
    		'pausems 2000
    	loop
    end sub
    ''''''''''''''''''''
    
    
    sub blink(pin, freq)
    	direction(pin) = output
    	do
    		output(pin) = not output(pin)
    		waitcnt(getcnt() + freq)
    ' This is the dhtxx access code.
    		'Temperature		
    		dht.start(30,22,1)
    		tempf1% = dht.read_tempf()
    		pausems 250
    		tempf# = tempf1%
    		tempf# = (tempf#/10.0)
    		' Humidity
    		humid1% = dht.read_humidity()
    		pausems 250
    		humid# = humid1%
    		humid# = (humid#/10.0)
    		'pausems 2000
    	loop
    end sub
    ''''''''''''''''''''
    
    
    sub menu()
    	print "         Menu"
    	print "quit - End the program."
    	print "tempf - Temperature in F degrees."
    	print "humid - Humidity in percentage."
    end sub
    ''''''''''''''''''''
    
    
  • ersmithersmith Posts: 4,750

    @Ray: The mount command has as its argument the name as it should appear on the P2 side, not the Rpi side, and that should be just one directory, like:

    mount "/host", _vfs_open_host()

    You would then access your files with something like:

    open "/host/test.csv" for append as #3

    Deciding which directory gets shown is the responsibility of the loadp2 command line. That is, your P2 program can't just access any file on the host RPi, it can only access the ones it is given permission to by loadp2. By default in FlexProp the directory chosen is whatever directory you have the P2 binary in. If you want to use directory "/home/pi/database" (which incidentally you spelled in two different ways in your program!) you would change the loadp2 command line to read

    "-9/home/pi/database"

    where it used to say

    "-9."

    ("." means "the current directory" in all OSes that we use FlexProp on).


    To check for errors you'd have to wrap the open in a TRY/CATCH block.

  • RsadeikaRsadeika Posts: 3,516
    edited 2021-01-31 16:37

    I tried it again, after making the changes you suggested, it works. It saved the created file in the path that it uses in the Compile & Run.


    Since I am using 'open "/host/test.csv" for append as #3', I was expecting a new line written every time I did a testfile command. At the moment it just overwrites the first line. Since I am using 'print #3 ...' I thought it would be adding a LFCR automatically. If I wanted to force an LFCR, how would I do that.


    The other thing, for the P2, how do I have the program loaded and run, I guess it is now flash and not EEPROM.


    Ray

  • RsadeikaRsadeika Posts: 3,516

    Interesting development, I updated my Raspberry Pi 4 this morning, FlexProp GUI no longer starts up. And this still occurs after I did a fresh installation of FlexProp. I do not know what the next step should be. Anybody have any ideas?


    Thanks

    Ray


    pi@rpi40:~/flexprop $ ./flexprop.tcl

    Error in startup script: couldn't execute "bin/proploader": no such file or directory

      while executing

    "exec -ignorestderr bin/proploader$EXE -W"

      (procedure "rescanPorts" line 18)

      invoked from within

    "rescanPorts"

      (file "/home/pi/flexprop/src/gui.tcl" line 2118)

      invoked from within

    "source $ROOTDIR/src/gui.tcl"

      (file "./flexprop.tcl" line 25)

    pi@rpi40:~/flexprop $ 


  • ersmithersmith Posts: 4,750

    Ray: it cannot find the "proploader" program that's supposed to be in the flexprop/bin directory, or else for some reason it cannot run it. I'd suggest doing a new "make install". Maybe some libraries changed in an incompatible way during the update.

  • RsadeikaRsadeika Posts: 3,516

    I just did a fresh make install, and the problem still persists. I will do a new Raspberry Pi OS install, and then a FlexProp make install, I hope the problem disappears.

    Ray

  • RsadeikaRsadeika Posts: 3,516

    I just completed a new Raspberry Pi OS install, and I did a fresh flexprop make install, everything seems to be back to normal. Not sure what/why it got broke in the first place. I hope it does not happen again.

    Ray

  • RsadeikaRsadeika Posts: 3,516
    edited 2021-02-06 13:10

    ``The program below works as expected. I added ersmith clock program, that also works as expected.

    The next step will be to add some data logging, since I have the temp module available. This is working with the Raspberry Pi, and I will be writing the data log to the RPi, just curious how that will work. Does this mean I will have to have the P2 USB cable always attached, or can this work with the ttyS0 connection.

    Ray

    ' solsta2.bas
    '
    'Feb 01,2021
    '
    'dim telnet as class using spin/SmartSerial.spin
    'telnet.start(63,62,0,115200)
    'open SendRecvDevice(@telnet.tx,@telnet.rx) as #2
    dim dht as class using "jm_dhtxx.spin2"
    dim rpi as class using "spin/SmartSerial.spin"
    ' Comm
    ' Connection to the Raspberry Pi
    rpi.start(6,4,0,115200)
    open SendRecvDevice(@rpi.tx,@rpi.rx) as #2
    
    '' Filesystem
    mount "/host", _vfs_open_host()
    
    '' Variables
    dim inBuff as string
    dim shared tempf#,humid#,tempf1%,humid1%
    ' Time
    dim as ubyte hours, mins, secs
    ' Date
    dim as ubyte MM, DD
    dim as integer YYYY
    dim s$
    
    '' Stack
    dim blink_stack(8)
    dim td_stack(10)
    
    '' Main
    print #2, "Type help for system menu."
    'COGs (cpu)
    ' Blink P57 LED while the program is running.
    var a = cpu(blink(57,80_000_000),@blink_stack(1))
    print #2, " "
    
    ' UI for the Raspberry Pi
    do
        print #2, "> ";
        input #2, inBuff
        if inBuff = "quit" then
            exit
        else if inBuff = "reboot" then
            _reboot
        else if inBuff = "help" then
            menu()
        else if inBuff = "setclock" then
            input #2, "Enter year month day as YYYY-MM-DD ", s$
            YYYY = val(left$(s$, 4))
            MM = val(mid$(s$, 6, 2))
            DD = val(right$(s$, 2)) 
            input #2, "Enter time as hh:mm:ss ", s$
            hours = val(left$(s$, 2))
            mins = val(mid$(s$, 4, 2))
            secs = val(right$(s$, 2))
            pausems 250
            var x = cpu(updateClock, @td_stack(1))      
        else if inBuff = "date" then
            print #2, using "%%/%%/####"; MM; DD; YYYY
        else if inBuff = "time" then
            print #2, using "##:%%:%%"; hours, mins, secs
        else if inBuff = "tempf" then
            print #2, using "##.## Degrees F";tempf#
        else if inBuff = "humid" then
            print #2, using "##.## Percent";humid#
        else
            print #2, "Invalid Command!"
        end if
    loop
    
    print #2, "Program Ended!"
    print #2, "0"
    _reboot
    end
    ''''''''''''''''''''
    
    '' Subroutines
    '' Subroutine for the CPU(COG)
    sub blink(pin, freq)
        direction(pin) = output
        do
            output(pin) = not output(pin)
            waitcnt(getcnt() + freq)
    ' This is the dhtxx access code.
            'Temperature        
            dht.start(30,22,1)
            tempf1% = dht.read_tempf()
            pausems 250
            tempf# = tempf1%
            tempf# = (tempf#/10.0)
            ' Humidity
            humid1% = dht.read_humidity()
            pausems 250
            humid# = humid1%
            humid# = (humid#/10.0)
        loop
    end sub
    ''''''''''''''''''''
    
    sub menu()
        print #2, "         Menu"
        print #2, "quit - End the program."
        print #2, "reboot - Reboot the system."
        print #2, "setclock - Setup the date and time."
        print #2, "date - Show todays date."
        print #2, "time - Show the current time."
        print #2, "tempf - Temperature in F degrees."
        print #2, "humid - Humidity in percentage."
    end sub
    ''''''''''''''''''''
    
    '' Helper subroutine; return number of days in month.
    ''
    function daysInMonth() as uinteger
      ' february special case
      if MM = 2 then
        if (YYYY mod 4 = 0) then
          if (YYYY mod 100 <> 0) or (YYYY mod 1000 = 0) then
            return 29
          endif
        endif
        return 28
      endif
      if (MM = 4) or (MM=6) or (MM=9) or (MM=11) return 30
      return 31
    end function
    ''''''''''''''''''''
    
    ' cpu (COG)
    '' Routine to keep the clock up to date.
    ''
    sub updateClock
      dim nextSecond
      dim FREQUENCY
    
      FREQUENCY = clkfreq
      nextSecond = getcnt() + FREQUENCY
      do
        waitcnt(nextSecond)
        nextSecond = nextSecond + FREQUENCY
        secs = secs + 1
        if (secs >= 60) then
          secs = 0
          mins = mins + 1
          if (mins >= 60) then
            mins = 0
        hours = hours + 1
        if (hours >= 24) then
          hours = 0
          DD = DD + 1
        endif
          endif
        endif
        if (DD > daysInMonth()) then
          DD = 1
          MM = MM + 1
          if (MM > 12) then
            MM = 1
        YYYY = YYYY + 1
          endif
        endif
      loop
    end sub
    ''''''''''''''''''''
    
  • RsadeikaRsadeika Posts: 3,516
    edited 2021-02-04 15:33

    A couple of things, after installing a new Raspberry pi OS on my RPi4, the 'mount "/host", _vfs_open_host()' is not working. And the 'Ports' needs an explanation.

    For the 'mount' when I use an open "/host/xxx.txt" for append as #3, it just locks up. Was there something else that has to be added to the new RPi OS install.

    For the Ports, I have /dev/ttyS0 and /dev/ttyUSB0, listed. Not selecting either one, and doing a Compile & Run on P2, the program runs, as expected. If I choose /dev/ttyUSB0 and do a Compile & Run on P2, then the program does not run, as expected. Not sure what to make of this.

    Ray

    testit
    ```Is this working.

  • ersmithersmith Posts: 4,750

    I do not have an RPI4 and so I can't try to diagnose it. My suggestion would be to go back to the OS version that was working for you.

    As for the ports, you say:
    "For the Ports, I have /dev/ttyS0 and /dev/ttyUSB0, listed. Not selecting either one, and doing a Compile & Run on P2, the program runs, as expected. If I choose /dev/ttyUSB0 and do a Compile & Run on P2, then the program does not run, as expected. Not sure what to make of this."

    If the results are "as expected", what is the problem?

  • RsadeikaRsadeika Posts: 3,516

    When I choose /dev/ttyUSB0, it looks like it is compiling, but the program does not run, so I guess the program did not get compiled and not run.

    "My suggestion would be to go back to the OS version that was working for you.". Easier said then done, do not know what version was working, besides I keep up with the updates, all the time. This is getting to be very tricky, first I had a problem with FlexProp GUI, did an OS fresh install. Now, it seems to have developed a new problem, do not know how to fix it.

    I guess I might have to go back to the Windows 10 machine.

    Ray

  • RsadeikaRsadeika Posts: 3,516

    A few things.

    I think I narrowed down the mount "/host"... thing. It only takes one directory in its path. So, open "/host/test.txt" is fine, but open "/host/test/test.txt" , halts the program. I tried this on my windows 10 machine, and the same thing occurs, it is not an RPi problem only.

    I used the 'pausems 60000' , thinking that it would be 60 seconds, but it is only 6 seconds, not sure how that works.

    I am using the ersmith clock program, would be nice if it had a daylight savings time capability. I guess for the time being, will just have to do it manually.

    Since the clock program is available, how can I use the date part to be added to a file name? In my data logging programming, I plan on having a date switch on file name after a 24 hour period. So, I would like to auto name a file something like 'open "/host/"+date+"test.txt" for append as #3.

    Ray

  • ersmithersmith Posts: 4,750

    Ray: Thanks for the bug reports. I've fixed the issue with directories on the host, and also with append mode. If you get the most recent source and rebuild you'll have those fixes. (I've posted binaries of the beta on Patreon, but for the RPi you'll have to build from source).
    All of the waitxxx and pausexxx functions are limited by the 32 bits of the system clock frequency, so they cannot wait more than about 30 seconds (at 160 MHz, less at higher frequencies).
    Daylight savings times rules are different in every country and sometimes even within the same country, so I didn't want to get into that rats' nest. Feel free to add the rules for your country to rtc.bas. Changing the date to a string shouldn't be too difficult, just build a string from the YYYY, MM, DD, and other similar variables.

  • RsadeikaRsadeika Posts: 3,516
    edited 2021-02-07 14:25

    Below, I am having some trouble with the code to check for a midnight time and then close #3, then create a new file with the new date. Not sure if the problem is in the comparison, or, I am using the 'or' incorrectly. Can anybody set me on the right track?

    Anybody have any ideas as to how a wait or pause or similar command be created that can work way beyond the limits that are in place now. It could be nice if I could go way beyond a minute, to start out with.

    Ray

    sub data_log()
    
    do
        if dlc% = 1 then
        '' Temperature
            print #3, using "%%/%%/####,"; MM, DD, YYYY;
            print #3, using "##:%%:%%,"; hours, mins, secs;
            print #3, "TS,";
            print #3, tempf#
        '' Humidity 
            print #3, using "%%/%%/####,"; MM, DD, YYYY;
            print #3, using "##:%%:%%,"; hours, mins, secs;
            print #3, "HS,";
            print #3, humid#
        '' Battery array    
            print #3, using "%%/%%/####,"; MM, DD, YYYY;
            print #3, using "##:%%:%%,"; hours, mins, secs;
            print #3, "BA,";
            print #3, val1#
        '' Panel array  
            print #3, using "%%/%%/####,"; MM, DD, YYYY;
            print #3, using "##:%%:%%,"; hours, mins, secs;
            print #3, "SA,";
            print #3, val2#
        '' DC power 
            print #3, using "%%/%%/####,"; MM, DD, YYYY;
            print #3, using "##:%%:%%,"; hours, mins, secs;
            print #3, "P1,";
            print #3, val3#
        '' Check if midnight, if yes, new xxxsolsta.csv file    
            timeit = (str$(hours)+":"+str$(mins)+":"+str$(secs))
            if timeit = "23:59:59" or timeit <= "0:00:25" then
                close #3
                date = (str$(MM)+str$(DD)+str$(YYYY))
                open "/host/"+date+"solsta.csv" for append as #3
            end if
        end if
        pausems 15000
    loop
    
    end sub
    ''''''''''''''''''''
    
  • ersmithersmith Posts: 4,750

    I wouldn't try to compare times by comparing the strings. It's probably better to check the hour directly, something like if hours = 0 and mins = 0 and secs <= 25. Also beware that your str$(MM)+str$(DD)+str$(YYYY) won't necessarily be unique; you'll want some seperators in there to distinguish between months and days (str$ doesn't put any leading 0's in). If you do want leading 0's you can use something like number$(MM, 2, 10) which will convert MM to 2 digits in base 10.

    As for how to wait for longer periods: you know how to wait for 1 second (pausems(1000)). How can you wait for 60 seconds? How can you wait for N seconds for arbitrary N? I'm sure you can figure this out.

  • Another trick is to keep your system time as an offset in seconds from any past midnight crossing. Then by simply doing a quick test once each second like this...

    if (seconds MOD 86400 = 0) then
    ‘It is midnight
    else
    ‘Not midnight
    end if

    ... you can easily determine when the midnight crossing has happened.

    If you’d like a complete date/time library that is written entirely in FlexBASIC, PM me.

  • RsadeikaRsadeika Posts: 3,516
    edited 2021-02-08 14:36

    The program below now works as expected, I will create a new thread, for further entries.

    I am now waiting for FlexProp to add some P2 WiFi support, when that occurs, then I will be adding a telnet UI for the program. That way I will be able to access the program via the Raspberry Pi and telnet via WiFi.

    I do not have a lot of comments, in the program. After looking at the FlexBasic code, it looks like it is very easy to follow the way the program works. If that is not the case, please comment.

    FlexBasic is a great programming achievement, the learning curve is quite low to get started with. Now I wonder if I can do a GUI. :-)

    Ray

    ' solsta2.bas
    '
    'Feb 01,2021
    '
    'dim telnet as class using spin/SmartSerial.spin
    'telnet.start(63,62,0,115200)
    'open SendRecvDevice(@telnet.tx,@telnet.rx) as #2
    dim adc_ez as class using "jm_analog_in.spin2"
    dim dht as class using "jm_dhtxx.spin2"
    dim rpi as class using "spin/SmartSerial.spin"
    ' Comm
    ' Connection to the Raspberry Pi
    rpi.start(6,4,0,115200)
    open SendRecvDevice(@rpi.tx,@rpi.rx) as #2
    
    '' Filesystem
    mount "/host", _vfs_open_host()
    
    '' Variables
    dim inBuff as string
    dim shared tempf#,humid#,tempf1%,humid1%
    ' Time
    dim as ubyte hours, mins, secs
    ' Date
    dim shared as ubyte MM, DD
    dim shared as integer YYYY
    dim s$
    dim shared val1#,val2#,val3#
    dim test#,test1#,test2#,test3#
    dim shared dlc% = 0
    dim shared date as string
    dim shared timeit as string
    dim shared time as string
    dim shared startt as string
    dim shared datet as string
    dim shared sl1%
    
    '' Stack
    dim blink_stack(8)
    dim td_stack(10)
    dim dlc_stack(256)
    
    '' Main
    print #2, "Type help for system menu."
    print #2, "Set the clock first (setclock)!"
    'COGs (cpu)
    ' Blink P57 LED while the program is running.
    var a = cpu(blink(57,80_000_000),@blink_stack(1))
    var b = cpu(data_log(),@dlc_stack(128))
    print #2, " "
    
    ' UI for the Raspberry Pi
    do
        print #2, "> ";
        input #2, inBuff
        if inBuff = "quit" then
            exit
        else if inBuff = "reboot" then
            _reboot
        else if inBuff = "help" then
            menu()
        else if inBuff = "setclock" then
            input #2, "Enter year month day as YYYY-MM-DD ", s$
            YYYY = val(left$(s$, 4))
            MM = val(mid$(s$, 6, 2))
            DD = val(right$(s$, 2)) 
            input #2, "Enter time as hh:mm:ss ", s$
            hours = val(left$(s$, 2))
            mins = val(mid$(s$, 4, 2))
            secs = val(right$(s$, 2))
            pausems 250
            var x = cpu(updateClock, @td_stack(1))
    
        else if inBuff = "date" then
            print #2, "New Date (y)"
            input #2, inBuff
            if inBuff = "y" then
                input #2, "Enter year month day as YYYY-MM-DD ", s$
                YYYY = val(left$(s$, 4))
                MM = val(mid$(s$, 6, 2))
                DD = val(right$(s$, 2)) 
            else
                print #2, using "%%/%%/####"; MM; DD; YYYY
            end if
        else if inBuff = "time" then
            print #2, "New Time (y)"
            input #2, inBuff
            if inBuff = "y" then
                input #2, "Enter time as hh:mm:ss ", s$
                hours = val(left$(s$, 2))
                mins = val(mid$(s$, 4, 2))
                secs = val(right$(s$, 2))
            else
                print #2, using "##:%%:%%"; hours, mins, secs
            end if
        else if inBuff = "tempf" then
            print #2, using "##.## Degrees F";tempf#
        else if inBuff = "humid" then
            print #2, using "##.## Percent";humid#
        else if inBuff = "battery" then
            print #2, using "##.### Battery Array Volts";val1#
        else if inBuff = "panels" then
            print #2, using "##.### Solar Array Volts";val2#
        else if inBuff = "dcpwr" then
            print #2, using "##.### DC Power Volts";val3#
        else if inBuff = "snapit" then
            snapit()
        else if inBuff = "startlog" then
            time = (str$(hours)+":"+str$(mins)+":"+str$(secs))
            startt = time
            date = (str$(MM)+str$(DD)+str$(YYYY))
            datet = (str$(MM)+"/"+str$(DD)+"/"+str$(YYYY))
            open "/host/"+date+"solsta.csv" for append as #3
            dlc% = 1
            sl1% = 1
        else if inBuff = "stoplog" then
            dlc% = 0
        else if inBuff = "logstate" then
            if sl1% = 1 then
                print #2, "Log started ";datet
                print #2, startt
            else
                print #2, "Log not started."
            end if
        else
            print #2, "Invalid Command!"
        end if
    loop
    
    print #2, "Program Ended!"
    print #2, "0"
    close #2
    close #3
    _reboot
    end
    ''''''''''''''''''''
    
    '' Subroutines
    '' Subroutine for the CPU(COG)
    sub blink(pin, freq)
        direction(pin) = output
        do
            output(pin) = not output(pin)
            waitcnt(getcnt() + freq)
    ' This is the dhtxx access code.
            'Temperature        
            dht.start(30,22,1)
            tempf1% = dht.read_tempf()
            pausems 250
            tempf# = tempf1%
            tempf# = (tempf#/10.0)
            ' Humidity
            humid1% = dht.read_humidity()
            pausems 250
            humid# = humid1%
            humid# = (humid#/10.0)
            ' Battery array
            adc_ez.start(0, 0, 100)  '' This uses P0
            pausems 250
            test# = (adc_ez.readit()/1)     
            ' Get actual value of percentage
            test1# = ((test# * 3.3)/100)  
            ' Calibration to show actual voltage
            val1# = (test1# * 5.04928)
            ' Panel array
            adc_ez.start(2, 0, 100)  '' This uses P2
            pausems 250
            test3# = (adc_ez.readit()/1)
            'print test3#
            test2# = ((test3# * 3.3)/100)
            'print test2#
            val2# = (test2# * 38.56749)
            ' DC power
            adc_ez.start(1, 0, 100)  '' This uses P1
            pausems 250
            test3# = (adc_ez.readit()/1)
            'print test3#
            test2# = ((test3# * 3.3)/100)
            'print test2#
            val3# = (test2# * 5.14015)
        loop
    end sub
    ''''''''''''''''''''
    
    sub data_log()
    
    do
        if dlc% = 1 then
        '' Temperature
            print #3, using "%%/%%/####,"; MM, DD, YYYY;
            print #3, using "##:%%:%%,"; hours, mins, secs;
            print #3, "TS,";
            print #3, tempf#
        '' Humidity 
            print #3, using "%%/%%/####,"; MM, DD, YYYY;
            print #3, using "##:%%:%%,"; hours, mins, secs;
            print #3, "HS,";
            print #3, humid#
        '' Battery array    
            print #3, using "%%/%%/####,"; MM, DD, YYYY;
            print #3, using "##:%%:%%,"; hours, mins, secs;
            print #3, "BA,";
            print #3, val1#
        '' Panel array  
            print #3, using "%%/%%/####,"; MM, DD, YYYY;
            print #3, using "##:%%:%%,"; hours, mins, secs;
            print #3, "SA,";
            print #3, val2#
        '' DC power 
            print #3, using "%%/%%/####,"; MM, DD, YYYY;
            print #3, using "##:%%:%%,"; hours, mins, secs;
            print #3, "P1,";
            print #3, val3#
        '' Check if midnight, if yes, new xxxsolsta.csv file    
            timeit = (str$(hours)+":"+str$(mins)+":"+str$(secs))
            'if timeit = "23:59:59" or timeit <= "0:00:25" then
            if hours = 0 and mins = 0 and secs <= 20 then
                close #3
                date = (str$(MM)+str$(DD)+str$(YYYY))
                open "/host/"+date+"solsta.csv" for append as #3
            end if
        end if
        pausems 15000
    loop
    
    end sub
    ''''''''''''''''''''
    
    sub menu()
        print #2, "         Menu"
        print #2, "quit - End the program."
        print #2, "reboot - Reboot the system."
        print #2, "setclock - Setup the date and time."
        print #2, "date - Show todays date."
        print #2, "time - Show the current time."
        print #2, "tempf - Temperature in F degrees."
        print #2, "humid - Humidity in percentage."
        print #2, "battery - Voltage of battery array."
        print #2, "panels - Voltage of solar panels."
        print #2, "dcpwr - Voltage output for DC power."
        print #2, "snapit - Show all the data values."
        print #2, "startlog - Start the data log."
        print #2, "stoplog - Stop the data log."
        print #2, "logstate - Status of data log."
    end sub
    ''''''''''''''''''''
    
    '' Helper subroutine; return number of days in month.
    ''
    function daysInMonth() as uinteger
      ' february special case
      if MM = 2 then
        if (YYYY mod 4 = 0) then
          if (YYYY mod 100 <> 0) or (YYYY mod 1000 = 0) then
            return 29
          endif
        endif
        return 28
      endif
      if (MM = 4) or (MM=6) or (MM=9) or (MM=11) return 30
      return 31
    end function
    ''''''''''''''''''''
    
    ' cpu (COG)
    '' Routine to keep the clock up to date.
    ''
    sub updateClock
      dim nextSecond
      dim FREQUENCY
    
      FREQUENCY = clkfreq
      nextSecond = getcnt() + FREQUENCY
      do
        waitcnt(nextSecond)
        nextSecond = nextSecond + FREQUENCY
        secs = secs + 1
        if (secs >= 60) then
          secs = 0
          mins = mins + 1
          if (mins >= 60) then
            mins = 0
        hours = hours + 1
        if (hours >= 24) then
          hours = 0
          DD = DD + 1
        endif
          endif
        endif
        if (DD > daysInMonth()) then
          DD = 1
          MM = MM + 1
          if (MM > 12) then
            MM = 1
        YYYY = YYYY + 1
          endif
        endif
      loop
    end sub
    ''''''''''''''''''''
    
    sub snapit
    
        print #2, using "%%/%%/####"; MM, DD, YYYY
        print #2, using "##:%%:%%"; hours, mins, secs
        print #2, using "##.### Battery Array Volts";val1#
        print #2, using "##.### Solar Array Volts";val2#
        print #2, using "##.### DC Power Volts";val3#
        print #2, using "##.## Degrees F";tempf#
        print #2, using "##.## Percent Humidity";humid#
    
    end sub
    ''''''''''''''''''''
    
    
  • RsadeikaRsadeika Posts: 3,516

    I have been running my program for a couple of days, and this shows up. Not sure what this means. The program is still running, and it is still doing the data logging. What memory is this this referring to.

    Ray

    ( Entering terminal mode.  Press Ctrl-] to exit. )
     !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!!  !!! out of memory !!! 
    
    
Sign In or Register to comment.