int pwm = 0;
void setup() {
pinMode(A2, INPUT);
pinMode(0, OUTPUT);
}
void loop() {
pwm = analogRead(A3); // read current pot position
pwm = pwm >>=2; // convert 10 bit from read to 8 bit for PWM, discarding 2 lower bits
analogWrite(0, pwm); // PWM output
}
I am currently using ATTiny85 but this could fit ATTiny5 (ATTiny4 does not have analog support) and at best I got this code to 672 bytes on ATTiny85 and 456 on ATTiny5
I used bitshift because it was quicker than divide by 4 or using map to convert 10 bit input to 8 bit output.
I guess the compiler would anyway optimize a /4 to a >>2, but if you directly manipulate the ADC registers instead of using analogRead() you don’t even need that. You can specify that the result is returned, left justified into an 8bit register.
If you don’t care too much about the pwm frequency, you can do it yourself in the loop by maintaining an 8 bit counter and switching the pin on at 0 and off at the pot value . I’m not sure what the resource savings would be, though.
If all you want to do is set a PWM value off an analog pin, you can put the adc in free running mode and it will give you an interrupt every time it completes a conversion and has a new value for you.
I'm not entirely sure it will work but it only takes up 162 bytes by getting rid of the Arduino runtime libraries. This is a .c file and not a .ino file. I don't have an ATtiny core (not needed for this program) so I compiled for an Arduino UNO and #undef'd the UNO processor so I could get the defines for an ATtiny85.
TinyKnob.c:
#undef __AVR_ATmega328P__
#define __AVR_ATtiny85__ 1
#include <avr/io.h> // includes <avr/iotn85.h> which includes <avr/iotnx5.h>
int main()
{
// void setup()
ADCSRA = 0;
ADCSRB = 0;
DIDR0 = _BV(ADC0D); // Disable digital input on ADC0
ADMUX = _BV(ADLAR); // Aref = Vcc, Value left justified, Channel = ADC0 (PB5)
ADCSRA = _BV(ADEN); // Enable ADC
// Enable PWM, Normal PWM, prescale=1
TCCR1 = _BV(PWM1A) | _BV(COM1A1) | _BV(CS10);
// void loop()
while (1)
{
// analogRead()
ADCSRA |= _BV(ADSC); // Start Conversion
while (ADCSRA & _BV(ADSC)); // Wait for conversion to complete
OCR1A = ADCH; // analogWrite()
}
}
Bit shifts 2 units over. Example: Arduino has a pwm value of 0000001101001101. A >> drops the least significiant bits, 2 states to drop 2. Then remaining binary value are then shifted by 2 and 00 is added as MSB, thus the new value for pwm is 0000000011010011
<< moves the value the other way by dropping MSB and adding 0's to the LSB