+ Post New Thread
Results 1 to 7 of 7
  1. #1
    Full Member level 1
    Points: 639, Level: 5

    Join Date
    Nov 2018
    Posts
    96
    Helped
    1 / 1
    Points
    639
    Level
    5

    Data acquisition using PIC starter kit

    I am having my project requirement to sample the analog data at the rate of 2 Mega samples per second streaming data and send to the PC. I am thinking to use PIC starter kit with USB or Ethernet with demo software for PC side to receive and download the PIC data. I just look at some Microchip starter kits but I am not sure I can use them for my application. Any suggestion or ideas ?

    •   AltAdvertisement

        
       

  2. #2
    Full Member level 1
    Points: 639, Level: 5

    Join Date
    Nov 2018
    Posts
    96
    Helped
    1 / 1
    Points
    639
    Level
    5

    Re: Data acquisition using PIC starter kit

    Hi,

    There is a little change in application requirement. I would have 500 kilo 12 bit samples per second and I need to send 10-12 character string with each sample to the PC. I guess USB full speed can send it to the PC. I am wondering is there any pin header on the PIC USB Starter Kit available for ADC channels ? The Microchip offers Free USB Software, is it capable to download and receive the PIC streaming data in the PC ?



    •   AltAdvertisement

        
       

  3. #3
    Advanced Member level 4
    Points: 8,209, Level: 21
    Achievements:
    7 years registered
    paulfjujo's Avatar
    Join Date
    Jun 2008
    Location
    France 01120
    Posts
    1,324
    Helped
    269 / 269
    Points
    8,209
    Level
    21

    Re: Data acquisition using PIC starter kit

    hello,

    Tell us wich MCU you want to use ..
    i think it is not possible to transmit in real time at 500Ksp/sec with PIC18F
    because it is allready difficult to assume 2µS/sample for the ADC itself ,
    you need a minimum timing for acquistion and between each ADC sampling...

    Maybe with rescent MCU, you can use ADC and DMA access
    but you can not send each value in real time with 10 ascii
    you send all, only when DMA Accses is finished.

    USB max speed 12Mb/sec
    10 char + value 16 bits => 12 chars or Bytes => 120 bits
    12 000 000 / 120 =>100 000 sample /sec
    + somme bytes for the exchange protocole and USB packett=> less than 100Ksp/sec

    see DSP MCU ....



    •   AltAdvertisement

        
       

  4. #4
    Super Moderator
    Points: 260,175, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    45,436
    Helped
    13823 / 13823
    Points
    260,175
    Level
    100

    Re: Data acquisition using PIC starter kit

    Think about an ADC with DMA support and USB high speed or 100 Mbit Ethernet interface. Suitable CPUs are e.g. PIC32 (new MZ family has USB HS) or ARM (e.g. STM32F4xx).



  5. #5
    Full Member level 1
    Points: 639, Level: 5

    Join Date
    Nov 2018
    Posts
    96
    Helped
    1 / 1
    Points
    639
    Level
    5

    Re: Data acquisition using PIC starter kit

    Thanks for your reply. I guess I would go with 50 kilo sample per second at the first stage and consider USB Full Speed for communication.

    - Sampling rate: 50 kilo samples per second
    - String: 10 character message with each sample
    - Transmission rate in bytes: (10 + 2) * 50 000 = 600 kilo bytes
    - Transmission rate in bits: 6 Mega bits per second

    How much is protocol overheard ? Which USB class is suitable for this application ? I realize that there is USB module on the PIC18F2550 which means that USB controller is present on the PIC18F2550, right ?. Does this means that I can directly connect the USB cable to the PIC pins D+, D-, GND ? after programming.



  6. #6
    Advanced Member level 4
    Points: 8,209, Level: 21
    Achievements:
    7 years registered
    paulfjujo's Avatar
    Join Date
    Jun 2008
    Location
    France 01120
    Posts
    1,324
    Helped
    269 / 269
    Points
    8,209
    Level
    21

    Re: Data acquisition using PIC starter kit

    Quote Originally Posted by joniengr View Post
    .... I realize that there is USB module on the PIC18F2550 which means that USB controller is present on the PIC18F2550, right ?. Does this means that I can directly connect the USB cable to the PIC pins D+, D-, GND ? after programming.
    Yes, but ......
    you need to use a HID Descriptor on PIC Side , and a HOST usb PC side
    any years ago , i did some test with the MikroC HID terminal
    a PIC18F2550 to send ADC measure trough USB cable , and get back some Order from the PC Terminal.

    The PIC communicate with HID USB trough a commun Memory AREA in RAM
    this amount of RAM is limited ..
    so you can only transmit bloc per bloc, not in contineous flow data rate.
    i didn't test what was the possible maximum speed of acquisition+ transfert

    i think, now, 18F2550 is too old, newer PIC can get better results .. liike 18F87J50 ?


    in the below example, i included the HID descriptor inside the main code..

    FYI

    Code:
    /*
     * Project name:
        original :  HID_Read_Write_Interrupt (Testing the USB HID connection)
        revised by paulfjujo
     * Copyright:
         (c) Mikroelektronika, 2011.
     * Revision History:
         20110929 initial release (FJ);
     * Description:
         This example establishes connection with the HID terminal that is active
         on the PC. Upon connection establishment, the HID Device Name will appear
         in the respective window. After that software will wait for data and
         it will return received data back.
     * Test configuration:
         MCU:             PIC18F2550
         dev.board:  StartUSB Board 18F2550
         Oscillator:      HS, 8.000 MHz  (USB osc. is raised with PLL to 48.000MHz)
         Ext. Modules:    None.
         SW:              mikroC PRO for PIC 6.50
     * NOTES:
         (*) Be VERY careful about the configuration flags for the 18F2550 - there's
         so much place for mistake!
    
     */
    
    
    
    #define CLS 12
    #define BS 8
    #define TAB 9
    #define CR 13
    #define LF 10
    #define Bell 7
    #define ON 0        // logique inverse avec led tiree au +5V
    #define OFF 1
    
    #define Nb_Count1 24  // 24 * 41.666mS = 1 seconde (init timer1 à 3035 et prescaler=1/8)
    
    sbit LED_Sup at LATA1_bit;    // led rouge
    sbit LED_Inf at LATB3_bit;    // led jaune   J2 enlevé et strap entre RB3 et LED3 verte
    
    
    unsigned char readbuff[64] absolute 0x500;   // Buffers should be in USB RAM, please consult datasheet
    unsigned char writebuff[64] absolute 0x540;
    
    
    const unsigned int USB_VENDOR_ID = 0x1234;
    const unsigned int USB_PRODUCT_ID = 0x1234;
    const char USB_SELF_POWER = 0xC0;            // Self powered 0xC0,  0x80 bus powered
    const char USB_MAX_POWER = 50;               // Bus power required in units of 2 mA
    const char HID_INPUT_REPORT_BYTES = 63;
    const char HID_OUTPUT_REPORT_BYTES = 63;
    const char USB_TRANSFER_TYPE = 0x03;         //0x03 Interrupt
    const char EP_IN_INTERVAL = 1;
    const char EP_OUT_INTERVAL = 1;
    const char USB_INTERRUPT = 1;
    const char USB_HID_EP = 1;
    const char USB_HID_RPT_SIZE = 57;
    
    /* Device Descriptor */
    const struct {
        char bLength;               // bLength         - Descriptor size in bytes (12h)
        char bDescriptorType;       // bDescriptorType - The constant DEVICE (01h)
        unsigned int bcdUSB;        // bcdUSB          - USB specification release number (BCD)
        char bDeviceClass;          // bDeviceClass    - Class Code
        char bDeviceSubClass;       // bDeviceSubClass - Subclass code
        char bDeviceProtocol;       // bDeviceProtocol - Protocol code
        char bMaxPacketSize0;       // bMaxPacketSize0 - Maximum packet size for endpoint 0
        unsigned int idVendor;      // idVendor        - Vendor ID
        unsigned int idProduct;     // idProduct       - Product ID
        unsigned int bcdDevice;     // bcdDevice       - Device release number (BCD)
        char iManufacturer;         // iManufacturer   - Index of string descriptor for the manufacturer
        char iProduct;              // iProduct        - Index of string descriptor for the product.
        char iSerialNumber;         // iSerialNumber   - Index of string descriptor for the serial number.
        char bNumConfigurations;    // bNumConfigurations - Number of possible configurations
    } device_dsc = {
          0x12,                   // bLength
          0x01,                   // bDescriptorType
          0x0200,                 // bcdUSB
          0x00,                   // bDeviceClass
          0x00,                   // bDeviceSubClass
          0x00,                   // bDeviceProtocol
          8,                      // bMaxPacketSize0
          USB_VENDOR_ID,          // idVendor
          USB_PRODUCT_ID,         // idProduct
          0x0001,                 // bcdDevice
          0x01,                   // iManufacturer
          0x02,                   // iProduct
          0x03,                   // iSerialNumber
          0x01                    // bNumConfigurations
      };
    
    /* Configuration 1 Descriptor */
    const char configDescriptor1[]= {
        // Configuration Descriptor
        0x09,                   // bLength             - Descriptor size in bytes
        0x02,                   // bDescriptorType     - The constant CONFIGURATION (02h)
        0x29,0x00,              // wTotalLength        - The number of bytes in the configuration descriptor and all of its subordinate descriptors
        1,                      // bNumInterfaces      - Number of interfaces in the configuration
        1,                      // bConfigurationValue - Identifier for Set Configuration and Get Configuration requests
        0,                      // iConfiguration      - Index of string descriptor for the configuration
        USB_SELF_POWER,         // bmAttributes        - Self/bus power and remote wakeup settings
        USB_MAX_POWER,          // bMaxPower           - Bus power required in units of 2 mA
    
        // Interface Descriptor
        0x09,                   // bLength - Descriptor size in bytes (09h)
        0x04,                   // bDescriptorType - The constant Interface (04h)
        0,                      // bInterfaceNumber - Number identifying this interface
        0,                      // bAlternateSetting - A number that identifies a descriptor with alternate settings for this bInterfaceNumber.
        2,                      // bNumEndpoint - Number of endpoints supported not counting endpoint zero
        0x03,                   // bInterfaceClass - Class code
        0,                      // bInterfaceSubclass - Subclass code
        0,                      // bInterfaceProtocol - Protocol code
        0,                      // iInterface - Interface string index
    
        // HID Class-Specific Descriptor
        0x09,                   // bLength - Descriptor size in bytes.
        0x21,                   // bDescriptorType - This descriptor's type: 21h to indicate the HID class.
        0x01,0x01,              // bcdHID - HID specification release number (BCD).
        0x00,                   // bCountryCode - Numeric expression identifying the country for localized hardware (BCD) or 00h.
        1,                      // bNumDescriptors - Number of subordinate report and physical descriptors.
        0x22,                   // bDescriptorType - The type of a class-specific descriptor that follows
        USB_HID_RPT_SIZE,0x00,  // wDescriptorLength - Total length of the descriptor identified above.
    
        // Endpoint Descriptor
        0x07,                   // bLength - Descriptor size in bytes (07h)
        0x05,                   // bDescriptorType - The constant Endpoint (05h)
        USB_HID_EP | 0x80,      // bEndpointAddress - Endpoint number and direction
        USB_TRANSFER_TYPE,      // bmAttributes - Transfer type and supplementary information
        0x40,0x00,              // wMaxPacketSize - Maximum packet size supported
        EP_IN_INTERVAL,         // bInterval - Service interval or NAK rate
    
        // Endpoint Descriptor
        0x07,                   // bLength - Descriptor size in bytes (07h)
        0x05,                   // bDescriptorType - The constant Endpoint (05h)
        USB_HID_EP,             // bEndpointAddress - Endpoint number and direction
        USB_TRANSFER_TYPE,      // bmAttributes - Transfer type and supplementary information
        0x40,0x00,              // wMaxPacketSize - Maximum packet size supported
        EP_OUT_INTERVAL         // bInterval - Service interval or NAK rate
    };
    
    const struct 
    {
      char report[USB_HID_RPT_SIZE];
    }
    
    hid_rpt_desc =
      {
         {0x06, 0x00, 0xFF,       // Usage Page = 0xFF00 (Vendor Defined Page 1)
          0x09, 0x01,             // Usage (Vendor Usage 1)
          0xA1, 0x01,             // Collection (Application)
          0x85, 0x01,             // Report ID=1 (This is a global variable)
          0x15, 0x00,             // Logical Minimum (data bytes in the report may have minimum value = 0. This is a global variable)
          0x26, 0xFF, 0x00,       // Logical Maximum (data bytes in the report may have maximum value = 256. This is a global variable)
    
      // Input report(ID=1)
          0x19, 0x01,             // Usage Minimum
          0x29, 0xFF,             // Usage Maximum
          0x75, 0x08,             // Report Size: 8-bit field size
          0x95, 0x3F,             // Report Count (63 + 1 byte for the report ID)
          0x81, 0x02,             // Input (Data, Var, Abs)
    
      // Output report(ID=1)
          0x19, 0x01,             // Usage Minimum
          0x29, 0xFF,             // Usage Maximum
          0x75, 0x08,             // Report Size: 8-bit field size
          0x95, 0x3F,             // Report Count (63 + 1 byte for the report ID)
          0x91, 0x02,             // Output (Data, Var, Abs)
          
          
          0x85, 0x02,             // Report ID=1 (This is a global variable)
          
          // Input report(ID=2)
          0x19, 0x01,             // Usage Minimum
          0x29, 0x08,             // Usage Maximum
          0x75, 0x08,             // Report Size: 8-bit field size
          0x95, 0x01,             // Report Count (1 byte + 1 byte for the report ID)
          0x81, 0x02,             // Input (Data, Var, Abs)
          
          // Output report(ID=2)
          0x19, 0x01,             // Usage Minimum
          0x29, 0x08,             // Usage Maximum
          0x75, 0x08,             // Report Size: 8-bit field size
          0x95, 0x01,             // Report Count (1 byte + 1 byte for the report ID)
          0x91, 0x02,             // Output (Data, Var, Abs)
    
          0xC0},                   // End Collection
      };
    
    //Language code string descriptor
    const struct {
      char bLength;
      char bDscType;
      unsigned int string[1];
      } strd1 = {
          4,
          0x03,
          {0x0409}
        };
    
    
    //Manufacturer string descriptor
    const struct{
      char bLength;
      char bDscType;
      unsigned int string[10];
      }strd2={
        22,           //size of this descriptor string
        0x03,
        {'p','a','u','l','f','j','u','j','o',' '}
      };
    
    //Product string descriptor
    const struct{
      char bLength;
      char bDscType;
      unsigned int string[10];
    }strd3={
        22,          //size of this descriptor string
        0x03,
        {'P','I','C','1','8','F','2','5','5','0'}
     };
     //Serial Number descriptor
    const struct{
      char bLength;
      char bDscType;
      unsigned int string[6];
    }strd4 = {
        14,          //size of this descriptor string
        0x03,
        {'A','B','C','1','2','3'} // Count as two bytes
     };
    
    //Array of configuration descriptors
    const char* USB_config_dsc_ptr[1];
    //Array of string descriptors
    const char* USB_string_dsc_ptr[3];
    
    
    
    const code char mesg0[]="MikroC Pro V6.50    ";
    const code char mesg1[]="HID Terminal USB PC ";
    const code char * Messages[]={mesg0,mesg1};
    
    unsigned char TEXTE[64];
    unsigned char * txt;
    unsigned char  addr;
    char * PtR;
    char * PtE;
    char cnt;
    char kk;
    unsigned int  i,j,k;
    char CRam1[20];
    unsigned int EAH,EAL,EA0;
    float ff1;
    int FDC_Mini;  // issu du potar de recopie      ADC value <20
    int FDC_Maxi;   // issu du potar de recopie    ADC value > 1000
    int Etat;
    volatile unsigned int Count1;
    volatile int Flag_Timer1;
    unsigned char sec;
    unsigned int Toggle;
    
    
    void USB_Init_Desc();
    void strConstRamCpy(unsigned char *dest, const code char *source) ;
    
    void interrupt(){
       USB_Interrupt_Proc();                  // USB servicing is done inside the interrupt
    }
    
    void Interrupts() iv 0x0018 ics ICS_AUTO
    {
       // ------  timer 1  ----------------
      if  ( (TMR1IE_bit==1) && ( TMR1IF_bit==1))
       {  // Test "Peripheral Interrupt Request Register 1" for Timer1 Flag
    
         Count1++;
         if (Count1>=Nb_Count1)
           {
            Count1=0;
            Flag_Timer1=1;
            TMR1IE_bit=0;
          }
          // 24 * 41.666mS = 1 seconde et init timer1 à 3035  et prescaler=1/8  at 48MHz
          TMR1H= 0x0B; // Hi (3035);
          TMR1L= 0xDB; // Lo (3035);
          PIR1.TMR1IF=0;
       }
    }
    
    
    
    void USB_Init_Desc(){
      USB_config_dsc_ptr[0] = &configDescriptor1;
      USB_string_dsc_ptr[0] = (const char*)&strd1;
      USB_string_dsc_ptr[1] = (const char*)&strd2;
      USB_string_dsc_ptr[2] = (const char*)&strd3;
      USB_string_dsc_ptr[3] = (const char*)&strd4;
      }
    
    
    void Init_Timer1(void)
     {
      T1CON=0;
      T1CKPS1_bit=1;  //prescal select=11 => 1/8
      T1CKPS0_bit=1;
     // T1GCON=0;
      TMR1H= 0x0B; // Hi (3035);     // 41mS at 49MHZ
      TMR1L= 0xDB; // Lo (3035);
     // TMR1H= NbCycles_T1>>8;
     // TMR1L= NbCycles_T1 & 0x00FF;
       Count1=0;
      Flag_Timer1=0;
      PIR1.TMR1IF=0;     // Reset Timer1 Flag
      PIE1.TMR1IE=0;  //Disable interrupt TMR1
      IPR1.TMR1IP=0;  // disable High level interrupt
      INTCON.PEIE=0;  // disable peripheral interrupt
      TMR1ON_bit=0;   // timer1 OFF
    }
    
    void Float2Ascii (float x, unsigned char *str,char precision)
    {
     /* converts a floating point number to an ascii string */
     /* x is stored into str, which should be at least 30 chars long */
     int ie, i, k, ndig;
     double y;
     ndig = ( precision<=0) ? 7 : (precision > 22 ? 23 : precision+1);
     ie = 0;
     /* if x negative, write minus and reverse */
     if ( x < 0)
     {
       *str++ = '-';
       x = -x;
     }
     /* put x in range 1 <= x < 10 */
     if (x > 0.0) while (x < 1.0)
     {
       x *= 10.0;                // a la place de =*
       ie--;
     }
     while (x >= 10.0)
     {
       x = x/10.0;
       ie++;
     }
     // in f format, number of digits is related to size
     ndig += ie;                                // a la place de =+
     //round. x is between 1 and 10 and ndig will be printed to
     // right of decimal point so rounding is ...
     for (y = i = 1; i < ndig; i++)
     y = y/10.;
     x += y/2.;
     if (x >= 10.0) {x = 1.0; ie++;}
     if (ie<0)
     {
       *str++ = '0'; *str++ = '.';
       if (ndig < 0) ie = ie-ndig;
       for (i = -1; i > ie; i--)  *str++ = '0';
     }
     for (i=0; i < ndig; i++)
     {
       k = x;
       *str++ = k + '0';
       if (i ==  ie ) *str++ = '.';
       x -= (y=k);
       x *= 10.0;
      }
     *str = '\0';
    }
    
    void Init_ADC()
    {
       ADCON0 = 0x00;// select channel 0 (AN0)
       ADCON1 = 0;
       ADCON2 = 0;
       ADCON1.VCFG1=0;    // VREF- = VSS=0V
       ADCON1.VCFG0=0;  // VREF+ = VDD=+5V
       ADCON1.PCFG3=1;
       ADCON1.PCFG2=1;
       ADCON1.PCFG1=1;
       ADCON1.PCFG0=0;
       ADCON0.ADON = 1;//Enable A/D module
       //ADCON2 setup: Right justified, Tacq=16Tad, Tad=2*Tosc (or Fosc/2)
       ADCON2.ADFM=1; // right justified
       ADCON2.ACQT2=1;  // 111 => 20 Tad
       ADCON2.ACQT1=1;
       ADCON2.ACQT0=1;
       ADCON2.ADCS2=1;  // FOSC /64
       ADCON2.ADCS1=1;
       ADCON2.ADCS0=1;
    }
    
    void Read_ADC0()
    {
        ADCON0.CHS0=0; // Channel 0 (AN0) Position du potar rectiligne
        Delay_ms(1);
        ADCON0.GO_DONE = 1;//Start A/D Conversion
        while(ADCON0.GO_DONE ==1);//Loop here until A/D conversion completes
        EA0=(ADRESH <<8) + ADRESL;
     }
     
    
    // --- Copie le texte depuis ROM vers RAM
    void strConstRamCpy(unsigned char *dest, const code char *source) {
      while (*source)*dest++ = *source++ ;
      *dest = 0 ;    // terminateur
    }
    
    
    
    void main(void)
    {
      PORTA=0;
      TRISA0_bit=1;  // Ana input  EA0
      TRISA1_bit=0;  // output to led verte (cablée  sur la carte StartUSB )
      TRISB0_bit=1;   // must be configure as input for I2C
      TRISB1_bit=1;    // must be configure as input for I2C
      TRISB3_bit=0;   // output to led rouge externe
      CMCON = 0x07;   // Disable comparators
    
      Delay_ms(150);    // wait for a while to oscillator stabilizes
    
      LED_Sup=0;
      LED_Inf=0;
      Toggle=0;
    
      Init_ADC();     // select channel 0 (AN0)
       Delay_ms(100);
       txt=&TEXTE[0];
      
      
      HID_Enable(&readbuff,&writebuff);       // Enable HID communication
      
    
      Init_Timer1();
      Flag_Timer1=0;
      TMR1IE_bit=1;
      TMR1ON_bit=1;
      PEIE_bit=1;
      GIE_bit=1;
      sprintf( &writebuff," Timer1 initialisé et Armé \r\n");
      // rajout test timer1 pour ne pas etre bloqué
      // si on a pas activé le terminal HID :  USB HID Libray
      while((Flag_Timer1==0)&& (!HID_Write(&writebuff,64)) );
    
    
       while(1)
      {
        while(!HID_Read() && (Flag_Timer1==0));                  // wait for data on USB
       if(Flag_Timer1==1)
       {
        Flag_Timer1=0;
        Count1=0;
        TMR1IE_bit=1;
        Read_ADC0();  // result into EA0
        ff1=(float)EA0 * 5.00 /1024.0;
        Float2Ascii (ff1, CRam1,2);
        if (Toggle==1)
          {
            Read_ADC0();  // result into EA0
            ff1=(float)EA0 * 5.00 /1024.0;
            Float2Ascii (ff1, CRam1,2);
            sprintf( &writebuff," ADC=% 5u    %04X  soit %s Volts \r\n",EA0,EA0,CRam1);
            while(!HID_Write(&writebuff,64));
          }
        }
       else
       {
            if(strncmp(&readbuff,"RED_ON",6)==0 )  LED_Sup=1;
            if(strncmp(&readbuff,"RED_OFF",7)==0 )  LED_Sup=0;
            if(strncmp(&readbuff,"GREEN_ON",8)==0) LED_Inf=1;
            if(strncmp(&readbuff,"GREEN_OFF",9)==0) LED_Inf=0;
            if(strncmp(&readbuff,"TOGGLE",6)==0) Toggle= Toggle ^ 0x0001;
           if (strncmp(&readbuff,"ADC",3)==0)
           {
    
              Read_ADC0();  // result into EA0
              ff1=(float)EA0 * 5.00 /1024.0;
              Float2Ascii (ff1, CRam1,2);
              sprintf( &writebuff," ADC=% 5u    %04X  soit %s Volts \r\n",EA0,EA0,CRam1);
            }
          while(!HID_Write(&writebuff,64));
        }
        if (EA0 >800)
        {
           LED_Sup=1;
         }
         if (EA0 <100)
         {
            LED_Inf=1;
          }
        Delay_ms(500);
      }
    }



    •   AltAdvertisement

        
       

  7. #7
    Full Member level 1
    Points: 639, Level: 5

    Join Date
    Nov 2018
    Posts
    96
    Helped
    1 / 1
    Points
    639
    Level
    5

    Re: Data acquisition using PIC starter kit

    Actually I have PIC18F2550 in house and PIC programmer. For learning purpose I would like to start working with that. The aim is to get throughput of 50 kilo sample per second with a string of 10 characters on USB full speed. Otherwise the string size can be reduced to 5 characters.

    How about PIC USB Starter Kit with PIC32 ? Would it be easy to implement the application on starter kit compared to PIC18F2550 ?

    I guess MPLAB' MLA (PIC8 and PIC16) and MPLAB Harmony (PIC32) both have demo projects for USB protocol, right ?

    How about the host software on PC side ?
    Last edited by joniengr; 21st September 2019 at 20:22.



--[[ ]]--