Each segment's current for 7-SEG-LED is 2.1mA because 74HC595's sink current is max20mA.
If you want more brighter, it should put buffer between 7SEG-LED and 74HC595(IC2).
If buffer is invert-type, you should modify word'7SEG_drive'.
Calibration is fairly straight forward: start the logger, set the time, run the clock for a day (or a week).
At the end of the time period, check the prop time against the original reference (in my case, one unit used internet time, another unit used AT&T cellular time which tends off by 3 minutes minimum).
The offset is calculated:
number of seconds delta * 80,000,000 (clock frequency) / number of hours = offset in ticks. It tends to be around 10,000,000 to 14,000,000 ticks per hour, or between 0.1 and 0.15 seconds per hour.
offsetInTicks is used with seftDriftOffest
My units so far run a little slow, so I will be using a postive offset value
After that, we would just let it run, and see if it drifts in one direction of the other over a longer time.
It won't be exact, but is purdy durn close, and close enough for most stuff I do.
The drift is corrected when the time is accessed. If we log once per second, that means the time is corrected once per second. As long as the time is accessed at least once per hour, this method should work fairly well.
The demo I'm working on is intended to log distance reading from SR04, and later temperature reading from a cheap thermal probe array, which is still being investigated.
Still working on a new demo for Logger1Simple. Turns out the most difficult activity is letting the logger run for long enough to calculate the time drift correction. All we have to do is let the clock run for a couple days or a week, and calculate how many seconds drift over how many hours.
seconds.delta * 80Mhz / hours = drift.ticks
Since we set and read the time manually, there a bit of slop. But after many hours (100+) the slop has less impact.
The PROBLEM is that windows updates itself several times a week, and my test units tend to be on old windows PCs. At least one update per week needs to restart the system. The system restart also restarts the quickstart running off the USB port, and ruins the test. Wrecked two of three week long tests. Bravo!
So now I'm changing my test rigs to use wall wart USB power supplies, and talking over serial using HC06 to Android. Take THAT, microsoft update!
So far my test rigs have been between 11 and 14 million ticks per hour slow. I think thats about 0.15 seconds per hour.
I asked for the code for Logge2. This newer version of the logger auomatically creates a new logfile each day. 24 hours of data (86400 records) per file should be easier to deal with than millions of records in a single file.
You could consider using a GPS clock as reference...
some units are quite inexpensive, and will be a nice add on to the little robot when not used for this task :-)
You could consider using a GPS clock as reference...
some units are quite inexpensive, and will be a nice add on to the little robot when not used for this task :-)
Thanks for the suggestion. That certainly is an option. At the moment, using the internal counter is significantly less expensive, much less complex, and more than adequate for the job. And kind of interesting to watch and play with .
When we get out of the lab, and farther than 30 feet, and the price comes down, we plan to upgrade from blue tooth to wifi. Then we will be able to auto sync to internet time.
When we get farther than wifi range, we plan to use cellular packet data infrastructure.
When we get farther than cell tower range, we will try out GPS. So its on the upgrade path, but not on the top of the list yet.
I haven't even used a realtime clock chip as a reference yet. Too many little things in the way of too many other little things.
movcnt, #5{14}' minimal advance (to avoid full range delay)addcnt, cnt' current timewaitcntcnt, #0' run-through
Based on that 72 cycles require an additional 58 cycles (14+58=72). With the ret included it's 54 as you found out already (i.e. final value is 5{14}+54{54}=59{68}).
From the looks of it you are missing 5 cycles (83 vs 88). When you start with mov cnt, #5 you will get a delay of 14 cycles for mov/add/waitcnt and 4 for the ret (#5 is the minimum delay for this code sequence to avoid overflow wait). In other words 5 maps to 18, to get 72 you need to start with mov cnt, #5 + (72 - 18).
Prop0 Cog6 ok
test1848 Prop0 Cog6 ok <--10.6usec
test2928 Prop0 Cog6 ok <--11.6usec
test3880 Prop0 Cog6 ok <--11usec
test4960 Prop0 Cog6 ok <--12usec
test51040 Prop0 Cog6 ok <--13usec
test61120 Prop0 Cog6 ok <--14usec
test71200 Prop0 Cog6 ok <--15usec
test81280 Prop0 Cog6 ok <--16usec
test91360 Prop0 Cog6 ok <--17usec
test101440 Prop0 Cog6 ok <--18usec
test202240 Prop0 Cog6 ok <--28usec
test303040 Prop0 Cog6 ok <--38usec
When calling word, there is overhead.
I think it is about 8usec.
No idea. I'd suggest letting the delay PASM code generate the timing itself for testing (capture cnt before/after and return it on the stack). This should get rid of any high level overhead. Then go from there.
movcnt, #5{14}' minimal advance (to avoid full range delay)addcnt, cnt' current timewaitcntcnt, #0' run-through
cnt register is read-only on manual.
My understanding;
[mov cnt, #5] use writable register
[add cnt, cnt] first cnt writable register, second cnt readable register
[waitcnt cnt, #0] compare cnt[readable register] and cnt[writable register]
Is this correct?
And this using way is garanteed?
Always no problem?
My understanding;
[mov cnt, #5] use writable register
[add cnt, cnt] first cnt writable register, second cnt readable register
[waitcnt cnt, #0] compare cnt[readable register] and cnt[writable register]
Is this correct?
Effectively yes. Using cnt in the destination slot of an insn addresses its shadow register (which is writable). So the above sequence comes down to:
mov shadow[cnt], #5{14}' minimal advance (to avoid full range delay)add shadow[cnt], cnt' current timewaitcnt shadow[cnt], #0' run-through
which is the equivalent to
mov tmp, #5{14}' minimal advance (to avoid full range delay)add tmp, cnt' current timewaitcnt tmp, #0' run-through
And yes, this is guaranteed to work. Just a shortcut when you run out of normal registers.
Hi.
I made summary about assembler_word's quetion.
My procedure is incorrect?
Hey! That's a good idea to do this. I'll try this out and see how far I get.
One thing I notice is in the "Caution" section. The assembler works on the top stack item, I think because this optimized in the prop architecture, this is fastest. Including code to use more stack items would be slower and begins to cost more in code space than it gains. Since we're using assembler, the need is "fastest and smallest".
If we need to leave more than one item on the stack, we might not have to store these in hub ram. I think we can just make additional assembler routines and call them in sequence in higher level forth macro, this might be faster than hub access. This would mean it puts responsibility for handling this efficiently on the designer, which is the usual trade off in forth. But I haven't used this yet, so I'm not sure whether my explanation is correct.
i think when when you reverse bias the diode, there is voltage on it. when you read the diode, the voltage falls. maybe the falling reverse is the same as rising forward, just weaker?
Comments
I made 7-Segment Dynamic drive curcuit.
http://youtu.be/PltTpgMuEdw
Each segment's current for 7-SEG-LED is 2.1mA because 74HC595's sink current is max20mA.
If you want more brighter, it should put buffer between 7SEG-LED and 74HC595(IC2).
If buffer is invert-type, you should modify word'7SEG_drive'.
Modified to searching free Cog by code.
demo WORD[7SEG_drive] operate on Cog5 Cog:0 #io chan:1 PropForth v5.5 2013Feb20 11:30 0 Cog:1 #io chan:1 PropForth v5.5 2013Feb20 11:30 0 Cog:2 #io chan:1 PropForth v5.5 2013Feb20 11:30 0 Cog:3 #io chan:1 PropForth v5.5 2013Feb20 11:30 0 Cog:4 #io chan:1 PropForth v5.5 2013Feb20 11:30 0 Cog:5 #io chan:1 RUNNING 7Seg-LED Cog:6 #io chan:1 PropForth v5.5 2013Feb20 11:30 0 6(0)->7(0) Cog:7 #io chan:1 SERIAL 7(0)->6(0) CON:Prop0 Cog5 RESET - last status: 0 ok Cog:0 #io chan:1 PropForth v5.5 2013Feb20 11:30 0 Cog:1 #io chan:1 PropForth v5.5 2013Feb20 11:30 0 Cog:2 #io chan:1 PropForth v5.5 2013Feb20 11:30 0 Cog:3 #io chan:1 PropForth v5.5 2013Feb20 11:30 0 Cog:4 #io chan:1 PropForth v5.5 2013Feb20 11:30 0 Cog:5 #io chan:1 PropForth v5.5 2013Feb20 11:30 0 Cog:6 #io chan:1 PropForth v5.5 2013Feb20 11:30 0 6(0)->7(0) Cog:7 #io chan:1 SERIAL 7(0)->6(0) Prop0 Cog6 ok
I made LED Infinity Mirror.
It seems to need better half-mirror.
http://www.google.co.jp/imgres?imgurl=http://www.instructables.com/files/deriv/FWL/S1PK/HKVKM7TN/FWLS1PKHKVKM7TN.LARGE.jpg&imgrefurl=http://www.instructables.com/id/Arduino-controlled-RGB-LED-Infinity-Mirror/&usg=__6J_fYUxe3zblV0WX0A5bLyXWN2c=&h=910&w=1024&sz=213&hl=ja&start=136&zoom=1&tbnid=UuIVm5Lf0y0HiM:&tbnh=133&tbnw=150&ei=NgsrUvLUOs69kAXAzYFI&prev=/images%3Fq%3Dinfinity%2BLED%26start%3D120%26sa%3DN%26hl%3Dja%26gbv%3D2%26tbm%3Disch&itbs=1&sa=X&ved=0CEoQrQMwDzh4
I'm working on a demo for the logger.
Calibration is fairly straight forward: start the logger, set the time, run the clock for a day (or a week).
At the end of the time period, check the prop time against the original reference (in my case, one unit used internet time, another unit used AT&T cellular time which tends off by 3 minutes minimum).
The offset is calculated:
number of seconds delta * 80,000,000 (clock frequency) / number of hours = offset in ticks. It tends to be around 10,000,000 to 14,000,000 ticks per hour, or between 0.1 and 0.15 seconds per hour.
offsetInTicks is used with seftDriftOffest
My units so far run a little slow, so I will be using a postive offset value
After that, we would just let it run, and see if it drifts in one direction of the other over a longer time.
It won't be exact, but is purdy durn close, and close enough for most stuff I do.
The drift is corrected when the time is accessed. If we log once per second, that means the time is corrected once per second. As long as the time is accessed at least once per hour, this method should work fairly well.
The demo I'm working on is intended to log distance reading from SR04, and later temperature reading from a cheap thermal probe array, which is still being investigated.
Still working on a new demo for Logger1Simple. Turns out the most difficult activity is letting the logger run for long enough to calculate the time drift correction. All we have to do is let the clock run for a couple days or a week, and calculate how many seconds drift over how many hours.
seconds.delta * 80Mhz / hours = drift.ticks
Since we set and read the time manually, there a bit of slop. But after many hours (100+) the slop has less impact.
The PROBLEM is that windows updates itself several times a week, and my test units tend to be on old windows PCs. At least one update per week needs to restart the system. The system restart also restarts the quickstart running off the USB port, and ruins the test. Wrecked two of three week long tests. Bravo!
So now I'm changing my test rigs to use wall wart USB power supplies, and talking over serial using HC06 to Android. Take THAT, microsoft update!
So far my test rigs have been between 11 and 14 million ticks per hour slow. I think thats about 0.15 seconds per hour.
I asked for the code for Logge2. This newer version of the logger auomatically creates a new logfile each day. 24 hours of data (86400 records) per file should be easier to deal with than millions of records in a single file.
some units are quite inexpensive, and will be a nice add on to the little robot when not used for this task :-)
Thanks for the suggestion. That certainly is an option. At the moment, using the internal counter is significantly less expensive, much less complex, and more than adequate for the job. And kind of interesting to watch and play with
When we get out of the lab, and farther than 30 feet, and the price comes down, we plan to upgrade from blue tooth to wifi. Then we will be able to auto sync to internet time.
When we get farther than wifi range, we plan to use cellular packet data infrastructure.
When we get farther than cell tower range, we will try out GPS. So its on the upgrade path, but not on the top of the list yet.
I haven't even used a realtime clock chip as a reference yet. Too many little things in the way of too many other little things.
I like so much them..
Massimo
http://youtu.be/r5xt8_0E6xM
\ ( n1 -- ) n1:delay-time[usec] fl build_BootOpt :rasm sub $C_stTOS , # 8 __1 jmpret __delay_ret , # __delay djnz $C_stTOS , # __1 spop jexit \ Delay 72ticks __delay mov $C_treg2 , # d59 add $C_treg2 , cnt waitcnt $C_treg2 , # 0 __delay_ret ret ;asm a_delay
When it want to delay 72ticks on __delay routin, how much value is [mov $C_treg2 , # d59]?
It seems to be ok as d59.
But I want to know correct value.
mov 4ticks
add 4ticks
waitcnt 6ticks + alpha
ret 4ticks
72 - 4 - 4 - 6 - 4 = 54
It seems small as 54.
mov cnt, #5{14} ' minimal advance (to avoid full range delay) add cnt, cnt ' current time waitcnt cnt, #0 ' run-through
Based on that 72 cycles require an additional 58 cycles (14+58=72). With the ret included it's 54 as you found out already (i.e. final value is 5{14}+54{54}=59{68}).Thanks kuroneko-san.
I wrote another code;
fl lockdict create a_tick forthentry $C_a_lxasm w, h11E h113 1- tuck - h9 lshift or here W@ alignl h10 lshift or l, z2WiPqk l, z1SyZfQ l, z3[yPSK l, z2WiPyk l, z24iPuE l, z2WiPRF l, z1SV01X l, z2Wyx8p l, z20ixFk l, z3ryx80 l, z1SV000 l, freedict : ticks a_tick . ; { \ ( n1 -- n2 ) n1:delay-time[usec] n2:ticks fl build_BootOpt :rasm mov $C_treg3 , cnt __1 jmpret __delay_ret , # __delay djnz $C_stTOS , # __1 mov $C_treg4 , cnt sub $C_treg4 , $C_treg3 mov $C_stTOS , $C_treg4 jexit \ Delay 72ticks __delay mov cnt , # d54 add cnt , cnt waitcnt cnt , # 0 __delay_ret ret ;asm a_tick }
Result below;
Prop0 Cog6 ok 1 ticks 83 Prop0 Cog6 ok 2 ticks 158 Prop0 Cog6 ok 3 ticks 233 Prop0 Cog6 ok
I expected below at 1 ticks;
impret __delay_ret , # __delay 4ticks
mov cnt , # d54 4ticks
add cnt , cnt 4ticks
waitcnt cnt , # 0 6ticks + 54ticks
ret 4ticks
djnz $C_stTOS , # __1 8ticks
mov $C_treg4 , cnt 4ticks
total ticks = 88
What is wrong?
I misunderstood about waitcnt.
I understnad waitcnt.
fl lockdict create a_delay forthentry $C_a_lxasm w, h11B h113 1- tuck - h9 lshift or here W@ alignl h10 lshift or l, z1SyZKN l, z3[yPSJ l, z1SyLI[ l, z1SV01X l, z2Wyx8u l, z20ixFk l, z3ryx80 l, z1SV000 l, freedict : cntCOG@ cnt COG@ cnt COG@ swap - . ; \ d272 : test1 cnt COG@ 1 a_delay cnt COG@ swap - d272 - . ; : test2 cnt COG@ 2 a_delay cnt COG@ swap - d272 - . ; : test3 cnt COG@ 3 a_delay cnt COG@ swap - d272 - . ; : test4 cnt COG@ 4 a_delay cnt COG@ swap - d272 - . ; : test5 cnt COG@ 5 a_delay cnt COG@ swap - d272 - . ; : test6 cnt COG@ 6 a_delay cnt COG@ swap - d272 - . ; : test7 cnt COG@ 7 a_delay cnt COG@ swap - d272 - . ; : test8 cnt COG@ 8 a_delay cnt COG@ swap - d272 - . ; : test9 cnt COG@ 9 a_delay cnt COG@ swap - d272 - . ; : test10 cnt COG@ d10 a_delay cnt COG@ swap - d272 - . ; : test20 cnt COG@ d20 a_delay cnt COG@ swap - d272 - . ; : test30 cnt COG@ d30 a_delay cnt COG@ swap - d272 - . ; { \ ( n1 -- ) n1:delay-time[usec] fl build_BootOpt :rasm __1 jmpret __delay_ret , # __delay djnz $C_stTOS , # __1 spop jexit \ Delay 72ticks __delay mov cnt , # d59 add cnt , cnt waitcnt cnt , # 0 __delay_ret ret ;asm a_delay }
Result;
Prop0 Cog6 ok test1 848 Prop0 Cog6 ok <--10.6usec test2 928 Prop0 Cog6 ok <--11.6usec test3 880 Prop0 Cog6 ok <--11usec test4 960 Prop0 Cog6 ok <--12usec test5 1040 Prop0 Cog6 ok <--13usec test6 1120 Prop0 Cog6 ok <--14usec test7 1200 Prop0 Cog6 ok <--15usec test8 1280 Prop0 Cog6 ok <--16usec test9 1360 Prop0 Cog6 ok <--17usec test10 1440 Prop0 Cog6 ok <--18usec test20 2240 Prop0 Cog6 ok <--28usec test30 3040 Prop0 Cog6 ok <--38usec
When calling word, there is overhead.
I think it is about 8usec.
Why is test2's ticks bigger than test3's ticks?
I have one more question.
fl lockdict create a_delay1 forthentry $C_a_lxasm w, h11B h113 1- tuck - h9 lshift or here W@ alignl h10 lshift or l, z1SyZKN l, z3[yPSJ l, z1SyLI[ l, z1SV01X l, z2Wyx8u l, z20ixFk l, z3ryx80 l, z1SV000 l, freedict lockdict create a_delay forthentry $C_a_lxasm w, h11C h113 1- tuck - h9 lshift or here W@ alignl h10 lshift or l, z24yPO8 l, z1SyZSO l, z3[yPSK l, z1SyLI[ l, z1SV01X l, z2Wyx8u l, z20ixFk l, z3ryx80 l, z1SV000 l, freedict : cntCOG@ cnt COG@ cnt COG@ swap - . ; \ d272 : testA cnt COG@ 1 a_delay1 cnt COG@ swap - d272 - . ; : testB cnt COG@ 9 a_delay cnt COG@ swap - d272 - . ; : testC cnt COG@ d100 a_delay1 cnt COG@ swap - d272 - . ; : testD cnt COG@ d108 a_delay cnt COG@ swap - d272 - . ; : testE cnt COG@ d1000 a_delay1 cnt COG@ swap - d272 - . ; : testF cnt COG@ d1008 a_delay cnt COG@ swap - d272 - . ; { \ ( n1 -- ) n1:delay-time[usec] fl build_BootOpt :rasm sub $C_stTOS , # 8 __1 jmpret __delay_ret , # __delay djnz $C_stTOS , # __1 spop jexit \ Delay 72ticks __delay mov cnt , # d59 add cnt , cnt waitcnt cnt , # 0 __delay_ret ret ;asm a_delay \ ( n1 -- ) n1:delay-time[usec] fl build_BootOpt :rasm __1 jmpret __delay_ret , # __delay djnz $C_stTOS , # __1 spop jexit \ Delay 72ticks __delay mov cnt , # d59 add cnt , cnt waitcnt cnt , # 0 __delay_ret ret ;asm a_delay1 }
Result below;
Prop0 Cog6 ok testA testB 848 752 Prop0 Cog6 ok testC testD 8640 8672 Prop0 Cog6 ok testE testF 80640 80672 Prop0 Cog6 ok
Difference between a_delay and a_delay1 is "sub $C_stTOS , # 8".
Result about testA/testB might be short delay.
testD is bigger than testC. (testF is bigger than testE)
What is 32ticks-delay?
Does forth-kernel cause?
I have question about cnt.
you wrote below;
mov cnt, #5{14} ' minimal advance (to avoid full range delay) add cnt, cnt ' current time waitcnt cnt, #0 ' run-through
cnt register is read-only on manual.
My understanding;
[mov cnt, #5] use writable register
[add cnt, cnt] first cnt writable register, second cnt readable register
[waitcnt cnt, #0] compare cnt[readable register] and cnt[writable register]
Is this correct?
And this using way is garanteed?
Always no problem?
mov shadow[cnt], #5{14} ' minimal advance (to avoid full range delay) add shadow[cnt], cnt ' current time waitcnt shadow[cnt], #0 ' run-through
which is the equivalent tomov tmp, #5{14} ' minimal advance (to avoid full range delay) add tmp, cnt ' current time waitcnt tmp, #0 ' run-through
And yes, this is guaranteed to work. Just a shortcut when you run out of normal registers.I understand about cnt.
I had been many problem during writing forth-code.
I made summary a little bit. Actually, a lot of problem by code's mistake.
I made summary about assembler_word's quetion.
My procedure is incorrect?
Hey! That's a good idea to do this. I'll try this out and see how far I get.
One thing I notice is in the "Caution" section. The assembler works on the top stack item, I think because this optimized in the prop architecture, this is fastest. Including code to use more stack items would be slower and begins to cost more in code space than it gains. Since we're using assembler, the need is "fastest and smallest".
If we need to leave more than one item on the stack, we might not have to store these in hub ram. I think we can just make additional assembler routines and call them in sequence in higher level forth macro, this might be faster than hub access. This would mean it puts responsibility for handling this efficiently on the designer, which is the usual trade off in forth. But I haven't used this yet, so I'm not sure whether my explanation is correct.
But LED is blinking at dark.
Why does LED still on?
My code is wrong?
http://youtu.be/duV-ZEEjIj0
i think when when you reverse bias the diode, there is voltage on it. when you read the diode, the voltage falls. maybe the falling reverse is the same as rising forward, just weaker?
need comment from somebody smart
I re-wrote LED_sensor code.
My code is wrong?