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.
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.
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.
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.
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.
[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.
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.
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.
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.
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.
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:
@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.
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
''''''''''''''''''''
@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.
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.
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
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.
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.
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.
``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
''''''''''''''''''''
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.
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?
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.
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: 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.
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
''''''''''''''''''''
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.
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
''''''''''''''''''''
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 !!!
Comments
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.
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
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.
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
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.
[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.
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
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.
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
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
''''''''''''''''''''
```
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:
@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.
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
@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.
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
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 $
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.
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
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
``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
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.
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?
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
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
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.
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
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 likenumber$(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.
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
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