Attiny85 pwm Frequency & Duty


I want to make a attiny85 pwm with 2 pots for frequency and duty.

// Attiny85, Avr-gcc
// control pwm frequency and duty cycle with 2 potenciometers
// pot1 on ADC0 - frequency 
// pot2 on ADC1 - duty cycle

#include <avr/io.h>
#include <avr/interrupt.h>

uint8_t  dutyCycle;
uint32_t frequency;
uint8_t  prescaler;

uint8_t adc_read(uint8_t channel)
   ADMUX   = (1<<ADLAR) | channel; // Uref = AVCC, left justify result
   ADCSRA |= (1<<ADSC);            // start conversion
   while(ADCSRA & (1<<ADSC));      // wait for conversion finished
   return ADCH;                    // return 8-bit adc value 

int main(void)
   // init ports
      DDRB |= (1<<DDB1);             // set portb.1 (OCR0B) to output 

   // init ADC
      ADCSRA = (1<<ADEN)|(1<<ADPS1)|(1<<ADPS2); //enable adc, set prescaler

   // init timers (timer0 mode 7,  non inverting pwm, TOP=OCR0A)
      TCCR0A = (0<<COM0A1) | (0<<COM0A0) | (1<<COM0B1) | (0<<COM0B0) | (1<<WGM01) | (1<<WGM00); 
      TCCR0B = (1<<WGM02) | (1<<CS02) | (0<<CS01) | (0<<CS00); // prescaler 8
      prescaler = 8;
           OCR0A = adc_read(0);                             // read pot1 and set freq 
           OCR0B = adc_read(1);                             // read pot2 and set duty 
//         if(OCR0B >= OCR0A) print("error"); 
           frequency = F_CPU / ((OCR0A + 1) * prescaler);   // [Hz]
           dutyCycle = 100 * OCR0B / OCR0A;                 // [percent] 

This code doesn’t seem to work. I want to pulse a Mosfet at arround 32khz (variable) with a variable duty on 2 pots.

I pulse a coil and charge battery’s with the Back EMF, but since the battery’s are all different in size I need to be able to tune the frequency and dutycycle.

I am not a programmer and I just can’t find a decent sketch thats seems to work.

Can anyone help?

Can you post a schematic of what you're proposing to do....?

lucky thing you're not doing anything with the values of dutycycle - you're not taking account of integer math.

What I am doing now is I have another pulse sketch (or it acts like it) that seems to only do a pulse on pb1 with a pot on pb2.

What I want is to change frequency and duty with a pot on say pot (freq) pb2, pot (duty cycle or mark) pb1, and output on resp. pb0 (pulser gate FET)…

The sketch I added wasn’t working like I thought it would.

Only one pot works and it seems it only changes frequency because I hear the coil squeel different when I turn the pot, so that looks good, only I need the dutycycle to so I can charge the coil longeror shorter…

This is what I plan on making.

Thanks already…

By the way I have also this sketch:

#include <Arduino.h>

 * Filename: tiny85PWM
 * Author: Nicholas Pelham
 * Date: 02 December 2014
 * Description:
 *   Provides basic pulse width modulation functionality for software pins
 *   0, 1, and 4 on the ATTiny85

 * Initializes Timer/Counter Control Registers, Waveform Generation Mode, 
 * Clock Select, and Compare Match Output Bits for Fast Pulse Width 
 * Modulation. Sets the Output Compare Registers appropriately for matching
 * frequency and initializes the OCRnA and OCRnB to 0.
void initPWM() {        
        // Timer 0
        TCCR0A = (1<<WGM00) | (1<<WGM01) 
    | (1<<COM0A1) | (1<<COM0B1);  // fast PWM, clear OC0A and OC0B on compare
        TCCR0B = (1<<CS00);       // fast PWM, top at 0xFF, no prescaler
        OCR0A = OCR0B = 0;      // duty cycle // pulse width

        // Timer 1
        TCCR1 = (1<<CS10);      // no prescaler
        GTCCR = (1<<COM1B1) | (1<<PWM1B);   // clear OC1B on compare
        OCR1B = 0;        // duty cycle // pulse width
        OCR1C = 255;        // frequency

 * Used in place of analogWrite to force pulse width modulation on software
 * pin 4. It may not be neccessary to assign the value directly to OCR0A or
 * OCR0B, but it is done for consistancy.
 * If an invalid pin number is passed as pinNum, the function passes the 
 * parameters to Arduino's analogWrite function.
 * Parameters:
 *    pinNum - Software pin number which will be assigned a value
 *    value  - The value ranging from 0 to 255 which will be assigned to the 
 *             pin.
void writePWM(unsigned short pinNum, unsigned char value)
  switch(pinNum) {
  case 0:
    OCR0A = value;      // duty cycle
  case 1:
    OCR0B = value;      // duty cycle
  case 4:
    OCR1B = value;      // duty cycle
    analogWrite(pinNum, value);

But this gives me an error on the attiny85 compilation

attiny85_3_pwm_dutyCycle:47: error: expected initializer before ‘switch’
switch(pinNum) {
exit status 1
expected initializer before ‘switch’

So I can’t try that one…