Data logging with Atmel Flash

Post details of your projects here.
Post Reply
YahooArchive
Posts: 1463
Joined: Fri Oct 19, 2012 5:11 am

Data logging with Atmel Flash

Post by YahooArchive » Thu Dec 06, 2012 5:16 pm

Attached are two little programs that collect two analog votages and stores them
for later readout. The first program collects and the second reads them out. I
am using it at a sample rate of approx one thousand pairs per sec.

Hopefully this might be of help to someone. I beat my head against the wall
until Bruce pointed out the errata at the end of the atmel data sheet. Do not
use chip erase!!!!

Regards.
Howard



----------


'THIS PROGRAM READS TWO ANALOG VOLTAGES CONNECTED AT AD(1) AND AD(4) ON THE
ARMMITE BOARD
'AND WRITES THEM TO AN ATMEL DATAFLASH MEMORY (AT45DB161D)

' MEMORY IS CONNECTED THUSLY: IO(2) AS CHIP SELECT,IO(4) AS CLOCK,
' IO(5) AS DATA OUT TO MEMORY, AND I0(6) AS DATA IN FROM MEMORY

'TO MAKE ADDRESSING SIMPLE, ONLY A SMALL FRACTION OF THE MEMORY IS USED..UP TO
64 PAGES
'IT CAN STORE 16,000 PAIRS OF 8 BIT VOLTAGES AT A RATE OF APROX 1,000 SAMPLE
PAIRS/SEC
'THE VOLTAGES ARE each READ 8 TIMES AND AVERAGED, THEN SHIFTED DOWN TO 8 BITS.

'VOLT1 GOES INTO THE BOTTOM OF THE PAGE, BYTES 1 THRU 250
'VOLT2 GOES INTO THE TOP, BYTES 256 THRU 505

'A SEPERATE PROGRAM "DATALOG_READ" IS USED TO READ OUT THE DATA VIA USB INTO THE
PC
'RUNNING BASICtools. I THEN CUT AND PASTE INTO EXCEL

'THE CODE IS NOT VERY ELEGANT (I AM 68 YEARS OLD AND CAN USE GOTO IF I WANT),
BUT IT WORKS

'MANY THANKS TO BRUCE EISENHARD AT CORIDIUM FOR HIS PATIENT ASSISTANCE. BEWARE
USING CHIP ERASE
'THE ATMEL CHIP. THAT COST ME MANY HOURS OF GRIEF BEFORE BRUCE POINTED OUT THE
ERRATA ON THE DATSHEET.



#define SPIpreSample
#include "SPI.bas"


DIM VOLT11 AS INTEGER ' STORES THE EIGHT READINGS OF VOLT1 AND VOLT2
DIM VOLT12 AS INTEGER
DIM VOLT13 AS INTEGER
DIM VOLT14 AS INTEGER
DIM VOLT15 AS INTEGER
DIM VOLT16 AS INTEGER
DIM VOLT17 AS INTEGER
DIM VOLT18 AS INTEGER
DIM VOLT21 AS INTEGER
DIM VOLT22 AS INTEGER
DIM VOLT23 AS INTEGER
DIM VOLT24 AS INTEGER
DIM VOLT25 AS INTEGER
DIM VOLT26 AS INTEGER
DIM VOLT27 AS INTEGER
DIM VOLT28 AS INTEGER
DIM VOLT1 AS INTEGER
DIM VOLT2 AS INTEGER

DIM COUNT AS INTEGER
DIM PAGE AS INTEGER ' PAGE NUMBER IN MEMORY
DIM PGADD AS INTEGER 'PAGE ADDRESS =FOUR TIMES PAGE NUMBER
DIM ODDPAGE AS INTEGER ' 1 IF PAGE OR BUFFER NUMBER IS ODD, ZERO
IF EVEN
DIM WHICHVOLT AS INTEGER ' THIS IS 0 FOR V1 , 1 FOR V2

DIM FIRSTBYTE AS INTEGER 'THESE ARE THE BYTES IN THE SPI OUTPUT
STRINGS
DIM SECONDBYTE AS INTEGER
DIM THIRDBYTE AS INTEGER

DIM VALUE AS INTEGER 'THIS IS WHAT IS WRITTEN TO MEMORY


'****************HERE ARE THE SUBROUTINES*********************

SUB READ_AND_AVERAGE ' READ BOTH CHANNELS 8 TIMES AND AVERAGE
VOLT11=AD(1)>>3
VOLT21=AD(4)>>3
VOLT12=AD(1)>>3
VOLT22=AD(4)>>3
VOLT13=AD(1)>>3
VOLT14=AD(1)>>3
VOLT24=AD(4)>>3
VOLT15=AD(1)>>3
VOLT25=AD(4)>>3
VOLT16=AD(1)>>3
VOLT26=AD(4)>>3
VOLT17=AD(1)>>3
VOLT27=AD(4)>>3
VOLT18=AD(1)>>3
VOLT28=AD(4)>>3
VOLT1=(VOLT11+VOLT12+VOLT13+VOLT14+VOLT15+VOLT16+VOLT17+VOLT18)>>8
VOLT2=(VOLT21+VOLT22+VOLT23+VOLT24+VOLT25+VOLT26+VOLT27+VOLT28)>>8
ENDSUB




SUB WRITE_BUFF ' WRITES VALUE INTO BUFFER
IF ODDPAGE=1 THEN FIRSTBYTE=$84 '$84 WRITES TO BUFFER ONE
IF ODDPAGE=0 THEN FIRSTBYTE=$87 '$87 WRITES TO BUFFER TWO
IF WHICHVOLT=0 THEN THIRDBYTE=128 'PUTS ZERO INTO LSB WHICH IS BIT 8 OF BYTE
IF WHICHVOLT=1 THEN THIRDBYTE=129
DIM outstring(5) AS STRING
outstring=chr(FIRSTBYTE)+chr($DC)+chr(THIRDBYTE)+chr(COUNT)+chr(VALUE)
SPIOUT (2,4,5,0,5,outstring)
OUT(2)=1
ENDSUB



SUB TURN_PAGE 'FIRST SAVE THE BUFFER TO MEMORY WITH BUILT IN ERASE
IF ODDPAGE=1 THEN FIRSTBYTE=$83 '$83 MOVES BUFFER ONE
IF ODDPAGE=0 THEN FIRSTBYTE=$86 '$86 MOVES BUTTER TWO
DIM outstring(4) AS STRING
outstring=chr(FIRSTBYTE)+chr(128)+chr(PGADD)+chr($DC)
SPIOUT (2,4,5,0,4,outstring)
OUT(2)=1

IF PAGE=40 THEN ' THIS SETS HOW MANY PAGES TO SAVE***************
OUT(15)=1 ' TURN OFF LED
END
ENDIF


PAGE=PAGE+1
COUNT=0
PGADD=PAGE<<2
ODDPAGE=PAGE AND 1
ENDSUB


'*********************HERE IS THE MAIN PROGRAM**************


MAIN: ' AND AWAY WE GO

DIR(15)=1 ' LED, O IS ON , 1 IS OFF
DIR(2)=1 'CHIP SELECT FOR DATAFLASH
DIR(4)=1 'CLOCK PIN FOR DATAFLASH
DIR(5)=1 'DATA OUT PIN TO DATAFLASH
DIR(6)=0 'DATA INPUT PIN FROM DATAFLASH

COUNT=1 'INITIALIZE
PAGE=1
PGADD=PAGE<<2
ODDPAGE=PAGE AND 1


OUT(15)=0 'THREE BLINKS OF LED BEFORE START
WAIT(500)
OUT(15)=1
WAIT(500)

OUT(15)=0
WAIT(500)
OUT(15)=1
WAIT(500)

OUT(15)=0
WAIT(500)
OUT(15)=1
WAIT(500)



' ******************THIS IS THE MAIN LOOP*****************

BEGIN:

OUT(15)=0 ' TURN ON LED FOR DURATION OF MEASUREMENT

WAIT(1) 'THIS SETS THE SAMPLE RATE*****************************

GOSUB READ_AND_AVERAGE

WHICHVOLT=0
VALUE=VOLT1
GOSUB WRITE_BUFF


WHICHVOLT=1
VALUE=VOLT2
GOSUB WRITE_BUFF

IF COUNT=250 THEN GOSUB TURN_PAGE
COUNT=COUNT+1
GOTO BEGIN


----------


'THIS IS DATALOG_READOUT
'THIS PROGRAM READ THE DATA WRITTEN BY DATALOG_RECORD



'I COULDNT MANAGE TO READ MAIN MEMORY DIRECTLY, SO I MOVE THE PAGES
'INTO THE BUFFERS AND READ THEM OUT FROM THERE.


#define SPIpreSample 'THIS IS REQUIRED FOR THE ATMEL CHIPS TIMING
#include "SPI.bas"



DIM VOLT1 AS INTEGER
DIM VOLT2 AS INTEGER

DIM COUNT AS INTEGER
DIM PAGE AS INTEGER ' PAGE NUMBER IN MEMORY
DIM PGADD AS INTEGER 'PAGE ADDRESS =FOUR TIMES PAGE NUMBER
DIM ODDPAGE AS INTEGER ' 1 IF ODD PAGE OR BUFFER
DIM WHICHVOLT AS INTEGER ' THIS IS 0 FOR V1 1 FOR V2

DIM FIRSTBYTE AS INTEGER ' USED IN THE SPI OUTSTRINGS
DIM SECONDBYTE AS INTEGER
DIM THIRDBYTE AS INTEGER

DIM VALUE AS INTEGER 'THIS IS WHAT IS READ FROM MEMORY


'***************** HERE ARE THE SUBROUTINES****************************



SUB MOVE_MEM_TO_BUFF
IF ODDPAGE=1 THEN FIRSTBYTE=$53 '$53 MOVE MAIN MEM TO BUFFER ONE
IF ODDPAGE=0 THEN FIRSTBYTE=$55 ' $55 MOVE MAIN MEM TO BUFFER TWO
DIM outstring(4) AS STRING
outstring=chr(FIRSTBYTE)+chr(128)+chr(PGADD)+chr($DC)
SPIOUT (2,4,5,0,4,outstring)
WAIT(1)
ENDSUB



SUB READ_BUFF 'SET WHICHVOLT BEFORE CALLING
IF WHICHVOLT=0 THEN THIRDBYTE=128 'THIS PUTS A ZERO AT BIT9 OF THE LOCATION
AND A 1 IN A DONT CARE LOCATION
IF WHICHVOLT=1 THEN THIRDBYTE=129 'THIS PUTS A ONE AT BIT 9
IF ODDPAGE=1 THEN FIRSTBYTE=$D4 'THIS IS $D4 TO READ BUFFER ONE
IF ODDPAGE=0 THEN FIRSTBYTE=$D6 'THIS IS $D6 TO READ BUFFER TWO
DIM outstring(5) AS STRING
DIM instring(10) AS STRING
outstring=chr(FIRSTBYTE)+chr($DC)+chr(THIRDBYTE)+chr(COUNT)+chr($DC) ' $DC IS A
DONT CARE BYTE
SPIIN(2,6,4,5,0,5,outstring,1,instring)
WAIT (1)
VALUE=instring(0)
ENDSUB


SUB TURN_PAGE
IF PAGE=40 THEN END ' THIS SETS HOW MANY PAGES TO READOUT*********************
PAGE=PAGE+1
COUNT=0
PGADD=PAGE<<2
ODDPAGE=PAGE AND 1
ENDSUB





'***************HERE IS THE MAIN***********************

MAIN: ' AND AWAY WE GO

DIR(15)=1 ' LED, O IS ON , 1 IS OFF
DIR(2)=1 'CHIP SELECT FOR MEMORY
DIR(4)=1 'CLOCK PIN FOR MEMORY
DIR(5)=1 'DATA OUT PIN TO MEMORY
DIR(6)=0 'DATA INPUT PIN FROM MEMORY



COUNT=1 'INITIALIZE
PAGE=1
PGADD=PAGE<<2 'SHIFT OVER SO LSB OF PAGE NUMER IS AT BIT 2 WHEN USED
THIRDBYTE
ODDPAGE=PAGE AND 1 'ZERO FOR EVEN NUMBERED PAGES AND ONE FOR ODD NUBERED


'****************THIS IS THE MAIN LOOP***************


BEGIN: 'THIS IS THE BEGINNING OF THE MAIN LOOP

GOSUB MOVE_MEM_TO_BUFF


WHICHVOLT=0 'VOLT1 IS IN THE LOWER 25O BYTES OF THE BUFFER
GOSUB READ_BUFF
VOLT1=VALUE

WHICHVOLT=1 'VOLT2 IS IN LOCATIONS 129 THRU 379
GOSUB READ_BUFF
VOLT2=VALUE

PRINT VOLT1 ,VOLT2, PAGE, COUNT

IF COUNT=250 THEN GOSUB TURN_PAGE
COUNT=COUNT+1
GOTO BEGIN



Post Reply