@RS_Jim
CASE only checks for equality so if you have MINS@ SWITCH it will take 0 to 59
as the argument for SWITCH which only sets a switch variable.
0 CASE <do something> BREAK
Compares 0 to the switch variable and if equal will do something and then EXIT which means that
this type of structure needs to be in a separate function and called from within your BEGIN AGAIN loop.
There is no way normally that you could check a CASE of > or < unless we define those operators but you could
do something like this:
pub SEQUENCE ( mins -- )
DUP IF (all off)
ELSE
20 / SWITCH
0 CASE ( 0..19 ) ( dstairs on ) BREAK
1 CASE ( 20..39 ) ( ustairs on ) BREAK
( 40..59 ) ( shop on ) \ CASE would be redundant at this point
THEN
;
pub MAIN
BEGIN
MINS@ SEQUENCE
AGAIN
;
Alternatively:
pub SEQUENCE ( mins -- )
DUP 39 > IF ( shop on ) DROP BREAK
DUP 19 > IF ( ustairs on ) DROP BREAK
IF ( dstairs on ) BREAK
( all off )
;
This last version is very simple and factoring SEQUENCE into its own word that
requires the parameter be passed to it on the stack allows you to test it easily
rather than being dependent upon the current time.
You may notice too that I used IF BREAK together and that's just a little trick
with the way that CASE BREAK is implemented in this version of Tachyon where
BREAK simply compiles "EXIT THEN" which you could have used too.
The first test 39 > will detect 40..59 and turn the shop on and then exit
The second test 19 > will detect 20..39 (since >39 has failed and proceeded to here)
The final test is simple is it or is it not 0 because the only conditions left are
0 or 1..19.
So this method is not so much about Forth but more about simplifying or rearranging your algorithm
rather than trying to make it fit into some particular syntax. In any language then it is simple to implement.
OK, odd thing happened... I loaded the other kernel as suggested, and then cut and pasted your hex code above. Seemed to work fine. Rebooted, and now I have multiple ROMS, and the SIDCOG twice! I have not even attempted to load the other ROMS. Are they built in to the kernel?
Peter,
Finally I get a chance to try some of your suggestions. Having a failure I am sure cockpit error on my side. this is what I see when I paste my commands in from notepad.
... .DT Sat, 15 Sep 2018 06:24:05 MST ok
... pub CTLAC %111 0 3 PINS! ??? in CTLAC at PINS!
;
... pub USTAIRS %110 0 3 PINS! ??? in USTAIRS at PINS!
;
... pub DSTAIRS %101 0 3 PINS! ??? in DSTAIRS at PINS!
;
... pub SHOP %011 0 3 PINS! ??? in SHOP at PINS!
;
... {
... pub CTLAC %111 0 3 PINS! ??? in CTLAC at PINS!
;
... pub USTAIRS %110 0 3 PINS! ??? in USTAIRS at PINS!
;
... pub DSTAIRS %101 0 3 PINS! ??? in DSTAIRS at PINS!
;
... pub SHOP %011 0 3 PINS! ??? in SHOP at PINS!
;
...
...
.. 128 bytes hvacregs
...
... pub HVAC 4 RUN:
... hvacregs 8 COG!
...
... ctlac ??? in HVAC at ctlac
OUTCLR
...
...
...
...
...
... BEGIN
...
... pub SEQUENCE ( mins -- )
...
... IF DAY@ > 5 BREAK
...
... IF HRS@ < 15 BREAK
...
... IF HRS@ > 19 BREAK
...
... DUP 39 > IF ( shop on ) DROP BREAK
... DUP 19 > IF ( ustairs on ) DROP BREAK
... IF ( dstairs on ) BREAK
... CTLAC
... ;
PINS! only existed in EXTEND for the old V3 Tachyon and there are probably better ways of doing this too. Since you are only storing to P0..P2 and no shifting is involved I would simply do this with your routines using USTAIRS as an example:
%111 OUTCLR %110 OUTSET
As you can see this is very simple as it resets P0..P2 in general and then sets them with the new data.
For reference:
OLD V3 CODE
\ Build up a mask using a starting pin number and the number of consecutive pins
\ Useage: #16 8 MASKS CONSTANT dbus
pub MASKS ( pin cnt -- mask )
0 ROT ROT ADO I MASK OR LOOP
;
pub PINS! ( data pin for -- )
ROT 3RD SHL ( pin for data<<pin ) --- shift data into correct position
ROT ROT MASKS ( data<<pin mask ) --- create mask
OUTCLR OUTSET
;
Updated version of MASKS
pub MASKS ( pin cnt -- mask ) SWAP FROM 0 SWAP FOR I MASK OR NEXT ;
......
pub HVAC 4 RUN:
hvacregs 8 COG!
ALLOFF
BEGIN
pub SEQUENCE ( mins -- )
.......
ALLOFF
;
I see I forgot the AGAIN!
Jim
while it is possible to continie from one word into the next without using the ";"
here it looks strange
especially with the BEGIN in the first definition and AGAIN in the second.
Probably you want to do s.th. else ...
so maybe check your
pub ... ;
pub ... ;
sequence
@RS_Jim - I can't figure out what you are trying to do, can you just write a paragraph or too that explains the sequence and the reasons and then we can come up with an efficient algorithm for it.
This kind of sequence is back to front but doesn't do anything even if it was fixed up:
IF DAY@ > 5 BREAK
Normally you might test two values which leaves a true/false after which you use IF and if it is true then do something before you exit with BREAK
DAY@ 5 > IF ( do something for day 6 and day 7 ) BREAK
BTW, you already used ALLOFF but you can combine it even more like this:
NEW COUNTER MODES
For as long as Tachyon has been around I have used the counters for frequency and duty cycle modes but never got around to adding some of the other modes. Of course they are easy enough to write directly to the registers but here is a simple way of accessing the DETECT modes. Simply use the words POS or NEG followed by optional EDGE and/or FB (for feedback) then completed with the keyword DETECT. Use it this way to count positive edges (with demo)
... 0 LOW ok
... B 0 APIN POS EDGE DETECT ok
... 100 FOR 0 HIGH 0 LOW NEXT ok
... COUNT@ . 100 ok
... 9600 SERBAUD ok
... $55 0 SEROUT ok
... COUNT@ . 106 ok
... 1 0 SEROUT ok
... COUNT@ . 108 ok
In the demo I just made sure P0 was low and not left floating then selected the B counter and set APIN to 0 and then POS EDGE DETECT mode. The next line toggle P0 100 times followed by checking the count with COUNT@. Then a simple serial output to look for those positive edge detect transitions etc.
I will expand upon these modes and include frequency and pulse-width/period measurement words to simplify user code.
These are some of the ways you can configure for DETECT:
NEW COUNTER MODES
For as long as Tachyon has been around I have used the counters for frequency and duty cycle modes but never got around to adding some of the other modes. Of course they are easy enough to write directly to the registers but here is a simple way of accessing the DETECT modes. Simply use the words POS or NEG followed by optional EDGE and/or FB (for feedback) then completed with the keyword DETECT. Use it this way to count positive edges (with demo)
... 0 LOW ok
... B 0 APIN POS EDGE DETECT ok
... 100 FOR 0 HIGH 0 LOW NEXT ok
... COUNT@ . 100 ok
... 9600 SERBAUD ok
... $55 0 SEROUT ok
... COUNT@ . 106 ok
... 1 0 SEROUT ok
... COUNT@ . 108 ok
In the demo I just made sure P0 was low and not left floating then selected the B counter and set APIN to 0 and then POS EDGE DETECT mode. The next line toggle P0 100 times followed by checking the count with COUNT@. Then a simple serial output to look for those positive edge detect transitions etc.
I will expand upon these modes and include frequency and pulse-width/period measurement words to simplify user code.
These are some of the ways you can configure for DETECT:
@MJB - The original Tachyon thread went to well over 3200 replies and 318,000 views so I guess this thread is only a little baby in that respect Still easy enough to lose a lot of posts but there are dozens of other Tachyon threads too.
What do you suggest? Maybe it needs to be assembled into an online document or linked documents that could become the basis for an online Tachyon tutorial and projects book since Tachyon is the means to the ends, that is, getting hardware up and running, but in a fast and fun way.
Peter,
You asked for a narrative description of what I wished to achieve. Here in Arizona, our utility rates are based upon Peak demand during the hours of 1500 and 2000 Monday through Friday. We have a two story house with an air conditioned work space in a two car garage. My concept for this system is to limit the operation of each HVAC to a twenty minute, non overlapping segment during each of the five "prime time hours" The system is based upon using NC relays in each of the thermostatic control lines. If the system fails nothing happens and the HVAC operates normally. During prime time hours, during each 20 minute segment, one of the Units will be permitted to run as its relay will be off thus contact closed allowing the Tstat to control the unit normally. Thus first 20 minutes downstairs closed and running (%011) upstairs and shop off. Second 20 minutes downstairs off upstairs on shop off ( %101) and the last 20 minutes upstairs and downstairs off and shop on (%110). My concept was that if the Day is 6 or 7, your done, nothing happens. If the hours are less than 1500 or greater than 1900 also do nothing. If the hours are between 1500 and 2000, each 20 minute segment is active. I was trying to use <> constructs to lessen the number of comparisons that needed to be performed.
If Day > 5 (=6 or = 7) exit, do nothing all relays off.
if Hours < 1500 exit, do nothing all relays off.
if Hours > 1900 exit, do nothing all relays off.
if hours are between 1500 and 2000, and minutes are 1to 19 inclusive dnstairs on other two off.
if hours are between 1500 and 2000, and minutes are 20 to 39 inclusive upstairs on others off.
if hours are between 1500 and 2000, and minutes are 40 to 59 inclusive shop on others off.
when minutes are 00 carry over from the last hour so that no unit turns on for 1 minute. (new thought)
Thus my thoughts:
Day > 5 exit
Hours < 1500 exit
Hours > 1900 exit
Minutes 1-19 downstairs on (relay off)
minutes 20-39 upstairs on (relay off)
Minutes 40-59 shop on (relay off)
I believe I could write this in PASM and easily fit it in 1 cog. I just thought forth was a better way to do it.
I hope this makes sense.
Jim
First thing I tackle is "teaching" Tachyon new words to expand its vocabulary so that I can "talk" to it in terms that are more application specific like this:
( our utility rates are based upon Peak demand during the hours of 1500 and 2000 Monday through Friday. )
--- true if peak which is Mon to Fri from 1500 to 2000
pub PEAK? ( -- flg ) DAY@ MON FRI WITHIN HOUR@ 15 20 WITHIN AND ;
Now I can use PEAK? as in PEAK? IF ( do something etc ) THEN
Damn Peter, here I thought I was being so smart with <> . So now I suppose I need t create a word for each HVAC unit that has the minutes WITHIN the appropriate 20 minute segment something like;
pub DNSTAIRS MINS@ 1 19 within %011 OUTSET
pub UPSTAIRS MINS@ 20 39 within %101 OUTSET ;
pub SHOP MINS@ 40 59 within %110 OUTSET ;
I never dreamed that TACHYON would have such a construct.
Jim
Perhaps but don't forget that you need conditional statements in there such as IF THEN. So each word can decide for itself whether it needs to be active, like this:
pub ?DNSTAIRS PEAK? IF MINS@ 1 19 WITHIN IF %011 OUTSET THEN ;
pub ?UPSTAIRS PEAK? IF MINS@ 20 39 WITHIN IF %101 OUTSET THEN ;
pub ?SHOP PEAK? IF MINS@ 40 59 WITHIN IF %110 OUTSET THEN ;
This doesn't give you the deadtime but that could be handled by replaced the OUTSET word in these functions with something that looks for a change and if so, turns off all outputs for a while before applying the new one. Here is something a little more functional which defines the relay pins, a relay memory to detect change and if there is then it applies a short dead time of 5 seconds etc.
--- RELAY CONTROL PINS --- one of P0..P2 active low (it seems)
2 := *DNSTAIRS
1 := *UPSTAIRS
0 := *SHOP
byte relay
--- select a relay update relay memory - if change turn off, wait, then set new
pub RELAY ( n -- ) relay C@ OVER relay C! <> IF %111 OUTSET 5 s relay C@ MASK OUTCLR THEN ;
pub ?DNSTAIRS PEAK? IF MINS@ 1 19 WITHIN IF *DNSTAIRS RELAY THEN THEN ;
pub ?UPSTAIRS PEAK? IF MINS@ 20 39 WITHIN IF *UPSTAIRS RELAY THEN THEN ;
pub ?SHOP PEAK? IF MINS@ 40 59 WITHIN IF *SHOP RELAY THEN THEN [s][/s];
Your main loop doesn't have to do much, in fact this loop wouldn't even need to loop, it could even run in the main console cog as a "keypoll" event
pub ?HVAC ?DNSTAIRS ?UPSTAIRS ?SHOP ;
--- poll ?HVAC in the background of the main cog
' ?HVAC +POLL
There are other ways of doing this too, but the main thing is to check the functionality of it all and make sure it works first, then "improve" it.
EDIT: I already have a better version again that doesn't worry about deadtime although it does turn off 1 min every hour as per spec but is called by the background timers every minute.
I've just started on the firmware for my data acquisition system - I loaded v5.4 + EXTEND in yesterday, smooth sailing. I have a card in the system that has an LTC2754 SPI 4-channel 16 bit D/A. I knocked together some cheap and cheerful routines to see how fast I could write to the chip. Turns out writing 5 32-bit values (4 channels + 'update all' command) takes about 70us (propeller running at 100MHz), so all things being equal I should be able to have an update rate of around 14kHz. I might be able to boost that further by using 24-bit writes.
One question: I will be adding a card that has an A/D on a separate SPI bus - is there currently support for multiple serial buses in Tachyon? If not, how difficult would be be to add? I intend to have a cog controlling each device asynchronously (they'll be sampling at different rates).
Anyway, allow me to express my gratitude for some sterling work - Tachyon is just the ticket for this project.
While I'm at it, thanks to MJB for compiling the 'encyclopedia' - extremely useful!
I've just started on the firmware for my data acquisition system - I loaded v5.4 + EXTEND in yesterday, smooth sailing. I have a card in the system that has an LTC2754 SPI 4-channel 16 bit D/A. I knocked together some cheap and cheerful routines to see how fast I could write to the chip. Turns out writing 5 32-bit values (4 channels + 'update all' command) takes about 70us (propeller running at 100MHz), so all things being equal I should be able to have an update rate of around 14kHz. I might be able to boost that further by using 24-bit writes.
One question: I will be adding a card that has an A/D on a separate SPI bus - is there currently support for multiple serial buses in Tachyon? If not, how difficult would be be to add? I intend to have a cog controlling each device asynchronously (they'll be sampling at different rates).
Anyway, allow me to express my gratitude for some sterling work - Tachyon is just the ticket for this project.
While I'm at it, thanks to MJB for compiling the 'encyclopedia' - extremely useful!
Andrew
each COG keeps it's own internal registers for SPI (clk, miso,mosi, ce, cnt)
so as long you are using separate COGs you should be fine.
As always - if you REALLY want to go with TACHYON then read the source.
Have a look into EXTEND for @SCK and SPIPINS
and TACHYON.SPIN for SPIPINS as well
There are actually two sets of SPI register in each COG
one for the embedded SPI functions sitting at #0 ff actually it is 1 ff, at 0 sits the RESET vector
and one for the more complex SPI functions loaded as RUNMODS sitting at #10 ff
Thanks MJB - that has clarified things. I had assumed SPIPINS was global, and resided in hub memory, but as you say, each cog maintains its own, so that will work very well. I only need half duplex, so the bare bones 'fast' routines should do the trick. If I decide I need 'blistering' speed, I can write my own ROM and have tachyon load that.
Hey @CtlAltDel - Looks good, line me up a Banana Daiquiri
You should be able to do a 24-bit SPIRD SPIRD SPIRD in around 6.24us but the SD block fastread/write routines use the counter so at 100MHz that would be a maximum rate of 12.5MHz SPI.
SPIWR32 writes 32-bits in 6.88us at 100MHz.
BTW all, I've started a new Tachyon projects folder, a compilation of various devices that have been interfaced and additional information and ideas on how it can be modified for other uses etc. This is not really an introduction or a tutorial or encyclopedia, but the wealth of information I am incorporating into it lets the beginner get straight into and hands on into a project, learning along the way. Like learning a few chords and playing a song, then building up theory and technique.
Hey @CtlAltDel - Looks good, line me up a Banana Daiquiri
Just the one? Lightweight
I've verified your timings. With 24 bit writes, and including the bit shifting and additions I need to do to build the control/address fields for each channel word, I can do a complete 4 channel update (5 24-bit writes) in 63us, 16 kHz - more than adequate for this application (controlling a piezoelectric element).
Hello Peter,
we are now switching to V5 NEON from DAWN and changed our make files using RECLAIM instead of COMPACT etc. It turns out, that compiling EASYNET returns an error:
.. TACHYON V5 Propeller .:.:--TACHYON--:.:. Forth V5r4 NEON 540180811.0000
0100 ok
0200 ok
0300 ok
0393 ??? in WCOLD at TELNET
0400
This currently is the only error message.
Earlier we had a DICTIONARY FULL message, but the system is responsive. After a RECLAIM the system hangs up until hardware reset.
We came around the DICTIONARY by removing not used words from EXTEND, like WS2812, PWM, ... etc.
Propeller .:.:--TACHYON--:.:. Forth V5r4 NEON 540180811.0000
*** MODULES *** Propeller .:.:--TACHYON--:.:. Forth V5r4 NEON 540180811.0000
3766: EASYFILE SDHC card + FAT32 Virtual Memory File System V1.2 171024-0000
2FF4: TOOLS DEV TOOLS
1980: EXTEND Primary extensions to TACHYON V5 kernel - 180915-1900
AUTORUN BOOT 2F82
FREQ = 96.00MHZ
*** INITS ***
MOUNT 3DA4
NO ROMS
*** I2C ***
$A0 EE/RTC
$A2 EE/RTC
INTERCOM:
CODE:$4850 = 18000 bytes
NAME:$5B3C = 6340 bytes
DATA:$77BD = 685 bytes
FREE: = 4844 bytes
Data Stack (0)
Mon, 01 Jan 2001 00:00:00 UTC
CARD: SL32G SD03.80 #DD3D.6825 2017/3 !C0FF.80C3 1,413us
FAT: #6464.6433 NO NAME FAT32 31,910,789,120 bytes (32kB clusters)
--------------------------------------------------------------------------------
... BACKUP BACKUP ok
.. IFDEF W5500
...
... TACHYON V5 Propeller .:.:--TACHYON--:.:. Forth V5r4 NEON 540180811.0000
0100 ok
0200 ok
0300 ok
0393 ??? in WCOLD at TELNET
0400
0600 ok
0700
0800 ok
0883 ok
End of source code, 0001 errors found Load time = 44.4
Code bytes used = 2594
Name bytes used = 1462
CODE:$5272 = 20594 bytes
NAME:$5586 = 7802 bytes
DATA:$784F = 831 bytes
FREE: = 788 bytes
Data Stack (0)
ok
...
... ---
... errors W@ NOT IF ' ifup +INIT THEN ok
...
... ?BACKUP BACKUP ok
...
... ---
... &13.12.15.14 WIZPINS ( P1372 ) ok
... \
... &17.1.19.18 WIZPINS ok
another RECLAIM results in FREE: 1480 bytes.
Is it just the case, that in the current version the complete system doesn't fit into the memory, that is, EXTEND, EASYNET and EASYFILE can not be loaded together? Or are we doing wrong? Maybe some Tariffs can reduce the code import and so reduce the deficit?
Peter,
I have been thinking about the original algorithm, and I believe that it will better to change the upstairs within period to 0 to 19. Doing that eliminates the chance that one unit could try and recycle too soon. The only other thing I need to do is figure out how to out clear everything when Hours = 20 and minutes =0. That will restore they system to the non peak condition of all relays off.
Should have some time today to do some testing. Will install this on a QS board so that I have the LEDs to sub for relays for tests.
I am looking forward to peaking into the projects folder.
@RS_Jim - The PEAK? word will return false if it is non-peak so therefore wouldn't you use this to turn off the relays? I think this code should do pretty much what you are after.
( our utility rates are based upon Peak demand during the hours of 1500 and 2000 Monday through Friday. )
--- true if peak which is Mon to Fri from 1500 to 2000
pub PEAK? ( -- flg ) DAY@ MON FRI WITHIN HOUR@ 15 20 WITHIN AND ;
( My concept for this system is to limit the operation of each HVAC to a twenty minute, non overlapping segment during each of the five "prime time hours" )
--- RELAY CONTROL PINS --- one of P0..P2 active low (it seems)
2 := *DNSTAIRS
1 := *UPSTAIRS
0 := *SHOP
byte relay
--- select a relay update relay memory - if change turn off, wait, then set new
pub RELAY ( n -- ) relay C@ OVER relay C! <> IF %111 OUTSET 5 s relay C@ MASK OUTCLR THEN ;
pub RELAY %111 OUTSET MASK OUTCLR ;
pub ?DNSTAIRS PEAK? MINS@ 0 19 WITHIN AND IF *DNSTAIRS RELAY THEN ;
pub ?UPSTAIRS PEAK? MINS@ 20 39 WITHIN AND IF *UPSTAIRS RELAY THEN ;
pub ?SHOP PEAK? MINS@ 40 59 WITHIN AND IF *SHOP RELAY THEN ;
pub ?OFF PEAK? NOT IF %111 OUTSET THEN ;
--- HVAC will be polled every minute
pub HVAC 60000 hvactmr ALARM: ?DNSTAIRS ?UPSTAIRS ?SHOP ?OFF ;
@ErNa - ok, I see I must have moved something around and forgotten about it but it's fixed now. I've trimmed EASYNET and it should compile fine provided you do a RECLAIM before you load it but I will have to see what else I can do to free up some memory.
Peter,
Thanks, The OFF word is perfect with one minor adjustment and that is I will change OUTSET to OUTCLEAR. The system is designed with NC relay contacts so in the event of a failure on the MCU side of things, the HVAC will function normally. This system, when active, will interrupt the COOL thermostat line (%011,%0101) when I wish a unit to not run.
Hopefully will get the system tested today on the QS board. Next project will be completing my WX station which has languished in a drawer for several years. I will use SPI to read from AS4055 for wind direction, Counters in detect mode for the rain gage and wind velocity. The Parallax Altimeter module for barometric pressure and eventually one of the newer Senseron chips for temp and RH.
Jim
Comments
CASE only checks for equality so if you have MINS@ SWITCH it will take 0 to 59
as the argument for SWITCH which only sets a switch variable. Compares 0 to the switch variable and if equal will do something and then EXIT which means that
this type of structure needs to be in a separate function and called from within your BEGIN AGAIN loop.
There is no way normally that you could check a CASE of > or < unless we define those operators but you could
do something like this:
Alternatively:
This last version is very simple and factoring SEQUENCE into its own word that
requires the parameter be passed to it on the stack allows you to test it easily
rather than being dependent upon the current time.
You may notice too that I used IF BREAK together and that's just a little trick
with the way that CASE BREAK is implemented in this version of Tachyon where
BREAK simply compiles "EXIT THEN" which you could have used too.
The first test 39 > will detect 40..59 and turn the shop on and then exit
The second test 19 > will detect 20..39 (since >39 has failed and proceeded to here)
The final test is simple is it or is it not 0 because the only conditions left are
0 or 1..19.
So this method is not so much about Forth but more about simplifying or rearranging your algorithm
rather than trying to make it fit into some particular syntax. In any language then it is simple to implement.
I've always meant to play with it one day I remember writing Forth code for a real SID chip once, that was a lot of fun!
Maybe I might find some time I will kick off a demo for it.
Finally I get a chance to try some of your suggestions. Having a failure I am sure cockpit error on my side. this is what I see when I paste my commands in from notepad.
Why do my PINS! commands fail?
JIm
For reference:
OLD V3 CODE
Updated version of MASKS
I picked up that PINS! From the Glossery, so I thought that was the way to do it. I like the new way better.
Jim
How about this? I see I forgot the AGAIN!
Jim
here it looks strange
especially with the BEGIN in the first definition and AGAIN in the second.
Probably you want to do s.th. else ...
so maybe check your
pub ... ;
pub ... ;
sequence
This kind of sequence is back to front but doesn't do anything even if it was fixed up:
Normally you might test two values which leaves a true/false after which you use IF and if it is true then do something before you exit with BREAK
BTW, you already used ALLOFF but you can combine it even more like this:
For as long as Tachyon has been around I have used the counters for frequency and duty cycle modes but never got around to adding some of the other modes. Of course they are easy enough to write directly to the registers but here is a simple way of accessing the DETECT modes. Simply use the words POS or NEG followed by optional EDGE and/or FB (for feedback) then completed with the keyword DETECT. Use it this way to count positive edges (with demo) In the demo I just made sure P0 was low and not left floating then selected the B counter and set APIN to 0 and then POS EDGE DETECT mode. The next line toggle P0 100 times followed by checking the count with COUNT@. Then a simple serial output to look for those positive edge detect transitions etc.
I will expand upon these modes and include frequency and pulse-width/period measurement words to simplify user code.
These are some of the ways you can configure for DETECT:
hi Peter
it is a pitty those gems get buried in long threads.
So I started again to collect them in my old - for some time abandoned -
attempt to preserve them until they go into the official documentation.
https://docs.google.com/document/d/1tMlS3Oa8Sqa4LD90inoA9-JfhzuG_8m-yphxWHdFlZM/edit#heading=h.vkltvfv0hasd
What do you suggest? Maybe it needs to be assembled into an online document or linked documents that could become the basis for an online Tachyon tutorial and projects book since Tachyon is the means to the ends, that is, getting hardware up and running, but in a fast and fun way.
You asked for a narrative description of what I wished to achieve. Here in Arizona, our utility rates are based upon Peak demand during the hours of 1500 and 2000 Monday through Friday. We have a two story house with an air conditioned work space in a two car garage. My concept for this system is to limit the operation of each HVAC to a twenty minute, non overlapping segment during each of the five "prime time hours" The system is based upon using NC relays in each of the thermostatic control lines. If the system fails nothing happens and the HVAC operates normally. During prime time hours, during each 20 minute segment, one of the Units will be permitted to run as its relay will be off thus contact closed allowing the Tstat to control the unit normally. Thus first 20 minutes downstairs closed and running (%011) upstairs and shop off. Second 20 minutes downstairs off upstairs on shop off ( %101) and the last 20 minutes upstairs and downstairs off and shop on (%110). My concept was that if the Day is 6 or 7, your done, nothing happens. If the hours are less than 1500 or greater than 1900 also do nothing. If the hours are between 1500 and 2000, each 20 minute segment is active. I was trying to use <> constructs to lessen the number of comparisons that needed to be performed.
If Day > 5 (=6 or = 7) exit, do nothing all relays off.
if Hours < 1500 exit, do nothing all relays off.
if Hours > 1900 exit, do nothing all relays off.
if hours are between 1500 and 2000, and minutes are 1to 19 inclusive dnstairs on other two off.
if hours are between 1500 and 2000, and minutes are 20 to 39 inclusive upstairs on others off.
if hours are between 1500 and 2000, and minutes are 40 to 59 inclusive shop on others off.
when minutes are 00 carry over from the last hour so that no unit turns on for 1 minute. (new thought)
Thus my thoughts:
Day > 5 exit
Hours < 1500 exit
Hours > 1900 exit
Minutes 1-19 downstairs on (relay off)
minutes 20-39 upstairs on (relay off)
Minutes 40-59 shop on (relay off)
I believe I could write this in PASM and easily fit it in 1 cog. I just thought forth was a better way to do it.
I hope this makes sense.
Jim
I just followed your link of saved nuggets of Tachyon wisdom. Wow, that is neat will have to book mark this for future reference.
Jim
Now I can use PEAK? as in PEAK? IF ( do something etc ) THEN
More to follow.....
Jim
This doesn't give you the deadtime but that could be handled by replaced the OUTSET word in these functions with something that looks for a change and if so, turns off all outputs for a while before applying the new one. Here is something a little more functional which defines the relay pins, a relay memory to detect change and if there is then it applies a short dead time of 5 seconds etc.
Your main loop doesn't have to do much, in fact this loop wouldn't even need to loop, it could even run in the main console cog as a "keypoll" event
pub ?HVAC ?DNSTAIRS ?UPSTAIRS ?SHOP ;
--- poll ?HVAC in the background of the main cog
' ?HVAC +POLL
There are other ways of doing this too, but the main thing is to check the functionality of it all and make sure it works first, then "improve" it.
EDIT: I already have a better version again that doesn't worry about deadtime although it does turn off 1 min every hour as per spec but is called by the background timers every minute.
Here's a simple FREQ? word that sets up a counter using the DETECT modes and takes a 100ms adjusted sample and returns with the frequency.
I use the A counter to generate a frequency while the B counter is used to count those pulses.
I've just started on the firmware for my data acquisition system - I loaded v5.4 + EXTEND in yesterday, smooth sailing. I have a card in the system that has an LTC2754 SPI 4-channel 16 bit D/A. I knocked together some cheap and cheerful routines to see how fast I could write to the chip. Turns out writing 5 32-bit values (4 channels + 'update all' command) takes about 70us (propeller running at 100MHz), so all things being equal I should be able to have an update rate of around 14kHz. I might be able to boost that further by using 24-bit writes.
One question: I will be adding a card that has an A/D on a separate SPI bus - is there currently support for multiple serial buses in Tachyon? If not, how difficult would be be to add? I intend to have a cog controlling each device asynchronously (they'll be sampling at different rates).
Anyway, allow me to express my gratitude for some sterling work - Tachyon is just the ticket for this project.
While I'm at it, thanks to MJB for compiling the 'encyclopedia' - extremely useful!
Andrew
each COG keeps it's own internal registers for SPI (clk, miso,mosi, ce, cnt)
so as long you are using separate COGs you should be fine.
As always - if you REALLY want to go with TACHYON then read the source.
Have a look into EXTEND for @SCK and SPIPINS
and TACHYON.SPIN for SPIPINS as well
There are actually two sets of SPI register in each COG
one for the embedded SPI functions sitting at #0 ff actually it is 1 ff, at 0 sits the RESET vector
and one for the more complex SPI functions loaded as RUNMODS sitting at #10 ff
Nice!
You should be able to do a 24-bit SPIRD SPIRD SPIRD in around 6.24us but the SD block fastread/write routines use the counter so at 100MHz that would be a maximum rate of 12.5MHz SPI.
SPIWR32 writes 32-bits in 6.88us at 100MHz.
BTW all, I've started a new Tachyon projects folder, a compilation of various devices that have been interfaced and additional information and ideas on how it can be modified for other uses etc. This is not really an introduction or a tutorial or encyclopedia, but the wealth of information I am incorporating into it lets the beginner get straight into and hands on into a project, learning along the way. Like learning a few chords and playing a song, then building up theory and technique.
Just the one? Lightweight
I've verified your timings. With 24 bit writes, and including the bit shifting and additions I need to do to build the control/address fields for each channel word, I can do a complete 4 channel update (5 24-bit writes) in 63us, 16 kHz - more than adequate for this application (controlling a piezoelectric element).
we are now switching to V5 NEON from DAWN and changed our make files using RECLAIM instead of COMPACT etc. It turns out, that compiling EASYNET returns an error:
This currently is the only error message.
Earlier we had a DICTIONARY FULL message, but the system is responsive. After a RECLAIM the system hangs up until hardware reset.
We came around the DICTIONARY by removing not used words from EXTEND, like WS2812, PWM, ... etc.
another RECLAIM results in FREE: 1480 bytes.
Is it just the case, that in the current version the complete system doesn't fit into the memory, that is, EXTEND, EASYNET and EASYFILE can not be loaded together? Or are we doing wrong? Maybe some Tariffs can reduce the code import and so reduce the deficit?
I have been thinking about the original algorithm, and I believe that it will better to change the upstairs within period to 0 to 19. Doing that eliminates the chance that one unit could try and recycle too soon. The only other thing I need to do is figure out how to out clear everything when Hours = 20 and minutes =0. That will restore they system to the non peak condition of all relays off.
Should have some time today to do some testing. Will install this on a QS board so that I have the LEDs to sub for relays for tests.
I am looking forward to peaking into the projects folder.
Jim
Thanks, The OFF word is perfect with one minor adjustment and that is I will change OUTSET to OUTCLEAR. The system is designed with NC relay contacts so in the event of a failure on the MCU side of things, the HVAC will function normally. This system, when active, will interrupt the COOL thermostat line (%011,%0101) when I wish a unit to not run.
Hopefully will get the system tested today on the QS board. Next project will be completing my WX station which has languished in a drawer for several years. I will use SPI to read from AS4055 for wind direction, Counters in detect mode for the rain gage and wind velocity. The Parallax Altimeter module for barometric pressure and eventually one of the newer Senseron chips for temp and RH.
Jim