Skip to main content
2 of 5
added 2557 characters in body
KoenR
  • 177
  • 1
  • 3
  • 11

Increase PWM bit resolution

I would like to increase the PWM bit resolution of the Arduino Uno. At this moment it is 8-bit which I consider too low. Is this possible without losing the ability of interrupts and delays?

Koen

EDIT Changed the Setup, which Edgar Bonet delivered, to what I think is a 13-bit resolution

void setupPWM16() {
    DDRB |= _BV(PB1) | _BV(PB2);        /* set pins as outputs */
    TCCR1A = _BV(COM1A1) | _BV(COM1B1)  /* non-inverting PWM */
        | _BV(WGM11);                   /* mode 14: fast PWM, TOP=ICR1 */
    TCCR1B = _BV(WGM13) | _BV(WGM12)
        | _BV(CS11);                    /* prescaler 8 */
    ICR1 = 0xffff;                      /* TOP counter value (freeing OCR1A*/
}

At this moment I am using oversampling to increase my analogread resolution. This in combination with increasing the frequency of the ADC. Is someone able to take a look at(although it is out of topic)?

    #define FASTADC 1
    // defines for setting and clearing register bits
    #ifndef cbi
    #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
    #endif
    #ifndef sbi
    #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
    #endif
    
    int value[100];   // variable to store the value coming from the sensor
    int i=0;
    
    void setup() 
    {
      Serial.begin(9600) ;
     int start ;
     int i ;
     
    #if FASTADC
     // set prescale to 16
     sbi(ADCSRA,ADPS2) ;
     cbi(ADCSRA,ADPS1) ;
     cbi(ADCSRA,ADPS0) ;
    #endif
    }
    
    void loop() 
      { 
      for (i=0;i<100;i++)
      {
       value[i]=Read12bit(0);
      } 
      for (i=0;i<100;i++)
      {
       Serial.println(value[i]);
      } 
      Serial.println();//Some blanks between values
      Serial.println();
      delay(5000);
     
    }
    
    
    int Read12bit(uint8_t pin){
      in

t Result = 0;
  analogRead(pin);                      //Switch ADC
  for(int i = 0;i < 16; i++) {          //Read 16 times
    Result = Result + analogRead(pin);  //Sum results 
  }
  Result = (int)Result/4;               //Divide by 4 for 12 bit value
  return(Result);
}

At this moment the resolution of this oversampled analogread is 12-bits. With a little calculation the time to read will take 0,208milliseconds. As I see no way to change the PWM to 12 bit mode, I have to increase the analogread to 13 bits. This will take the measurement 0,832 milliseconds. This seems rather big, so my question is can I do this in another way?

KoenR
  • 177
  • 1
  • 3
  • 11