
Originally Posted by
enigma
I`m reading in data from an A/D conversion approx once a second. I need to store these to a total of 20 readings in a way which overwrites the oldest reading as each new reading is added. Should one data element exceed a limit between two values I need to send the stored data as serial output consisting of the 10 values prior to the event and also the 10 values after the event.
Pete,
You are looking for a ring or circular buffer. Sayzer gave you a bit of code to look at. Here is another approach.
Code:
;-------------------------
; PIC16F877A
High_Limit CON 196
Low_Limit CON 64
ADC_Value VAR BYTE ; Latest ADC Reading
Buff_Pointer VAR BYTE ; Current spot in Buffer
Buff_Len VAR BYTE ; Number of Values in Buffer
History VAR BYTE[10] ; Last 10 ADC Readings
Remaining_Vals VAR BYTE ; Number of Values left to send
Counter VAR BYTE
; Initialize values
Remaining_Vals = 0
Buff_Pointer = 0
Buff_Len = 0
Main:
ADCIN 0,ADC_Value
IF (ADC_Value > High_Limit) OR (ADC_Value < Low_Limit) THEN ; Check Limits
; Out-of-limits
IF Buff_Len > 0 THEN ;There is something in Buffer
; Send out Contents of Buffer Before Current Value
FOR Counter = 0 TO Buff_Len - 1
IF Buff_Pointer + Counter > 9 THEN
HSEROUT [History(Buff_Pointer + Counter - 10)] ; Output Value
ELSE
HSEROUT [History(Buff_Pointer + Counter)] ; Output Value
ENDIF
NEXT Counter
Buff_Len = 0 ; Reset Buffer
Buff_Pointer = 0
ENDIF
HSEROUT [ADC_Value] ; Send out current Value
Remaining_Vals = 10 ; Set count so next 10 Values will be sent
ELSE
' Within Limits
IF Remaining_Vals > 0 THEN ; post out-of-limit values to be sent
HSEROUT [ADC_Value] ; Send out current Value
Remaining_Vals = Remaining_Vals - 1
ELSE
;Add Value to Buffer
Buff_Len = Buff_Len + 1
IF Buff_Len = 11 THEN
Buff_Len = 10
Buff_Pointer = Buff_Pointer + 1 ; Move Pointer to 2nd oldest
If Buff_Pointer = 10 THEN Buff_Pointer = 0 ; Wrap Around
ENDIF
IF Buff_Pointer + (Buff_Len - 1) > 9 THEN
History(Buff_Pointer + Buff_Len - 11) = ADC_Value
ELSE
History(Buff_Pointer + Buff_Len - 1) = ADC_Value
ENDIF
ENDIF
ENDIF
GOTO Main
It will check each reading. If it is out of limits, it will send the contents of the buffer (which could be less than 10 if the out of limits occurs before 10 readings), then send the current ADC readings, then send the next 10 readings.
If, while sending the 10 readings after an out of limit condition, it will reset the counter and send 10 more readings.
It is set up to use HSEROUT, so you will have to change that as neede to suit your purpose. Also, you will need to setup the ADCIN as well.
You should have plenty of material to get this going.
HTH,
SteveB
Bookmarks