how do i get a return array?
RS_Jim Posts: 1,713
I have the frollowing method:
PUB ADC_READ(packet) repeat x from 0 to ADC_CHANS if x < ADC_CHANS rawadc[x] := adc.read(x) ' read a channel else rawadc[x] := pinread(DIPSW) bytemove(@packet[x<<1], @rawadc[x], 2) ' transfer into packet
I can put a print statement after and all of the right values are in the array @packet but when I try to return the array I get a hex word that is all the same value for each member of the array. Hex 6A24 .
Looks to me like memory address it is definately not the analog value.
If you're passing an address to the method, you'll want to do it like this:
You're using @ with a value that is already a pointer. To use the pointer in Spin you use byte, word, or long -- depending on what is pointed to. In your case, you're saving words, so that's what I used. Note that we don't have to multiply x by 2 in this version because we're specifying a word.
I always prefix pointer variables with p_ to remind myself the variable is holding an address.
Thanks Jon, that is working. A question about your multi channel ADC method. how would you calibrate just 1 channel? By my calculations it takes 327 microseconds to calibrate 8 channels @ a 200MHz clock. I do not wish to spend that much time every time around my collection loop. I would like to see it be more like 1 channel around the loop. What do you think.
We can't always count on generic libraries to provide all the answers -- you may need to take a different approach.
Since you want to re-calibrate and read a pin, you could write an inline assembly routine that does the same work as the code in the Spin library. This seems to work -- but use at your own risk. It takes 126us (at 200MHz) to re-calibrate and read a pin; it returns the pin voltage in millivolts (0..3300). Drop it into your app and call it with the pin you want to read.
Eight channels should be as fast as one channel since they can all operate in parallel.
EDIT: Of course, that's painful to make parallel timings fit in an object oriented world.
I've discovered that a pin's ADC response time for instrumentation is largely dependant on the drive strength of the input signal. The Sinc3 filter can digitally settle in a few microseconds but it takes more time for the analogue input to drive the ADC analogue circuits to that level as it switches between GIO, VIO and the input. A stronger signal will drive it faster. One solution is to use an op-amp as a low impedance buffer.
PS: I haven't actually proven this by adding an op-amp myself. Instead, I noticed that a high impedance input signal is a lot slower slewing compare to VIO and GIO when running the calibrations. Further reading - https://forums.parallax.com/discussion/comment/1545000/#Comment_1545000
Thanks Jon and Evan. Your replies made me do some basic math on my loops and I should have plenty of time to perform Jon's in line assembly calls on all eight channels within my loop requirements. I will install the code and test it to see where I get. Thanks again to both of you for your ideas.
you have 4 lines of code commented out.
Is that because they are unnecessary?
Those registers don't change, but I left in the commented lines in case you decide to break things up -- you may then need to uncomment them.
Thanks Jon, I thought you might have a special motive. Now I have to figure out why, no matter what pin I plug in, I get 0 as the result.
Test it separately with something as simple as a pot. I just did and it's fine.
BTW, I found this demo in the PNut folder that Chip wrote to install an 8-channel ADC TSR into the interpreter. It might need updating because of recent changes to interpreter memory. I'm not skilled enough with PASM2 to understand how this works, but I did see it running on a Parallax live stream.
Note that if you install this TRS your available memory for inline code will be reduced.
I downloaded the ADC sample program and since I don't have a copy of the VGA object I was trying to translate it to using my ANSI terminal program instead. All was going well until I have to access the "samples" variable in the ISR that is part of a RES statment in the PASM code. He uses a command "regexec(@adc_pasm) "and then "reg[samples][[i]" to acquire the data from the ADC code. If I could figure out how to access "samples" I could try his code.
As far as trying to run your adc read inline PASM my problem was printing out the wrong thing. When I tell it to print the VAR that I just read the ADC into it works just great. Now to get that to integrate into my main program!
Hi chip, I downloaded and opened the file thar Jon attached above and I would like to try it. I have two problems:
1. I dont have any way to attach to attach it to my laptop.
2. There are two commands in the code I dont know
a: REGEXEC.Edit I found the meaning of this.
B: I don't know how to access the "samples" var in the res section of the pasm code.
edit Ok I think I have now found out how to access the samples. will try tomorrow am and see.
I am working in Spin2 and any enlightenment would be much appreciated.
Enlightenment is coming from "Hello Propeller".
REGEXEC allows you to load custom PASM into the user space of the Spin2 interpreter and run it. For obvious reasons, this only works in native Spin2 (PNut and Propeller Tool), it won't work with a compiler. In Chip's demo he's using REG to access the samples. While not documented, REG seems to allow access to registers in the interpreter cog. In native Spin2 there are 8 registers (pr0..pr7) that can be used to communicate between Spin and the interpreter. I did this little test.
Thanks Jon, I discovered much to my dismay that this may never work with flexprop. I thought that an isr running in the background was a neat solution. I may have to try running proptool or peanut under wine on my Linux machine.
Seems like it would be easier to write a routine that runs in its own cog measuring each pin and writing to a destination array. The main program would just read the array for current ADC values.
I am sure that is the way it is going to happen. I was disappointed to learn that I was not going to be able to try Chip's adc software. I just may have to try proptool under wine.
As an update I have been trying to run proptool under wine, but sofar proptool reports no io ports. I have downloaded and run regedit but have not figured out how to save the settings in regedit.I am also not sure if the settings need to be entered as "/dev/ttyUSB0" or "->/dev/ttyUSB0 ". The wall is feeling abused where I have been hitting it with my head.
Edit: the vga programs Chip included with his vga adc program are not in the proptool library. I was going to use one as a guide to replacing it with a terminal program. His use of "send" intrigued me and I was wondering if it could be used in a regular terminal program.