Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 03:44 19 May 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : (MM) D/A converter

     Page 1 of 3    
Author Message
Talbit
Senior Member

Joined: 07/06/2011
Location: Australia
Posts: 210
Posted: 09:05pm 29 Dec 2012
Copy link to clipboard 
Print this post

Gents,
I'm working on a new project for the New Year. Don't ask - all will be revealed if it works!
I have a zillion hex numbers I want to run through a Futerlec SPI 12 bit DAC mini board (MINIDAC)

http://www.futurlec.com/Mini_DAC.shtml

Here's an example...

1EE
1F3
1FF
20D
212
20B
1FD
1F5
1F5
1F9
1FE
202
207
209
208
200
1F4
1E9
1E8
1F1
205
215
219
20B
1F6
1E4

My plan is to load all the hex numbers I have onto an SD card on my PC and get the MM to read each one in sequence and output the number through SPI to the SPI DAC mini board at a rate of about 50 per second.
There are too many numbers to load into the MM ram so I need to pick off each number in sequence from the SD card.
Is it feasible, if so how?
I'm lazy - please help
Talbit
Talbit
 
paceman
Guru

Joined: 07/10/2011
Location: Australia
Posts: 1329
Posted: 10:21pm 29 Dec 2012
Copy link to clipboard 
Print this post

Hi Trevor,

I'll have a go at answering the easy part of this - one amateur to another - no guarantees! The SPI stuff for the MINIDAC board will be pretty specific but there are other SPI examples in the MMBasic library and in CG's download manual for the CGCOLORMAX and CGMMSTICK

The easy part (i.e. the non-SPI part) should be pretty straight forward assuming you don't want to do too much else while you're doing the B:read/SPIwrite stuff. I reckon MMBasic should be quick enough.

1. Open the file and leave it open until you read the end-of-file (EOF).
2. Use the SETTICK command to give you the timing interrupts at 20ms i.e. 50/sec. and the SETTICK target will be your read/write routine.
3. Do some other useful program stuff.
4. The interrupt target routine will do the reading and writing
5. Program drops out of read/write loop; disable interrupt and close file.
--------------------
OPEN "B:filename" FOR INPUT AS #1
SETTICK 20,target.....i.e. the read/write routine label
DO WHILE NOT EOF......better check syntax of this
.
.Other program stuff
.
LOOP
SETTICK 0,0
CLOSE #1

target: INPUT #1,variable
Do all the SPI write stuff.....someone else's input required here!
IRETURN
-------------------------

Have fun with the SPI stuff

Greg
Edited by paceman 2012-12-31
 
MicroBlocks

Guru

Joined: 12/05/2012
Location: Thailand
Posts: 2209
Posted: 10:59pm 29 Dec 2012
Copy link to clipboard 
Print this post

A text file with all the numbers in it should probably work.
Maybe put 50 values in one line and fixed width.
Like this:
1EE1F31FF200.............21920B1F61E4

'You open the file for INPUT with
OPEN "values.txt" FOR INPUT AS #1
'As long as the file has values
DO WHILE NOT EOF(1)
'read a line of text
LINE INPUT #1, values$
'loop through the values
FOR pos = 1 TO 150 STEP 3
'extracting them one by one from the string
value$ = MID$(values$,pos,3)
'convert value$ if needed
'output it to the SPI
NEXT
LOOP
CLOSE #1

This will do the job without any control about timing.
If you need exactly 50 per second you will need to use a timer and interrupt.
If timing is not very critical you could even get away with a pause in the main loop. :)

I think a Timer interrupt should work but as it has a lowest priority it might get off target, it is the simplest way to do it so it is the best place to start.
You setup a timer every 20 millisecond with SETTICK 20, TargetRoutine

If this does not give an exact enough interrupt you would probably need to make something that gives a pulse on a pin. Pin 1 has the highest priority and pin 29 the lowest. You can use this command:
SETPIN pin, cfg , target

The exact timing will force you to use a buffer, you don't want to do file access while serving a interrupt.
To do that you would need the main program to fill that buffer, so instead of the above program where it splits the values$ with FOR loop you would need to place that string into a buffer.
A circular buffer is the simplest.
You create a buffer by using a array.
maybe one that has only ten elements is already enough.
You fill that array with the main program and read from it when servicing the timer interrupt.
You need to do so administrative work to prevent writing to an element in the index that is not processed yet and a way to tell if there are unprocessed values left in the array.
A circular buffer will use two variables: a head and a tail.
You put new values at the tail position and read from the head position.
When you do that you increase the value of that variable to point to the next position in the array.
You also need to check if head or tail is within the arrays boundaries.
An easy way to prevent values to be overwritten or read when it is empty is to use a counter variable that counts how many values are stored in the array.

For that circular buffer you need three functions:
InitBuffer
ReadFromBuffer
WriteToBuffer

Initbuffer will setup the array and initialise the three variables needed for administrative work. All the variable will need to be global as you need them both in the main loop and in the timer interrupt routine.
Dim Buffer$(10)
Capacity = 10
Counter = 0
Head = 0
Tail = 0
The last three will need to be set in the InitBuffer to reinitialise the buffer:

ReadfromBuffer first checks if there is a value available by checking the Counter.
If that is higher then zero a value is present at the head position.
If Counter > 0 then
'You then take that value
value$ = Buffer$(head)
'increase the Head value
Head = Head + 1
'check if the Head is within bounds of the array
IF Head > Capacity THEN head = 0
'decrease the counter
Counter = Counter + 1
'return from the function

WriteToBuffer first checks if there is room in the array by checking the Counter.
If that value is lower then Capacity a value can be stored at the Tail position.

IF Counter < Capacity then
'You store the value at that position
Buffer$(Tail) = value$
'Increase the Tail position
Tail = Tail + 1
'Check if the Tail is within bounds of the array
IF Tail > Capacity then Tail = 0
'Increase the counter
Counter = Counter + 1
'return from the function


Just some ideas to get you started. There are still more conditions that need to be tested.


Edited by TZAdvantage 2012-12-31
Microblocks. Build with logic.
 
MOBI
Guru

Joined: 02/12/2012
Location: Australia
Posts: 819
Posted: 11:34pm 29 Dec 2012
Copy link to clipboard 
Print this post

Geez, now that's what I call a well presented "bit" of advice.

I can't wait to see where all this is leading as I have often toyed with the same idea. I've done heaps of a to d but not much of the reverse. The possibilities are many. The last lot I did was in 1969 in voice crypto on HMAS Vendetta in Vietnam.

David M

Edited by MOBI 2012-12-31
David M.
 
Talbit
Senior Member

Joined: 07/06/2011
Location: Australia
Posts: 210
Posted: 12:01am 30 Dec 2012
Copy link to clipboard 
Print this post

Thank you gentlemen!!!
Great answers. I'll need some time in the New Year to get it going.
I'm still waiting for the DACMINI boards to arrive from Futurlec.
Boy, are they slow!
Anyway, your answers deserve a run down on what I'm trying to do. I have in my possession a copy of the first seismogram of the Apollo 11 moonwalk. It was recorded of a drum recorder in real time. The original is at the Lamont Doherty University in the U.S. I managed to make contact with a fellow who is/was involved in the resurrection of the original data. It has been digitised and archived and is available for anyone to play with. If you get the data you can plug it into an Excel spread sheet and graph it. All very good but a bit too pristine! I have in my possession a seismic drum recorder, the same as the one that was used to make the first seismogram. If I can get the individual numbers into the DAC then I should be able to place it onto the drum recorder. The timing shouldn't be a problem. I can artificially add the time marks to match the original. The data is time tagged but I need to match it up with the original time marks on the original seismogram.
Thanks again.
Regards
Talbit
Talbit
 
panky

Guru

Joined: 02/10/2012
Location: Australia
Posts: 1099
Posted: 12:55am 30 Dec 2012
Copy link to clipboard 
Print this post

Hi Talbit,

One problem you may come across is that when you read in data, a character at a time, if you get a hex1A, it will be interpretted as an EOF.

I have not been able to find a reliable way of reading and writing 8 bit bytes and getting access to the whole 256 possible characters short of some multi character mangling/manipulation.

There are also some issues with CR and LF. Also, I think that there are differences between DOS MM and Colour MM Basic in this respect.

From what little I can glean from Geoff's source (due to my limitations ;-) ), I think that the MicroChip file handling routines do not keep a file length parameter in the directory, rather they just rely on an embedded EOF character or sequence - others may be able to expand on this for you.

Cheers,
Panky.

... almost all of the Maximites, the MicromMites, the MM Extremes, the ArmMites, the PicoMite and loving it!
 
MOBI
Guru

Joined: 02/12/2012
Location: Australia
Posts: 819
Posted: 01:42am 30 Dec 2012
Copy link to clipboard 
Print this post

  panky said  if you get a hex1A, it will be interpretted as an EOF.


Would it be possible to first determine the length of the file and then read in the data without doing a EOF check and instead use a byte counter?

Just wondering.

David M
David M.
 
Talbit
Senior Member

Joined: 07/06/2011
Location: Australia
Posts: 210
Posted: 02:24am 30 Dec 2012
Copy link to clipboard 
Print this post

Having no EOF might be better if it's going to pose a problem. So a counter might be a serious option. Besides, the astronauts were back inside the LEM before the data stops! But there is also a stretch of data when they took off from the surface. That made a mess of the seismic trace let me tell you !!!
Talbit
Talbit
 
paceman
Guru

Joined: 07/10/2011
Location: Australia
Posts: 1329
Posted: 02:27am 30 Dec 2012
Copy link to clipboard 
Print this post

  Talbit said   Thank you gentlemen!!!
Great answers. I'll need some time in the New Year to get it going.
I'm still waiting for the DACMINI boards to arrive from Futurlec.
Boy, are they slow!


Hi Trevor,
See, I told you I was an amateur!

Re Futurlec: I've had a few orders from them and they've mostly taken 2-3 weeks to Melbourne - it comes from Thailand. The biggest holdup is when there's an item not in stock, as always, and they don't tell you that that's the case (fortunately most stuff I've ordered has been in stock). If you send a reply e-mail to them (to their order acknowledgement e-mail) they are quick to respond and will let you know if anything's on back-order. They'll ship non back-order items immediately too if you ask - at least they did for me.

Greg
 
MicroBlocks

Guru

Joined: 12/05/2012
Location: Thailand
Posts: 2209
Posted: 02:52am 30 Dec 2012
Copy link to clipboard 
Print this post

  Talbit said   Having no EOF might be better if it's going to pose a problem. So a counter might be a serious option.
Talbit


Don't think about doing that unless you run into that problem. Programming languages are presumed to be bug free until it is proven that it is not.

If you follow my suggestion of using a text file and use line input to read line by line you would have no problem with reading the file.

As always you should built in some error detection and ability to recover from that.
Using error trapping and checking the values you read should be sufficient.

A bit of defensive programming goes a long way so if you for instance expect to read a line that contains 150 bytes a check on that before continuing with the next step would prevent errors.
Anywhere you can put in a check (guard code) to prevent problems further up in the code is making your software more resilient.
Edited by TZAdvantage 2012-12-31
Microblocks. Build with logic.
 
panky

Guru

Joined: 02/10/2012
Location: Australia
Posts: 1099
Posted: 12:30pm 30 Dec 2012
Copy link to clipboard 
Print this post

  MOBI said  
  panky said  if you get a hex1A, it will be interpretted as an EOF.


Would it be possible to first determine the length of the file and then read in the data without doing a EOF check and instead use a byte counter?


David,

As far as I can determine from the source code, the MicroChip file I/O routines that Geoff uses do not make any use of a file length value. The value must be there somewhere as it is visable when you read the SD card in a PC. I'm not familiar enough with the FAT file structure on an SD card to add anything further however I plan to do some research and will post anything further I can glean.

Regards, Doug.
... almost all of the Maximites, the MicromMites, the MM Extremes, the ArmMites, the PicoMite and loving it!
 
MOBI
Guru

Joined: 02/12/2012
Location: Australia
Posts: 819
Posted: 12:50pm 30 Dec 2012
Copy link to clipboard 
Print this post


  panky said  As far as I can determine from the source code, the MicroChip file I/O routines that Geoff uses do not make any use of a file length value


  Quote  DO WHILE NOT EOF(1)


In other Basic languages etc there is a file length instruction, I can't speak for MM because I don't have one...yet...(I am going to have to or risk being left in the cold..dark..)

What I was thinking was to....belay that. What format is the seismic data in? e.g. is it binary or text. If it is text, then you should not be troubled by a randon eof byte and should be able to count the bytes one at a time until valid eof is encountered. Then load in the bytes, say, to an array. I don't know how big an array the MM can handle. Just putting some thoughts into the ring.

David MEdited by MOBI 2012-12-31
David M.
 
Talbit
Senior Member

Joined: 07/06/2011
Location: Australia
Posts: 210
Posted: 03:44pm 30 Dec 2012
Copy link to clipboard 
Print this post

Gents,
The data came to me in the form of 17 files XXXX.csv
I can send you one if you like.
I opened the file with Excel. It can't load it all in because of the size limitations of Excel (the later versions can)
I highlight the actual seismic Z component data (the vertical seismometer) which is 3 text digits per sample then I graph it. It shows the seismic signal.
I then ran it through a HEX converter in Excel and I have the same numbers in hex. I might need it in this form for the SPI DAC but won't know until I get the boards.
Back to the MM. I don't think the array would be big enough to take all the data. There are about 180,000 samples per file. That's why I need to read it directly from the SD card. It needs to read all of the data in sequence without any breaks. The data probably goes for about 24 hours but it might be longer.
So my first task is to load all of the data (Number or HEX) onto the SD card (using the PC)in one big file. I don't know what type of file that should be.
Regards
Trevor
Talbit
Talbit
 
vk4tec

Senior Member

Joined: 24/03/2012
Location: Australia
Posts: 239
Posted: 03:50pm 30 Dec 2012
Copy link to clipboard 
Print this post

When I found that excel ( old version was limited to 65000 lines )

I went looking to LINUX

I put all my data into an MySQL table

I then use perl GD:GRAPH to make me nice online web graphs

- Andrew -
Andrew Rich VK4TEC
www.tech-software.net
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 5923
Posted: 02:06pm 31 Dec 2012
Copy link to clipboard 
Print this post

  Talbit said   Gents,
The data came to me in the form of 17 files XXXX.csv

Back to the MM. I don't think the array would be big enough to take all the data. There are about 180,000 samples per file. That's why I need to read it directly from the SD card. It needs to read all of the data in sequence without any breaks. The data probably goes for about 24 hours but it might be longer.
So my first task is to load all of the data (Number or HEX) onto the SD card (using the PC)in one big file. I don't know what type of file that should be.
Regards
Trevor
Talbit


My choice would be to produce a big text file in the correct format on the PC and feed it slowly to the maximite.
That leaves the maximite to do the timing and feeding to the DA.

It would be fairly simple to write a program in Liberty Basic to feed the file(s) out the serial port.

Jim

VK7JH
MMedit   MMBasic Help
 
MOBI
Guru

Joined: 02/12/2012
Location: Australia
Posts: 819
Posted: 02:48pm 31 Dec 2012
Copy link to clipboard 
Print this post

  Quote  My choice would be to produce a big text file in the correct format on the PC and feed it slowly to the maximite.
That leaves the maximite to do the timing and feeding to the DA.


I agree, but wouldn't it be just as easy to put the big text file(s) on the SD and not bother with the PC after that? Or is reading the SD too slow for the required DAC timing?

David M.
David M.
 
Talbit
Senior Member

Joined: 07/06/2011
Location: Australia
Posts: 210
Posted: 09:10pm 31 Dec 2012
Copy link to clipboard 
Print this post

Thanks gents for all the advice. I'm soaking it all up and will get onto it very soon.
Yes I'd rather just run the whole shebang using the MM with SD card and the Futurlec DAC.
Trevor
Talbit
 
vk4tec

Senior Member

Joined: 24/03/2012
Location: Australia
Posts: 239
Posted: 10:19pm 31 Dec 2012
Copy link to clipboard 
Print this post

I am curious, why do you need to go back to voltages ?

- Andrew -
Andrew Rich VK4TEC
www.tech-software.net
 
Talbit
Senior Member

Joined: 07/06/2011
Location: Australia
Posts: 210
Posted: 11:58am 01 Jan 2013
Copy link to clipboard 
Print this post

Andrew,
Please - be as curious as you like!
I need to convert the digital data to voltages to drive an amplifier and then the pen on the drum recorder. It's all analogue. Once I've got the SD card to read each individual number and D to A convert it, I will just feed it into the amp then the pen (hopefully) will recreate the original seismogram.
All pretty straight forward I hope. I'm done with my clocks for now so I'll start on getting the SD card part going. I recon if I can get the MM to pick off the number from the SD and print it on the screen one at a time then I'm at least halfway there.
These days, seismic systems are mostly digital with fancy earthquake pickers etc. But there are still these old style drum recorders in use around the world. The Rabaul Volcano Observatory in PNG (I've spent quite a few years there) still use them as do some people in the states. It's old fashion stuff but it does give you real time data because usually it's using real time analogue telemetry. Digital does have some inherent delays so the time stamping needs to be does at the source. Timing is critical in seismic work. Also when you lay out the drum recorder sheet on a table you can see the whole 24 hours activity at a glance.
I'll try and find a happy snap of a system I built for a volcano in PNG showing the drum recorder.
Trevor
Talbit
 
Talbit
Senior Member

Joined: 07/06/2011
Location: Australia
Posts: 210
Posted: 01:37am 07 Jan 2013
Copy link to clipboard 
Print this post

Gents,
The project so far...
I still haven't received the DAC boards from Futurlec so can't get the SPI going yet. But from the MCP4922 data sheet it appears as though I need to get my original data and turn it into straight binary. The original is in ASCII. That shouldn't be too much of a problem. Then I have to get the data and add 4 control bits for the board. I need to arrange it so there are 4 control bits (MSB) and 12 data bits (LSB), making a straight 16 bit binary word.
I've stuck with the KISS principal and come up with this...
' Apollo 11 First Lunar Seismogram, July 1969
' Original data supplied by Yosio Nakamura Institute for Geophysics
' University of Texas at Austin[yosio@utig.ig.utexas.edu]
' Stored on Maximite SD card
' Trevor Dalziell January 2013
'
' Data to the board is 16 bit straight binary. Only 1 of the DAC amplifiers is used
' Bits 0-11 are data from the Maximite.
' Bit 12 is Output Power Down Control bit. Set to 1
' Bit 13 is Output Gain Select bit. Set to 1. Needs experimenting.
' Bit 14 Vref Input Buffer Control. Set to 1. Needs experimenting.
' Bit 15 selects which DAC to write to. Set to 0. Writes to DAC "A"

'____ SPI Setup ____

' Pin 12 = Rx
' Pin 13 = Tx
' Pin 14 = Enable (Active low)
' Pin 15 = Clock (Active low)


Pin(14) = 1
Pin(15) = 1
Setpin 12,2 'Input
Setpin 13,8 'Digital output - Data
Setpin 14,8 'Digital output - Enable
Setpin 15,8 'Digital output - Clock


OPEN "Apollo.txt" FOR INPUT AS #1

DO

LINE INPUT #1, values$

PRINT values$

'Seismic$= Write command AND values$ 'Needs work here.

Pin(14)=0
a = SPI(12,13,15,val(values$),H,3,12) 'High speed, Mode 3, 12 bits for now. 16 bit Control and data later.
Pin(14)=1

PAUSE 20

LOOP

CLOSE #1


All it does is print out each line of data as it picks it from the SD card. It then does a dummy SPI which I presume will work (after a lot more work!) It crashes when it sees a bit of data that is too large but I should be able to get around that when I add some error checking, or maybe tidy up the original data. It's not error free.
I haven't bothered with EOF.
Trevor
Talbit
 
     Page 1 of 3    
Print this page
© JAQ Software 2024