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;
while(1)
{
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.
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
break;
case 1:
OCR0B = value; // duty cycle
break;
case 4:
OCR1B = value; // duty cycle
break;
default:
analogWrite(pinNum, value);
break;
}
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'