PDA

View Full Version : Logging ADC values to flash


brian
09-25-07, 03:25 PM
I would like to use my IsoPod V2 V0.6 to log battery voltage of an RC plane in flight. The IsoPod is being powered by the Battery Eliminator circuit on the speed controller, which cuts off the motor at 5V. I've tested a little autostart app that can detect if the IsoPod has been reset, and so far, it looks like the IsoPod stays alive through the whole motor run (a little surprising with the 5V cutoff), but to be safe, I would like to log my voltage samples to flash. I plan to sample once per second, so I can get everything I need in less than 1000 samples.

Any recommendations on how to do this? Write to ram with a periodic SAVE-RAM? Can I write flash directly? Can't seem to find an example of this anywhere, other then the documentation regardinf SAVE-RAM. Can I safely do a SAVE-RAM from within an application?

brian
09-26-07, 08:00 PM
I think I have mostly answered my own question. The word EE! seems to be the ticket. It looks like I can define a variable as a pointer and increment it by two every time I want to store a new value. Example:

HEX 1800 EEERASE OK
HEX 1800 CONSTANT START_BUFFER EEWORD OK
( Data flash memory pointer for storing adc samples OK
VARIABLE PTR EEWORD OK
( Initialize buffer pointer OK
START_BUFFER PTR ! EEWORD OK
SAVE-RAM OK
HEX 1234 START_BUFFER EE! OK
START_BUFFER @ U. 1234 OK

My stored value does appear to be persistant across a power cycle, however, my PTR and START_BUFFER words were gone for some reason. I'm also putting these words into a larger app, and find that my the download hangs when it gets to START_BUFFER PTR ! . When I type this by hand, I find that it takes quite a long time to compile for some reason, and may be what's messing up the download.

One big gotcha BTW. You have to do the ERASE before writing new values. You can only program flash bits low. You have to use on ERASE to set them high again. If you are just poking various values into flash from the command line without an erase, the value starts to look weird. In fact in my case it eventually went to 0 and it took me a while to figure out what was going on. :)

nmitech
09-27-07, 09:52 AM
The example below will read ADC0 approx. one every second and store to User Data Flash. The green led will toggle each time the ADC0 is sampling and it will stay off when it reaches 1000 samples.

At anytime, you can look at the user data flash by enter,
\ HEX 1800 400 DUMP



SCRUB

HEX

1800 CONSTANT EE-START EEWORD \ start of user data flash
VARIABLE SAMPLE EEWORD

DECIMAL
LOOPINDEX CNT
70 CNT END EEWORD

MACHINE AD-SAMPLING EEWORD
ON-MACHINE AD-SAMPLING
APPEND-STATE GET-ADC0 EEWORD
APPEND-STATE SAMPLE-COUNT EEWORD

IN-STATE GET-ADC0
CONDITION
CNT COUNT
CAUSES
ADC0 ANALOGIN EE-START SAMPLE @ + EE!
SAMPLE 1+!
GRNLED OFF
THEN-STATE
SAMPLE-COUNT
TO-HAPPEN
IN-EE

IN-STATE SAMPLE-COUNT
CONDITION
CNT COUNT SAMPLE @ 1000 < AND
CAUSES
GRNLED ON
THEN-STATE
GET-ADC0
TO-HAPPEN
IN-EE

\ erase 1024 cells of data flash
\ each bank of data flash contains 256 cells
\ to store 1000 samples we need to use 4 banks
HEX
: EEER-4BANK
4 0 DO 1800 I 100 * + EEERASE LOOP
; EEWORD

DECIMAL
: MAIN
REDLED OFF
YELLED OFF
GRNLED ON
EEER-4BANK
0 SAMPLE !
CNT RESET
GET-ADC0 SET-STATE
EVERY 50000 CYCLES SCHEDULE-RUNS AD-SAMPLING
; EEWORD


HEX 3C00 AUTOSTART MAIN ( V0.60 AUTOSTART

SAVE-RAM

\ press reset or recycle the power to start

brian
09-27-07, 12:32 PM
Ok thanks. This is pretty close to what I have, except that the sampling is done inside the fisrt state of the led chase example from the downloads page. I definitely was not aware that EEERASE worked in 256 byte blocks. The Forth word html doc only seems to go to V5.0. Where is the EEERASE word documented?

I'm also a little confused by:

CAUSES
ADC0 ANALOGIN EE-START SAMPLE @ + EE!
SAMPLE 1+!

Since two bytes are being stored, why isn't the address offset incremented by two each time. Is it that EE! does not use a true byte address? Sorry, I'm a C programmer by trade, so I'm used to working with byte address pointers :) The Forth word document for EE! just says ( 16b addr --- ) for the arguments to EE! . Thanks for the info on the DUMP word. I should be able to see how the address alignment is working from that.

brian
09-27-07, 12:51 PM
Ok. I can see from the DUMP command that EE! seems to expect a word address. Thanks, I definitely had that wrong. I guess that makes sense. Makes sure that the values are alway properly word-aligned. Does EE! actually have to write a whole 256 byte block every time, or can it write just the single word? Also, The document says the 'delay' for this write is determined by EDP, but EDP is just a pointer into the flash, so I don't understand what that means. Just trying to get some idea how much time it takes to write each sample i.e. the max sample rate I can expect when doing this.

Thanks again for all the help.

nmitech
09-28-07, 10:18 AM
Does EE! actually have to write a whole 256 byte block every time, or can it write just the single word?
You don't have to write the whole page everytime. Only when you erase.


Just trying to get some idea how much time it takes to write each sample i.e. the max sample rate I can expect when doing this.


Here is the example on the downloadpage. You can use this to measure your sample time. The clockrate is 5Mhz based on the IsoMax system timer.


HEX
( Use 0C00 for '803,'805 . 1200 for '807s)
0C00 CONSTANT SYS_BASE EEWORD

( TimerC3 158 offset for newer IsoMax
( TimerD3 178 for V0.6 and older
SYS_BASE 178 + CONSTANT TMRD3_BASE EEWORD

TMRD3_BASE CONSTANT TMR_CMP1 EEWORD
TMRD3_BASE 5 + CONSTANT TMR_CNTR EEWORD

( Need a Time Offset, to adjust time before and after execution of test word
DECIMAL 28 CONSTANT T0 EEWORD

: T' ( i*x -- j*x n ) ' CFA
TMR_CNTR @ >R EXECUTE TMR_CNTR @ R> ( end start )
2DUP U< IF - TMR_CMP1 @ + ELSE - THEN T0 -
; EEWORD

ISOMAX-START


( Use on DUP
( Put initial value on stack to be dupped
( follow with T'
( Print result
( Drop original and dupped numbers.
( 1 T' DUP . DROP DROP

( Some other actual examples
( 1 2 T' + . DROP 8 OK
( 4 2 T' / . DROP 52 OK
( : X 4 2 / ; OK
( T' X . DROP 88 OK