Announcement

Collapse
No announcement yet.

chipKIT uno32 Arduino MD experiments

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • #16
    here's my latest code for my 16 bit adc project.

    it appears to be sampling at about 4.4 microseconds, from my timing experiments, I'm hoping to get it in the 2-3 microseconds range,

    the areas for improvement are:

    A single 16 bit transfer instead of the 2, 8 byte transfers

    Using a different type of digital write for the SELPIN.

    Philip

    (maybe tomarrow i'll post a picture or a video of it action)

    Code:
    /*  ADS8319 16-BIT, 500-KSPS, SERIAL INTERFACE experiment by Philip Crawford
     
              This is free software, for educational use only / for the Chipkit uno32        
     
    */
     
    #include <DSPI.h> // the DSPI library has a little more flexiabilty
                      // than the standard SPI library  
    #include <CK_LCD5110_Graph.h>
    #define SELPIN 9 
    #define MISOPIN 12
    #define SCLKPIN 13
    // This program requires a Nokia 5110 LCD module.
    //
    // It is assumed that the LCD module is connected to
    // the following pins:
    //      SCK  - Pin 41
    //      MOSI - Pin 40
    //      DC   - Pin 39
    //      RST  - Pin 38
    //      CS   - Pin 37
    //
    LCD5110 myGLCD(41,40,39,38,37);
    extern unsigned char SmallFont[];
    int adcvalue;
    byte byte1; byte byte2;
    const float   aRefVoltage = 4.096;
    float volts = 0;
    DSPI0    spi;
    void setup() {
     
    pinMode(SELPIN, OUTPUT); // ADC's conversion pin
    pinMode(SCLKPIN, OUTPUT);// ADC's clock pin
    pinMode(MISOPIN, INPUT); // ADC's data out
       myGLCD.InitLCD();
       myGLCD.setFont(SmallFont);
       myGLCD.print("ADC read", CENTER, 0);
       myGLCD.update();
    spi.begin();
    spi.setSpeed(20000000); // 20 mhz spi clock
    Serial.begin(9600);
    }
    void loop(){ // calls the subroutine "read_adc" 
    read_adc();
    }
    void read_adc()
    {
       digitalWrite(SELPIN, HIGH); // starts conversion of adc
       digitalWrite(SELPIN, LOW);  // ends conversion, starts Acquisition
     
    byte1 = spi.transfer(0x00); //transfer (read) 8 bits from the adc chip D15-8
    byte2 = spi.transfer(0x00); //transfer (read) the second 8 bits. D7-0
     
    adcvalue = (byte1 << 8 ) | (byte2 & 0xff); // combine the 2 bytes to make our 16 bit word
     
       Serial.print("Adc value:  ");         
       Serial.print(adcvalue,HEX);           // display the HEX value also
    volts = (adcvalue*aRefVoltage/65535);    // formula for figureing voltage
                                             // 65535 = the 16 bit "deciamal" value 
       Serial.print("   Adc volts:  ");      
       Serial.println(volts,5);              // display the "voltage" with 5 digits
      myGLCD.print("ADC read", CENTER, 0);   
     
      myGLCD.printNumF(volts, 5, CENTER,10); // display the "voltage" with 5 digits
                                             // lets center the value 
                                             // and display it on the 10th pixel
                                             // from the top left
      myGLCD.update();                       // update the display
     
     
    delay (100);                           
     
    }

    Comment


    • #17
      Hi hdphilip,

      I like the 2 transfers even though they might not be the fastest solution. It allows the guys running with 8-bit MCUs to follow in your footsteps... just my 2 cents.

      A video would be great once you get in going!

      rickodetrader

      Comment


      • #18
        hello rick

        here's a picture of the timing on my DSO quad,

        The red trace is the adc's conversion pin (SELPIN)

        The green trace is the data out of the adc.

        The blue trace is the 8 bite data (spi.transfer(0x00) so you can see their is a small gap between the the data bursts, that gap is about 1 us, so if i can remove it, I'd get a better sample time.


        I re-wrote the software to use the C32 compiler functions, the MPIDE digitalwrite's are a little slow,

        my current sample window is: 3.032 us

        That means if I were to set up a 13 us sample window, I'd be able to sample it 4 times, on every transmit pulse!

        This is called the "Direct Sampling System" copyrighted


        The SPI bus is running at 16 MHz



        Compare this timing diagram, with the ads8319 data sheet (figure 46) and it'll make a little more sense of the data sheet

        I'll make a video and post it a little latter on.



        Philip
        Attached Files

        Comment


        • #19
          Here's a video of my adc converter in action.

          http://youtu.be/FKZtVaCFWHI

          a couple things to notice,

          When i adjust the voltage down, it doesn't goes to zero, this is because the diagram I was following wanted -.3 volts VSS on the buffer op-amp, and i just grounded it.
          but all in all I'm pretty happy with my results, It's pretty stable.

          where to go from here?

          Been thinking about trying out the Linear Technology' LTC2368-18 ADC , but from what I seen so far is, I'll need to work on the SPI interface, might have write my own, I'll need to squeeze 24 MHz out of it to make the results worth while.

          here's my to do list:

          see why my 7660 circuit didn't work right, (horrible ripple)

          hardware:

          try out my DG4157 switch
          try out my mosfet driver circuit
          order a spare chipkit uno32, and a spare pic32 proocessor
          order a LTC2368-18 ADC and all the trimmings...........
          software:

          figure out some pulse timing software.

          hook up a rotary encoder..



          Questions or ideas?

          Philip

          Comment


          • #20
            Hi hdphilip,

            Great work!

            I can see the gap and am beginning to want to eat my words "i like the 2 transfers". Should have known something like this would have been the result of doing it that way.

            So if you can remove the 1uS gap does that mean the sample window would be about ~2 uS and you could sample 5 times rather than 4... that would be pretty good

            Went searching for some information on 16-bit SPI transfers but it turned out it is in Assembler/C and not that compatible with arduino, ATMELs yes, PICs yes however. From what I can tell there is support but the libraries themselves are geared towards one "brand" or the other. You probably have already seen this...

            So that is where I am concentrating my efforts now since i"m going to need to in the future... learning to use AVR dev environment and getting it going with the Atmega8, 168 and 328's that I've got.

            Have you hooked up the current project to the output of a PI preamp yet to see what you get? From the bugwhiskers thread he seemed to move ahead in leaps and bounds once he started sampling.

            I want to start sampling.

            Good luck hope to see more of yourwork in the future

            rickodetrader

            Comment


            • #21
              hey rick

              So if you can remove the 1uS gap does that mean the sample window would be about ~2 uS and you could sample 5 times rather than 4... that would be pretty good
              so thats the idea, it's something I've been thinking about, I'll have to use the pic 32 compiler "c" commands to do it. but I'm searching the web for ideas.

              here's something about the screen shot of my timing diagram, if you noticed i had my time base set to 1us, but at the time i took the screen shot the spi bus was running at 8 MHz, so that's why the sampling would seem to be longer than the 3.032us.

              when i can get the "gap" solved, I'll be closer to sampling, but it'll take alot more before I'm ready, i also need to figure out how to make a audio output software.

              it's good your learning the development software for the ATmega328, but always keep an open mind to the pic's. one of these days, your going to be looking for a faster micro controller. another reason why i like the pic 32 it's 3.3 volts. even though I've ran many of my arduino custom projects board on 3.3 volts at 8 MHz

              Philip

              Comment


              • #22
                mind the gap ...

                c function to open pic32 SPI channel for 16 bit transfers


                eg usage .....

                SPIconfig(SPI_CHANNEL2, 1, 0, 0); // initialize SPI channel 2 as master,16 bit, no frame mode


                note the frame size is not passed as a variable ..... you could add it easily enough.

                /************************************************** *******************
                * Function: void SpiInitDevice(SpiChannel chn, int isMaster, int frmEn, int frmMaster)
                *
                * PreCondition: None
                *
                * Input: chn - the SPI channel to use
                * isMaster - 1: the device is to act as a bus master
                * 0: the device is an SPI slave
                * frmEn - 1: frame mode is enabled
                * - 0: frame mode is disabled
                * frmMaster - 0: if frame mode is enabled, the device is a frame slave (FRMSYNC is input)
                * 1: if frame mode is enabled, the device is a frame master (FRMSYNC is output)
                *
                * Output: None
                *
                * Side Effects: None
                *
                * Overview: Inits the SPI channel 'chn' to use 16 bit words
                * Performs the device initialization in both master/slave modes.
                *
                * Note: None
                ************************************************** ******************/
                void SPIconfig(SpiChannel chn, int isMaster, int frmEn, int frmMaster)
                {
                SpiOpenFlags oFlags=SPI_OPEN_MODE16|SPI_OPEN_SMP_END; // SPI open mode
                if(isMaster)
                {
                oFlags|=SPI_OPEN_MSTEN;
                }
                if(frmEn)
                {
                oFlags|=SPI_OPEN_FRMEN;
                if(!frmMaster)
                {
                oFlags|=SPI_OPEN_FSP_IN;
                }
                }


                SpiChnOpen(chn, oFlags, 4); // divide fpb by 4, configure the I/O ports.
                }

                Comment


                • #23
                  ...oh and dont forget ....

                  ... to include plib.h in you c header files or you will not be able to access the standard pic peripheral library definitions and functions in MPIDE ...saves reading heaps of obscure bitfields in chip specification documents.

                  eg

                  #include <plib.h>


                  moodz

                  Comment


                  • #24
                    Custom user functions in arduino.

                    If you really "must" use the arduino sketch IDE environment you can add your C functions as a user library and access them like the regular arduino functions. You can also add assembly or CPP functions the same way.

                    See here ....

                    http://www.arduino.cc/en/Hacking/Libraries

                    Moodz

                    Comment


                    • #25
                      Hi moodz,

                      Thanks for pointing that one out.

                      rickodetrader

                      Comment


                      • #26
                        hello moodz

                        Thanks for your input,

                        i tried the spi routine,


                        #include <plib.h>
                        #include <SPI.h>
                        SPIconfig(SPI_CHANNEL2, 1, 0, 0); // initialize SPI channel 2 as master,16 bit, no frame mode

                        void SPIconfig(SpiChannel chn, int isMaster, int frmEn, int frmMaster)
                        {
                        SpiOpenFlags oFlags=SPI_OPEN_MODE16|SPI_OPEN_SMP_END; // SPI open mode
                        if(isMaster)
                        {
                        oFlags|=SPI_OPEN_MSTEN;
                        }
                        if(frmEn)
                        {
                        oFlags|=SPI_OPEN_FRMEN;
                        if(!frmMaster)
                        {
                        oFlags|=SPI_OPEN_FSP_IN;
                        }
                        }

                        SpiChnOpen(chn, oFlags, 4); // divide fpb by 4, configure the I/O ports.
                        }

                        but i get a error

                        it might be the code is calling somthing in the spi libary

                        "invalid conversion from 'unsigned int' to SpiOpenFlags'

                        I just started usuing the plib.h

                        here's my latest,

                        Code:
                        void read_adc()
                        {
                          mPORTDClearBits(BIT_3);
                          mPORTDSetBits(BIT_3);    // starts conversion of adc
                          for(i=0;i<23;i++){       // fine tunes converision pulse width   
                            Nop();
                          }
                          mPORTDClearBits(BIT_3);
                         
                          byte1 = spi.transfer(0x00); //transfer (read) 8 bits from the adc chip D15-8
                          byte2 = spi.transfer(0x00); //transfer (read) the second 8 bits. D7-0   
                          adcvalue = (byte1 << 8 ) | (byte2 & 0xff); // combine the 2 bytes to make our 16 bit word
                          Serial.print("Adc value:  ");         
                          Serial.print(adcvalue,HEX);           // display the HEX value also
                          volts = (adcvalue*aRefVoltage/65535);    // formula for figureing voltage
                          // 65535 = the 16 bit "deciamal" value 
                          Serial.print("   Adc volts:  ");      
                          Serial.println(volts,5);              // display the "voltage" with 5 digits
                          myGLCD.print("ADC read", CENTER, 0);   
                          myGLCD.printNumF(volts, 5, CENTER,10); // display the "voltage" with 5 digits
                          myGLCD.update();                       // update the display
                          delay (200);                           
                        }



                        Philip

                        Comment


                        • #27
                          Hi Philip. . I am not sure how much c programming you do but in this case it helps to declare the function first ..so the compiler knows what the variable types are otherwise it makes assumptions ....

                          At the top of your code after the includes put this line ...

                          void SPIconfig(SpiChannel, int , int, int);


                          The other way to do it is to make sure the function is written / listed before the code that calls it.

                          Moodz

                          Comment


                          • #28
                            ....a really good book

                            http://www.borders.com.au/by/lucio-di-jasio/

                            See programming 32 bit microcontrollers in C : exploring the PIC32

                            One of the most excellent books on C and micro controllers I have ever read. Tells you how to do all the things you need to know for metal detector building .... Though it is not a book about metal detectors LOL.

                            Covers dsp , rotary encoders, pulse generation, Audio generation, sd card access even video generation ! And it's all pic32. Suits beginners to experts and covers using the mpide.

                            You should buy it ....but you might find an "evaluation" copy on the web somewhere

                            Moodz

                            Comment


                            • #29
                              hello moodz
                              Hi Philip. . I am not sure how much c programming you do but in this case it helps to declare the function first ..so the compiler knows what the variable types are otherwise it makes assumptions ....
                              well as far as programming pic32's, 2 weeks, I've been programming the arduino's for about a couple of years, I do it as a hobby, as I'm sure most people on forums do. I learn as I go, and google the questions I have.



                              I'd be curious to know what spi library your spi routines are base on. And maybe a simple working example.



                              Philip

                              Comment


                              • #30
                                Originally posted by hdphilip View Post
                                hello moodz


                                well as far as programming pic32's, 2 weeks, I've been programming the arduino's for about a couple of years, I do it as a hobby, as I'm sure most people on forums do. I learn as I go, and google the questions I have.



                                I'd be curious to know what spi library your spi routines are base on. And maybe a simple working example.



                                Philip

                                Hi Philip .... have a look here

                                http://www.microchip.com/wwwproducts...ame=en532434#1

                                Look at the code example for SPI and run the loopback example ....once you have the loopback working OK its time to connect to your SPI device ....getting the timing optimised on SPI can take a bit of work.
                                I am presuming you have the 32 bit compiler installed in MPIDE.

                                The library I am using is the standard peripheral library plib ....

                                moodz

                                Comment

                                Working...
                                X