Shop OBEX P1 Docs P2 Docs Learn Events
how do i get a return array? — Parallax Forums

how do i get a return array?

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.
``

Comments

  • JonnyMacJonnyMac Posts: 8,918
    edited 2023-01-29 03:10

    If you're passing an address to the method, you'll want to do it like this:

    pub adc_read(p_packet) | x, raw
    
      repeat x from 0 to ADC_CHANS
        if (x < ADC_CHANS)
          raw := adc.read(x)
        else
          raw := pinread(DIP_SW)
    
        word[p_packet][x] := raw
    

    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.
    Jim

  • JonnyMacJonnyMac Posts: 8,918
    edited 2023-01-31 04:24

    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.

    pub cal_read(pin) : mv
    
    '' Calibrate and read analog input pin for 0 to 3.3v input
    '' -- 12 bits, using SINC2, 2048 samples
    
      org
                            fltl      pin                           ' release 
                            wrpin     ##(P_ADC | P_ADC_GIO), pin    ' set sp mode (read ground)
                            wxpin     #(12-1), 0                    ' set sp x reg
                            wypin     #0, pin                       ' set sp y reg
                            drvl      pin                           ' enable sp
    
                            getct     pr7                           ' allow pin to stabilize
                            addct1    pr7, ##(2048 << 2)  
                            waitct1
                            rdpin     pr0, pin
    
                            fltl      pin  
                            wrpin     ##(P_ADC | P_ADC_VIO), pin    ' set sp mode (read Vcc)
                          ' wxpin     #(12-1), 0 
                          ' wypin     #0, pin  
                            drvl      pin   
    
                            getct     pr7 
                            addct1    pr7, ##(2048 << 2)  
                            waitct1
                            rdpin     pr1, pin
    
                            fltl      pin 
                            wrpin     ##(P_ADC | P_ADC_1X), pin     ' set sp mode (read pin)
                          ' wxpin     #(12-1), 0  
                          ' wypin     #0, pin  
                            drvl      pin  
    
                            getct     pr7 
                            addct1    pr7, ##(2048 << 2)  
                            waitct1
                            rdpin     pr2, pin 
    
                            ' scale raw value to range 0..3300
    
                            sub       pr2, pr0                      ' remove ground offset
                            mul       pr2, ##3300                   ' multiply by input span
                            sub       pr1, pr0                      ' calibration span
                            qdiv      pr2, pr1
                            getqx     mv
      end
    
  • evanhevanh Posts: 15,171
    edited 2023-01-31 06:25

    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.

  • evanhevanh Posts: 15,171
    edited 2023-01-31 06:55

    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.
    Jim

  • Jon,
    you have 4 lines of code commented out.

                          ' wxpin     #(12-1), 0  
                          ' wypin     #0, pin  
    
                          ' wxpin     #(12-1), 0  
                          ' wypin     #0, pin  
    

    Is that because they are unnecessary?
    Jim

  • 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.
    Jim

  • 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.

  • Thanks Jon,
    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!
    Jim

  • RS_JimRS_Jim Posts: 1,753
    edited 2023-02-03 03:12

    @cgracey,
    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".
    Thanks
    Jim

  • JonnyMacJonnyMac Posts: 8,918
    edited 2023-02-03 15:54

    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.
    Jim

  • 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.

  • Jon,
    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.
    Jim

  • RS_JimRS_Jim Posts: 1,753
    edited 2023-02-18 23:08

    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.
    Jim
    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.
    End edit

Sign In or Register to comment.